[PATCH 12/12] WPA: Extend the fils_pmk_to_ptk() function to also derive HLTK

Ilan Peer <[email protected]>
Newsgroups gmane.linux.drivers.hostap
Message-ID <[email protected]>
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 <[email protected]>
---
 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(-)

diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index d77c0b02f6..52eeedea13 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -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;
diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c
index 24cfcaba50..deae2a35f9 100644
--- a/src/common/wpa_common.c
+++ b/src/common/wpa_common.c
@@ -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);
 	}
diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h
index 3815584964..57d47f03eb 100644
--- a/src/common/wpa_common.h
+++ b/src/common/wpa_common.h
@@ -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,
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 6841bcf0a7..4a64fbb455 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -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;
 	}
diff --git a/wlantest/rx_mgmt.c b/wlantest/rx_mgmt.c
index 6729371508..561f6b63c1 100644
--- a/wlantest/rx_mgmt.c
+++ b/wlantest/rx_mgmt.c
@@ -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 */
-- 
2.17.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.