X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fopenwrt.git;a=blobdiff_plain;f=package%2Fnetwork%2Fservices%2Fhostapd%2Fpatches%2F064-0014-EAP-pwd-Check-element-x-y-coordinates-explicitly.patch;fp=package%2Fnetwork%2Fservices%2Fhostapd%2Fpatches%2F064-0014-EAP-pwd-Check-element-x-y-coordinates-explicitly.patch;h=0000000000000000000000000000000000000000;hp=ab1edfaffcbffa1455a63e4a40e154d2f5aa8a92;hb=8af79550e6c280717660f66032d89d21007b15d2;hpb=a03219ba09a55ad49926e5c2d60ddff095fe5096 diff --git a/package/network/services/hostapd/patches/064-0014-EAP-pwd-Check-element-x-y-coordinates-explicitly.patch b/package/network/services/hostapd/patches/064-0014-EAP-pwd-Check-element-x-y-coordinates-explicitly.patch deleted file mode 100644 index ab1edfaffc..0000000000 --- a/package/network/services/hostapd/patches/064-0014-EAP-pwd-Check-element-x-y-coordinates-explicitly.patch +++ /dev/null @@ -1,320 +0,0 @@ -From 16d4f1069118aa19bfce013493e1ac5783f92f1d Mon Sep 17 00:00:00 2001 -From: Jouni Malinen -Date: Fri, 5 Apr 2019 02:12:50 +0300 -Subject: [PATCH 14/14] EAP-pwd: Check element x,y coordinates explicitly - -This adds an explicit check for 0 < x,y < prime based on RFC 5931, -2.8.5.2.2 requirement. The earlier checks might have covered this -implicitly, but it is safer to avoid any dependency on implicit checks -and specific crypto library behavior. (CVE-2019-9498 and CVE-2019-9499) - -Furthermore, this moves the EAP-pwd element and scalar parsing and -validation steps into shared helper functions so that there is no need -to maintain two separate copies of this common functionality between the -server and peer implementations. - -Signed-off-by: Jouni Malinen ---- - src/eap_common/eap_pwd_common.c | 106 ++++++++++++++++++++++++++++++++++++++++ - src/eap_common/eap_pwd_common.h | 3 ++ - src/eap_peer/eap_pwd.c | 45 ++--------------- - src/eap_server/eap_server_pwd.c | 45 ++--------------- - 4 files changed, 117 insertions(+), 82 deletions(-) - ---- a/src/eap_common/eap_pwd_common.c -+++ b/src/eap_common/eap_pwd_common.c -@@ -427,3 +427,109 @@ int compute_keys(EAP_PWD_group *grp, con - - return 1; - } -+ -+ -+static int eap_pwd_element_coord_ok(const struct crypto_bignum *prime, -+ const u8 *buf, size_t len) -+{ -+ struct crypto_bignum *val; -+ int ok = 1; -+ -+ val = crypto_bignum_init_set(buf, len); -+ if (!val || crypto_bignum_is_zero(val) || -+ crypto_bignum_cmp(val, prime) >= 0) -+ ok = 0; -+ crypto_bignum_deinit(val, 0); -+ return ok; -+} -+ -+ -+struct crypto_ec_point * eap_pwd_get_element(EAP_PWD_group *group, -+ const u8 *buf) -+{ -+ struct crypto_ec_point *element; -+ const struct crypto_bignum *prime; -+ size_t prime_len; -+ struct crypto_bignum *cofactor = NULL; -+ -+ prime = crypto_ec_get_prime(group->group); -+ prime_len = crypto_ec_prime_len(group->group); -+ -+ /* RFC 5931, 2.8.5.2.2: 0 < x,y < p */ -+ if (!eap_pwd_element_coord_ok(prime, buf, prime_len) || -+ !eap_pwd_element_coord_ok(prime, buf + prime_len, prime_len)) { -+ wpa_printf(MSG_INFO, "EAP-pwd: Invalid coordinate in element"); -+ return NULL; -+ } -+ -+ element = crypto_ec_point_from_bin(group->group, buf); -+ if (!element) { -+ wpa_printf(MSG_INFO, "EAP-pwd: EC point from element failed"); -+ return NULL; -+ } -+ -+ /* RFC 5931, 2.8.5.2.2: on curve and not the point at infinity */ -+ if (!crypto_ec_point_is_on_curve(group->group, element) || -+ crypto_ec_point_is_at_infinity(group->group, element)) { -+ wpa_printf(MSG_INFO, "EAP-pwd: Invalid element"); -+ goto fail; -+ } -+ -+ cofactor = crypto_bignum_init(); -+ if (!cofactor || crypto_ec_cofactor(group->group, cofactor) < 0) { -+ wpa_printf(MSG_INFO, -+ "EAP-pwd: Unable to get cofactor for curve"); -+ goto fail; -+ } -+ -+ if (!crypto_bignum_is_one(cofactor)) { -+ struct crypto_ec_point *point; -+ int ok = 1; -+ -+ /* check to ensure peer's element is not in a small sub-group */ -+ point = crypto_ec_point_init(group->group); -+ if (!point || -+ crypto_ec_point_mul(group->group, element, -+ cofactor, point) != 0 || -+ crypto_ec_point_is_at_infinity(group->group, point)) -+ ok = 0; -+ crypto_ec_point_deinit(point, 0); -+ -+ if (!ok) { -+ wpa_printf(MSG_INFO, -+ "EAP-pwd: Small sub-group check on peer element failed"); -+ goto fail; -+ } -+ } -+ -+out: -+ crypto_bignum_deinit(cofactor, 0); -+ return element; -+fail: -+ crypto_ec_point_deinit(element, 0); -+ element = NULL; -+ goto out; -+} -+ -+ -+struct crypto_bignum * eap_pwd_get_scalar(EAP_PWD_group *group, const u8 *buf) -+{ -+ struct crypto_bignum *scalar; -+ const struct crypto_bignum *order; -+ size_t order_len; -+ -+ order = crypto_ec_get_order(group->group); -+ order_len = crypto_ec_order_len(group->group); -+ -+ /* RFC 5931, 2.8.5.2: 1 < scalar < r */ -+ scalar = crypto_bignum_init_set(buf, order_len); -+ if (!scalar || crypto_bignum_is_zero(scalar) || -+ crypto_bignum_is_one(scalar) || -+ crypto_bignum_cmp(scalar, order) >= 0) { -+ wpa_printf(MSG_INFO, "EAP-pwd: received scalar is invalid"); -+ crypto_bignum_deinit(scalar, 0); -+ scalar = NULL; -+ } -+ -+ return scalar; -+} ---- a/src/eap_common/eap_pwd_common.h -+++ b/src/eap_common/eap_pwd_common.h -@@ -67,5 +67,8 @@ int compute_keys(EAP_PWD_group *grp, con - struct crypto_hash * eap_pwd_h_init(void); - void eap_pwd_h_update(struct crypto_hash *hash, const u8 *data, size_t len); - void eap_pwd_h_final(struct crypto_hash *hash, u8 *digest); -+struct crypto_ec_point * eap_pwd_get_element(EAP_PWD_group *group, -+ const u8 *buf); -+struct crypto_bignum * eap_pwd_get_scalar(EAP_PWD_group *group, const u8 *buf); - - #endif /* EAP_PWD_COMMON_H */ ---- a/src/eap_peer/eap_pwd.c -+++ b/src/eap_peer/eap_pwd.c -@@ -308,7 +308,7 @@ eap_pwd_perform_commit_exchange(struct e - const struct wpabuf *reqData, - const u8 *payload, size_t payload_len) - { -- struct crypto_ec_point *K = NULL, *point = NULL; -+ struct crypto_ec_point *K = NULL; - struct crypto_bignum *mask = NULL, *cofactor = NULL; - const u8 *ptr = payload; - u8 *scalar = NULL, *element = NULL; -@@ -572,63 +572,27 @@ eap_pwd_perform_commit_exchange(struct e - /* process the request */ - data->k = crypto_bignum_init(); - K = crypto_ec_point_init(data->grp->group); -- point = crypto_ec_point_init(data->grp->group); -- if (!data->k || !K || !point) { -+ if (!data->k || !K) { - wpa_printf(MSG_INFO, "EAP-PWD (peer): peer data allocation " - "fail"); - goto fin; - } - - /* element, x then y, followed by scalar */ -- data->server_element = crypto_ec_point_from_bin(data->grp->group, ptr); -+ data->server_element = eap_pwd_get_element(data->grp, ptr); - if (!data->server_element) { - wpa_printf(MSG_INFO, "EAP-PWD (peer): setting peer element " - "fail"); - goto fin; - } - ptr += prime_len * 2; -- data->server_scalar = crypto_bignum_init_set(ptr, order_len); -+ data->server_scalar = eap_pwd_get_scalar(data->grp, ptr); - if (!data->server_scalar) { - wpa_printf(MSG_INFO, - "EAP-PWD (peer): setting peer scalar fail"); - goto fin; - } - -- /* verify received scalar */ -- if (crypto_bignum_is_zero(data->server_scalar) || -- crypto_bignum_is_one(data->server_scalar) || -- crypto_bignum_cmp(data->server_scalar, -- crypto_ec_get_order(data->grp->group)) >= 0) { -- wpa_printf(MSG_INFO, -- "EAP-PWD (peer): received scalar is invalid"); -- goto fin; -- } -- -- /* verify received element */ -- if (!crypto_ec_point_is_on_curve(data->grp->group, -- data->server_element) || -- crypto_ec_point_is_at_infinity(data->grp->group, -- data->server_element)) { -- wpa_printf(MSG_INFO, -- "EAP-PWD (peer): received element is invalid"); -- goto fin; -- } -- -- /* check to ensure server's element is not in a small sub-group */ -- if (!crypto_bignum_is_one(cofactor)) { -- if (crypto_ec_point_mul(data->grp->group, data->server_element, -- cofactor, point) < 0) { -- wpa_printf(MSG_INFO, "EAP-PWD (peer): cannot multiply " -- "server element by order!\n"); -- goto fin; -- } -- if (crypto_ec_point_is_at_infinity(data->grp->group, point)) { -- wpa_printf(MSG_INFO, "EAP-PWD (peer): server element " -- "is at infinity!\n"); -- goto fin; -- } -- } -- - /* compute the shared key, k */ - if (crypto_ec_point_mul(data->grp->group, data->grp->pwe, - data->server_scalar, K) < 0 || -@@ -702,7 +666,6 @@ fin: - crypto_bignum_deinit(mask, 1); - crypto_bignum_deinit(cofactor, 1); - crypto_ec_point_deinit(K, 1); -- crypto_ec_point_deinit(point, 1); - if (data->outbuf == NULL) - eap_pwd_state(data, FAILURE); - else ---- a/src/eap_server/eap_server_pwd.c -+++ b/src/eap_server/eap_server_pwd.c -@@ -669,7 +669,7 @@ eap_pwd_process_commit_resp(struct eap_s - { - const u8 *ptr; - struct crypto_bignum *cofactor = NULL; -- struct crypto_ec_point *K = NULL, *point = NULL; -+ struct crypto_ec_point *K = NULL; - int res = 0; - size_t prime_len, order_len; - -@@ -688,9 +688,8 @@ eap_pwd_process_commit_resp(struct eap_s - - data->k = crypto_bignum_init(); - cofactor = crypto_bignum_init(); -- point = crypto_ec_point_init(data->grp->group); - K = crypto_ec_point_init(data->grp->group); -- if (!data->k || !cofactor || !point || !K) { -+ if (!data->k || !cofactor || !K) { - wpa_printf(MSG_INFO, "EAP-PWD (server): peer data allocation " - "fail"); - goto fin; -@@ -704,55 +703,20 @@ eap_pwd_process_commit_resp(struct eap_s - - /* element, x then y, followed by scalar */ - ptr = payload; -- data->peer_element = crypto_ec_point_from_bin(data->grp->group, ptr); -+ data->peer_element = eap_pwd_get_element(data->grp, ptr); - if (!data->peer_element) { - wpa_printf(MSG_INFO, "EAP-PWD (server): setting peer element " - "fail"); - goto fin; - } - ptr += prime_len * 2; -- data->peer_scalar = crypto_bignum_init_set(ptr, order_len); -+ data->peer_scalar = eap_pwd_get_scalar(data->grp, ptr); - if (!data->peer_scalar) { - wpa_printf(MSG_INFO, "EAP-PWD (server): peer data allocation " - "fail"); - goto fin; - } - -- /* verify received scalar */ -- if (crypto_bignum_is_zero(data->peer_scalar) || -- crypto_bignum_is_one(data->peer_scalar) || -- crypto_bignum_cmp(data->peer_scalar, -- crypto_ec_get_order(data->grp->group)) >= 0) { -- wpa_printf(MSG_INFO, -- "EAP-PWD (server): received scalar is invalid"); -- goto fin; -- } -- -- /* verify received element */ -- if (!crypto_ec_point_is_on_curve(data->grp->group, -- data->peer_element) || -- crypto_ec_point_is_at_infinity(data->grp->group, -- data->peer_element)) { -- wpa_printf(MSG_INFO, -- "EAP-PWD (server): received element is invalid"); -- goto fin; -- } -- -- /* check to ensure peer's element is not in a small sub-group */ -- if (!crypto_bignum_is_one(cofactor)) { -- if (crypto_ec_point_mul(data->grp->group, data->peer_element, -- cofactor, point) != 0) { -- wpa_printf(MSG_INFO, "EAP-PWD (server): cannot " -- "multiply peer element by order"); -- goto fin; -- } -- if (crypto_ec_point_is_at_infinity(data->grp->group, point)) { -- wpa_printf(MSG_INFO, "EAP-PWD (server): peer element " -- "is at infinity!\n"); -- goto fin; -- } -- } -- - /* detect reflection attacks */ - if (crypto_bignum_cmp(data->my_scalar, data->peer_scalar) == 0 || - crypto_ec_point_cmp(data->grp->group, data->my_element, -@@ -804,7 +768,6 @@ eap_pwd_process_commit_resp(struct eap_s - - fin: - crypto_ec_point_deinit(K, 1); -- crypto_ec_point_deinit(point, 1); - crypto_bignum_deinit(cofactor, 1); - - if (res)