[PATCH 89/92] NAN: Support NDP establishment with PASN cipher suites
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Wed Apr 22 05:24:20 PDT 2026
If pairing is used, PASN cipher suites (7, 8) should be used for NDP
establishment as well.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
src/common/nan_defs.h | 8 ++++++++
src/nan/nan_crypto.c | 22 ++++++++++++++--------
src/nan/nan_sec.c | 33 +++++++++++++++------------------
wpa_supplicant/nan_supplicant.c | 7 ++++++-
4 files changed, 43 insertions(+), 27 deletions(-)
diff --git a/src/common/nan_defs.h b/src/common/nan_defs.h
index b851d6219c..e9b6f21be6 100644
--- a/src/common/nan_defs.h
+++ b/src/common/nan_defs.h
@@ -496,6 +496,14 @@ enum nan_cipher_suite_id {
NAN_CS_MAX
};
+/* Helper macros to check CSID properties */
+#define NAN_CS_IS_128(csid) \
+ ((csid) == NAN_CS_SK_CCM_128 || (csid) == NAN_CS_PK_PASN_128)
+#define NAN_CS_IS_256(csid) \
+ ((csid) == NAN_CS_SK_GCM_256 || (csid) == NAN_CS_PK_PASN_256)
+#define NAN_CS_IS_VALID_NDP(csid) \
+ (NAN_CS_IS_128(csid) || NAN_CS_IS_256(csid))
+
struct nan_cipher_suite {
u8 csid; /* Cipher Suite ID */
u8 instance_id; /* Publish ID */
diff --git a/src/nan/nan_crypto.c b/src/nan/nan_crypto.c
index 7f4f50971c..b2632ea920 100644
--- a/src/nan/nan_crypto.c
+++ b/src/nan/nan_crypto.c
@@ -30,8 +30,10 @@ static size_t nan_crypto_cipher_kck_len(enum nan_cipher_suite_id cipher)
{
switch (cipher) {
case NAN_CS_SK_CCM_128:
+ case NAN_CS_PK_PASN_128:
return 16;
case NAN_CS_SK_GCM_256:
+ case NAN_CS_PK_PASN_256:
return 24;
default:
return 0;
@@ -58,8 +60,10 @@ static size_t nan_cipher_key_len(enum nan_cipher_suite_id cipher)
{
switch (cipher) {
case NAN_CS_SK_CCM_128:
+ case NAN_CS_PK_PASN_128:
return 16;
case NAN_CS_SK_GCM_256:
+ case NAN_CS_PK_PASN_256:
return 32;
default:
return 0;
@@ -112,7 +116,7 @@ int nan_crypto_pmk_to_ptk(const u8 *pmk, const u8 *iaddr, const u8 *raddr,
size_t ptk_len;
int ret;
- if (cipher != NAN_CS_SK_CCM_128 && cipher != NAN_CS_SK_GCM_256)
+ if (!NAN_CS_IS_VALID_NDP(cipher))
return -1;
if (!ptk)
@@ -129,7 +133,7 @@ int nan_crypto_pmk_to_ptk(const u8 *pmk, const u8 *iaddr, const u8 *raddr,
ptk->tk_len = nan_cipher_key_len(cipher);
ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len;
- if (cipher == NAN_CS_SK_CCM_128)
+ if (NAN_CS_IS_128(cipher))
ret = sha256_prf(pmk, PMK_LEN, NAN_PTK_LABEL, data,
sizeof(data), tmp, ptk_len);
else
@@ -183,7 +187,7 @@ int nan_crypto_calc_pmkid(const u8 *pmk, const u8 *iaddr, const u8 *raddr,
os_memset(data, 0, sizeof(data));
os_memset(digest, 0, sizeof(digest));
- if (cipher != NAN_CS_SK_CCM_128 && cipher != NAN_CS_SK_GCM_256)
+ if (!NAN_CS_IS_VALID_NDP(cipher))
return -1;
if (!serv_id || is_zero_ether_addr(serv_id))
@@ -198,7 +202,7 @@ int nan_crypto_calc_pmkid(const u8 *pmk, const u8 *iaddr, const u8 *raddr,
wpa_hexdump_key(MSG_DEBUG, "NAN: PMKID data", data, sizeof(data));
- if (cipher == NAN_CS_SK_CCM_128)
+ if (NAN_CS_IS_128(cipher))
ret = hmac_sha256(pmk, PMK_LEN, data, sizeof(data), digest);
else
ret = hmac_sha384(pmk, PMK_LEN, data, sizeof(data), digest);
@@ -228,10 +232,10 @@ int nan_crypto_calc_auth_token(enum nan_cipher_suite_id cipher,
u8 hash[MAX_MAC_LEN];
int ret;
- if (cipher != NAN_CS_SK_CCM_128 && cipher != NAN_CS_SK_GCM_256)
+ if (!NAN_CS_IS_VALID_NDP(cipher))
return -1;
- if (cipher == NAN_CS_SK_CCM_128)
+ if (NAN_CS_IS_128(cipher))
ret = nan_crypto_sha256(buf, len, hash);
else
ret = nan_crypto_sha384(buf, len, hash);
@@ -268,13 +272,13 @@ int nan_crypto_key_mic(const u8 *buf, size_t len, const u8 *kck,
os_memset(digest, 0, sizeof(digest));
- if (cipher != NAN_CS_SK_CCM_128 && cipher != NAN_CS_SK_GCM_256)
+ if (!NAN_CS_IS_VALID_NDP(cipher))
return -1;
wpa_hexdump_key(MSG_DEBUG, "NAN: MIC data", buf, len);
wpa_hexdump_key(MSG_DEBUG, "NAN: KCK", kck, kck_len);
- if (cipher == NAN_CS_SK_CCM_128) {
+ if (NAN_CS_IS_128(cipher)) {
mic_len = NAN_KEY_MIC_LEN;
ret = hmac_sha256(kck, kck_len, buf, len, digest);
} else {
@@ -305,8 +309,10 @@ int nan_crypto_derive_nd_pmk(const char *pwd, const u8 *service_id,
switch (csid) {
case NAN_CS_SK_CCM_128:
+ case NAN_CS_PK_PASN_128:
return pbkdf2_sha256(pwd, salt, sizeof(salt), 4096, nd_pmk, 32);
case NAN_CS_SK_GCM_256:
+ case NAN_CS_PK_PASN_256:
return pbkdf2_sha384(pwd, salt, sizeof(salt), 4096, nd_pmk, 32);
default:
return -1;
diff --git a/src/nan/nan_sec.c b/src/nan/nan_sec.c
index 995d358b77..d3d8b90d0e 100644
--- a/src/nan/nan_sec.c
+++ b/src/nan/nan_sec.c
@@ -120,8 +120,7 @@ static int nan_sec_parse_csia(const u8 *csia, size_t csia_len, u8 *instance_id,
return -1;
}
- if (cs->csid != NAN_CS_SK_CCM_128 &&
- cs->csid != NAN_CS_SK_GCM_256) {
+ if (!NAN_CS_IS_VALID_NDP(cs->csid)) {
wpa_printf(MSG_DEBUG,
"NAN: SEC: Unsupported cipher suite=%u",
cs->csid);
@@ -206,9 +205,9 @@ static int nan_sec_key_mic_ver(struct nan_data *nan, const u8 *buf, size_t len,
os_memset(mic, 0, sizeof(mic));
- if (csid == NAN_CS_SK_CCM_128)
+ if (NAN_CS_IS_128(csid))
mic_len = NAN_KEY_MIC_LEN;
- else if (csid == NAN_CS_SK_GCM_256)
+ else if (NAN_CS_IS_256(csid))
mic_len = NAN_KEY_MIC_24_LEN;
else
return -1;
@@ -270,7 +269,7 @@ static int nan_sec_rx_m2(struct nan_data *nan, struct nan_peer *peer,
* with the MIC differently.
*/
pos = (const u8 *) (key + 1);
- if (ndp_sec->i_csid == NAN_CS_SK_CCM_128)
+ if (NAN_CS_IS_128(ndp_sec->i_csid))
pos += NAN_KEY_MIC_LEN;
else
pos += NAN_KEY_MIC_24_LEN;
@@ -338,7 +337,7 @@ static int nan_sec_rx_m3(struct nan_data *nan, struct nan_peer *peer,
* with the mic differently
*/
pos = (u8 *) (key + 1);
- if (ndp_sec->i_csid == NAN_CS_SK_CCM_128)
+ if (NAN_CS_IS_128(ndp_sec->i_csid))
mic_len = NAN_KEY_MIC_LEN;
else
mic_len = NAN_KEY_MIC_24_LEN;
@@ -396,7 +395,7 @@ static int nan_sec_rx_m4(struct nan_data *nan, struct nan_peer *peer,
* Due to the different MIC size, need to handle the fields starting
* with the mic differently
*/
- if (ndp_sec->i_csid == NAN_CS_SK_CCM_128)
+ if (NAN_CS_IS_128(ndp_sec->i_csid))
pos += NAN_KEY_MIC_LEN;
else
pos += NAN_KEY_MIC_24_LEN;
@@ -490,7 +489,7 @@ int nan_sec_rx(struct nan_data *nan, struct nan_peer *peer,
total_len = sizeof(*key) + 2;
- if (cipher == NAN_CS_SK_CCM_128) {
+ if (NAN_CS_IS_128(cipher)) {
if (shared_key_desc_len <
sizeof(struct nan_shared_key) + sizeof(*key) +
NAN_KEY_MIC_LEN + 2) {
@@ -655,9 +654,9 @@ static int nan_sec_add_m1_attrs(struct nan_data *nan, struct nan_peer *peer,
size_t key_len = sizeof(struct wpa_eapol_key) + 2;
int ret;
- if (ndp_sec->i_csid == NAN_CS_SK_CCM_128)
+ if (NAN_CS_IS_128(ndp_sec->i_csid))
key_len += NAN_KEY_MIC_LEN;
- else if (ndp_sec->i_csid == NAN_CS_SK_GCM_256)
+ else if (NAN_CS_IS_256(ndp_sec->i_csid))
key_len += NAN_KEY_MIC_24_LEN;
else
return -1;
@@ -738,9 +737,9 @@ static int nan_sec_add_m2_attrs(struct nan_data *nan, struct nan_peer *peer,
size_t key_len;
key_len = sizeof(struct wpa_eapol_key) + 2;
- if (ndp_sec->i_csid == NAN_CS_SK_CCM_128)
+ if (NAN_CS_IS_128(ndp_sec->i_csid))
key_len += NAN_KEY_MIC_LEN;
- else if (ndp_sec->i_csid == NAN_CS_SK_GCM_256)
+ else if (NAN_CS_IS_256(ndp_sec->i_csid))
key_len += NAN_KEY_MIC_24_LEN;
else
return -1;
@@ -811,9 +810,9 @@ static int nan_sec_add_key_attrs(struct nan_data *nan, struct nan_peer *peer,
u16 info;
size_t key_len = sizeof(struct wpa_eapol_key) + 2;
- if (ndp_sec->i_csid == NAN_CS_SK_CCM_128)
+ if (NAN_CS_IS_128(ndp_sec->i_csid))
key_len += NAN_KEY_MIC_LEN;
- else if (ndp_sec->i_csid == NAN_CS_SK_GCM_256)
+ else if (NAN_CS_IS_256(ndp_sec->i_csid))
key_len += NAN_KEY_MIC_24_LEN;
else
return -1;
@@ -903,8 +902,7 @@ int nan_sec_add_attrs(struct nan_data *nan, struct nan_peer *peer,
nan_sec_dump(nan, peer);
/* No security configuration */
- if (peer->ndp_setup.sec.i_csid != NAN_CS_SK_CCM_128 &&
- peer->ndp_setup.sec.i_csid != NAN_CS_SK_GCM_256)
+ if (!NAN_CS_IS_VALID_NDP(peer->ndp_setup.sec.i_csid))
return 0;
switch (subtype) {
@@ -1154,8 +1152,7 @@ bool nan_sec_ndp_store_keys(struct nan_data *nan, struct nan_peer *peer,
peer->ndp_setup.state != NAN_NDP_STATE_DONE)
return false;
- if (ndp_sec->i_csid != NAN_CS_SK_CCM_128 &&
- ndp_sec->i_csid != NAN_CS_SK_GCM_256)
+ if (!NAN_CS_IS_VALID_NDP(ndp_sec->i_csid))
return false;
dl_list_for_each_safe(cur, next, &peer->info.sec,
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index ab9209e0f3..7f86567e1f 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -366,9 +366,11 @@ static int wpas_nan_set_ndi_keys(struct wpa_supplicant *wpa_s,
os_memset(rsc, 0, sizeof(rsc));
switch (csid) {
case NAN_CS_SK_CCM_128:
+ case NAN_CS_PK_PASN_128:
alg = WPA_ALG_CCMP;
break;
case NAN_CS_SK_GCM_256:
+ case NAN_CS_PK_PASN_256:
alg = WPA_ALG_GCMP_256;
break;
default:
@@ -1171,10 +1173,13 @@ int wpas_nan_init(struct wpa_supplicant *wpa_s)
!!(wpa_s->nan_capa.drv_flags &
WPA_DRIVER_FLAGS_NAN_SUPPORT_USERSPACE_DE);
- /* Currently support shared key suites only */
wpa_s->nan_supported_csids = BIT(NAN_CS_SK_CCM_128) |
BIT(NAN_CS_SK_GCM_256);
+#ifdef CONFIG_PASN
+ wpa_s->nan_supported_csids |= BIT(NAN_CS_PK_PASN_128) |
+ BIT(NAN_CS_PK_PASN_256);
+#endif /* CONFIG_PASN */
return 0;
}
--
2.53.0
More information about the Hostap
mailing list