[git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-375-gdf29831

by Jussi Kivilinna cvs at cvs.gnupg.org
Sat Nov 9 21:45:39 CET 2013


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU crypto library".

The branch, master has been updated
       via  df29831d008e32faf74091d080a415731418d158 (commit)
      from  51501b638546665163bbb85a14308fdb99211a28 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit df29831d008e32faf74091d080a415731418d158
Author: Jussi Kivilinna <jussi.kivilinna at iki.fi>
Date:   Sat Nov 9 22:39:19 2013 +0200

    Fix Serpent-AVX2 and Camellia-AVX2 counter modes
    
    * cipher/camellia-aesni-avx2-amd64.S
    (_gcry_camellia_aesni_avx2_ctr_enc): Byte-swap before checking for
    overflow handling.
    * cipher/camellia-glue.c (selftest_ctr_128, selftest_cfb_128)
    (selftest_cbc_128): Add 16 to nblocks.
    * cipher/cipher-selftest.c (_gcry_selftest_helper_ctr): Add test with
    non-overflowing IV and modify overflow IV to detect broken endianness
    handling.
    * cipher/serpent-avx2-amd64.S (_gcry_serpent_avx2_ctr_enc): Byte-swap
    before checking for overflow handling; Fix crazy-mixed-endian IV
    construction to big-endian.
    * cipher/serpent.c (selftest_ctr_128, selftest_cfb_128)
    (selftest_cbc_128): Add 8 to nblocks.
    --
    
    The selftest for CTR was setting counter-IV to all '0xff' except last byte.
    This had the effect that even with broken endianness handling Serpent-AVX2 and
    Camellia-AVX2 passed the tests.
    
    Patch corrects the CTR selftest and fixes the broken implementations.
    
    Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>

diff --git a/cipher/camellia-aesni-avx2-amd64.S b/cipher/camellia-aesni-avx2-amd64.S
index f0a4fd8..78ef2d6 100644
--- a/cipher/camellia-aesni-avx2-amd64.S
+++ b/cipher/camellia-aesni-avx2-amd64.S
@@ -937,6 +937,9 @@ _gcry_camellia_aesni_avx2_ctr_enc:
 	 *	%rcx: iv (big endian, 128bit)
 	 */
 
+	movq 8(%rcx), %r11;
+	bswapq %r11;
+
 	vzeroupper;
 
 	movq %rsp, %r10;
@@ -958,7 +961,7 @@ _gcry_camellia_aesni_avx2_ctr_enc:
 	vmovdqa %ymm13, 15 * 32(%rax);
 
 	/* check need for handling 64-bit overflow and carry */
-	cmpq $(0xffffffffffffffff - 32), (%rcx);
+	cmpq $(0xffffffffffffffff - 32), %r11;
 	ja .Lload_ctr_carry;
 
 	/* construct IVs */
diff --git a/cipher/camellia-glue.c b/cipher/camellia-glue.c
index 42b62d2..b7ae0fc 100644
--- a/cipher/camellia-glue.c
+++ b/cipher/camellia-glue.c
@@ -537,7 +537,7 @@ _gcry_camellia_cfb_dec(void *context, unsigned char *iv,
 static const char*
 selftest_ctr_128 (void)
 {
-  const int nblocks = 32+1;
+  const int nblocks = 32+16+1;
   const int blocksize = CAMELLIA_BLOCK_SIZE;
   const int context_size = sizeof(CAMELLIA_context);
 
@@ -551,7 +551,7 @@ selftest_ctr_128 (void)
 static const char*
 selftest_cbc_128 (void)
 {
-  const int nblocks = 32+2;
+  const int nblocks = 32+16+2;
   const int blocksize = CAMELLIA_BLOCK_SIZE;
   const int context_size = sizeof(CAMELLIA_context);
 
@@ -565,7 +565,7 @@ selftest_cbc_128 (void)
 static const char*
 selftest_cfb_128 (void)
 {
-  const int nblocks = 32+2;
+  const int nblocks = 32+16+2;
   const int blocksize = CAMELLIA_BLOCK_SIZE;
   const int context_size = sizeof(CAMELLIA_context);
 
diff --git a/cipher/cipher-selftest.c b/cipher/cipher-selftest.c
index 17742e3..8e58150 100644
--- a/cipher/cipher-selftest.c
+++ b/cipher/cipher-selftest.c
@@ -286,7 +286,8 @@ _gcry_selftest_helper_ctr (const char *cipher, gcry_cipher_setkey_t setkey_func,
 			   const int context_size)
 {
   int i, j, offs, diff;
-  unsigned char *ctx, *plaintext, *plaintext2, *ciphertext, *iv, *iv2, *mem;
+  unsigned char *ctx, *plaintext, *plaintext2, *ciphertext, *ciphertext2,
+                *iv, *iv2, *mem;
   unsigned int ctx_aligned_size, memsize;
 
   static const unsigned char key[16] ATTR_ALIGNED_16 = {
@@ -299,7 +300,7 @@ _gcry_selftest_helper_ctr (const char *cipher, gcry_cipher_setkey_t setkey_func,
   ctx_aligned_size = context_size + 15;
   ctx_aligned_size -= ctx_aligned_size & 0xf;
 
-  memsize = ctx_aligned_size + (blocksize * 2) + (blocksize * nblocks * 3) + 16;
+  memsize = ctx_aligned_size + (blocksize * 2) + (blocksize * nblocks * 4) + 16;
 
   mem = gcry_calloc (1, memsize);
   if (!mem)
@@ -312,6 +313,7 @@ _gcry_selftest_helper_ctr (const char *cipher, gcry_cipher_setkey_t setkey_func,
   plaintext = iv2 + blocksize;
   plaintext2 = plaintext + nblocks * blocksize;
   ciphertext = plaintext2 + nblocks * blocksize;
+  ciphertext2 = ciphertext + nblocks * blocksize;
 
   /* Initialize ctx */
   setkey_func (ctx, key, sizeof(key));
@@ -357,10 +359,64 @@ _gcry_selftest_helper_ctr (const char *cipher, gcry_cipher_setkey_t setkey_func,
       return "selftest for CTR failed - see syslog for details";
     }
 
-  /* Test parallelized code paths */
+  /* Test bulk encryption with typical IV. */
+  memset(iv, 0x57, blocksize-4);
+  iv[blocksize-1] = 1;
+  iv[blocksize-2] = 0;
+  iv[blocksize-3] = 0;
+  iv[blocksize-4] = 0;
+  memset(iv2, 0x57, blocksize-4);
+  iv2[blocksize-1] = 1;
+  iv2[blocksize-2] = 0;
+  iv2[blocksize-3] = 0;
+  iv2[blocksize-4] = 0;
+
+  for (i = 0; i < blocksize * nblocks; i++)
+    plaintext2[i] = plaintext[i] = i;
+
+  /* Create CTR ciphertext manually.  */
+  for (i = 0; i < blocksize * nblocks; i+=blocksize)
+    {
+      encrypt_one (ctx, &ciphertext[i], iv);
+      for (j = 0; j < blocksize; j++)
+        ciphertext[i+j] ^= plaintext[i+j];
+      for (j = blocksize; j > 0; j--)
+        {
+          iv[j-1]++;
+          if (iv[j-1])
+            break;
+        }
+    }
+
+  bulk_ctr_enc (ctx, iv2, ciphertext2, plaintext2, nblocks);
+
+  if (memcmp (ciphertext2, ciphertext, blocksize * nblocks))
+    {
+      gcry_free (mem);
+#ifdef HAVE_SYSLOG
+      syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+              "%s-CTR-%d test failed (plaintext mismatch, bulk)", cipher,
+              blocksize * 8);
+#endif
+      return "selftest for CTR failed - see syslog for details";
+    }
+  if (memcmp(iv2, iv, blocksize))
+    {
+      gcry_free (mem);
+#ifdef HAVE_SYSLOG
+      syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+              "%s-CTR-%d test failed (IV mismatch, bulk)", cipher,
+              blocksize * 8);
+#endif
+      return "selftest for CTR failed - see syslog for details";
+    }
+
+  /* Test parallelized code paths (check counter overflow handling) */
   for (diff = 0; diff < nblocks; diff++) {
     memset(iv, 0xff, blocksize);
     iv[blocksize-1] -= diff;
+    iv[0] = iv[1] = 0;
+    iv[2] = 0x07;
 
     for (i = 0; i < blocksize * nblocks; i++)
       plaintext[i] = i;
@@ -382,6 +438,8 @@ _gcry_selftest_helper_ctr (const char *cipher, gcry_cipher_setkey_t setkey_func,
     /* Decrypt using bulk CTR and compare result.  */
     memset(iv2, 0xff, blocksize);
     iv2[blocksize-1] -= diff;
+    iv2[0] = iv2[1] = 0;
+    iv2[2] = 0x07;
 
     bulk_ctr_enc (ctx, iv2, plaintext2, ciphertext, nblocks);
 
@@ -389,7 +447,7 @@ _gcry_selftest_helper_ctr (const char *cipher, gcry_cipher_setkey_t setkey_func,
       {
         gcry_free (mem);
 #ifdef HAVE_SYSLOG
-        syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+       fprintf(stderr, "Libgcrypt warning: "
                 "%s-CTR-%d test failed (plaintext mismatch, diff: %d)", cipher,
 		blocksize * 8, diff);
 #endif
@@ -399,7 +457,7 @@ _gcry_selftest_helper_ctr (const char *cipher, gcry_cipher_setkey_t setkey_func,
       {
         gcry_free (mem);
 #ifdef HAVE_SYSLOG
-        syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+       fprintf(stderr, "Libgcrypt warning: "
                 "%s-CTR-%d test failed (IV mismatch, diff: %d)", cipher,
 		blocksize * 8, diff);
 #endif
diff --git a/cipher/serpent-avx2-amd64.S b/cipher/serpent-avx2-amd64.S
index 532361d..3177574 100644
--- a/cipher/serpent-avx2-amd64.S
+++ b/cipher/serpent-avx2-amd64.S
@@ -598,6 +598,9 @@ _gcry_serpent_avx2_ctr_enc:
 	 *	%rcx: iv (big endian, 128bit)
 	 */
 
+	movq 8(%rcx), %rax;
+	bswapq %rax;
+
 	vzeroupper;
 
 	vbroadcasti128 .Lbswap128_mask RIP, RTMP3;
@@ -614,25 +617,25 @@ _gcry_serpent_avx2_ctr_enc:
 	vpshufb RTMP3, RTMP0, RA0; /* +1 ; +0 */
 
 	/* check need for handling 64-bit overflow and carry */
-	cmpq $(0xffffffffffffffff - 16), (%rcx);
+	cmpq $(0xffffffffffffffff - 16), %rax;
 	ja .Lhandle_ctr_carry;
 
 	/* construct IVs */
-	vpsubq RTMP2, RTMP0, RA1; /* +3 ; +2 */
-	vpshufb RTMP3, RA1, RA1;
-	vpsubq RTMP2, RA1, RA2;   /* +5 ; +4 */
-	vpshufb RTMP3, RA2, RA2;
-	vpsubq RTMP2, RA2, RA3;   /* +7 ; +6 */
-	vpshufb RTMP3, RA3, RA3;
-	vpsubq RTMP2, RA3, RB0;   /* +9 ; +8 */
-	vpshufb RTMP3, RB0, RB0;
-	vpsubq RTMP2, RB0, RB1;   /* +11 ; +10 */
-	vpshufb RTMP3, RB1, RB1;
-	vpsubq RTMP2, RB1, RB2;   /* +13 ; +12 */
-	vpshufb RTMP3, RB2, RB2;
-	vpsubq RTMP2, RB2, RB3;   /* +15 ; +14 */
-	vpshufb RTMP3, RB3, RB3;
-	vpsubq RTMP2, RB3, RTMP0; /* +16 */
+	vpsubq RTMP2, RTMP0, RTMP0; /* +3 ; +2 */
+	vpshufb RTMP3, RTMP0, RA1;
+	vpsubq RTMP2, RTMP0, RTMP0; /* +5 ; +4 */
+	vpshufb RTMP3, RTMP0, RA2;
+	vpsubq RTMP2, RTMP0, RTMP0; /* +7 ; +6 */
+	vpshufb RTMP3, RTMP0, RA3;
+	vpsubq RTMP2, RTMP0, RTMP0; /* +9 ; +8 */
+	vpshufb RTMP3, RTMP0, RB0;
+	vpsubq RTMP2, RTMP0, RTMP0; /* +11 ; +10 */
+	vpshufb RTMP3, RTMP0, RB1;
+	vpsubq RTMP2, RTMP0, RTMP0; /* +13 ; +12 */
+	vpshufb RTMP3, RTMP0, RB2;
+	vpsubq RTMP2, RTMP0, RTMP0; /* +15 ; +14 */
+	vpshufb RTMP3, RTMP0, RB3;
+	vpsubq RTMP2, RTMP0, RTMP0; /* +16 */
 	vpshufb RTMP3x, RTMP0x, RTMP0x;
 
 	jmp .Lctr_carry_done;
diff --git a/cipher/serpent.c b/cipher/serpent.c
index 4a24ddd..915cc95 100644
--- a/cipher/serpent.c
+++ b/cipher/serpent.c
@@ -1158,7 +1158,7 @@ _gcry_serpent_cfb_dec(void *context, unsigned char *iv,
 static const char*
 selftest_ctr_128 (void)
 {
-  const int nblocks = 16+1;
+  const int nblocks = 16+8+1;
   const int blocksize = sizeof(serpent_block_t);
   const int context_size = sizeof(serpent_context_t);
 
@@ -1173,7 +1173,7 @@ selftest_ctr_128 (void)
 static const char*
 selftest_cbc_128 (void)
 {
-  const int nblocks = 16+2;
+  const int nblocks = 16+8+2;
   const int blocksize = sizeof(serpent_block_t);
   const int context_size = sizeof(serpent_context_t);
 
@@ -1188,7 +1188,7 @@ selftest_cbc_128 (void)
 static const char*
 selftest_cfb_128 (void)
 {
-  const int nblocks = 16+2;
+  const int nblocks = 16+8+2;
   const int blocksize = sizeof(serpent_block_t);
   const int context_size = sizeof(serpent_context_t);
 

-----------------------------------------------------------------------

Summary of changes:
 cipher/camellia-aesni-avx2-amd64.S |    5 ++-
 cipher/camellia-glue.c             |    6 ++--
 cipher/cipher-selftest.c           |   68 +++++++++++++++++++++++++++++++++---
 cipher/serpent-avx2-amd64.S        |   35 ++++++++++---------
 cipher/serpent.c                   |    6 ++--
 5 files changed, 92 insertions(+), 28 deletions(-)


hooks/post-receive
-- 
The GNU crypto library
http://git.gnupg.org




More information about the Gnupg-commits mailing list