From 355b8d91b23e3ab49e1bad8e0e563bad3baaa079 Mon Sep 17 00:00:00 2001 From: 19909236985 Date: Thu, 24 Dec 2020 19:56:42 +0800 Subject: [PATCH] fix CVE-2019-13377 --- CVE-2019-13377-1.patch | 28 ++++ CVE-2019-13377-2-pre.patch | 246 ++++++++++++++++++++++++++++++++++++ CVE-2019-13377-2-pre1.patch | 43 +++++++ CVE-2019-13377-2.patch | 70 ++++++++++ CVE-2019-13377-3.patch | 66 ++++++++++ CVE-2019-13377-4.patch | 59 +++++++++ CVE-2019-13377-5.patch | 58 +++++++++ CVE-2019-13377-6-pre.patch | 59 +++++++++ CVE-2019-13377-6.patch | 53 ++++++++ wpa_supplicant.spec | 35 +++-- 10 files changed, 707 insertions(+), 10 deletions(-) create mode 100644 CVE-2019-13377-1.patch create mode 100644 CVE-2019-13377-2-pre.patch create mode 100644 CVE-2019-13377-2-pre1.patch create mode 100644 CVE-2019-13377-2.patch create mode 100644 CVE-2019-13377-3.patch create mode 100644 CVE-2019-13377-4.patch create mode 100644 CVE-2019-13377-5.patch create mode 100644 CVE-2019-13377-6-pre.patch create mode 100644 CVE-2019-13377-6.patch diff --git a/CVE-2019-13377-1.patch b/CVE-2019-13377-1.patch new file mode 100644 index 0000000..2df2e1a --- /dev/null +++ b/CVE-2019-13377-1.patch @@ -0,0 +1,28 @@ +From e43f08991f00820c1f711ca254021d5f83b5cd7d Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Thu, 25 Apr 2019 18:52:34 +0300 +Subject: [PATCH 1/6] SAE: Use const_time_memcmp() for pwd_value >= prime + comparison + +This reduces timing and memory access pattern differences for an +operation that could depend on the used password. + +Signed-off-by: Jouni Malinen +(cherry picked from commit 8e14b030e558d23f65d761895c07089404e61cf1) + +diff --git a/src/common/sae.c b/src/common/sae.c +index 72b7954..4741753 100644 +--- a/src/common/sae.c ++++ b/src/common/sae.c +@@ -287,7 +287,7 @@ static int sae_test_pwd_seed_ecc(struct sae_data *sae, const u8 *pwd_seed, + wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value", + pwd_value, sae->tmp->prime_len); + +- if (os_memcmp(pwd_value, prime, sae->tmp->prime_len) >= 0) ++ if (const_time_memcmp(pwd_value, prime, sae->tmp->prime_len) >= 0) + return 0; + + x_cand = crypto_bignum_init_set(pwd_value, sae->tmp->prime_len); +-- +2.23.0 + diff --git a/CVE-2019-13377-2-pre.patch b/CVE-2019-13377-2-pre.patch new file mode 100644 index 0000000..886b097 --- /dev/null +++ b/CVE-2019-13377-2-pre.patch @@ -0,0 +1,246 @@ +From 8b093db2c3f489a74b67f687becf750d24fcf626 Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Sat, 13 Apr 2019 17:30:22 +0300 +Subject: EAP-pwd: Remove unused checks for cofactor > 1 cases + +None of the ECC groups supported in the implementation had a cofactor +greater than 1, so these checks are unreachable and for all cases, the +cofactor is known to be 1. Furthermore, RFC 5931 explicitly disallow use +of ECC groups with cofactor larger than 1, so this checks cannot be +needed for any curve that is compliant with the RFC. + +Remove the unneeded group cofactor checks to simplify the +implementation. +--- + src/eap_common/eap_pwd_common.c | 53 ++--------------------------------------- + src/eap_peer/eap_pwd.c | 23 +++--------------- + src/eap_server/eap_server_pwd.c | 23 ++---------------- + 3 files changed, 7 insertions(+), 92 deletions(-) + +diff --git a/src/eap_common/eap_pwd_common.c b/src/eap_common/eap_pwd_common.c +index ccd3627..cd7cd0f 100644 +--- a/src/eap_common/eap_pwd_common.c ++++ b/src/eap_common/eap_pwd_common.c +@@ -149,7 +149,7 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, + u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_* + * mask */ + size_t primebytelen = 0, primebitlen; +- struct crypto_bignum *x_candidate = NULL, *cofactor = NULL; ++ struct crypto_bignum *x_candidate = NULL; + const struct crypto_bignum *prime; + u8 mask, found_ctr = 0, is_odd = 0; + +@@ -159,21 +159,15 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, + os_memset(x_bin, 0, sizeof(x_bin)); + + prime = crypto_ec_get_prime(grp->group); +- cofactor = crypto_bignum_init(); + grp->pwe = crypto_ec_point_init(grp->group); + tmp1 = crypto_bignum_init(); + pm1 = crypto_bignum_init(); + one = crypto_bignum_init_set((const u8 *) "\x01", 1); +- if (!cofactor || !grp->pwe || !tmp1 || !pm1 || !one) { ++ if ( !grp->pwe || !tmp1 || !pm1 || !one) { + wpa_printf(MSG_INFO, "EAP-pwd: unable to create bignums"); + goto fail; + } + +- if (crypto_ec_cofactor(grp->group, cofactor) < 0) { +- wpa_printf(MSG_INFO, "EAP-pwd: unable to get cofactor for " +- "curve"); +- goto fail; +- } + primebitlen = crypto_ec_prime_len_bits(grp->group); + primebytelen = crypto_ec_prime_len(grp->group); + if ((prfbuf = os_malloc(primebytelen)) == NULL) { +@@ -342,19 +336,6 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, + goto fail; + } + +- if (!crypto_bignum_is_one(cofactor)) { +- /* make sure the point is not in a small sub-group */ +- if (crypto_ec_point_mul(grp->group, grp->pwe, cofactor, +- grp->pwe) != 0) { +- wpa_printf(MSG_INFO, +- "EAP-pwd: cannot multiply generator by order"); +- goto fail; +- } +- if (crypto_ec_point_is_at_infinity(grp->group, grp->pwe)) { +- wpa_printf(MSG_INFO, "EAP-pwd: point is at infinity"); +- goto fail; +- } +- } + wpa_printf(MSG_DEBUG, "EAP-pwd: found a PWE in %02d tries", found_ctr); + + if (0) { +@@ -364,7 +345,6 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, + ret = 1; + } + /* cleanliness and order.... */ +- crypto_bignum_deinit(cofactor, 1); + crypto_bignum_deinit(x_candidate, 1); + crypto_bignum_deinit(pm1, 0); + crypto_bignum_deinit(tmp1, 1); +@@ -491,35 +471,7 @@ struct crypto_ec_point * eap_pwd_get_element(EAP_PWD_group *group, + goto fail; + } + +- cofactor = crypto_bignum_init(); +- if (!cofactor || crypto_ec_cofactor(group->group, cofactor) < 0) { +- wpa_printf(MSG_INFO, +- "EAP-pwd: Unable to get cofactor for curve"); +- goto fail; +- } +- +- if (!crypto_bignum_is_one(cofactor)) { +- struct crypto_ec_point *point; +- int ok = 1; +- +- /* check to ensure peer's element is not in a small sub-group */ +- point = crypto_ec_point_init(group->group); +- if (!point || +- crypto_ec_point_mul(group->group, element, +- cofactor, point) != 0 || +- crypto_ec_point_is_at_infinity(group->group, point)) +- ok = 0; +- crypto_ec_point_deinit(point, 0); +- +- if (!ok) { +- wpa_printf(MSG_INFO, +- "EAP-pwd: Small sub-group check on peer element failed"); +- goto fail; +- } +- } +- + out: +- crypto_bignum_deinit(cofactor, 0); + return element; + fail: + crypto_ec_point_deinit(element, 0); +diff --git a/src/eap_peer/eap_pwd.c b/src/eap_peer/eap_pwd.c +index 8064f3f..1ed00e2 100644 +--- a/src/eap_peer/eap_pwd.c ++++ b/src/eap_peer/eap_pwd.c +@@ -347,7 +347,7 @@ eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data, + const u8 *payload, size_t payload_len) + { + struct crypto_ec_point *K = NULL, *point = NULL; +- struct crypto_bignum *mask = NULL, *cofactor = NULL; ++ struct crypto_bignum *mask = NULL; + const u8 *ptr; + u8 *scalar = NULL, *element = NULL; + size_t prime_len, order_len; +@@ -370,20 +370,14 @@ eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data, + + data->private_value = crypto_bignum_init(); + data->my_element = crypto_ec_point_init(data->grp->group); +- cofactor = crypto_bignum_init(); + data->my_scalar = crypto_bignum_init(); + mask = crypto_bignum_init(); +- if (!data->private_value || !data->my_element || !cofactor || ++ if (!data->private_value || !data->my_element || + !data->my_scalar || !mask) { + wpa_printf(MSG_INFO, "EAP-PWD (peer): scalar allocation fail"); + goto fin; + } + +- if (crypto_ec_cofactor(data->grp->group, cofactor) < 0) { +- wpa_printf(MSG_INFO, "EAP-pwd (peer): unable to get cofactor " +- "for curve"); +- goto fin; +- } + + if (crypto_bignum_rand(data->private_value, + crypto_ec_get_order(data->grp->group)) < 0 || +@@ -470,17 +464,9 @@ eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data, + goto fin; + } + +- /* ensure that the shared key isn't in a small sub-group */ +- if (!crypto_bignum_is_one(cofactor)) { +- if (crypto_ec_point_mul(data->grp->group, K, cofactor, K) < 0) { +- wpa_printf(MSG_INFO, "EAP-PWD (peer): cannot multiply " +- "shared key point by order"); +- goto fin; +- } +- } + + /* +- * This check is strictly speaking just for the case above where ++ * This check is strictly speaking just for the case where + * co-factor > 1 but it was suggested that even though this is probably + * never going to happen it is a simple and safe check "just to be + * sure" so let's be safe. +@@ -529,7 +515,6 @@ fin: + os_free(scalar); + os_free(element); + crypto_bignum_deinit(mask, 1); +- crypto_bignum_deinit(cofactor, 1); + crypto_ec_point_deinit(K, 1); + crypto_ec_point_deinit(point, 1); + if (data->outbuf == NULL) +diff --git a/src/eap_server/eap_server_pwd.c b/src/eap_server/eap_server_pwd.c +index b952b67..aa0f0d8 100644 +--- a/src/eap_server/eap_server_pwd.c ++++ b/src/eap_server/eap_server_pwd.c +@@ -602,7 +602,6 @@ eap_pwd_process_commit_resp(struct eap_sm *sm, struct eap_pwd_data *data, + const u8 *payload, size_t payload_len) + { + const u8 *ptr; +- struct crypto_bignum *cofactor = NULL; + struct crypto_ec_point *K = NULL, *point = NULL; + int res = 0; + size_t prime_len, order_len; +@@ -621,20 +620,14 @@ eap_pwd_process_commit_resp(struct eap_sm *sm, struct eap_pwd_data *data, + } + + data->k = crypto_bignum_init(); +- cofactor = crypto_bignum_init(); + point = crypto_ec_point_init(data->grp->group); + K = crypto_ec_point_init(data->grp->group); +- if (!data->k || !cofactor || !point || !K) { ++ if (!data->k || !point || !K) { + wpa_printf(MSG_INFO, "EAP-PWD (server): peer data allocation " + "fail"); + goto fin; + } + +- if (crypto_ec_cofactor(data->grp->group, cofactor) < 0) { +- wpa_printf(MSG_INFO, "EAP-PWD (server): unable to get " +- "cofactor for curve"); +- goto fin; +- } + + /* element, x then y, followed by scalar */ + ptr = payload; +@@ -666,18 +659,9 @@ eap_pwd_process_commit_resp(struct eap_sm *sm, struct eap_pwd_data *data, + goto fin; + } + +- /* ensure that the shared key isn't in a small sub-group */ +- if (!crypto_bignum_is_one(cofactor)) { +- if (crypto_ec_point_mul(data->grp->group, K, cofactor, +- K) != 0) { +- wpa_printf(MSG_INFO, "EAP-PWD (server): cannot " +- "multiply shared key point by order!\n"); +- goto fin; +- } +- } + + /* +- * This check is strictly speaking just for the case above where ++ * This check is strictly speaking just for the case where + * co-factor > 1 but it was suggested that even though this is probably + * never going to happen it is a simple and safe check "just to be + * sure" so let's be safe. +@@ -697,7 +681,6 @@ eap_pwd_process_commit_resp(struct eap_sm *sm, struct eap_pwd_data *data, + fin: + crypto_ec_point_deinit(K, 1); + crypto_ec_point_deinit(point, 1); +- crypto_bignum_deinit(cofactor, 1); + + if (res) + eap_pwd_state(data, PWD_Confirm_Req); +-- +2.23.0 + diff --git a/CVE-2019-13377-2-pre1.patch b/CVE-2019-13377-2-pre1.patch new file mode 100644 index 0000000..3631686 --- /dev/null +++ b/CVE-2019-13377-2-pre1.patch @@ -0,0 +1,43 @@ +From 92e1b96c26a84e503847bdd22ebadf697c4031ad Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Sat, 13 Apr 2019 17:20:57 +0300 +Subject: EAP-pwd: Disallow ECC groups with a prime under 256 bits + +Based on the SAE implementation guidance update to not allow ECC groups +with a prime that is under 256 bits, reject groups 25, 26, and 27 in +EAP-pwd. + +Signed-off-by: Jouni Malinen +--- + +diff --git a/src/eap_common/eap_pwd_common.c b/src/eap_common/eap_pwd_common.c +index a2dd386..ccd3627 100644 +--- a/src/eap_common/eap_pwd_common.c ++++ b/src/eap_common/eap_pwd_common.c +@@ -84,11 +84,23 @@ static int eap_pwd_kdf(const u8 *key, size_t keylen, const u8 *label, + return 0; + } + ++static int eap_pwd_suitable_group(u16 num) ++{ ++ /* Do not allow ECC groups with prime under 256 bits based on guidance ++ * for the similar design in SAE. */ ++ return num == 19 || num == 20 || num == 21 || ++ num == 28 || num == 29 || num == 30; ++} + EAP_PWD_group * get_eap_pwd_group(u16 num) + { + EAP_PWD_group *grp; + + grp = os_zalloc(sizeof(EAP_PWD_group)); ++ if (!eap_pwd_suitable_group(num)) { ++ wpa_printf(MSG_INFO, "EAP-pwd: unsuitable group %u", num); ++ return NULL; ++ } ++ + if (!grp) + return NULL; + grp->group = crypto_ec_init(num); +-- +2.23.0 + diff --git a/CVE-2019-13377-2.patch b/CVE-2019-13377-2.patch new file mode 100644 index 0000000..d419574 --- /dev/null +++ b/CVE-2019-13377-2.patch @@ -0,0 +1,70 @@ +From 20d7bd83c43fb24c4cf84d3045254d3ee1957166 Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Thu, 25 Apr 2019 19:07:05 +0300 +Subject: [PATCH 2/6] EAP-pwd: Use const_time_memcmp() for pwd_value >= prime + comparison + +This reduces timing and memory access pattern differences for an +operation that could depend on the used password. + +Signed-off-by: Jouni Malinen +(cherry picked from commit 7958223fdcfe82479e6ed71019a84f6d4cbf799c) +--- + src/eap_common/eap_pwd_common.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/src/eap_common/eap_pwd_common.c b/src/eap_common/eap_pwd_common.c +index cd7cd0f..a2aaafe 100644 +--- a/src/eap_common/eap_pwd_common.c ++++ b/src/eap_common/eap_pwd_common.c +@@ -142,6 +142,7 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, + u8 qnr_bin[MAX_ECC_PRIME_LEN]; + u8 qr_or_qnr_bin[MAX_ECC_PRIME_LEN]; + u8 x_bin[MAX_ECC_PRIME_LEN]; ++ u8 prime_bin[MAX_ECC_PRIME_LEN]; + struct crypto_bignum *tmp1 = NULL, *tmp2 = NULL, *pm1 = NULL; + struct crypto_hash *hash; + unsigned char pwe_digest[SHA256_MAC_LEN], *prfbuf = NULL, ctr; +@@ -159,6 +160,11 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, + os_memset(x_bin, 0, sizeof(x_bin)); + + prime = crypto_ec_get_prime(grp->group); ++ primebitlen = crypto_ec_prime_len_bits(grp->group); ++ primebytelen = crypto_ec_prime_len(grp->group); ++ if (crypto_bignum_to_bin(prime, prime_bin, sizeof(prime_bin), ++ primebytelen) < 0) ++ return -1; + grp->pwe = crypto_ec_point_init(grp->group); + tmp1 = crypto_bignum_init(); + pm1 = crypto_bignum_init(); +@@ -168,8 +174,6 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, + goto fail; + } + +- primebitlen = crypto_ec_prime_len_bits(grp->group); +- primebytelen = crypto_ec_prime_len(grp->group); + if ((prfbuf = os_malloc(primebytelen)) == NULL) { + wpa_printf(MSG_INFO, "EAP-pwd: unable to malloc space for prf " + "buffer"); +@@ -235,6 +239,8 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, + if (primebitlen % 8) + buf_shift_right(prfbuf, primebytelen, + 8 - primebitlen % 8); ++ if (const_time_memcmp(prfbuf, prime_bin, primebytelen) >= 0) ++ continue; + + crypto_bignum_deinit(x_candidate, 1); + x_candidate = crypto_bignum_init_set(prfbuf, primebytelen); +@@ -244,9 +250,6 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, + goto fail; + } + +- if (crypto_bignum_cmp(x_candidate, prime) >= 0) +- continue; +- + wpa_hexdump_key(MSG_DEBUG, "EAP-pwd: x_candidate", + prfbuf, primebytelen); + const_time_select_bin(found, x_bin, prfbuf, primebytelen, +-- +2.23.0 + diff --git a/CVE-2019-13377-3.patch b/CVE-2019-13377-3.patch new file mode 100644 index 0000000..07d41ed --- /dev/null +++ b/CVE-2019-13377-3.patch @@ -0,0 +1,66 @@ +From ee34d8cfbd0fbf7ba7429531d4bee1c43b074d8b Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Thu, 25 Apr 2019 19:23:05 +0300 +Subject: [PATCH 3/6] OpenSSL: Use BN_bn2binpad() or BN_bn2bin_padded() if + available + +This converts crypto_bignum_to_bin() to use the OpenSSL/BoringSSL +functions BN_bn2binpad()/BN_bn2bin_padded(), when available, to avoid +differences in runtime and memory access patterns depending on the +leading bytes of the BIGNUM value. + +OpenSSL 1.0.2 and LibreSSL do not include such functions, so those cases +are still using the previous implementation where the BN_num_bytes() +call may result in different memory access pattern. + +Signed-off-by: Jouni Malinen +(cherry picked from commit 1e237903f5b5d3117342daf006c5878cdb45e3d3) +--- + src/crypto/crypto_openssl.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c +index 748a7ad..00b61b9 100644 +--- a/src/crypto/crypto_openssl.c ++++ b/src/crypto/crypto_openssl.c +@@ -1129,14 +1129,27 @@ void crypto_bignum_deinit(struct crypto_bignum *n, int clear) + int crypto_bignum_to_bin(const struct crypto_bignum *a, + u8 *buf, size_t buflen, size_t padlen) + { ++#ifdef OPENSSL_IS_BORINGSSL ++#else /* OPENSSL_IS_BORINGSSL */ ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) ++#else + int num_bytes, offset; ++#endif ++#endif /* OPENSSL_IS_BORINGSSL */ + + if (TEST_FAIL()) + return -1; + + if (padlen > buflen) + return -1; +- ++#ifdef OPENSSL_IS_BORINGSSL ++ if (BN_bn2bin_padded(buf, padlen, (const BIGNUM *) a) == 0) ++ return -1; ++ return padlen; ++#else /* OPENSSL_IS_BORINGSSL */ ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) ++ return BN_bn2binpad((const BIGNUM *) a, buf, padlen); ++#else + num_bytes = BN_num_bytes((const BIGNUM *) a); + if ((size_t) num_bytes > buflen) + return -1; +@@ -1149,6 +1162,8 @@ int crypto_bignum_to_bin(const struct crypto_bignum *a, + BN_bn2bin((const BIGNUM *) a, buf + offset); + + return num_bytes + offset; ++#endif ++#endif /* OPENSSL_IS_BORINGSSL */ + } + + +-- +2.23.0 + diff --git a/CVE-2019-13377-4.patch b/CVE-2019-13377-4.patch new file mode 100644 index 0000000..f685a60 --- /dev/null +++ b/CVE-2019-13377-4.patch @@ -0,0 +1,59 @@ +From a25b48118d75f3c2d7cb1b2c3b4cffb13091a34c Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Mon, 24 Jun 2019 23:01:06 +0300 +Subject: [PATCH 4/6] SAE: Run through prf result processing even if it >= + prime + +This reduces differences in timing and memory access within the +hunting-and-pecking loop for ECC groups that have a prime that is not +close to a power of two (e.g., Brainpool curves). + +Signed-off-by: Jouni Malinen +(cherry picked from commit 147bf7b88a9c231322b5b574263071ca6dbb0503) +--- + src/common/sae.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/src/common/sae.c b/src/common/sae.c +index 4741753..e155a71 100644 +--- a/src/common/sae.c ++++ b/src/common/sae.c +@@ -274,6 +274,8 @@ static int sae_test_pwd_seed_ecc(struct sae_data *sae, const u8 *pwd_seed, + struct crypto_bignum *y_sqr, *x_cand; + int res; + size_t bits; ++ int cmp_prime; ++ unsigned int in_range; + + wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, SHA256_MAC_LEN); + +@@ -287,8 +289,13 @@ static int sae_test_pwd_seed_ecc(struct sae_data *sae, const u8 *pwd_seed, + wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value", + pwd_value, sae->tmp->prime_len); + +- if (const_time_memcmp(pwd_value, prime, sae->tmp->prime_len) >= 0) +- return 0; ++ cmp_prime = const_time_memcmp(pwd_value, prime, sae->tmp->prime_len); ++ /* Create a const_time mask for selection based on prf result ++ * being smaller than prime. */ ++ in_range = const_time_fill_msb((unsigned int) cmp_prime); ++ /* The algorithm description would skip the next steps if ++ * cmp_prime >= 0 (reutnr 0 here), but go through them regardless to ++ * minimize externally observable differences in behavior. */ + + x_cand = crypto_bignum_init_set(pwd_value, sae->tmp->prime_len); + if (!x_cand) +@@ -300,7 +307,9 @@ static int sae_test_pwd_seed_ecc(struct sae_data *sae, const u8 *pwd_seed, + + res = is_quadratic_residue_blind(sae, prime, bits, qr, qnr, y_sqr); + crypto_bignum_deinit(y_sqr, 1); +- return res; ++ if (res < 0) ++ return res; ++ return const_time_select_int(in_range, res, 0); + } + + +-- +2.23.0 + diff --git a/CVE-2019-13377-5.patch b/CVE-2019-13377-5.patch new file mode 100644 index 0000000..dfdf4ac --- /dev/null +++ b/CVE-2019-13377-5.patch @@ -0,0 +1,58 @@ +From 00a6cc73da61b03c146b6c341d0d1e572bcef432 Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Mon, 24 Jun 2019 23:02:51 +0300 +Subject: [PATCH 5/6] EAP-pwd: Run through prf result processing even if it >= + prime + +This reduces differences in timing and memory access within the +hunting-and-pecking loop for ECC groups that have a prime that is not +close to a power of two (e.g., Brainpool curves). + +Signed-off-by: Jouni Malinen +(cherry picked from commit cd803299ca485eb857e37c88f973fccfbb8600e5) + +--- + src/eap_common/eap_pwd_common.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/src/eap_common/eap_pwd_common.c b/src/eap_common/eap_pwd_common.c +index a2aaafe..8e7966e 100644 +--- a/src/eap_common/eap_pwd_common.c ++++ b/src/eap_common/eap_pwd_common.c +@@ -153,6 +153,8 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, + struct crypto_bignum *x_candidate = NULL; + const struct crypto_bignum *prime; + u8 mask, found_ctr = 0, is_odd = 0; ++ int cmp_prime; ++ unsigned int in_range; + + if (grp->pwe) + return -1; +@@ -239,8 +241,13 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, + if (primebitlen % 8) + buf_shift_right(prfbuf, primebytelen, + 8 - primebitlen % 8); +- if (const_time_memcmp(prfbuf, prime_bin, primebytelen) >= 0) +- continue; ++ cmp_prime = const_time_memcmp(prfbuf, prime_bin, primebytelen); ++ /* Create a const_time mask for selection based on prf result ++ * being smaller than prime. */ ++ in_range = const_time_fill_msb((unsigned int) cmp_prime); ++ /* The algorithm description would skip the next steps if ++ * cmp_prime >= 0, but go through them regardless to minimize ++ * externally observable differences in behavior. */ + + crypto_bignum_deinit(x_candidate, 1); + x_candidate = crypto_bignum_init_set(prfbuf, primebytelen); +@@ -308,7 +315,7 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, + goto fail; + mask = const_time_eq(res, check); + found_ctr = const_time_select_u8(found, found_ctr, ctr); +- found |= mask; ++ found |= mask & in_range; + } + if (found == 0) { + wpa_printf(MSG_INFO, +-- +2.23.0 + diff --git a/CVE-2019-13377-6-pre.patch b/CVE-2019-13377-6-pre.patch new file mode 100644 index 0000000..603fab4 --- /dev/null +++ b/CVE-2019-13377-6-pre.patch @@ -0,0 +1,59 @@ +From db54db11aec763b6fc74715c36e0f9de0d65e206 Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Mon, 8 Apr 2019 18:01:07 +0300 +Subject: SAE: Reject unsuitable groups based on REVmd changes + +The rules defining which DH groups are suitable for SAE use were +accepted into IEEE 802.11 REVmd based on this document: +https://mentor.ieee.org/802.11/dcn/19/11-19-0387-02-000m-addressing-some-sae-comments.docx + +Enforce those rules in production builds of wpa_supplicant and hostapd. +CONFIG_TESTING_OPTIONS=y builds can still be used to select any o the +implemented groups to maintain testing coverage. + +Signed-off-by: Jouni Malinen + +--- + src/common/sae.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/src/common/sae.c b/src/common/sae.c +index e155a71..91b6b41 100644 +--- a/src/common/sae.c ++++ b/src/common/sae.c +@@ -17,11 +17,32 @@ + #include "ieee802_11_defs.h" + #include "sae.h" + ++static int sae_suitable_group(int group) ++{ ++#ifdef CONFIG_TESTING_OPTIONS ++ /* Allow all groups for testing purposes in non-production builds. */ ++ return 1; ++#else /* CONFIG_TESTING_OPTIONS */ ++ /* Enforce REVmd rules on which SAE groups are suitable for production ++ * purposes: FFC groups whose prime is >= 3072 bits and ECC groups ++ * defined over a prime field whose prime is >= 256 bits. Furthermore, ++ * ECC groups defined over a characteristic 2 finite field and ECC ++ * groups with a co-factor greater than 1 are not suitable. */ ++ return group == 19 || group == 20 || group == 21 || ++ group == 28 || group == 29 || group == 30 || ++ group == 15 || group == 16 || group == 17 || group == 18; ++#endif /* CONFIG_TESTING_OPTIONS */ ++} + + int sae_set_group(struct sae_data *sae, int group) + { + struct sae_temporary_data *tmp; + ++ if (!sae_suitable_group(group)) { ++ wpa_printf(MSG_DEBUG, "SAE: Reject unsuitable group %d", group); ++ return -1; ++ } ++ + sae_clear_data(sae); + tmp = sae->tmp = os_zalloc(sizeof(*tmp)); + if (tmp == NULL) +-- +2.23.0 + diff --git a/CVE-2019-13377-6.patch b/CVE-2019-13377-6.patch new file mode 100644 index 0000000..7015b0f --- /dev/null +++ b/CVE-2019-13377-6.patch @@ -0,0 +1,53 @@ +From 558518ed63202e5358116ab7e0afd5e85490f2ef Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Sat, 27 Jul 2019 23:19:17 +0300 +Subject: [PATCH 6/6] dragonfly: Disable use of groups using Brainpool curves + +Disable groups that use Brainpool curves for now since they leak more +timing information due to the prime not being close to a power of two. +This removes use of groups 28, 29, and 30 from SAE and EAP-pwd. + +Signed-off-by: Jouni Malinen +(cherry picked from commit 876c5eaa6dae1a87a17603fc489a44c29eedc2e3) + +--- + src/common/sae.c | 7 +++++-- + src/eap_common/eap_pwd_common.c | 3 +-- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/src/common/sae.c b/src/common/sae.c +index 91b6b41..5ef6c4c 100644 +--- a/src/common/sae.c ++++ b/src/common/sae.c +@@ -27,9 +27,12 @@ static int sae_suitable_group(int group) + * purposes: FFC groups whose prime is >= 3072 bits and ECC groups + * defined over a prime field whose prime is >= 256 bits. Furthermore, + * ECC groups defined over a characteristic 2 finite field and ECC +- * groups with a co-factor greater than 1 are not suitable. */ ++ * groups with a co-factor greater than 1 are not suitable. Disable ++ * groups that use Brainpool curves as well for now since they leak more ++ * timing information due to the prime not being close to a power of ++ * two. */ ++ + return group == 19 || group == 20 || group == 21 || +- group == 28 || group == 29 || group == 30 || + group == 15 || group == 16 || group == 17 || group == 18; + #endif /* CONFIG_TESTING_OPTIONS */ + } +diff --git a/src/eap_common/eap_pwd_common.c b/src/eap_common/eap_pwd_common.c +index 8e7966e..bac2796 100644 +--- a/src/eap_common/eap_pwd_common.c ++++ b/src/eap_common/eap_pwd_common.c +@@ -88,8 +88,7 @@ static int eap_pwd_suitable_group(u16 num) + { + /* Do not allow ECC groups with prime under 256 bits based on guidance + * for the similar design in SAE. */ +- return num == 19 || num == 20 || num == 21 || +- num == 28 || num == 29 || num == 30; ++ return num == 19 || num == 20 || num == 21; + } + EAP_PWD_group * get_eap_pwd_group(u16 num) + { +-- +2.23.0 + diff --git a/wpa_supplicant.spec b/wpa_supplicant.spec index e810efe..c799012 100644 --- a/wpa_supplicant.spec +++ b/wpa_supplicant.spec @@ -1,7 +1,7 @@ Name: wpa_supplicant Epoch: 1 Version: 2.6 -Release: 26 +Release: 27 Summary: A WPA Supplicant with support for WPA and WPA2 (IEEE 802.11i / RSN) License: BSD Url: https://w1.fi/wpa_supplicant/ @@ -52,14 +52,14 @@ Patch6035: macsec-0036-mka-Fix-the-order-of-operations-in-secure-channel-de. Patch6036: macsec-0037-mka-Fix-use-after-free-when-receive-secure-channels-.patch Patch6037: macsec-0038-mka-Fix-use-after-free-when-transmit-secure-channels.patch Patch6038: macsec-0039-macsec_linux-Fix-NULL-pointer-dereference-on-error-c.patch -Patch6039: https://w1.fi/security/2017-1/rebased-v2.6-0001-hostapd-Avoid-key-reinstallation-in-FT-handshake.patch -Patch6040: https://w1.fi/security/2017-1/rebased-v2.6-0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch -Patch6041: https://w1.fi/security/2017-1/rebased-v2.6-0003-Extend-protection-of-GTK-IGTK-reinstallation-of-WNM-.patch -Patch6042: https://w1.fi/security/2017-1/rebased-v2.6-0004-Prevent-installation-of-an-all-zero-TK.patch -Patch6043: https://w1.fi/security/2017-1/rebased-v2.6-0005-Fix-PTK-rekeying-to-generate-a-new-ANonce.patch -Patch6044: https://w1.fi/security/2017-1/rebased-v2.6-0006-TDLS-Reject-TPK-TK-reconfiguration.patch -Patch6045: https://w1.fi/security/2017-1/rebased-v2.6-0007-WNM-Ignore-WNM-Sleep-Mode-Response-without-pending-r.patch -Patch6046: https://w1.fi/security/2017-1/rebased-v2.6-0008-FT-Do-not-allow-multiple-Reassociation-Response-fram.patch +Patch6039: rebased-v2.6-0001-hostapd-Avoid-key-reinstallation-in-FT-handshake.patch +Patch6040: rebased-v2.6-0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch +Patch6041: rebased-v2.6-0003-Extend-protection-of-GTK-IGTK-reinstallation-of-WNM-.patch +Patch6042: rebased-v2.6-0004-Prevent-installation-of-an-all-zero-TK.patch +Patch6043: rebased-v2.6-0005-Fix-PTK-rekeying-to-generate-a-new-ANonce.patch +Patch6044: rebased-v2.6-0006-TDLS-Reject-TPK-TK-reconfiguration.patch +Patch6045: rebased-v2.6-0007-WNM-Ignore-WNM-Sleep-Mode-Response-without-pending-r.patch +Patch6046: rebased-v2.6-0008-FT-Do-not-allow-multiple-Reassociation-Response-fram.patch Patch6047: rh1451834-nl80211-Fix-race-condition-in-detecting-MAC-change.patch Patch6048: rh1462262-use-system-openssl-ciphers.patch Patch6049: rh1465138-openssl-Fix-openssl-1-1-private-key-callback.patch @@ -81,12 +81,21 @@ Patch6064: CVE-2019-9497.patch Patch6065: CVE-2019-9498-and-CVE-2019-9499.patch Patch6066: CVE-2019-11555-1.patch Patch6067: CVE-2019-11555-2.patch -Patch6068: https://w1.fi/security/2018-1/rebased-v2.6-0001-WPA-Ignore-unauthenticated-encrypted-EAPOL-Key-data.patch +Patch6068: rebased-v2.6-0001-WPA-Ignore-unauthenticated-encrypted-EAPOL-Key-data.patch Patch6069: CVE-2019-9499.patch Patch6070: CVE-2019-9495-pre1.patch Patch6071: CVE-2019-9495-pre2.patch Patch6072: CVE-2019-9495-pre3.patch Patch6073: CVE-2019-9495.patch +Patch6074: CVE-2019-13377-1.patch +Patch6075: CVE-2019-13377-2-pre1.patch +Patch6076: CVE-2019-13377-2-pre.patch +Patch6077: CVE-2019-13377-2.patch +Patch6078: CVE-2019-13377-3.patch +Patch6079: CVE-2019-13377-4.patch +Patch60710: CVE-2019-13377-5.patch +Patch60711: CVE-2019-13377-6-pre.patch +Patch60712: CVE-2019-13377-6.patch Patch9000: add-options-of-wpa_supplicant-service.patch Patch9001: allow-to-override-names-of-qt4-tools.patch @@ -183,6 +192,12 @@ install -m644 %{name}/doc/docbook/*.5 %{buildroot}%{_mandir}/man5 %{_mandir}/man5/* %changelog +* Thu Dec 24 2020 wuchaochao - 1:2.6-27 +- Type:cves +- ID: CVE-2019-13377 +- SUG:NA +- DESC: fix CVE-2019-13377 + * Tue Feb 04 2020 zhouyihang - 1:2.6-26 - Type:cves - ID: CVE-2019-9495 -- Gitee