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>
diff --git a/crypto/rsa/blinding.c b/crypto/rsa/blinding.c index 1367ff6..272aa35 100644 --- a/crypto/rsa/blinding.c +++ b/crypto/rsa/blinding.c
@@ -185,9 +185,7 @@ 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 @@ 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 @@ } } - 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,