diff options
| -rw-r--r-- | meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/CVE-2022-23303-4.patch | 609 | ||||
| -rw-r--r-- | meta/recipes-connectivity/wpa-supplicant/wpa-supplicant_2.9.bb | 1 |
2 files changed, 610 insertions, 0 deletions
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 @@ | |||
| 1 | From 208e5687ff2e48622e28d8888ce5444a54353bbd Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Jouni Malinen <jouni@codeaurora.org> | ||
| 3 | Date: Tue, 27 Aug 2019 16:33:15 +0300 | ||
| 4 | Subject: [PATCH 1/4] crypto: Add more bignum/EC helper functions | ||
| 5 | |||
| 6 | These are needed for implementing SAE hash-to-element. | ||
| 7 | |||
| 8 | Signed-off-by: Jouni Malinen <jouni@codeaurora.org> | ||
| 9 | |||
| 10 | Upstream-Status: Backport | ||
| 11 | https://w1.fi/security/2022-1/ | ||
| 12 | |||
| 13 | CVE: CVE-2022-23303 CVE-2022-23304 | ||
| 14 | Signed-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 | |||
| 22 | diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h | ||
| 23 | index 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 | * | ||
| 99 | diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c | ||
| 100 | index 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) | ||
| 225 | diff --git a/src/crypto/crypto_wolfssl.c b/src/crypto/crypto_wolfssl.c | ||
| 226 | index 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 | -- | ||
| 324 | 2.25.1 | ||
| 325 | |||
| 326 | From 2232d3d5f188b65dbb6c823ac62175412739eb16 Mon Sep 17 00:00:00 2001 | ||
| 327 | From: Jouni Malinen <j@w1.fi> | ||
| 328 | Date: Fri, 7 Jan 2022 13:47:16 +0200 | ||
| 329 | Subject: [PATCH 2/4] dragonfly: Add sqrt() helper function | ||
| 330 | |||
| 331 | This is a backport of "SAE: Move sqrt() implementation into a helper | ||
| 332 | function" to introduce the helper function needed for the following | ||
| 333 | patches. | ||
| 334 | |||
| 335 | Signed-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 | |||
| 341 | diff --git a/src/common/dragonfly.c b/src/common/dragonfly.c | ||
| 342 | index 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 | +} | ||
| 383 | diff --git a/src/common/dragonfly.h b/src/common/dragonfly.h | ||
| 384 | index 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 | -- | ||
| 396 | 2.25.1 | ||
| 397 | |||
| 398 | From fe534b0baaa8c0e6ddeb24cf529d6e50e33dc501 Mon Sep 17 00:00:00 2001 | ||
| 399 | From: Jouni Malinen <j@w1.fi> | ||
| 400 | Date: Fri, 7 Jan 2022 13:47:16 +0200 | ||
| 401 | Subject: [PATCH 3/4] SAE: Derive the y coordinate for PWE with own | ||
| 402 | implementation | ||
| 403 | |||
| 404 | The crypto_ec_point_solve_y_coord() wrapper function might not use | ||
| 405 | constant time operations in the crypto library and as such, could leak | ||
| 406 | side channel information about the password that is used to generate the | ||
| 407 | PWE in the hunting and pecking loop. As such, calculate the two possible | ||
| 408 | y coordinate values and pick the correct one to use with constant time | ||
| 409 | selection. | ||
| 410 | |||
| 411 | Signed-off-by: Jouni Malinen <j@w1.fi> | ||
| 412 | --- | ||
| 413 | src/common/sae.c | 47 +++++++++++++++++++++++++++++++++-------------- | ||
| 414 | 1 file changed, 33 insertions(+), 14 deletions(-) | ||
| 415 | |||
| 416 | diff --git a/src/common/sae.c b/src/common/sae.c | ||
| 417 | index 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 | -- | ||
| 495 | 2.25.1 | ||
| 496 | |||
| 497 | From 603cd880e7f90595482658a7136fa6a7be5cb485 Mon Sep 17 00:00:00 2001 | ||
| 498 | From: Jouni Malinen <j@w1.fi> | ||
| 499 | Date: Fri, 7 Jan 2022 18:52:27 +0200 | ||
| 500 | Subject: [PATCH 4/4] EAP-pwd: Derive the y coordinate for PWE with own | ||
| 501 | implementation | ||
| 502 | |||
| 503 | The crypto_ec_point_solve_y_coord() wrapper function might not use | ||
| 504 | constant time operations in the crypto library and as such, could leak | ||
| 505 | side channel information about the password that is used to generate the | ||
| 506 | PWE in the hunting and pecking loop. As such, calculate the two possible | ||
| 507 | y coordinate values and pick the correct one to use with constant time | ||
| 508 | selection. | ||
| 509 | |||
| 510 | Signed-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 | |||
| 515 | diff --git a/src/eap_common/eap_pwd_common.c b/src/eap_common/eap_pwd_common.c | ||
| 516 | index 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 | -- | ||
| 608 | 2.25.1 | ||
| 609 | |||
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant_2.9.bb b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant_2.9.bb index cddcfb6811..a8fb34b1a1 100644 --- a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant_2.9.bb +++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant_2.9.bb | |||
| @@ -33,6 +33,7 @@ SRC_URI = "http://w1.fi/releases/wpa_supplicant-${PV}.tar.gz \ | |||
| 33 | file://CVE-2021-0326.patch \ | 33 | file://CVE-2021-0326.patch \ |
| 34 | file://CVE-2021-27803.patch \ | 34 | file://CVE-2021-27803.patch \ |
| 35 | file://CVE-2021-30004.patch \ | 35 | file://CVE-2021-30004.patch \ |
| 36 | file://CVE-2022-23303-4.patch \ | ||
| 36 | " | 37 | " |
| 37 | SRC_URI[md5sum] = "2d2958c782576dc9901092fbfecb4190" | 38 | SRC_URI[md5sum] = "2d2958c782576dc9901092fbfecb4190" |
| 38 | SRC_URI[sha256sum] = "fcbdee7b4a64bea8177973299c8c824419c413ec2e3a95db63dd6a5dc3541f17" | 39 | SRC_URI[sha256sum] = "fcbdee7b4a64bea8177973299c8c824419c413ec2e3a95db63dd6a5dc3541f17" |
