summaryrefslogtreecommitdiff
path: root/cipher/blowfish.c
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2015-05-03 17:28:40 +0300
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2015-05-14 13:41:05 +0300
commite05682093ffb003b589a697428d918d755ac631d (patch)
tree4f5f130f657ea9631fcdf499e7c45136d620e198 /cipher/blowfish.c
parentc46b015bedba7ce0db68929bd33a86a54ab3d919 (diff)
downloadlibgcrypt-e05682093ffb003b589a697428d918d755ac631d.tar.gz
Enable AMD64 Blowfish implementation on WIN64
* cipher/blowfish-amd64.S: Enable when HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined. (ELF): New macro to mask lines with ELF specific commands. * cipher/blowfish.c (USE_AMD64_ASM): Enable when HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined. [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS] (call_sysv_fn): New. (do_encrypt, do_encrypt_block, do_decrypt_block) [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]: Call assembly function through 'call_sysv_fn'. (blowfish_amd64_ctr_enc, blowfish_amd64_cbc_dec) (blowfish_amd64_cfb_dec): New wrapper functions for bulk assembly functions. .. Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Diffstat (limited to 'cipher/blowfish.c')
-rw-r--r--cipher/blowfish.c74
1 files changed, 70 insertions, 4 deletions
diff --git a/cipher/blowfish.c b/cipher/blowfish.c
index ae470d8b..a3fc26ce 100644
--- a/cipher/blowfish.c
+++ b/cipher/blowfish.c
@@ -45,7 +45,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)) && \
(BLOWFISH_ROUNDS == 16)
# define USE_AMD64_ASM 1
#endif
@@ -280,22 +281,87 @@ extern void _gcry_blowfish_amd64_cbc_dec(BLOWFISH_context *ctx, byte *out,
extern void _gcry_blowfish_amd64_cfb_dec(BLOWFISH_context *ctx, byte *out,
const byte *in, byte *iv);
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+static inline void
+call_sysv_fn (const void *fn, const void *arg1, const void *arg2,
+ const void *arg3, const void *arg4)
+{
+ /* Call SystemV ABI function without storing non-volatile XMM registers,
+ * as target function does not use vector instruction sets. */
+ asm volatile ("callq *%0\n\t"
+ : "+a" (fn),
+ "+D" (arg1),
+ "+S" (arg2),
+ "+d" (arg3),
+ "+c" (arg4)
+ :
+ : "cc", "memory", "r8", "r9", "r10", "r11");
+}
+#endif
+
static void
do_encrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+ call_sysv_fn (_gcry_blowfish_amd64_do_encrypt, bc, ret_xl, ret_xr, NULL);
+#else
_gcry_blowfish_amd64_do_encrypt (bc, ret_xl, ret_xr);
+#endif
}
static void
do_encrypt_block (BLOWFISH_context *context, byte *outbuf, const byte *inbuf)
{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+ call_sysv_fn (_gcry_blowfish_amd64_encrypt_block, context, outbuf, inbuf,
+ NULL);
+#else
_gcry_blowfish_amd64_encrypt_block (context, outbuf, inbuf);
+#endif
}
static void
do_decrypt_block (BLOWFISH_context *context, byte *outbuf, const byte *inbuf)
{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+ call_sysv_fn (_gcry_blowfish_amd64_decrypt_block, context, outbuf, inbuf,
+ NULL);
+#else
_gcry_blowfish_amd64_decrypt_block (context, outbuf, inbuf);
+#endif
+}
+
+static inline void
+blowfish_amd64_ctr_enc(BLOWFISH_context *ctx, byte *out, const byte *in,
+ byte *ctr)
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+ call_sysv_fn (_gcry_blowfish_amd64_ctr_enc, ctx, out, in, ctr);
+#else
+ _gcry_blowfish_amd64_ctr_enc(ctx, out, in, ctr);
+#endif
+}
+
+static inline void
+blowfish_amd64_cbc_dec(BLOWFISH_context *ctx, byte *out, const byte *in,
+ byte *iv)
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+ call_sysv_fn (_gcry_blowfish_amd64_cbc_dec, ctx, out, in, iv);
+#else
+ _gcry_blowfish_amd64_cbc_dec(ctx, out, in, iv);
+#endif
+}
+
+static inline void
+blowfish_amd64_cfb_dec(BLOWFISH_context *ctx, byte *out, const byte *in,
+ byte *iv)
+{
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+ call_sysv_fn (_gcry_blowfish_amd64_cfb_dec, ctx, out, in, iv);
+#else
+ _gcry_blowfish_amd64_cfb_dec(ctx, out, in, iv);
+#endif
}
static unsigned int
@@ -605,7 +671,7 @@ _gcry_blowfish_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg,
/* Process data in 4 block chunks. */
while (nblocks >= 4)
{
- _gcry_blowfish_amd64_ctr_enc(ctx, outbuf, inbuf, ctr);
+ blowfish_amd64_ctr_enc(ctx, outbuf, inbuf, ctr);
nblocks -= 4;
outbuf += 4 * BLOWFISH_BLOCKSIZE;
@@ -674,7 +740,7 @@ _gcry_blowfish_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg,
/* Process data in 4 block chunks. */
while (nblocks >= 4)
{
- _gcry_blowfish_amd64_cbc_dec(ctx, outbuf, inbuf, iv);
+ blowfish_amd64_cbc_dec(ctx, outbuf, inbuf, iv);
nblocks -= 4;
outbuf += 4 * BLOWFISH_BLOCKSIZE;
@@ -734,7 +800,7 @@ _gcry_blowfish_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg,
/* Process data in 4 block chunks. */
while (nblocks >= 4)
{
- _gcry_blowfish_amd64_cfb_dec(ctx, outbuf, inbuf, iv);
+ blowfish_amd64_cfb_dec(ctx, outbuf, inbuf, iv);
nblocks -= 4;
outbuf += 4 * BLOWFISH_BLOCKSIZE;