fix CVE-2022-23303 CVE-2022-23304
This commit is contained in:
parent
e6892295e0
commit
d785ed924e
318
backport-0001-CVE-2022-23303-CVE-2022-23304.patch
Normal file
318
backport-0001-CVE-2022-23303-CVE-2022-23304.patch
Normal 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
|
||||
|
||||
72
backport-0002-CVE-2022-23303-CVE-2022-23304.patch
Normal file
72
backport-0002-CVE-2022-23303-CVE-2022-23304.patch
Normal 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
|
||||
|
||||
100
backport-0003-CVE-2022-23303-CVE-2022-23304.patch
Normal file
100
backport-0003-CVE-2022-23303-CVE-2022-23304.patch
Normal 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
|
||||
|
||||
109
backport-0004-CVE-2022-23303-CVE-2022-23304.patch
Normal file
109
backport-0004-CVE-2022-23303-CVE-2022-23304.patch
Normal 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
|
||||
|
||||
4084
backport-Add-support-for-wolfSSL-cryptographic-library.patch
Normal file
4084
backport-Add-support-for-wolfSSL-cryptographic-library.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user