Don't draw entropy during FIPS power-on tests.

Change-Id: I8512c6bfb62f1a83afc8f763d681bf5db3b4ceae
Reviewed-on: https://boringssl-review.googlesource.com/17144
Commit-Queue: Adam Langley <alangley@gmail.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/fipsmodule/bcm.c b/crypto/fipsmodule/bcm.c
index 76fbae3..c6ea796 100644
--- a/crypto/fipsmodule/bcm.c
+++ b/crypto/fipsmodule/bcm.c
@@ -245,8 +245,7 @@
       !set_bignum(&rsa->q, kQ, sizeof(kQ)) ||
       !set_bignum(&rsa->dmp1, kDModPMinusOne, sizeof(kDModPMinusOne)) ||
       !set_bignum(&rsa->dmq1, kDModQMinusOne, sizeof(kDModQMinusOne)) ||
-      !set_bignum(&rsa->iqmp, kQInverseModP, sizeof(kQInverseModP)) ||
-      !RSA_check_fips(rsa)) {
+      !set_bignum(&rsa->iqmp, kQInverseModP, sizeof(kQInverseModP))) {
     RSA_free(rsa);
     return NULL;
   }
@@ -277,8 +276,7 @@
   BIGNUM *d = BN_bin2bn(kD, sizeof(kD), NULL);
   if (ec_key == NULL || qx == NULL || qy == NULL || d == NULL ||
       !EC_KEY_set_public_key_affine_coordinates(ec_key, qx, qy) ||
-      !EC_KEY_set_private_key(ec_key, d) ||
-      !EC_KEY_check_fips(ec_key)) {
+      !EC_KEY_set_private_key(ec_key, d)) {
     EC_KEY_free(ec_key);
     ec_key = NULL;
   }
@@ -460,6 +458,21 @@
       0xd5, 0xa8, 0x66, 0x16, 0xbd, 0x18, 0x3c, 0xf2, 0xaa, 0x7a, 0x2b,
       0x37, 0xf9, 0xab, 0x35, 0x64, 0x15, 0x01, 0x3f, 0xc4,
   };
+  const uint8_t kECDSASigR[32] = {
+      0x67, 0x80, 0xc5, 0xfc, 0x70, 0x27, 0x5e, 0x2c, 0x70, 0x61, 0xa0,
+      0xe7, 0x87, 0x7b, 0xb1, 0x74, 0xde, 0xad, 0xeb, 0x98, 0x87, 0x02,
+      0x7f, 0x3f, 0xa8, 0x36, 0x54, 0x15, 0x8b, 0xa7, 0xf5,
+#if !defined(BORINGSSL_FIPS_BREAK_ECDSA_SIG)
+      0x0c,
+#else
+      0x00,
+#endif
+  };
+  const uint8_t kECDSASigS[32] = {
+      0xa5, 0x93, 0xe0, 0x23, 0x91, 0xe7, 0x4b, 0x8d, 0x77, 0x25, 0xa6,
+      0xba, 0x4d, 0xd9, 0x86, 0x77, 0xda, 0x7d, 0x8f, 0xef, 0xc4, 0x1a,
+      0xf0, 0xcc, 0x81, 0xe5, 0xea, 0x3f, 0xc2, 0x41, 0x7f, 0xd8,
+  };
 
   AES_KEY aes_key;
   uint8_t aes_iv[16];
@@ -572,6 +585,11 @@
 
   /* RSA Sign KAT */
   unsigned sig_len;
