xref: /dflybsd-src/contrib/wpa_supplicant/src/common/wpa_common.c (revision 6d49e1aea1f916afb9e202b8d2ad09cfab6e48c3)
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