[PATCH 5/6] Reduce amount of duplicated code in OCB bulk implementations

Jussi Kivilinna jussi.kivilinna at iki.fi
Mon Jul 27 11:04:35 CEST 2015


* cipher/cipher-ocb.c (_gcry_cipher_ocb_authenticate)
(ocb_crypt): Change bulk function to return number of unprocessed
blocks.
* src/cipher.h (_gcry_aes_ocb_crypt, _gcry_aes_ocb_auth)
(_gcry_camellia_ocb_crypt, _gcry_camellia_ocb_auth)
(_gcry_serpent_ocb_crypt, _gcry_serpent_ocb_auth)
(_gcry_twofish_ocb_crypt, _gcry_twofish_ocb_auth): Change return type
to 'size_t'.
* cipher/camellia-glue.c (get_l): Only if USE_AESNI_AVX or
USE_AESNI_AVX2 defined.
(_gcry_camellia_ocb_crypt, _gcry_camellia_ocb_auth): Change return type
to 'size_t' and return remaining blocks; Remove unaccelerated common
code path. Enable remaining common code only if USE_AESNI_AVX or
USE_AESNI_AVX2 defined; Remove unaccelerated common code.
* cipher/rijndael.c (_gcry_aes_ocb_crypt, _gcry_aes_ocb_auth): Change
return type to 'size_t' and return zero.
* cipher/serpent.c (get_l): Only if USE_SSE2, USE_AVX2 or USE_NEON
defined.
(_gcry_serpent_ocb_crypt, _gcry_serpent_ocb_auth): Change return type
to 'size_t' and return remaining blocks; Remove unaccelerated common
code path. Enable remaining common code only if USE_SSE2, USE_AVX2 or
USE_NEON defined; Remove unaccelerated common code.
* cipher/twofish.c (get_l): Only if USE_AMD64_ASM defined.
(_gcry_twofish_ocb_crypt, _gcry_twofish_ocb_auth): Change return type
to 'size_t' and return remaining blocks; Remove unaccelerated common
code path. Enable remaining common code only if USE_AMD64_ASM defined;
Remove unaccelerated common code.
--

Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
 cipher/camellia-glue.c   |   87 +++++++++++++-------------------------------
 cipher/cipher-internal.h |    7 ++--
 cipher/cipher-ocb.c      |   32 +++++++++++-----
 cipher/rijndael.c        |    8 +++-
 cipher/serpent.c         |   85 ++++++++++++-------------------------------
 cipher/twofish.c         |   91 ++++++++++------------------------------------
 src/cipher.h             |   38 ++++++++++---------
 7 files changed, 120 insertions(+), 228 deletions(-)

diff --git a/cipher/camellia-glue.c b/cipher/camellia-glue.c
index 197e1b3..99516fc 100644
--- a/cipher/camellia-glue.c
+++ b/cipher/camellia-glue.c
@@ -604,6 +604,7 @@ _gcry_camellia_cfb_dec(void *context, unsigned char *iv,
   _gcry_burn_stack(burn_stack_depth);
 }
 
+#if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
 static inline const unsigned char *
 get_l (gcry_cipher_hd_t c, unsigned char *l_tmp, u64 i)
 {
@@ -614,22 +615,29 @@ get_l (gcry_cipher_hd_t c, unsigned char *l_tmp, u64 i)
   else
       return _gcry_cipher_ocb_get_l (c, l_tmp, i);
 }
+#endif
 
 /* Bulk encryption/decryption of complete blocks in OCB mode. */
-void
+size_t
 _gcry_camellia_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
 			  const void *inbuf_arg, size_t nblocks, int encrypt)
 {
+#if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
   CAMELLIA_context *ctx = (void *)&c->context.c;
   unsigned char *outbuf = outbuf_arg;
   const unsigned char *inbuf = inbuf_arg;
   unsigned char l_tmp[CAMELLIA_BLOCK_SIZE];
-  const unsigned char *l;
   int burn_stack_depth;
   u64 blkn = c->u_mode.ocb.data_nblocks;
 
   burn_stack_depth = encrypt ? CAMELLIA_encrypt_stack_burn_size :
 			      CAMELLIA_decrypt_stack_burn_size;
+#else
+  (void)c;
+  (void)outbuf_arg;
+  (void)inbuf_arg;
+  (void)encrypt;
+#endif
 
 #ifdef USE_AESNI_AVX2
   if (ctx->use_aesni_avx2)
@@ -723,70 +731,35 @@ _gcry_camellia_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
     }
 #endif
 
