2
* WPA/RSN - Shared functions for supplicant and authenticator
3
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 2 as
7
* published by the Free Software Foundation.
9
* Alternatively, this software may be distributed under the terms of BSD
12
* See README and COPYING for more details.
23
#include "ieee802_11_defs.h"
25
#include "wpa_common.h"
29
* wpa_eapol_key_mic - Calculate EAPOL-Key MIC
30
* @key: EAPOL-Key Key Confirmation Key (KCK)
31
* @ver: Key descriptor version (WPA_KEY_INFO_TYPE_*)
32
* @buf: Pointer to the beginning of the EAPOL header (version field)
33
* @len: Length of the EAPOL frame (from EAPOL header to the end of the frame)
34
* @mic: Pointer to the buffer to which the EAPOL-Key MIC is written
35
* Returns: 0 on success, -1 on failure
37
* Calculate EAPOL-Key MIC for an EAPOL-Key packet. The EAPOL-Key MIC field has
38
* to be cleared (all zeroes) when calling this function.
40
* Note: 'IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames' has an error in the
41
* description of the Key MIC calculation. It includes packet data from the
42
* beginning of the EAPOL-Key header, not EAPOL header. This incorrect change
43
* happened during final editing of the standard and the correct behavior is
44
* defined in the last draft (IEEE 802.11i/D10).
46
int wpa_eapol_key_mic(const u8 *key, int ver, const u8 *buf, size_t len,
49
u8 hash[SHA1_MAC_LEN];
52
case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
53
hmac_md5(key, 16, buf, len, mic);
55
case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
56
hmac_sha1(key, 16, buf, len, hash);
57
os_memcpy(mic, hash, MD5_MAC_LEN);
59
#ifdef CONFIG_IEEE80211R
60
case WPA_KEY_INFO_TYPE_AES_128_CMAC:
61
omac1_aes_128(key, buf, len, mic);
63
#endif /* CONFIG_IEEE80211R */
73
* wpa_pmk_to_ptk - Calculate PTK from PMK, addresses, and nonces
74
* @pmk: Pairwise master key
75
* @pmk_len: Length of PMK
76
* @label: Label to use in derivation
79
* @nonce1: ANonce or SNonce
80
* @nonce2: SNonce or ANonce
81
* @ptk: Buffer for pairwise transient key
82
* @ptk_len: Length of PTK
84
* IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
85
* PTK = PRF-X(PMK, "Pairwise key expansion",
86
* Min(AA, SA) || Max(AA, SA) ||
87
* Min(ANonce, SNonce) || Max(ANonce, SNonce))
89
* STK = PRF-X(SMK, "Peer key expansion",
90
* Min(MAC_I, MAC_P) || Max(MAC_I, MAC_P) ||
91
* Min(INonce, PNonce) || Max(INonce, PNonce))
93
void wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
94
const u8 *addr1, const u8 *addr2,
95
const u8 *nonce1, const u8 *nonce2,
96
u8 *ptk, size_t ptk_len)
98
u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN];
100
if (os_memcmp(addr1, addr2, ETH_ALEN) < 0) {
101
os_memcpy(data, addr1, ETH_ALEN);
102
os_memcpy(data + ETH_ALEN, addr2, ETH_ALEN);
104
os_memcpy(data, addr2, ETH_ALEN);
105
os_memcpy(data + ETH_ALEN, addr1, ETH_ALEN);
108
if (os_memcmp(nonce1, nonce2, WPA_NONCE_LEN) < 0) {
109
os_memcpy(data + 2 * ETH_ALEN, nonce1, WPA_NONCE_LEN);
110
os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce2,
113
os_memcpy(data + 2 * ETH_ALEN, nonce2, WPA_NONCE_LEN);
114
os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce1,
118
sha1_prf(pmk, pmk_len, label, data, sizeof(data), ptk, ptk_len);
120
wpa_printf(MSG_DEBUG, "WPA: PTK derivation - A1=" MACSTR " A2=" MACSTR,
121
MAC2STR(addr1), MAC2STR(addr2));
122
wpa_hexdump_key(MSG_DEBUG, "WPA: PMK", pmk, pmk_len);
123
wpa_hexdump_key(MSG_DEBUG, "WPA: PTK", ptk, ptk_len);
127
#ifdef CONFIG_IEEE80211R
128
int wpa_ft_mic(const u8 *kck, int use_aes_cmac,
129
const u8 *sta_addr, const u8 *ap_addr,
130
u8 transaction_seqnum, const u8 *mdie, size_t mdie_len,
131
const u8 *ftie, size_t ftie_len,
132
const u8 *rsnie, size_t rsnie_len,
133
const u8 *ric, size_t ric_len, u8 *mic)
138
buf_len = 2 * ETH_ALEN + 1 + mdie_len + ftie_len + rsnie_len + ric_len;
139
buf = os_malloc(buf_len);
144
os_memcpy(pos, sta_addr, ETH_ALEN);
146
os_memcpy(pos, ap_addr, ETH_ALEN);
148
*pos++ = transaction_seqnum;
150
os_memcpy(pos, rsnie, rsnie_len);
154
os_memcpy(pos, mdie, mdie_len);
158
struct rsn_ftie *_ftie;
159
os_memcpy(pos, ftie, ftie_len);
160
if (ftie_len < 2 + sizeof(*_ftie)) {
164
_ftie = (struct rsn_ftie *) (pos + 2);
165
os_memset(_ftie->mic, 0, sizeof(_ftie->mic));
169
os_memcpy(pos, ric, ric_len);
173
wpa_hexdump(MSG_MSGDUMP, "FT: MIC data", buf, pos - buf);
175
omac1_aes_128(kck, buf, pos - buf, mic);
177
hmac_md5(kck, 16, buf, pos - buf, mic);
183
#endif /* CONFIG_IEEE80211R */
186
#ifndef CONFIG_NO_WPA2
187
static int rsn_selector_to_bitfield(const u8 *s)
189
if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NONE)
190
return WPA_CIPHER_NONE;
191
if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_WEP40)
192
return WPA_CIPHER_WEP40;
193
if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_TKIP)
194
return WPA_CIPHER_TKIP;
195
if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_CCMP)
196
return WPA_CIPHER_CCMP;
197
if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_WEP104)
198
return WPA_CIPHER_WEP104;
199
#ifdef CONFIG_IEEE80211W
200
if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_AES_128_CMAC)
201
return WPA_CIPHER_AES_128_CMAC;
202
#endif /* CONFIG_IEEE80211W */
207
static int rsn_key_mgmt_to_bitfield(const u8 *s)
209
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_UNSPEC_802_1X)
210
return WPA_KEY_MGMT_IEEE8021X;
211
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X)
212
return WPA_KEY_MGMT_PSK;
213
#ifdef CONFIG_IEEE80211R
214
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_802_1X)
215
return WPA_KEY_MGMT_FT_IEEE8021X;
216
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_PSK)
217
return WPA_KEY_MGMT_FT_PSK;
218
#endif /* CONFIG_IEEE80211R */
221
#endif /* CONFIG_NO_WPA2 */
225
* wpa_parse_wpa_ie_rsn - Parse RSN IE
226
* @rsn_ie: Buffer containing RSN IE
227
* @rsn_ie_len: RSN IE buffer length (including IE number and length octets)
228
* @data: Pointer to structure that will be filled in with parsed data
229
* Returns: 0 on success, <0 on failure
231
int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
232
struct wpa_ie_data *data)
234
#ifndef CONFIG_NO_WPA2
235
const struct rsn_ie_hdr *hdr;
240
os_memset(data, 0, sizeof(*data));
241
data->proto = WPA_PROTO_RSN;
242
data->pairwise_cipher = WPA_CIPHER_CCMP;
243
data->group_cipher = WPA_CIPHER_CCMP;
244
data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
245
data->capabilities = 0;
248
#ifdef CONFIG_IEEE80211W
249
data->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
250
#else /* CONFIG_IEEE80211W */
251
data->mgmt_group_cipher = 0;
252
#endif /* CONFIG_IEEE80211W */
254
if (rsn_ie_len == 0) {
255
/* No RSN IE - fail silently */
259
if (rsn_ie_len < sizeof(struct rsn_ie_hdr)) {
260
wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
261
__func__, (unsigned long) rsn_ie_len);
265
hdr = (const struct rsn_ie_hdr *) rsn_ie;
267
if (hdr->elem_id != WLAN_EID_RSN ||
268
hdr->len != rsn_ie_len - 2 ||
269
WPA_GET_LE16(hdr->version) != RSN_VERSION) {
270
wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
275
pos = (const u8 *) (hdr + 1);
276
left = rsn_ie_len - sizeof(*hdr);
278
if (left >= RSN_SELECTOR_LEN) {
279
data->group_cipher = rsn_selector_to_bitfield(pos);
280
#ifdef CONFIG_IEEE80211W
281
if (data->group_cipher == WPA_CIPHER_AES_128_CMAC) {
282
wpa_printf(MSG_DEBUG, "%s: AES-128-CMAC used as group "
286
#endif /* CONFIG_IEEE80211W */
287
pos += RSN_SELECTOR_LEN;
288
left -= RSN_SELECTOR_LEN;
289
} else if (left > 0) {
290
wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
296
data->pairwise_cipher = 0;
297
count = WPA_GET_LE16(pos);
300
if (count == 0 || left < count * RSN_SELECTOR_LEN) {
301
wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
302
"count %u left %u", __func__, count, left);
305
for (i = 0; i < count; i++) {
306
data->pairwise_cipher |= rsn_selector_to_bitfield(pos);
307
pos += RSN_SELECTOR_LEN;
308
left -= RSN_SELECTOR_LEN;
310
#ifdef CONFIG_IEEE80211W
311
if (data->pairwise_cipher & WPA_CIPHER_AES_128_CMAC) {
312
wpa_printf(MSG_DEBUG, "%s: AES-128-CMAC used as "
313
"pairwise cipher", __func__);
316
#endif /* CONFIG_IEEE80211W */
317
} else if (left == 1) {
318
wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
325
count = WPA_GET_LE16(pos);
328
if (count == 0 || left < count * RSN_SELECTOR_LEN) {
329
wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
330
"count %u left %u", __func__, count, left);
333
for (i = 0; i < count; i++) {
334
data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos);
335
pos += RSN_SELECTOR_LEN;
336
left -= RSN_SELECTOR_LEN;
338
} else if (left == 1) {
339
wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
345
data->capabilities = WPA_GET_LE16(pos);
351
data->num_pmkid = WPA_GET_LE16(pos);
354
if (left < (int) data->num_pmkid * PMKID_LEN) {
355
wpa_printf(MSG_DEBUG, "%s: PMKID underflow "
356
"(num_pmkid=%lu left=%d)",
357
__func__, (unsigned long) data->num_pmkid,
363
pos += data->num_pmkid * PMKID_LEN;
364
left -= data->num_pmkid * PMKID_LEN;
368
#ifdef CONFIG_IEEE80211W
370
data->mgmt_group_cipher = rsn_selector_to_bitfield(pos);
371
if (data->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC) {
372
wpa_printf(MSG_DEBUG, "%s: Unsupported management "
373
"group cipher 0x%x", __func__,
374
data->mgmt_group_cipher);
377
pos += RSN_SELECTOR_LEN;
378
left -= RSN_SELECTOR_LEN;
380
#endif /* CONFIG_IEEE80211W */
383
wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes - ignored",
388
#else /* CONFIG_NO_WPA2 */
390
#endif /* CONFIG_NO_WPA2 */
394
#ifdef CONFIG_IEEE80211R
397
* wpa_derive_pmk_r0 - Derive PMK-R0 and PMKR0Name
399
* IEEE 802.11r/D5.0 - 8.5.1.5.3
401
void wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
402
const u8 *ssid, size_t ssid_len,
403
const u8 *mdid, const u8 *r0kh_id, size_t r0kh_id_len,
404
const u8 *s0kh_id, u8 *pmk_r0, u8 *pmk_r0_name)
406
u8 buf[1 + WPA_MAX_SSID_LEN + MOBILITY_DOMAIN_ID_LEN + 1 +
407
FT_R0KH_ID_MAX_LEN + ETH_ALEN];
408
u8 *pos, r0_key_data[48], hash[32];
413
* R0-Key-Data = KDF-384(XXKey, "R0 Key Derivation",
414
* SSIDlength || SSID || MDID || R0KHlength ||
415
* R0KH-ID || S0KH-ID)
416
* XXKey is either the second 256 bits of MSK or PSK.
417
* PMK-R0 = L(R0-Key-Data, 0, 256)
418
* PMK-R0Name-Salt = L(R0-Key-Data, 256, 128)
420
if (ssid_len > WPA_MAX_SSID_LEN || r0kh_id_len > FT_R0KH_ID_MAX_LEN)
424
os_memcpy(pos, ssid, ssid_len);
426
os_memcpy(pos, mdid, MOBILITY_DOMAIN_ID_LEN);
427
pos += MOBILITY_DOMAIN_ID_LEN;
428
*pos++ = r0kh_id_len;
429
os_memcpy(pos, r0kh_id, r0kh_id_len);
431
os_memcpy(pos, s0kh_id, ETH_ALEN);
434
sha256_prf(xxkey, xxkey_len, "R0 Key Derivation", buf, pos - buf,
435
r0_key_data, sizeof(r0_key_data));
436
os_memcpy(pmk_r0, r0_key_data, PMK_LEN);
439
* PMKR0Name = Truncate-128(SHA-256("R0 Key Name" || PMK-R0Name-Salt)
441
addr[0] = (const u8 *) "R0 Key Name";
443
addr[1] = r0_key_data + PMK_LEN;
446
sha256_vector(2, addr, len, hash);
447
os_memcpy(pmk_r0_name, hash, WPA_PMK_NAME_LEN);
452
* wpa_derive_pmk_r1_name - Derive PMKR1Name
454
* IEEE 802.11r/D5.0 - 8.5.1.5.4
456
void wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
457
const u8 *s1kh_id, u8 *pmk_r1_name)
464
* PMKR1Name = Truncate-128(SHA-256("R1 Key Name" || PMKR0Name ||
465
* R1KH-ID || S1KH-ID))
467
addr[0] = (const u8 *) "R1 Key Name";
469
addr[1] = pmk_r0_name;
470
len[1] = WPA_PMK_NAME_LEN;
472
len[2] = FT_R1KH_ID_LEN;
476
sha256_vector(4, addr, len, hash);
477
os_memcpy(pmk_r1_name, hash, WPA_PMK_NAME_LEN);
482
* wpa_derive_pmk_r1 - Derive PMK-R1 and PMKR1Name from PMK-R0
484
* IEEE 802.11r/D5.0 - 8.5.1.5.4
486
void wpa_derive_pmk_r1(const u8 *pmk_r0, const u8 *pmk_r0_name,
487
const u8 *r1kh_id, const u8 *s1kh_id,
488
u8 *pmk_r1, u8 *pmk_r1_name)
490
u8 buf[FT_R1KH_ID_LEN + ETH_ALEN];
493
/* PMK-R1 = KDF-256(PMK-R0, "R1 Key Derivation", R1KH-ID || S1KH-ID) */
495
os_memcpy(pos, r1kh_id, FT_R1KH_ID_LEN);
496
pos += FT_R1KH_ID_LEN;
497
os_memcpy(pos, s1kh_id, ETH_ALEN);
500
sha256_prf(pmk_r0, PMK_LEN, "R1 Key Derivation", buf, pos - buf,
503
wpa_derive_pmk_r1_name(pmk_r0_name, r1kh_id, s1kh_id, pmk_r1_name);
508
* wpa_pmk_r1_to_ptk - Derive PTK and PTKName from PMK-R1
510
* IEEE 802.11r/D5.0 - 8.5.1.5.5
512
void wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce,
513
const u8 *sta_addr, const u8 *bssid,
514
const u8 *pmk_r1_name,
515
u8 *ptk, size_t ptk_len, u8 *ptk_name)
517
u8 buf[2 * WPA_NONCE_LEN + 2 * ETH_ALEN];
523
* PTK = KDF-PTKLen(PMK-R1, "PTK Key derivation", SNonce || ANonce ||
527
os_memcpy(pos, snonce, WPA_NONCE_LEN);
528
pos += WPA_NONCE_LEN;
529
os_memcpy(pos, anonce, WPA_NONCE_LEN);
530
pos += WPA_NONCE_LEN;
531
os_memcpy(pos, bssid, ETH_ALEN);
533
os_memcpy(pos, sta_addr, ETH_ALEN);
536
sha256_prf(pmk_r1, PMK_LEN, "PTK Key derivation", buf, pos - buf,
540
* PTKName = Truncate-128(SHA-256(PMKR1Name || "PTK Name" || SNonce ||
541
* ANonce || BSSID || STA-ADDR))
543
addr[0] = pmk_r1_name;
544
len[0] = WPA_PMK_NAME_LEN;
545
addr[1] = (const u8 *) "PTK Name";
548
len[2] = WPA_NONCE_LEN;
550
len[3] = WPA_NONCE_LEN;
556
sha256_vector(6, addr, len, hash);
557
os_memcpy(ptk_name, hash, WPA_PMK_NAME_LEN);
560
#endif /* CONFIG_IEEE80211R */