FILS: Implement FILS-FT derivation

This extends fils_pmk_to_ptk() to allow FILS-FT to be derived. The
callers do not yet use that capability; i.e., actual use will be added
in separate commits.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2017-05-07 11:47:44 +03:00
parent 80ddf5d995
commit 215eaa748b
4 changed files with 28 additions and 7 deletions

View file

@ -2092,7 +2092,7 @@ int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk,
res = fils_pmk_to_ptk(pmk, pmk_len, sm->addr, sm->wpa_auth->addr,
snonce, anonce, &sm->PTK, ick, &ick_len,
sm->wpa_key_mgmt, sm->pairwise);
sm->wpa_key_mgmt, sm->pairwise, NULL, NULL);
if (res < 0)
return res;
sm->PTK_valid = TRUE;

View file

@ -339,10 +339,12 @@ int fils_pmkid_erp(int akmp, const u8 *reauth, size_t reauth_len,
int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
const u8 *snonce, const u8 *anonce, struct wpa_ptk *ptk,
u8 *ick, size_t *ick_len, int akmp, int cipher)
u8 *ick, size_t *ick_len, int akmp, int cipher,
u8 *fils_ft, size_t *fils_ft_len)
{
u8 data[2 * ETH_ALEN + 2 * FILS_NONCE_LEN];
u8 tmp[FILS_ICK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN];
u8 tmp[FILS_ICK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
FILS_FT_MAX_LEN];
size_t key_data_len;
const char *label = "FILS PTK Derivation";
@ -372,6 +374,18 @@ int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
return -1;
key_data_len = *ick_len + ptk->kek_len + ptk->tk_len;
if (fils_ft && fils_ft_len) {
if (akmp == WPA_KEY_MGMT_FT_FILS_SHA256) {
*fils_ft_len = 32;
} else if (akmp == WPA_KEY_MGMT_FT_FILS_SHA384) {
*fils_ft_len = 48;
} else {
*fils_ft_len = 0;
fils_ft = NULL;
}
key_data_len += *fils_ft_len;
}
if (wpa_key_mgmt_sha384(akmp)) {
wpa_printf(MSG_DEBUG, "FILS: PTK derivation using PRF(SHA384)");
if (sha384_prf(pmk, pmk_len, label, data, sizeof(data),
@ -400,7 +414,12 @@ int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
os_memcpy(ptk->tk, tmp + *ick_len + ptk->kek_len, ptk->tk_len);
wpa_hexdump_key(MSG_DEBUG, "FILS: TK", ptk->tk, ptk->tk_len);
/* TODO: FILS-FT */
if (fils_ft && fils_ft_len) {
os_memcpy(fils_ft, tmp + *ick_len + ptk->kek_len + ptk->tk_len,
*fils_ft_len);
wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-FT",
fils_ft, *fils_ft_len);
}
os_memset(tmp, 0, sizeof(tmp));
return 0;

View file

@ -202,6 +202,7 @@ struct wpa_eapol_key {
#define WPA_KEK_MAX_LEN 64
#define WPA_TK_MAX_LEN 32
#define FILS_ICK_MAX_LEN 48
#define FILS_FT_MAX_LEN 48
/**
* struct wpa_ptk - WPA Pairwise Transient Key
@ -346,7 +347,8 @@ int fils_pmkid_erp(int akmp, const u8 *reauth, size_t reauth_len,
u8 *pmkid);
int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
const u8 *snonce, const u8 *anonce, struct wpa_ptk *ptk,
u8 *ick, size_t *ick_len, int akmp, int cipher);
u8 *ick, size_t *ick_len, int akmp, int cipher,
u8 *fils_ft, size_t *fils_ft_len);
int fils_key_auth_sk(const u8 *ick, size_t ick_len, const u8 *snonce,
const u8 *anonce, const u8 *sta_addr, const u8 *bssid,
const u8 *g_sta, size_t g_sta_len,

View file

@ -3603,8 +3603,8 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data,
if (fils_pmk_to_ptk(sm->pmk, sm->pmk_len, sm->own_addr, sm->bssid,
sm->fils_nonce, sm->fils_anonce, &sm->ptk,
ick, &ick_len, sm->key_mgmt, sm->pairwise_cipher) <
0) {
ick, &ick_len, sm->key_mgmt, sm->pairwise_cipher,
NULL, NULL) < 0) {
wpa_printf(MSG_DEBUG, "FILS: Failed to derive PTK");
goto fail;
}