-  if (encrypt)
-    {
-      for (; nblocks; nblocks--)
-	{
-	  l = get_l(c, l_tmp, ++blkn);
-
-	  /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
-	  buf_xor_1 (c->u_iv.iv, l, CAMELLIA_BLOCK_SIZE);
-	  buf_cpy (l_tmp, inbuf, CAMELLIA_BLOCK_SIZE);
-	  /* Checksum_i = Checksum_{i-1} xor P_i  */
-	  buf_xor_1 (c->u_ctr.ctr, l_tmp, CAMELLIA_BLOCK_SIZE);
-	  /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
-	  buf_xor_1 (l_tmp, c->u_iv.iv, CAMELLIA_BLOCK_SIZE);
-	  Camellia_EncryptBlock(ctx->keybitlength, l_tmp, ctx->keytable, l_tmp);
-	  buf_xor_1 (l_tmp, c->u_iv.iv, CAMELLIA_BLOCK_SIZE);
-	  buf_cpy (outbuf, l_tmp, CAMELLIA_BLOCK_SIZE);
-
-	  inbuf += CAMELLIA_BLOCK_SIZE;
-	  outbuf += CAMELLIA_BLOCK_SIZE;
-	}
-    }
-  else
-    {
-      for (; nblocks; nblocks--)
-	{
-	  l = get_l(c, l_tmp, ++blkn);
-
-	  /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
-	  buf_xor_1 (c->u_iv.iv, l, CAMELLIA_BLOCK_SIZE);
-	  buf_cpy (l_tmp, inbuf, CAMELLIA_BLOCK_SIZE);
-	  /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
-	  buf_xor_1 (l_tmp, c->u_iv.iv, CAMELLIA_BLOCK_SIZE);
-	  Camellia_DecryptBlock(ctx->keybitlength, l_tmp, ctx->keytable, l_tmp);
-	  buf_xor_1 (l_tmp, c->u_iv.iv, CAMELLIA_BLOCK_SIZE);
-	  /* Checksum_i = Checksum_{i-1} xor P_i  */
-	  buf_xor_1 (c->u_ctr.ctr, l_tmp, CAMELLIA_BLOCK_SIZE);
-	  buf_cpy (outbuf, l_tmp, CAMELLIA_BLOCK_SIZE);
-
-	  inbuf += CAMELLIA_BLOCK_SIZE;
-	  outbuf += CAMELLIA_BLOCK_SIZE;
-	}
-    }
-
+#if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
   c->u_mode.ocb.data_nblocks = blkn;
 
   wipememory(&l_tmp, sizeof(l_tmp));
 
   if (burn_stack_depth)
     _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *));
+#endif
+
+  return nblocks;
 }
 
 /* Bulk authentication of complete blocks in OCB mode. */
-void
+size_t
 _gcry_camellia_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
-			size_t nblocks)
+			 size_t nblocks)
 {
+#if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
   CAMELLIA_context *ctx = (void *)&c->context.c;
   const unsigned char *abuf = abuf_arg;
   unsigned char l_tmp[CAMELLIA_BLOCK_SIZE];
-  const unsigned char *l;
   int burn_stack_depth;
   u64 blkn = c->u_mode.ocb.aad_nblocks;
 
   burn_stack_depth = CAMELLIA_encrypt_stack_burn_size;
+#else
+  (void)c;
+  (void)abuf_arg;
+#endif
 
 #ifdef USE_AESNI_AVX2
   if (ctx->use_aesni_avx2)
@@ -870,26 +843,16 @@ _gcry_camellia_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
     }
 #endif
 
