[RFC 08/30] WPA: Add function to calculate SMD MIC
Ilan Peer
ilan.peer at intel.com
Wed Oct 21 06:43:26 PDT 2026
Add a function to calculate a MIC used during ST preparation and
execution when per-AP MLD PTK mode is used, as defined in Draft
IEEE P802.11bn D2.0 in section 37.16.4.2.
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
src/common/wpa_common.c | 95 +++++++++++++++++++++++++++++++++++++++++
src/common/wpa_common.h | 4 ++
2 files changed, 99 insertions(+)
diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c
index c38c50c37e3f..617278faf931 100644
--- a/src/common/wpa_common.c
+++ b/src/common/wpa_common.c
@@ -5456,3 +5456,98 @@ int hkdf_expand(size_t hash_len, const u8 *prk, size_t prk_len,
}
#endif /* CONFIG_SAE || CONFIG_PQC */
+
+
+/**
+ * wpa_smd_mic - Calculate MIC for SMD with per-AP MLD PTK
+ * @key: The PTK-KCK key
+ * @key_len: Length of the key
+ * @hash_alg: Hash algorithm to use for MIC calculation
+ * @aa: MLD MAC address of the target AP MLD
+ * @spa: MLD MAC address of the non-AP MLD
+ * @anonce: Nonce generated by the AP MLD and included in the ST
+ * preparation response
+ * @snonce: Nonce generated by the target non-AP MLD and included in the ST
+ * preparation request
+ * @st_prep: Whether the MIC is calculated for ST preparation response
+ * @mic: Buffer to hold the calculated MIC (must be large enough for
+ * the hash / 2)
+ * Returns: Length of the calculated MIC on success, 0 on failure
+ *
+ * The MIC calculation is defined in IEEE P802.11bn/D2.0, 37.16.4.2.
+ */
+int wpa_smd_mic(const u8 *key, size_t key_len, enum rsn_hash_alg hash_alg,
+ const u8 *aa, const u8 *spa, const u8 *anonce,
+ const u8 *snonce, bool st_prep, u8 *mic)
+{
+ u8 *tmp = NULL;
+ size_t len = 2 * ETH_ALEN + 2 * WPA_NONCE_LEN, hash_len;
+ u8 hash[SHA512_MAC_LEN];
+ int ret;
+ const u8 *addr1, *addr2, *nonce1, *nonce2;
+
+ tmp = os_malloc(len);
+ if (!tmp) {
+ wpa_printf(MSG_DEBUG,
+ "WPA: SMD: Failed to allocate memory for MIC");
+ return 0;
+ }
+
+ /*
+ * The MIC calculation is different between ST preparation response
+ * and ST execution request:
+ * ST preparation response: HMAC-HASH(PTK-KCK, AA || SPA || ANonce || SNonce)
+ * ST execution request: HMAC-HASH(PTK-KCK, SPA || AA || SNonce || ANonce)
+ */
+ if (st_prep) {
+ addr1 = aa;
+ addr2 = spa;
+ nonce1 = anonce;
+ nonce2 = snonce;
+ } else {
+ addr1 = spa;
+ addr2 = aa;
+ nonce1 = snonce;
+ nonce2 = anonce;
+ }
+
+ os_memcpy(tmp, addr1, ETH_ALEN);
+ os_memcpy(tmp + ETH_ALEN, addr2, ETH_ALEN);
+ os_memcpy(tmp + 2 * ETH_ALEN, nonce1, WPA_NONCE_LEN);
+ os_memcpy(tmp + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce2, WPA_NONCE_LEN);
+
+ switch (hash_alg) {
+ case RSN_HASH_SHA256:
+ ret = hmac_sha256(key, key_len, tmp, len, hash);
+ hash_len = SHA256_MAC_LEN;
+ break;
+#ifdef CONFIG_SHA384
+ case RSN_HASH_SHA384:
+ ret = hmac_sha384(key, key_len, tmp, len, hash);
+ hash_len = SHA384_MAC_LEN;
+
+ break;
+#endif /* CONFIG_SHA384 */
+#ifdef CONFIG_SHA512
+ case RSN_HASH_SHA512:
+ ret = hmac_sha512(key, key_len, tmp, len, hash);
+ hash_len = SHA512_MAC_LEN;
+ break;
+#endif /* CONFIG_SHA512 */
+ default:
+ wpa_printf(MSG_DEBUG,
+ "WPA: SMD: Invalid hash algorithm for MIC calculation: %d",
+ hash_alg);
+ hash_len = 0;
+ ret = -1;
+ }
+
+ wpa_printf(MSG_DEBUG,
+ "WPA: SMD: MIC calculation. ret=%d, hash_alg=%d, hash_len=%zu",
+ ret, hash_alg, hash_len);
+ if (!ret)
+ os_memcpy(mic, hash, hash_len / 2);
+
+ os_free(tmp);
+ return ret ? 0 : hash_len / 2;
+}
diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h
index e9e98acdc520..b6bed37da7d9 100644
--- a/src/common/wpa_common.h
+++ b/src/common/wpa_common.h
@@ -938,4 +938,8 @@ int hkdf_expand(size_t hash_len, const u8 *prk, size_t prk_len,
const struct ieee80211_pqc_profile *
pqc_profile_get(int security_profile_num);
+int wpa_smd_mic(const u8 *key, size_t key_len, enum rsn_hash_alg hash_alg,
+ const u8 *aa, const u8 *spa, const u8 *anonce,
+ const u8 *snonce, bool st_prep, u8 *mic);
+
#endif /* WPA_COMMON_H */
--
2.55.0
More information about the Hostap
mailing list