[PATCH 41/92] NAN: Set PASN data for pairing verification
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Wed Apr 22 05:23:32 PDT 2026
From: Avraham Stern <avraham.stern at intel.com>
When pairing verification is requested, set the PASN data with the
cached NPK as the PMK and use the AKMP used in the original pairing.
Set the PMKID to a custom PMKID as defined in Wi-Fi Aware
specification version 4.0, section 7.6.5.
Signed-off-by: Avraham Stern <avraham.stern at intel.com>
---
src/nan/nan.h | 15 ++++++
src/nan/nan_pairing.c | 107 +++++++++++++++++++++++++++++++++++++++++-
2 files changed, 120 insertions(+), 2 deletions(-)
diff --git a/src/nan/nan.h b/src/nan/nan.h
index 6e16e006c3..47fbc1e067 100644
--- a/src/nan/nan.h
+++ b/src/nan/nan.h
@@ -640,6 +640,21 @@ struct nan_config {
size_t nik_len, int cipher_ver,
int nik_lifetime, int akmp, u8 *npk,
size_t npk_len);
+
+ /**
+ * get_npk_akmp - Get the cached NPK and AKMP for a peer
+ *
+ * @ctx: Callback context from cb_ctx
+ * @peer_nmi: Peer NMI address
+ * @nonce: Nonce from the peer's NIRA
+ * @tag: Tag from the peer's NIRA
+ * @akmp: On success, would hold the AKMP suite used to establish
+ * the NPKSA.
+ * Returns: The NPK on success, NULL on failure
+ */
+ const struct wpabuf *(*get_npk_akmp)(void *ctx, const u8 *peer_nmi,
+ const u8 *nonce, const u8 *tag,
+ int *akmp);
};
struct nan_data * nan_init(const struct nan_config *cfg);
diff --git a/src/nan/nan_pairing.c b/src/nan/nan_pairing.c
index 35c140ca9f..4f88ba37e3 100644
--- a/src/nan/nan_pairing.c
+++ b/src/nan/nan_pairing.c
@@ -123,6 +123,12 @@ static bool nan_pairing_is_supported(struct nan_data *nan_data,
"NAN: Pairing: Peer doesn't support pairing verification");
return false;
}
+
+ if (!nan_data->cfg->get_npk_akmp) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Pairing: get_npk_akmp callback not set");
+ return false;
+ }
}
return true;
@@ -194,6 +200,97 @@ static int nan_pairing_send_cb(void *ctx, const u8 *data, size_t data_len,
}
+/*
+ * nan_pasn_verification_init - Initialize PASN data for pairing verification
+ *
+ * @nan_data: Pointer to NAN data structure containing configuration
+ * @peer: Pointer to the NAN peer structure
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function gets the NPK and AKMP for the given peer and sets it as the
+ * PASN PMK and AKMP. It also generates the NIRA nonce and tag to be used as the
+ * custom PMKID for the PASN verification process.
+ */
+static int nan_pasn_verification_init(struct nan_data *nan_data,
+ struct nan_peer *peer)
+{
+ struct nan_pairing_peer_data *pairing_data;
+ const struct wpabuf *npk;
+ int akmp;
+ u8 npkid[NAN_NIRA_NONCE_LEN + NAN_NIRA_TAG_LEN];
+ struct pasn_data *pasn;
+
+ pairing_data = &peer->pairing;
+ pasn = pairing_data->pasn;
+
+ if (!pairing_data->nonce_tag_valid) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Pairing: NIK ID not available for verification");
+ return -1;
+ }
+
+ npk = nan_data->cfg->get_npk_akmp(nan_data->cfg->cb_ctx, peer->nmi_addr,
+ pairing_data->nonce,
+ pairing_data->tag, &akmp);
+ if (!npk) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Pairing: Failed to get NPK AKMP for verification");
+ return -1;
+ }
+
+ pasn_set_akmp(pairing_data->pasn, akmp);
+
+ os_free(pasn->pasn_groups);
+ pasn->pasn_groups = os_calloc(2, sizeof(int));
+ if (!pasn->pasn_groups) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Pairing: Failed to allocate PASN groups");
+ return -1;
+ }
+
+ pasn->pasn_groups[0] = pasn->group;
+
+ if (pairing_data->self_pairing_role == NAN_PAIRING_ROLE_INITIATOR)
+ pasn_initiator_pmksa_cache_add(nan_data->initiator_pmksa,
+ nan_data->cfg->nmi_addr,
+ peer->nmi_addr,
+ wpabuf_head_u8(npk),
+ wpabuf_len(npk), NULL, akmp);
+ else
+ pasn_responder_pmksa_cache_add(nan_data->responder_pmksa,
+ nan_data->cfg->nmi_addr,
+ peer->nmi_addr,
+ wpabuf_head_u8(npk),
+ wpabuf_len(npk), NULL, akmp);
+
+ /*
+ * According to Wi-Fi Aware Specification version 4.0, section 7.6.5,
+ * pairing verification uses NPKID constructed from NIRA nonce and tag.
+ * The same nonce and tag should be used in the NIRA added to PASN
+ * first and second frames.
+ */
+ if (nan_nira_get_tag_nonce(nan_data->cfg, npkid,
+ &npkid[NAN_NIRA_NONCE_LEN]) < 0) {
+ wpa_printf(MSG_DEBUG, "NAN: Failed to get NIRA tag and nonce");
+ return -1;
+ }
+
+ pasn_set_custom_pmkid(pairing_data->pasn, npkid);
+ return 0;
+}
+
+
+static int nan_validate_custom_pmkid(void *ctx, const u8 *addr, const u8 *pmkid)
+{
+ /*
+ * In NAN pairing, custom PMKID is constructed from NIRA nonce and tag.
+ * Matching the tag to a known NIK is done during NIRA validation
+ * so here we just accept any PMKID.
+ */
+ return 0;
+}
+
+
static int nan_pairing_pasn_initialize(struct nan_data *nan_data,
struct nan_peer *peer, u8 auth_mode,
int cipher, const char *password,
@@ -268,6 +365,12 @@ static int nan_pairing_pasn_initialize(struct nan_data *nan_data,
goto fail;
}
pasn->pasn_groups[0] = pasn->group;
+ } else if (auth_mode == NAN_PASN_AUTH_MODE_PMK) {
+ if (nan_pasn_verification_init(nan_data, peer)) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Pairing: PASN verification init failed");
+ goto fail;
+ }
} else {
wpa_printf(MSG_DEBUG,
"NAN: Pairing: Unsupported authentication mode %u",
@@ -290,8 +393,8 @@ static int nan_pairing_pasn_initialize(struct nan_data *nan_data,
wpabuf_free(rsnxe);
}
- pasn_register_callbacks(pasn, nan_data, nan_pairing_send_cb, NULL,
- NULL, NULL);
+ pasn_register_callbacks(pasn, nan_data, nan_pairing_send_cb,
+ nan_validate_custom_pmkid, NULL, NULL);
return 0;
fail:
--
2.53.0
More information about the Hostap
mailing list