-  for (; nblocks; nblocks--)
-    {
-      l = get_l(c, l_tmp, ++blkn);
-
-      /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
-      buf_xor_1 (c->u_mode.ocb.aad_offset, l, CAMELLIA_BLOCK_SIZE);
-      /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
-      buf_xor (l_tmp, c->u_mode.ocb.aad_offset, abuf, CAMELLIA_BLOCK_SIZE);
-      Camellia_EncryptBlock(ctx->keybitlength, l_tmp, ctx->keytable, l_tmp);
-      buf_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, CAMELLIA_BLOCK_SIZE);
-
-      abuf += CAMELLIA_BLOCK_SIZE;
-    }
-
+#if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
   c->u_mode.ocb.aad_nblocks = blkn;
 
   wipememory(&l_tmp, sizeof(l_tmp));
 
   if (burn_stack_depth)
     _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *));
+#endif
+
+  return nblocks;
 }
 
 /* Run the self-tests for CAMELLIA-CTR-128, tests IV increment of bulk CTR
diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h
index e20ea56..bb86d37 100644
--- a/cipher/cipher-internal.h
+++ b/cipher/cipher-internal.h
@@ -128,9 +128,10 @@ struct gcry_cipher_handle
     void (*ctr_enc)(void *context, unsigned char *iv,
                     void *outbuf_arg, const void *inbuf_arg,
                     size_t nblocks);
-    void (*ocb_crypt)(gcry_cipher_hd_t c, void *outbuf_arg,
-                      const void *inbuf_arg, size_t nblocks, int encrypt);
-    void (*ocb_auth)(gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks);
+    size_t (*ocb_crypt)(gcry_cipher_hd_t c, void *outbuf_arg,
+			const void *inbuf_arg, size_t nblocks, int encrypt);
+    size_t (*ocb_auth)(gcry_cipher_hd_t c, const void *abuf_arg,
+		       size_t nblocks);
   } bulk;
 
 
diff --git a/cipher/cipher-ocb.c b/cipher/cipher-ocb.c
index bc6fd87..096975a 100644
--- a/cipher/cipher-ocb.c
+++ b/cipher/cipher-ocb.c
@@ -260,10 +260,17 @@ _gcry_cipher_ocb_authenticate (gcry_cipher_hd_t c, const unsigned char *abuf,
   /* Use a bulk method if available.  */
   if (abuflen >= OCB_BLOCK_LEN && c->bulk.ocb_auth)
     {
-      size_t nblks = abuflen / OCB_BLOCK_LEN;
-      c->bulk.ocb_auth (c, abuf, nblks);
-      abuf += nblks * OCB_BLOCK_LEN;
-      abuflen -= nblks * OCB_BLOCK_LEN;
+      size_t nblks;
+      size_t nleft;
+      size_t ndone;
+
+      nblks = abuflen / OCB_BLOCK_LEN;
+      nleft = c->bulk.ocb_auth (c, abuf, nblks);
+      ndone = nblks - nleft;
+
+      abuf += ndone * OCB_BLOCK_LEN;
+      abuflen -= ndone * OCB_BLOCK_LEN;
+      nblks = nleft;
     }
 
   /* Hash all full blocks.  */
@@ -354,12 +361,17 @@ ocb_crypt (gcry_cipher_hd_t c, int encrypt,
   /* Use a bulk method if available.  */
   if (nblks && c->bulk.ocb_crypt)
     {
-      c->bulk.ocb_crypt (c, outbuf, inbuf, nblks, encrypt);
-      inbuf  += nblks * OCB_BLOCK_LEN;
-      outbuf += nblks * OCB_BLOCK_LEN;
-      inbuflen -= nblks * OCB_BLOCK_LEN;
-      outbuflen -= nblks * OCB_BLOCK_LEN;
-      nblks = 0;
+      size_t nleft;
+      size_t ndone;
+
+      nleft = c->bulk.ocb_crypt (c, outbuf, inbuf, nblks, encrypt);
+      ndone = nblks - nleft;
+
+      inbuf += ndone * OCB_BLOCK_LEN;
+      outbuf += ndone * OCB_BLOCK_LEN;
+      inbuflen -= ndone * OCB_BLOCK_LEN;
+      outbuflen -= ndone * OCB_BLOCK_LEN;
+      nblks = nleft;
     }
 
   if (nblks)
diff --git a/cipher/rijndael.c b/cipher/rijndael.c
index 1fe16d6..4368c6d 100644
--- a/cipher/rijndael.c
+++ b/cipher/rijndael.c
@@ -1200,7 +1200,7 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv,
 
 

 /* Bulk encryption/decryption of complete blocks in OCB mode. */
-void
+size_t
 _gcry_aes_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
                      const void *inbuf_arg, size_t nblocks, int encrypt)
 {
@@ -1303,11 +1303,13 @@ _gcry_aes_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
 
   if (burn_depth)
     _gcry_burn_stack (burn_depth + 4 * sizeof(void *));
+
+  return 0;
 }
 
 
 /* Bulk authentication of complete blocks in OCB mode. */
