Skip to content

Commit 86361a3

Browse files
briansmithdavidben
authored andcommitted
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 cbf56a5. Change-Id: Ic2fd6980e0d359dcd53772a7c31bdd0267e316b4 Reviewed-on: https://boringssl-review.googlesource.com/7594 Reviewed-by: David Benjamin <davidben@google.com>
1 parent d035730 commit 86361a3

4 files changed

Lines changed: 29 additions & 71 deletions

File tree

crypto/rsa/blinding.c

Lines changed: 12 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@
108108

109109
#include <openssl/rsa.h>
110110

111-
#include <assert.h>
112111
#include <string.h>
113112

114113
#include <openssl/bn.h>
@@ -123,18 +122,13 @@
123122
struct bn_blinding_st {
124123
BIGNUM *A; /* The base blinding factor, Montgomery-encoded. */
125124
BIGNUM *Ai; /* The inverse of the blinding factor, Montgomery-encoded. */
126-
BIGNUM *e;
127125
unsigned counter;
128126
};
129127

130-
static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
131-
const BIGNUM *q, BN_CTX *ctx);
132-
static int bn_blinding_create_param(BN_BLINDING *b, const BN_MONT_CTX *mont,
133-
BN_CTX *ctx);
134-
135-
BN_BLINDING *BN_BLINDING_new(const RSA *rsa, BN_CTX *ctx) {
136-
assert(ctx != NULL);
128+
static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e,
129+
const BN_MONT_CTX *mont, BN_CTX *ctx);
137130

131+
BN_BLINDING *BN_BLINDING_new(void) {
138132
BN_BLINDING *ret = OPENSSL_malloc(sizeof(BN_BLINDING));
139133
if (ret == NULL) {
140134
OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
@@ -152,19 +146,6 @@ BN_BLINDING *BN_BLINDING_new(const RSA *rsa, BN_CTX *ctx) {
152146
goto err;
153147
}
154148

155-
if (rsa->e != NULL) {
156-
ret->e = BN_dup(rsa->e);
157-
if (ret->e == NULL) {
158-
goto err;
159-
}
160-
} else {
161-
ret->e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
162-
if (ret->e == NULL) {
163-
OPENSSL_PUT_ERROR(RSA, RSA_R_NO_PUBLIC_EXPONENT);
164-
goto err;
165-
}
166-
}
167-
168149
/* The blinding values need to be created before this blinding can be used. */
169150
ret->counter = BN_BLINDING_COUNTER - 1;
170151

@@ -182,15 +163,14 @@ void BN_BLINDING_free(BN_BLINDING *r) {
182163

183164
BN_free(r->A);
184165
BN_free(r->Ai);
185-
BN_free(r->e);
186166
OPENSSL_free(r);
187167
}
188168

189-
static int bn_blinding_update(BN_BLINDING *b, const BN_MONT_CTX *mont,
190-
BN_CTX *ctx) {
169+
static int bn_blinding_update(BN_BLINDING *b, const BIGNUM *e,
170+
const BN_MONT_CTX *mont, BN_CTX *ctx) {
191171
if (++b->counter == BN_BLINDING_COUNTER) {
192172
/* re-create blinding parameters */
193-
if (!bn_blinding_create_param(b, mont, ctx)) {
173+
if (!bn_blinding_create_param(b, e, mont, ctx)) {
194174
goto err;
195175
}
196176
b->counter = 0;
@@ -213,12 +193,12 @@ static int bn_blinding_update(BN_BLINDING *b, const BN_MONT_CTX *mont,
213193
return 0;
214194
}
215195

216-
int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BN_MONT_CTX *mont,
217-
BN_CTX *ctx) {
196+
int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BIGNUM *e,
197+
const BN_MONT_CTX *mont, BN_CTX *ctx) {
218198
/* |n| is not Montgomery-encoded and |b->A| is. |BN_mod_mul_montgomery|
219199
* cancels one Montgomery factor, so the resulting value of |n| is unencoded.
220200
*/
221-
if (!bn_blinding_update(b, mont, ctx) ||
201+
if (!bn_blinding_update(b, e, mont, ctx) ||
222202
!BN_mod_mul_montgomery(n, n, b->A, mont, ctx)) {
223203
return 0;
224204
}
@@ -234,8 +214,8 @@ int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont,
234214
return BN_mod_mul_montgomery(n, n, b->Ai, mont, ctx);
235215
}
236216

237-
static int bn_blinding_create_param(BN_BLINDING *b, const BN_MONT_CTX *mont,
238-
BN_CTX *ctx) {
217+
static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e,
218+
const BN_MONT_CTX *mont, BN_CTX *ctx) {
239219
BIGNUM mont_N_consttime;
240220
BN_init(&mont_N_consttime);
241221
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,
273253
}
274254
} while (1);
275255

276-
if (!BN_mod_exp_mont(b->A, b->A, b->e, &mont->N, ctx, mont)) {
256+
if (!BN_mod_exp_mont(b->A, b->A, e, &mont->N, ctx, mont)) {
277257
OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
278258
return 0;
279259
}
@@ -285,36 +265,3 @@ static int bn_blinding_create_param(BN_BLINDING *b, const BN_MONT_CTX *mont,
285265

286266
return 1;
287267
}
288-
289-
static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
290-
const BIGNUM *q, BN_CTX *ctx) {
291-
BIGNUM *ret = NULL, *r0, *r1, *r2;
292-
293-
if (d == NULL || p == NULL || q == NULL) {
294-
return NULL;
295-
}
296-
297-
BN_CTX_start(ctx);
298-
r0 = BN_CTX_get(ctx);
299-
r1 = BN_CTX_get(ctx);
300-
r2 = BN_CTX_get(ctx);
301-
if (r2 == NULL) {
302-
goto err;
303-
}
304-
305-
if (!BN_sub(r1, p, BN_value_one())) {
306-
goto err;
307-
}
308-
if (!BN_sub(r2, q, BN_value_one())) {
309-
goto err;
310-
}
311-
if (!BN_mul(r0, r1, r2, ctx)) {
312-
goto err;
313-
}
314-
315-
ret = BN_mod_inverse(NULL, d, r0, ctx);
316-
317-
err:
318-
BN_CTX_end(ctx);
319-
return ret;
320-
}

crypto/rsa/internal.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@ int rsa_default_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb);
8787
#define RSA_PKCS1_PADDING_SIZE 11
8888

8989

90-
BN_BLINDING *BN_BLINDING_new(const RSA *rsa, BN_CTX *ctx);
90+
BN_BLINDING *BN_BLINDING_new(void);
9191
void BN_BLINDING_free(BN_BLINDING *b);
92-
int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BN_MONT_CTX *mont_ctx,
93-
BN_CTX *ctx);
92+
int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BIGNUM *e,
93+
const BN_MONT_CTX *mont_ctx, BN_CTX *ctx);
9494
int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont_ctx,
9595
BN_CTX *ctx);
9696

crypto/rsa/rsa_impl.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used,
244244
* the arrays by one and use the newly created element. */
245245

246246
CRYPTO_MUTEX_unlock(&rsa->lock);
247-
ret = BN_BLINDING_new(rsa, ctx);
247+
ret = BN_BLINDING_new();
248248
if (ret == NULL) {
249249
return NULL;
250250
}
@@ -557,6 +557,13 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
557557
}
558558

