summaryrefslogtreecommitdiffstats
path: root/crypto/bn/bn_blind.c
diff options
context:
space:
mode:
authorBernd Edlinger <bernd.edlinger@hotmail.de>2023-02-13 17:46:41 +0100
committerTomas Mraz <tomas@openssl.org>2023-04-04 12:16:54 +0200
commita00d757d9ca212994625d1a02c81cc5edd27e13b (patch)
tree11a94e74063f704284978aa1f197fb9a37fbb18b /crypto/bn/bn_blind.c
parent908eaceb62624f5b5c505b286d904bd3a4e8a64a (diff)
Alternative fix for CVE-2022-4304
This is about a timing leak in the topmost limb of the internal result of RSA_private_decrypt, before the padding check. There are in fact at least three bugs together that caused the timing leak: First and probably most important is the fact that the blinding did not use the constant time code path at all when the RSA object was used for a private decrypt, due to the fact that the Montgomery context rsa->_method_mod_n was not set up early enough in rsa_ossl_private_decrypt, when BN_BLINDING_create_param needed it, and that was persisted as blinding->m_ctx, although the RSA object creates the Montgomery context just a bit later. Then the infamous bn_correct_top was used on the secret value right after the blinding was removed. And finally the function BN_bn2binpad did not use the constant-time code path since the BN_FLG_CONSTTIME was not set on the secret value. In order to address the first problem, this patch makes sure that the rsa->_method_mod_n is initialized right before the blinding context. And to fix the second problem, we add a new utility function bn_correct_top_consttime, a const-time variant of bn_correct_top. Together with the fact, that BN_bn2binpad is already constant time if the flag BN_FLG_CONSTTIME is set, this should eliminate the timing oracle completely. In addition the no-asm variant may also have branches that depend on secret values, because the last invocation of bn_sub_words in bn_from_montgomery_word had branches when the function is compiled by certain gcc compiler versions, due to the clumsy coding style. So additionally this patch stream-lined the no-asm C-code in order to avoid branches where possible and improve the resulting code quality. Reviewed-by: Paul Dale <pauli@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/20283)
Diffstat (limited to 'crypto/bn/bn_blind.c')
-rw-r--r--crypto/bn/bn_blind.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/crypto/bn/bn_blind.c b/crypto/bn/bn_blind.c
index 650ffe69d9..7e5a1c52e2 100644
--- a/crypto/bn/bn_blind.c
+++ b/crypto/bn/bn_blind.c
@@ -191,7 +191,8 @@ int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
n->top = (int)(rtop & ~mask) | (ntop & mask);
n->flags |= (BN_FLG_FIXED_TOP & ~mask);
}
- ret = BN_mod_mul_montgomery(n, n, r, b->m_ctx, ctx);
+ ret = bn_mul_mont_fixed_top(n, n, r, b->m_ctx, ctx);
+ bn_correct_top_consttime(n);
} else {
ret = BN_mod_mul(n, n, r, b->mod, ctx);
}