[git] GCRYPT - branch, LIBGCRYPT-1-6-BRANCH, updated. libgcrypt-1.6.3-8-gb85c8d6

by Werner Koch cvs at cvs.gnupg.org
Fri Sep 4 13:04:20 CEST 2015


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, LIBGCRYPT-1-6-BRANCH has been updated
       via  b85c8d6645039fc9d403791750510e439731d479 (commit)
       via  9f32789ee81c2db90a977ff3b401411507ffba82 (commit)
      from  842535b7ea0a9811405e0feae0e9ffb349ee5360 (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 b85c8d6645039fc9d403791750510e439731d479
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Aug 31 23:13:27 2015 +0200

    rsa: Add verify after sign to avoid Lenstra's CRT attack.
    
    * cipher/rsa.c (rsa_sign): Check the CRT.
    --
    
    Failures in the computation of the CRT (e.g. due faulty hardware) can
    lead to a leak of the private key.  The standard precaution against
    this is to verify the signature after signing.  GnuPG does this itself
    and even has an option to disable this.  However, the low performance
    impact of this extra precaution suggest that it should always be done
    and Libgcrypt is the right place here.  For decryption is not done
    because the application will detect the failure due to garbled
    plaintext and in any case no key derived material will be send to the
    user.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/cipher/rsa.c b/cipher/rsa.c
index 9a8d235..0b98b6a 100644
--- a/cipher/rsa.c
+++ b/cipher/rsa.c
@@ -1112,7 +1112,9 @@ rsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
   struct pk_encoding_ctx ctx;
   gcry_mpi_t data = NULL;
   RSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL, NULL};
+  RSA_public_key pk;
   gcry_mpi_t sig = NULL;
+  gcry_mpi_t result = NULL;
 
   _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN,
                                    rsa_get_nbits (keyparms));
@@ -1148,11 +1150,25 @@ rsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
         }
     }
 
-  /* Do RSA computation and build the result.  */
+  /* Do RSA computation.  */
   sig = mpi_new (0);
   secret (sig, data, &sk);
   if (DBG_CIPHER)
     log_printmpi ("rsa_sign    res", sig);
