[RFC v2 71/99] NAN: Add ND-PMK derivation API in nan_crypto.c

Andrei Otcheretianski andrei.otcheretianski at intel.com
Tue Dec 23 03:52:15 PST 2025


This function will be used to derive PMK from password for secure NDP
establishment.
Add it to module tests as well.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
 src/nan/nan.h              |  3 +++
 src/nan/nan_crypto.c       | 24 ++++++++++++++++++++++++
 src/nan/nan_module_tests.c | 26 +++++++++++++++++++++++++-
 3 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/src/nan/nan.h b/src/nan/nan.h
index 862d852f83..ddb7179a18 100644
--- a/src/nan/nan.h
+++ b/src/nan/nan.h
@@ -545,4 +545,7 @@ bool nan_peer_npk_nik_caching_supported(struct nan_data *nan, const u8 *addr);
 int nan_get_peer_ndc_freq(struct nan_data *nan ,
 			  struct nan_peer_schedule *peer_sched,
 			  u8 map_idx);
+int nan_crypto_derive_nd_pmk(const char *pwd, const u8 *service_id,
+			     enum nan_cipher_suite_id csid,
+			     const u8 *peer_nmi, u8 *nd_pmk);
 #endif /* NAN_H */
diff --git a/src/nan/nan_crypto.c b/src/nan/nan_crypto.c
index 9dceb2f648..1aff8bc13d 100644
--- a/src/nan/nan_crypto.c
+++ b/src/nan/nan_crypto.c
@@ -396,3 +396,27 @@ int nan_crypto_key_mic(const u8 *buf, size_t len, const u8 *kck,
 	wpa_hexdump_key(MSG_DEBUG, "MIC", mic, mic_len);
 	return 0;
 }
+
+
+int nan_crypto_derive_nd_pmk(const char *pwd, const u8 *service_id,
+			     enum nan_cipher_suite_id csid,
+			     const u8 *peer_nmi, u8 *nd_pmk)
+{
+	u8 salt[1 + 1 + NAN_SERVICE_ID_LEN + ETH_ALEN];
+
+	salt[0] = 0;
+	salt[1] = (u8)csid;
+	os_memcpy(salt + 2, service_id, NAN_SERVICE_ID_LEN);
+	os_memcpy(salt + 2 + NAN_SERVICE_ID_LEN, peer_nmi, ETH_ALEN);
+
+	switch (csid) {
+	case NAN_CS_SK_CCM_128:
+		return pbkdf2_sha256(pwd, salt, sizeof(salt), 4096, nd_pmk, 32);
+	case NAN_CS_SK_GCM_256:
+		return pbkdf2_sha384(pwd, salt, sizeof(salt), 4096, nd_pmk, 32);
+	default:
+		return -1;
+	}
+
+	return -1;
+}
diff --git a/src/nan/nan_module_tests.c b/src/nan/nan_module_tests.c
index 3ccce9243d..87f9271a8d 100644
--- a/src/nan/nan_module_tests.c
+++ b/src/nan/nan_module_tests.c
@@ -1433,13 +1433,37 @@ static int nan_test_crypto_auth_token(void)
 }
 
 
+static int nan_test_derive_nd_pmk(void)
+{
+	u8 pmk[PMK_LEN];
+	const char *pwd = "NAN";
+	u8 service_id[NAN_SERVICE_ID_LEN] = {
+		0x2b, 0x9c, 0x45, 0x0f, 0x66, 0x71,
+	};
+	u8 nmi[ETH_ALEN] = {
+		0x02, 0x90, 0x4c, 0x12, 0xd0, 0x01,
+	};
+	u8 expected_pmk_ccm128[PMK_LEN] = {
+		0xee, 0x35, 0x85, 0x06, 0x30, 0x56, 0xd1, 0x64,
+		0xd1, 0x54, 0x54, 0xad, 0x39, 0x01, 0x0d, 0x4e,
+		0x26, 0x40, 0xb0, 0xd8, 0x2f, 0xb2, 0x4a, 0x2d,
+		0x68, 0x99, 0x86, 0x2d, 0x27, 0x3c, 0x68, 0xbf,
+	};
+
+	NAN_CRYPTO_FAIL(nan_crypto_derive_nd_pmk(pwd, service_id,
+						 NAN_CS_SK_CCM_128, nmi, pmk));
+	NAN_CRYPTO_FAIL(os_memcmp(pmk, expected_pmk_ccm128, PMK_LEN));
+
+	return 0;
+}
+
 int nan_test_crypto(void)
 {
 	NAN_CRYPTO_FAIL(nan_test_crypto_key_mic());
 	NAN_CRYPTO_FAIL(nan_test_crypto_pmkid());
 	NAN_CRYPTO_FAIL(nan_test_ptk());
 	NAN_CRYPTO_FAIL(nan_test_crypto_auth_token());
-
+	NAN_CRYPTO_FAIL(nan_test_derive_nd_pmk());
 	return 0;
 }
 
-- 
2.49.0




More information about the Hostap mailing list