Require the public exponent to be available in RSA blinding.

Require the public exponent to be available unless
|RSA_FLAG_NO_BLINDING| is set on the key. Also, document this.

If the public exponent |e| is not available, then we could compute it
from |p|, |q|, and |d|. However, there's no reasonable situation in
which we'd have |p| or |q| but not |e|; either we have all the CRT
parameters, or we have (e, d, n), or we have only (d, n). The
calculation to compute |e| exposes the private key to risk of side
channel attacks.

Also, it was particularly wasteful to compute |e| for each
|BN_BLINDING| created, instead of just once before the first
|BN_BLINDING| was created.

|BN_BLINDING| now no longer needs to contain a duplicate copy of |e|,
so it is now more space-efficient.

Note that the condition |b->e != NULL| in |bn_blinding_update| was
always true since commit cbf56a5683ddda831ff91c46ea48d1fba545db66.

Change-Id: Ic2fd6980e0d359dcd53772a7c31bdd0267e316b4
Reviewed-on: https://boringssl-review.googlesource.com/7594
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/rsa/blinding.c b/crypto/rsa/blinding.c
index 776839e..d9d90c2 100644
--- a/crypto/rsa/blinding.c
+++ b/crypto/rsa/blinding.c
@@ -108,7 +108,6 @@
 
 #include <openssl/rsa.h>
 
-#include <assert.h>
 #include <string.h>
 
 #include <openssl/bn.h>
@@ -123,18 +122,13 @@
 struct bn_blinding_st {
   BIGNUM *A; /* The base blinding factor, Montgomery-encoded. */
   BIGNUM *Ai; /* The inverse of the blinding factor, Montgomery-encoded. */
-  BIGNUM *e;
   unsigned counter;
 };
 
-static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
-                                  const BIGNUM *q, BN_CTX *ctx);
-static int bn_blinding_create_param(BN_BLINDING *b, const BN_MONT_CTX *mont,
-                                    BN_CTX *ctx);
+static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e,
+                                    const BN_MONT_CTX *mont, BN_CTX *ctx);
 
-BN_BLINDING *BN_BLINDING_new(const RSA *rsa, BN_CTX *ctx) {
-  assert(ctx != NULL);
-
+BN_BLINDING *BN_BLINDING_new(void) {
   BN_BLINDING *ret = OPENSSL_malloc(sizeof(BN_BLINDING));
   if (ret == NULL) {
     OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
@@ -152,19 +146,6 @@
     goto err;
   }
 
-  if (rsa->e != NULL) {
-    ret->e = BN_dup(rsa->e);
-    if (ret->e == NULL) {
-      goto err;
-    }
-  } else {
-    ret->e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
-    if (ret->e == NULL) {
-      OPENSSL_PUT_ERROR(RSA, RSA_R_NO_PUBLIC_EXPONENT);
-      goto err;
-    }
-  }
-
   /* The blinding values need to be created before this blinding can be used. */
   ret->counter = BN_BLINDING_COUNTER - 1;
 
@@ -182,15 +163,14 @@
 
   BN_free(r->A);
   BN_free(r->Ai);
-  BN_free(r->e);
   OPENSSL_free(r);
 }
 
-static int bn_blinding_update(BN_BLINDING *b, const BN_MONT_CTX *mont,
-                              BN_CTX *ctx) {
+static int bn_blinding_update(BN_BLINDING *b, const BIGNUM *e,
+                              const BN_MONT_CTX *mont, BN_CTX *ctx) {
   if (++b->counter == BN_BLINDING_COUNTER) {
     /* re-create blinding parameters */
-    if (!bn_blinding_create_param(b, mont, ctx)) {
+    if (!bn_blinding_create_param(b, e, mont, ctx)) {
       goto err;
     }
     b->counter = 0;
@@ -213,12 +193,12 @@
   return 0;
 }
 
-int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BN_MONT_CTX *mont,
-                        BN_CTX *ctx) {
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BIGNUM *e,
+                        const BN_MONT_CTX *mont, BN_CTX *ctx) {
   /* |n| is not Montgomery-encoded and |b->A| is. |BN_mod_mul_montgomery|
    * cancels one Montgomery factor, so the resulting value of |n| is unencoded.
    */
-  if (!bn_blinding_update(b, mont, ctx) ||
+  if (!bn_blinding_update(b, e, mont, ctx) ||
       !BN_mod_mul_montgomery(n, n, b->A, mont, ctx)) {
     return 0;
   }
@@ -234,8 +214,8 @@
   return BN_mod_mul_montgomery(n, n, b->Ai, mont, ctx);
 }
 
-static int bn_blinding_create_param(BN_BLINDING *b, const BN_MONT_CTX *mont,
-                                    BN_CTX *ctx) {
+static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e,
+                                    const BN_MONT_CTX *mont, BN_CTX *ctx) {
   BIGNUM mont_N_consttime;
   BN_init(&mont_N_consttime);
   BN_with_flags(&mont_N_consttime, &mont->N, BN_FLG_CONSTTIME);
@@ -273,7 +253,7 @@
     }
   } while (1);
 
-  if (!BN_mod_exp_mont(b->A, b->A, b->e, &mont->N, ctx, mont)) {
+  if (!BN_mod_exp_mont(b->A, b->A, e, &mont->N, ctx, mont)) {
     OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
     return 0;
   }
@@ -285,36 +265,3 @@
 
   return 1;
 }
-
-static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
-                                  const BIGNUM *q, BN_CTX *ctx) {
-  BIGNUM *ret = NULL, *r0, *r1, *r2;
-
-  if (d == NULL || p == NULL || q == NULL) {
-    return NULL;
-  }
-
-  BN_CTX_start(ctx);
-  r0 = BN_CTX_get(ctx);
-  r1 = BN_CTX_get(ctx);
-  r2 = BN_CTX_get(ctx);
-  if (r2 == NULL) {
-    goto err;
-  }
-
-  if (!BN_sub(r1, p, BN_value_one())) {
-    goto err;
-  }
-  if (!BN_sub(r2, q, BN_value_one())) {
-    goto err;
-  }
-  if (!BN_mul(r0, r1, r2, ctx)) {
-    goto err;
-  }
-
-  ret = BN_mod_inverse(NULL, d, r0, ctx);
-
-err:
-  BN_CTX_end(ctx);
-  return ret;
-}
diff --git a/crypto/rsa/internal.h b/crypto/rsa/internal.h
index ae8cdb7..c6ea97f 100644
--- a/crypto/rsa/internal.h
+++ b/crypto/rsa/internal.h
@@ -87,10 +87,10 @@
 #define RSA_PKCS1_PADDING_SIZE 11
 
 
-BN_BLINDING *BN_BLINDING_new(const RSA *rsa, BN_CTX *ctx);
+BN_BLINDING *BN_BLINDING_new(void);
 void BN_BLINDING_free(BN_BLINDING *b);
-int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BN_MONT_CTX *mont_ctx,
-                        BN_CTX *ctx);
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BIGNUM *e,
+                        const BN_MONT_CTX *mont_ctx, BN_CTX *ctx);
 int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont_ctx,
                        BN_CTX *ctx);
 
