From 66129b3334a5aa54ff8a97981507e4704f759571 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Sat, 2 May 2015 13:27:06 +0300 Subject: Enable AMD64 AES implementation for WIN64 * cipher/rijndael-amd64.S: Enable when HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined. (ELF): New macro to mask lines with ELF specific commands. * cipher/rijndael-internal.h (USE_AMD64_ASM): Enable when HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined. (do_encrypt, do_decrypt) [USE_AMD64_ASM && !HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS]: Use assembly block to call AMD64 assembly encrypt/decrypt function. -- Signed-off-by: Jussi Kivilinna --- cipher/rijndael-amd64.S | 17 ++++++++++++----- cipher/rijndael-internal.h | 3 ++- cipher/rijndael.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/cipher/rijndael-amd64.S b/cipher/rijndael-amd64.S index 24c555a2..b149e948 100644 --- a/cipher/rijndael-amd64.S +++ b/cipher/rijndael-amd64.S @@ -20,7 +20,8 @@ #ifdef __x86_64 #include -#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && defined(USE_AES) +#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ + defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_AES) #ifdef __PIC__ # define RIP (%rip) @@ -28,6 +29,12 @@ # define RIP #endif +#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS +# define ELF(...) __VA_ARGS__ +#else +# define ELF(...) /*_*/ +#endif + .text /* table macros */ @@ -205,7 +212,7 @@ .align 8 .globl _gcry_aes_amd64_encrypt_block -.type _gcry_aes_amd64_encrypt_block,@function; +ELF(.type _gcry_aes_amd64_encrypt_block,@function;) _gcry_aes_amd64_encrypt_block: /* input: @@ -279,7 +286,7 @@ _gcry_aes_amd64_encrypt_block: lastencround(11); jmp .Lenc_done; -.size _gcry_aes_amd64_encrypt_block,.-_gcry_aes_amd64_encrypt_block; +ELF(.size _gcry_aes_amd64_encrypt_block,.-_gcry_aes_amd64_encrypt_block;) #define do_decround(next_r) \ do16bit_shr(16, mov, RA, Dsize, D0, RNA, D0, RNB, RT0, RT1); \ @@ -365,7 +372,7 @@ _gcry_aes_amd64_encrypt_block: .align 8 .globl _gcry_aes_amd64_decrypt_block -.type _gcry_aes_amd64_decrypt_block,@function; +ELF(.type _gcry_aes_amd64_decrypt_block,@function;) _gcry_aes_amd64_decrypt_block: /* input: @@ -440,7 +447,7 @@ _gcry_aes_amd64_decrypt_block: decround(9); jmp .Ldec_tail; -.size _gcry_aes_amd64_decrypt_block,.-_gcry_aes_amd64_decrypt_block; +ELF(.size _gcry_aes_amd64_decrypt_block,.-_gcry_aes_amd64_decrypt_block;) #endif /*USE_AES*/ #endif /*__x86_64*/ diff --git a/cipher/rijndael-internal.h b/cipher/rijndael-internal.h index 33ca53f6..6641728c 100644 --- a/cipher/rijndael-internal.h +++ b/cipher/rijndael-internal.h @@ -39,7 +39,8 @@ /* USE_AMD64_ASM indicates whether to use AMD64 assembly code. */ #undef USE_AMD64_ASM -#if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) +#if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ + defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) # define USE_AMD64_ASM 1 #endif diff --git a/cipher/rijndael.c b/cipher/rijndael.c index ade41c9d..7ebf3293 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -665,8 +665,25 @@ do_encrypt (const RIJNDAEL_context *ctx, unsigned char *bx, const unsigned char *ax) { #ifdef USE_AMD64_ASM +# ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS return _gcry_aes_amd64_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds, encT); +# else + /* Call SystemV ABI function without storing non-volatile XMM registers, + * as target function does not use vector instruction sets. */ + uintptr_t ret; + asm ("movq %[encT], %%r8\n\t" + "callq *%[ret]\n\t" + : [ret] "=a" (ret) + : "0" (_gcry_aes_amd64_encrypt_block), + "D" (ctx->keyschenc), + "S" (bx), + "d" (ax), + "c" (ctx->rounds), + [encT] "r" (encT) + : "cc", "memory", "r8", "r9", "r10", "r11"); + return ret; +# endif /* HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS */ #elif defined(USE_ARM_ASM) return _gcry_aes_arm_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds, encT); #else @@ -1008,8 +1025,25 @@ do_decrypt (const RIJNDAEL_context *ctx, unsigned char *bx, const unsigned char *ax) { #ifdef USE_AMD64_ASM +# ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS return _gcry_aes_amd64_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds, &dec_tables); +# else + /* Call SystemV ABI function without storing non-volatile XMM registers, + * as target function does not use vector instruction sets. */ + uintptr_t ret; + asm ("movq %[dectabs], %%r8\n\t" + "callq *%[ret]\n\t" + : [ret] "=a" (ret) + : "0" (_gcry_aes_amd64_decrypt_block), + "D" (ctx->keyschdec), + "S" (bx), + "d" (ax), + "c" (ctx->rounds), + [dectabs] "r" (&dec_tables) + : "cc", "memory", "r8", "r9", "r10", "r11"); + return ret; +# endif /* HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS */ #elif defined(USE_ARM_ASM) return _gcry_aes_arm_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds, &dec_tables); -- cgit v1.2.1