diff options
Diffstat (limited to 'freebsd/contrib/wpa/src/common/wpa_common.c')
-rw-r--r-- | freebsd/contrib/wpa/src/common/wpa_common.c | 67 |
1 files changed, 57 insertions, 10 deletions
diff --git a/freebsd/contrib/wpa/src/common/wpa_common.c b/freebsd/contrib/wpa/src/common/wpa_common.c index 0e647132..6fcbf20c 100644 --- a/freebsd/contrib/wpa/src/common/wpa_common.c +++ b/freebsd/contrib/wpa/src/common/wpa_common.c @@ -342,14 +342,21 @@ int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver, * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy * PTK = PRF-X(PMK, "Pairwise key expansion", * Min(AA, SA) || Max(AA, SA) || - * Min(ANonce, SNonce) || Max(ANonce, SNonce)) + * Min(ANonce, SNonce) || Max(ANonce, SNonce) + * [ || Z.x ]) + * + * The optional Z.x component is used only with DPP and that part is not defined + * in IEEE 802.11. */ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label, const u8 *addr1, const u8 *addr2, const u8 *nonce1, const u8 *nonce2, - struct wpa_ptk *ptk, int akmp, int cipher) + struct wpa_ptk *ptk, int akmp, int cipher, + const u8 *z, size_t z_len) { - u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN]; +#define MAX_Z_LEN 66 /* with NIST P-521 */ + u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN + MAX_Z_LEN]; + size_t data_len = 2 * ETH_ALEN + 2 * WPA_NONCE_LEN; u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN]; size_t ptk_len; @@ -358,6 +365,9 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label, return -1; } + if (z_len > MAX_Z_LEN) + return -1; + if (os_memcmp(addr1, addr2, ETH_ALEN) < 0) { os_memcpy(data, addr1, ETH_ALEN); os_memcpy(data + ETH_ALEN, addr2, ETH_ALEN); @@ -376,6 +386,11 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label, WPA_NONCE_LEN); } + if (z && z_len) { + os_memcpy(data + 2 * ETH_ALEN + 2 * WPA_NONCE_LEN, z, z_len); + data_len += z_len; + } + ptk->kck_len = wpa_kck_len(akmp, pmk_len); ptk->kek_len = wpa_kek_len(akmp, pmk_len); ptk->tk_len = wpa_cipher_key_len(cipher); @@ -390,7 +405,7 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label, if (wpa_key_mgmt_sha384(akmp)) { #if defined(CONFIG_SUITEB192) || defined(CONFIG_FILS) wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)"); - if (sha384_prf(pmk, pmk_len, label, data, sizeof(data), + if (sha384_prf(pmk, pmk_len, label, data, data_len, tmp, ptk_len) < 0) return -1; #else /* CONFIG_SUITEB192 || CONFIG_FILS */ @@ -399,7 +414,7 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label, } else if (wpa_key_mgmt_sha256(akmp) || akmp == WPA_KEY_MGMT_OWE) { #if defined(CONFIG_IEEE80211W) || defined(CONFIG_SAE) || defined(CONFIG_FILS) wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)"); - if (sha256_prf(pmk, pmk_len, label, data, sizeof(data), + if (sha256_prf(pmk, pmk_len, label, data, data_len, tmp, ptk_len) < 0) return -1; #else /* CONFIG_IEEE80211W or CONFIG_SAE or CONFIG_FILS */ @@ -408,17 +423,17 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label, #ifdef CONFIG_DPP } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 32) { wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)"); - if (sha256_prf(pmk, pmk_len, label, data, sizeof(data), + if (sha256_prf(pmk, pmk_len, label, data, data_len, tmp, ptk_len) < 0) return -1; } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 48) { wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)"); - if (sha384_prf(pmk, pmk_len, label, data, sizeof(data), + if (sha384_prf(pmk, pmk_len, label, data, data_len, tmp, ptk_len) < 0) return -1; } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 64) { wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA512)"); - if (sha512_prf(pmk, pmk_len, label, data, sizeof(data), + if (sha512_prf(pmk, pmk_len, label, data, data_len, tmp, ptk_len) < 0) return -1; } else if (akmp == WPA_KEY_MGMT_DPP) { @@ -428,7 +443,7 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label, #endif /* CONFIG_DPP */ } else { wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA1)"); - if (sha1_prf(pmk, pmk_len, label, data, sizeof(data), tmp, + if (sha1_prf(pmk, pmk_len, label, data, data_len, tmp, ptk_len) < 0) return -1; } @@ -437,6 +452,8 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label, MAC2STR(addr1), MAC2STR(addr2)); wpa_hexdump(MSG_DEBUG, "WPA: Nonce1", nonce1, WPA_NONCE_LEN); wpa_hexdump(MSG_DEBUG, "WPA: Nonce2", nonce2, WPA_NONCE_LEN); + if (z && z_len) + wpa_hexdump_key(MSG_DEBUG, "WPA: Z.x", z, z_len); wpa_hexdump_key(MSG_DEBUG, "WPA: PMK", pmk, pmk_len); wpa_hexdump_key(MSG_DEBUG, "WPA: PTK", tmp, ptk_len); @@ -453,6 +470,7 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label, ptk->kck2_len = 0; os_memset(tmp, 0, sizeof(tmp)); + os_memset(data, 0, data_len); return 0; } @@ -882,6 +900,12 @@ static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len, parse->igtk_len = len; break; #endif /* CONFIG_IEEE80211W */ +#ifdef CONFIG_OCV + case FTIE_SUBELEM_OCI: + parse->oci = pos; + parse->oci_len = len; + break; +#endif /* CONFIG_OCV */ default: wpa_printf(MSG_DEBUG, "FT: Unknown subelem id %u", id); break; @@ -1205,6 +1229,7 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, left = rsn_ie_len - 6; data->group_cipher = WPA_CIPHER_GTK_NOT_USED; + data->has_group = 1; data->key_mgmt = WPA_KEY_MGMT_OSEN; data->proto = WPA_PROTO_OSEN; } else { @@ -1226,6 +1251,7 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, if (left >= RSN_SELECTOR_LEN) { data->group_cipher = rsn_selector_to_bitfield(pos); + data->has_group = 1; if (!wpa_cipher_valid_group(data->group_cipher)) { wpa_printf(MSG_DEBUG, "%s: invalid group cipher 0x%x (%08x)", @@ -1251,6 +1277,8 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, "count %u left %u", __func__, count, left); return -4; } + if (count) + data->has_pairwise = 1; for (i = 0; i < count; i++) { data->pairwise_cipher |= rsn_selector_to_bitfield(pos); pos += RSN_SELECTOR_LEN; @@ -1469,6 +1497,15 @@ int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len, } +int wpa_default_rsn_cipher(int freq) +{ + if (freq > 56160) + return WPA_CIPHER_GCMP; /* DMG */ + + return WPA_CIPHER_CCMP; +} + + #ifdef CONFIG_IEEE80211R /** @@ -1756,7 +1793,7 @@ int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, size_t pmk_r1_len, os_memcpy(ptk->tk, tmp + offset, ptk->tk_len); offset += ptk->tk_len; os_memcpy(ptk->kck2, tmp + offset, ptk->kck2_len); - offset = ptk->kck2_len; + offset += ptk->kck2_len; os_memcpy(ptk->kek2, tmp + offset, ptk->kek2_len); wpa_hexdump_key(MSG_DEBUG, "FT: KCK", ptk->kck, ptk->kck_len); @@ -2040,6 +2077,16 @@ u32 wpa_akm_to_suite(int akm) return RSN_AUTH_KEY_MGMT_FT_FILS_SHA256; if (akm & WPA_KEY_MGMT_FT_FILS_SHA384) return RSN_AUTH_KEY_MGMT_FT_FILS_SHA384; + if (akm & WPA_KEY_MGMT_SAE) + return RSN_AUTH_KEY_MGMT_SAE; + if (akm & WPA_KEY_MGMT_FT_SAE) + return RSN_AUTH_KEY_MGMT_FT_SAE; + if (akm & WPA_KEY_MGMT_OWE) + return RSN_AUTH_KEY_MGMT_OWE; + if (akm & WPA_KEY_MGMT_DPP) + return RSN_AUTH_KEY_MGMT_DPP; + if (akm & WPA_KEY_MGMT_OSEN) + return RSN_AUTH_KEY_MGMT_OSEN; return 0; } |