diff options
author | Vadim Sukhomlinov <sukhomlinov@google.com> | 2021-12-29 15:29:00 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-12-30 04:03:41 +0000 |
commit | a555d36f391600dd4de3798fd14a604cb83b2d42 (patch) | |
tree | fa0b49cc4dd425326db790e2c16a61312999682d /board | |
parent | ae6151720c4f1e4901c957128dbc7e59bbcd220b (diff) | |
download | chrome-ec-a555d36f391600dd4de3798fd14a604cb83b2d42.tar.gz |
cr50: reduce TRNG use during RSA prime checkstabilize-14438.B-cr50_stab
It seems we have relatively high number of devices with slow TRNG,
mostly Octopus and Grunt platforms. To mitigate potential issues reduce
load on TRNG during witness generation in prime number check, relying
on already generated random from DRBG.
BUG=b:211648605
TEST=test/tpm_test/tpm_test.py - checking RSA key gen and that
deterministic key gen is not affected.
Signed-off-by: Vadim Sukhomlinov <sukhomlinov@google.com>
Change-Id: Id661ad4191321b761c25a5c1fc3bda10336feff9
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3361250
Reviewed-by: Vadim Sukhomlinov <sukhomlinov@chromium.org>
Tested-by: Vadim Sukhomlinov <sukhomlinov@chromium.org>
Reviewed-by: Andrey Pronin <apronin@chromium.org>
Commit-Queue: Vadim Sukhomlinov <sukhomlinov@chromium.org>
Auto-Submit: Vadim Sukhomlinov <sukhomlinov@chromium.org>
Diffstat (limited to 'board')
-rw-r--r-- | board/cr50/dcrypto/bn.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/board/cr50/dcrypto/bn.c b/board/cr50/dcrypto/bn.c index a65f496429..9141e5e014 100644 --- a/board/cr50/dcrypto/bn.c +++ b/board/cr50/dcrypto/bn.c @@ -1233,14 +1233,45 @@ static int bn_probable_prime(const struct LITE_BIGNUM *p) return 0; for (i = A.dmax - 1; i >= 0; i--) { - while (BN_DIGIT(&A, i) > BN_DIGIT(p, i)) { - uint64_t rnd = fips_trng_rand32(); + uint32_t digit_a = BN_DIGIT(&A, i); + uint32_t digit_p = BN_DIGIT(p, i); - if (!rand_valid(rnd)) - return 0; - BN_DIGIT(&A, i) = (uint32_t)rnd; + if (digit_a < digit_p) + break; + + if (digit_a == digit_p) + continue; + + /** + * digit_a > digit_p, which means + * 0 =< p < 0xffffffff. Update digit_a such that + * it is less or equal than digit_p in unbiased way. + */ + if (digit_p <= 1) + digit_a &= digit_p; + else { + /** + * 1 < p < 0xffffffff, so + * 2 < p+1 <= 0xffffffff + */ + uint32_t digit_p_1 = digit_p + 1; + /** + * Compute threshold when not a whole + * number of p+1 fits in 32-bit. + */ + uint32_t max_p = + (0xffffffff / digit_p_1) * digit_p_1; + while (digit_a >= max_p) { + uint64_t rnd = fips_trng_rand32(); + + if (!rand_valid(rnd)) + return 0; + digit_a = rnd; + } + digit_a = digit_a % digit_p_1; } - if (BN_DIGIT(&A, i) < BN_DIGIT(p, i)) + BN_DIGIT(&A, i) = digit_a; + if (digit_a < digit_p) break; } |