summaryrefslogtreecommitdiff
path: root/cipher/salsa20.c
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2015-05-14 12:37:21 +0300
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2015-05-14 14:10:28 +0300
commit12bc93ca8187b8061c2e705427ef22f5a71d29b0 (patch)
tree6f13fd580e6a6a67630207a9e126ff6deca01e06 /cipher/salsa20.c
parent8d7de4dbf7732c6eb9e9853ad7c19c89075ace6f (diff)
downloadlibgcrypt-12bc93ca8187b8061c2e705427ef22f5a71d29b0.tar.gz
Enable AMD64 Salsa20 implementation on WIN64
* cipher/salsa20-amd64.S: Enable when HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined. (ELF): New macro to mask lines with ELF specific commands. * cipher/salsa20.c (USE_AMD64): Enable when HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined. [USE_AMD64] (ASM_FUNC_ABI, ASM_EXTRA_STACK): New. (_gcry_salsa20_amd64_keysetup, _gcry_salsa20_amd64_ivsetup) (_gcry_salsa20_amd64_encrypt_blocks): Add ASM_FUNC_ABI. [USE_AMD64] (salsa20_core): Add ASM_EXTRA_STACK. (salsa20_do_encrypt_stream) [USE_AMD64]: Add ASM_EXTRA_STACK. -- Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Diffstat (limited to 'cipher/salsa20.c')
-rw-r--r--cipher/salsa20.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/cipher/salsa20.c b/cipher/salsa20.c
index d75fe515..fa3d23b8 100644
--- a/cipher/salsa20.c
+++ b/cipher/salsa20.c
@@ -43,7 +43,8 @@
/* USE_AMD64 indicates whether to compile with AMD64 code. */
#undef USE_AMD64
-#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 1
#endif
@@ -118,12 +119,25 @@ static const char *selftest (void);
#ifdef USE_AMD64
+
+/* Assembly implementations use SystemV ABI, ABI conversion and additional
+ * stack to store XMM6-XMM15 needed on Win64. */
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+# define ASM_FUNC_ABI __attribute__((sysv_abi))
+# define ASM_EXTRA_STACK (10 * 16)
+#else
+# define ASM_FUNC_ABI
+# define ASM_EXTRA_STACK 0
+#endif
+
/* AMD64 assembly implementations of Salsa20. */
-void _gcry_salsa20_amd64_keysetup(u32 *ctxinput, const void *key, int keybits);
-void _gcry_salsa20_amd64_ivsetup(u32 *ctxinput, const void *iv);
+void _gcry_salsa20_amd64_keysetup(u32 *ctxinput, const void *key, int keybits)
+ ASM_FUNC_ABI;
+void _gcry_salsa20_amd64_ivsetup(u32 *ctxinput, const void *iv)
+ ASM_FUNC_ABI;
unsigned int
_gcry_salsa20_amd64_encrypt_blocks(u32 *ctxinput, const void *src, void *dst,
- size_t len, int rounds);
+ size_t len, int rounds) ASM_FUNC_ABI;
static void
salsa20_keysetup(SALSA20_context_t *ctx, const byte *key, int keylen)
@@ -141,7 +155,8 @@ static unsigned int
salsa20_core (u32 *dst, SALSA20_context_t *ctx, unsigned int rounds)
{
memset(dst, 0, SALSA20_BLOCK_SIZE);
- return _gcry_salsa20_amd64_encrypt_blocks(ctx->input, dst, dst, 1, rounds);
+ return _gcry_salsa20_amd64_encrypt_blocks(ctx->input, dst, dst, 1, rounds)
+ + ASM_EXTRA_STACK;
}
#else /* USE_AMD64 */
@@ -418,6 +433,7 @@ salsa20_do_encrypt_stream (SALSA20_context_t *ctx,
size_t nblocks = length / SALSA20_BLOCK_SIZE;
burn = _gcry_salsa20_amd64_encrypt_blocks(ctx->input, inbuf, outbuf,
nblocks, rounds);
+ burn += ASM_EXTRA_STACK;
length -= SALSA20_BLOCK_SIZE * nblocks;
outbuf += SALSA20_BLOCK_SIZE * nblocks;
inbuf += SALSA20_BLOCK_SIZE * nblocks;