Fix error handling in |bn_blinding_update|.

The fields of the |bn_blinding_st| are not updated atomically.
Consequently, one field (|A| or |Ai|) might get updated while the
other field (|Ai| or |A|) doesn't get updated, if an error occurs in
the middle of updating. Deal with this by reseting the counter so that
|A| and |Ai| will both get recreated the next time the blinding is
used.

Fix a separate but related issue by resetting the counter to zero after
calling |bn_blinding_create_param| only if |bn_blinding_create_param|
succeeded. Previously, regardless of whether an error occured in
|bn_blinding_create_param|, |b->counter| would get reset to zero. The
consequence of this was that potentially-bad blinding values would get
used 32 times instead of (32 - |b->counter|) times.

Change-Id: I236cdb6120870ef06cba129ed86619f593cbcf3d
Reviewed-on: https://boringssl-review.googlesource.com/7520
Reviewed-by: David Benjamin <davidben@google.com>
This commit is contained in:
Brian Smith 2016-03-20 00:33:11 -10:00 committed by David Benjamin
parent e11988f511
commit 95b9769340

View File

@ -185,9 +185,7 @@ void BN_BLINDING_free(BN_BLINDING *r) {
static int bn_blinding_update(BN_BLINDING *b, BN_CTX *ctx,
const BN_MONT_CTX *mont_ctx) {
int ret = 0;
if (b->A == NULL || b->Ai == NULL) {
if (b->A == NULL || b->Ai == NULL || b->e == NULL) {
OPENSSL_PUT_ERROR(RSA, RSA_R_BN_NOT_INITIALIZED);
goto err;
}
@ -196,11 +194,12 @@ static int bn_blinding_update(BN_BLINDING *b, BN_CTX *ctx,
b->counter = 0;
}
if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL) {
if (++b->counter == BN_BLINDING_COUNTER) {
/* re-create blinding parameters */
if (!bn_blinding_create_param(b, NULL, NULL, ctx, mont_ctx)) {
goto err;
}
b->counter = 0;
} else {
if (!BN_mod_mul(b->A, b->A, b->A, b->mod, ctx)) {
goto err;
@ -210,13 +209,16 @@ static int bn_blinding_update(BN_BLINDING *b, BN_CTX *ctx,
}
}
ret = 1;
return 1;
err:
if (b->counter == BN_BLINDING_COUNTER) {
b->counter = 0;
}
return ret;
/* |A| and |Ai| may be in an inconsistent state so they both need to be
* replaced the next time this blinding is used. Note that this is only
* sufficient because support for |BN_BLINDING_NO_UPDATE| and
* |BN_BLINDING_NO_RECREATE| was previously dropped. */
b->counter = BN_BLINDING_COUNTER - 1;
return 0;
}
int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx,