fix CVE-2022-23303 CVE-2022-23304

This commit is contained in:
shixuantong 2022-01-26 17:24:07 +08:00
parent e6892295e0
commit d785ed924e
7 changed files with 4915 additions and 1 deletions

View File

@ -0,0 +1,318 @@
From 208e5687ff2e48622e28d8888ce5444a54353bbd Mon Sep 17 00:00:00 2001
From: Jouni Malinen <jouni@codeaurora.org>
Date: Tue, 27 Aug 2019 16:33:15 +0300
Subject: [PATCH 1/4] crypto: Add more bignum/EC helper functions
These are needed for implementing SAE hash-to-element.
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
---
src/crypto/crypto.h | 45 ++++++++++++++++++++++
src/crypto/crypto_openssl.c | 94 +++++++++++++++++++++++++++++++++++++++++++++
src/crypto/crypto_wolfssl.c | 66 +++++++++++++++++++++++++++++++
3 files changed, 205 insertions(+)
diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h
index bdc3ba6..0bc9df4 100644
--- a/src/crypto/crypto.h
+++ b/src/crypto/crypto.h
@@ -508,6 +508,13 @@ struct crypto_bignum * crypto_bignum_init(void);
struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len);
/**
+ * crypto_bignum_init_set - Allocate memory for bignum and set the value (uint)
+ * @val: Value to set
+ * Returns: Pointer to allocated bignum or %NULL on failure
+ */
+struct crypto_bignum * crypto_bignum_init_uint(unsigned int val);
+
+/**
* crypto_bignum_deinit - Free bignum
* @n: Bignum from crypto_bignum_init() or crypto_bignum_init_set()
* @clear: Whether to clear the value from memory
@@ -594,6 +601,19 @@ int crypto_bignum_div(const struct crypto_bignum *a,
struct crypto_bignum *c);
/**
+ * crypto_bignum_addmod - d = a + b (mod c)
+ * @a: Bignum
+ * @b: Bignum
+ * @c: Bignum
+ * @d: Bignum; used to store the result of (a + b) % c
+ * Returns: 0 on success, -1 on failure
+ */
+int crypto_bignum_addmod(const struct crypto_bignum *a,
+ const struct crypto_bignum *b,
+ const struct crypto_bignum *c,
+ struct crypto_bignum *d);
+
+/**
* crypto_bignum_mulmod - d = a * b (mod c)
* @a: Bignum
* @b: Bignum
@@ -607,6 +627,28 @@ int crypto_bignum_mulmod(const struct crypto_bignum *a,
struct crypto_bignum *d);
/**
+ * crypto_bignum_sqrmod - c = a^2 (mod b)
+ * @a: Bignum
+ * @b: Bignum
+ * @c: Bignum; used to store the result of a^2 % b
+ * Returns: 0 on success, -1 on failure
+ */
+int crypto_bignum_sqrmod(const struct crypto_bignum *a,
+ const struct crypto_bignum *b,
+ struct crypto_bignum *c);
+
+/**
+ * crypto_bignum_sqrtmod - returns sqrt(a) (mod b)
+ * @a: Bignum
+ * @b: Bignum
+ * @c: Bignum; used to store the result
+ * Returns: 0 on success, -1 on failure
+ */
+int crypto_bignum_sqrtmod(const struct crypto_bignum *a,
+ const struct crypto_bignum *b,
+ struct crypto_bignum *c);
+
+/**
* crypto_bignum_cmp - Compare two bignums
* @a: Bignum
* @b: Bignum
@@ -695,6 +737,9 @@ const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e);
*/
const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e);
+const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e);
+const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e);
+
/**
* struct crypto_ec_point - Elliptic curve point
*
diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c
index 00b61b9..80867b6 100644
--- a/src/crypto/crypto_openssl.c
+++ b/src/crypto/crypto_openssl.c
@@ -1117,6 +1117,24 @@ struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len)
}
+struct crypto_bignum * crypto_bignum_init_uint(unsigned int val)
+{
+ BIGNUM *bn;
+
+ if (TEST_FAIL())
+ return NULL;
+
+ bn = BN_new();
+ if (!bn)
+ return NULL;
+ if (BN_set_word(bn, val) != 1) {
+ BN_free(bn);
+ return NULL;
+ }
+ return (struct crypto_bignum *) bn;
+}
+
+
void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
{
if (clear)
@@ -1278,6 +1296,28 @@ int crypto_bignum_div(const struct crypto_bignum *a,
}
+int crypto_bignum_addmod(const struct crypto_bignum *a,
+ const struct crypto_bignum *b,
+ const struct crypto_bignum *c,
+ struct crypto_bignum *d)
+{
+ int res;
+ BN_CTX *bnctx;
+
+ if (TEST_FAIL())
+ return -1;
+
+ bnctx = BN_CTX_new();
+ if (!bnctx)
+ return -1;
+ res = BN_mod_add((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b,
+ (const BIGNUM *) c, bnctx);
+ BN_CTX_free(bnctx);
+
+ return res ? 0 : -1;
+}
+
+
int crypto_bignum_mulmod(const struct crypto_bignum *a,
const struct crypto_bignum *b,
const struct crypto_bignum *c,
@@ -1301,6 +1341,48 @@ int crypto_bignum_mulmod(const struct crypto_bignum *a,
}
+int crypto_bignum_sqrmod(const struct crypto_bignum *a,
+ const struct crypto_bignum *b,
+ struct crypto_bignum *c)
+{
+ int res;
+ BN_CTX *bnctx;
+
+ if (TEST_FAIL())
+ return -1;
+
+ bnctx = BN_CTX_new();
+ if (!bnctx)
+ return -1;
+ res = BN_mod_sqr((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b,
+ bnctx);
+ BN_CTX_free(bnctx);
+
+ return res ? 0 : -1;
+}
+
+
+int crypto_bignum_sqrtmod(const struct crypto_bignum *a,
+ const struct crypto_bignum *b,
+ struct crypto_bignum *c)
+{
+ BN_CTX *bnctx;
+ BIGNUM *res;
+
+ if (TEST_FAIL())
+ return -1;
+
+ bnctx = BN_CTX_new();
+ if (!bnctx)
+ return -1;
+ res = BN_mod_sqrt((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b,
+ bnctx);
+ BN_CTX_free(bnctx);
+
+ return res ? 0 : -1;
+}
+
+
int crypto_bignum_cmp(const struct crypto_bignum *a,
const struct crypto_bignum *b)
{
@@ -1494,6 +1576,18 @@ const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
}
+const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e)
+{
+ return (const struct crypto_bignum *) e->a;
+}
+
+
+const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e)
+{
+ return (const struct crypto_bignum *) e->b;
+}
+
+
void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
{
if (clear)
diff --git a/src/crypto/crypto_wolfssl.c b/src/crypto/crypto_wolfssl.c
index 90163c4..683c553 100644
--- a/src/crypto/crypto_wolfssl.c
+++ b/src/crypto/crypto_wolfssl.c
@@ -1043,6 +1043,26 @@ struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len)
}
+struct crypto_bignum * crypto_bignum_init_uint(unsigned int val)
+{
+ mp_int *a;
+
+ if (TEST_FAIL())
+ return NULL;
+
+ a = (mp_int *) crypto_bignum_init();
+ if (!a)
+ return NULL;
+
+ if (mp_set_int(a, val) != MP_OKAY) {
+ os_free(a);
+ a = NULL;
+ }
+
+ return (struct crypto_bignum *) a;
+}
+
+
void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
{
if (!n)
@@ -1167,6 +1187,19 @@ int crypto_bignum_div(const struct crypto_bignum *a,
}
+int crypto_bignum_addmod(const struct crypto_bignum *a,
+ const struct crypto_bignum *b,
+ const struct crypto_bignum *c,
+ struct crypto_bignum *d)
+{
+ if (TEST_FAIL())
+ return -1;
+
+ return mp_addmod((mp_int *) a, (mp_int *) b, (mp_int *) c,
+ (mp_int *) d) == MP_OKAY ? 0 : -1;
+}
+
+
int crypto_bignum_mulmod(const struct crypto_bignum *a,
const struct crypto_bignum *b,
const struct crypto_bignum *m,
@@ -1180,6 +1213,27 @@ int crypto_bignum_mulmod(const struct crypto_bignum *a,
}
+int crypto_bignum_sqrmod(const struct crypto_bignum *a,
+ const struct crypto_bignum *b,
+ struct crypto_bignum *c)
+{
+ if (TEST_FAIL())
+ return -1;
+
+ return mp_sqrmod((mp_int *) a, (mp_int *) b,
+ (mp_int *) c) == MP_OKAY ? 0 : -1;
+}
+
+
+int crypto_bignum_sqrtmod(const struct crypto_bignum *a,
+ const struct crypto_bignum *b,
+ struct crypto_bignum *c)
+{
+ /* TODO */
+ return -1;
+}
+
+
int crypto_bignum_rshift(const struct crypto_bignum *a, int n,
struct crypto_bignum *r)
{
@@ -1401,6 +1455,18 @@ const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
}
+const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e)
+{
+ return (const struct crypto_bignum *) &e->a;
+}
+
+
+const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e)
+{
+ return (const struct crypto_bignum *) &e->b;
+}
+
+
void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
{
ecc_point *point = (ecc_point *) p;
--
1.8.3.1

View File

@ -0,0 +1,72 @@
From 2232d3d5f188b65dbb6c823ac62175412739eb16 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Fri, 7 Jan 2022 13:47:16 +0200
Subject: [PATCH 2/4] dragonfly: Add sqrt() helper function
This is a backport of "SAE: Move sqrt() implementation into a helper
function" to introduce the helper function needed for the following
patches.
Signed-off-by: Jouni Malinen <j@w1.fi>
---
src/common/dragonfly.c | 34 ++++++++++++++++++++++++++++++++++
src/common/dragonfly.h | 3 +++
2 files changed, 37 insertions(+)
diff --git a/src/common/dragonfly.c b/src/common/dragonfly.c
index 1e80404..7dcc6de 100644
--- a/src/common/dragonfly.c
+++ b/src/common/dragonfly.c
@@ -25,3 +25,37 @@ int dragonfly_suitable_group(int group, int ecc_only)
(!ecc_only &&
(group == 15 || group == 16 || group == 17 || group == 18));
}
+
+
+/* res = sqrt(val) */
+int dragonfly_sqrt(struct crypto_ec *ec, const struct crypto_bignum *val,
+ struct crypto_bignum *res)
+{
+ const struct crypto_bignum *prime;
+ struct crypto_bignum *tmp, *one;
+ int ret = 0;
+ u8 prime_bin[DRAGONFLY_MAX_ECC_PRIME_LEN];
+ size_t prime_len;
+
+ /* For prime p such that p = 3 mod 4, sqrt(w) = w^((p+1)/4) mod p */
+
+ prime = crypto_ec_get_prime(ec);
+ prime_len = crypto_ec_prime_len(ec);
+ tmp = crypto_bignum_init();
+ one = crypto_bignum_init_uint(1);
+
+ if (crypto_bignum_to_bin(prime, prime_bin, sizeof(prime_bin),
+ prime_len) < 0 ||
+ (prime_bin[prime_len - 1] & 0x03) != 3 ||
+ !tmp || !one ||
+ /* tmp = (p+1)/4 */
+ crypto_bignum_add(prime, one, tmp) < 0 ||
+ crypto_bignum_rshift(tmp, 2, tmp) < 0 ||
+ /* res = sqrt(val) */
+ crypto_bignum_exptmod(val, tmp, prime, res) < 0)
+ ret = -1;
+
+ crypto_bignum_deinit(tmp, 0);
+ crypto_bignum_deinit(one, 0);
+ return ret;
+}
diff --git a/src/common/dragonfly.h b/src/common/dragonfly.h
index 9f3c428..f0f49d0 100644
--- a/src/common/dragonfly.h
+++ b/src/common/dragonfly.h
@@ -12,4 +12,7 @@
int dragonfly_suitable_group(int group, int ecc_only);
+int dragonfly_sqrt(struct crypto_ec *ec, const struct crypto_bignum *val,
+ struct crypto_bignum *res);
+
#endif /* DRAGONFLY_H */
--
1.8.3.1

View File

@ -0,0 +1,100 @@
From fe534b0baaa8c0e6ddeb24cf529d6e50e33dc501 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Fri, 7 Jan 2022 13:47:16 +0200
Subject: [PATCH 3/4] SAE: Derive the y coordinate for PWE with own
implementation
The crypto_ec_point_solve_y_coord() wrapper function might not use
constant time operations in the crypto library and as such, could leak
side channel information about the password that is used to generate the
PWE in the hunting and pecking loop. As such, calculate the two possible
y coordinate values and pick the correct one to use with constant time
selection.
Signed-off-by: Jouni Malinen <j@w1.fi>
---
src/common/sae.c | 47 +++++++++++++++++++++++++++++++++--------------
1 file changed, 33 insertions(+), 14 deletions(-)
diff --git a/src/common/sae.c b/src/common/sae.c
index b35821d..c168bf1 100644
--- a/src/common/sae.c
+++ b/src/common/sae.c
@@ -459,15 +459,17 @@ static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1,
int pwd_seed_odd = 0;
u8 prime[SAE_MAX_ECC_PRIME_LEN];
size_t prime_len;
- struct crypto_bignum *x = NULL, *qr = NULL, *qnr = NULL;
+ struct crypto_bignum *x = NULL, *y = NULL, *qr = NULL, *qnr = NULL;
u8 x_bin[SAE_MAX_ECC_PRIME_LEN];
u8 x_cand_bin[SAE_MAX_ECC_PRIME_LEN];
u8 qr_bin[SAE_MAX_ECC_PRIME_LEN];
u8 qnr_bin[SAE_MAX_ECC_PRIME_LEN];
+ u8 x_y[2 * SAE_MAX_ECC_PRIME_LEN];
size_t bits;
int res = -1;
u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
* mask */
+ unsigned int is_eq;
os_memset(x_bin, 0, sizeof(x_bin));
@@ -567,25 +569,42 @@ static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1,
goto fail;
}
- if (!sae->tmp->pwe_ecc)
- sae->tmp->pwe_ecc = crypto_ec_point_init(sae->tmp->ec);
- if (!sae->tmp->pwe_ecc)
- res = -1;
- else
- res = crypto_ec_point_solve_y_coord(sae->tmp->ec,
- sae->tmp->pwe_ecc, x,
- pwd_seed_odd);
- if (res < 0) {
- /*
- * This should not happen since we already checked that there
- * is a result.
- */
+ /* y = sqrt(x^3 + ax + b) mod p
+ * if LSB(save) == LSB(y): PWE = (x, y)
+ * else: PWE = (x, p - y)
+ *
+ * Calculate y and the two possible values for PWE and after that,
+ * use constant time selection to copy the correct alternative.
+ */
+ y = crypto_ec_point_compute_y_sqr(sae->tmp->ec, x);
+ if (!y ||
+ dragonfly_sqrt(sae->tmp->ec, y, y) < 0 ||
+ crypto_bignum_to_bin(y, x_y, SAE_MAX_ECC_PRIME_LEN,
+ prime_len) < 0 ||
+ crypto_bignum_sub(sae->tmp->prime, y, y) < 0 ||
+ crypto_bignum_to_bin(y, x_y + SAE_MAX_ECC_PRIME_LEN,
+ SAE_MAX_ECC_PRIME_LEN, prime_len) < 0) {
wpa_printf(MSG_DEBUG, "SAE: Could not solve y");
+ goto fail;
+ }
+
+ is_eq = const_time_eq(pwd_seed_odd, x_y[prime_len - 1] & 0x01);
+ const_time_select_bin(is_eq, x_y, x_y + SAE_MAX_ECC_PRIME_LEN,
+ prime_len, x_y + prime_len);
+ os_memcpy(x_y, x_bin, prime_len);
+ wpa_hexdump_key(MSG_DEBUG, "SAE: PWE", x_y, 2 * prime_len);
+ crypto_ec_point_deinit(sae->tmp->pwe_ecc, 1);
+ sae->tmp->pwe_ecc = crypto_ec_point_from_bin(sae->tmp->ec, x_y);
+ if (!sae->tmp->pwe_ecc) {
+ wpa_printf(MSG_DEBUG, "SAE: Could not generate PWE");
+ res = -1;
}
fail:
+ forced_memzero(x_y, sizeof(x_y));
crypto_bignum_deinit(qr, 0);
crypto_bignum_deinit(qnr, 0);
+ crypto_bignum_deinit(y, 1);
os_free(dummy_password);
bin_clear_free(tmp_password, password_len);
crypto_bignum_deinit(x, 1);
--
1.8.3.1

View File

@ -0,0 +1,109 @@
From 603cd880e7f90595482658a7136fa6a7be5cb485 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Fri, 7 Jan 2022 18:52:27 +0200
Subject: [PATCH 4/4] EAP-pwd: Derive the y coordinate for PWE with own
implementation
The crypto_ec_point_solve_y_coord() wrapper function might not use
constant time operations in the crypto library and as such, could leak
side channel information about the password that is used to generate the
PWE in the hunting and pecking loop. As such, calculate the two possible
y coordinate values and pick the correct one to use with constant time
selection.
Signed-off-by: Jouni Malinen <j@w1.fi>
---
src/eap_common/eap_pwd_common.c | 42 +++++++++++++++++++++++++++++++++++------
1 file changed, 36 insertions(+), 6 deletions(-)
diff --git a/src/eap_common/eap_pwd_common.c b/src/eap_common/eap_pwd_common.c
index 755aafb..ab8eb92 100644
--- a/src/eap_common/eap_pwd_common.c
+++ b/src/eap_common/eap_pwd_common.c
@@ -137,7 +137,8 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
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;
+ u8 x_y[2 * MAX_ECC_PRIME_LEN];
+ struct crypto_bignum *tmp1 = NULL, *tmp2 = NULL, *pm1 = NULL, *y = NULL;
struct crypto_hash *hash;
unsigned char pwe_digest[SHA256_MAC_LEN], *prfbuf = NULL, ctr;
int ret = 0, check, res;
@@ -149,6 +150,7 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
u8 mask, found_ctr = 0, is_odd = 0;
int cmp_prime;
unsigned int in_range;
+ unsigned int is_eq;
if (grp->pwe)
return -1;
@@ -161,7 +163,6 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
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();
one = crypto_bignum_init_set((const u8 *) "\x01", 1);
@@ -323,10 +324,37 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
*/
crypto_bignum_deinit(x_candidate, 1);
x_candidate = crypto_bignum_init_set(x_bin, primebytelen);
- if (!x_candidate ||
- crypto_ec_point_solve_y_coord(grp->group, grp->pwe, x_candidate,
- is_odd) != 0) {
- wpa_printf(MSG_INFO, "EAP-pwd: Could not solve for y");
+ if (!x_candidate)
+ goto fail;
+
+ /* y = sqrt(x^3 + ax + b) mod p
+ * if LSB(y) == LSB(pwd-seed): PWE = (x, y)
+ * else: PWE = (x, p - y)
+ *
+ * Calculate y and the two possible values for PWE and after that,
+ * use constant time selection to copy the correct alternative.
+ */
+ y = crypto_ec_point_compute_y_sqr(grp->group, x_candidate);
+ if (!y ||
+ dragonfly_sqrt(grp->group, y, y) < 0 ||
+ crypto_bignum_to_bin(y, x_y, MAX_ECC_PRIME_LEN, primebytelen) < 0 ||
+ crypto_bignum_sub(prime, y, y) < 0 ||
+ crypto_bignum_to_bin(y, x_y + MAX_ECC_PRIME_LEN,
+ MAX_ECC_PRIME_LEN, primebytelen) < 0) {
+ wpa_printf(MSG_DEBUG, "SAE: Could not solve y");
+ goto fail;
+ }
+
+ /* Constant time selection of the y coordinate from the two
+ * options */
+ is_eq = const_time_eq(is_odd, x_y[primebytelen - 1] & 0x01);
+ const_time_select_bin(is_eq, x_y, x_y + MAX_ECC_PRIME_LEN,
+ primebytelen, x_y + primebytelen);
+ os_memcpy(x_y, x_bin, primebytelen);
+ wpa_hexdump_key(MSG_DEBUG, "EAP-pwd: PWE", x_y, 2 * primebytelen);
+ grp->pwe = crypto_ec_point_from_bin(grp->group, x_y);
+ if (!grp->pwe) {
+ wpa_printf(MSG_DEBUG, "EAP-pwd: Could not generate PWE");
goto fail;
}
@@ -353,6 +381,7 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
crypto_bignum_deinit(pm1, 0);
crypto_bignum_deinit(tmp1, 1);
crypto_bignum_deinit(tmp2, 1);
+ crypto_bignum_deinit(y, 1);
crypto_bignum_deinit(qr, 1);
crypto_bignum_deinit(qnr, 1);
crypto_bignum_deinit(qr_or_qnr, 1);
@@ -362,6 +391,7 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
os_memset(qnr_bin, 0, sizeof(qnr_bin));
os_memset(qr_or_qnr_bin, 0, sizeof(qr_or_qnr_bin));
os_memset(pwe_digest, 0, sizeof(pwe_digest));
+ forced_memzero(x_y, sizeof(x_y));
return ret;
}
--
1.8.3.1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,219 @@
From 2b84ca4dd96459b661b0ebaf40ec43074fc9f42c Mon Sep 17 00:00:00 2001
From: Jouni Malinen <jouni@codeaurora.org>
Date: Thu, 25 Apr 2019 19:45:27 +0300
Subject: Share common SAE and EAP-pwd functionality: suitable groups
Start sharing common SAE and EAP-pwd functionality by adding a new
source code file that can be included into both. This first step is
bringing in a shared function to check whether a group is suitable.
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
---
src/common/dragonfly.c | 27 +++++++++++++++++++++++++++
src/common/dragonfly.h | 15 +++++++++++++++
src/common/sae.c | 27 ++++++---------------------
src/eap_common/eap_pwd_common.c | 9 ++-------
wpa_supplicant/Android.mk | 6 ++++++
wpa_supplicant/Makefile | 6 ++++++
6 files changed, 62 insertions(+), 28 deletions(-)
create mode 100644 src/common/dragonfly.c
create mode 100644 src/common/dragonfly.h
diff --git a/src/common/dragonfly.c b/src/common/dragonfly.c
new file mode 100644
index 0000000..1e80404
--- /dev/null
+++ b/src/common/dragonfly.c
@@ -0,0 +1,27 @@
+/*
+ * Shared Dragonfly functionality
+ * Copyright (c) 2012-2016, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2019, The Linux Foundation
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "utils/includes.h"
+
+#include "utils/common.h"
+#include "dragonfly.h"
+
+
+int dragonfly_suitable_group(int group, int ecc_only)
+{
+ /* 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 ||
+ (!ecc_only &&
+ (group == 15 || group == 16 || group == 17 || group == 18));
+}
diff --git a/src/common/dragonfly.h b/src/common/dragonfly.h
new file mode 100644
index 0000000..9f3c428
--- /dev/null
+++ b/src/common/dragonfly.h
@@ -0,0 +1,15 @@
+/*
+ * Shared Dragonfly functionality
+ * Copyright (c) 2012-2016, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2019, The Linux Foundation
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef DRAGONFLY_H
+#define DRAGONFLY_H
+
+int dragonfly_suitable_group(int group, int ecc_only);
+
+#endif /* DRAGONFLY_H */
diff --git a/src/common/sae.c b/src/common/sae.c
index 5ef6c4c..b35821d 100644
--- a/src/common/sae.c
+++ b/src/common/sae.c
@@ -15,36 +15,21 @@
#include "crypto/random.h"
#include "crypto/dh_groups.h"
#include "ieee802_11_defs.h"
+#include "dragonfly.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. 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 == 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)) {
+#ifdef CONFIG_TESTING_OPTIONS
+ /* Allow all groups for testing purposes in non-production builds. */
+#else /* CONFIG_TESTING_OPTIONS */
+ if (!dragonfly_suitable_group(group, 0)) {
wpa_printf(MSG_DEBUG, "SAE: Reject unsuitable group %d", group);
return -1;
}
+#endif /* CONFIG_TESTING_OPTIONS */
sae_clear_data(sae);
tmp = sae->tmp = os_zalloc(sizeof(*tmp));
diff --git a/src/eap_common/eap_pwd_common.c b/src/eap_common/eap_pwd_common.c
index bac2796..755aafb 100644
--- a/src/eap_common/eap_pwd_common.c
+++ b/src/eap_common/eap_pwd_common.c
@@ -9,6 +9,7 @@
#include "includes.h"
#include "common.h"
#include "utils/const_time.h"
+#include "common/dragonfly.h"
#include "crypto/sha256.h"
#include "crypto/crypto.h"
#include "eap_defs.h"
@@ -84,18 +85,12 @@ 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;
-}
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)) {
+ if (!dragonfly_suitable_group(num, 1)) {
wpa_printf(MSG_INFO, "EAP-pwd: unsuitable group %u", num);
return NULL;
}
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 924ac07..aa5ac8c 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -236,6 +236,7 @@ L_CFLAGS += -DCONFIG_SAE
OBJS += src/common/sae.c
NEED_ECC=y
NEED_DH_GROUPS=y
+NEED_DRAGONFLY=y
endif
ifdef CONFIG_WNM
@@ -641,6 +642,7 @@ OBJS += src/eap_peer/eap_pwd.c src/eap_common/eap_pwd_common.c
CONFIG_IEEE8021X_EAPOL=y
NEED_SHA256=y
NEED_ECC=y
+NEED_DRAGONFLY=y
endif
ifdef CONFIG_EAP_EKE
@@ -918,6 +920,10 @@ ifdef CONFIG_SMARTCARD
L_CFLAGS += -DCONFIG_SMARTCARD
endif
+ifdef NEED_DRAGONFLY
+OBJS += src/common/dragonfly.c
+endif
+
ifdef MS_FUNCS
OBJS += src/crypto/ms_funcs.c
NEED_DES=y
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index d70189b..8fce344 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -270,6 +270,7 @@ CFLAGS += -DCONFIG_SAE
OBJS += ../src/common/sae.o
NEED_ECC=y
NEED_DH_GROUPS=y
+NEED_DRAGONFLY=y
endif
ifdef CONFIG_WNM
@@ -673,6 +674,7 @@ OBJS += ../src/eap_peer/eap_pwd.o ../src/eap_common/eap_pwd_common.o
CONFIG_IEEE8021X_EAPOL=y
NEED_SHA256=y
NEED_ECC=y
+NEED_DRAGONFLY=y
endif
ifdef CONFIG_EAP_EKE
@@ -967,6 +969,10 @@ ifdef CONFIG_SMARTCARD
CFLAGS += -DCONFIG_SMARTCARD
endif
+ifdef NEED_DRAGONFLY
+OBJS += ../src/common/dragonfly.o
+endif
+
ifdef MS_FUNCS
OBJS += ../src/crypto/ms_funcs.o
NEED_DES=y
--
1.8.3.1

View File

@ -1,7 +1,7 @@
Name: wpa_supplicant
Epoch: 1
Version: 2.6
Release: 29
Release: 30
Summary: A WPA Supplicant with support for WPA and WPA2 (IEEE 802.11i / RSN)
License: BSD or GPLv2
Url: https://w1.fi/wpa_supplicant/
@ -100,6 +100,12 @@ Patch83: add-options-of-wpa_supplicant-service.patch
Patch84: allow-to-override-names-of-qt4-tools.patch
Patch85: CVE-2021-27803.patch
Patch86: CVE-2021-0326.patch
Patch87: backport-Add-support-for-wolfSSL-cryptographic-library.patch
Patch88: backport-Share-common-SAE-and-EAP-pwd-functionality-suitable-.patch
Patch89: backport-0001-CVE-2022-23303-CVE-2022-23304.patch
Patch90: backport-0002-CVE-2022-23303-CVE-2022-23304.patch
Patch91: backport-0003-CVE-2022-23303-CVE-2022-23304.patch
Patch92: backport-0004-CVE-2022-23303-CVE-2022-23304.patch
BuildRequires: qt-devel >= 4.0 openssl-devel readline-devel dbus-devel libnl3-devel systemd-units docbook-utils
Requires(post): systemd-sysv
@ -193,6 +199,12 @@ install -m644 %{name}/doc/docbook/*.5 %{buildroot}%{_mandir}/man5
%{_mandir}/man5/*
%changelog
* Wed Jan 26 2022 shixuantong <shixuantong@huawei.com> - 1:2.6-30
- Type:cves
- ID:CVE-2022-23303 CVE-2022-23304
- SUG:NA
- DESC:fix CVE-2022-23303 CVE-2022-23304
* Wed Sep 22 2021 gaoyusong <gaoyusong1@huawei.com> - 1:2.6-29
- Type:cves
- ID: CVE-2021-0326