summaryrefslogtreecommitdiff
path: root/crypto/rsa/rsa_sp800_56b_check.c
diff options
context:
space:
mode:
authorNicola Tuveri <nic.tuv@gmail.com>2020-06-16 20:12:13 +0300
committerNicola Tuveri <nic.tuv@gmail.com>2020-06-21 13:45:27 +0300
commitd4bf0d57a84a9bcdeba839b66138949be8221e17 (patch)
tree7a9eeb03f3a029c76bd055f00bed8c6898d30058 /crypto/rsa/rsa_sp800_56b_check.c
parent200ae2ee8e1cec5c9af2ea36298bf6583bcd415d (diff)
downloadopenssl-new-d4bf0d57a84a9bcdeba839b66138949be8221e17.tar.gz
Flag RSA secret BNs as consttime on keygen and checks
<https://github.com/openssl/openssl/pull/11765> switched the default code path for keygen. External testing through TriggerFlow highlighted that in several places we failed (once more!) to set the `BN_FLG_CONSTTIME` flag on critical secret values (either long term or temporary values). This commit tries to make sure that the secret BN values inside the `rsa struct` are always flagged on creation, and that temporary values derived from these secrets are flagged when allocated from a BN_CTX. Acknowledgments --------------- Thanks to @Voker57, @bbbrumley, @sohhas, @cpereida for the [OpenSSL Triggerflow CI] ([paper]) through which this defect was detected and tested, and for providing early feedback to fix the issue! [OpenSSL Triggerflow CI]: https://gitlab.com/nisec/openssl-triggerflow-ci [paper]: https://eprint.iacr.org/2019/366 Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/12167)
Diffstat (limited to 'crypto/rsa/rsa_sp800_56b_check.c')
-rw-r--r--crypto/rsa/rsa_sp800_56b_check.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/crypto/rsa/rsa_sp800_56b_check.c b/crypto/rsa/rsa_sp800_56b_check.c
index df9b7bf054..9840d08285 100644
--- a/crypto/rsa/rsa_sp800_56b_check.c
+++ b/crypto/rsa/rsa_sp800_56b_check.c
@@ -37,7 +37,15 @@ int rsa_check_crt_components(const RSA *rsa, BN_CTX *ctx)
r = BN_CTX_get(ctx);
p1 = BN_CTX_get(ctx);
q1 = BN_CTX_get(ctx);
- ret = (q1 != NULL)
+ if (q1 != NULL) {
+ BN_set_flags(r, BN_FLG_CONSTTIME);
+ BN_set_flags(p1, BN_FLG_CONSTTIME);
+ BN_set_flags(q1, BN_FLG_CONSTTIME);
+ ret = 1;
+ } else {
+ ret = 0;
+ }
+ ret = ret
/* p1 = p -1 */
&& (BN_copy(p1, rsa->p) != NULL)
&& BN_sub_word(p1, 1)
@@ -62,6 +70,7 @@ int rsa_check_crt_components(const RSA *rsa, BN_CTX *ctx)
/* (f) 1 = (qInv . q) mod p */
&& BN_mod_mul(r, rsa->iqmp, rsa->q, rsa->p, ctx)
&& BN_is_one(r);
+ BN_clear(r);
BN_clear(p1);
BN_clear(q1);
BN_CTX_end(ctx);
@@ -138,7 +147,14 @@ int rsa_check_prime_factor(BIGNUM *p, BIGNUM *e, int nbits, BN_CTX *ctx)
BN_CTX_start(ctx);
p1 = BN_CTX_get(ctx);
gcd = BN_CTX_get(ctx);
- ret = (gcd != NULL)
+ if (gcd != NULL) {
+ BN_set_flags(p1, BN_FLG_CONSTTIME);
+ BN_set_flags(gcd, BN_FLG_CONSTTIME);
+ ret = 1;
+ } else {
+ ret = 0;
+ }
+ ret = ret
/* (Step 5d) GCD(p-1, e) = 1 */
&& (BN_copy(p1, p) != NULL)
&& BN_sub_word(p1, 1)
@@ -172,7 +188,18 @@ int rsa_check_private_exponent(const RSA *rsa, int nbits, BN_CTX *ctx)
lcm = BN_CTX_get(ctx);
p1q1 = BN_CTX_get(ctx);
gcd = BN_CTX_get(ctx);
- ret = (gcd != NULL
+ if (gcd != NULL) {
+ BN_set_flags(r, BN_FLG_CONSTTIME);
+ BN_set_flags(p1, BN_FLG_CONSTTIME);
+ BN_set_flags(q1, BN_FLG_CONSTTIME);
+ BN_set_flags(lcm, BN_FLG_CONSTTIME);
+ BN_set_flags(p1q1, BN_FLG_CONSTTIME);
+ BN_set_flags(gcd, BN_FLG_CONSTTIME);
+ ret = 1;
+ } else {
+ ret = 0;
+ }
+ ret = (ret
/* LCM(p - 1, q - 1) */
&& (rsa_get_lcm(ctx, rsa->p, rsa->q, lcm, gcd, p1, q1, p1q1) == 1)
/* (Step 6a) d < LCM(p - 1, q - 1) */
@@ -181,6 +208,7 @@ int rsa_check_private_exponent(const RSA *rsa, int nbits, BN_CTX *ctx)
&& BN_mod_mul(r, rsa->e, rsa->d, lcm, ctx)
&& BN_is_one(r));
+ BN_clear(r);
BN_clear(p1);
BN_clear(q1);
BN_clear(lcm);
@@ -236,7 +264,12 @@ int rsa_check_pminusq_diff(BIGNUM *diff, const BIGNUM *p, const BIGNUM *q,
return (BN_num_bits(diff) > bitlen);
}
-/* return LCM(p-1, q-1) */
+/*
+ * return LCM(p-1, q-1)
+ *
+ * Caller should ensure that lcm, gcd, p1, q1, p1q1 are flagged with
+ * BN_FLG_CONSTTIME.
+ */
int rsa_get_lcm(BN_CTX *ctx, const BIGNUM *p, const BIGNUM *q,
BIGNUM *lcm, BIGNUM *gcd, BIGNUM *p1, BIGNUM *q1,
BIGNUM *p1q1)