1 /* 2 * WPA Supplicant - PeerKey for Direct Link Setup (DLS) 3 * Copyright (c) 2006-2008, Jouni Malinen <j (at) w1.fi> 4 * 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. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15 #include "includes.h" 16 17 #ifdef CONFIG_PEERKEY 18 19 #include "common.h" 20 #include "crypto/sha1.h" 21 #include "crypto/sha256.h" 22 #include "eloop.h" 23 #include "wpa.h" 24 #include "wpa_i.h" 25 #include "wpa_ie.h" 26 #include "ieee802_11_defs.h" 27 #include "peerkey.h" 28 29 30 static u8 * wpa_add_ie(u8 *pos, const u8 *ie, size_t ie_len) 31 { 32 os_memcpy(pos, ie, ie_len); 33 return pos + ie_len; 34 } 35 36 37 static u8 * wpa_add_kde(u8 *pos, u32 kde, const u8 *data, size_t data_len) 38 { 39 *pos++ = WLAN_EID_VENDOR_SPECIFIC; 40 *pos++ = RSN_SELECTOR_LEN + data_len; 41 RSN_SELECTOR_PUT(pos, kde); 42 pos += RSN_SELECTOR_LEN; 43 os_memcpy(pos, data, data_len); 44 pos += data_len; 45 return pos; 46 } 47 48 49 static void wpa_supplicant_smk_timeout(void *eloop_ctx, void *timeout_ctx) 50 { 51 #if 0 52 struct wpa_sm *sm = eloop_ctx; 53 struct wpa_peerkey *peerkey = timeout_ctx; 54 #endif 55 /* TODO: time out SMK and any STK that was generated using this SMK */ 56 } 57 58 59 static void wpa_supplicant_peerkey_free(struct wpa_sm *sm, 60 struct wpa_peerkey *peerkey) 61 { 62 eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey); 63 os_free(peerkey); 64 } 65 66 67 static int wpa_supplicant_send_smk_error(struct wpa_sm *sm, const u8 *dst, 68 const u8 *peer, 69 u16 mui, u16 error_type, int ver) 70 { 71 size_t rlen; 72 struct wpa_eapol_key *err; 73 struct rsn_error_kde error; 74 u8 *rbuf, *pos; 75 size_t kde_len; 76 u16 key_info; 77 78 kde_len = 2 + RSN_SELECTOR_LEN + sizeof(error); 79 if (peer) 80 kde_len += 2 + RSN_SELECTOR_LEN + ETH_ALEN; 81 82 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, 83 NULL, sizeof(*err) + kde_len, &rlen, 84 (void *) &err); 85 if (rbuf == NULL) 86 return -1; 87 88 err->type = EAPOL_KEY_TYPE_RSN; 89 key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC | 90 WPA_KEY_INFO_SECURE | WPA_KEY_INFO_ERROR | 91 WPA_KEY_INFO_REQUEST; 92 WPA_PUT_BE16(err->key_info, key_info); 93 WPA_PUT_BE16(err->key_length, 0); 94 os_memcpy(err->replay_counter, sm->request_counter, 95 WPA_REPLAY_COUNTER_LEN); 96 inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN); 97 98 WPA_PUT_BE16(err->key_data_length, (u16) kde_len); 99 pos = (u8 *) (err + 1); 100 101 if (peer) { 102 /* Peer MAC Address KDE */ 103 pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN); 104 } 105 106 /* Error KDE */ 107 error.mui = host_to_be16(mui); 108 error.error_type = host_to_be16(error_type); 109 wpa_add_kde(pos, RSN_KEY_DATA_ERROR, (u8 *) &error, sizeof(error)); 110 111 if (peer) { 112 wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK Error (peer " 113 MACSTR " mui %d error_type %d)", 114 MAC2STR(peer), mui, error_type); 115 } else { 116 wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK Error " 117 "(mui %d error_type %d)", mui, error_type); 118 } 119 120 wpa_eapol_key_send(sm, sm->ptk.kck, ver, dst, ETH_P_EAPOL, 121 rbuf, rlen, err->key_mic); 122 123 return 0; 124 } 125 126 127 static int wpa_supplicant_send_smk_m3(struct wpa_sm *sm, 128 const unsigned char *src_addr, 129 const struct wpa_eapol_key *key, 130 int ver, struct wpa_peerkey *peerkey) 131 { 132 size_t rlen; 133 struct wpa_eapol_key *reply; 134 u8 *rbuf, *pos; 135 size_t kde_len; 136 u16 key_info; 137 138 /* KDEs: Peer RSN IE, Initiator MAC Address, Initiator Nonce */ 139 kde_len = peerkey->rsnie_p_len + 140 2 + RSN_SELECTOR_LEN + ETH_ALEN + 141 2 + RSN_SELECTOR_LEN + WPA_NONCE_LEN; 142 143 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, 144 NULL, sizeof(*reply) + kde_len, &rlen, 145 (void *) &reply); 146 if (rbuf == NULL) 147 return -1; 148 149 reply->type = EAPOL_KEY_TYPE_RSN; 150 key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC | 151 WPA_KEY_INFO_SECURE; 152 WPA_PUT_BE16(reply->key_info, key_info); 153 WPA_PUT_BE16(reply->key_length, 0); 154 os_memcpy(reply->replay_counter, key->replay_counter, 155 WPA_REPLAY_COUNTER_LEN); 156 157 os_memcpy(reply->key_nonce, peerkey->pnonce, WPA_NONCE_LEN); 158 159 WPA_PUT_BE16(reply->key_data_length, (u16) kde_len); 160 pos = (u8 *) (reply + 1); 161 162 /* Peer RSN IE */ 163 pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len); 164 165 /* Initiator MAC Address KDE */ 166 pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peerkey->addr, ETH_ALEN); 167 168 /* Initiator Nonce */ 169 wpa_add_kde(pos, RSN_KEY_DATA_NONCE, peerkey->inonce, WPA_NONCE_LEN); 170 171 wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK M3"); 172 wpa_eapol_key_send(sm, sm->ptk.kck, ver, src_addr, ETH_P_EAPOL, 173 rbuf, rlen, reply->key_mic); 174 175 return 0; 176 } 177 178 179 static int wpa_supplicant_process_smk_m2( 180 struct wpa_sm *sm, const unsigned char *src_addr, 181 const struct wpa_eapol_key *key, size_t extra_len, int ver) 182 { 183 struct wpa_peerkey *peerkey; 184 struct wpa_eapol_ie_parse kde; 185 struct wpa_ie_data ie; 186 int cipher; 187 struct rsn_ie_hdr *hdr; 188 u8 *pos; 189 190 wpa_printf(MSG_DEBUG, "RSN: Received SMK M2"); 191 192 if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) { 193 wpa_printf(MSG_INFO, "RSN: SMK handshake not allowed for " 194 "the current network"); 195 return -1; 196 } 197 198 if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) < 199 0) { 200 wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M2"); 201 return -1; 202 } 203 204 if (kde.rsn_ie == NULL || kde.mac_addr == NULL || 205 kde.mac_addr_len < ETH_ALEN) { 206 wpa_printf(MSG_INFO, "RSN: No RSN IE or MAC address KDE in " 207 "SMK M2"); 208 return -1; 209 } 210 211 wpa_printf(MSG_DEBUG, "RSN: SMK M2 - SMK initiator " MACSTR, 212 MAC2STR(kde.mac_addr)); 213 214 if (kde.rsn_ie_len > PEERKEY_MAX_IE_LEN) { 215 wpa_printf(MSG_INFO, "RSN: Too long Initiator RSN IE in SMK " 216 "M2"); 217 return -1; 218 } 219 220 if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) { 221 wpa_printf(MSG_INFO, "RSN: Failed to parse RSN IE in SMK M2"); 222 return -1; 223 } 224 225 cipher = ie.pairwise_cipher & sm->allowed_pairwise_cipher; 226 if (cipher & WPA_CIPHER_CCMP) { 227 wpa_printf(MSG_DEBUG, "RSN: Using CCMP for PeerKey"); 228 cipher = WPA_CIPHER_CCMP; 229 } else if (cipher & WPA_CIPHER_TKIP) { 230 wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey"); 231 cipher = WPA_CIPHER_TKIP; 232 } else { 233 wpa_printf(MSG_INFO, "RSN: No acceptable cipher in SMK M2"); 234 wpa_supplicant_send_smk_error(sm, src_addr, kde.mac_addr, 235 STK_MUI_SMK, STK_ERR_CPHR_NS, 236 ver); 237 return -1; 238 } 239 240 /* TODO: find existing entry and if found, use that instead of adding 241 * a new one; how to handle the case where both ends initiate at the 242 * same time? */ 243 peerkey = os_zalloc(sizeof(*peerkey)); 244 if (peerkey == NULL) 245 return -1; 246 os_memcpy(peerkey->addr, kde.mac_addr, ETH_ALEN); 247 os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN); 248 os_memcpy(peerkey->rsnie_i, kde.rsn_ie, kde.rsn_ie_len); 249 peerkey->rsnie_i_len = kde.rsn_ie_len; 250 peerkey->cipher = cipher; 251 #ifdef CONFIG_IEEE80211W 252 if (ie.key_mgmt & (WPA_KEY_MGMT_IEEE8021X_SHA256 | 253 WPA_KEY_MGMT_PSK_SHA256)) 254 peerkey->use_sha256 = 1; 255 #endif /* CONFIG_IEEE80211W */ 256 257 if (os_get_random(peerkey->pnonce, WPA_NONCE_LEN)) { 258 wpa_msg(sm->ctx->ctx, MSG_WARNING, 259 "WPA: Failed to get random data for PNonce"); 260 wpa_supplicant_peerkey_free(sm, peerkey); 261 return -1; 262 } 263 264 hdr = (struct rsn_ie_hdr *) peerkey->rsnie_p; 265 hdr->elem_id = WLAN_EID_RSN; 266 WPA_PUT_LE16(hdr->version, RSN_VERSION); 267 pos = (u8 *) (hdr + 1); 268 /* Group Suite can be anything for SMK RSN IE; receiver will just 269 * ignore it. */ 270 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); 271 pos += RSN_SELECTOR_LEN; 272 /* Include only the selected cipher in pairwise cipher suite */ 273 WPA_PUT_LE16(pos, 1); 274 pos += 2; 275 if (cipher == WPA_CIPHER_CCMP) 276 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); 277 else if (cipher == WPA_CIPHER_TKIP) 278 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP); 279 pos += RSN_SELECTOR_LEN; 280 281 hdr->len = (pos - peerkey->rsnie_p) - 2; 282 peerkey->rsnie_p_len = pos - peerkey->rsnie_p; 283 wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake", 284 peerkey->rsnie_p, peerkey->rsnie_p_len); 285 286 wpa_supplicant_send_smk_m3(sm, src_addr, key, ver, peerkey); 287 288 peerkey->next = sm->peerkey; 289 sm->peerkey = peerkey; 290 291 return 0; 292 } 293 294 295 /** 296 * rsn_smkid - Derive SMK identifier 297 * @smk: Station master key (32 bytes) 298 * @pnonce: Peer Nonce 299 * @mac_p: Peer MAC address 300 * @inonce: Initiator Nonce 301 * @mac_i: Initiator MAC address 302 * @use_sha256: Whether to use SHA256-based KDF 303 * 304 * 8.5.1.4 Station to station (STK) key hierarchy 305 * SMKID = HMAC-SHA1-128(SMK, "SMK Name" || PNonce || MAC_P || INonce || MAC_I) 306 */ 307 static void rsn_smkid(const u8 *smk, const u8 *pnonce, const u8 *mac_p, 308 const u8 *inonce, const u8 *mac_i, u8 *smkid, 309 int use_sha256) 310 { 311 char *title = "SMK Name"; 312 const u8 *addr[5]; 313 const size_t len[5] = { 8, WPA_NONCE_LEN, ETH_ALEN, WPA_NONCE_LEN, 314 ETH_ALEN }; 315 unsigned char hash[SHA256_MAC_LEN]; 316 317 addr[0] = (u8 *) title; 318 addr[1] = pnonce; 319 addr[2] = mac_p; 320 addr[3] = inonce; 321 addr[4] = mac_i; 322 323 #ifdef CONFIG_IEEE80211W 324 if (use_sha256) 325 hmac_sha256_vector(smk, PMK_LEN, 5, addr, len, hash); 326 else 327 #endif /* CONFIG_IEEE80211W */ 328 hmac_sha1_vector(smk, PMK_LEN, 5, addr, len, hash); 329 os_memcpy(smkid, hash, PMKID_LEN); 330 } 331 332 333 static void wpa_supplicant_send_stk_1_of_4(struct wpa_sm *sm, 334 struct wpa_peerkey *peerkey) 335 { 336 size_t mlen; 337 struct wpa_eapol_key *msg; 338 u8 *mbuf; 339 size_t kde_len; 340 u16 key_info, ver; 341 342 kde_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN; 343 344 mbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL, 345 sizeof(*msg) + kde_len, &mlen, 346 (void *) &msg); 347 if (mbuf == NULL) 348 return; 349 350 msg->type = EAPOL_KEY_TYPE_RSN; 351 352 if (peerkey->cipher == WPA_CIPHER_CCMP) 353 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES; 354 else 355 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4; 356 357 key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK; 358 WPA_PUT_BE16(msg->key_info, key_info); 359 360 if (peerkey->cipher == WPA_CIPHER_CCMP) 361 WPA_PUT_BE16(msg->key_length, 16); 362 else 363 WPA_PUT_BE16(msg->key_length, 32); 364 365 os_memcpy(msg->replay_counter, peerkey->replay_counter, 366 WPA_REPLAY_COUNTER_LEN); 367 inc_byte_array(peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN); 368 369 WPA_PUT_BE16(msg->key_data_length, kde_len); 370 wpa_add_kde((u8 *) (msg + 1), RSN_KEY_DATA_PMKID, 371 peerkey->smkid, PMKID_LEN); 372 373 if (os_get_random(peerkey->inonce, WPA_NONCE_LEN)) { 374 wpa_msg(sm->ctx->ctx, MSG_WARNING, 375 "RSN: Failed to get random data for INonce (STK)"); 376 os_free(mbuf); 377 return; 378 } 379 wpa_hexdump(MSG_DEBUG, "RSN: INonce for STK 4-Way Handshake", 380 peerkey->inonce, WPA_NONCE_LEN); 381 os_memcpy(msg->key_nonce, peerkey->inonce, WPA_NONCE_LEN); 382 383 wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 1/4 to " MACSTR, 384 MAC2STR(peerkey->addr)); 385 wpa_eapol_key_send(sm, NULL, ver, peerkey->addr, ETH_P_EAPOL, 386 mbuf, mlen, NULL); 387 } 388 389 390 static void wpa_supplicant_send_stk_3_of_4(struct wpa_sm *sm, 391 struct wpa_peerkey *peerkey) 392 { 393 size_t mlen; 394 struct wpa_eapol_key *msg; 395 u8 *mbuf, *pos; 396 size_t kde_len; 397 u16 key_info, ver; 398 be32 lifetime; 399 400 kde_len = peerkey->rsnie_i_len + 401 2 + RSN_SELECTOR_LEN + sizeof(lifetime); 402 403 mbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL, 404 sizeof(*msg) + kde_len, &mlen, 405 (void *) &msg); 406 if (mbuf == NULL) 407 return; 408 409 msg->type = EAPOL_KEY_TYPE_RSN; 410 411 if (peerkey->cipher == WPA_CIPHER_CCMP) 412 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES; 413 else 414 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4; 415 416 key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK | 417 WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE; 418 WPA_PUT_BE16(msg->key_info, key_info); 419 420 if (peerkey->cipher == WPA_CIPHER_CCMP) 421 WPA_PUT_BE16(msg->key_length, 16); 422 else 423 WPA_PUT_BE16(msg->key_length, 32); 424 425 os_memcpy(msg->replay_counter, peerkey->replay_counter, 426 WPA_REPLAY_COUNTER_LEN); 427 inc_byte_array(peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN); 428 429 WPA_PUT_BE16(msg->key_data_length, kde_len); 430 pos = (u8 *) (msg + 1); 431 pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len); 432 lifetime = host_to_be32(peerkey->lifetime); 433 wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME, 434 (u8 *) &lifetime, sizeof(lifetime)); 435 436 os_memcpy(msg->key_nonce, peerkey->inonce, WPA_NONCE_LEN); 437 438 wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 3/4 to " MACSTR, 439 MAC2STR(peerkey->addr)); 440 wpa_eapol_key_send(sm, peerkey->stk.kck, ver, peerkey->addr, 441 ETH_P_EAPOL, mbuf, mlen, msg->key_mic); 442 } 443 444 445 static int wpa_supplicant_process_smk_m4(struct wpa_peerkey *peerkey, 446 struct wpa_eapol_ie_parse *kde) 447 { 448 wpa_printf(MSG_DEBUG, "RSN: Received SMK M4 (Initiator " MACSTR ")", 449 MAC2STR(kde->mac_addr)); 450 451 if (os_memcmp(kde->smk + PMK_LEN, peerkey->pnonce, WPA_NONCE_LEN) != 0) 452 { 453 wpa_printf(MSG_INFO, "RSN: PNonce in SMK KDE does not " 454 "match with the one used in SMK M3"); 455 return -1; 456 } 457 458 if (os_memcmp(kde->nonce, peerkey->inonce, WPA_NONCE_LEN) != 0) { 459 wpa_printf(MSG_INFO, "RSN: INonce in SMK M4 did not " 460 "match with the one received in SMK M2"); 461 return -1; 462 } 463 464 return 0; 465 } 466 467 468 static int wpa_supplicant_process_smk_m5(struct wpa_sm *sm, 469 const unsigned char *src_addr, 470 const struct wpa_eapol_key *key, 471 int ver, 472 struct wpa_peerkey *peerkey, 473 struct wpa_eapol_ie_parse *kde) 474 { 475 int cipher; 476 struct wpa_ie_data ie; 477 478 wpa_printf(MSG_DEBUG, "RSN: Received SMK M5 (Peer " MACSTR ")", 479 MAC2STR(kde->mac_addr)); 480 if (kde->rsn_ie == NULL || kde->rsn_ie_len > PEERKEY_MAX_IE_LEN || 481 wpa_parse_wpa_ie_rsn(kde->rsn_ie, kde->rsn_ie_len, &ie) < 0) { 482 wpa_printf(MSG_INFO, "RSN: No RSN IE in SMK M5"); 483 /* TODO: abort negotiation */ 484 return -1; 485 } 486 487 if (os_memcmp(key->key_nonce, peerkey->inonce, WPA_NONCE_LEN) != 0) { 488 wpa_printf(MSG_INFO, "RSN: Key Nonce in SMK M5 does " 489 "not match with INonce used in SMK M1"); 490 return -1; 491 } 492 493 if (os_memcmp(kde->smk + PMK_LEN, peerkey->inonce, WPA_NONCE_LEN) != 0) 494 { 495 wpa_printf(MSG_INFO, "RSN: INonce in SMK KDE does not " 496 "match with the one used in SMK M1"); 497 return -1; 498 } 499 500 os_memcpy(peerkey->rsnie_p, kde->rsn_ie, kde->rsn_ie_len); 501 peerkey->rsnie_p_len = kde->rsn_ie_len; 502 os_memcpy(peerkey->pnonce, kde->nonce, WPA_NONCE_LEN); 503 504 cipher = ie.pairwise_cipher & sm->allowed_pairwise_cipher; 505 if (cipher & WPA_CIPHER_CCMP) { 506 wpa_printf(MSG_DEBUG, "RSN: Using CCMP for PeerKey"); 507 peerkey->cipher = WPA_CIPHER_CCMP; 508 } else if (cipher & WPA_CIPHER_TKIP) { 509 wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey"); 510 peerkey->cipher = WPA_CIPHER_TKIP; 511 } else { 512 wpa_printf(MSG_INFO, "RSN: SMK Peer STA " MACSTR " selected " 513 "unacceptable cipher", MAC2STR(kde->mac_addr)); 514 wpa_supplicant_send_smk_error(sm, src_addr, kde->mac_addr, 515 STK_MUI_SMK, STK_ERR_CPHR_NS, 516 ver); 517 /* TODO: abort negotiation */ 518 return -1; 519 } 520 521 return 0; 522 } 523 524 525 static int wpa_supplicant_process_smk_m45( 526 struct wpa_sm *sm, const unsigned char *src_addr, 527 const struct wpa_eapol_key *key, size_t extra_len, int ver) 528 { 529 struct wpa_peerkey *peerkey; 530 struct wpa_eapol_ie_parse kde; 531 u32 lifetime; 532 struct os_time now; 533 534 if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) { 535 wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for " 536 "the current network"); 537 return -1; 538 } 539 540 if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) < 541 0) { 542 wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M4/M5"); 543 return -1; 544 } 545 546 if (kde.mac_addr == NULL || kde.mac_addr_len < ETH_ALEN || 547 kde.nonce == NULL || kde.nonce_len < WPA_NONCE_LEN || 548 kde.smk == NULL || kde.smk_len < PMK_LEN + WPA_NONCE_LEN || 549 kde.lifetime == NULL || kde.lifetime_len < 4) { 550 wpa_printf(MSG_INFO, "RSN: No MAC Address, Nonce, SMK, or " 551 "Lifetime KDE in SMK M4/M5"); 552 return -1; 553 } 554 555 for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) { 556 if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) == 0 && 557 os_memcmp(peerkey->initiator ? peerkey->inonce : 558 peerkey->pnonce, 559 key->key_nonce, WPA_NONCE_LEN) == 0) 560 break; 561 } 562 if (peerkey == NULL) { 563 wpa_printf(MSG_INFO, "RSN: No matching SMK handshake found " 564 "for SMK M4/M5: peer " MACSTR, 565 MAC2STR(kde.mac_addr)); 566 return -1; 567 } 568 569 if (peerkey->initiator) { 570 if (wpa_supplicant_process_smk_m5(sm, src_addr, key, ver, 571 peerkey, &kde) < 0) 572 return -1; 573 } else { 574 if (wpa_supplicant_process_smk_m4(peerkey, &kde) < 0) 575 return -1; 576 } 577 578 os_memcpy(peerkey->smk, kde.smk, PMK_LEN); 579 peerkey->smk_complete = 1; 580 wpa_hexdump_key(MSG_DEBUG, "RSN: SMK", peerkey->smk, PMK_LEN); 581 lifetime = WPA_GET_BE32(kde.lifetime); 582 wpa_printf(MSG_DEBUG, "RSN: SMK lifetime %u seconds", lifetime); 583 if (lifetime > 1000000000) 584 lifetime = 1000000000; /* avoid overflowing expiration time */ 585 peerkey->lifetime = lifetime; 586 os_get_time(&now); 587 peerkey->expiration = now.sec + lifetime; 588 eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout, 589 sm, peerkey); 590 591 if (peerkey->initiator) { 592 rsn_smkid(peerkey->smk, peerkey->pnonce, peerkey->addr, 593 peerkey->inonce, sm->own_addr, peerkey->smkid, 594 peerkey->use_sha256); 595 wpa_supplicant_send_stk_1_of_4(sm, peerkey); 596 } else { 597 rsn_smkid(peerkey->smk, peerkey->pnonce, sm->own_addr, 598 peerkey->inonce, peerkey->addr, peerkey->smkid, 599 peerkey->use_sha256); 600 } 601 wpa_hexdump(MSG_DEBUG, "RSN: SMKID", peerkey->smkid, PMKID_LEN); 602 603 return 0; 604 } 605 606 607 static int wpa_supplicant_process_smk_error( 608 struct wpa_sm *sm, const unsigned char *src_addr, 609 const struct wpa_eapol_key *key, size_t extra_len) 610 { 611 struct wpa_eapol_ie_parse kde; 612 struct rsn_error_kde error; 613 u8 peer[ETH_ALEN]; 614 u16 error_type; 615 616 wpa_printf(MSG_DEBUG, "RSN: Received SMK Error"); 617 618 if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) { 619 wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for " 620 "the current network"); 621 return -1; 622 } 623 624 if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) < 625 0) { 626 wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK Error"); 627 return -1; 628 } 629 630 if (kde.error == NULL || kde.error_len < sizeof(error)) { 631 wpa_printf(MSG_INFO, "RSN: No Error KDE in SMK Error"); 632 return -1; 633 } 634 635 if (kde.mac_addr && kde.mac_addr_len >= ETH_ALEN) 636 os_memcpy(peer, kde.mac_addr, ETH_ALEN); 637 os_memcpy(&error, kde.error, sizeof(error)); 638 error_type = be_to_host16(error.error_type); 639 wpa_msg(sm->ctx->ctx, MSG_INFO, 640 "RSN: SMK Error KDE received: MUI %d error_type %d peer " 641 MACSTR, 642 be_to_host16(error.mui), error_type, 643 MAC2STR(peer)); 644 645 if (kde.mac_addr && 646 (error_type == STK_ERR_STA_NR || error_type == STK_ERR_STA_NRSN || 647 error_type == STK_ERR_CPHR_NS)) { 648 struct wpa_peerkey *peerkey; 649 650 for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) { 651 if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) == 652 0) 653 break; 654 } 655 if (peerkey == NULL) { 656 wpa_printf(MSG_DEBUG, "RSN: No matching SMK handshake " 657 "found for SMK Error"); 658 return -1; 659 } 660 /* TODO: abort SMK/STK handshake and remove all related keys */ 661 } 662 663 return 0; 664 } 665 666 667 static void wpa_supplicant_process_stk_1_of_4(struct wpa_sm *sm, 668 struct wpa_peerkey *peerkey, 669 const struct wpa_eapol_key *key, 670 u16 ver) 671 { 672 struct wpa_eapol_ie_parse ie; 673 const u8 *kde; 674 size_t len, kde_buf_len; 675 struct wpa_ptk *stk; 676 u8 buf[8], *kde_buf, *pos; 677 be32 lifetime; 678 679 wpa_printf(MSG_DEBUG, "RSN: RX message 1 of STK 4-Way Handshake from " 680 MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver); 681 682 os_memset(&ie, 0, sizeof(ie)); 683 684 /* RSN: msg 1/4 should contain SMKID for the selected SMK */ 685 kde = (const u8 *) (key + 1); 686 len = WPA_GET_BE16(key->key_data_length); 687 wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", kde, len); 688 if (wpa_supplicant_parse_ies(kde, len, &ie) < 0 || ie.pmkid == NULL) { 689 wpa_printf(MSG_DEBUG, "RSN: No SMKID in STK 1/4"); 690 return; 691 } 692 if (os_memcmp(ie.pmkid, peerkey->smkid, PMKID_LEN) != 0) { 693 wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 1/4", 694 ie.pmkid, PMKID_LEN); 695 return; 696 } 697 698 if (os_get_random(peerkey->pnonce, WPA_NONCE_LEN)) { 699 wpa_msg(sm->ctx->ctx, MSG_WARNING, 700 "RSN: Failed to get random data for PNonce"); 701 return; 702 } 703 wpa_hexdump(MSG_DEBUG, "WPA: Renewed PNonce", 704 peerkey->pnonce, WPA_NONCE_LEN); 705 706 /* Calculate STK which will be stored as a temporary STK until it has 707 * been verified when processing message 3/4. */ 708 stk = &peerkey->tstk; 709 wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion", 710 sm->own_addr, peerkey->addr, 711 peerkey->pnonce, key->key_nonce, 712 (u8 *) stk, sizeof(*stk), 713 peerkey->use_sha256); 714 /* Supplicant: swap tx/rx Mic keys */ 715 os_memcpy(buf, stk->u.auth.tx_mic_key, 8); 716 os_memcpy(stk->u.auth.tx_mic_key, stk->u.auth.rx_mic_key, 8); 717 os_memcpy(stk->u.auth.rx_mic_key, buf, 8); 718 peerkey->tstk_set = 1; 719 720 kde_buf_len = peerkey->rsnie_p_len + 721 2 + RSN_SELECTOR_LEN + sizeof(lifetime) + 722 2 + RSN_SELECTOR_LEN + PMKID_LEN; 723 kde_buf = os_malloc(kde_buf_len); 724 if (kde_buf == NULL) 725 return; 726 pos = kde_buf; 727 pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len); 728 lifetime = host_to_be32(peerkey->lifetime); 729 pos = wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME, 730 (u8 *) &lifetime, sizeof(lifetime)); 731 wpa_add_kde(pos, RSN_KEY_DATA_PMKID, peerkey->smkid, PMKID_LEN); 732 733 if (wpa_supplicant_send_2_of_4(sm, peerkey->addr, key, ver, 734 peerkey->pnonce, kde_buf, kde_buf_len, 735 stk)) { 736 os_free(kde_buf); 737 return; 738 } 739 os_free(kde_buf); 740 741 os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN); 742 } 743 744 745 static void wpa_supplicant_update_smk_lifetime(struct wpa_sm *sm, 746 struct wpa_peerkey *peerkey, 747 struct wpa_eapol_ie_parse *kde) 748 { 749 u32 lifetime; 750 struct os_time now; 751 752 if (kde->lifetime == NULL || kde->lifetime_len < sizeof(lifetime)) 753 return; 754 755 lifetime = WPA_GET_BE32(kde->lifetime); 756 757 if (lifetime >= peerkey->lifetime) { 758 wpa_printf(MSG_DEBUG, "RSN: Peer used SMK lifetime %u seconds " 759 "which is larger than or equal to own value %u " 760 "seconds - ignored", lifetime, peerkey->lifetime); 761 return; 762 } 763 764 wpa_printf(MSG_DEBUG, "RSN: Peer used shorter SMK lifetime %u seconds " 765 "(own was %u seconds) - updated", 766 lifetime, peerkey->lifetime); 767 peerkey->lifetime = lifetime; 768 769 os_get_time(&now); 770 peerkey->expiration = now.sec + lifetime; 771 eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey); 772 eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout, 773 sm, peerkey); 774 } 775 776 777 static void wpa_supplicant_process_stk_2_of_4(struct wpa_sm *sm, 778 struct wpa_peerkey *peerkey, 779 const struct wpa_eapol_key *key, 780 u16 ver) 781 { 782 struct wpa_eapol_ie_parse kde; 783 const u8 *keydata; 784 size_t len; 785 786 wpa_printf(MSG_DEBUG, "RSN: RX message 2 of STK 4-Way Handshake from " 787 MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver); 788 789 os_memset(&kde, 0, sizeof(kde)); 790 791 /* RSN: msg 2/4 should contain SMKID for the selected SMK and RSN IE 792 * from the peer. It may also include Lifetime KDE. */ 793 keydata = (const u8 *) (key + 1); 794 len = WPA_GET_BE16(key->key_data_length); 795 wpa_hexdump(MSG_DEBUG, "RSN: msg 2/4 key data", keydata, len); 796 if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0 || 797 kde.pmkid == NULL || kde.rsn_ie == NULL) { 798 wpa_printf(MSG_DEBUG, "RSN: No SMKID or RSN IE in STK 2/4"); 799 return; 800 } 801 802 if (os_memcmp(kde.pmkid, peerkey->smkid, PMKID_LEN) != 0) { 803 wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 2/4", 804 kde.pmkid, PMKID_LEN); 805 return; 806 } 807 808 if (kde.rsn_ie_len != peerkey->rsnie_p_len || 809 os_memcmp(kde.rsn_ie, peerkey->rsnie_p, kde.rsn_ie_len) != 0) { 810 wpa_printf(MSG_INFO, "RSN: Peer RSN IE in SMK and STK " 811 "handshakes did not match"); 812 wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in SMK handshake", 813 peerkey->rsnie_p, peerkey->rsnie_p_len); 814 wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in STK handshake", 815 kde.rsn_ie, kde.rsn_ie_len); 816 return; 817 } 818 819 wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde); 820 821 wpa_supplicant_send_stk_3_of_4(sm, peerkey); 822 os_memcpy(peerkey->pnonce, key->key_nonce, WPA_NONCE_LEN); 823 } 824 825 826 static void wpa_supplicant_process_stk_3_of_4(struct wpa_sm *sm, 827 struct wpa_peerkey *peerkey, 828 const struct wpa_eapol_key *key, 829 u16 ver) 830 { 831 struct wpa_eapol_ie_parse kde; 832 const u8 *keydata; 833 size_t len, key_len; 834 const u8 *_key; 835 u8 key_buf[32], rsc[6]; 836 837 wpa_printf(MSG_DEBUG, "RSN: RX message 3 of STK 4-Way Handshake from " 838 MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver); 839 840 os_memset(&kde, 0, sizeof(kde)); 841 842 /* RSN: msg 3/4 should contain Initiator RSN IE. It may also include 843 * Lifetime KDE. */ 844 keydata = (const u8 *) (key + 1); 845 len = WPA_GET_BE16(key->key_data_length); 846 wpa_hexdump(MSG_DEBUG, "RSN: msg 3/4 key data", keydata, len); 847 if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0) { 848 wpa_printf(MSG_DEBUG, "RSN: Failed to parse key data in " 849 "STK 3/4"); 850 return; 851 } 852 853 if (kde.rsn_ie_len != peerkey->rsnie_i_len || 854 os_memcmp(kde.rsn_ie, peerkey->rsnie_i, kde.rsn_ie_len) != 0) { 855 wpa_printf(MSG_INFO, "RSN: Initiator RSN IE in SMK and STK " 856 "handshakes did not match"); 857 wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in SMK " 858 "handshake", 859 peerkey->rsnie_i, peerkey->rsnie_i_len); 860 wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in STK " 861 "handshake", 862 kde.rsn_ie, kde.rsn_ie_len); 863 return; 864 } 865 866 if (os_memcmp(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN) != 0) { 867 wpa_printf(MSG_WARNING, "RSN: INonce from message 1 of STK " 868 "4-Way Handshake differs from 3 of STK 4-Way " 869 "Handshake - drop packet (src=" MACSTR ")", 870 MAC2STR(peerkey->addr)); 871 return; 872 } 873 874 wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde); 875 876 if (wpa_supplicant_send_4_of_4(sm, peerkey->addr, key, ver, 877 WPA_GET_BE16(key->key_info), 878 NULL, 0, &peerkey->stk)) 879 return; 880 881 _key = (u8 *) peerkey->stk.tk1; 882 if (peerkey->cipher == WPA_CIPHER_TKIP) { 883 /* Swap Tx/Rx keys for Michael MIC */ 884 os_memcpy(key_buf, _key, 16); 885 os_memcpy(key_buf + 16, peerkey->stk.u.auth.rx_mic_key, 8); 886 os_memcpy(key_buf + 24, peerkey->stk.u.auth.tx_mic_key, 8); 887 _key = key_buf; 888 key_len = 32; 889 } else 890 key_len = 16; 891 892 os_memset(rsc, 0, 6); 893 if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1, 894 rsc, sizeof(rsc), _key, key_len) < 0) { 895 wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the " 896 "driver."); 897 return; 898 } 899 } 900 901 902 static void wpa_supplicant_process_stk_4_of_4(struct wpa_sm *sm, 903 struct wpa_peerkey *peerkey, 904 const struct wpa_eapol_key *key, 905 u16 ver) 906 { 907 u8 rsc[6]; 908 909 wpa_printf(MSG_DEBUG, "RSN: RX message 4 of STK 4-Way Handshake from " 910 MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver); 911 912 os_memset(rsc, 0, 6); 913 if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1, 914 rsc, sizeof(rsc), (u8 *) peerkey->stk.tk1, 915 peerkey->cipher == WPA_CIPHER_TKIP ? 32 : 16) < 0) { 916 wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the " 917 "driver."); 918 return; 919 } 920 } 921 922 923 /** 924 * peerkey_verify_eapol_key_mic - Verify PeerKey MIC 925 * @sm: Pointer to WPA state machine data from wpa_sm_init() 926 * @peerkey: Pointer to the PeerKey data for the peer 927 * @key: Pointer to the EAPOL-Key frame header 928 * @ver: Version bits from EAPOL-Key Key Info 929 * @buf: Pointer to the beginning of EAPOL-Key frame 930 * @len: Length of the EAPOL-Key frame 931 * Returns: 0 on success, -1 on failure 932 */ 933 int peerkey_verify_eapol_key_mic(struct wpa_sm *sm, 934 struct wpa_peerkey *peerkey, 935 struct wpa_eapol_key *key, u16 ver, 936 const u8 *buf, size_t len) 937 { 938 u8 mic[16]; 939 int ok = 0; 940 941 if (peerkey->initiator && !peerkey->stk_set) { 942 wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion", 943 sm->own_addr, peerkey->addr, 944 peerkey->inonce, key->key_nonce, 945 (u8 *) &peerkey->stk, sizeof(peerkey->stk), 946 peerkey->use_sha256); 947 peerkey->stk_set = 1; 948 } 949 950 os_memcpy(mic, key->key_mic, 16); 951 if (peerkey->tstk_set) { 952 os_memset(key->key_mic, 0, 16); 953 wpa_eapol_key_mic(peerkey->tstk.kck, ver, buf, len, 954 key->key_mic); 955 if (os_memcmp(mic, key->key_mic, 16) != 0) { 956 wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC " 957 "when using TSTK - ignoring TSTK"); 958 } else { 959 ok = 1; 960 peerkey->tstk_set = 0; 961 peerkey->stk_set = 1; 962 os_memcpy(&peerkey->stk, &peerkey->tstk, 963 sizeof(peerkey->stk)); 964 } 965 } 966 967 if (!ok && peerkey->stk_set) { 968 os_memset(key->key_mic, 0, 16); 969 wpa_eapol_key_mic(peerkey->stk.kck, ver, buf, len, 970 key->key_mic); 971 if (os_memcmp(mic, key->key_mic, 16) != 0) { 972 wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC " 973 "- dropping packet"); 974 return -1; 975 } 976 ok = 1; 977 } 978 979 if (!ok) { 980 wpa_printf(MSG_WARNING, "RSN: Could not verify EAPOL-Key MIC " 981 "- dropping packet"); 982 return -1; 983 } 984 985 os_memcpy(peerkey->replay_counter, key->replay_counter, 986 WPA_REPLAY_COUNTER_LEN); 987 peerkey->replay_counter_set = 1; 988 return 0; 989 } 990 991 992 /** 993 * wpa_sm_stkstart - Send EAPOL-Key Request for STK handshake (STK M1) 994 * @sm: Pointer to WPA state machine data from wpa_sm_init() 995 * @peer: MAC address of the peer STA 996 * Returns: 0 on success, or -1 on failure 997 * 998 * Send an EAPOL-Key Request to the current authenticator to start STK 999 * handshake with the peer. 1000 */ 1001 int wpa_sm_stkstart(struct wpa_sm *sm, const u8 *peer) 1002 { 1003 size_t rlen, kde_len; 1004 struct wpa_eapol_key *req; 1005 int key_info, ver; 1006 u8 bssid[ETH_ALEN], *rbuf, *pos, *count_pos; 1007 u16 count; 1008 struct rsn_ie_hdr *hdr; 1009 struct wpa_peerkey *peerkey; 1010 struct wpa_ie_data ie; 1011 1012 if (sm->proto != WPA_PROTO_RSN || !sm->ptk_set || !sm->peerkey_enabled) 1013 return -1; 1014 1015 if (sm->ap_rsn_ie && 1016 wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &ie) == 0 && 1017 !(ie.capabilities & WPA_CAPABILITY_PEERKEY_ENABLED)) { 1018 wpa_printf(MSG_DEBUG, "RSN: Current AP does not support STK"); 1019 return -1; 1020 } 1021 1022 if (sm->pairwise_cipher == WPA_CIPHER_CCMP) 1023 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES; 1024 else 1025 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4; 1026 1027 if (wpa_sm_get_bssid(sm, bssid) < 0) { 1028 wpa_printf(MSG_WARNING, "Failed to read BSSID for EAPOL-Key " 1029 "SMK M1"); 1030 return -1; 1031 } 1032 1033 /* TODO: find existing entry and if found, use that instead of adding 1034 * a new one */ 1035 peerkey = os_zalloc(sizeof(*peerkey)); 1036 if (peerkey == NULL) 1037 return -1; 1038 peerkey->initiator = 1; 1039 os_memcpy(peerkey->addr, peer, ETH_ALEN); 1040 #ifdef CONFIG_IEEE80211W 1041 if (wpa_key_mgmt_sha256(sm->key_mgmt)) 1042 peerkey->use_sha256 = 1; 1043 #endif /* CONFIG_IEEE80211W */ 1044 1045 /* SMK M1: 1046 * EAPOL-Key(S=1, M=1, A=0, I=0, K=0, SM=1, KeyRSC=0, Nonce=INonce, 1047 * MIC=MIC, DataKDs=(RSNIE_I, MAC_P KDE)) 1048 */ 1049 1050 hdr = (struct rsn_ie_hdr *) peerkey->rsnie_i; 1051 hdr->elem_id = WLAN_EID_RSN; 1052 WPA_PUT_LE16(hdr->version, RSN_VERSION); 1053 pos = (u8 *) (hdr + 1); 1054 /* Group Suite can be anything for SMK RSN IE; receiver will just 1055 * ignore it. */ 1056 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); 1057 pos += RSN_SELECTOR_LEN; 1058 count_pos = pos; 1059 pos += 2; 1060 1061 count = 0; 1062 if (sm->allowed_pairwise_cipher & WPA_CIPHER_CCMP) { 1063 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); 1064 pos += RSN_SELECTOR_LEN; 1065 count++; 1066 } 1067 if (sm->allowed_pairwise_cipher & WPA_CIPHER_TKIP) { 1068 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP); 1069 pos += RSN_SELECTOR_LEN; 1070 count++; 1071 } 1072 WPA_PUT_LE16(count_pos, count); 1073 1074 hdr->len = (pos - peerkey->rsnie_i) - 2; 1075 peerkey->rsnie_i_len = pos - peerkey->rsnie_i; 1076 wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake", 1077 peerkey->rsnie_i, peerkey->rsnie_i_len); 1078 1079 kde_len = peerkey->rsnie_i_len + 2 + RSN_SELECTOR_LEN + ETH_ALEN; 1080 1081 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL, 1082 sizeof(*req) + kde_len, &rlen, 1083 (void *) &req); 1084 if (rbuf == NULL) { 1085 wpa_supplicant_peerkey_free(sm, peerkey); 1086 return -1; 1087 } 1088 1089 req->type = EAPOL_KEY_TYPE_RSN; 1090 key_info = WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC | 1091 WPA_KEY_INFO_SECURE | WPA_KEY_INFO_REQUEST | ver; 1092 WPA_PUT_BE16(req->key_info, key_info); 1093 WPA_PUT_BE16(req->key_length, 0); 1094 os_memcpy(req->replay_counter, sm->request_counter, 1095 WPA_REPLAY_COUNTER_LEN); 1096 inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN); 1097 1098 if (os_get_random(peerkey->inonce, WPA_NONCE_LEN)) { 1099 wpa_msg(sm->ctx->ctx, MSG_WARNING, 1100 "WPA: Failed to get random data for INonce"); 1101 os_free(rbuf); 1102 wpa_supplicant_peerkey_free(sm, peerkey); 1103 return -1; 1104 } 1105 os_memcpy(req->key_nonce, peerkey->inonce, WPA_NONCE_LEN); 1106 wpa_hexdump(MSG_DEBUG, "WPA: INonce for SMK handshake", 1107 req->key_nonce, WPA_NONCE_LEN); 1108 1109 WPA_PUT_BE16(req->key_data_length, (u16) kde_len); 1110 pos = (u8 *) (req + 1); 1111 1112 /* Initiator RSN IE */ 1113 pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len); 1114 /* Peer MAC address KDE */ 1115 wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN); 1116 1117 wpa_printf(MSG_INFO, "RSN: Sending EAPOL-Key SMK M1 Request (peer " 1118 MACSTR ")", MAC2STR(peer)); 1119 wpa_eapol_key_send(sm, sm->ptk.kck, ver, bssid, ETH_P_EAPOL, 1120 rbuf, rlen, req->key_mic); 1121 1122 peerkey->next = sm->peerkey; 1123 sm->peerkey = peerkey; 1124 1125 return 0; 1126 } 1127 1128 1129 /** 1130 * peerkey_deinit - Free PeerKey values 1131 * @sm: Pointer to WPA state machine data from wpa_sm_init() 1132 */ 1133 void peerkey_deinit(struct wpa_sm *sm) 1134 { 1135 struct wpa_peerkey *prev, *peerkey = sm->peerkey; 1136 while (peerkey) { 1137 prev = peerkey; 1138 peerkey = peerkey->next; 1139 os_free(prev); 1140 } 1141 } 1142 1143 1144 void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey, 1145 struct wpa_eapol_key *key, u16 key_info, u16 ver) 1146 { 1147 if ((key_info & (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) == 1148 (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) { 1149 /* 3/4 STK 4-Way Handshake */ 1150 wpa_supplicant_process_stk_3_of_4(sm, peerkey, key, ver); 1151 } else if (key_info & WPA_KEY_INFO_ACK) { 1152 /* 1/4 STK 4-Way Handshake */ 1153 wpa_supplicant_process_stk_1_of_4(sm, peerkey, key, ver); 1154 } else if (key_info & WPA_KEY_INFO_SECURE) { 1155 /* 4/4 STK 4-Way Handshake */ 1156 wpa_supplicant_process_stk_4_of_4(sm, peerkey, key, ver); 1157 } else { 1158 /* 2/4 STK 4-Way Handshake */ 1159 wpa_supplicant_process_stk_2_of_4(sm, peerkey, key, ver); 1160 } 1161 } 1162 1163 1164 void peerkey_rx_eapol_smk(struct wpa_sm *sm, const u8 *src_addr, 1165 struct wpa_eapol_key *key, size_t extra_len, 1166 u16 key_info, u16 ver) 1167 { 1168 if (key_info & WPA_KEY_INFO_ERROR) { 1169 /* SMK Error */ 1170 wpa_supplicant_process_smk_error(sm, src_addr, key, extra_len); 1171 } else if (key_info & WPA_KEY_INFO_ACK) { 1172 /* SMK M2 */ 1173 wpa_supplicant_process_smk_m2(sm, src_addr, key, extra_len, 1174 ver); 1175 } else { 1176 /* SMK M4 or M5 */ 1177 wpa_supplicant_process_smk_m45(sm, src_addr, key, extra_len, 1178 ver); 1179 } 1180 } 1181 1182 #endif /* CONFIG_PEERKEY */ 1183