summaryrefslogtreecommitdiffstats
path: root/package/network/services/hostapd/patches/084-EAP-pwd-Derive-the-y-coordinate-for-PWE-with-own-imp.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/network/services/hostapd/patches/084-EAP-pwd-Derive-the-y-coordinate-for-PWE-with-own-imp.patch')
-rw-r--r--package/network/services/hostapd/patches/084-EAP-pwd-Derive-the-y-coordinate-for-PWE-with-own-imp.patch108
1 files changed, 108 insertions, 0 deletions
diff --git a/package/network/services/hostapd/patches/084-EAP-pwd-Derive-the-y-coordinate-for-PWE-with-own-imp.patch b/package/network/services/hostapd/patches/084-EAP-pwd-Derive-the-y-coordinate-for-PWE-with-own-imp.patch
new file mode 100644
index 0000000000..c5ddddcec3
--- /dev/null
+++ b/package/network/services/hostapd/patches/084-EAP-pwd-Derive-the-y-coordinate-for-PWE-with-own-imp.patch
@@ -0,0 +1,108 @@
+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 | 46 ++++++++++++++++++++++++++-------
+ 1 file changed, 36 insertions(+), 10 deletions(-)
+
+--- a/src/eap_common/eap_pwd_common.c
++++ b/src/eap_common/eap_pwd_common.c
+@@ -127,7 +127,8 @@ int compute_password_element(EAP_PWD_gro
+ 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 *tmp2 = NULL;
++ u8 x_y[2 * MAX_ECC_PRIME_LEN];
++ struct crypto_bignum *tmp2 = NULL, *y = NULL;
+ struct crypto_hash *hash;
+ unsigned char pwe_digest[SHA256_MAC_LEN], *prfbuf = NULL, ctr;
+ int ret = 0, res;
+@@ -139,6 +140,7 @@ int compute_password_element(EAP_PWD_gro
+ u8 found_ctr = 0, is_odd = 0;
+ int cmp_prime;
+ unsigned int in_range;
++ unsigned int is_eq;
+
+ if (grp->pwe)
+ return -1;
+@@ -151,11 +153,6 @@ int compute_password_element(EAP_PWD_gro
+ if (crypto_bignum_to_bin(prime, prime_bin, sizeof(prime_bin),
+ primebytelen) < 0)
+ return -1;
+- grp->pwe = crypto_ec_point_init(grp->group);
+- if (!grp->pwe) {
+- wpa_printf(MSG_INFO, "EAP-pwd: unable to create bignums");
+- goto fail;
+- }
+
+ if ((prfbuf = os_malloc(primebytelen)) == NULL) {
+ wpa_printf(MSG_INFO, "EAP-pwd: unable to malloc space for prf "
+@@ -261,10 +258,37 @@ int compute_password_element(EAP_PWD_gro
+ */
+ 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;
+ }
+
+@@ -289,6 +313,7 @@ int compute_password_element(EAP_PWD_gro
+ /* cleanliness and order.... */
+ crypto_bignum_deinit(x_candidate, 1);
+ crypto_bignum_deinit(tmp2, 1);
++ crypto_bignum_deinit(y, 1);
+ crypto_bignum_deinit(qr, 1);
+ crypto_bignum_deinit(qnr, 1);
+ bin_clear_free(prfbuf, primebytelen);
+@@ -296,6 +321,7 @@ int compute_password_element(EAP_PWD_gro
+ 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;
+ }