]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
EAP-pwd peer: Configurable set of groups with reduced default
authorJouni Malinen <jouni@codeaurora.org>
Tue, 23 Jul 2019 10:16:59 +0000 (13:16 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 23 Jul 2019 10:16:59 +0000 (13:16 +0300)
Make the EAP-pwd peer use same default set of allowed groups as the SAE
implementation in wpa_supplicant uses, i.e., the groups 19-21 using NIST
curves P-256, P-384, and P-521. Previously, all groups that were
supported by the crypto library were allowed. In practice, this change
disables use of the Brainpool curves (groups 28-30) with recent OpenSSL
versions.

The default set of groups can be overridden with a new phase1 network
profile parameter, eap_pwd_groups=<list of allowed ranges>. For example,
phase1="eap_pwd_groups=0-65535" would restore previous behavior of
allowing all implemented groups to be used while eap_pwd_groups=19,20
would enable only the groups using NIST curves P-256 and P-384 to be
used.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
src/eap_peer/eap_pwd.c

index 6cd72e0c13916a905f35d6b25ea1283b3f5b9a4f..54f102a3b04384a131a32a01751e4f3bed7c86ae 100644 (file)
@@ -30,6 +30,7 @@ struct eap_pwd_data {
        u8 *password;
        size_t password_len;
        int password_hash;
+       struct wpa_freq_range_list allowed_groups;
        u16 group_num;
        u8 prep;
        u8 token[4];
@@ -54,6 +55,9 @@ struct eap_pwd_data {
 };
 
 
+static void eap_pwd_deinit(struct eap_sm *sm, void *priv);
+
+
 #ifndef CONFIG_NO_STDOUT_DEBUG
 static const char * eap_pwd_state_txt(int state)
 {
@@ -92,6 +96,7 @@ static void * eap_pwd_init(struct eap_sm *sm)
        size_t identity_len, password_len;
        int fragment_size;
        int pwhash;
+       const char *phase1;
 
        password = eap_get_config_password2(sm, &password_len, &pwhash);
        if (password == NULL) {
@@ -129,6 +134,30 @@ static void * eap_pwd_init(struct eap_sm *sm)
        data->password_len = password_len;
        data->password_hash = pwhash;
 
+       phase1 = eap_get_config_phase1(sm);
+       if (phase1) {
+               const char *pos, *end;
+               char *copy = NULL;
+               int res;
+
+               pos = os_strstr(phase1, "eap_pwd_groups=");
+               if (pos) {
+                       pos += 15;
+                       end = os_strchr(pos, ' ');
+                       if (end) {
+                               copy = os_zalloc(end - pos + 1);
+                               if (!copy)
+                                       goto fail;
+                               os_memcpy(copy, pos, end - pos);
+                               pos = copy;
+                       }
+                       res = freq_range_list_parse(&data->allowed_groups, pos);
+                       os_free(copy);
+                       if (res)
+                               goto fail;
+               }
+       }
+
        data->out_frag_pos = data->in_frag_pos = 0;
        data->inbuf = data->outbuf = NULL;
        fragment_size = eap_get_config_fragment_size(sm);
@@ -140,6 +169,9 @@ static void * eap_pwd_init(struct eap_sm *sm)
        data->state = PWD_ID_Req;
 
        return data;
+fail:
+       eap_pwd_deinit(sm, data);
+       return NULL;
 }
 
 
@@ -163,6 +195,7 @@ static void eap_pwd_deinit(struct eap_sm *sm, void *priv)
        }
        wpabuf_free(data->inbuf);
        wpabuf_free(data->outbuf);
+       os_free(data->allowed_groups.range);
        bin_clear_free(data, sizeof(*data));
 }
 
@@ -203,6 +236,18 @@ static u8 * eap_pwd_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
 }
 
 
+static int eap_pwd_allowed_group(struct eap_pwd_data *data, u16 group)
+{
+       if (!data->allowed_groups.range) {
+               /* By default, allow the groups using NIST curves P-256, P-384,
+                * and P-521. */
+               return group == 19 || group == 20 || group == 21;
+       }
+
+       return freq_range_list_includes(&data->allowed_groups, group);
+}
+
+
 static void
 eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
                            struct eap_method_ret *ret,
@@ -228,9 +273,11 @@ eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
        wpa_printf(MSG_DEBUG,
                   "EAP-PWD: Server EAP-pwd-ID proposal: group=%u random=%u prf=%u prep=%u",
                   data->group_num, id->random_function, id->prf, id->prep);
-       if ((id->random_function != EAP_PWD_DEFAULT_RAND_FUNC) ||
-           (id->prf != EAP_PWD_DEFAULT_PRF)) {
-               ret->ignore = TRUE;
+       if (id->random_function != EAP_PWD_DEFAULT_RAND_FUNC ||
+           id->prf != EAP_PWD_DEFAULT_PRF ||
+           !eap_pwd_allowed_group(data, data->group_num)) {
+               wpa_printf(MSG_INFO,
+                          "EAP-pwd: Unsupported or disabled proposal");
                eap_pwd_state(data, FAILURE);
                return;
        }