1/* 2 * WPA Supplicant - PeerKey for Direct Link Setup (DLS) 3 * Copyright (c) 2006-2008, Jouni Malinen <j@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 "common/ieee802_11_defs.h" 24#include "wpa.h" 25#include "wpa_i.h" 26#include "wpa_ie.h" 27#include "peerkey.h" 28 29 30static 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 37static 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 49static 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 59static 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 67static 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 127static 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 179static 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->msg_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 */ 307static 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 333static 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->msg_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 390static 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 445static 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 468static 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 525static 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 607static 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 else 638 os_memset(peer, 0, ETH_ALEN); 639 os_memcpy(&error, kde.error, sizeof(error)); 640 error_type = be_to_host16(error.error_type); 641 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 642 "RSN: SMK Error KDE received: MUI %d error_type %d peer " 643 MACSTR, 644 be_to_host16(error.mui), error_type, 645 MAC2STR(peer)); 646 647 if (kde.mac_addr && 648 (error_type == STK_ERR_STA_NR || error_type == STK_ERR_STA_NRSN || 649 error_type == STK_ERR_CPHR_NS)) { 650 struct wpa_peerkey *peerkey; 651 652 for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) { 653 if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) == 654 0) 655 break; 656 } 657 if (peerkey == NULL) { 658 wpa_printf(MSG_DEBUG, "RSN: No matching SMK handshake " 659 "found for SMK Error"); 660 return -1; 661 } 662 /* TODO: abort SMK/STK handshake and remove all related keys */ 663 } 664 665 return 0; 666} 667 668 669static void wpa_supplicant_process_stk_1_of_4(struct wpa_sm *sm, 670 struct wpa_peerkey *peerkey, 671 const struct wpa_eapol_key *key, 672 u16 ver) 673{ 674 struct wpa_eapol_ie_parse ie; 675 const u8 *kde; 676 size_t len, kde_buf_len; 677 struct wpa_ptk *stk; 678 u8 buf[8], *kde_buf, *pos; 679 be32 lifetime; 680 681 wpa_printf(MSG_DEBUG, "RSN: RX message 1 of STK 4-Way Handshake from " 682 MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver); 683 684 os_memset(&ie, 0, sizeof(ie)); 685 686 /* RSN: msg 1/4 should contain SMKID for the selected SMK */ 687 kde = (const u8 *) (key + 1); 688 len = WPA_GET_BE16(key->key_data_length); 689 wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", kde, len); 690 if (wpa_supplicant_parse_ies(kde, len, &ie) < 0 || ie.pmkid == NULL) { 691 wpa_printf(MSG_DEBUG, "RSN: No SMKID in STK 1/4"); 692 return; 693 } 694 if (os_memcmp(ie.pmkid, peerkey->smkid, PMKID_LEN) != 0) { 695 wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 1/4", 696 ie.pmkid, PMKID_LEN); 697 return; 698 } 699 700 if (os_get_random(peerkey->pnonce, WPA_NONCE_LEN)) { 701 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 702 "RSN: Failed to get random data for PNonce"); 703 return; 704 } 705 wpa_hexdump(MSG_DEBUG, "WPA: Renewed PNonce", 706 peerkey->pnonce, WPA_NONCE_LEN); 707 708 /* Calculate STK which will be stored as a temporary STK until it has 709 * been verified when processing message 3/4. */ 710 stk = &peerkey->tstk; 711 wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion", 712 sm->own_addr, peerkey->addr, 713 peerkey->pnonce, key->key_nonce, 714 (u8 *) stk, sizeof(*stk), 715 peerkey->use_sha256); 716 /* Supplicant: swap tx/rx Mic keys */ 717 os_memcpy(buf, stk->u.auth.tx_mic_key, 8); 718 os_memcpy(stk->u.auth.tx_mic_key, stk->u.auth.rx_mic_key, 8); 719 os_memcpy(stk->u.auth.rx_mic_key, buf, 8); 720 peerkey->tstk_set = 1; 721 722 kde_buf_len = peerkey->rsnie_p_len + 723 2 + RSN_SELECTOR_LEN + sizeof(lifetime) + 724 2 + RSN_SELECTOR_LEN + PMKID_LEN; 725 kde_buf = os_malloc(kde_buf_len); 726 if (kde_buf == NULL) 727 return; 728 pos = kde_buf; 729 pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len); 730 lifetime = host_to_be32(peerkey->lifetime); 731 pos = wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME, 732 (u8 *) &lifetime, sizeof(lifetime)); 733 wpa_add_kde(pos, RSN_KEY_DATA_PMKID, peerkey->smkid, PMKID_LEN); 734 735 if (wpa_supplicant_send_2_of_4(sm, peerkey->addr, key, ver, 736 peerkey->pnonce, kde_buf, kde_buf_len, 737 stk)) { 738 os_free(kde_buf); 739 return; 740 } 741 os_free(kde_buf); 742 743 os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN); 744} 745 746 747static void wpa_supplicant_update_smk_lifetime(struct wpa_sm *sm, 748 struct wpa_peerkey *peerkey, 749 struct wpa_eapol_ie_parse *kde) 750{ 751 u32 lifetime; 752 struct os_time now; 753 754 if (kde->lifetime == NULL || kde->lifetime_len < sizeof(lifetime)) 755 return; 756 757 lifetime = WPA_GET_BE32(kde->lifetime); 758 759 if (lifetime >= peerkey->lifetime) { 760 wpa_printf(MSG_DEBUG, "RSN: Peer used SMK lifetime %u seconds " 761 "which is larger than or equal to own value %u " 762 "seconds - ignored", lifetime, peerkey->lifetime); 763 return; 764 } 765 766 wpa_printf(MSG_DEBUG, "RSN: Peer used shorter SMK lifetime %u seconds " 767 "(own was %u seconds) - updated", 768 lifetime, peerkey->lifetime); 769 peerkey->lifetime = lifetime; 770 771 os_get_time(&now); 772 peerkey->expiration = now.sec + lifetime; 773 eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey); 774 eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout, 775 sm, peerkey); 776} 777 778 779static void wpa_supplicant_process_stk_2_of_4(struct wpa_sm *sm, 780 struct wpa_peerkey *peerkey, 781 const struct wpa_eapol_key *key, 782 u16 ver) 783{ 784 struct wpa_eapol_ie_parse kde; 785 const u8 *keydata; 786 size_t len; 787 788 wpa_printf(MSG_DEBUG, "RSN: RX message 2 of STK 4-Way Handshake from " 789 MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver); 790 791 os_memset(&kde, 0, sizeof(kde)); 792 793 /* RSN: msg 2/4 should contain SMKID for the selected SMK and RSN IE 794 * from the peer. It may also include Lifetime KDE. */ 795 keydata = (const u8 *) (key + 1); 796 len = WPA_GET_BE16(key->key_data_length); 797 wpa_hexdump(MSG_DEBUG, "RSN: msg 2/4 key data", keydata, len); 798 if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0 || 799 kde.pmkid == NULL || kde.rsn_ie == NULL) { 800 wpa_printf(MSG_DEBUG, "RSN: No SMKID or RSN IE in STK 2/4"); 801 return; 802 } 803 804 if (os_memcmp(kde.pmkid, peerkey->smkid, PMKID_LEN) != 0) { 805 wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 2/4", 806 kde.pmkid, PMKID_LEN); 807 return; 808 } 809 810 if (kde.rsn_ie_len != peerkey->rsnie_p_len || 811 os_memcmp(kde.rsn_ie, peerkey->rsnie_p, kde.rsn_ie_len) != 0) { 812 wpa_printf(MSG_INFO, "RSN: Peer RSN IE in SMK and STK " 813 "handshakes did not match"); 814 wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in SMK handshake", 815 peerkey->rsnie_p, peerkey->rsnie_p_len); 816 wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in STK handshake", 817 kde.rsn_ie, kde.rsn_ie_len); 818 return; 819 } 820 821 wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde); 822 823 wpa_supplicant_send_stk_3_of_4(sm, peerkey); 824 os_memcpy(peerkey->pnonce, key->key_nonce, WPA_NONCE_LEN); 825} 826 827 828static void wpa_supplicant_process_stk_3_of_4(struct wpa_sm *sm, 829 struct wpa_peerkey *peerkey, 830 const struct wpa_eapol_key *key, 831 u16 ver) 832{ 833 struct wpa_eapol_ie_parse kde; 834 const u8 *keydata; 835 size_t len, key_len; 836 const u8 *_key; 837 u8 key_buf[32], rsc[6]; 838 839 wpa_printf(MSG_DEBUG, "RSN: RX message 3 of STK 4-Way Handshake from " 840 MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver); 841 842 os_memset(&kde, 0, sizeof(kde)); 843 844 /* RSN: msg 3/4 should contain Initiator RSN IE. It may also include 845 * Lifetime KDE. */ 846 keydata = (const u8 *) (key + 1); 847 len = WPA_GET_BE16(key->key_data_length); 848 wpa_hexdump(MSG_DEBUG, "RSN: msg 3/4 key data", keydata, len); 849 if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0) { 850 wpa_printf(MSG_DEBUG, "RSN: Failed to parse key data in " 851 "STK 3/4"); 852 return; 853 } 854 855 if (kde.rsn_ie_len != peerkey->rsnie_i_len || 856 os_memcmp(kde.rsn_ie, peerkey->rsnie_i, kde.rsn_ie_len) != 0) { 857 wpa_printf(MSG_INFO, "RSN: Initiator RSN IE in SMK and STK " 858 "handshakes did not match"); 859 wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in SMK " 860 "handshake", 861 peerkey->rsnie_i, peerkey->rsnie_i_len); 862 wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in STK " 863 "handshake", 864 kde.rsn_ie, kde.rsn_ie_len); 865 return; 866 } 867 868 if (os_memcmp(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN) != 0) { 869 wpa_printf(MSG_WARNING, "RSN: INonce from message 1 of STK " 870 "4-Way Handshake differs from 3 of STK 4-Way " 871 "Handshake - drop packet (src=" MACSTR ")", 872 MAC2STR(peerkey->addr)); 873 return; 874 } 875 876 wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde); 877 878 if (wpa_supplicant_send_4_of_4(sm, peerkey->addr, key, ver, 879 WPA_GET_BE16(key->key_info), 880 NULL, 0, &peerkey->stk)) 881 return; 882 883 _key = (u8 *) peerkey->stk.tk1; 884 if (peerkey->cipher == WPA_CIPHER_TKIP) { 885 /* Swap Tx/Rx keys for Michael MIC */ 886 os_memcpy(key_buf, _key, 16); 887 os_memcpy(key_buf + 16, peerkey->stk.u.auth.rx_mic_key, 8); 888 os_memcpy(key_buf + 24, peerkey->stk.u.auth.tx_mic_key, 8); 889 _key = key_buf; 890 key_len = 32; 891 } else 892 key_len = 16; 893 894 os_memset(rsc, 0, 6); 895 if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1, 896 rsc, sizeof(rsc), _key, key_len) < 0) { 897 wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the " 898 "driver."); 899 return; 900 } 901} 902 903 904static void wpa_supplicant_process_stk_4_of_4(struct wpa_sm *sm, 905 struct wpa_peerkey *peerkey, 906 const struct wpa_eapol_key *key, 907 u16 ver) 908{ 909 u8 rsc[6]; 910 911 wpa_printf(MSG_DEBUG, "RSN: RX message 4 of STK 4-Way Handshake from " 912 MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver); 913 914 os_memset(rsc, 0, 6); 915 if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1, 916 rsc, sizeof(rsc), (u8 *) peerkey->stk.tk1, 917 peerkey->cipher == WPA_CIPHER_TKIP ? 32 : 16) < 0) { 918 wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the " 919 "driver."); 920 return; 921 } 922} 923 924 925/** 926 * peerkey_verify_eapol_key_mic - Verify PeerKey MIC 927 * @sm: Pointer to WPA state machine data from wpa_sm_init() 928 * @peerkey: Pointer to the PeerKey data for the peer 929 * @key: Pointer to the EAPOL-Key frame header 930 * @ver: Version bits from EAPOL-Key Key Info 931 * @buf: Pointer to the beginning of EAPOL-Key frame 932 * @len: Length of the EAPOL-Key frame 933 * Returns: 0 on success, -1 on failure 934 */ 935int peerkey_verify_eapol_key_mic(struct wpa_sm *sm, 936 struct wpa_peerkey *peerkey, 937 struct wpa_eapol_key *key, u16 ver, 938 const u8 *buf, size_t len) 939{ 940 u8 mic[16]; 941 int ok = 0; 942 943 if (peerkey->initiator && !peerkey->stk_set) { 944 wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion", 945 sm->own_addr, peerkey->addr, 946 peerkey->inonce, key->key_nonce, 947 (u8 *) &peerkey->stk, sizeof(peerkey->stk), 948 peerkey->use_sha256); 949 peerkey->stk_set = 1; 950 } 951 952 os_memcpy(mic, key->key_mic, 16); 953 if (peerkey->tstk_set) { 954 os_memset(key->key_mic, 0, 16); 955 wpa_eapol_key_mic(peerkey->tstk.kck, ver, buf, len, 956 key->key_mic); 957 if (os_memcmp(mic, key->key_mic, 16) != 0) { 958 wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC " 959 "when using TSTK - ignoring TSTK"); 960 } else { 961 ok = 1; 962 peerkey->tstk_set = 0; 963 peerkey->stk_set = 1; 964 os_memcpy(&peerkey->stk, &peerkey->tstk, 965 sizeof(peerkey->stk)); 966 } 967 } 968 969 if (!ok && peerkey->stk_set) { 970 os_memset(key->key_mic, 0, 16); 971 wpa_eapol_key_mic(peerkey->stk.kck, ver, buf, len, 972 key->key_mic); 973 if (os_memcmp(mic, key->key_mic, 16) != 0) { 974 wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC " 975 "- dropping packet"); 976 return -1; 977 } 978 ok = 1; 979 } 980 981 if (!ok) { 982 wpa_printf(MSG_WARNING, "RSN: Could not verify EAPOL-Key MIC " 983 "- dropping packet"); 984 return -1; 985 } 986 987 os_memcpy(peerkey->replay_counter, key->replay_counter, 988 WPA_REPLAY_COUNTER_LEN); 989 peerkey->replay_counter_set = 1; 990 return 0; 991} 992 993 994/** 995 * wpa_sm_stkstart - Send EAPOL-Key Request for STK handshake (STK M1) 996 * @sm: Pointer to WPA state machine data from wpa_sm_init() 997 * @peer: MAC address of the peer STA 998 * Returns: 0 on success, or -1 on failure 999 * 1000 * Send an EAPOL-Key Request to the current authenticator to start STK 1001 * handshake with the peer. 1002 */ 1003int wpa_sm_stkstart(struct wpa_sm *sm, const u8 *peer) 1004{ 1005 size_t rlen, kde_len; 1006 struct wpa_eapol_key *req; 1007 int key_info, ver; 1008 u8 bssid[ETH_ALEN], *rbuf, *pos, *count_pos; 1009 u16 count; 1010 struct rsn_ie_hdr *hdr; 1011 struct wpa_peerkey *peerkey; 1012 struct wpa_ie_data ie; 1013 1014 if (sm->proto != WPA_PROTO_RSN || !sm->ptk_set || !sm->peerkey_enabled) 1015 return -1; 1016 1017 if (sm->ap_rsn_ie && 1018 wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &ie) == 0 && 1019 !(ie.capabilities & WPA_CAPABILITY_PEERKEY_ENABLED)) { 1020 wpa_printf(MSG_DEBUG, "RSN: Current AP does not support STK"); 1021 return -1; 1022 } 1023 1024 if (sm->pairwise_cipher == WPA_CIPHER_CCMP) 1025 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES; 1026 else 1027 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4; 1028 1029 if (wpa_sm_get_bssid(sm, bssid) < 0) { 1030 wpa_printf(MSG_WARNING, "Failed to read BSSID for EAPOL-Key " 1031 "SMK M1"); 1032 return -1; 1033 } 1034 1035 /* TODO: find existing entry and if found, use that instead of adding 1036 * a new one */ 1037 peerkey = os_zalloc(sizeof(*peerkey)); 1038 if (peerkey == NULL) 1039 return -1; 1040 peerkey->initiator = 1; 1041 os_memcpy(peerkey->addr, peer, ETH_ALEN); 1042#ifdef CONFIG_IEEE80211W 1043 if (wpa_key_mgmt_sha256(sm->key_mgmt)) 1044 peerkey->use_sha256 = 1; 1045#endif /* CONFIG_IEEE80211W */ 1046 1047 /* SMK M1: 1048 * EAPOL-Key(S=1, M=1, A=0, I=0, K=0, SM=1, KeyRSC=0, Nonce=INonce, 1049 * MIC=MIC, DataKDs=(RSNIE_I, MAC_P KDE)) 1050 */ 1051 1052 hdr = (struct rsn_ie_hdr *) peerkey->rsnie_i; 1053 hdr->elem_id = WLAN_EID_RSN; 1054 WPA_PUT_LE16(hdr->version, RSN_VERSION); 1055 pos = (u8 *) (hdr + 1); 1056 /* Group Suite can be anything for SMK RSN IE; receiver will just 1057 * ignore it. */ 1058 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); 1059 pos += RSN_SELECTOR_LEN; 1060 count_pos = pos; 1061 pos += 2; 1062 1063 count = 0; 1064 if (sm->allowed_pairwise_cipher & WPA_CIPHER_CCMP) { 1065 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); 1066 pos += RSN_SELECTOR_LEN; 1067 count++; 1068 } 1069 if (sm->allowed_pairwise_cipher & WPA_CIPHER_TKIP) { 1070 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP); 1071 pos += RSN_SELECTOR_LEN; 1072 count++; 1073 } 1074 WPA_PUT_LE16(count_pos, count); 1075 1076 hdr->len = (pos - peerkey->rsnie_i) - 2; 1077 peerkey->rsnie_i_len = pos - peerkey->rsnie_i; 1078 wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake", 1079 peerkey->rsnie_i, peerkey->rsnie_i_len); 1080 1081 kde_len = peerkey->rsnie_i_len + 2 + RSN_SELECTOR_LEN + ETH_ALEN; 1082 1083 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL, 1084 sizeof(*req) + kde_len, &rlen, 1085 (void *) &req); 1086 if (rbuf == NULL) { 1087 wpa_supplicant_peerkey_free(sm, peerkey); 1088 return -1; 1089 } 1090 1091 req->type = EAPOL_KEY_TYPE_RSN; 1092 key_info = WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC | 1093 WPA_KEY_INFO_SECURE | WPA_KEY_INFO_REQUEST | ver; 1094 WPA_PUT_BE16(req->key_info, key_info); 1095 WPA_PUT_BE16(req->key_length, 0); 1096 os_memcpy(req->replay_counter, sm->request_counter, 1097 WPA_REPLAY_COUNTER_LEN); 1098 inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN); 1099 1100 if (os_get_random(peerkey->inonce, WPA_NONCE_LEN)) { 1101 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 1102 "WPA: Failed to get random data for INonce"); 1103 os_free(rbuf); 1104 wpa_supplicant_peerkey_free(sm, peerkey); 1105 return -1; 1106 } 1107 os_memcpy(req->key_nonce, peerkey->inonce, WPA_NONCE_LEN); 1108 wpa_hexdump(MSG_DEBUG, "WPA: INonce for SMK handshake", 1109 req->key_nonce, WPA_NONCE_LEN); 1110 1111 WPA_PUT_BE16(req->key_data_length, (u16) kde_len); 1112 pos = (u8 *) (req + 1); 1113 1114 /* Initiator RSN IE */ 1115 pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len); 1116 /* Peer MAC address KDE */ 1117 wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN); 1118 1119 wpa_printf(MSG_INFO, "RSN: Sending EAPOL-Key SMK M1 Request (peer " 1120 MACSTR ")", MAC2STR(peer)); 1121 wpa_eapol_key_send(sm, sm->ptk.kck, ver, bssid, ETH_P_EAPOL, 1122 rbuf, rlen, req->key_mic); 1123 1124 peerkey->next = sm->peerkey; 1125 sm->peerkey = peerkey; 1126 1127 return 0; 1128} 1129 1130 1131/** 1132 * peerkey_deinit - Free PeerKey values 1133 * @sm: Pointer to WPA state machine data from wpa_sm_init() 1134 */ 1135void peerkey_deinit(struct wpa_sm *sm) 1136{ 1137 struct wpa_peerkey *prev, *peerkey = sm->peerkey; 1138 while (peerkey) { 1139 prev = peerkey; 1140 peerkey = peerkey->next; 1141 os_free(prev); 1142 } 1143} 1144 1145 1146void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey, 1147 struct wpa_eapol_key *key, u16 key_info, u16 ver) 1148{ 1149 if ((key_info & (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) == 1150 (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) { 1151 /* 3/4 STK 4-Way Handshake */ 1152 wpa_supplicant_process_stk_3_of_4(sm, peerkey, key, ver); 1153 } else if (key_info & WPA_KEY_INFO_ACK) { 1154 /* 1/4 STK 4-Way Handshake */ 1155 wpa_supplicant_process_stk_1_of_4(sm, peerkey, key, ver); 1156 } else if (key_info & WPA_KEY_INFO_SECURE) { 1157 /* 4/4 STK 4-Way Handshake */ 1158 wpa_supplicant_process_stk_4_of_4(sm, peerkey, key, ver); 1159 } else { 1160 /* 2/4 STK 4-Way Handshake */ 1161 wpa_supplicant_process_stk_2_of_4(sm, peerkey, key, ver); 1162 } 1163} 1164 1165 1166void peerkey_rx_eapol_smk(struct wpa_sm *sm, const u8 *src_addr, 1167 struct wpa_eapol_key *key, size_t extra_len, 1168 u16 key_info, u16 ver) 1169{ 1170 if (key_info & WPA_KEY_INFO_ERROR) { 1171 /* SMK Error */ 1172 wpa_supplicant_process_smk_error(sm, src_addr, key, extra_len); 1173 } else if (key_info & WPA_KEY_INFO_ACK) { 1174 /* SMK M2 */ 1175 wpa_supplicant_process_smk_m2(sm, src_addr, key, extra_len, 1176 ver); 1177 } else { 1178 /* SMK M4 or M5 */ 1179 wpa_supplicant_process_smk_m45(sm, src_addr, key, extra_len, 1180 ver); 1181 } 1182} 1183 1184#endif /* CONFIG_PEERKEY */ 1185