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