From e8c1a52cfab8796d0aed6aead31cc8e12c4b09d3 Mon Sep 17 00:00:00 2001 From: tb <> Date: Wed, 5 Apr 2023 11:30:12 +0000 Subject: Set up the RSA's _method_mod_n before the initial blinding As observed by Bernd Edlinger, the main part of the RSA timing leak that was recently made public is that the initial blinding isn't done with Montgomery exponentiation but rather with plain exponentiation. Pull up the initialization of the cached Montgomery context to ensure we use Montgomery exponentiation. Do this for private_{de,en}crypt(). Interestingly, the latter was fixed in OpenSSL a while ago by Andy Polyakov as part of the "smooth CRT-RSA" addition. If this code was anything but completely insane this would never have been an issue in the first place. But it's libcrypto... ok jsing --- src/lib/libcrypto/rsa/rsa_eay.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'src/lib') diff --git a/src/lib/libcrypto/rsa/rsa_eay.c b/src/lib/libcrypto/rsa/rsa_eay.c index a19201727e..089b8782d5 100644 --- a/src/lib/libcrypto/rsa/rsa_eay.c +++ b/src/lib/libcrypto/rsa/rsa_eay.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rsa_eay.c,v 1.56 2022/12/26 07:18:52 jmc Exp $ */ +/* $OpenBSD: rsa_eay.c,v 1.57 2023/04/05 11:30:12 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -403,6 +403,12 @@ RSA_eay_private_encrypt(int flen, const unsigned char *from, unsigned char *to, goto err; } + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) { + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, + CRYPTO_LOCK_RSA, rsa->n, ctx)) + goto err; + } + if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { blinding = rsa_get_blinding(rsa, &local_blinding, ctx); if (blinding == NULL) { @@ -431,11 +437,6 @@ RSA_eay_private_encrypt(int flen, const unsigned char *from, unsigned char *to, BN_init(&d); BN_with_flags(&d, rsa->d, BN_FLG_CONSTTIME); - if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, - CRYPTO_LOCK_RSA, rsa->n, ctx)) - goto err; - if (!rsa->meth->bn_mod_exp(ret, f, &d, rsa->n, ctx, rsa->_method_mod_n)) { goto err; @@ -521,6 +522,12 @@ RSA_eay_private_decrypt(int flen, const unsigned char *from, unsigned char *to, goto err; } + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) { + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, + CRYPTO_LOCK_RSA, rsa->n, ctx)) + goto err; + } + if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { blinding = rsa_get_blinding(rsa, &local_blinding, ctx); if (blinding == NULL) { @@ -550,11 +557,6 @@ RSA_eay_private_decrypt(int flen, const unsigned char *from, unsigned char *to, BN_init(&d); BN_with_flags(&d, rsa->d, BN_FLG_CONSTTIME); - if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, - CRYPTO_LOCK_RSA, rsa->n, ctx)) - goto err; - if (!rsa->meth->bn_mod_exp(ret, f, &d, rsa->n, ctx, rsa->_method_mod_n)) { goto err; -- cgit v1.2.3-55-g6feb