[git] GCRYPT - branch, LIBGCRYPT-1-7-BRANCH, updated. libgcrypt-1.7.3-30-gacb7003

by Werner Koch cvs at cvs.gnupg.org
Fri Dec 9 15:58:09 CET 2016


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-7-BRANCH has been updated
       via  acb7003a9a6faf5d3c0e7961a6d36e351910bd97 (commit)
       via  a72ce0a1fbb3648d80696885d6a7e78b3029bebc (commit)
       via  d6f84f4fc59235795ae393d8fab0081eb5889120 (commit)
       via  008fd92917547981d3c4dc77fd1e8c242bf4a7ea (commit)
       via  c6b7041bbc11391b7c6b0bf649aa4979ad3d0b52 (commit)
       via  9678a9f3dcbd2944d62f12c63fa27a8fd72b1201 (commit)
       via  71612fd517468c9d25a7f65f081fb88f40904787 (commit)
      from  1f1ab84fd1dea3fee596d3223fe96b154b37aa6f (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 acb7003a9a6faf5d3c0e7961a6d36e351910bd97
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Dec 9 15:55:19 2016 +0100

    Post release updates
    
    --

diff --git a/NEWS b/NEWS
index c49c8c1..ecfa180 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+Noteworthy changes in version 1.7.5 (unreleased)  [C21/A1/R_]
+------------------------------------------------
+
+
 Noteworthy changes in version 1.7.4 (2016-12-09)  [C21/A1/R4]
 ------------------------------------------------
 
diff --git a/configure.ac b/configure.ac
index 5d0844d..267438a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,7 +30,7 @@ min_automake_version="1.14"
 # for the LT versions.
 m4_define(mym4_version_major, [1])
 m4_define(mym4_version_minor, [7])
-m4_define(mym4_version_micro, [4])
+m4_define(mym4_version_micro, [5])
 
 # Below is m4 magic to extract and compute the revision number, the
 # decimalized short revision number, a beta version string, and a flag

commit a72ce0a1fbb3648d80696885d6a7e78b3029bebc
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Dec 9 15:41:34 2016 +0100

    Release 1.7.4.
    
    * configure.ac: Bump LT version to C21/A1/R4.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/NEWS b/NEWS
index cdf1ef4..c49c8c1 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,36 @@
-Noteworthy changes in version 1.7.4 (unreleased)  [C21/A1/R_]
+Noteworthy changes in version 1.7.4 (2016-12-09)  [C21/A1/R4]
 ------------------------------------------------
 
+ * Performance:
+
+   - More ARMv8/AArch32 improvements for AES, GCM, SHA-256, and SHA-1.
+
+   - Add ARMv8/AArch32 assembly implementation for Twofish and
+     Camellia.
+
+   - Add bulk processing implementation for ARMv8/AArch32.
+
+   - Add Stribog OIDs.
+
+   - Improve the DRBG performance and sync the code with the Linux
+     version.
+
+ * Internal changes:
+
+   - When secure memory is requested by the MPI functions or by
+     gcry_xmalloc_secure, they do not anymore lead to a fatal error if
+     the secure memory pool is used up.  Instead new pools are
+     allocated as needed.  These new pools are not protected against
+     being swapped out (mlock can't be used).  However, these days
+     this is considered a minor issue and can easily be mitigated by
+     using encrypted swap space.
+
+ * Bug fixes:
+
+   - Fix GOST 28147 CryptoPro-B S-box.
+
+   - Fix error code handling of mlock calls.
+
 
 Noteworthy changes in version 1.7.3 (2016-08-17)  [C21/A1/R3]
 ------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 7bbf4bd..5d0844d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -56,7 +56,7 @@ AC_INIT([libgcrypt],[mym4_full_version],[http://bugs.gnupg.org])
 #   (No interfaces changed:                   REVISION++)
 LIBGCRYPT_LT_CURRENT=21
 LIBGCRYPT_LT_AGE=1
-LIBGCRYPT_LT_REVISION=3
+LIBGCRYPT_LT_REVISION=4
 
 
 # If the API is changed in an incompatible way: increment the next counter.

commit d6f84f4fc59235795ae393d8fab0081eb5889120
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Dec 9 12:10:54 2016 +0100

    Improve handling of mlock error codes.
    
    * acinclude.m4 (GNUPG_CHECK_MLOCK): Check also for EAGAIN which is a
    legitimate return code and does not indicate a broken mlock().
    * src/secmem.c (lock_pool_pages): Test ERR instead of ERRNO which
    could have been overwritten by cap_from+text et al.
    --
    
      On FreeBSD, if there are not enough free pages, mlock() can return
      EAGAIN, as documented in mlock(2). That doesn't mean that mlock is
      broken. I suspect this same issue also exists on the other BSD's.
    
    Suggested-by: Ruben Kerkhof <ruben at rubenkerkhof.com>
    
    This is (now) also true for Linux.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/acinclude.m4 b/acinclude.m4
index 96be833..90b3cb9 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -242,7 +242,7 @@ int main()
     pool += (pgsize - ((long int)pool % pgsize));
 
     err = mlock( pool, 4096 );
-    if( !err || errno == EPERM )
+    if( !err || errno == EPERM || errno == EGAIN)
         return 0; /* okay */
 
     return 1;  /* hmmm */
diff --git a/src/secmem.c b/src/secmem.c
index 9f228f0..46bbf82 100644
--- a/src/secmem.c
+++ b/src/secmem.c
@@ -282,15 +282,15 @@ lock_pool_pages (void *p, size_t n)
 
   if (err)
     {
-      if (errno != EPERM
-#ifdef EAGAIN	/* OpenBSD returns this */
-	  && errno != EAGAIN
+      if (err != EPERM
+#ifdef EAGAIN	/* BSD and also Linux may return EAGAIN */
+	  && err != EAGAIN
 #endif
 #ifdef ENOSYS	/* Some SCOs return this (function not implemented) */
-	  && errno != ENOSYS
+	  && err != ENOSYS
 #endif
 #ifdef ENOMEM  /* Linux might return this. */
-            && errno != ENOMEM
+            && err != ENOMEM
 #endif
 	  )
 	log_error ("can't lock memory: %s\n", strerror (err));
@@ -341,15 +341,15 @@ lock_pool_pages (void *p, size_t n)
 
   if (err)
     {
-      if (errno != EPERM
-#ifdef EAGAIN	/* OpenBSD returns this. */
-	  && errno != EAGAIN
+      if (err != EPERM
+#ifdef EAGAIN	/* BSD and also Linux may return this. */
+	  && err != EAGAIN
 #endif
 #ifdef ENOSYS	/* Some SCOs return this (function not implemented). */
-	  && errno != ENOSYS
+	  && err != ENOSYS
 #endif
 #ifdef ENOMEM  /* Linux might return this. */
-            && errno != ENOMEM
+            && err != ENOMEM
 #endif
 	  )
 	log_error ("can't lock memory: %s\n", strerror (err));

commit 008fd92917547981d3c4dc77fd1e8c242bf4a7ea
Author: Stephan Mueller <smueller at chronox.de>
Date:   Sat Dec 3 19:18:01 2016 +0100

    random: Eliminate unneeded memcpy invocations in the DRBG.
    
    * random/random-drbg.c (drbg_hash): Remove arg 'outval' and return a
    pointer instead.
    (drbg_instantiate): Reduce size of scratchpad.
    (drbg_hmac_update): Avoid use of scratch buffers for the hash.
    (drbg_hmac_generate, drbg_hash_df): Ditto.
    (drbg_hash_process_addtl): Ditto.
    (drbg_hash_hashgen): Ditto.
    (drbg_hash_generate): Ditto.
    
    --
    The gcry_md_read returns a pointer to the hash which can be directly
    used instead of copying it into a scratch buffer. This eliminates a
    number of memcpy invocations for HMAC and Hash DRBG and reduces the
    memory footprint of the Hash DRBG by the block size of the used hash.
    
    The performance increase is between 1 and 3 MB/s depending on the output
    buffer size.
    
    Signed-off-by: Stephan Mueller <smueller at chronox.de>
    
    ChangeLog entries above written by -wk.

diff --git a/random/random-drbg.c b/random/random-drbg.c
index dc8e8f3..e2fe861 100644
--- a/random/random-drbg.c
+++ b/random/random-drbg.c
@@ -374,9 +374,7 @@ static gpg_err_code_t drbg_hmac_init (drbg_state_t drbg);
 static gpg_err_code_t drbg_hmac_setkey (drbg_state_t drbg,
 					const unsigned char *key);
 static void drbg_hash_fini (drbg_state_t drbg);
-static gpg_err_code_t drbg_hash (drbg_state_t drbg,
-                                 unsigned char *outval,
-                                 const drbg_string_t *buf);
+static byte *drbg_hash (drbg_state_t drbg, const drbg_string_t *buf);
 static gpg_err_code_t drbg_sym_init (drbg_state_t drbg);
 static void drbg_sym_fini (drbg_state_t drbg);
 static gpg_err_code_t drbg_sym_setkey (drbg_state_t drbg,
@@ -1042,24 +1040,21 @@ drbg_hmac_update (drbg_state_t drbg, drbg_string_t *seed, int reseed)
   /* we execute two rounds of V/K massaging */
   for (i = 2; 0 < i; i--)
     {
+      byte *retval;
       /* first round uses 0x0, second 0x1 */
       unsigned char prefix = DRBG_PREFIX0;
       if (1 == i)
 	prefix = DRBG_PREFIX1;
       /* 10.1.2.2 step 1 and 4 -- concatenation and HMAC for key */
       seed2.buf = &prefix;
-      ret = drbg_hash (drbg, drbg->C, &seed1);
-      if (ret)
-	return ret;
-
-      ret = drbg_hmac_setkey (drbg, drbg->C);
+      retval = drbg_hash (drbg, &seed1);
+      ret = drbg_hmac_setkey (drbg, retval);
       if (ret)
 	return ret;
 
       /* 10.1.2.2 step 2 and 5 -- HMAC for V */
-      ret = drbg_hash (drbg, drbg->V, &cipherin);
-      if (ret)
-	return ret;
+      retval = drbg_hash (drbg, &cipherin);
+      memcpy(drbg->V, retval, drbg_blocklen (drbg));
 
       /* 10.1.2.2 step 3 */
       if (!seed || 0 == seed->len)
@@ -1091,9 +1086,8 @@ drbg_hmac_generate (drbg_state_t drbg, unsigned char *buf, unsigned int buflen,
     {
       unsigned int outlen = 0;
       /* 10.1.2.5 step 4.1 */
-      ret = drbg_hash (drbg, drbg->V, &data);
-      if (ret)
-	return ret;
+      byte *retval = drbg_hash (drbg, &data);
+      memcpy(drbg->V, retval, drbg_blocklen (drbg));
       outlen = (drbg_blocklen (drbg) < (buflen - len)) ?
 	drbg_blocklen (drbg) : (buflen - len);
 
@@ -1137,14 +1131,10 @@ drbg_hash_df (drbg_state_t drbg,
               unsigned char *outval, size_t outlen,
               drbg_string_t *entropy)
 {
-  gpg_err_code_t ret = 0;
   size_t len = 0;
   unsigned char input[5];
-  unsigned char *tmp = drbg->scratchpad + drbg_statelen (drbg);
   drbg_string_t data1;
 
-  memset (tmp, 0, drbg_blocklen (drbg));
-
   /* 10.4.1 step 3 */
   input[0] = 1;
   drbg_cpu_to_be32 ((outlen * 8), &input[1]);
@@ -1158,20 +1148,16 @@ drbg_hash_df (drbg_state_t drbg,
     {
       short blocklen = 0;
       /* 10.4.1 step 4.1 */
-      ret = drbg_hash (drbg, tmp, &data1);
-      if (ret)
-	goto out;
+      byte *retval = drbg_hash (drbg, &data1);
       /* 10.4.1 step 4.2 */
       input[0]++;
       blocklen = (drbg_blocklen (drbg) < (outlen - len)) ?
 	drbg_blocklen (drbg) : (outlen - len);
-      memcpy (outval + len, tmp, blocklen);
+      memcpy (outval + len, retval, blocklen);
       len += blocklen;
     }
 
- out:
-  memset (tmp, 0, drbg_blocklen (drbg));
-  return ret;
+  return 0;
 }
 
 /* update function for Hash DRBG as defined in 10.1.1.2 / 10.1.1.3 */
@@ -1227,13 +1213,10 @@ drbg_hash_update (drbg_state_t drbg, drbg_string_t *seed, int reseed)
 static gpg_err_code_t
 drbg_hash_process_addtl (drbg_state_t drbg, drbg_string_t *addtl)
 {
-  gpg_err_code_t ret = 0;
   drbg_string_t data1, data2;
   drbg_string_t *data3;
   unsigned char prefix = DRBG_PREFIX2;
-
-  /* this is value w as per documentation */
-  memset (drbg->scratchpad, 0, drbg_blocklen (drbg));
+  byte *retval;
 
   /* 10.1.1.4 step 2 */
   if (!addtl || 0 == addtl->len)
@@ -1247,37 +1230,25 @@ drbg_hash_process_addtl (drbg_state_t drbg, drbg_string_t *addtl)
   data2.next = data3;
   data3->next = NULL;
   /* 10.1.1.4 step 2a -- cipher invocation */
-  ret = drbg_hash (drbg, drbg->scratchpad, &data1);
-  if (ret)
-    goto out;
+  retval = drbg_hash (drbg, &data1);
 
   /* 10.1.1.4 step 2b */
-  drbg_add_buf (drbg->V, drbg_statelen (drbg),
-		drbg->scratchpad, drbg_blocklen (drbg));
+  drbg_add_buf (drbg->V, drbg_statelen (drbg), retval, drbg_blocklen (drbg));
 
- out:
-  memset (drbg->scratchpad, 0, drbg_blocklen (drbg));
-  return ret;
+  return 0;
 }
 
 /*
  * Hashgen defined in 10.1.1.4
  */
 static gpg_err_code_t
-drbg_hash_hashgen (drbg_state_t drbg,
-                   unsigned char *buf, unsigned int buflen)
+drbg_hash_hashgen (drbg_state_t drbg, unsigned char *buf, unsigned int buflen)
 {
-  gpg_err_code_t ret = 0;
   unsigned int len = 0;
   unsigned char *src = drbg->scratchpad;
-  unsigned char *dst = drbg->scratchpad + drbg_statelen (drbg);
   drbg_string_t data;
   unsigned char prefix = DRBG_PREFIX1;
 
-  /* use the scratchpad as a lookaside buffer */
-  memset (src, 0, drbg_statelen (drbg));
-  memset (dst, 0, drbg_blocklen (drbg));
-
   /* 10.1.1.4 step hashgen 2 */
   memcpy (src, drbg->V, drbg_statelen (drbg));
 
@@ -1286,44 +1257,36 @@ drbg_hash_hashgen (drbg_state_t drbg,
     {
       unsigned int outlen = 0;
       /* 10.1.1.4 step hashgen 4.1 */
-      ret = drbg_hash (drbg, dst, &data);
-      if (ret)
-	goto out;
+      byte *retval = drbg_hash (drbg, &data);
       outlen = (drbg_blocklen (drbg) < (buflen - len)) ?
 	drbg_blocklen (drbg) : (buflen - len);
       /* 10.1.1.4 step hashgen 4.2 */
-      memcpy (buf + len, dst, outlen);
+      memcpy (buf + len, retval, outlen);
       len += outlen;
       /* 10.1.1.4 hashgen step 4.3 */
       if (len < buflen)
 	drbg_add_buf (src, drbg_statelen (drbg), &prefix, 1);
     }
 
- out:
-  memset (drbg->scratchpad, 0,
-	  (drbg_statelen (drbg) + drbg_blocklen (drbg)));
-  return ret;
+  memset (drbg->scratchpad, 0, drbg_statelen (drbg));
+  return 0;
 }
 
 /* Generate function for Hash DRBG as defined in 10.1.1.4  */
 static gpg_err_code_t
-drbg_hash_generate (drbg_state_t drbg,
-			 unsigned char *buf, unsigned int buflen,
-			 drbg_string_t *addtl)
+drbg_hash_generate (drbg_state_t drbg, unsigned char *buf, unsigned int buflen,
+		    drbg_string_t *addtl)
 {
-  gpg_err_code_t ret = 0;
+  gpg_err_code_t ret;
   unsigned char prefix = DRBG_PREFIX3;
   drbg_string_t data1, data2;
+  byte *retval;
   union
   {
     unsigned char req[8];
     u64 req_int;
   } u;
 
-  /*
-   * scratchpad usage: drbg_hash_process_addtl uses the scratchpad, but
-   * fully completes before returning. Thus, we can reuse the scratchpad
-   */
   /* 10.1.1.4 step 2 */
   ret = drbg_hash_process_addtl (drbg, addtl);
   if (ret)
@@ -1334,27 +1297,20 @@ drbg_hash_generate (drbg_state_t drbg,
   if (ret)
     return ret;
 
-  /* this is the value H as documented in 10.1.1.4 */
-  memset (drbg->scratchpad, 0, drbg_blocklen (drbg));
   /* 10.1.1.4 step 4 */
   drbg_string_fill (&data1, &prefix, 1);
   drbg_string_fill (&data2, drbg->V, drbg_statelen (drbg));
   data1.next = &data2;
-  ret = drbg_hash (drbg, drbg->scratchpad, &data1);
-  if (ret)
-    goto out;
+
+  /* this is the value H as documented in 10.1.1.4 */
+  retval = drbg_hash (drbg, &data1);
 
   /* 10.1.1.4 step 5 */
-  drbg_add_buf (drbg->V, drbg_statelen (drbg),
-		     drbg->scratchpad, drbg_blocklen (drbg));
-  drbg_add_buf (drbg->V, drbg_statelen (drbg), drbg->C,
-		     drbg_statelen (drbg));
+  drbg_add_buf (drbg->V, drbg_statelen (drbg), retval, drbg_blocklen (drbg));
+  drbg_add_buf (drbg->V, drbg_statelen (drbg), drbg->C, drbg_statelen (drbg));
   u.req_int = be_bswap64 (drbg->reseed_ctr);
-  drbg_add_buf (drbg->V, drbg_statelen (drbg), u.req,
-		     sizeof (u.req));
+  drbg_add_buf (drbg->V, drbg_statelen (drbg), u.req, sizeof (u.req));
 
- out:
-  memset (drbg->scratchpad, 0, drbg_blocklen (drbg));
   return ret;
 }
 
@@ -1699,7 +1655,7 @@ drbg_instantiate (drbg_state_t drbg,
       drbg_blocklen (drbg) +	/* iv */
       drbg_statelen (drbg) + drbg_blocklen (drbg);	/* temp */
   else
-    sb_size = drbg_statelen (drbg) + drbg_blocklen (drbg);
+    sb_size = drbg_statelen (drbg);
 
   if (0 < sb_size)
     {
@@ -2626,8 +2582,8 @@ drbg_hash_fini (drbg_state_t drbg)
   _gcry_md_close (hd);
 }
 
-static gpg_err_code_t
-drbg_hash (drbg_state_t drbg, unsigned char *outval, const drbg_string_t *buf)
+static byte *
+drbg_hash (drbg_state_t drbg, const drbg_string_t *buf)
 {
   gcry_md_hd_t hd = (gcry_md_hd_t)drbg->priv_data;
 
@@ -2635,9 +2591,7 @@ drbg_hash (drbg_state_t drbg, unsigned char *outval, const drbg_string_t *buf)
   for (; NULL != buf; buf = buf->next)
     _gcry_md_write (hd, buf->buf, buf->len);
   _gcry_md_final (hd);
-  memcpy (outval, _gcry_md_read (hd, drbg->core->backend_cipher),
-	  drbg_blocklen (drbg));
-  return 0;
+  return _gcry_md_read (hd, drbg->core->backend_cipher);
 }
 
 static void

commit c6b7041bbc11391b7c6b0bf649aa4979ad3d0b52
Author: Stephan Mueller <smueller at chronox.de>
Date:   Thu Dec 1 17:15:10 2016 +0100

    random: Add performance improvements for the DRBG.
    
    * random/random-drbg.c (struct drbg_state_ops_s): New function
    pointers 'crypto_init' and 'crypto-fini'.
    (struct drbg_state_s): New fields 'priv_data', 'ctr_handle', and
    'ctr_null'.
    (drbg_hash_init, drbg_hash_fini): New.
    (drbg_hmac_init, drbg_hmac_setkey): New.
    (drbg_sym_fini, drbg_sym_init, drbg_sym_setkey): New.
    (drbg_sym_ctr): New.
    (drbg_ctr_bcc): Set the key.
    (drbg_ctr_df): Ditto.
    (drbg_hmac_update): Ditto.
    (drbg_hmac_generate): Replace drgb_hmac by drbg_hash.
    (drbg_hash_df): Ditto.
    (drbg_hash_process_addtl): Ditto.
    (drbg_hash_hashgen): Ditto.
    (drbg_ctr_update): Rework.
    (drbg_ctr_generate): Rework.
    (drbg_ctr_ops): Init new functions pointers.
    (drbg_uninstantiate): Call fini function.
    (drbg_instantiate): Call init function.
    
    --
    The performance improvements can be categorized as follows:
    
    * Initialize the cipher handle of the backend ciphers once and re-use
      them for subsequent cipher invocations.
    
    * Limit the invocation of setkey to the cases when the key is newly
      created.
    
    * Use the AES CTR mode and rip out the counter maintenance in the DRBG
      code. This allows the use of accelerated CTR AES implementations. To
      use the CTR AES mode, a NULL buffer is created that is used as the
      "plaintext" to the CTR mode, because the DRBG CTR AES operation is the
      result of the encryption of the CTR (i.e. the NULL buffer makes the
      final XOR of the CTR AES mode a noop).
    
    The following timing measurements are made. The measurement do not use a
    precise timing operation and should rather serve as a general hint to
    the performance improvements.
    
     On a Broadwell i7 CPU:
    
    	block size	4096		1024		128		32		16
     aes256 old		28MB/s	27MB/s	19MB/s	11MB/s	6MB/s
     aes128 old		29MB/s	32MB/s	23MB/s	15MB/s	9MB/s
     sha256 old		48MB/s	48MB/s	33MB/s	16MB/s	8MB/s
     hmac sha256 old	15MB/s	15MB/s	10MB/s	5MB/s	2MB/s
    
     aes256 new		180MB/s	169MB/s	93MB/s	37MB/s	20MB/s
     aes128 new		240MB/s	221MB/s	125MB/s	51MB/s	27MB/s
     sha256 new		75MB/s	69MB/s	48MB/s	23MB/s	11MB/s
     hmac sha256 new	37MB/s	34MB/s	21MB/s	8MB/s	4MB/s
    
    Signed-off-by: Stephan Mueller <smueller at chronox.de>
    
    ChnageLog entries above written by -wk

diff --git a/random/random-drbg.c b/random/random-drbg.c
index 9676f0e..dc8e8f3 100644
--- a/random/random-drbg.c
+++ b/random/random-drbg.c
@@ -289,6 +289,8 @@ struct drbg_state_ops_s
   gpg_err_code_t (*generate) (drbg_state_t drbg,
 			      unsigned char *buf, unsigned int buflen,
 			      drbg_string_t *addtl);
+  gpg_err_code_t (*crypto_init) (drbg_state_t drbg);
+  void		 (*crypto_fini) (drbg_state_t drbg);
 };
 
 struct drbg_test_data_s
@@ -309,6 +311,10 @@ struct drbg_state_s
 				 * 10.1.1.1 1c) */
   unsigned char *scratchpad;	/* some memory the DRBG can use for its
 				 * operation -- allocated during init */
+  void *priv_data;		/* Cipher handle */
+  gcry_cipher_hd_t ctr_handle;	/* CTR mode cipher handle */
+#define DRBG_CTR_NULL_LEN 128
+  unsigned char *ctr_null;	/* CTR mode zero buffer */
   int seeded:1;			/* DRBG fully seeded? */
   int pr:1;			/* Prediction resistance enabled? */
   /* Taken from libgcrypt ANSI X9.31 DRNG: We need to keep track of the
@@ -363,14 +369,23 @@ static const struct drbg_core_s drbg_cores[] = {
   {DRBG_CTRAES | DRBG_SYM256, 48, 16, GCRY_CIPHER_AES256}
 };
 
-static gpg_err_code_t drbg_sym (drbg_state_t drbg,
-                                const unsigned char *key,
-                                unsigned char *outval,
-                                const drbg_string_t *buf);
-static gpg_err_code_t drbg_hmac (drbg_state_t drbg,
-                                 const unsigned char *key,
+static gpg_err_code_t drbg_hash_init (drbg_state_t drbg);
+static gpg_err_code_t drbg_hmac_init (drbg_state_t drbg);
+static gpg_err_code_t drbg_hmac_setkey (drbg_state_t drbg,
+					const unsigned char *key);
+static void drbg_hash_fini (drbg_state_t drbg);
+static gpg_err_code_t drbg_hash (drbg_state_t drbg,
                                  unsigned char *outval,
                                  const drbg_string_t *buf);
+static gpg_err_code_t drbg_sym_init (drbg_state_t drbg);
+static void drbg_sym_fini (drbg_state_t drbg);
+static gpg_err_code_t drbg_sym_setkey (drbg_state_t drbg,
+				       const unsigned char *key);
+static gpg_err_code_t drbg_sym (drbg_state_t drbg, unsigned char *outval,
+				const drbg_string_t *buf);
+static gpg_err_code_t drbg_sym_ctr (drbg_state_t drbg,
+			const unsigned char *inbuf, unsigned int inbuflen,
+			unsigned char *outbuf, unsigned int outbuflen);
 
 /******************************************************************
  ******************************************************************
@@ -666,6 +681,10 @@ drbg_ctr_bcc (drbg_state_t drbg,
   /* 10.4.3 step 1 */
   memset (out, 0, drbg_blocklen (drbg));
 
+  ret = drbg_sym_setkey(drbg, key);
+  if (ret)
+    return ret;
+
   /* 10.4.3 step 2 / 4 */
   while (inpos)
     {
@@ -698,7 +717,7 @@ drbg_ctr_bcc (drbg_state_t drbg,
 	    }
 	}
       /* 10.4.3 step 4.2 */
-      ret = drbg_sym (drbg, key, out, &data);
+      ret = drbg_sym (drbg, out, &data);
       if (ret)
 	return ret;
       /* 10.4.3 step 2 */
@@ -839,6 +858,9 @@ drbg_ctr_df (drbg_state_t drbg, unsigned char *df_data,
   /* 10.4.2 step 12: overwriting of outval */
 
   /* 10.4.2 step 13 */
+  ret = drbg_sym_setkey(drbg, temp);
+  if (ret)
+    goto out;
   while (generated_len < bytes_to_return)
     {
       short blocklen = 0;
@@ -846,11 +868,10 @@ drbg_ctr_df (drbg_state_t drbg, unsigned char *df_data,
       /* the truncation of the key length is implicit as the key
        * is only drbg_blocklen in size -- check for the implementation
        * of the cipher function callback */
-      ret = drbg_sym (drbg, temp, X, &cipherin);
+      ret = drbg_sym (drbg, X, &cipherin);
       if (ret)
 	goto out;
-      blocklen = (drbg_blocklen (drbg) <
-		  (bytes_to_return - generated_len)) ?
+      blocklen = (drbg_blocklen (drbg) < (bytes_to_return - generated_len)) ?
 	drbg_blocklen (drbg) : (bytes_to_return - generated_len);
       /* 10.4.2 step 13.2 and 14 */
       memcpy (df_data + generated_len, X, blocklen);
@@ -889,54 +910,51 @@ drbg_ctr_update (drbg_state_t drbg, drbg_string_t *addtl, int reseed)
   unsigned char *temp = drbg->scratchpad;
   unsigned char *df_data = drbg->scratchpad +
     drbg_statelen (drbg) + drbg_blocklen (drbg);
-  unsigned char *temp_p, *df_data_p;	/* pointer to iterate over buffers */
-  unsigned int len = 0;
-  drbg_string_t cipherin;
   unsigned char prefix = DRBG_PREFIX1;
 
   memset (temp, 0, drbg_statelen (drbg) + drbg_blocklen (drbg));
   if (3 > reseed)
     memset (df_data, 0, drbg_statelen (drbg));
 
-  /* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */
-  if (addtl && 0 < addtl->len)
+  if (!reseed)
     {
-      ret =
-	drbg_ctr_df (drbg, df_data, drbg_statelen (drbg), addtl);
+      /*
+       * The DRBG uses the CTR mode of the underlying AES cipher. The
+       * CTR mode increments the counter value after the AES operation
+       * but SP800-90A requires that the counter is incremented before
+       * the AES operation. Hence, we increment it at the time we set
+       * it by one.
+       */
+      drbg_add_buf (drbg->V, drbg_blocklen (drbg), &prefix, 1);
+
+      ret = _gcry_cipher_setkey (drbg->ctr_handle, drbg->C, drbg_keylen (drbg));
       if (ret)
-	goto out;
+        goto out;
     }
 
-  drbg_string_fill (&cipherin, drbg->V, drbg_blocklen (drbg));
-  /* 10.2.1.3.2 step 2 and 3 -- are already covered as we memset(0)
-   * all memory during initialization */
-  while (len < (drbg_statelen (drbg)))
+  /* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */
+  if (addtl && 0 < addtl->len)
     {
-      /* 10.2.1.2 step 2.1 */
-      drbg_add_buf (drbg->V, drbg_blocklen (drbg), &prefix, 1);
-      /* 10.2.1.2 step 2.2 */
-      /* using target of temp + len: 10.2.1.2 step 2.3 and 3 */
-      ret = drbg_sym (drbg, drbg->C, temp + len, &cipherin);
+      ret =
+	drbg_ctr_df (drbg, df_data, drbg_statelen (drbg), addtl);
       if (ret)
 	goto out;
-      /* 10.2.1.2 step 2.3 and 3 */
-      len += drbg_blocklen (drbg);
     }
 
-  /* 10.2.1.2 step 4 */
-  temp_p = temp;
-  df_data_p = df_data;
-  for (len = 0; len < drbg_statelen (drbg); len++)
-    {
-      *temp_p ^= *df_data_p;
-      df_data_p++;
-      temp_p++;
-    }
+  ret = drbg_sym_ctr (drbg, df_data, drbg_statelen(drbg),
+		      temp, drbg_statelen(drbg));
+  if (ret)
+    goto out;
 
   /* 10.2.1.2 step 5 */
-  memcpy (drbg->C, temp, drbg_keylen (drbg));
+  ret = _gcry_cipher_setkey (drbg->ctr_handle, temp, drbg_keylen (drbg));
+  if (ret)
+    goto out;
+
   /* 10.2.1.2 step 6 */
   memcpy (drbg->V, temp + drbg_keylen (drbg), drbg_blocklen (drbg));
+  /* See above: increment counter by one to compensate timing of CTR op */
+  drbg_add_buf (drbg->V, drbg_blocklen (drbg), &prefix, 1);
   ret = 0;
 
  out:
@@ -957,9 +975,6 @@ drbg_ctr_generate (drbg_state_t drbg,
                    drbg_string_t *addtl)
 {
   gpg_err_code_t ret = 0;
-  unsigned int len = 0;
-  drbg_string_t data;
-  unsigned char prefix = DRBG_PREFIX1;
 
   memset (drbg->scratchpad, 0, drbg_blocklen (drbg));
 
@@ -973,24 +988,9 @@ drbg_ctr_generate (drbg_state_t drbg,
     }
 
   /* 10.2.1.5.2 step 4.1 */
-  drbg_add_buf (drbg->V, drbg_blocklen (drbg), &prefix, 1);
-  drbg_string_fill (&data, drbg->V, drbg_blocklen (drbg));
-  while (len < buflen)
-    {
-      unsigned int outlen = 0;
-      /* 10.2.1.5.2 step 4.2 */
-      ret = drbg_sym (drbg, drbg->C, drbg->scratchpad, &data);
-      if (ret)
-	goto out;
-      outlen = (drbg_blocklen (drbg) < (buflen - len)) ?
-	drbg_blocklen (drbg) : (buflen - len);
-      /* 10.2.1.5.2 step 4.3 */
-      memcpy (buf + len, drbg->scratchpad, outlen);
-      len += outlen;
-      /* 10.2.1.5.2 step 6 */
-      if (len < buflen)
-	drbg_add_buf (drbg->V, drbg_blocklen (drbg), &prefix, 1);
-    }
+  ret = drbg_sym_ctr (drbg, drbg->ctr_null, DRBG_CTR_NULL_LEN, buf, buflen);
+  if (ret)
+    goto out;
 
   /* 10.2.1.5.2 step 6 */
   if (addtl)
@@ -998,13 +998,14 @@ drbg_ctr_generate (drbg_state_t drbg,
   ret = drbg_ctr_update (drbg, addtl, 3);
 
  out:
-  memset (drbg->scratchpad, 0, drbg_blocklen (drbg));
   return ret;
 }
 
 static struct drbg_state_ops_s drbg_ctr_ops = {
   drbg_ctr_update,
-  drbg_ctr_generate
+  drbg_ctr_generate,
+  drbg_sym_init,
+  drbg_sym_fini,
 };
 
 /******************************************************************
@@ -1023,6 +1024,9 @@ drbg_hmac_update (drbg_state_t drbg, drbg_string_t *seed, int reseed)
       /* 10.1.2.3 step 2 already implicitly covered with
        * the initial memset(0) of drbg->C */
       memset (drbg->V, 1, drbg_statelen (drbg));
+      ret = drbg_hmac_setkey (drbg, drbg->C);
+      if (ret)
+	return ret;
     }
 
   /* build linked list which implements the concatenation and fill
@@ -1044,12 +1048,16 @@ drbg_hmac_update (drbg_state_t drbg, drbg_string_t *seed, int reseed)
 	prefix = DRBG_PREFIX1;
       /* 10.1.2.2 step 1 and 4 -- concatenation and HMAC for key */
       seed2.buf = &prefix;
-      ret = drbg_hmac (drbg, drbg->C, drbg->C, &seed1);
+      ret = drbg_hash (drbg, drbg->C, &seed1);
+      if (ret)
+	return ret;
+
+      ret = drbg_hmac_setkey (drbg, drbg->C);
       if (ret)
 	return ret;
 
       /* 10.1.2.2 step 2 and 5 -- HMAC for V */
-      ret = drbg_hmac (drbg, drbg->C, drbg->V, &cipherin);
+      ret = drbg_hash (drbg, drbg->V, &cipherin);
       if (ret)
 	return ret;
 
@@ -1083,7 +1091,7 @@ drbg_hmac_generate (drbg_state_t drbg, unsigned char *buf, unsigned int buflen,
     {
       unsigned int outlen = 0;
       /* 10.1.2.5 step 4.1 */
-      ret = drbg_hmac (drbg, drbg->C, drbg->V, &data);
+      ret = drbg_hash (drbg, drbg->V, &data);
       if (ret)
 	return ret;
       outlen = (drbg_blocklen (drbg) < (buflen - len)) ?
@@ -1104,7 +1112,9 @@ drbg_hmac_generate (drbg_state_t drbg, unsigned char *buf, unsigned int buflen,
 
 static struct drbg_state_ops_s drbg_hmac_ops = {
   drbg_hmac_update,
-  drbg_hmac_generate
+  drbg_hmac_generate,
+  drbg_hmac_init,
+  drbg_hash_fini,
 };
 
 /******************************************************************
@@ -1148,7 +1158,7 @@ drbg_hash_df (drbg_state_t drbg,
     {
       short blocklen = 0;
       /* 10.4.1 step 4.1 */
-      ret = drbg_hmac (drbg, NULL, tmp, &data1);
+      ret = drbg_hash (drbg, tmp, &data1);
       if (ret)
 	goto out;
       /* 10.4.1 step 4.2 */
@@ -1237,13 +1247,13 @@ drbg_hash_process_addtl (drbg_state_t drbg, drbg_string_t *addtl)
   data2.next = data3;
   data3->next = NULL;
   /* 10.1.1.4 step 2a -- cipher invocation */
-  ret = drbg_hmac (drbg, NULL, drbg->scratchpad, &data1);
+  ret = drbg_hash (drbg, drbg->scratchpad, &data1);
   if (ret)
     goto out;
 
   /* 10.1.1.4 step 2b */
   drbg_add_buf (drbg->V, drbg_statelen (drbg),
-		     drbg->scratchpad, drbg_blocklen (drbg));
+		drbg->scratchpad, drbg_blocklen (drbg));
 
  out:
   memset (drbg->scratchpad, 0, drbg_blocklen (drbg));
@@ -1276,7 +1286,7 @@ drbg_hash_hashgen (drbg_state_t drbg,
     {
       unsigned int outlen = 0;
       /* 10.1.1.4 step hashgen 4.1 */
-      ret = drbg_hmac (drbg, NULL, dst, &data);
+      ret = drbg_hash (drbg, dst, &data);
       if (ret)
 	goto out;
       outlen = (drbg_blocklen (drbg) < (buflen - len)) ?
@@ -1330,7 +1340,7 @@ drbg_hash_generate (drbg_state_t drbg,
   drbg_string_fill (&data1, &prefix, 1);
   drbg_string_fill (&data2, drbg->V, drbg_statelen (drbg));
   data1.next = &data2;
-  ret = drbg_hmac (drbg, NULL, drbg->scratchpad, &data1);
+  ret = drbg_hash (drbg, drbg->scratchpad, &data1);
   if (ret)
     goto out;
 
@@ -1354,7 +1364,9 @@ drbg_hash_generate (drbg_state_t drbg,
  */
 static struct drbg_state_ops_s drbg_hash_ops = {
   drbg_hash_update,
-  drbg_hash_generate
+  drbg_hash_generate,
+  drbg_hash_init,
+  drbg_hash_fini,
 };
 
 /******************************************************************
@@ -1599,6 +1611,7 @@ drbg_uninstantiate (drbg_state_t drbg)
 {
   if (!drbg)
     return GPG_ERR_INV_ARG;
+  drbg->d_ops->crypto_fini(drbg);
   xfree (drbg->V);
   drbg->V = NULL;
   xfree (drbg->C);
@@ -1666,13 +1679,16 @@ drbg_instantiate (drbg_state_t drbg,
 
   /* 9.1 step 4 is implicit in  drbg_sec_strength */
 
-  /* no allocation of drbg as this is done by the kernel crypto API */
+  ret = drbg->d_ops->crypto_init(drbg);
+  if (ret)
+    goto err;
+
   drbg->V = xcalloc_secure (1, drbg_statelen (drbg));
   if (!drbg->V)
-    goto err;
+    goto fini;
   drbg->C = xcalloc_secure (1, drbg_statelen (drbg));
   if (!drbg->C)
-    goto err;
+    goto fini;
   /* scratchpad is only generated for CTR and Hash */
   if (drbg->core->flags & DRBG_HMAC)
     sb_size = 0;
@@ -1689,19 +1705,21 @@ drbg_instantiate (drbg_state_t drbg,
     {
       drbg->scratchpad = xcalloc_secure (1, sb_size);
       if (!drbg->scratchpad)
-	goto err;
+	goto fini;
     }
   dbg (("DRBG: state allocated with scratchpad size %u bytes\n", sb_size));
 
   /* 9.1 step 6 through 11 */
   ret = drbg_seed (drbg, pers, 0);
   if (ret)
-    goto err;
+    goto fini;
 
   dbg (("DRBG: core %d %s prediction resistance successfully initialized\n",
 	coreref, pr ? "with" : "without"));
   return 0;
 
+ fini:
+  drbg->d_ops->crypto_fini(drbg);
  err:
   drbg_uninstantiate (drbg);
   return ret;
@@ -2563,59 +2581,160 @@ _gcry_rngdrbg_selftest (selftest_report_func_t report)
  ***************************************************************/
 
 static gpg_err_code_t
-drbg_hmac (drbg_state_t drbg, const unsigned char *key,
-		unsigned char *outval, const drbg_string_t *buf)
+drbg_hash_init (drbg_state_t drbg)
 {
+  gcry_md_hd_t hd;
   gpg_error_t err;
+
+  err = _gcry_md_open (&hd, drbg->core->backend_cipher, 0);
+  if (err)
+    return err;
+
+  drbg->priv_data = hd;
+
+  return 0;
+}
+
+static gpg_err_code_t
+drbg_hmac_init (drbg_state_t drbg)
+{
   gcry_md_hd_t hd;
+  gpg_error_t err;
 
-  if (key)
-    {
-      err =
-	_gcry_md_open (&hd, drbg->core->backend_cipher, GCRY_MD_FLAG_HMAC);
-      if (err)
-	return err;
-      err = _gcry_md_setkey (hd, key, drbg_statelen (drbg));
-      if (err)
-	return err;
-    }
-  else
-    {
-      err = _gcry_md_open (&hd, drbg->core->backend_cipher, 0);
-      if (err)
-	return err;
-    }
+  err = _gcry_md_open (&hd, drbg->core->backend_cipher, GCRY_MD_FLAG_HMAC);
+  if (err)
+    return err;
+
+  drbg->priv_data = hd;
+
+  return 0;
+}
+
+static gpg_err_code_t
+drbg_hmac_setkey (drbg_state_t drbg, const unsigned char *key)
+{
+  gcry_md_hd_t hd = (gcry_md_hd_t)drbg->priv_data;
+
+  return _gcry_md_setkey (hd, key, drbg_statelen (drbg));
+}
+
+static void
+drbg_hash_fini (drbg_state_t drbg)
+{
+  gcry_md_hd_t hd = (gcry_md_hd_t)drbg->priv_data;
+
+  _gcry_md_close (hd);
+}
+
+static gpg_err_code_t
+drbg_hash (drbg_state_t drbg, unsigned char *outval, const drbg_string_t *buf)
+{
+  gcry_md_hd_t hd = (gcry_md_hd_t)drbg->priv_data;
+
+  _gcry_md_reset(hd);
   for (; NULL != buf; buf = buf->next)
     _gcry_md_write (hd, buf->buf, buf->len);
   _gcry_md_final (hd);
   memcpy (outval, _gcry_md_read (hd, drbg->core->backend_cipher),
 	  drbg_blocklen (drbg));
-  _gcry_md_close (hd);
   return 0;
 }
 
+static void
+drbg_sym_fini (drbg_state_t drbg)
+{
+  gcry_cipher_hd_t hd = (gcry_cipher_hd_t)drbg->priv_data;
+
+  if (hd)
+    _gcry_cipher_close (hd);
+  if (drbg->ctr_handle)
+    _gcry_cipher_close (drbg->ctr_handle);
+  if (drbg->ctr_null)
+    free(drbg->ctr_null);
+}
+
 static gpg_err_code_t
-drbg_sym (drbg_state_t drbg, const unsigned char *key,
-          unsigned char *outval, const drbg_string_t *buf)
+drbg_sym_init (drbg_state_t drbg)
 {
-  gpg_error_t err;
   gcry_cipher_hd_t hd;
+  gpg_error_t err;
+
+  drbg->ctr_null = calloc(1, DRBG_CTR_NULL_LEN);
+  if (!drbg->ctr_null)
+    return GPG_ERR_ENOMEM;
 
   err = _gcry_cipher_open (&hd, drbg->core->backend_cipher,
-                           GCRY_CIPHER_MODE_ECB, 0);
+			   GCRY_CIPHER_MODE_ECB, 0);
   if (err)
-    return err;
+    {
+      drbg_sym_fini (drbg);
+      return err;
+    }
+  drbg->priv_data = hd;
+
+  err = _gcry_cipher_open (&drbg->ctr_handle, drbg->core->backend_cipher,
+			   GCRY_CIPHER_MODE_CTR, 0);
+  if (err)
+    {
+      drbg_sym_fini (drbg);
+      return err;
+    }
+
+
   if (drbg_blocklen (drbg) !=
       _gcry_cipher_get_algo_blklen (drbg->core->backend_cipher))
-    return -GPG_ERR_NO_ERROR;
+    {
+      drbg_sym_fini (drbg);
+      return -GPG_ERR_NO_ERROR;
+    }
+
+  return 0;
+}
+
+static gpg_err_code_t
+drbg_sym_setkey (drbg_state_t drbg, const unsigned char *key)
+{
+  gcry_cipher_hd_t hd = (gcry_cipher_hd_t)drbg->priv_data;
+
+  return _gcry_cipher_setkey (hd, key, drbg_keylen (drbg));
+}
+
+static gpg_err_code_t
+drbg_sym (drbg_state_t drbg, unsigned char *outval, const drbg_string_t *buf)
+{
+  gcry_cipher_hd_t hd = (gcry_cipher_hd_t)drbg->priv_data;
+
+  _gcry_cipher_reset(hd);
   if (drbg_blocklen (drbg) < buf->len)
     return -GPG_ERR_NO_ERROR;
-  err = _gcry_cipher_setkey (hd, key, drbg_keylen (drbg));
+  /* in is only component */
+  return _gcry_cipher_encrypt (hd, outval, drbg_blocklen (drbg), buf->buf,
+			       buf->len);
+}
+
+static gpg_err_code_t
+drbg_sym_ctr (drbg_state_t drbg,
+	      const unsigned char *inbuf, unsigned int inbuflen,
+	      unsigned char *outbuf, unsigned int outbuflen)
+{
+  gpg_error_t err;
+
+  _gcry_cipher_reset(drbg->ctr_handle);
+  err = _gcry_cipher_setctr(drbg->ctr_handle, drbg->V, drbg_blocklen (drbg));
   if (err)
     return err;
-  /* in is only component */
-  _gcry_cipher_encrypt (hd, outval, drbg_blocklen (drbg), buf->buf,
-			buf->len);
-  _gcry_cipher_close (hd);
-  return 0;
+
+  while (outbuflen)
+    {
+       unsigned int cryptlen = (inbuflen > outbuflen) ? outbuflen : inbuflen;
+
+       err = _gcry_cipher_encrypt (drbg->ctr_handle, outbuf, cryptlen, inbuf,
+				   cryptlen);
+       if (err)
+         return err;
+
+       outbuflen -= cryptlen;
+       outbuf += cryptlen;
+    }
+  return _gcry_cipher_getctr(drbg->ctr_handle, drbg->V, drbg_blocklen (drbg));
 }

commit 9678a9f3dcbd2944d62f12c63fa27a8fd72b1201
Author: Stephan Mueller <smueller at chronox.de>
Date:   Thu Dec 1 17:11:42 2016 +0100

    cipher: New function for reading the counter in CTR mode
    
    * cipher/cipher.c (gcry_cipher_getctr): New.
    --
    The API call allows reading the current counter of the CTR mode. The API
    remains internal to libgcrypt and is not exported to external callers.
    
    Signed-off-by: Stephan Mueller <smueller at chronox.de>
    
    ChangeLog entry above added by -wk

diff --git a/cipher/cipher.c b/cipher/cipher.c
index ff3340f..55853da 100644
--- a/cipher/cipher.c
+++ b/cipher/cipher.c
@@ -1117,6 +1117,16 @@ _gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen)
   return 0;
 }
 
+gpg_err_code_t
+_gcry_cipher_getctr (gcry_cipher_hd_t hd, void *ctr, size_t ctrlen)
+{
+  if (ctr && ctrlen == hd->spec->blocksize)
+    memcpy (ctr, hd->u_ctr.ctr, hd->spec->blocksize);
+  else
+    return GPG_ERR_INV_ARG;
+
+  return 0;
+}
 
 gcry_err_code_t
 _gcry_cipher_authenticate (gcry_cipher_hd_t hd, const void *abuf,
diff --git a/src/gcrypt-int.h b/src/gcrypt-int.h
index d367307..549605b 100644
--- a/src/gcrypt-int.h
+++ b/src/gcrypt-int.h
@@ -88,6 +88,8 @@ gpg_err_code_t _gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag,
                                       size_t taglen);
 gpg_err_code_t _gcry_cipher_setctr (gcry_cipher_hd_t hd,
                                     const void *ctr, size_t ctrlen);
+gpg_err_code_t _gcry_cipher_getctr (gcry_cipher_hd_t hd,
+                                    void *ctr, size_t ctrlen);
 size_t _gcry_cipher_get_algo_keylen (int algo);
 size_t _gcry_cipher_get_algo_blklen (int algo);
 

commit 71612fd517468c9d25a7f65f081fb88f40904787
Author: Stephan Mueller <smueller at chronox.de>
Date:   Sun Nov 27 10:14:21 2016 +0100

    doc: Remove comment that is not applicable any more.
    
    --
    Signed-off-by: Stephan Mueller <smueller at chronox.de>

diff --git a/random/random-drbg.c b/random/random-drbg.c
index f9d11a3..9676f0e 100644
--- a/random/random-drbg.c
+++ b/random/random-drbg.c
@@ -899,8 +899,6 @@ drbg_ctr_update (drbg_state_t drbg, drbg_string_t *addtl, int reseed)
     memset (df_data, 0, drbg_statelen (drbg));
 
   /* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */
-  /* TODO use reseed variable to avoid re-doing DF operation */
-  (void) reseed;
   if (addtl && 0 < addtl->len)
     {
       ret =

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

Summary of changes:
 NEWS                 |  36 ++++-
 acinclude.m4         |   2 +-
 cipher/cipher.c      |  10 ++
 configure.ac         |   4 +-
 random/random-drbg.c | 421 ++++++++++++++++++++++++++++++---------------------
 src/gcrypt-int.h     |   2 +
 src/secmem.c         |  20 +--
 7 files changed, 306 insertions(+), 189 deletions(-)


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




More information about the Gnupg-commits mailing list