diff mbox series

[v2,06/20] WPA: Extend the fils_pmk_to_ptk() function to also derive KDK

Message ID 20201216110033.8314-7-ilan.peer@intel.com
State Accepted
Headers show
Series Support base Pre association Security Negotiation (PASN) | expand

Commit Message

Peer, Ilan Dec. 16, 2020, 11 a.m. UTC
Extend the fils_pmk_to_ptk() to also derive Key Derivation
Key (KDK) 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(-)

Comments

Jouni Malinen Jan. 18, 2021, 5:14 p.m. UTC | #1
On Wed, Dec 16, 2020 at 01:00:19PM +0200, Ilan Peer wrote:
> Extend the fils_pmk_to_ptk() to also derive Key Derivation
> Key (KDK) which can later be used for secure LTF measurements.

> diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c
> @@ -682,9 +697,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->kdk_len) {
> +		os_memcpy(ptk->kdk, tmp + *ick_len + ptk->kek_len +
> +			  ptk->tk_len, ptk->kdk_len);
> +		wpa_hexdump_key(MSG_DEBUG, "FILS: KDK", ptk->kdk,
> +				ptk->kdk_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->kdk_len, *fils_ft_len);
>  		wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-FT",
>  				fils_ft, *fils_ft_len);
>  	}

This is in incorrect order, i.e., FILS-FT, if derived, is before KDK in
FILS-Key-Data. I've fixed this in my review version, so no need to send
an updated patch.
Peer, Ilan Jan. 19, 2021, 7:15 a.m. UTC | #2
> -----Original Message-----
> From: Jouni Malinen <j@w1.fi>
> Sent: Monday, January 18, 2021 19:14
> To: Peer, Ilan <ilan.peer@intel.com>
> Cc: hostap@lists.infradead.org
> Subject: Re: [PATCH v2 06/20] WPA: Extend the fils_pmk_to_ptk() function
> to also derive KDK
> 
> On Wed, Dec 16, 2020 at 01:00:19PM +0200, Ilan Peer wrote:
> > Extend the fils_pmk_to_ptk() to also derive Key Derivation Key (KDK)
> > which can later be used for secure LTF measurements.
> 
> > diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c
> @@
> > -682,9 +697,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->kdk_len) {
> > +		os_memcpy(ptk->kdk, tmp + *ick_len + ptk->kek_len +
> > +			  ptk->tk_len, ptk->kdk_len);
> > +		wpa_hexdump_key(MSG_DEBUG, "FILS: KDK", ptk->kdk,
> > +				ptk->kdk_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->kdk_len, *fils_ft_len);
> >  		wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-FT",
> >  				fils_ft, *fils_ft_len);
> >  	}
> 
> This is in incorrect order, i.e., FILS-FT, if derived, is before KDK in FILS-Key-
> Data. I've fixed this in my review version, so no need to send an updated
> patch.

Sure. 

Thanks,

Ilan.
diff mbox series

Patch

diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 65da18cbe9..dbba41d31a 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -2314,7 +2314,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.kdk ? WPA_KDK_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 4669aa24eb..092960cc25 100644
--- a/src/common/wpa_common.c
+++ b/src/common/wpa_common.c
@@ -593,12 +593,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 kdk_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_KDK_MAX_LEN];
 	size_t key_data_len;
 	const char *label = "FILS PTK Derivation";
 	int ret = -1;
@@ -609,6 +609,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)
+	 * KDK = L(FILS-Key-Data, ICK_bits + KEK_bits + TK_bits, KDK_bits)
+	 *
 	 * If doing FT initial mobility domain association:
 	 * FILS-FT = L(FILS-Key-Data, ICK_bits + KEK_bits + TK_bits,
 	 *             FILS-FT_bits)
@@ -640,6 +642,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 (kdk_len) {
+		if (kdk_len > WPA_KDK_MAX_LEN) {
+			wpa_printf(MSG_ERROR, "FILS: KDK len=%zu too big",
+				   kdk_len);
+			goto err;
+		}
+
+		ptk->kdk_len = kdk_len;
+		key_data_len += kdk_len;
+	} else {
+		ptk->kdk_len = 0;
+	}
+
 	if (fils_ft && fils_ft_len) {
 		if (akmp == WPA_KEY_MGMT_FT_FILS_SHA256) {
 			*fils_ft_len = 32;
@@ -682,9 +697,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->kdk_len) {
+		os_memcpy(ptk->kdk, tmp + *ick_len + ptk->kek_len +
+			  ptk->tk_len, ptk->kdk_len);
+		wpa_hexdump_key(MSG_DEBUG, "FILS: KDK", ptk->kdk,
+				ptk->kdk_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->kdk_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 7c1aef532b..8137062abd 100644
--- a/src/common/wpa_common.h
+++ b/src/common/wpa_common.h
@@ -391,7 +391,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 kdk_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 11003050d1..80364e9b7c 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -4350,7 +4350,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->kdk ? WPA_KDK_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 f7041b8cb9..61c7f6a4ce 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 */