hostapd: Update to version 2.8 (2019-04-21)
[openwrt/openwrt.git] / package / network / services / hostapd / patches / 064-0014-EAP-pwd-Check-element-x-y-coordinates-explicitly.patch
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 (file)
index ab1edfa..0000000
+++ /dev/null
@@ -1,320 +0,0 @@
-From 16d4f1069118aa19bfce013493e1ac5783f92f1d Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-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 <jouni@codeaurora.org>
----
- 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)