diff options
author | Brian Smith <brian@briansmith.org> | 2016-03-27 08:42:31 +0300 |
---|---|---|
committer | David Benjamin <davidben@google.com> | 2016-04-19 02:34:46 +0300 |
commit | 86361a391062e02012c92d1eefa20df3deb897f3 (patch) | |
tree | d5aa9138c127b7f1ecd5510e2952f7791a69bb06 /crypto/rsa | |
parent | d035730ac7ebb82fbf1895fea50c29048bb6edb2 (diff) |
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>
Diffstat (limited to 'crypto/rsa')
-rw-r--r-- | crypto/rsa/blinding.c | 77 | ||||
-rw-r--r-- | crypto/rsa/internal.h | 6 | ||||
-rw-r--r-- | crypto/rsa/rsa_impl.c | 11 |
3 files changed, 24 insertions, 70 deletions
diff --git a/crypto/rsa/blinding.c b/crypto/rsa/blinding.c index 776839e5..d9d90c2b 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); - -BN_BLINDING *BN_BLINDING_new(const RSA *rsa, BN_CTX *ctx) { - assert(ctx != NULL); +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(void) { BN_BLINDING *ret = OPENSSL_malloc(sizeof(BN_BLINDING)); if (ret == NULL) { OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); @@ -152,19 +146,6 @@ BN_BLINDING *BN_BLINDING_new(const RSA *rsa, BN_CTX *ctx) { 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 @@ void BN_BLINDING_free(BN_BLINDING *r) { 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 @@ err: 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 @@ int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont, 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 @@ static int bn_blinding_create_param(BN_BLINDING *b, const BN_MONT_CTX *mont, } } 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 @@ static int bn_blinding_create_param(BN_BLINDING *b, const BN_MONT_CTX *mont, 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 ae8cdb7c..c6ea97f0 100644 --- a/crypto/rsa/internal.h +++ b/crypto/rsa/internal.h @@ -87,10 +87,10 @@ int rsa_default_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb); #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 ad8e3f91..3e30d898 100644 --- a/crypto/rsa/rsa_impl.c +++ b/crypto/rsa/rsa_impl.c @@ -244,7 +244,7 @@ static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used, * 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 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, } 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 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, 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; } } |