lkundrak / rpms / hostapd

Forked from rpms/hostapd 4 years ago
Clone

Blame 0001-OpenSSL-Use-constant-time-operations-for-private-big.patch

John W. Linville aeb7fa6
From d42c477cc794163a3757956bbffca5cea000923c Mon Sep 17 00:00:00 2001
John W. Linville aeb7fa6
From: Jouni Malinen <jouni@codeaurora.org>
John W. Linville aeb7fa6
Date: Tue, 26 Feb 2019 11:43:03 +0200
John W. Linville aeb7fa6
Subject: [PATCH 01/14] OpenSSL: Use constant time operations for private
John W. Linville aeb7fa6
 bignums
John W. Linville aeb7fa6
John W. Linville aeb7fa6
This helps in reducing measurable timing differences in operations
John W. Linville aeb7fa6
involving private information. BoringSSL has removed BN_FLG_CONSTTIME
John W. Linville aeb7fa6
and expects specific constant time functions to be called instead, so a
John W. Linville aeb7fa6
bit different approach is needed depending on which library is used.
John W. Linville aeb7fa6
John W. Linville aeb7fa6
The main operation that needs protection against side channel attacks is
John W. Linville aeb7fa6
BN_mod_exp() that depends on private keys (the public key validation
John W. Linville aeb7fa6
step in crypto_dh_derive_secret() is an exception that can use the
John W. Linville aeb7fa6
faster version since it does not depend on private keys).
John W. Linville aeb7fa6
John W. Linville aeb7fa6
crypto_bignum_div() is currently used only in SAE FFC case with not
John W. Linville aeb7fa6
safe-prime groups and only with values that do not depend on private
John W. Linville aeb7fa6
keys, so it is not critical to protect it.
John W. Linville aeb7fa6
John W. Linville aeb7fa6
crypto_bignum_inverse() is currently used only in SAE FFC PWE
John W. Linville aeb7fa6
derivation. The additional protection here is targeting only OpenSSL.
John W. Linville aeb7fa6
BoringSSL may need conversion to using BN_mod_inverse_blinded().
John W. Linville aeb7fa6
John W. Linville aeb7fa6
This is related to CVE-2019-9494 and CVE-2019-9495.
John W. Linville aeb7fa6
John W. Linville aeb7fa6
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
John W. Linville aeb7fa6
---
John W. Linville aeb7fa6
 src/crypto/crypto_openssl.c | 20 +++++++++++++++-----
John W. Linville aeb7fa6
 1 file changed, 15 insertions(+), 5 deletions(-)
John W. Linville aeb7fa6
John W. Linville aeb7fa6
diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c
John W. Linville aeb7fa6
index 9c2ba58..ac53cc8 100644
John W. Linville aeb7fa6
--- a/src/crypto/crypto_openssl.c
John W. Linville aeb7fa6
+++ b/src/crypto/crypto_openssl.c
John W. Linville aeb7fa6
@@ -607,7 +607,8 @@ int crypto_mod_exp(const u8 *base, size_t base_len,
John W. Linville aeb7fa6
 	    bn_result == NULL)
John W. Linville aeb7fa6
 		goto error;
John W. Linville aeb7fa6
 
John W. Linville aeb7fa6
-	if (BN_mod_exp(bn_result, bn_base, bn_exp, bn_modulus, ctx) != 1)
John W. Linville aeb7fa6
+	if (BN_mod_exp_mont_consttime(bn_result, bn_base, bn_exp, bn_modulus,
John W. Linville aeb7fa6
+				      ctx, NULL) != 1)
John W. Linville aeb7fa6
 		goto error;
John W. Linville aeb7fa6
 
John W. Linville aeb7fa6
 	*result_len = BN_bn2bin(bn_result, result);