-void
+size_t
 _gcry_aes_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks)
 {
   RIJNDAEL_context *ctx = (void *)&c->context.c;
@@ -1364,6 +1366,8 @@ _gcry_aes_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks)
 
   if (burn_depth)
     _gcry_burn_stack (burn_depth + 4 * sizeof(void *));
+
+  return 0;
 }
 
 
diff --git a/cipher/serpent.c b/cipher/serpent.c
index eb491aa..0a54a17 100644
--- a/cipher/serpent.c
+++ b/cipher/serpent.c
@@ -1226,6 +1226,7 @@ _gcry_serpent_cfb_dec(void *context, unsigned char *iv,
   _gcry_burn_stack(burn_stack_depth);
 }
 
+#if defined(USE_AVX2) || defined(USE_SSE2) || defined(USE_NEON)
 static inline const unsigned char *
 get_l (gcry_cipher_hd_t c, unsigned char *l_tmp, u64 i)
 {
@@ -1236,19 +1237,26 @@ get_l (gcry_cipher_hd_t c, unsigned char *l_tmp, u64 i)
   else
       return _gcry_cipher_ocb_get_l (c, l_tmp, i);
 }
+#endif
 
 /* Bulk encryption/decryption of complete blocks in OCB mode. */
-void
+size_t
 _gcry_serpent_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
 			const void *inbuf_arg, size_t nblocks, int encrypt)
 {
+#if defined(USE_AVX2) || defined(USE_SSE2) || defined(USE_NEON)
   serpent_context_t *ctx = (void *)&c->context.c;
   unsigned char *outbuf = outbuf_arg;
   const unsigned char *inbuf = inbuf_arg;
   unsigned char l_tmp[sizeof(serpent_block_t)];
-  const unsigned char *l;
   int burn_stack_depth = 2 * sizeof (serpent_block_t);
   u64 blkn = c->u_mode.ocb.data_nblocks;
+#else
+  (void)c;
+  (void)outbuf_arg;
+  (void)inbuf_arg;
+  (void)encrypt;
+#endif
 
 #ifdef USE_AVX2
   if (ctx->use_avx2)
@@ -1381,68 +1389,33 @@ _gcry_serpent_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
     }
 #endif
 
-  if (encrypt)
-    {
-      for (; nblocks; nblocks--)
-	{
-	  l = get_l(c, l_tmp, ++blkn);
-
-	  /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
-	  buf_xor_1 (c->u_iv.iv, l, sizeof(serpent_block_t));
-	  buf_cpy (l_tmp, inbuf, sizeof(serpent_block_t));
-	  /* Checksum_i = Checksum_{i-1} xor P_i  */
-	  buf_xor_1 (c->u_ctr.ctr, l_tmp, sizeof(serpent_block_t));
-	  /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
-	  buf_xor_1 (l_tmp, c->u_iv.iv, sizeof(serpent_block_t));
-	  serpent_encrypt_internal(ctx, l_tmp, l_tmp);
-	  buf_xor_1 (l_tmp, c->u_iv.iv, sizeof(serpent_block_t));
-	  buf_cpy (outbuf, l_tmp, sizeof(serpent_block_t));
-
-	  inbuf += sizeof(serpent_block_t);
-	  outbuf += sizeof(serpent_block_t);
-	}
-    }
-  else
-    {
-      for (; nblocks; nblocks--)
-	{
-	  l = get_l(c, l_tmp, ++blkn);
-
-	  /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
-	  buf_xor_1 (c->u_iv.iv, l, sizeof(serpent_block_t));
-	  buf_cpy (l_tmp, inbuf, sizeof(serpent_block_t));
-	  /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
-	  buf_xor_1 (l_tmp, c->u_iv.iv, sizeof(serpent_block_t));
-	  serpent_decrypt_internal(ctx, l_tmp, l_tmp);
-	  buf_xor_1 (l_tmp, c->u_iv.iv, sizeof(serpent_block_t));
-	  /* Checksum_i = Checksum_{i-1} xor P_i  */
-	  buf_xor_1 (c->u_ctr.ctr, l_tmp, sizeof(serpent_block_t));
-	  buf_cpy (outbuf, l_tmp, sizeof(serpent_block_t));
-
-	  inbuf += sizeof(serpent_block_t);
-	  outbuf += sizeof(serpent_block_t);
-	}
-    }
-
+#if defined(USE_AVX2) || defined(USE_SSE2) || defined(USE_NEON)
   c->u_mode.ocb.data_nblocks = blkn;
 
   wipememory(&l_tmp, sizeof(l_tmp));
 
   if (burn_stack_depth)
     _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *));