559559
if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) {
560+
/* Keys without public exponents must have blinding explicitly disabled to
561+
* be used. */
562+
if (rsa->e == NULL) {
563+
OPENSSL_PUT_ERROR(RSA, RSA_R_NO_PUBLIC_EXPONENT);
564+
goto err;
565+
}
566+
560567
if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx)) {
561568
OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
562569
goto err;
@@ -567,7 +574,7 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
567574
OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
568575
goto err;
569576
}
570-
if (!BN_BLINDING_convert(f, blinding, rsa->mont_n, ctx)) {
577+
if (!BN_BLINDING_convert(f, blinding, rsa->e, rsa->mont_n, ctx)) {
571578
goto err;
572579
}
573580
}

include/openssl/rsa.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,11 @@ OPENSSL_EXPORT void *RSA_get_ex_data(const RSA *r, int idx);
416416
/* Deprecated and ignored. */
417417
#define RSA_FLAG_CACHE_PRIVATE 4
418418

419-
/* RSA_FLAG_NO_BLINDING disables blinding of private operations. */
419+
/* RSA_FLAG_NO_BLINDING disables blinding of private operations, which is a
420+
* dangerous thing to do. It is deprecated and may be ignored in the future.
421+
*
422+
* This flag must be used if a key without the public exponent |e| is used for
423+
* private key operations; avoid using such keys whenever possible. */
420424
#define RSA_FLAG_NO_BLINDING 8
421425

422426
/* RSA_FLAG_EXT_PKEY is deprecated and ignored. */

0 commit comments

Comments
 (0)