diff --git a/crypto/rsa/rsa_impl.c b/crypto/rsa/rsa_impl.c
index ad8e3f9..3e30d89 100644
--- a/crypto/rsa/rsa_impl.c
+++ b/crypto/rsa/rsa_impl.c
@@ -244,7 +244,7 @@
    * the arrays by one and use the newly created element. */
 
   CRYPTO_MUTEX_unlock(&rsa->lock);
-  ret = BN_BLINDING_new(rsa, ctx);
+  ret = BN_BLINDING_new();
   if (ret == NULL) {
     return NULL;
   }
@@ -557,6 +557,13 @@
   }
 
   if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) {
+    /* Keys without public exponents must have blinding explicitly disabled to
+     * be used. */
+    if (rsa->e == NULL) {
+      OPENSSL_PUT_ERROR(RSA, RSA_R_NO_PUBLIC_EXPONENT);
+      goto err;
+    }
+
     if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx)) {
       OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
       goto err;
@@ -567,7 +574,7 @@
       OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
       goto err;
     }
-    if (!BN_BLINDING_convert(f, blinding, rsa->mont_n, ctx)) {
+    if (!BN_BLINDING_convert(f, blinding, rsa->e, rsa->mont_n, ctx)) {
       goto err;
     }
   }
diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h
index ea42525..83fdf16 100644
--- a/include/openssl/rsa.h
+++ b/include/openssl/rsa.h
@@ -416,7 +416,11 @@
 /* Deprecated and ignored. */
 #define RSA_FLAG_CACHE_PRIVATE 4
 
-/* RSA_FLAG_NO_BLINDING disables blinding of private operations. */
+/* RSA_FLAG_NO_BLINDING disables blinding of private operations, which is a
+ * dangerous thing to do. It is deprecated and may be ignored in the future.
+ *
+ * This flag must be used if a key without the public exponent |e| is used for
+ * private key operations; avoid using such keys whenever possible. */
 #define RSA_FLAG_NO_BLINDING 8
 
 /* RSA_FLAG_EXT_PKEY is deprecated and ignored. */