+#endif
+
+  return nblocks;
 }
 
 /* Bulk authentication of complete blocks in OCB mode. */
-void
+size_t
 _gcry_serpent_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
 			size_t nblocks)
 {
+#if defined(USE_AVX2) || defined(USE_SSE2) || defined(USE_NEON)
   serpent_context_t *ctx = (void *)&c->context.c;
   const unsigned char *abuf = abuf_arg;
   unsigned char l_tmp[sizeof(serpent_block_t)];
-  const unsigned char *l;
   int burn_stack_depth = 2 * sizeof(serpent_block_t);
   u64 blkn = c->u_mode.ocb.aad_nblocks;
+#else
+  (void)c;
+  (void)abuf_arg;
+#endif
 
 #ifdef USE_AVX2
   if (ctx->use_avx2)
@@ -1560,26 +1533,16 @@ _gcry_serpent_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
     }
 #endif
 
-  for (; nblocks; nblocks--)
-    {
-      l = get_l(c, l_tmp, ++blkn);
-
-      /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
-      buf_xor_1 (c->u_mode.ocb.aad_offset, l, sizeof(serpent_block_t));
-      /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
-      buf_xor (l_tmp, c->u_mode.ocb.aad_offset, abuf, sizeof(serpent_block_t));
-      serpent_encrypt_internal(ctx, l_tmp, l_tmp);
-      buf_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, sizeof(serpent_block_t));
-
-      abuf += sizeof(serpent_block_t);
-    }
-
+#if defined(USE_AVX2) || defined(USE_SSE2) || defined(USE_NEON)
   c->u_mode.ocb.aad_nblocks = blkn;
 
   wipememory(&l_tmp, sizeof(l_tmp));
 
   if (burn_stack_depth)
     _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *));
+#endif
+
+  return nblocks;
 }
 
 

diff --git a/cipher/twofish.c b/cipher/twofish.c
index 9b9c35f..3ee2be5 100644
--- a/cipher/twofish.c
+++ b/cipher/twofish.c
@@ -1271,6 +1271,7 @@ _gcry_twofish_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg,
   _gcry_burn_stack(burn_stack_depth);
 }
 
+#ifdef USE_AMD64_ASM
 static inline const unsigned char *
 get_l (gcry_cipher_hd_t c, unsigned char *l_tmp, u64 i)
 {
@@ -1281,21 +1282,21 @@ get_l (gcry_cipher_hd_t c, unsigned char *l_tmp, u64 i)
   else
       return _gcry_cipher_ocb_get_l (c, l_tmp, i);
 }
+#endif
 
 /* Bulk encryption/decryption of complete blocks in OCB mode. */
