summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Sukhomlinov <sukhomlinov@google.com>2021-12-29 15:29:00 -0800
committerCommit Bot <commit-bot@chromium.org>2021-12-30 04:03:41 +0000
commita555d36f391600dd4de3798fd14a604cb83b2d42 (patch)
treefa0b49cc4dd425326db790e2c16a61312999682d
parentae6151720c4f1e4901c957128dbc7e59bbcd220b (diff)
downloadchrome-ec-stabilize-14438.B-cr50_stab.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>
-rw-r--r--board/cr50/dcrypto/bn.c43
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;
}