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