summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2015-05-02 13:27:06 +0300
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2015-05-02 14:45:30 +0300
commit66129b3334a5aa54ff8a97981507e4704f759571 (patch)
tree92a4c68c6c84b387e41f15f675e0b44f40472fd1
parent8422d5d699265b960bd1ca837044ee052fc5b614 (diff)
downloadlibgcrypt-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.S17
-rw-r--r--cipher/rijndael-internal.h3
-rw-r--r--cipher/rijndael.c34
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);