+
+  /* Disable blinding for the power-on tests because it's not needed and
+   * triggers an entropy draw. */
+  rsa_key->flags |= RSA_FLAG_NO_BLINDING;
+
   if (!RSA_sign(NID_sha256, kPlaintextSHA256, sizeof(kPlaintextSHA256), output,
                 &sig_len, rsa_key) ||
       !check_test(kRSASignature, output, sizeof(kRSASignature),
@@ -595,15 +613,28 @@
   }
 
   /* ECDSA Sign/Verify PWCT */
+
+  /* The 'k' value for ECDSA is fixed to avoid an entropy draw. */
+  ec_key->fixed_k = BN_new();
+  if (ec_key->fixed_k == NULL ||
+      !BN_set_word(ec_key->fixed_k, 42)) {
+    printf("Out of memory\n");
+    goto err;
+  }
+
   ECDSA_SIG *sig =
       ECDSA_do_sign(kPlaintextSHA256, sizeof(kPlaintextSHA256), ec_key);
-#if defined(BORINGSSL_FIPS_BREAK_ECDSA_SIG)
-  sig->r->d[0] = ~sig->r->d[0];
-#endif
+
+  uint8_t ecdsa_r_bytes[sizeof(kECDSASigR)];
+  uint8_t ecdsa_s_bytes[sizeof(kECDSASigS)];
   if (sig == NULL ||
-      !ECDSA_do_verify(kPlaintextSHA256, sizeof(kPlaintextSHA256), sig,
-                       ec_key)) {
-    printf("ECDSA Sign/Verify power-on PWCT failed.\n");
+      BN_num_bytes(sig->r) != sizeof(ecdsa_r_bytes) ||
+      !BN_bn2bin(sig->r, ecdsa_r_bytes) ||
+      BN_num_bytes(sig->s) != sizeof(ecdsa_s_bytes) ||
+      !BN_bn2bin(sig->s, ecdsa_s_bytes) ||
+      !check_test(kECDSASigR, ecdsa_r_bytes, sizeof(kECDSASigR), "ECDSA R") ||
+      !check_test(kECDSASigS, ecdsa_s_bytes, sizeof(kECDSASigS), "ECDSA S")) {
+    printf("ECDSA KAT failed.\n");
     goto err;
   }
 
diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c
index 67b92a7..acabb06 100644
--- a/crypto/fipsmodule/ec/ec_key.c
+++ b/crypto/fipsmodule/ec/ec_key.c
@@ -152,6 +152,7 @@
   EC_GROUP_free(r->group);
   EC_POINT_free(r->pub_key);
   BN_clear_free(r->priv_key);
+  BN_free(r->fixed_k);
 
   CRYPTO_free_ex_data(g_ec_ex_data_class_bss_get(), r, &r->ex_data);
 
diff --git a/crypto/fipsmodule/ec/internal.h b/crypto/fipsmodule/ec/internal.h
index b86a0f9..d14fec6 100644
--- a/crypto/fipsmodule/ec/internal.h
+++ b/crypto/fipsmodule/ec/internal.h
@@ -235,6 +235,10 @@
   EC_POINT *pub_key;
   BIGNUM *priv_key;
 
+  /* fixed_k may contain a specific value of 'k', to be used in ECDSA signing.
+   * This is only for the FIPS power-on tests. */
+  BIGNUM *fixed_k;
+
   unsigned int enc_flag;
   point_conversion_form_t conv_form;
 
diff --git a/crypto/fipsmodule/ecdsa/ecdsa.c b/crypto/fipsmodule/ecdsa/ecdsa.c
index 37f8223..9e719f2 100644
--- a/crypto/fipsmodule/ecdsa/ecdsa.c
+++ b/crypto/fipsmodule/ecdsa/ecdsa.c
@@ -262,7 +262,11 @@
     /* If possible, we'll include the private key and message digest in the k
      * generation. The |digest| argument is only empty if |ECDSA_sign_setup| is
      * being used. */
-    if (digest_len > 0) {
+    if (eckey->fixed_k != NULL) {
+      if (!BN_copy(k, eckey->fixed_k)) {
+        goto err;
+      }
+    } else if (digest_len > 0) {
       do {
         if (!BN_generate_dsa_nonce(k, order, EC_KEY_get0_private_key(eckey),
                                    digest, digest_len, ctx)) {