Recast ECDSA nonce hardening as DRBG additional data.

FIPS 186-4 prescribes a particular ECDSA nonce selection algorithm,
implemented by BN_range_range_ex. Recast our nonce hardening mechanism
as additional data to be passed into the RBG during that algorithm.

Change-Id: Ic16a10cd58fd7deb7461f0c109a698ea80faff00
Reviewed-on: https://boringssl-review.googlesource.com/15046
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/bn/random.c b/crypto/bn/random.c
index 428b4c3..55eca80 100644
--- a/crypto/bn/random.c
+++ b/crypto/bn/random.c
@@ -114,11 +114,17 @@
 #include <openssl/mem.h>
 #include <openssl/rand.h>
 #include <openssl/sha.h>
+#include <openssl/type_check.h>
 
 #include "../internal.h"
+#include "../rand/internal.h"
 
 
-int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) {
+static const uint8_t kZeroAdditionalData[32] = {0};
+
+static int bn_rand_with_additional_data(BIGNUM *rnd, int bits, int top,
+                                        int bottom,
+                                        const uint8_t additional_data[32]) {
   uint8_t *buf = NULL;
   int ret = 0, bit, bytes, mask;
 
@@ -153,9 +159,7 @@
   }
 
   /* Make a random number and set the top and bottom bits. */
-  if (!RAND_bytes(buf, bytes)) {
-    goto err;
-  }
+  RAND_bytes_with_additional_data(buf, bytes, additional_data);
 
   if (top != BN_RAND_TOP_ANY) {
     if (top == BN_RAND_TOP_TWO && bits > 1) {
@@ -191,12 +195,18 @@
   return (ret);
 }
 
+int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) {
+  return bn_rand_with_additional_data(rnd, bits, top, bottom,
+                                      kZeroAdditionalData);
+}
+
 int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom) {
   return BN_rand(rnd, bits, top, bottom);
 }
 
-int BN_rand_range_ex(BIGNUM *r, BN_ULONG min_inclusive,
-                     const BIGNUM *max_exclusive) {
+static int bn_rand_range_with_additional_data(
+    BIGNUM *r, BN_ULONG min_inclusive, const BIGNUM *max_exclusive,
+    const uint8_t additional_data[32]) {
   if (BN_cmp_word(max_exclusive, min_inclusive) <= 0) {
     OPENSSL_PUT_ERROR(BN, BN_R_INVALID_RANGE);
     return 0;
@@ -214,7 +224,8 @@
     }
 
     if (/* steps 4 and 5 */
-        !BN_rand(r, n, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY) ||
+        !bn_rand_with_additional_data(r, n, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY,
+                                      additional_data) ||
         /* step 7 */
         !BN_add_word(r, min_inclusive)) {
       return 0;
@@ -228,6 +239,12 @@
   return 1;
 }
 
+int BN_rand_range_ex(BIGNUM *r, BN_ULONG min_inclusive,
+                     const BIGNUM *max_exclusive) {
+  return bn_rand_range_with_additional_data(r, min_inclusive, max_exclusive,
+                                            kZeroAdditionalData);
+}
+
 int BN_rand_range(BIGNUM *r, const BIGNUM *range) {
   return BN_rand_range_ex(r, 0, range);
 }
@@ -239,80 +256,31 @@
 int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv,
                           const uint8_t *message, size_t message_len,
                           BN_CTX *ctx) {
-  SHA512_CTX sha;
-  /* We use 512 bits of random data per iteration to
-   * ensure that we have at least |range| bits of randomness. */
-  uint8_t random_bytes[64];
-  uint8_t digest[SHA512_DIGEST_LENGTH];
-  size_t done, todo, attempt;
-  const unsigned num_k_bytes = BN_num_bytes(range);
-  const unsigned bits_to_mask = (8 - (BN_num_bits(range) % 8)) % 8;
-  uint8_t private_bytes[96];
-  uint8_t *k_bytes = NULL;
-  int ret = 0;
-
-  if (out == NULL) {
-    return 0;
-  }
-
-  if (BN_is_zero(range)) {
-    OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
-    goto err;
-  }
-
-  k_bytes = OPENSSL_malloc(num_k_bytes);
-  if (!k_bytes) {
-    OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
-    goto err;
-  }
-
   /* We copy |priv| into a local buffer to avoid furthur exposing its
    * length. */
-  todo = sizeof(priv->d[0]) * priv->top;
+  uint8_t private_bytes[96];
+  size_t todo = sizeof(priv->d[0]) * priv->top;
   if (todo > sizeof(private_bytes)) {
     /* No reasonable DSA or ECDSA key should have a private key
      * this large and we don't handle this case in order to avoid
      * leaking the length of the private key. */
     OPENSSL_PUT_ERROR(BN, BN_R_PRIVATE_KEY_TOO_LARGE);
-    goto err;
+    return 0;
   }
   OPENSSL_memcpy(private_bytes, priv->d, todo);
   OPENSSL_memset(private_bytes + todo, 0, sizeof(private_bytes) - todo);
 
-  for (attempt = 0;; attempt++) {
-    for (done = 0; done < num_k_bytes;) {
-      if (!RAND_bytes(random_bytes, sizeof(random_bytes))) {
-        goto err;
-      }
-      SHA512_Init(&sha);
-      SHA512_Update(&sha, &attempt, sizeof(attempt));
-      SHA512_Update(&sha, &done, sizeof(done));
-      SHA512_Update(&sha, private_bytes, sizeof(private_bytes));
-      SHA512_Update(&sha, message, message_len);
-      SHA512_Update(&sha, random_bytes, sizeof(random_bytes));
-      SHA512_Final(digest, &sha);
+  /* Pass a SHA256 hash of the private key and message as additional data into
+   * the RBG. This is a hardening measure against entropy failure. */
+  OPENSSL_COMPILE_ASSERT(SHA256_DIGEST_LENGTH == 32,
+                         additional_data_is_different_size_from_sha256);
+  SHA256_CTX sha;
+  uint8_t digest[SHA256_DIGEST_LENGTH];
+  SHA256_Init(&sha);
+  SHA256_Update(&sha, private_bytes, sizeof(private_bytes));
+  SHA256_Update(&sha, message, message_len);
+  SHA256_Final(digest, &sha);
 
-      todo = num_k_bytes - done;
-      if (todo > SHA512_DIGEST_LENGTH) {
-        todo = SHA512_DIGEST_LENGTH;
-      }
-      OPENSSL_memcpy(k_bytes + done, digest, todo);
-      done += todo;
-    }
-
-    k_bytes[0] &= 0xff >> bits_to_mask;
-
-    if (!BN_bin2bn(k_bytes, num_k_bytes, out)) {
-      goto err;
-    }
-    if (BN_cmp(out, range) < 0) {
-      break;
-    }
-  }
-
-  ret = 1;
-
-err:
-  OPENSSL_free(k_bytes);
-  return ret;
+  /* Select a value k from [1, range-1], following FIPS 186-4 appendix B.5.2. */
+  return bn_rand_range_with_additional_data(out, 1, range, digest);
 }