-void
+size_t
 _gcry_twofish_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
 			const void *inbuf_arg, size_t nblocks, int encrypt)
 {
+#ifdef USE_AMD64_ASM
   TWOFISH_context *ctx = (void *)&c->context.c;
   unsigned char *outbuf = outbuf_arg;
   const unsigned char *inbuf = inbuf_arg;
   unsigned char l_tmp[TWOFISH_BLOCKSIZE];
-  const unsigned char *l;
   unsigned int burn, burn_stack_depth = 0;
   u64 blkn = c->u_mode.ocb.data_nblocks;
 
-#ifdef USE_AMD64_ASM
   {
     const void *Ls[3];
 
@@ -1326,54 +1327,6 @@ _gcry_twofish_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
 
     /* Use generic code to handle smaller chunks... */
   }
-#endif
-
-  if (encrypt)
-    {
-      for (; nblocks; nblocks--)
-	{
-	  l = get_l(c, l_tmp, ++blkn);
-
-	  /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
-	  buf_xor_1 (c->u_iv.iv, l, TWOFISH_BLOCKSIZE);
-	  buf_cpy (l_tmp, inbuf, TWOFISH_BLOCKSIZE);
-	  /* Checksum_i = Checksum_{i-1} xor P_i  */
-	  buf_xor_1 (c->u_ctr.ctr, l_tmp, TWOFISH_BLOCKSIZE);
-	  /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
-	  buf_xor_1 (l_tmp, c->u_iv.iv, TWOFISH_BLOCKSIZE);
-	  burn = twofish_encrypt(ctx, l_tmp, l_tmp);
-	  if (burn > burn_stack_depth)
-	    burn_stack_depth = burn;
-	  buf_xor_1 (l_tmp, c->u_iv.iv, TWOFISH_BLOCKSIZE);
-	  buf_cpy (outbuf, l_tmp, TWOFISH_BLOCKSIZE);
-
-	  inbuf += TWOFISH_BLOCKSIZE;
-	  outbuf += TWOFISH_BLOCKSIZE;
-	}
-    }
-  else
-    {
-      for (; nblocks; nblocks--)
-	{
-	  l = get_l(c, l_tmp, ++blkn);
-
-	  /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
-	  buf_xor_1 (c->u_iv.iv, l, TWOFISH_BLOCKSIZE);
-	  buf_cpy (l_tmp, inbuf, TWOFISH_BLOCKSIZE);
-	  /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
-	  buf_xor_1 (l_tmp, c->u_iv.iv, TWOFISH_BLOCKSIZE);
-	  burn = twofish_decrypt(ctx, l_tmp, l_tmp);
-	  if (burn > burn_stack_depth)
-	    burn_stack_depth = burn;
-	  buf_xor_1 (l_tmp, c->u_iv.iv, TWOFISH_BLOCKSIZE);
-	  /* Checksum_i = Checksum_{i-1} xor P_i  */
-	  buf_xor_1 (c->u_ctr.ctr, l_tmp, TWOFISH_BLOCKSIZE);
-	  buf_cpy (outbuf, l_tmp, TWOFISH_BLOCKSIZE);
-
-	  inbuf += TWOFISH_BLOCKSIZE;
-	  outbuf += TWOFISH_BLOCKSIZE;
-	}
-    }
 
   c->u_mode.ocb.data_nblocks = blkn;
 
@@ -1381,21 +1334,28 @@ _gcry_twofish_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
 
   if (burn_stack_depth)
     _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *));
+#else
+  (void)c;
+  (void)outbuf_arg;
+  (void)inbuf_arg;
+  (void)encrypt;
+#endif
+
+  return nblocks;
 }
 
 /* Bulk authentication of complete blocks in OCB mode. */
-void
+size_t
 _gcry_twofish_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
 			size_t nblocks)
 {
+#ifdef USE_AMD64_ASM
   TWOFISH_context *ctx = (void *)&c->context.c;
   const unsigned char *abuf = abuf_arg;
   unsigned char l_tmp[TWOFISH_BLOCKSIZE];
-  const unsigned char *l;
   unsigned int burn, burn_stack_depth = 0;
   u64 blkn = c->u_mode.ocb.aad_nblocks;
 
-#ifdef USE_AMD64_ASM
   {
     const void *Ls[3];
 
@@ -1421,23 +1381,6 @@ _gcry_twofish_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
 
     /* Use generic code to handle smaller chunks... */
   }
-#endif
-
-  for (; nblocks; nblocks--)
-    {
-      l = get_l(c, l_tmp, ++blkn);
-
-      /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
-      buf_xor_1 (c->u_mode.ocb.aad_offset, l, TWOFISH_BLOCKSIZE);
-      /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
-      buf_xor (l_tmp, c->u_mode.ocb.aad_offset, abuf, TWOFISH_BLOCKSIZE);
-      burn = twofish_encrypt(ctx, l_tmp, l_tmp);
-      if (burn > burn_stack_depth)
-	burn_stack_depth = burn;
-      buf_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, TWOFISH_BLOCKSIZE);
-
-      abuf += TWOFISH_BLOCKSIZE;
-    }
 
   c->u_mode.ocb.aad_nblocks = blkn;
 