+
+  /* Check that the created signature is good.  This detects a failure
+     of the CRT algorithm  (Lenstra's attack on RSA's use of the CRT).  */
+  result = mpi_new (0);
+  pk.n = sk.n;
+  pk.e = sk.e;
+  public (result, sig, &pk);
+  if (mpi_cmp (result, data))
+    {
+      rc = GPG_ERR_BAD_SIGNATURE;
+      goto leave;
+    }
+
+  /* Convert the result.  */
   if ((ctx.flags & PUBKEY_FLAG_FIXEDLEN))
     {
       /* We need to make sure to return the correct length to avoid
@@ -1172,6 +1188,7 @@ rsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
 
 
  leave:
+  _gcry_mpi_release (result);
   _gcry_mpi_release (sig);
   _gcry_mpi_release (sk.n);
   _gcry_mpi_release (sk.e);

commit 9f32789ee81c2db90a977ff3b401411507ffba82
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Sep 4 12:32:16 2015 +0200

    w32: Fix alignment problem with AESNI on Windows >= 8
    
    * cipher/cipher-selftest.c (_gcry_cipher_selftest_alloc_ctx): New.
    * cipher/rijndael.c (selftest_basic_128, selftest_basic_192)
    (selftest_basic_256): Allocate context on the heap.
    --
    
    The stack alignment on Windows changed and because ld seems to limit
    stack variables to a 8 byte alignment (we request 16), we get bus
    errors from the selftests if AESNI is in use.
    
    GnuPG-bug-id: 2085
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/cipher/cipher-selftest.c b/cipher/cipher-selftest.c
index bb33d94..0852332 100644
--- a/cipher/cipher-selftest.c
+++ b/cipher/cipher-selftest.c
@@ -44,6 +44,29 @@
 #endif
 
 
+/* Return an allocated buffers of size CONTEXT_SIZE with an alignment
+   of 16.  The caller must free that buffer using the address returned
+   at R_MEM.  Returns NULL and sets ERRNO on failure.  */
+void *
+_gcry_cipher_selftest_alloc_ctx (const int context_size, unsigned char **r_mem)
+{
+  int offs;
+  unsigned int ctx_aligned_size, memsize;
+
+  ctx_aligned_size = context_size + 15;
+  ctx_aligned_size -= ctx_aligned_size & 0xf;
+
+  memsize = ctx_aligned_size + 16;
+
+  *r_mem = xtrycalloc (1, memsize);
+  if (!*r_mem)
+    return NULL;
+
+  offs = (16 - ((uintptr_t)*r_mem & 15)) & 15;
+  return (void*)(*r_mem + offs);
+}
+
+
 /* Run the self-tests for <block cipher>-CBC-<block size>, tests bulk CBC
    decryption.  Returns NULL on success. */
 const char *
diff --git a/cipher/cipher-selftest.h b/cipher/cipher-selftest.h
index 3a0fe98..885c317 100644
--- a/cipher/cipher-selftest.h
+++ b/cipher/cipher-selftest.h
@@ -40,6 +40,11 @@ typedef void (*gcry_cipher_bulk_ctr_enc_t)(void *context, unsigned char *iv,
 					   const void *inbuf_arg,
 					   size_t nblocks);
 
+/* Helper function to allocate an aligned context for selftests.  */
+void *_gcry_cipher_selftest_alloc_ctx (const int context_size,
+                                       unsigned char **r_mem);
+
+
 /* Helper function for bulk CBC decryption selftest */
 const char *
 _gcry_selftest_helper_cbc (const char *cipher, gcry_cipher_setkey_t setkey,
diff --git a/cipher/rijndael.c b/cipher/rijndael.c
index 8019f0a..ac96e7b 100644
--- a/cipher/rijndael.c
+++ b/cipher/rijndael.c
@@ -2338,7 +2338,8 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv,
 static const char*
 selftest_basic_128 (void)
 {
-  RIJNDAEL_context ctx;
+  RIJNDAEL_context *ctx;
+  unsigned char *ctxmem;
   unsigned char scratch[16];
 
   /* The test vectors are from the AES supplied ones; more or less
@@ -2381,11 +2382,21 @@ selftest_basic_128 (void)
     };
 #endif
 
-  rijndael_setkey (&ctx, key_128, sizeof (key_128));
-  rijndael_encrypt (&ctx, scratch, plaintext_128);
+  /* Because gcc/ld can only align the CTX struct on 8 bytes on the
+     stack, we need to allocate that context on the heap.  */
+  ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem);
+  if (!ctx)
+    return "failed to allocate memory";
+
+  rijndael_setkey (ctx, key_128, sizeof (key_128));
+  rijndael_encrypt (ctx, scratch, plaintext_128);
   if (memcmp (scratch, ciphertext_128, sizeof (ciphertext_128)))
-     return "AES-128 test encryption failed.";
-  rijndael_decrypt (&ctx, scratch, scratch);
+    {
+      xfree (ctxmem);
+      return "AES-128 test encryption failed.";
+    }
+  rijndael_decrypt (ctx, scratch, scratch);
+  xfree (ctxmem);
   if (memcmp (scratch, plaintext_128, sizeof (plaintext_128)))
     return "AES-128 test decryption failed.";
 
@@ -2396,7 +2407,8 @@ selftest_basic_128 (void)
 static const char*
 selftest_basic_192 (void)
 {
-  RIJNDAEL_context ctx;
+  RIJNDAEL_context *ctx;
+  unsigned char *ctxmem;
   unsigned char scratch[16];
 
   static unsigned char plaintext_192[16] =
@@ -2416,11 +2428,18 @@ selftest_basic_192 (void)
       0x12,0x13,0x1A,0xC7,0xC5,0x47,0x88,0xAA
     };
 
-  rijndael_setkey (&ctx, key_192, sizeof(key_192));
-  rijndael_encrypt (&ctx, scratch, plaintext_192);
+  ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem);
+  if (!ctx)
+    return "failed to allocate memory";
+  rijndael_setkey (ctx, key_192, sizeof(key_192));
+  rijndael_encrypt (ctx, scratch, plaintext_192);
   if (memcmp (scratch, ciphertext_192, sizeof (ciphertext_192)))
-    return "AES-192 test encryption failed.";
-  rijndael_decrypt (&ctx, scratch, scratch);
+    {
+      xfree (ctxmem);
+      return "AES-192 test encryption failed.";
+    }
+  rijndael_decrypt (ctx, scratch, scratch);
+  xfree (ctxmem);
   if (memcmp (scratch, plaintext_192, sizeof (plaintext_192)))
     return "AES-192 test decryption failed.";
 
@@ -2432,7 +2451,8 @@ selftest_basic_192 (void)
 static const char*
 selftest_basic_256 (void)
 {
-  RIJNDAEL_context ctx;
+  RIJNDAEL_context *ctx;
+  unsigned char *ctxmem;
   unsigned char scratch[16];
 
   static unsigned char plaintext_256[16] =
@@ -2453,11 +2473,18 @@ selftest_basic_256 (void)
       0x9A,0xCF,0x72,0x80,0x86,0x04,0x0A,0xE3
     };
 
-  rijndael_setkey (&ctx, key_256, sizeof(key_256));
-  rijndael_encrypt (&ctx, scratch, plaintext_256);
+  ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem);
+  if (!ctx)
+    return "failed to allocate memory";
+  rijndael_setkey (ctx, key_256, sizeof(key_256));
+  rijndael_encrypt (ctx, scratch, plaintext_256);
   if (memcmp (scratch, ciphertext_256, sizeof (ciphertext_256)))
-    return "AES-256 test encryption failed.";
-  rijndael_decrypt (&ctx, scratch, scratch);
+    {
+      xfree (ctxmem);
+      return "AES-256 test encryption failed.";
+    }
+  rijndael_decrypt (ctx, scratch, scratch);
+  xfree (ctxmem);
   if (memcmp (scratch, plaintext_256, sizeof (plaintext_256)))
     return "AES-256 test decryption failed.";
 

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

Summary of changes:
 cipher/cipher-selftest.c | 23 +++++++++++++++++++
 cipher/cipher-selftest.h |  5 +++++
 cipher/rijndael.c        | 57 +++++++++++++++++++++++++++++++++++-------------
 cipher/rsa.c             | 19 +++++++++++++++-
 4 files changed, 88 insertions(+), 16 deletions(-)


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




More information about the Gnupg-commits mailing list