summaryrefslogtreecommitdiffstats
path: root/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-connectivity/wpa-supplicant/wpa-supplicant')
-rw-r--r--meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2021-0326.patch45
-rw-r--r--meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2021-27803.patch58
-rw-r--r--meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2021-30004.patch123
-rw-r--r--meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-23303-4.patch609
4 files changed, 835 insertions, 0 deletions
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2021-0326.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2021-0326.patch
new file mode 100644
index 0000000000..8c90fa3421
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2021-0326.patch
@@ -0,0 +1,45 @@
1From 947272febe24a8f0ea828b5b2f35f13c3821901e Mon Sep 17 00:00:00 2001
2From: Jouni Malinen <jouni@codeaurora.org>
3Date: Mon, 9 Nov 2020 11:43:12 +0200
4Subject: [PATCH] P2P: Fix copying of secondary device types for P2P group
5 client
6
7Parsing and copying of WPS secondary device types list was verifying
8that the contents is not too long for the internal maximum in the case
9of WPS messages, but similar validation was missing from the case of P2P
10group information which encodes this information in a different
11attribute. This could result in writing beyond the memory area assigned
12for these entries and corrupting memory within an instance of struct
13p2p_device. This could result in invalid operations and unexpected
14behavior when trying to free pointers from that corrupted memory.
15
16Upstream-Status: Backport
17CVE: CVE-2021-0326
18
19Reference to upstream patch:
20[https://w1.fi/cgit/hostap/commit/?id=947272febe24a8f0ea828b5b2f35f13c3821901e]
21
22Credit to OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=27269
23Fixes: e57ae6e19edf ("P2P: Keep track of secondary device types for peers")
24Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
25Signed-off-by: Stefan Ghinea <stefan.ghinea@windriver.com>
26---
27 src/p2p/p2p.c | 2 ++
28 1 file changed, 2 insertions(+)
29
30diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
31index a08ba02..079270f 100644
32--- a/src/p2p/p2p.c
33+++ b/src/p2p/p2p.c
34@@ -453,6 +453,8 @@ static void p2p_copy_client_info(struct p2p_device *dev,
35 dev->info.config_methods = cli->config_methods;
36 os_memcpy(dev->info.pri_dev_type, cli->pri_dev_type, 8);
37 dev->info.wps_sec_dev_type_list_len = 8 * cli->num_sec_dev_types;
38+ if (dev->info.wps_sec_dev_type_list_len > WPS_SEC_DEV_TYPE_MAX_LEN)
39+ dev->info.wps_sec_dev_type_list_len = WPS_SEC_DEV_TYPE_MAX_LEN;
40 os_memcpy(dev->info.wps_sec_dev_type_list, cli->sec_dev_types,
41 dev->info.wps_sec_dev_type_list_len);
42 }
43--
442.17.1
45
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2021-27803.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2021-27803.patch
new file mode 100644
index 0000000000..004b1dbd19
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2021-27803.patch
@@ -0,0 +1,58 @@
1From 8460e3230988ef2ec13ce6b69b687e941f6cdb32 Mon Sep 17 00:00:00 2001
2From: Jouni Malinen <jouni@codeaurora.org>
3Date: Tue, 8 Dec 2020 23:52:50 +0200
4Subject: [PATCH] P2P: Fix a corner case in peer addition based on PD Request
5
6p2p_add_device() may remove the oldest entry if there is no room in the
7peer table for a new peer. This would result in any pointer to that
8removed entry becoming stale. A corner case with an invalid PD Request
9frame could result in such a case ending up using (read+write) freed
10memory. This could only by triggered when the peer table has reached its
11maximum size and the PD Request frame is received from the P2P Device
12Address of the oldest remaining entry and the frame has incorrect P2P
13Device Address in the payload.
14
15Fix this by fetching the dev pointer again after having called
16p2p_add_device() so that the stale pointer cannot be used.
17
18Fixes: 17bef1e97a50 ("P2P: Add peer entry based on Provision Discovery Request")
19Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
20
21Upstream-Status: Backport
22CVE: CVE-2021-27803
23
24Reference to upstream patch:
25[https://w1.fi/cgit/hostap/commit/?id=8460e3230988ef2ec13ce6b69b687e941f6cdb32]
26
27Signed-off-by: Stefan Ghinea <stefan.ghinea@windriver.com>
28---
29 src/p2p/p2p_pd.c | 12 +++++-------
30 1 file changed, 5 insertions(+), 7 deletions(-)
31
32diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c
33index 3994ec0..05fd593 100644
34--- a/src/p2p/p2p_pd.c
35+++ b/src/p2p/p2p_pd.c
36@@ -595,14 +595,12 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
37 goto out;
38 }
39
40+ dev = p2p_get_device(p2p, sa);
41 if (!dev) {
42- dev = p2p_get_device(p2p, sa);
43- if (!dev) {
44- p2p_dbg(p2p,
45- "Provision Discovery device not found "
46- MACSTR, MAC2STR(sa));
47- goto out;
48- }
49+ p2p_dbg(p2p,
50+ "Provision Discovery device not found "
51+ MACSTR, MAC2STR(sa));
52+ goto out;
53 }
54 } else if (msg.wfd_subelems) {
55 wpabuf_free(dev->info.wfd_subelems);
56--
572.17.1
58
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2021-30004.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2021-30004.patch
new file mode 100644
index 0000000000..e2540fc26b
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2021-30004.patch
@@ -0,0 +1,123 @@
1From a0541334a6394f8237a4393b7372693cd7e96f15 Mon Sep 17 00:00:00 2001
2From: Jouni Malinen <j@w1.fi>
3Date: Sat, 13 Mar 2021 18:19:31 +0200
4Subject: [PATCH] ASN.1: Validate DigestAlgorithmIdentifier parameters
5
6The supported hash algorithms do not use AlgorithmIdentifier parameters.
7However, there are implementations that include NULL parameters in
8addition to ones that omit the parameters. Previous implementation did
9not check the parameters value at all which supported both these cases,
10but did not reject any other unexpected information.
11
12Use strict validation of digest algorithm parameters and reject any
13unexpected value when validating a signature. This is needed to prevent
14potential forging attacks.
15
16Signed-off-by: Jouni Malinen <j@w1.fi>
17
18Upstream-Status: Backport
19CVE: CVE-2021-30004
20
21Reference to upstream patch:
22[https://w1.fi/cgit/hostap/commit/?id=a0541334a6394f8237a4393b7372693cd7e96f15]
23
24Signed-off-by: Stefan Ghinea <stefan.ghinea@windriver.com>
25---
26 src/tls/pkcs1.c | 21 +++++++++++++++++++++
27 src/tls/x509v3.c | 20 ++++++++++++++++++++
28 2 files changed, 41 insertions(+)
29
30diff --git a/src/tls/pkcs1.c b/src/tls/pkcs1.c
31index 141ac50..e09db07 100644
32--- a/src/tls/pkcs1.c
33+++ b/src/tls/pkcs1.c
34@@ -240,6 +240,8 @@ int pkcs1_v15_sig_ver(struct crypto_public_key *pk,
35 os_free(decrypted);
36 return -1;
37 }
38+ wpa_hexdump(MSG_MSGDUMP, "PKCS #1: DigestInfo",
39+ hdr.payload, hdr.length);
40
41 pos = hdr.payload;
42 end = pos + hdr.length;
43@@ -261,6 +263,8 @@ int pkcs1_v15_sig_ver(struct crypto_public_key *pk,
44 os_free(decrypted);
45 return -1;
46 }
47+ wpa_hexdump(MSG_MSGDUMP, "PKCS #1: DigestAlgorithmIdentifier",
48+ hdr.payload, hdr.length);
49 da_end = hdr.payload + hdr.length;
50
51 if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) {
52@@ -269,6 +273,23 @@ int pkcs1_v15_sig_ver(struct crypto_public_key *pk,
53 os_free(decrypted);
54 return -1;
55 }
56+ wpa_hexdump(MSG_MSGDUMP, "PKCS #1: Digest algorithm parameters",
57+ next, da_end - next);
58+
59+ /*
60+ * RFC 5754: The correct encoding for the SHA2 algorithms would be to
61+ * omit the parameters, but there are implementation that encode these
62+ * as a NULL element. Allow these two cases and reject anything else.
63+ */
64+ if (da_end > next &&
65+ (asn1_get_next(next, da_end - next, &hdr) < 0 ||
66+ !asn1_is_null(&hdr) ||
67+ hdr.payload + hdr.length != da_end)) {
68+ wpa_printf(MSG_DEBUG,
69+ "PKCS #1: Unexpected digest algorithm parameters");
70+ os_free(decrypted);
71+ return -1;
72+ }
73
74 if (!asn1_oid_equal(&oid, hash_alg)) {
75 char txt[100], txt2[100];
76diff --git a/src/tls/x509v3.c b/src/tls/x509v3.c
77index 1bd5aa0..bf2289f 100644
78--- a/src/tls/x509v3.c
79+++ b/src/tls/x509v3.c
80@@ -1834,6 +1834,7 @@ int x509_check_signature(struct x509_certificate *issuer,
81 os_free(data);
82 return -1;
83 }
84+ wpa_hexdump(MSG_MSGDUMP, "X509: DigestInfo", hdr.payload, hdr.length);
85
86 pos = hdr.payload;
87 end = pos + hdr.length;
88@@ -1855,6 +1856,8 @@ int x509_check_signature(struct x509_certificate *issuer,
89 os_free(data);
90 return -1;
91 }
92+ wpa_hexdump(MSG_MSGDUMP, "X509: DigestAlgorithmIdentifier",
93+ hdr.payload, hdr.length);
94 da_end = hdr.payload + hdr.length;
95
96 if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) {
97@@ -1862,6 +1865,23 @@ int x509_check_signature(struct x509_certificate *issuer,
98 os_free(data);
99 return -1;
100 }
101+ wpa_hexdump(MSG_MSGDUMP, "X509: Digest algorithm parameters",
102+ next, da_end - next);
103+
104+ /*
105+ * RFC 5754: The correct encoding for the SHA2 algorithms would be to
106+ * omit the parameters, but there are implementation that encode these
107+ * as a NULL element. Allow these two cases and reject anything else.
108+ */
109+ if (da_end > next &&
110+ (asn1_get_next(next, da_end - next, &hdr) < 0 ||
111+ !asn1_is_null(&hdr) ||
112+ hdr.payload + hdr.length != da_end)) {
113+ wpa_printf(MSG_DEBUG,
114+ "X509: Unexpected digest algorithm parameters");
115+ os_free(data);
116+ return -1;
117+ }
118
119 if (x509_sha1_oid(&oid)) {
120 if (signature->oid.oid[6] != 5 /* sha-1WithRSAEncryption */) {
121--
1222.17.1
123
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-23303-4.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-23303-4.patch
new file mode 100644
index 0000000000..21e65ba961
--- /dev/null
+++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-23303-4.patch
@@ -0,0 +1,609 @@
1From 208e5687ff2e48622e28d8888ce5444a54353bbd Mon Sep 17 00:00:00 2001
2From: Jouni Malinen <jouni@codeaurora.org>
3Date: Tue, 27 Aug 2019 16:33:15 +0300
4Subject: [PATCH 1/4] crypto: Add more bignum/EC helper functions
5
6These are needed for implementing SAE hash-to-element.
7
8Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
9
10Upstream-Status: Backport
11https://w1.fi/security/2022-1/
12
13CVE: CVE-2022-23303 CVE-2022-23304
14Signed-off-by: Steve Sakoman <steve@sakoman.com>
15
16---
17 src/crypto/crypto.h | 45 ++++++++++++++++++
18 src/crypto/crypto_openssl.c | 94 +++++++++++++++++++++++++++++++++++++
19 src/crypto/crypto_wolfssl.c | 66 ++++++++++++++++++++++++++
20 3 files changed, 205 insertions(+)
21
22diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h
23index 15f8ad04cea4..68476dbce96c 100644
24--- a/src/crypto/crypto.h
25+++ b/src/crypto/crypto.h
26@@ -518,6 +518,13 @@ struct crypto_bignum * crypto_bignum_init(void);
27 */
28 struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len);
29
30+/**
31+ * crypto_bignum_init_set - Allocate memory for bignum and set the value (uint)
32+ * @val: Value to set
33+ * Returns: Pointer to allocated bignum or %NULL on failure
34+ */
35+struct crypto_bignum * crypto_bignum_init_uint(unsigned int val);
36+
37 /**
38 * crypto_bignum_deinit - Free bignum
39 * @n: Bignum from crypto_bignum_init() or crypto_bignum_init_set()
40@@ -612,6 +619,19 @@ int crypto_bignum_div(const struct crypto_bignum *a,
41 const struct crypto_bignum *b,
42 struct crypto_bignum *c);
43
44+/**
45+ * crypto_bignum_addmod - d = a + b (mod c)
46+ * @a: Bignum
47+ * @b: Bignum
48+ * @c: Bignum
49+ * @d: Bignum; used to store the result of (a + b) % c
50+ * Returns: 0 on success, -1 on failure
51+ */
52+int crypto_bignum_addmod(const struct crypto_bignum *a,
53+ const struct crypto_bignum *b,
54+ const struct crypto_bignum *c,
55+ struct crypto_bignum *d);
56+
57 /**
58 * crypto_bignum_mulmod - d = a * b (mod c)
59 * @a: Bignum
60@@ -625,6 +645,28 @@ int crypto_bignum_mulmod(const struct crypto_bignum *a,
61 const struct crypto_bignum *c,
62 struct crypto_bignum *d);
63
64+/**
65+ * crypto_bignum_sqrmod - c = a^2 (mod b)
66+ * @a: Bignum
67+ * @b: Bignum
68+ * @c: Bignum; used to store the result of a^2 % b
69+ * Returns: 0 on success, -1 on failure
70+ */
71+int crypto_bignum_sqrmod(const struct crypto_bignum *a,
72+ const struct crypto_bignum *b,
73+ struct crypto_bignum *c);
74+
75+/**
76+ * crypto_bignum_sqrtmod - returns sqrt(a) (mod b)
77+ * @a: Bignum
78+ * @b: Bignum
79+ * @c: Bignum; used to store the result
80+ * Returns: 0 on success, -1 on failure
81+ */
82+int crypto_bignum_sqrtmod(const struct crypto_bignum *a,
83+ const struct crypto_bignum *b,
84+ struct crypto_bignum *c);
85+
86 /**
87 * crypto_bignum_rshift - r = a >> n
88 * @a: Bignum
89@@ -731,6 +773,9 @@ const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e);
90 */
91 const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e);
92
93+const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e);
94+const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e);
95+
96 /**
97 * struct crypto_ec_point - Elliptic curve point
98 *
99diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c
100index bab33a537293..ed463105e8f1 100644
101--- a/src/crypto/crypto_openssl.c
102+++ b/src/crypto/crypto_openssl.c
103@@ -1283,6 +1283,24 @@ struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len)
104 }
105
106
107+struct crypto_bignum * crypto_bignum_init_uint(unsigned int val)
108+{
109+ BIGNUM *bn;
110+
111+ if (TEST_FAIL())
112+ return NULL;
113+
114+ bn = BN_new();
115+ if (!bn)
116+ return NULL;
117+ if (BN_set_word(bn, val) != 1) {
118+ BN_free(bn);
119+ return NULL;
120+ }
121+ return (struct crypto_bignum *) bn;
122+}
123+
124+
125 void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
126 {
127 if (clear)
128@@ -1449,6 +1467,28 @@ int crypto_bignum_div(const struct crypto_bignum *a,
129 }
130
131
132+int crypto_bignum_addmod(const struct crypto_bignum *a,
133+ const struct crypto_bignum *b,
134+ const struct crypto_bignum *c,
135+ struct crypto_bignum *d)
136+{
137+ int res;
138+ BN_CTX *bnctx;
139+
140+ if (TEST_FAIL())
141+ return -1;
142+
143+ bnctx = BN_CTX_new();
144+ if (!bnctx)
145+ return -1;
146+ res = BN_mod_add((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b,
147+ (const BIGNUM *) c, bnctx);
148+ BN_CTX_free(bnctx);
149+
150+ return res ? 0 : -1;
151+}
152+
153+
154 int crypto_bignum_mulmod(const struct crypto_bignum *a,
155 const struct crypto_bignum *b,
156 const struct crypto_bignum *c,
157@@ -1472,6 +1512,48 @@ int crypto_bignum_mulmod(const struct crypto_bignum *a,
158 }
159
160
161+int crypto_bignum_sqrmod(const struct crypto_bignum *a,
162+ const struct crypto_bignum *b,
163+ struct crypto_bignum *c)
164+{
165+ int res;
166+ BN_CTX *bnctx;
167+
168+ if (TEST_FAIL())
169+ return -1;
170+
171+ bnctx = BN_CTX_new();
172+ if (!bnctx)
173+ return -1;
174+ res = BN_mod_sqr((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b,
175+ bnctx);
176+ BN_CTX_free(bnctx);
177+
178+ return res ? 0 : -1;
179+}
180+
181+
182+int crypto_bignum_sqrtmod(const struct crypto_bignum *a,
183+ const struct crypto_bignum *b,
184+ struct crypto_bignum *c)
185+{
186+ BN_CTX *bnctx;
187+ BIGNUM *res;
188+
189+ if (TEST_FAIL())
190+ return -1;
191+
192+ bnctx = BN_CTX_new();
193+ if (!bnctx)
194+ return -1;
195+ res = BN_mod_sqrt((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b,
196+ bnctx);
197+ BN_CTX_free(bnctx);
198+
199+ return res ? 0 : -1;
200+}
201+
202+
203 int crypto_bignum_rshift(const struct crypto_bignum *a, int n,
204 struct crypto_bignum *r)
205 {
206@@ -1682,6 +1764,18 @@ const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
207 }
208
209
210+const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e)
211+{
212+ return (const struct crypto_bignum *) e->a;
213+}
214+
215+
216+const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e)
217+{
218+ return (const struct crypto_bignum *) e->b;
219+}
220+
221+
222 void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
223 {
224 if (clear)
225diff --git a/src/crypto/crypto_wolfssl.c b/src/crypto/crypto_wolfssl.c
226index 4cedab4367cd..e9894b335e53 100644
227--- a/src/crypto/crypto_wolfssl.c
228+++ b/src/crypto/crypto_wolfssl.c
229@@ -1042,6 +1042,26 @@ struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len)
230 }
231
232
233+struct crypto_bignum * crypto_bignum_init_uint(unsigned int val)
234+{
235+ mp_int *a;
236+
237+ if (TEST_FAIL())
238+ return NULL;
239+
240+ a = (mp_int *) crypto_bignum_init();
241+ if (!a)
242+ return NULL;
243+
244+ if (mp_set_int(a, val) != MP_OKAY) {
245+ os_free(a);
246+ a = NULL;
247+ }
248+
249+ return (struct crypto_bignum *) a;
250+}
251+
252+
253 void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
254 {
255 if (!n)
256@@ -1168,6 +1188,19 @@ int crypto_bignum_div(const struct crypto_bignum *a,
257 }
258
259
260+int crypto_bignum_addmod(const struct crypto_bignum *a,
261+ const struct crypto_bignum *b,
262+ const struct crypto_bignum *c,
263+ struct crypto_bignum *d)
264+{
265+ if (TEST_FAIL())
266+ return -1;
267+
268+ return mp_addmod((mp_int *) a, (mp_int *) b, (mp_int *) c,
269+ (mp_int *) d) == MP_OKAY ? 0 : -1;
270+}
271+
272+
273 int crypto_bignum_mulmod(const struct crypto_bignum *a,
274 const struct crypto_bignum *b,
275 const struct crypto_bignum *m,
276@@ -1181,6 +1214,27 @@ int crypto_bignum_mulmod(const struct crypto_bignum *a,
277 }
278
279
280+int crypto_bignum_sqrmod(const struct crypto_bignum *a,
281+ const struct crypto_bignum *b,
282+ struct crypto_bignum *c)
283+{
284+ if (TEST_FAIL())
285+ return -1;
286+
287+ return mp_sqrmod((mp_int *) a, (mp_int *) b,
288+ (mp_int *) c) == MP_OKAY ? 0 : -1;
289+}
290+
291+
292+int crypto_bignum_sqrtmod(const struct crypto_bignum *a,
293+ const struct crypto_bignum *b,
294+ struct crypto_bignum *c)
295+{
296+ /* TODO */
297+ return -1;
298+}
299+
300+
301 int crypto_bignum_rshift(const struct crypto_bignum *a, int n,
302 struct crypto_bignum *r)
303 {
304@@ -1386,6 +1440,18 @@ const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
305 }
306
307
308+const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e)
309+{
310+ return (const struct crypto_bignum *) &e->a;
311+}
312+
313+
314+const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e)
315+{
316+ return (const struct crypto_bignum *) &e->b;
317+}
318+
319+
320 void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
321 {
322 ecc_point *point = (ecc_point *) p;
323--
3242.25.1
325
326From 2232d3d5f188b65dbb6c823ac62175412739eb16 Mon Sep 17 00:00:00 2001
327From: Jouni Malinen <j@w1.fi>
328Date: Fri, 7 Jan 2022 13:47:16 +0200
329Subject: [PATCH 2/4] dragonfly: Add sqrt() helper function
330
331This is a backport of "SAE: Move sqrt() implementation into a helper
332function" to introduce the helper function needed for the following
333patches.
334
335Signed-off-by: Jouni Malinen <j@w1.fi>
336---
337 src/common/dragonfly.c | 34 ++++++++++++++++++++++++++++++++++
338 src/common/dragonfly.h | 2 ++
339 2 files changed, 36 insertions(+)
340
341diff --git a/src/common/dragonfly.c b/src/common/dragonfly.c
342index 547be66f1561..1e842716668e 100644
343--- a/src/common/dragonfly.c
344+++ b/src/common/dragonfly.c
345@@ -213,3 +213,37 @@ int dragonfly_generate_scalar(const struct crypto_bignum *order,
346 "dragonfly: Unable to get randomness for own scalar");
347 return -1;
348 }
349+
350+
351+/* res = sqrt(val) */
352+int dragonfly_sqrt(struct crypto_ec *ec, const struct crypto_bignum *val,
353+ struct crypto_bignum *res)
354+{
355+ const struct crypto_bignum *prime;
356+ struct crypto_bignum *tmp, *one;
357+ int ret = 0;
358+ u8 prime_bin[DRAGONFLY_MAX_ECC_PRIME_LEN];
359+ size_t prime_len;
360+
361+ /* For prime p such that p = 3 mod 4, sqrt(w) = w^((p+1)/4) mod p */
362+
363+ prime = crypto_ec_get_prime(ec);
364+ prime_len = crypto_ec_prime_len(ec);
365+ tmp = crypto_bignum_init();
366+ one = crypto_bignum_init_uint(1);
367+
368+ if (crypto_bignum_to_bin(prime, prime_bin, sizeof(prime_bin),
369+ prime_len) < 0 ||
370+ (prime_bin[prime_len - 1] & 0x03) != 3 ||
371+ !tmp || !one ||
372+ /* tmp = (p+1)/4 */
373+ crypto_bignum_add(prime, one, tmp) < 0 ||
374+ crypto_bignum_rshift(tmp, 2, tmp) < 0 ||
375+ /* res = sqrt(val) */
376+ crypto_bignum_exptmod(val, tmp, prime, res) < 0)
377+ ret = -1;
378+
379+ crypto_bignum_deinit(tmp, 0);
380+ crypto_bignum_deinit(one, 0);
381+ return ret;
382+}
383diff --git a/src/common/dragonfly.h b/src/common/dragonfly.h
384index ec3dd593eda4..84d67f575c54 100644
385--- a/src/common/dragonfly.h
386+++ b/src/common/dragonfly.h
387@@ -27,5 +27,7 @@ int dragonfly_generate_scalar(const struct crypto_bignum *order,
388 struct crypto_bignum *_rand,
389 struct crypto_bignum *_mask,
390 struct crypto_bignum *scalar);
391+int dragonfly_sqrt(struct crypto_ec *ec, const struct crypto_bignum *val,
392+ struct crypto_bignum *res);
393
394 #endif /* DRAGONFLY_H */
395--
3962.25.1
397
398From fe534b0baaa8c0e6ddeb24cf529d6e50e33dc501 Mon Sep 17 00:00:00 2001
399From: Jouni Malinen <j@w1.fi>
400Date: Fri, 7 Jan 2022 13:47:16 +0200
401Subject: [PATCH 3/4] SAE: Derive the y coordinate for PWE with own
402 implementation
403
404The crypto_ec_point_solve_y_coord() wrapper function might not use
405constant time operations in the crypto library and as such, could leak
406side channel information about the password that is used to generate the
407PWE in the hunting and pecking loop. As such, calculate the two possible
408y coordinate values and pick the correct one to use with constant time
409selection.
410
411Signed-off-by: Jouni Malinen <j@w1.fi>
412---
413 src/common/sae.c | 47 +++++++++++++++++++++++++++++++++--------------
414 1 file changed, 33 insertions(+), 14 deletions(-)
415
416diff --git a/src/common/sae.c b/src/common/sae.c
417index 08fdbfd18173..8d79ed962768 100644
418--- a/src/common/sae.c
419+++ b/src/common/sae.c
420@@ -286,14 +286,16 @@ static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1,
421 int pwd_seed_odd = 0;
422 u8 prime[SAE_MAX_ECC_PRIME_LEN];
423 size_t prime_len;
424- struct crypto_bignum *x = NULL, *qr = NULL, *qnr = NULL;
425+ struct crypto_bignum *x = NULL, *y = NULL, *qr = NULL, *qnr = NULL;
426 u8 x_bin[SAE_MAX_ECC_PRIME_LEN];
427 u8 x_cand_bin[SAE_MAX_ECC_PRIME_LEN];
428 u8 qr_bin[SAE_MAX_ECC_PRIME_LEN];
429 u8 qnr_bin[SAE_MAX_ECC_PRIME_LEN];
430+ u8 x_y[2 * SAE_MAX_ECC_PRIME_LEN];
431 int res = -1;
432 u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
433 * mask */
434+ unsigned int is_eq;
435
436 os_memset(x_bin, 0, sizeof(x_bin));
437
438@@ -402,25 +404,42 @@ static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1,
439 goto fail;
440 }
441
442- if (!sae->tmp->pwe_ecc)
443- sae->tmp->pwe_ecc = crypto_ec_point_init(sae->tmp->ec);
444- if (!sae->tmp->pwe_ecc)
445- res = -1;
446- else
447- res = crypto_ec_point_solve_y_coord(sae->tmp->ec,
448- sae->tmp->pwe_ecc, x,
449- pwd_seed_odd);
450- if (res < 0) {
451- /*
452- * This should not happen since we already checked that there
453- * is a result.
454- */
455+ /* y = sqrt(x^3 + ax + b) mod p
456+ * if LSB(save) == LSB(y): PWE = (x, y)
457+ * else: PWE = (x, p - y)
458+ *
459+ * Calculate y and the two possible values for PWE and after that,
460+ * use constant time selection to copy the correct alternative.
461+ */
462+ y = crypto_ec_point_compute_y_sqr(sae->tmp->ec, x);
463+ if (!y ||
464+ dragonfly_sqrt(sae->tmp->ec, y, y) < 0 ||
465+ crypto_bignum_to_bin(y, x_y, SAE_MAX_ECC_PRIME_LEN,
466+ prime_len) < 0 ||
467+ crypto_bignum_sub(sae->tmp->prime, y, y) < 0 ||
468+ crypto_bignum_to_bin(y, x_y + SAE_MAX_ECC_PRIME_LEN,
469+ SAE_MAX_ECC_PRIME_LEN, prime_len) < 0) {
470 wpa_printf(MSG_DEBUG, "SAE: Could not solve y");
471+ goto fail;
472+ }
473+
474+ is_eq = const_time_eq(pwd_seed_odd, x_y[prime_len - 1] & 0x01);
475+ const_time_select_bin(is_eq, x_y, x_y + SAE_MAX_ECC_PRIME_LEN,
476+ prime_len, x_y + prime_len);
477+ os_memcpy(x_y, x_bin, prime_len);
478+ wpa_hexdump_key(MSG_DEBUG, "SAE: PWE", x_y, 2 * prime_len);
479+ crypto_ec_point_deinit(sae->tmp->pwe_ecc, 1);
480+ sae->tmp->pwe_ecc = crypto_ec_point_from_bin(sae->tmp->ec, x_y);
481+ if (!sae->tmp->pwe_ecc) {
482+ wpa_printf(MSG_DEBUG, "SAE: Could not generate PWE");
483+ res = -1;
484 }
485
486 fail:
487+ forced_memzero(x_y, sizeof(x_y));
488 crypto_bignum_deinit(qr, 0);
489 crypto_bignum_deinit(qnr, 0);
490+ crypto_bignum_deinit(y, 1);
491 os_free(dummy_password);
492 bin_clear_free(tmp_password, password_len);
493 crypto_bignum_deinit(x, 1);
494--
4952.25.1
496
497From 603cd880e7f90595482658a7136fa6a7be5cb485 Mon Sep 17 00:00:00 2001
498From: Jouni Malinen <j@w1.fi>
499Date: Fri, 7 Jan 2022 18:52:27 +0200
500Subject: [PATCH 4/4] EAP-pwd: Derive the y coordinate for PWE with own
501 implementation
502
503The crypto_ec_point_solve_y_coord() wrapper function might not use
504constant time operations in the crypto library and as such, could leak
505side channel information about the password that is used to generate the
506PWE in the hunting and pecking loop. As such, calculate the two possible
507y coordinate values and pick the correct one to use with constant time
508selection.
509
510Signed-off-by: Jouni Malinen <j@w1.fi>
511---
512 src/eap_common/eap_pwd_common.c | 46 ++++++++++++++++++++++++++-------
513 1 file changed, 36 insertions(+), 10 deletions(-)
514
515diff --git a/src/eap_common/eap_pwd_common.c b/src/eap_common/eap_pwd_common.c
516index 2b2b8efdbd01..ff22b29b087a 100644
517--- a/src/eap_common/eap_pwd_common.c
518+++ b/src/eap_common/eap_pwd_common.c
519@@ -127,7 +127,8 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
520 u8 qr_or_qnr_bin[MAX_ECC_PRIME_LEN];
521 u8 x_bin[MAX_ECC_PRIME_LEN];
522 u8 prime_bin[MAX_ECC_PRIME_LEN];
523- struct crypto_bignum *tmp2 = NULL;
524+ u8 x_y[2 * MAX_ECC_PRIME_LEN];
525+ struct crypto_bignum *tmp2 = NULL, *y = NULL;
526 struct crypto_hash *hash;
527 unsigned char pwe_digest[SHA256_MAC_LEN], *prfbuf = NULL, ctr;
528 int ret = 0, res;
529@@ -139,6 +140,7 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
530 u8 found_ctr = 0, is_odd = 0;
531 int cmp_prime;
532 unsigned int in_range;
533+ unsigned int is_eq;
534
535 if (grp->pwe)
536 return -1;
537@@ -151,11 +153,6 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
538 if (crypto_bignum_to_bin(prime, prime_bin, sizeof(prime_bin),
539 primebytelen) < 0)
540 return -1;
541- grp->pwe = crypto_ec_point_init(grp->group);
542- if (!grp->pwe) {
543- wpa_printf(MSG_INFO, "EAP-pwd: unable to create bignums");
544- goto fail;
545- }
546
547 if ((prfbuf = os_malloc(primebytelen)) == NULL) {
548 wpa_printf(MSG_INFO, "EAP-pwd: unable to malloc space for prf "
549@@ -261,10 +258,37 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
550 */
551 crypto_bignum_deinit(x_candidate, 1);
552 x_candidate = crypto_bignum_init_set(x_bin, primebytelen);
553- if (!x_candidate ||
554- crypto_ec_point_solve_y_coord(grp->group, grp->pwe, x_candidate,
555- is_odd) != 0) {
556- wpa_printf(MSG_INFO, "EAP-pwd: Could not solve for y");
557+ if (!x_candidate)
558+ goto fail;
559+
560+ /* y = sqrt(x^3 + ax + b) mod p
561+ * if LSB(y) == LSB(pwd-seed): PWE = (x, y)
562+ * else: PWE = (x, p - y)
563+ *
564+ * Calculate y and the two possible values for PWE and after that,
565+ * use constant time selection to copy the correct alternative.
566+ */
567+ y = crypto_ec_point_compute_y_sqr(grp->group, x_candidate);
568+ if (!y ||
569+ dragonfly_sqrt(grp->group, y, y) < 0 ||
570+ crypto_bignum_to_bin(y, x_y, MAX_ECC_PRIME_LEN, primebytelen) < 0 ||
571+ crypto_bignum_sub(prime, y, y) < 0 ||
572+ crypto_bignum_to_bin(y, x_y + MAX_ECC_PRIME_LEN,
573+ MAX_ECC_PRIME_LEN, primebytelen) < 0) {
574+ wpa_printf(MSG_DEBUG, "SAE: Could not solve y");
575+ goto fail;
576+ }
577+
578+ /* Constant time selection of the y coordinate from the two
579+ * options */
580+ is_eq = const_time_eq(is_odd, x_y[primebytelen - 1] & 0x01);
581+ const_time_select_bin(is_eq, x_y, x_y + MAX_ECC_PRIME_LEN,
582+ primebytelen, x_y + primebytelen);
583+ os_memcpy(x_y, x_bin, primebytelen);
584+ wpa_hexdump_key(MSG_DEBUG, "EAP-pwd: PWE", x_y, 2 * primebytelen);
585+ grp->pwe = crypto_ec_point_from_bin(grp->group, x_y);
586+ if (!grp->pwe) {
587+ wpa_printf(MSG_DEBUG, "EAP-pwd: Could not generate PWE");
588 goto fail;
589 }
590
591@@ -289,6 +313,7 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
592 /* cleanliness and order.... */
593 crypto_bignum_deinit(x_candidate, 1);
594 crypto_bignum_deinit(tmp2, 1);
595+ crypto_bignum_deinit(y, 1);
596 crypto_bignum_deinit(qr, 1);
597 crypto_bignum_deinit(qnr, 1);
598 bin_clear_free(prfbuf, primebytelen);
599@@ -296,6 +321,7 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
600 os_memset(qnr_bin, 0, sizeof(qnr_bin));
601 os_memset(qr_or_qnr_bin, 0, sizeof(qr_or_qnr_bin));
602 os_memset(pwe_digest, 0, sizeof(pwe_digest));
603+ forced_memzero(x_y, sizeof(x_y));
604
605 return ret;
606 }
607--
6082.25.1
609