@@ -1445,6 +1388,12 @@ _gcry_twofish_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
 
   if (burn_stack_depth)
     _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *));
+#else
+  (void)c;
+  (void)abuf_arg;
+#endif
+
+  return nblocks;
 }
 
 

diff --git a/src/cipher.h b/src/cipher.h
index d16746a..52f2695 100644
--- a/src/cipher.h
+++ b/src/cipher.h
@@ -136,10 +136,10 @@ void _gcry_aes_cbc_dec (void *context, unsigned char *iv,
 void _gcry_aes_ctr_enc (void *context, unsigned char *ctr,
                         void *outbuf_arg, const void *inbuf_arg,
                         size_t nblocks);
-void _gcry_aes_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
-                         const void *inbuf_arg, size_t nblocks, int encrypt);
-void _gcry_aes_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
-                         size_t nblocks);
+size_t _gcry_aes_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
+			    const void *inbuf_arg, size_t nblocks, int encrypt);
+size_t _gcry_aes_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
+			   size_t nblocks);
 
 /*-- blowfish.c --*/
 void _gcry_blowfish_cfb_dec (void *context, unsigned char *iv,
@@ -177,11 +177,11 @@ void _gcry_camellia_cbc_dec (void *context, unsigned char *iv,
 void _gcry_camellia_cfb_dec (void *context, unsigned char *iv,
                              void *outbuf_arg, const void *inbuf_arg,
                              size_t nblocks);
-void _gcry_camellia_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
-			       const void *inbuf_arg, size_t nblocks,
-			       int encrypt);
-void _gcry_camellia_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
-			      size_t nblocks);
+size_t _gcry_camellia_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
+				 const void *inbuf_arg, size_t nblocks,
+				 int encrypt);
+size_t _gcry_camellia_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
+				size_t nblocks);
 
 /*-- des.c --*/
 void _gcry_3des_ctr_enc (void *context, unsigned char *ctr,
@@ -206,11 +206,11 @@ void _gcry_serpent_cbc_dec (void *context, unsigned char *iv,
 void _gcry_serpent_cfb_dec (void *context, unsigned char *iv,
                             void *outbuf_arg, const void *inbuf_arg,
                             size_t nblocks);
-void _gcry_serpent_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
-			      const void *inbuf_arg, size_t nblocks,
-			      int encrypt);
-void _gcry_serpent_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
-			     size_t nblocks);
+size_t _gcry_serpent_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
+				const void *inbuf_arg, size_t nblocks,
+				int encrypt);
+size_t _gcry_serpent_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
+			       size_t nblocks);
 
 /*-- twofish.c --*/
 void _gcry_twofish_ctr_enc (void *context, unsigned char *ctr,
@@ -222,11 +222,11 @@ void _gcry_twofish_cbc_dec (void *context, unsigned char *iv,
 void _gcry_twofish_cfb_dec (void *context, unsigned char *iv,
                             void *outbuf_arg, const void *inbuf_arg,
                             size_t nblocks);
-void _gcry_twofish_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
-			      const void *inbuf_arg, size_t nblocks,
-			      int encrypt);
-void _gcry_twofish_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
-			     size_t nblocks);
+size_t _gcry_twofish_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
+				const void *inbuf_arg, size_t nblocks,
+				int encrypt);
+size_t _gcry_twofish_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
+			       size_t nblocks);
 
 /*-- dsa.c --*/
 void _gcry_register_pk_dsa_progress (gcry_handler_progress_t cbc, void *cb_data);




More information about the Gcrypt-devel mailing list