1*6d49e1aeSJan Lentfer /* 2*6d49e1aeSJan Lentfer * WPA/RSN - Shared functions for supplicant and authenticator 3*6d49e1aeSJan Lentfer * Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi> 4*6d49e1aeSJan Lentfer * 5*6d49e1aeSJan Lentfer * This program is free software; you can redistribute it and/or modify 6*6d49e1aeSJan Lentfer * it under the terms of the GNU General Public License version 2 as 7*6d49e1aeSJan Lentfer * published by the Free Software Foundation. 8*6d49e1aeSJan Lentfer * 9*6d49e1aeSJan Lentfer * Alternatively, this software may be distributed under the terms of BSD 10*6d49e1aeSJan Lentfer * license. 11*6d49e1aeSJan Lentfer * 12*6d49e1aeSJan Lentfer * See README and COPYING for more details. 13*6d49e1aeSJan Lentfer */ 14*6d49e1aeSJan Lentfer 15*6d49e1aeSJan Lentfer #include "includes.h" 16*6d49e1aeSJan Lentfer 17*6d49e1aeSJan Lentfer #include "common.h" 18*6d49e1aeSJan Lentfer #include "md5.h" 19*6d49e1aeSJan Lentfer #include "sha1.h" 20*6d49e1aeSJan Lentfer #include "sha256.h" 21*6d49e1aeSJan Lentfer #include "aes_wrap.h" 22*6d49e1aeSJan Lentfer #include "crypto.h" 23*6d49e1aeSJan Lentfer #include "ieee802_11_defs.h" 24*6d49e1aeSJan Lentfer #include "defs.h" 25*6d49e1aeSJan Lentfer #include "wpa_common.h" 26*6d49e1aeSJan Lentfer 27*6d49e1aeSJan Lentfer 28*6d49e1aeSJan Lentfer /** 29*6d49e1aeSJan Lentfer * wpa_eapol_key_mic - Calculate EAPOL-Key MIC 30*6d49e1aeSJan Lentfer * @key: EAPOL-Key Key Confirmation Key (KCK) 31*6d49e1aeSJan Lentfer * @ver: Key descriptor version (WPA_KEY_INFO_TYPE_*) 32*6d49e1aeSJan Lentfer * @buf: Pointer to the beginning of the EAPOL header (version field) 33*6d49e1aeSJan Lentfer * @len: Length of the EAPOL frame (from EAPOL header to the end of the frame) 34*6d49e1aeSJan Lentfer * @mic: Pointer to the buffer to which the EAPOL-Key MIC is written 35*6d49e1aeSJan Lentfer * Returns: 0 on success, -1 on failure 36*6d49e1aeSJan Lentfer * 37*6d49e1aeSJan Lentfer * Calculate EAPOL-Key MIC for an EAPOL-Key packet. The EAPOL-Key MIC field has 38*6d49e1aeSJan Lentfer * to be cleared (all zeroes) when calling this function. 39*6d49e1aeSJan Lentfer * 40*6d49e1aeSJan Lentfer * Note: 'IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames' has an error in the 41*6d49e1aeSJan Lentfer * description of the Key MIC calculation. It includes packet data from the 42*6d49e1aeSJan Lentfer * beginning of the EAPOL-Key header, not EAPOL header. This incorrect change 43*6d49e1aeSJan Lentfer * happened during final editing of the standard and the correct behavior is 44*6d49e1aeSJan Lentfer * defined in the last draft (IEEE 802.11i/D10). 45*6d49e1aeSJan Lentfer */ 46*6d49e1aeSJan Lentfer int wpa_eapol_key_mic(const u8 *key, int ver, const u8 *buf, size_t len, 47*6d49e1aeSJan Lentfer u8 *mic) 48*6d49e1aeSJan Lentfer { 49*6d49e1aeSJan Lentfer u8 hash[SHA1_MAC_LEN]; 50*6d49e1aeSJan Lentfer 51*6d49e1aeSJan Lentfer switch (ver) { 52*6d49e1aeSJan Lentfer case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4: 53*6d49e1aeSJan Lentfer hmac_md5(key, 16, buf, len, mic); 54*6d49e1aeSJan Lentfer break; 55*6d49e1aeSJan Lentfer case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES: 56*6d49e1aeSJan Lentfer hmac_sha1(key, 16, buf, len, hash); 57*6d49e1aeSJan Lentfer os_memcpy(mic, hash, MD5_MAC_LEN); 58*6d49e1aeSJan Lentfer break; 59*6d49e1aeSJan Lentfer #if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W) 60*6d49e1aeSJan Lentfer case WPA_KEY_INFO_TYPE_AES_128_CMAC: 61*6d49e1aeSJan Lentfer return omac1_aes_128(key, buf, len, mic); 62*6d49e1aeSJan Lentfer #endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */ 63*6d49e1aeSJan Lentfer default: 64*6d49e1aeSJan Lentfer return -1; 65*6d49e1aeSJan Lentfer } 66*6d49e1aeSJan Lentfer 67*6d49e1aeSJan Lentfer return 0; 68*6d49e1aeSJan Lentfer } 69*6d49e1aeSJan Lentfer 70*6d49e1aeSJan Lentfer 71*6d49e1aeSJan Lentfer /** 72*6d49e1aeSJan Lentfer * wpa_pmk_to_ptk - Calculate PTK from PMK, addresses, and nonces 73*6d49e1aeSJan Lentfer * @pmk: Pairwise master key 74*6d49e1aeSJan Lentfer * @pmk_len: Length of PMK 75*6d49e1aeSJan Lentfer * @label: Label to use in derivation 76*6d49e1aeSJan Lentfer * @addr1: AA or SA 77*6d49e1aeSJan Lentfer * @addr2: SA or AA 78*6d49e1aeSJan Lentfer * @nonce1: ANonce or SNonce 79*6d49e1aeSJan Lentfer * @nonce2: SNonce or ANonce 80*6d49e1aeSJan Lentfer * @ptk: Buffer for pairwise transient key 81*6d49e1aeSJan Lentfer * @ptk_len: Length of PTK 82*6d49e1aeSJan Lentfer * @use_sha256: Whether to use SHA256-based KDF 83*6d49e1aeSJan Lentfer * 84*6d49e1aeSJan Lentfer * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy 85*6d49e1aeSJan Lentfer * PTK = PRF-X(PMK, "Pairwise key expansion", 86*6d49e1aeSJan Lentfer * Min(AA, SA) || Max(AA, SA) || 87*6d49e1aeSJan Lentfer * Min(ANonce, SNonce) || Max(ANonce, SNonce)) 88*6d49e1aeSJan Lentfer * 89*6d49e1aeSJan Lentfer * STK = PRF-X(SMK, "Peer key expansion", 90*6d49e1aeSJan Lentfer * Min(MAC_I, MAC_P) || Max(MAC_I, MAC_P) || 91*6d49e1aeSJan Lentfer * Min(INonce, PNonce) || Max(INonce, PNonce)) 92*6d49e1aeSJan Lentfer */ 93*6d49e1aeSJan Lentfer void wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label, 94*6d49e1aeSJan Lentfer const u8 *addr1, const u8 *addr2, 95*6d49e1aeSJan Lentfer const u8 *nonce1, const u8 *nonce2, 96*6d49e1aeSJan Lentfer u8 *ptk, size_t ptk_len, int use_sha256) 97*6d49e1aeSJan Lentfer { 98*6d49e1aeSJan Lentfer u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN]; 99*6d49e1aeSJan Lentfer 100*6d49e1aeSJan Lentfer if (os_memcmp(addr1, addr2, ETH_ALEN) < 0) { 101*6d49e1aeSJan Lentfer os_memcpy(data, addr1, ETH_ALEN); 102*6d49e1aeSJan Lentfer os_memcpy(data + ETH_ALEN, addr2, ETH_ALEN); 103*6d49e1aeSJan Lentfer } else { 104*6d49e1aeSJan Lentfer os_memcpy(data, addr2, ETH_ALEN); 105*6d49e1aeSJan Lentfer os_memcpy(data + ETH_ALEN, addr1, ETH_ALEN); 106*6d49e1aeSJan Lentfer } 107*6d49e1aeSJan Lentfer 108*6d49e1aeSJan Lentfer if (os_memcmp(nonce1, nonce2, WPA_NONCE_LEN) < 0) { 109*6d49e1aeSJan Lentfer os_memcpy(data + 2 * ETH_ALEN, nonce1, WPA_NONCE_LEN); 110*6d49e1aeSJan Lentfer os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce2, 111*6d49e1aeSJan Lentfer WPA_NONCE_LEN); 112*6d49e1aeSJan Lentfer } else { 113*6d49e1aeSJan Lentfer os_memcpy(data + 2 * ETH_ALEN, nonce2, WPA_NONCE_LEN); 114*6d49e1aeSJan Lentfer os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce1, 115*6d49e1aeSJan Lentfer WPA_NONCE_LEN); 116*6d49e1aeSJan Lentfer } 117*6d49e1aeSJan Lentfer 118*6d49e1aeSJan Lentfer #ifdef CONFIG_IEEE80211W 119*6d49e1aeSJan Lentfer if (use_sha256) 120*6d49e1aeSJan Lentfer sha256_prf(pmk, pmk_len, label, data, sizeof(data), 121*6d49e1aeSJan Lentfer ptk, ptk_len); 122*6d49e1aeSJan Lentfer else 123*6d49e1aeSJan Lentfer #endif /* CONFIG_IEEE80211W */ 124*6d49e1aeSJan Lentfer sha1_prf(pmk, pmk_len, label, data, sizeof(data), ptk, 125*6d49e1aeSJan Lentfer ptk_len); 126*6d49e1aeSJan Lentfer 127*6d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "WPA: PTK derivation - A1=" MACSTR " A2=" MACSTR, 128*6d49e1aeSJan Lentfer MAC2STR(addr1), MAC2STR(addr2)); 129*6d49e1aeSJan Lentfer wpa_hexdump_key(MSG_DEBUG, "WPA: PMK", pmk, pmk_len); 130*6d49e1aeSJan Lentfer wpa_hexdump_key(MSG_DEBUG, "WPA: PTK", ptk, ptk_len); 131*6d49e1aeSJan Lentfer } 132*6d49e1aeSJan Lentfer 133*6d49e1aeSJan Lentfer 134*6d49e1aeSJan Lentfer #ifdef CONFIG_IEEE80211R 135*6d49e1aeSJan Lentfer int wpa_ft_mic(const u8 *kck, const u8 *sta_addr, const u8 *ap_addr, 136*6d49e1aeSJan Lentfer u8 transaction_seqnum, const u8 *mdie, size_t mdie_len, 137*6d49e1aeSJan Lentfer const u8 *ftie, size_t ftie_len, 138*6d49e1aeSJan Lentfer const u8 *rsnie, size_t rsnie_len, 139*6d49e1aeSJan Lentfer const u8 *ric, size_t ric_len, u8 *mic) 140*6d49e1aeSJan Lentfer { 141*6d49e1aeSJan Lentfer u8 *buf, *pos; 142*6d49e1aeSJan Lentfer size_t buf_len; 143*6d49e1aeSJan Lentfer 144*6d49e1aeSJan Lentfer buf_len = 2 * ETH_ALEN + 1 + mdie_len + ftie_len + rsnie_len + ric_len; 145*6d49e1aeSJan Lentfer buf = os_malloc(buf_len); 146*6d49e1aeSJan Lentfer if (buf == NULL) 147*6d49e1aeSJan Lentfer return -1; 148*6d49e1aeSJan Lentfer 149*6d49e1aeSJan Lentfer pos = buf; 150*6d49e1aeSJan Lentfer os_memcpy(pos, sta_addr, ETH_ALEN); 151*6d49e1aeSJan Lentfer pos += ETH_ALEN; 152*6d49e1aeSJan Lentfer os_memcpy(pos, ap_addr, ETH_ALEN); 153*6d49e1aeSJan Lentfer pos += ETH_ALEN; 154*6d49e1aeSJan Lentfer *pos++ = transaction_seqnum; 155*6d49e1aeSJan Lentfer if (rsnie) { 156*6d49e1aeSJan Lentfer os_memcpy(pos, rsnie, rsnie_len); 157*6d49e1aeSJan Lentfer pos += rsnie_len; 158*6d49e1aeSJan Lentfer } 159*6d49e1aeSJan Lentfer if (mdie) { 160*6d49e1aeSJan Lentfer os_memcpy(pos, mdie, mdie_len); 161*6d49e1aeSJan Lentfer pos += mdie_len; 162*6d49e1aeSJan Lentfer } 163*6d49e1aeSJan Lentfer if (ftie) { 164*6d49e1aeSJan Lentfer struct rsn_ftie *_ftie; 165*6d49e1aeSJan Lentfer os_memcpy(pos, ftie, ftie_len); 166*6d49e1aeSJan Lentfer if (ftie_len < 2 + sizeof(*_ftie)) { 167*6d49e1aeSJan Lentfer os_free(buf); 168*6d49e1aeSJan Lentfer return -1; 169*6d49e1aeSJan Lentfer } 170*6d49e1aeSJan Lentfer _ftie = (struct rsn_ftie *) (pos + 2); 171*6d49e1aeSJan Lentfer os_memset(_ftie->mic, 0, sizeof(_ftie->mic)); 172*6d49e1aeSJan Lentfer pos += ftie_len; 173*6d49e1aeSJan Lentfer } 174*6d49e1aeSJan Lentfer if (ric) { 175*6d49e1aeSJan Lentfer os_memcpy(pos, ric, ric_len); 176*6d49e1aeSJan Lentfer pos += ric_len; 177*6d49e1aeSJan Lentfer } 178*6d49e1aeSJan Lentfer 179*6d49e1aeSJan Lentfer wpa_hexdump(MSG_MSGDUMP, "FT: MIC data", buf, pos - buf); 180*6d49e1aeSJan Lentfer if (omac1_aes_128(kck, buf, pos - buf, mic)) { 181*6d49e1aeSJan Lentfer os_free(buf); 182*6d49e1aeSJan Lentfer return -1; 183*6d49e1aeSJan Lentfer } 184*6d49e1aeSJan Lentfer 185*6d49e1aeSJan Lentfer os_free(buf); 186*6d49e1aeSJan Lentfer 187*6d49e1aeSJan Lentfer return 0; 188*6d49e1aeSJan Lentfer } 189*6d49e1aeSJan Lentfer #endif /* CONFIG_IEEE80211R */ 190*6d49e1aeSJan Lentfer 191*6d49e1aeSJan Lentfer 192*6d49e1aeSJan Lentfer #ifndef CONFIG_NO_WPA2 193*6d49e1aeSJan Lentfer static int rsn_selector_to_bitfield(const u8 *s) 194*6d49e1aeSJan Lentfer { 195*6d49e1aeSJan Lentfer if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NONE) 196*6d49e1aeSJan Lentfer return WPA_CIPHER_NONE; 197*6d49e1aeSJan Lentfer if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_WEP40) 198*6d49e1aeSJan Lentfer return WPA_CIPHER_WEP40; 199*6d49e1aeSJan Lentfer if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_TKIP) 200*6d49e1aeSJan Lentfer return WPA_CIPHER_TKIP; 201*6d49e1aeSJan Lentfer if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_CCMP) 202*6d49e1aeSJan Lentfer return WPA_CIPHER_CCMP; 203*6d49e1aeSJan Lentfer if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_WEP104) 204*6d49e1aeSJan Lentfer return WPA_CIPHER_WEP104; 205*6d49e1aeSJan Lentfer #ifdef CONFIG_IEEE80211W 206*6d49e1aeSJan Lentfer if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_AES_128_CMAC) 207*6d49e1aeSJan Lentfer return WPA_CIPHER_AES_128_CMAC; 208*6d49e1aeSJan Lentfer #endif /* CONFIG_IEEE80211W */ 209*6d49e1aeSJan Lentfer return 0; 210*6d49e1aeSJan Lentfer } 211*6d49e1aeSJan Lentfer 212*6d49e1aeSJan Lentfer 213*6d49e1aeSJan Lentfer static int rsn_key_mgmt_to_bitfield(const u8 *s) 214*6d49e1aeSJan Lentfer { 215*6d49e1aeSJan Lentfer if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_UNSPEC_802_1X) 216*6d49e1aeSJan Lentfer return WPA_KEY_MGMT_IEEE8021X; 217*6d49e1aeSJan Lentfer if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X) 218*6d49e1aeSJan Lentfer return WPA_KEY_MGMT_PSK; 219*6d49e1aeSJan Lentfer #ifdef CONFIG_IEEE80211R 220*6d49e1aeSJan Lentfer if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_802_1X) 221*6d49e1aeSJan Lentfer return WPA_KEY_MGMT_FT_IEEE8021X; 222*6d49e1aeSJan Lentfer if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_PSK) 223*6d49e1aeSJan Lentfer return WPA_KEY_MGMT_FT_PSK; 224*6d49e1aeSJan Lentfer #endif /* CONFIG_IEEE80211R */ 225*6d49e1aeSJan Lentfer #ifdef CONFIG_IEEE80211W 226*6d49e1aeSJan Lentfer if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SHA256) 227*6d49e1aeSJan Lentfer return WPA_KEY_MGMT_IEEE8021X_SHA256; 228*6d49e1aeSJan Lentfer if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_SHA256) 229*6d49e1aeSJan Lentfer return WPA_KEY_MGMT_PSK_SHA256; 230*6d49e1aeSJan Lentfer #endif /* CONFIG_IEEE80211W */ 231*6d49e1aeSJan Lentfer return 0; 232*6d49e1aeSJan Lentfer } 233*6d49e1aeSJan Lentfer #endif /* CONFIG_NO_WPA2 */ 234*6d49e1aeSJan Lentfer 235*6d49e1aeSJan Lentfer 236*6d49e1aeSJan Lentfer /** 237*6d49e1aeSJan Lentfer * wpa_parse_wpa_ie_rsn - Parse RSN IE 238*6d49e1aeSJan Lentfer * @rsn_ie: Buffer containing RSN IE 239*6d49e1aeSJan Lentfer * @rsn_ie_len: RSN IE buffer length (including IE number and length octets) 240*6d49e1aeSJan Lentfer * @data: Pointer to structure that will be filled in with parsed data 241*6d49e1aeSJan Lentfer * Returns: 0 on success, <0 on failure 242*6d49e1aeSJan Lentfer */ 243*6d49e1aeSJan Lentfer int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, 244*6d49e1aeSJan Lentfer struct wpa_ie_data *data) 245*6d49e1aeSJan Lentfer { 246*6d49e1aeSJan Lentfer #ifndef CONFIG_NO_WPA2 247*6d49e1aeSJan Lentfer const struct rsn_ie_hdr *hdr; 248*6d49e1aeSJan Lentfer const u8 *pos; 249*6d49e1aeSJan Lentfer int left; 250*6d49e1aeSJan Lentfer int i, count; 251*6d49e1aeSJan Lentfer 252*6d49e1aeSJan Lentfer os_memset(data, 0, sizeof(*data)); 253*6d49e1aeSJan Lentfer data->proto = WPA_PROTO_RSN; 254*6d49e1aeSJan Lentfer data->pairwise_cipher = WPA_CIPHER_CCMP; 255*6d49e1aeSJan Lentfer data->group_cipher = WPA_CIPHER_CCMP; 256*6d49e1aeSJan Lentfer data->key_mgmt = WPA_KEY_MGMT_IEEE8021X; 257*6d49e1aeSJan Lentfer data->capabilities = 0; 258*6d49e1aeSJan Lentfer data->pmkid = NULL; 259*6d49e1aeSJan Lentfer data->num_pmkid = 0; 260*6d49e1aeSJan Lentfer #ifdef CONFIG_IEEE80211W 261*6d49e1aeSJan Lentfer data->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC; 262*6d49e1aeSJan Lentfer #else /* CONFIG_IEEE80211W */ 263*6d49e1aeSJan Lentfer data->mgmt_group_cipher = 0; 264*6d49e1aeSJan Lentfer #endif /* CONFIG_IEEE80211W */ 265*6d49e1aeSJan Lentfer 266*6d49e1aeSJan Lentfer if (rsn_ie_len == 0) { 267*6d49e1aeSJan Lentfer /* No RSN IE - fail silently */ 268*6d49e1aeSJan Lentfer return -1; 269*6d49e1aeSJan Lentfer } 270*6d49e1aeSJan Lentfer 271*6d49e1aeSJan Lentfer if (rsn_ie_len < sizeof(struct rsn_ie_hdr)) { 272*6d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "%s: ie len too short %lu", 273*6d49e1aeSJan Lentfer __func__, (unsigned long) rsn_ie_len); 274*6d49e1aeSJan Lentfer return -1; 275*6d49e1aeSJan Lentfer } 276*6d49e1aeSJan Lentfer 277*6d49e1aeSJan Lentfer hdr = (const struct rsn_ie_hdr *) rsn_ie; 278*6d49e1aeSJan Lentfer 279*6d49e1aeSJan Lentfer if (hdr->elem_id != WLAN_EID_RSN || 280*6d49e1aeSJan Lentfer hdr->len != rsn_ie_len - 2 || 281*6d49e1aeSJan Lentfer WPA_GET_LE16(hdr->version) != RSN_VERSION) { 282*6d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version", 283*6d49e1aeSJan Lentfer __func__); 284*6d49e1aeSJan Lentfer return -2; 285*6d49e1aeSJan Lentfer } 286*6d49e1aeSJan Lentfer 287*6d49e1aeSJan Lentfer pos = (const u8 *) (hdr + 1); 288*6d49e1aeSJan Lentfer left = rsn_ie_len - sizeof(*hdr); 289*6d49e1aeSJan Lentfer 290*6d49e1aeSJan Lentfer if (left >= RSN_SELECTOR_LEN) { 291*6d49e1aeSJan Lentfer data->group_cipher = rsn_selector_to_bitfield(pos); 292*6d49e1aeSJan Lentfer #ifdef CONFIG_IEEE80211W 293*6d49e1aeSJan Lentfer if (data->group_cipher == WPA_CIPHER_AES_128_CMAC) { 294*6d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "%s: AES-128-CMAC used as group " 295*6d49e1aeSJan Lentfer "cipher", __func__); 296*6d49e1aeSJan Lentfer return -1; 297*6d49e1aeSJan Lentfer } 298*6d49e1aeSJan Lentfer #endif /* CONFIG_IEEE80211W */ 299*6d49e1aeSJan Lentfer pos += RSN_SELECTOR_LEN; 300*6d49e1aeSJan Lentfer left -= RSN_SELECTOR_LEN; 301*6d49e1aeSJan Lentfer } else if (left > 0) { 302*6d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much", 303*6d49e1aeSJan Lentfer __func__, left); 304*6d49e1aeSJan Lentfer return -3; 305*6d49e1aeSJan Lentfer } 306*6d49e1aeSJan Lentfer 307*6d49e1aeSJan Lentfer if (left >= 2) { 308*6d49e1aeSJan Lentfer data->pairwise_cipher = 0; 309*6d49e1aeSJan Lentfer count = WPA_GET_LE16(pos); 310*6d49e1aeSJan Lentfer pos += 2; 311*6d49e1aeSJan Lentfer left -= 2; 312*6d49e1aeSJan Lentfer if (count == 0 || left < count * RSN_SELECTOR_LEN) { 313*6d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), " 314*6d49e1aeSJan Lentfer "count %u left %u", __func__, count, left); 315*6d49e1aeSJan Lentfer return -4; 316*6d49e1aeSJan Lentfer } 317*6d49e1aeSJan Lentfer for (i = 0; i < count; i++) { 318*6d49e1aeSJan Lentfer data->pairwise_cipher |= rsn_selector_to_bitfield(pos); 319*6d49e1aeSJan Lentfer pos += RSN_SELECTOR_LEN; 320*6d49e1aeSJan Lentfer left -= RSN_SELECTOR_LEN; 321*6d49e1aeSJan Lentfer } 322*6d49e1aeSJan Lentfer #ifdef CONFIG_IEEE80211W 323*6d49e1aeSJan Lentfer if (data->pairwise_cipher & WPA_CIPHER_AES_128_CMAC) { 324*6d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "%s: AES-128-CMAC used as " 325*6d49e1aeSJan Lentfer "pairwise cipher", __func__); 326*6d49e1aeSJan Lentfer return -1; 327*6d49e1aeSJan Lentfer } 328*6d49e1aeSJan Lentfer #endif /* CONFIG_IEEE80211W */ 329*6d49e1aeSJan Lentfer } else if (left == 1) { 330*6d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)", 331*6d49e1aeSJan Lentfer __func__); 332*6d49e1aeSJan Lentfer return -5; 333*6d49e1aeSJan Lentfer } 334*6d49e1aeSJan Lentfer 335*6d49e1aeSJan Lentfer if (left >= 2) { 336*6d49e1aeSJan Lentfer data->key_mgmt = 0; 337*6d49e1aeSJan Lentfer count = WPA_GET_LE16(pos); 338*6d49e1aeSJan Lentfer pos += 2; 339*6d49e1aeSJan Lentfer left -= 2; 340*6d49e1aeSJan Lentfer if (count == 0 || left < count * RSN_SELECTOR_LEN) { 341*6d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), " 342*6d49e1aeSJan Lentfer "count %u left %u", __func__, count, left); 343*6d49e1aeSJan Lentfer return -6; 344*6d49e1aeSJan Lentfer } 345*6d49e1aeSJan Lentfer for (i = 0; i < count; i++) { 346*6d49e1aeSJan Lentfer data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos); 347*6d49e1aeSJan Lentfer pos += RSN_SELECTOR_LEN; 348*6d49e1aeSJan Lentfer left -= RSN_SELECTOR_LEN; 349*6d49e1aeSJan Lentfer } 350*6d49e1aeSJan Lentfer } else if (left == 1) { 351*6d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)", 352*6d49e1aeSJan Lentfer __func__); 353*6d49e1aeSJan Lentfer return -7; 354*6d49e1aeSJan Lentfer } 355*6d49e1aeSJan Lentfer 356*6d49e1aeSJan Lentfer if (left >= 2) { 357*6d49e1aeSJan Lentfer data->capabilities = WPA_GET_LE16(pos); 358*6d49e1aeSJan Lentfer pos += 2; 359*6d49e1aeSJan Lentfer left -= 2; 360*6d49e1aeSJan Lentfer } 361*6d49e1aeSJan Lentfer 362*6d49e1aeSJan Lentfer if (left >= 2) { 363*6d49e1aeSJan Lentfer data->num_pmkid = WPA_GET_LE16(pos); 364*6d49e1aeSJan Lentfer pos += 2; 365*6d49e1aeSJan Lentfer left -= 2; 366*6d49e1aeSJan Lentfer if (left < (int) data->num_pmkid * PMKID_LEN) { 367*6d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "%s: PMKID underflow " 368*6d49e1aeSJan Lentfer "(num_pmkid=%lu left=%d)", 369*6d49e1aeSJan Lentfer __func__, (unsigned long) data->num_pmkid, 370*6d49e1aeSJan Lentfer left); 371*6d49e1aeSJan Lentfer data->num_pmkid = 0; 372*6d49e1aeSJan Lentfer return -9; 373*6d49e1aeSJan Lentfer } else { 374*6d49e1aeSJan Lentfer data->pmkid = pos; 375*6d49e1aeSJan Lentfer pos += data->num_pmkid * PMKID_LEN; 376*6d49e1aeSJan Lentfer left -= data->num_pmkid * PMKID_LEN; 377*6d49e1aeSJan Lentfer } 378*6d49e1aeSJan Lentfer } 379*6d49e1aeSJan Lentfer 380*6d49e1aeSJan Lentfer #ifdef CONFIG_IEEE80211W 381*6d49e1aeSJan Lentfer if (left >= 4) { 382*6d49e1aeSJan Lentfer data->mgmt_group_cipher = rsn_selector_to_bitfield(pos); 383*6d49e1aeSJan Lentfer if (data->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC) { 384*6d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "%s: Unsupported management " 385*6d49e1aeSJan Lentfer "group cipher 0x%x", __func__, 386*6d49e1aeSJan Lentfer data->mgmt_group_cipher); 387*6d49e1aeSJan Lentfer return -10; 388*6d49e1aeSJan Lentfer } 389*6d49e1aeSJan Lentfer pos += RSN_SELECTOR_LEN; 390*6d49e1aeSJan Lentfer left -= RSN_SELECTOR_LEN; 391*6d49e1aeSJan Lentfer } 392*6d49e1aeSJan Lentfer #endif /* CONFIG_IEEE80211W */ 393*6d49e1aeSJan Lentfer 394*6d49e1aeSJan Lentfer if (left > 0) { 395*6d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes - ignored", 396*6d49e1aeSJan Lentfer __func__, left); 397*6d49e1aeSJan Lentfer } 398*6d49e1aeSJan Lentfer 399*6d49e1aeSJan Lentfer return 0; 400*6d49e1aeSJan Lentfer #else /* CONFIG_NO_WPA2 */ 401*6d49e1aeSJan Lentfer return -1; 402*6d49e1aeSJan Lentfer #endif /* CONFIG_NO_WPA2 */ 403*6d49e1aeSJan Lentfer } 404*6d49e1aeSJan Lentfer 405*6d49e1aeSJan Lentfer 406*6d49e1aeSJan Lentfer #ifdef CONFIG_IEEE80211R 407*6d49e1aeSJan Lentfer 408*6d49e1aeSJan Lentfer /** 409*6d49e1aeSJan Lentfer * wpa_derive_pmk_r0 - Derive PMK-R0 and PMKR0Name 410*6d49e1aeSJan Lentfer * 411*6d49e1aeSJan Lentfer * IEEE Std 802.11r-2008 - 8.5.1.5.3 412*6d49e1aeSJan Lentfer */ 413*6d49e1aeSJan Lentfer void wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len, 414*6d49e1aeSJan Lentfer const u8 *ssid, size_t ssid_len, 415*6d49e1aeSJan Lentfer const u8 *mdid, const u8 *r0kh_id, size_t r0kh_id_len, 416*6d49e1aeSJan Lentfer const u8 *s0kh_id, u8 *pmk_r0, u8 *pmk_r0_name) 417*6d49e1aeSJan Lentfer { 418*6d49e1aeSJan Lentfer u8 buf[1 + WPA_MAX_SSID_LEN + MOBILITY_DOMAIN_ID_LEN + 1 + 419*6d49e1aeSJan Lentfer FT_R0KH_ID_MAX_LEN + ETH_ALEN]; 420*6d49e1aeSJan Lentfer u8 *pos, r0_key_data[48], hash[32]; 421*6d49e1aeSJan Lentfer const u8 *addr[2]; 422*6d49e1aeSJan Lentfer size_t len[2]; 423*6d49e1aeSJan Lentfer 424*6d49e1aeSJan Lentfer /* 425*6d49e1aeSJan Lentfer * R0-Key-Data = KDF-384(XXKey, "FT-R0", 426*6d49e1aeSJan Lentfer * SSIDlength || SSID || MDID || R0KHlength || 427*6d49e1aeSJan Lentfer * R0KH-ID || S0KH-ID) 428*6d49e1aeSJan Lentfer * XXKey is either the second 256 bits of MSK or PSK. 429*6d49e1aeSJan Lentfer * PMK-R0 = L(R0-Key-Data, 0, 256) 430*6d49e1aeSJan Lentfer * PMK-R0Name-Salt = L(R0-Key-Data, 256, 128) 431*6d49e1aeSJan Lentfer */ 432*6d49e1aeSJan Lentfer if (ssid_len > WPA_MAX_SSID_LEN || r0kh_id_len > FT_R0KH_ID_MAX_LEN) 433*6d49e1aeSJan Lentfer return; 434*6d49e1aeSJan Lentfer pos = buf; 435*6d49e1aeSJan Lentfer *pos++ = ssid_len; 436*6d49e1aeSJan Lentfer os_memcpy(pos, ssid, ssid_len); 437*6d49e1aeSJan Lentfer pos += ssid_len; 438*6d49e1aeSJan Lentfer os_memcpy(pos, mdid, MOBILITY_DOMAIN_ID_LEN); 439*6d49e1aeSJan Lentfer pos += MOBILITY_DOMAIN_ID_LEN; 440*6d49e1aeSJan Lentfer *pos++ = r0kh_id_len; 441*6d49e1aeSJan Lentfer os_memcpy(pos, r0kh_id, r0kh_id_len); 442*6d49e1aeSJan Lentfer pos += r0kh_id_len; 443*6d49e1aeSJan Lentfer os_memcpy(pos, s0kh_id, ETH_ALEN); 444*6d49e1aeSJan Lentfer pos += ETH_ALEN; 445*6d49e1aeSJan Lentfer 446*6d49e1aeSJan Lentfer sha256_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf, 447*6d49e1aeSJan Lentfer r0_key_data, sizeof(r0_key_data)); 448*6d49e1aeSJan Lentfer os_memcpy(pmk_r0, r0_key_data, PMK_LEN); 449*6d49e1aeSJan Lentfer 450*6d49e1aeSJan Lentfer /* 451*6d49e1aeSJan Lentfer * PMKR0Name = Truncate-128(SHA-256("FT-R0N" || PMK-R0Name-Salt) 452*6d49e1aeSJan Lentfer */ 453*6d49e1aeSJan Lentfer addr[0] = (const u8 *) "FT-R0N"; 454*6d49e1aeSJan Lentfer len[0] = 6; 455*6d49e1aeSJan Lentfer addr[1] = r0_key_data + PMK_LEN; 456*6d49e1aeSJan Lentfer len[1] = 16; 457*6d49e1aeSJan Lentfer 458*6d49e1aeSJan Lentfer sha256_vector(2, addr, len, hash); 459*6d49e1aeSJan Lentfer os_memcpy(pmk_r0_name, hash, WPA_PMK_NAME_LEN); 460*6d49e1aeSJan Lentfer } 461*6d49e1aeSJan Lentfer 462*6d49e1aeSJan Lentfer 463*6d49e1aeSJan Lentfer /** 464*6d49e1aeSJan Lentfer * wpa_derive_pmk_r1_name - Derive PMKR1Name 465*6d49e1aeSJan Lentfer * 466*6d49e1aeSJan Lentfer * IEEE Std 802.11r-2008 - 8.5.1.5.4 467*6d49e1aeSJan Lentfer */ 468*6d49e1aeSJan Lentfer void wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id, 469*6d49e1aeSJan Lentfer const u8 *s1kh_id, u8 *pmk_r1_name) 470*6d49e1aeSJan Lentfer { 471*6d49e1aeSJan Lentfer u8 hash[32]; 472*6d49e1aeSJan Lentfer const u8 *addr[4]; 473*6d49e1aeSJan Lentfer size_t len[4]; 474*6d49e1aeSJan Lentfer 475*6d49e1aeSJan Lentfer /* 476*6d49e1aeSJan Lentfer * PMKR1Name = Truncate-128(SHA-256("FT-R1N" || PMKR0Name || 477*6d49e1aeSJan Lentfer * R1KH-ID || S1KH-ID)) 478*6d49e1aeSJan Lentfer */ 479*6d49e1aeSJan Lentfer addr[0] = (const u8 *) "FT-R1N"; 480*6d49e1aeSJan Lentfer len[0] = 6; 481*6d49e1aeSJan Lentfer addr[1] = pmk_r0_name; 482*6d49e1aeSJan Lentfer len[1] = WPA_PMK_NAME_LEN; 483*6d49e1aeSJan Lentfer addr[2] = r1kh_id; 484*6d49e1aeSJan Lentfer len[2] = FT_R1KH_ID_LEN; 485*6d49e1aeSJan Lentfer addr[3] = s1kh_id; 486*6d49e1aeSJan Lentfer len[3] = ETH_ALEN; 487*6d49e1aeSJan Lentfer 488*6d49e1aeSJan Lentfer sha256_vector(4, addr, len, hash); 489*6d49e1aeSJan Lentfer os_memcpy(pmk_r1_name, hash, WPA_PMK_NAME_LEN); 490*6d49e1aeSJan Lentfer } 491*6d49e1aeSJan Lentfer 492*6d49e1aeSJan Lentfer 493*6d49e1aeSJan Lentfer /** 494*6d49e1aeSJan Lentfer * wpa_derive_pmk_r1 - Derive PMK-R1 and PMKR1Name from PMK-R0 495*6d49e1aeSJan Lentfer * 496*6d49e1aeSJan Lentfer * IEEE Std 802.11r-2008 - 8.5.1.5.4 497*6d49e1aeSJan Lentfer */ 498*6d49e1aeSJan Lentfer void wpa_derive_pmk_r1(const u8 *pmk_r0, const u8 *pmk_r0_name, 499*6d49e1aeSJan Lentfer const u8 *r1kh_id, const u8 *s1kh_id, 500*6d49e1aeSJan Lentfer u8 *pmk_r1, u8 *pmk_r1_name) 501*6d49e1aeSJan Lentfer { 502*6d49e1aeSJan Lentfer u8 buf[FT_R1KH_ID_LEN + ETH_ALEN]; 503*6d49e1aeSJan Lentfer u8 *pos; 504*6d49e1aeSJan Lentfer 505*6d49e1aeSJan Lentfer /* PMK-R1 = KDF-256(PMK-R0, "FT-R1", R1KH-ID || S1KH-ID) */ 506*6d49e1aeSJan Lentfer pos = buf; 507*6d49e1aeSJan Lentfer os_memcpy(pos, r1kh_id, FT_R1KH_ID_LEN); 508*6d49e1aeSJan Lentfer pos += FT_R1KH_ID_LEN; 509*6d49e1aeSJan Lentfer os_memcpy(pos, s1kh_id, ETH_ALEN); 510*6d49e1aeSJan Lentfer pos += ETH_ALEN; 511*6d49e1aeSJan Lentfer 512*6d49e1aeSJan Lentfer sha256_prf(pmk_r0, PMK_LEN, "FT-R1", buf, pos - buf, pmk_r1, PMK_LEN); 513*6d49e1aeSJan Lentfer 514*6d49e1aeSJan Lentfer wpa_derive_pmk_r1_name(pmk_r0_name, r1kh_id, s1kh_id, pmk_r1_name); 515*6d49e1aeSJan Lentfer } 516*6d49e1aeSJan Lentfer 517*6d49e1aeSJan Lentfer 518*6d49e1aeSJan Lentfer /** 519*6d49e1aeSJan Lentfer * wpa_pmk_r1_to_ptk - Derive PTK and PTKName from PMK-R1 520*6d49e1aeSJan Lentfer * 521*6d49e1aeSJan Lentfer * IEEE Std 802.11r-2008 - 8.5.1.5.5 522*6d49e1aeSJan Lentfer */ 523*6d49e1aeSJan Lentfer void wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce, 524*6d49e1aeSJan Lentfer const u8 *sta_addr, const u8 *bssid, 525*6d49e1aeSJan Lentfer const u8 *pmk_r1_name, 526*6d49e1aeSJan Lentfer u8 *ptk, size_t ptk_len, u8 *ptk_name) 527*6d49e1aeSJan Lentfer { 528*6d49e1aeSJan Lentfer u8 buf[2 * WPA_NONCE_LEN + 2 * ETH_ALEN]; 529*6d49e1aeSJan Lentfer u8 *pos, hash[32]; 530*6d49e1aeSJan Lentfer const u8 *addr[6]; 531*6d49e1aeSJan Lentfer size_t len[6]; 532*6d49e1aeSJan Lentfer 533*6d49e1aeSJan Lentfer /* 534*6d49e1aeSJan Lentfer * PTK = KDF-PTKLen(PMK-R1, "FT-PTK", SNonce || ANonce || 535*6d49e1aeSJan Lentfer * BSSID || STA-ADDR) 536*6d49e1aeSJan Lentfer */ 537*6d49e1aeSJan Lentfer pos = buf; 538*6d49e1aeSJan Lentfer os_memcpy(pos, snonce, WPA_NONCE_LEN); 539*6d49e1aeSJan Lentfer pos += WPA_NONCE_LEN; 540*6d49e1aeSJan Lentfer os_memcpy(pos, anonce, WPA_NONCE_LEN); 541*6d49e1aeSJan Lentfer pos += WPA_NONCE_LEN; 542*6d49e1aeSJan Lentfer os_memcpy(pos, bssid, ETH_ALEN); 543*6d49e1aeSJan Lentfer pos += ETH_ALEN; 544*6d49e1aeSJan Lentfer os_memcpy(pos, sta_addr, ETH_ALEN); 545*6d49e1aeSJan Lentfer pos += ETH_ALEN; 546*6d49e1aeSJan Lentfer 547*6d49e1aeSJan Lentfer sha256_prf(pmk_r1, PMK_LEN, "FT-PTK", buf, pos - buf, ptk, ptk_len); 548*6d49e1aeSJan Lentfer 549*6d49e1aeSJan Lentfer /* 550*6d49e1aeSJan Lentfer * PTKName = Truncate-128(SHA-256(PMKR1Name || "FT-PTKN" || SNonce || 551*6d49e1aeSJan Lentfer * ANonce || BSSID || STA-ADDR)) 552*6d49e1aeSJan Lentfer */ 553*6d49e1aeSJan Lentfer addr[0] = pmk_r1_name; 554*6d49e1aeSJan Lentfer len[0] = WPA_PMK_NAME_LEN; 555*6d49e1aeSJan Lentfer addr[1] = (const u8 *) "FT-PTKN"; 556*6d49e1aeSJan Lentfer len[1] = 7; 557*6d49e1aeSJan Lentfer addr[2] = snonce; 558*6d49e1aeSJan Lentfer len[2] = WPA_NONCE_LEN; 559*6d49e1aeSJan Lentfer addr[3] = anonce; 560*6d49e1aeSJan Lentfer len[3] = WPA_NONCE_LEN; 561*6d49e1aeSJan Lentfer addr[4] = bssid; 562*6d49e1aeSJan Lentfer len[4] = ETH_ALEN; 563*6d49e1aeSJan Lentfer addr[5] = sta_addr; 564*6d49e1aeSJan Lentfer len[5] = ETH_ALEN; 565*6d49e1aeSJan Lentfer 566*6d49e1aeSJan Lentfer sha256_vector(6, addr, len, hash); 567*6d49e1aeSJan Lentfer os_memcpy(ptk_name, hash, WPA_PMK_NAME_LEN); 568*6d49e1aeSJan Lentfer } 569*6d49e1aeSJan Lentfer 570*6d49e1aeSJan Lentfer #endif /* CONFIG_IEEE80211R */ 571