diff options
author | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2015-05-02 13:27:06 +0300 |
---|---|---|
committer | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2015-05-02 14:45:30 +0300 |
commit | 66129b3334a5aa54ff8a97981507e4704f759571 (patch) | |
tree | 92a4c68c6c84b387e41f15f675e0b44f40472fd1 | |
parent | 8422d5d699265b960bd1ca837044ee052fc5b614 (diff) | |
download | libgcrypt-66129b3334a5aa54ff8a97981507e4704f759571.tar.gz |
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 <jussi.kivilinna@iki.fi>
-rw-r--r-- | cipher/rijndael-amd64.S | 17 | ||||
-rw-r--r-- | cipher/rijndael-internal.h | 3 | ||||
-rw-r--r-- | 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 <config.h> -#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); |