EAP-pwd peer: Configurable set of groups with reduced default

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>
This commit is contained in:
Jouni Malinen 2019-07-23 13:16:59 +03:00 committed by Jouni Malinen
parent 1c63a1c4c6
commit 226da33d75

View 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;
}