John W. Linville aeb7fa6
@@ -1360,8 +1361,9 @@ int crypto_bignum_exptmod(const struct crypto_bignum *a,
John W. Linville aeb7fa6
 	bnctx = BN_CTX_new();
John W. Linville aeb7fa6
 	if (bnctx == NULL)
John W. Linville aeb7fa6
 		return -1;
John W. Linville aeb7fa6
-	res = BN_mod_exp((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b,
John W. Linville aeb7fa6
-			 (const BIGNUM *) c, bnctx);
John W. Linville aeb7fa6
+	res = BN_mod_exp_mont_consttime((BIGNUM *) d, (const BIGNUM *) a,
John W. Linville aeb7fa6
+					(const BIGNUM *) b, (const BIGNUM *) c,
John W. Linville aeb7fa6
+					bnctx, NULL);
John W. Linville aeb7fa6
 	BN_CTX_free(bnctx);
John W. Linville aeb7fa6
 
John W. Linville aeb7fa6
 	return res ? 0 : -1;
John W. Linville aeb7fa6
@@ -1380,6 +1382,11 @@ int crypto_bignum_inverse(const struct crypto_bignum *a,
John W. Linville aeb7fa6
 	bnctx = BN_CTX_new();
John W. Linville aeb7fa6
 	if (bnctx == NULL)
John W. Linville aeb7fa6
 		return -1;
John W. Linville aeb7fa6
+#ifdef OPENSSL_IS_BORINGSSL
John W. Linville aeb7fa6
+	/* TODO: use BN_mod_inverse_blinded() ? */
John W. Linville aeb7fa6
+#else /* OPENSSL_IS_BORINGSSL */
John W. Linville aeb7fa6
+	BN_set_flags((BIGNUM *) a, BN_FLG_CONSTTIME);
John W. Linville aeb7fa6
+#endif /* OPENSSL_IS_BORINGSSL */
John W. Linville aeb7fa6
 	res = BN_mod_inverse((BIGNUM *) c, (const BIGNUM *) a,
John W. Linville aeb7fa6
 			     (const BIGNUM *) b, bnctx);
John W. Linville aeb7fa6
 	BN_CTX_free(bnctx);
John W. Linville aeb7fa6
@@ -1413,6 +1420,9 @@ int crypto_bignum_div(const struct crypto_bignum *a,
John W. Linville aeb7fa6
 	bnctx = BN_CTX_new();
John W. Linville aeb7fa6
 	if (bnctx == NULL)
John W. Linville aeb7fa6
 		return -1;
John W. Linville aeb7fa6
+#ifndef OPENSSL_IS_BORINGSSL
John W. Linville aeb7fa6
+	BN_set_flags((BIGNUM *) a, BN_FLG_CONSTTIME);
John W. Linville aeb7fa6
+#endif /* OPENSSL_IS_BORINGSSL */
John W. Linville aeb7fa6
 	res = BN_div((BIGNUM *) c, NULL, (const BIGNUM *) a,
John W. Linville aeb7fa6
 		     (const BIGNUM *) b, bnctx);
John W. Linville aeb7fa6
 	BN_CTX_free(bnctx);
John W. Linville aeb7fa6
@@ -1504,8 +1514,8 @@ int crypto_bignum_legendre(const struct crypto_bignum *a,
John W. Linville aeb7fa6
 	    /* exp = (p-1) / 2 */
John W. Linville aeb7fa6
 	    !BN_sub(exp, (const BIGNUM *) p, BN_value_one()) ||
John W. Linville aeb7fa6
 	    !BN_rshift1(exp, exp) ||
John W. Linville aeb7fa6
-	    !BN_mod_exp(tmp, (const BIGNUM *) a, exp, (const BIGNUM *) p,
John W. Linville aeb7fa6
-			bnctx))
John W. Linville aeb7fa6
+	    !BN_mod_exp_mont_consttime(tmp, (const BIGNUM *) a, exp,
John W. Linville aeb7fa6
+				       (const BIGNUM *) p, bnctx, NULL))
John W. Linville aeb7fa6
 		goto fail;
John W. Linville aeb7fa6
 
John W. Linville aeb7fa6
 	if (BN_is_word(tmp, 1))
John W. Linville aeb7fa6
-- 
John W. Linville aeb7fa6
2.7.4
John W. Linville aeb7fa6