@@ -2313,7 +2313,8 @@ int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk,
snonce, anonce, dhss, dhss_len,
&sm->PTK, ick, &ick_len,
sm->wpa_key_mgmt, sm->pairwise,
- fils_ft, &fils_ft_len);
+ fils_ft, &fils_ft_len,
+ sm->wpa_auth->conf.hltk ? WPA_HLTK_MAX_LEN : 0);
if (res < 0)
return res;
sm->PTK_valid = TRUE;
@@ -584,12 +584,12 @@ int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
const u8 *snonce, const u8 *anonce, const u8 *dhss,
size_t dhss_len, struct wpa_ptk *ptk,
u8 *ick, size_t *ick_len, int akmp, int cipher,
- u8 *fils_ft, size_t *fils_ft_len)
+ u8 *fils_ft, size_t *fils_ft_len, size_t hltk_len)
{
u8 *data, *pos;
size_t data_len;
u8 tmp[FILS_ICK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
- FILS_FT_MAX_LEN];
+ FILS_FT_MAX_LEN + WPA_HLTK_MAX_LEN];
size_t key_data_len;
const char *label = "FILS PTK Derivation";
int ret = -1;
@@ -600,6 +600,8 @@ int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
* ICK = L(FILS-Key-Data, 0, ICK_bits)
* KEK = L(FILS-Key-Data, ICK_bits, KEK_bits)
* TK = L(FILS-Key-Data, ICK_bits + KEK_bits, TK_bits)
+ * HLTK = L(FILS-Key-Data, ICK_bits + KEK_bits + TK_bits, HLTK_bits)
+ *
* If doing FT initial mobility domain association:
* FILS-FT = L(FILS-Key-Data, ICK_bits + KEK_bits + TK_bits,
* FILS-FT_bits)
@@ -631,6 +633,19 @@ int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
goto err;
key_data_len = *ick_len + ptk->kek_len + ptk->tk_len;
+ if (hltk_len) {
+ if (hltk_len > WPA_HLTK_MAX_LEN) {
+ wpa_printf(MSG_ERROR, "FILS: HLTK len=%zu too big",
+ hltk_len);
+ goto err;
+ }
+
+ ptk->hltk_len = hltk_len;
+ key_data_len += hltk_len;
+ } else {
+ ptk->hltk_len = 0;
+ }
+
if (fils_ft && fils_ft_len) {
if (akmp == WPA_KEY_MGMT_FT_FILS_SHA256) {
*fils_ft_len = 32;
@@ -673,9 +688,16 @@ 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);
+ if (ptk->hltk_len) {
+ os_memcpy(ptk->hltk, tmp + *ick_len + ptk->kek_len +
+ ptk->tk_len, ptk->hltk_len);
+ wpa_hexdump_key(MSG_DEBUG, "FILS: HLTK", ptk->hltk,
+ ptk->hltk_len);
+ }
+
if (fils_ft && fils_ft_len) {
- os_memcpy(fils_ft, tmp + *ick_len + ptk->kek_len + ptk->tk_len,
- *fils_ft_len);
+ os_memcpy(fils_ft, tmp + *ick_len + ptk->kek_len + ptk->tk_len +
+ ptk->hltk_len, *fils_ft_len);
wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-FT",
fils_ft, *fils_ft_len);
}
@@ -369,7 +369,7 @@ int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
const u8 *snonce, const u8 *anonce, const u8 *dhss,
size_t dhss_len, struct wpa_ptk *ptk,
u8 *ick, size_t *ick_len, int akmp, int cipher,
- u8 *fils_ft, size_t *fils_ft_len);
+ u8 *fils_ft, size_t *fils_ft_len, size_t hltk_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,
@@ -4144,7 +4144,8 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data,
dh_ss ? wpabuf_len(dh_ss) : 0,
&sm->ptk, ick, &ick_len,
sm->key_mgmt, sm->pairwise_cipher,
- sm->fils_ft, &sm->fils_ft_len) < 0) {
+ sm->fils_ft, &sm->fils_ft_len,
+ sm->hltk ? WPA_HLTK_MAX_LEN : 0) < 0) {
wpa_printf(MSG_DEBUG, "FILS: Failed to derive PTK");
goto fail;
}
@@ -494,7 +494,7 @@ static int try_rmsk(struct wlantest *wt, struct wlantest_bss *bss,
sta->snonce, sta->anonce, NULL, 0,
&ptk, ick, &ick_len,
sta->key_mgmt, sta->pairwise_cipher,
- NULL, NULL) < 0)
+ NULL, NULL, 0) < 0)
return -1;
/* Check AES-SIV decryption with the derived key */
Extend the fils_pmk_to_ptk() to also derive High Level Transient Key (HLTK) which can later be used for secure LTF measurements. Signed-off-by: Ilan Peer <ilan.peer@intel.com> --- src/ap/wpa_auth.c | 3 ++- src/common/wpa_common.c | 30 ++++++++++++++++++++++++++---- src/common/wpa_common.h | 2 +- src/rsn_supp/wpa.c | 3 ++- wlantest/rx_mgmt.c | 2 +- 5 files changed, 32 insertions(+), 8 deletions(-)