EAP-PEAP: Derive EMSK and use 128-octet derivation for MSK
Derive EMSK when using EAP-PEAP to enable ERP. In addition, change the MSK derivation for EAP-PEAP to always derive 128 octets of key material instead of the 64 octets to cover just the MSK. This is needed with the PRF used in TLS 1.3 since the output length is mixed into the PRF context. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
a2674fd902
commit
4e1cd3468e
2 changed files with 72 additions and 6 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* EAP peer method: EAP-PEAP (draft-josefsson-pppext-eap-tls-eap-10.txt)
|
||||
* Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
|
@ -169,7 +169,7 @@ static void * eap_peap_init(struct eap_sm *sm)
|
|||
static void eap_peap_free_key(struct eap_peap_data *data)
|
||||
{
|
||||
if (data->key_data) {
|
||||
bin_clear_free(data->key_data, EAP_TLS_KEY_LEN);
|
||||
bin_clear_free(data->key_data, EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
|
||||
data->key_data = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -1081,12 +1081,18 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
|
|||
"key derivation", label);
|
||||
data->key_data =
|
||||
eap_peer_tls_derive_key(sm, &data->ssl, label,
|
||||
EAP_TLS_KEY_LEN);
|
||||
EAP_TLS_KEY_LEN +
|
||||
EAP_EMSK_LEN);
|
||||
if (data->key_data) {
|
||||
wpa_hexdump_key(MSG_DEBUG,
|
||||
"EAP-PEAP: Derived key",
|
||||
data->key_data,
|
||||
EAP_TLS_KEY_LEN);
|
||||
wpa_hexdump_key(MSG_DEBUG,
|
||||
"EAP-PEAP: Derived EMSK",
|
||||
data->key_data +
|
||||
EAP_TLS_KEY_LEN,
|
||||
EAP_EMSK_LEN);
|
||||
} else {
|
||||
wpa_printf(MSG_DEBUG, "EAP-PEAP: Failed to "
|
||||
"derive key");
|
||||
|
@ -1264,6 +1270,29 @@ static u8 * eap_peap_getKey(struct eap_sm *sm, void *priv, size_t *len)
|
|||
}
|
||||
|
||||
|
||||
static u8 * eap_peap_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
|
||||
{
|
||||
struct eap_peap_data *data = priv;
|
||||
u8 *key;
|
||||
|
||||
if (!data->key_data || !data->phase2_success)
|
||||
return NULL;
|
||||
|
||||
if (data->crypto_binding_used) {
|
||||
/* [MS-PEAP] does not define EMSK derivation */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
key = os_memdup(data->key_data + EAP_TLS_KEY_LEN, EAP_EMSK_LEN);
|
||||
if (!key)
|
||||
return NULL;
|
||||
|
||||
*len = EAP_EMSK_LEN;
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
static u8 * eap_peap_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
|
||||
{
|
||||
struct eap_peap_data *data = priv;
|
||||
|
@ -1296,6 +1325,7 @@ int eap_peer_peap_register(void)
|
|||
eap->process = eap_peap_process;
|
||||
eap->isKeyAvailable = eap_peap_isKeyAvailable;
|
||||
eap->getKey = eap_peap_getKey;
|
||||
eap->get_emsk = eap_peap_get_emsk;
|
||||
eap->get_status = eap_peap_get_status;
|
||||
eap->has_reauth_data = eap_peap_has_reauth_data;
|
||||
eap->deinit_for_reauth = eap_peap_deinit_for_reauth;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* hostapd / EAP-PEAP (draft-josefsson-pppext-eap-tls-eap-10.txt)
|
||||
* Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
|
@ -756,7 +756,7 @@ static void eap_peap_process_phase2_tlv(struct eap_sm *sm,
|
|||
} else {
|
||||
eap_peap_state(data, FAILURE);
|
||||
}
|
||||
|
||||
|
||||
} else if (status == EAP_TLV_RESULT_FAILURE) {
|
||||
wpa_printf(MSG_INFO, "EAP-PEAP: TLV Result - Failure "
|
||||
"- requested %s", requested);
|
||||
|
@ -1328,8 +1328,9 @@ static u8 * eap_peap_getKey(struct eap_sm *sm, void *priv, size_t *len)
|
|||
/* TODO: PEAPv1 - different label in some cases */
|
||||
eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
|
||||
"client EAP encryption",
|
||||
EAP_TLS_KEY_LEN);
|
||||
EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
|
||||
if (eapKeyData) {
|
||||
os_memset(eapKeyData + EAP_TLS_KEY_LEN, 0, EAP_EMSK_LEN);
|
||||
*len = EAP_TLS_KEY_LEN;
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Derived key",
|
||||
eapKeyData, EAP_TLS_KEY_LEN);
|
||||
|
@ -1341,6 +1342,40 @@ static u8 * eap_peap_getKey(struct eap_sm *sm, void *priv, size_t *len)
|
|||
}
|
||||
|
||||
|
||||
static u8 * eap_peap_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
|
||||
{
|
||||
struct eap_peap_data *data = priv;
|
||||
u8 *eapKeyData, *emsk;
|
||||
|
||||
if (data->state != SUCCESS)
|
||||
return NULL;
|
||||
|
||||
if (data->crypto_binding_used) {
|
||||
/* [MS-PEAP] does not define EMSK derivation */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* TODO: PEAPv1 - different label in some cases */
|
||||
eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
|
||||
"client EAP encryption",
|
||||
EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
|
||||
if (eapKeyData) {
|
||||
emsk = os_memdup(eapKeyData + EAP_TLS_KEY_LEN, EAP_EMSK_LEN);
|
||||
bin_clear_free(eapKeyData, EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
|
||||
if (!emsk)
|
||||
return NULL;
|
||||
*len = EAP_EMSK_LEN;
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Derived EMSK",
|
||||
emsk, EAP_EMSK_LEN);
|
||||
} else {
|
||||
wpa_printf(MSG_DEBUG, "EAP-PEAP: Failed to derive EMSK");
|
||||
emsk = NULL;
|
||||
}
|
||||
|
||||
return emsk;
|
||||
}
|
||||
|
||||
|
||||
static Boolean eap_peap_isSuccess(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
struct eap_peap_data *data = priv;
|
||||
|
@ -1376,6 +1411,7 @@ int eap_server_peap_register(void)
|
|||
eap->process = eap_peap_process;
|
||||
eap->isDone = eap_peap_isDone;
|
||||
eap->getKey = eap_peap_getKey;
|
||||
eap->get_emsk = eap_peap_get_emsk;
|
||||
eap->isSuccess = eap_peap_isSuccess;
|
||||
eap->getSessionId = eap_peap_get_session_id;
|
||||
|
||||
|
|
Loading…
Reference in a new issue