peerkey.c revision 61d9df3e62aaa0e87ad05452fcb95142159a17b6
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 = ie.pairwise_cipher & sm->allowed_pairwise_cipher; 221 if (cipher & WPA_CIPHER_CCMP) { 222 wpa_printf(MSG_DEBUG, "RSN: Using CCMP for PeerKey"); 223 cipher = WPA_CIPHER_CCMP; 224 } else if (cipher & WPA_CIPHER_GCMP) { 225 wpa_printf(MSG_DEBUG, "RSN: Using GCMP for PeerKey"); 226 cipher = WPA_CIPHER_GCMP; 227 } else if (cipher & WPA_CIPHER_TKIP) { 228 wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey"); 229 cipher = WPA_CIPHER_TKIP; 230 } else { 231 wpa_printf(MSG_INFO, "RSN: No acceptable cipher in SMK M2"); 232 wpa_supplicant_send_smk_error(sm, src_addr, kde.mac_addr, 233 STK_MUI_SMK, STK_ERR_CPHR_NS, 234 ver); 235 return -1; 236 } 237 238 /* TODO: find existing entry and if found, use that instead of adding 239 * a new one; how to handle the case where both ends initiate at the 240 * same time? */ 241 peerkey = os_zalloc(sizeof(*peerkey)); 242 if (peerkey == NULL) 243 return -1; 244 os_memcpy(peerkey->addr, kde.mac_addr, ETH_ALEN); 245 os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN); 246 os_memcpy(peerkey->rsnie_i, kde.rsn_ie, kde.rsn_ie_len); 247 peerkey->rsnie_i_len = kde.rsn_ie_len; 248 peerkey->cipher = cipher; 249#ifdef CONFIG_IEEE80211W 250 if (ie.key_mgmt & (WPA_KEY_MGMT_IEEE8021X_SHA256 | 251 WPA_KEY_MGMT_PSK_SHA256)) 252 peerkey->use_sha256 = 1; 253#endif /* CONFIG_IEEE80211W */ 254 255 if (random_get_bytes(peerkey->pnonce, WPA_NONCE_LEN)) { 256 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 257 "WPA: Failed to get random data for PNonce"); 258 wpa_supplicant_peerkey_free(sm, peerkey); 259 return -1; 260 } 261 262 hdr = (struct rsn_ie_hdr *) peerkey->rsnie_p; 263 hdr->elem_id = WLAN_EID_RSN; 264 WPA_PUT_LE16(hdr->version, RSN_VERSION); 265 pos = (u8 *) (hdr + 1); 266 /* Group Suite can be anything for SMK RSN IE; receiver will just 267 * ignore it. */ 268 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); 269 pos += RSN_SELECTOR_LEN; 270 /* Include only the selected cipher in pairwise cipher suite */ 271 WPA_PUT_LE16(pos, 1); 272 pos += 2; 273 if (cipher == WPA_CIPHER_CCMP) 274 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); 275 else if (cipher == WPA_CIPHER_GCMP) 276 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP); 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_TKIP) 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_TKIP) 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 (random_get_bytes(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_TKIP) 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_TKIP) 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_GCMP) { 509 wpa_printf(MSG_DEBUG, "RSN: Using GCMP for PeerKey"); 510 peerkey->cipher = WPA_CIPHER_GCMP; 511 } else if (cipher & WPA_CIPHER_TKIP) { 512 wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey"); 513 peerkey->cipher = WPA_CIPHER_TKIP; 514 } else { 515 wpa_printf(MSG_INFO, "RSN: SMK Peer STA " MACSTR " selected " 516 "unacceptable cipher", MAC2STR(kde->mac_addr)); 517 wpa_supplicant_send_smk_error(sm, src_addr, kde->mac_addr, 518 STK_MUI_SMK, STK_ERR_CPHR_NS, 519 ver); 520 /* TODO: abort negotiation */ 521 return -1; 522 } 523 524 return 0; 525} 526 527 528static int wpa_supplicant_process_smk_m45( 529 struct wpa_sm *sm, const unsigned char *src_addr, 530 const struct wpa_eapol_key *key, size_t extra_len, int ver) 531{ 532 struct wpa_peerkey *peerkey; 533 struct wpa_eapol_ie_parse kde; 534 u32 lifetime; 535 struct os_time now; 536 537 if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) { 538 wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for " 539 "the current network"); 540 return -1; 541 } 542 543 if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) < 544 0) { 545 wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M4/M5"); 546 return -1; 547 } 548 549 if (kde.mac_addr == NULL || kde.mac_addr_len < ETH_ALEN || 550 kde.nonce == NULL || kde.nonce_len < WPA_NONCE_LEN || 551 kde.smk == NULL || kde.smk_len < PMK_LEN + WPA_NONCE_LEN || 552 kde.lifetime == NULL || kde.lifetime_len < 4) { 553 wpa_printf(MSG_INFO, "RSN: No MAC Address, Nonce, SMK, or " 554 "Lifetime KDE in SMK M4/M5"); 555 return -1; 556 } 557 558 for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) { 559 if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) == 0 && 560 os_memcmp(peerkey->initiator ? peerkey->inonce : 561 peerkey->pnonce, 562 key->key_nonce, WPA_NONCE_LEN) == 0) 563 break; 564 } 565 if (peerkey == NULL) { 566 wpa_printf(MSG_INFO, "RSN: No matching SMK handshake found " 567 "for SMK M4/M5: peer " MACSTR, 568 MAC2STR(kde.mac_addr)); 569 return -1; 570 } 571 572 if (peerkey->initiator) { 573 if (wpa_supplicant_process_smk_m5(sm, src_addr, key, ver, 574 peerkey, &kde) < 0) 575 return -1; 576 } else { 577 if (wpa_supplicant_process_smk_m4(peerkey, &kde) < 0) 578 return -1; 579 } 580 581 os_memcpy(peerkey->smk, kde.smk, PMK_LEN); 582 peerkey->smk_complete = 1; 583 wpa_hexdump_key(MSG_DEBUG, "RSN: SMK", peerkey->smk, PMK_LEN); 584 lifetime = WPA_GET_BE32(kde.lifetime); 585 wpa_printf(MSG_DEBUG, "RSN: SMK lifetime %u seconds", lifetime); 586 if (lifetime > 1000000000) 587 lifetime = 1000000000; /* avoid overflowing expiration time */ 588 peerkey->lifetime = lifetime; 589 os_get_time(&now); 590 peerkey->expiration = now.sec + lifetime; 591 eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout, 592 sm, peerkey); 593 594 if (peerkey->initiator) { 595 rsn_smkid(peerkey->smk, peerkey->pnonce, peerkey->addr, 596 peerkey->inonce, sm->own_addr, peerkey->smkid, 597 peerkey->use_sha256); 598 wpa_supplicant_send_stk_1_of_4(sm, peerkey); 599 } else { 600 rsn_smkid(peerkey->smk, peerkey->pnonce, sm->own_addr, 601 peerkey->inonce, peerkey->addr, peerkey->smkid, 602 peerkey->use_sha256); 603 } 604 wpa_hexdump(MSG_DEBUG, "RSN: SMKID", peerkey->smkid, PMKID_LEN); 605 606 return 0; 607} 608 609 610static int wpa_supplicant_process_smk_error( 611 struct wpa_sm *sm, const unsigned char *src_addr, 612 const struct wpa_eapol_key *key, size_t extra_len) 613{ 614 struct wpa_eapol_ie_parse kde; 615 struct rsn_error_kde error; 616 u8 peer[ETH_ALEN]; 617 u16 error_type; 618 619 wpa_printf(MSG_DEBUG, "RSN: Received SMK Error"); 620 621 if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) { 622 wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for " 623 "the current network"); 624 return -1; 625 } 626 627 if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) < 628 0) { 629 wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK Error"); 630 return -1; 631 } 632 633 if (kde.error == NULL || kde.error_len < sizeof(error)) { 634 wpa_printf(MSG_INFO, "RSN: No Error KDE in SMK Error"); 635 return -1; 636 } 637 638 if (kde.mac_addr && kde.mac_addr_len >= ETH_ALEN) 639 os_memcpy(peer, kde.mac_addr, ETH_ALEN); 640 else 641 os_memset(peer, 0, ETH_ALEN); 642 os_memcpy(&error, kde.error, sizeof(error)); 643 error_type = be_to_host16(error.error_type); 644 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 645 "RSN: SMK Error KDE received: MUI %d error_type %d peer " 646 MACSTR, 647 be_to_host16(error.mui), error_type, 648 MAC2STR(peer)); 649 650 if (kde.mac_addr && 651 (error_type == STK_ERR_STA_NR || error_type == STK_ERR_STA_NRSN || 652 error_type == STK_ERR_CPHR_NS)) { 653 struct wpa_peerkey *peerkey; 654 655 for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) { 656 if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) == 657 0) 658 break; 659 } 660 if (peerkey == NULL) { 661 wpa_printf(MSG_DEBUG, "RSN: No matching SMK handshake " 662 "found for SMK Error"); 663 return -1; 664 } 665 /* TODO: abort SMK/STK handshake and remove all related keys */ 666 } 667 668 return 0; 669} 670 671 672static void wpa_supplicant_process_stk_1_of_4(struct wpa_sm *sm, 673 struct wpa_peerkey *peerkey, 674 const struct wpa_eapol_key *key, 675 u16 ver) 676{ 677 struct wpa_eapol_ie_parse ie; 678 const u8 *kde; 679 size_t len, kde_buf_len; 680 struct wpa_ptk *stk; 681 u8 buf[8], *kde_buf, *pos; 682 be32 lifetime; 683 684 wpa_printf(MSG_DEBUG, "RSN: RX message 1 of STK 4-Way Handshake from " 685 MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver); 686 687 os_memset(&ie, 0, sizeof(ie)); 688 689 /* RSN: msg 1/4 should contain SMKID for the selected SMK */ 690 kde = (const u8 *) (key + 1); 691 len = WPA_GET_BE16(key->key_data_length); 692 wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", kde, len); 693 if (wpa_supplicant_parse_ies(kde, len, &ie) < 0 || ie.pmkid == NULL) { 694 wpa_printf(MSG_DEBUG, "RSN: No SMKID in STK 1/4"); 695 return; 696 } 697 if (os_memcmp(ie.pmkid, peerkey->smkid, PMKID_LEN) != 0) { 698 wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 1/4", 699 ie.pmkid, PMKID_LEN); 700 return; 701 } 702 703 if (random_get_bytes(peerkey->pnonce, WPA_NONCE_LEN)) { 704 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 705 "RSN: Failed to get random data for PNonce"); 706 return; 707 } 708 wpa_hexdump(MSG_DEBUG, "WPA: Renewed PNonce", 709 peerkey->pnonce, WPA_NONCE_LEN); 710 711 /* Calculate STK which will be stored as a temporary STK until it has 712 * been verified when processing message 3/4. */ 713 stk = &peerkey->tstk; 714 wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion", 715 sm->own_addr, peerkey->addr, 716 peerkey->pnonce, key->key_nonce, 717 (u8 *) stk, sizeof(*stk), 718 peerkey->use_sha256); 719 /* Supplicant: swap tx/rx Mic keys */ 720 os_memcpy(buf, stk->u.auth.tx_mic_key, 8); 721 os_memcpy(stk->u.auth.tx_mic_key, stk->u.auth.rx_mic_key, 8); 722 os_memcpy(stk->u.auth.rx_mic_key, buf, 8); 723 peerkey->tstk_set = 1; 724 725 kde_buf_len = peerkey->rsnie_p_len + 726 2 + RSN_SELECTOR_LEN + sizeof(lifetime) + 727 2 + RSN_SELECTOR_LEN + PMKID_LEN; 728 kde_buf = os_malloc(kde_buf_len); 729 if (kde_buf == NULL) 730 return; 731 pos = kde_buf; 732 pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len); 733 lifetime = host_to_be32(peerkey->lifetime); 734 pos = wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME, 735 (u8 *) &lifetime, sizeof(lifetime)); 736 wpa_add_kde(pos, RSN_KEY_DATA_PMKID, peerkey->smkid, PMKID_LEN); 737 738 if (wpa_supplicant_send_2_of_4(sm, peerkey->addr, key, ver, 739 peerkey->pnonce, kde_buf, kde_buf_len, 740 stk)) { 741 os_free(kde_buf); 742 return; 743 } 744 os_free(kde_buf); 745 746 os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN); 747} 748 749 750static void wpa_supplicant_update_smk_lifetime(struct wpa_sm *sm, 751 struct wpa_peerkey *peerkey, 752 struct wpa_eapol_ie_parse *kde) 753{ 754 u32 lifetime; 755 struct os_time now; 756 757 if (kde->lifetime == NULL || kde->lifetime_len < sizeof(lifetime)) 758 return; 759 760 lifetime = WPA_GET_BE32(kde->lifetime); 761 762 if (lifetime >= peerkey->lifetime) { 763 wpa_printf(MSG_DEBUG, "RSN: Peer used SMK lifetime %u seconds " 764 "which is larger than or equal to own value %u " 765 "seconds - ignored", lifetime, peerkey->lifetime); 766 return; 767 } 768 769 wpa_printf(MSG_DEBUG, "RSN: Peer used shorter SMK lifetime %u seconds " 770 "(own was %u seconds) - updated", 771 lifetime, peerkey->lifetime); 772 peerkey->lifetime = lifetime; 773 774 os_get_time(&now); 775 peerkey->expiration = now.sec + lifetime; 776 eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey); 777 eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout, 778 sm, peerkey); 779} 780 781 782static void wpa_supplicant_process_stk_2_of_4(struct wpa_sm *sm, 783 struct wpa_peerkey *peerkey, 784 const struct wpa_eapol_key *key, 785 u16 ver) 786{ 787 struct wpa_eapol_ie_parse kde; 788 const u8 *keydata; 789 size_t len; 790 791 wpa_printf(MSG_DEBUG, "RSN: RX message 2 of STK 4-Way Handshake from " 792 MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver); 793 794 os_memset(&kde, 0, sizeof(kde)); 795 796 /* RSN: msg 2/4 should contain SMKID for the selected SMK and RSN IE 797 * from the peer. It may also include Lifetime KDE. */ 798 keydata = (const u8 *) (key + 1); 799 len = WPA_GET_BE16(key->key_data_length); 800 wpa_hexdump(MSG_DEBUG, "RSN: msg 2/4 key data", keydata, len); 801 if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0 || 802 kde.pmkid == NULL || kde.rsn_ie == NULL) { 803 wpa_printf(MSG_DEBUG, "RSN: No SMKID or RSN IE in STK 2/4"); 804 return; 805 } 806 807 if (os_memcmp(kde.pmkid, peerkey->smkid, PMKID_LEN) != 0) { 808 wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 2/4", 809 kde.pmkid, PMKID_LEN); 810 return; 811 } 812 813 if (kde.rsn_ie_len != peerkey->rsnie_p_len || 814 os_memcmp(kde.rsn_ie, peerkey->rsnie_p, kde.rsn_ie_len) != 0) { 815 wpa_printf(MSG_INFO, "RSN: Peer RSN IE in SMK and STK " 816 "handshakes did not match"); 817 wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in SMK handshake", 818 peerkey->rsnie_p, peerkey->rsnie_p_len); 819 wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in STK handshake", 820 kde.rsn_ie, kde.rsn_ie_len); 821 return; 822 } 823 824 wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde); 825 826 wpa_supplicant_send_stk_3_of_4(sm, peerkey); 827 os_memcpy(peerkey->pnonce, key->key_nonce, WPA_NONCE_LEN); 828} 829 830 831static void wpa_supplicant_process_stk_3_of_4(struct wpa_sm *sm, 832 struct wpa_peerkey *peerkey, 833 const struct wpa_eapol_key *key, 834 u16 ver) 835{ 836 struct wpa_eapol_ie_parse kde; 837 const u8 *keydata; 838 size_t len, key_len; 839 const u8 *_key; 840 u8 key_buf[32], rsc[6]; 841 842 wpa_printf(MSG_DEBUG, "RSN: RX message 3 of STK 4-Way Handshake from " 843 MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver); 844 845 os_memset(&kde, 0, sizeof(kde)); 846 847 /* RSN: msg 3/4 should contain Initiator RSN IE. It may also include 848 * Lifetime KDE. */ 849 keydata = (const u8 *) (key + 1); 850 len = WPA_GET_BE16(key->key_data_length); 851 wpa_hexdump(MSG_DEBUG, "RSN: msg 3/4 key data", keydata, len); 852 if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0) { 853 wpa_printf(MSG_DEBUG, "RSN: Failed to parse key data in " 854 "STK 3/4"); 855 return; 856 } 857 858 if (kde.rsn_ie_len != peerkey->rsnie_i_len || 859 os_memcmp(kde.rsn_ie, peerkey->rsnie_i, kde.rsn_ie_len) != 0) { 860 wpa_printf(MSG_INFO, "RSN: Initiator RSN IE in SMK and STK " 861 "handshakes did not match"); 862 wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in SMK " 863 "handshake", 864 peerkey->rsnie_i, peerkey->rsnie_i_len); 865 wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in STK " 866 "handshake", 867 kde.rsn_ie, kde.rsn_ie_len); 868 return; 869 } 870 871 if (os_memcmp(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN) != 0) { 872 wpa_printf(MSG_WARNING, "RSN: INonce from message 1 of STK " 873 "4-Way Handshake differs from 3 of STK 4-Way " 874 "Handshake - drop packet (src=" MACSTR ")", 875 MAC2STR(peerkey->addr)); 876 return; 877 } 878 879 wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde); 880 881 if (wpa_supplicant_send_4_of_4(sm, peerkey->addr, key, ver, 882 WPA_GET_BE16(key->key_info), 883 NULL, 0, &peerkey->stk)) 884 return; 885 886 _key = (u8 *) peerkey->stk.tk1; 887 if (peerkey->cipher == WPA_CIPHER_TKIP) { 888 /* Swap Tx/Rx keys for Michael MIC */ 889 os_memcpy(key_buf, _key, 16); 890 os_memcpy(key_buf + 16, peerkey->stk.u.auth.rx_mic_key, 8); 891 os_memcpy(key_buf + 24, peerkey->stk.u.auth.tx_mic_key, 8); 892 _key = key_buf; 893 key_len = 32; 894 } else 895 key_len = 16; 896 897 os_memset(rsc, 0, 6); 898 if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1, 899 rsc, sizeof(rsc), _key, key_len) < 0) { 900 wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the " 901 "driver."); 902 return; 903 } 904} 905 906 907static void wpa_supplicant_process_stk_4_of_4(struct wpa_sm *sm, 908 struct wpa_peerkey *peerkey, 909 const struct wpa_eapol_key *key, 910 u16 ver) 911{ 912 u8 rsc[6]; 913 914 wpa_printf(MSG_DEBUG, "RSN: RX message 4 of STK 4-Way Handshake from " 915 MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver); 916 917 os_memset(rsc, 0, 6); 918 if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1, 919 rsc, sizeof(rsc), (u8 *) peerkey->stk.tk1, 920 peerkey->cipher == WPA_CIPHER_TKIP ? 32 : 16) < 0) { 921 wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the " 922 "driver."); 923 return; 924 } 925} 926 927 928/** 929 * peerkey_verify_eapol_key_mic - Verify PeerKey MIC 930 * @sm: Pointer to WPA state machine data from wpa_sm_init() 931 * @peerkey: Pointer to the PeerKey data for the peer 932 * @key: Pointer to the EAPOL-Key frame header 933 * @ver: Version bits from EAPOL-Key Key Info 934 * @buf: Pointer to the beginning of EAPOL-Key frame 935 * @len: Length of the EAPOL-Key frame 936 * Returns: 0 on success, -1 on failure 937 */ 938int peerkey_verify_eapol_key_mic(struct wpa_sm *sm, 939 struct wpa_peerkey *peerkey, 940 struct wpa_eapol_key *key, u16 ver, 941 const u8 *buf, size_t len) 942{ 943 u8 mic[16]; 944 int ok = 0; 945 946 if (peerkey->initiator && !peerkey->stk_set) { 947 wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion", 948 sm->own_addr, peerkey->addr, 949 peerkey->inonce, key->key_nonce, 950 (u8 *) &peerkey->stk, sizeof(peerkey->stk), 951 peerkey->use_sha256); 952 peerkey->stk_set = 1; 953 } 954 955 os_memcpy(mic, key->key_mic, 16); 956 if (peerkey->tstk_set) { 957 os_memset(key->key_mic, 0, 16); 958 wpa_eapol_key_mic(peerkey->tstk.kck, ver, buf, len, 959 key->key_mic); 960 if (os_memcmp(mic, key->key_mic, 16) != 0) { 961 wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC " 962 "when using TSTK - ignoring TSTK"); 963 } else { 964 ok = 1; 965 peerkey->tstk_set = 0; 966 peerkey->stk_set = 1; 967 os_memcpy(&peerkey->stk, &peerkey->tstk, 968 sizeof(peerkey->stk)); 969 } 970 } 971 972 if (!ok && peerkey->stk_set) { 973 os_memset(key->key_mic, 0, 16); 974 wpa_eapol_key_mic(peerkey->stk.kck, ver, buf, len, 975 key->key_mic); 976 if (os_memcmp(mic, key->key_mic, 16) != 0) { 977 wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC " 978 "- dropping packet"); 979 return -1; 980 } 981 ok = 1; 982 } 983 984 if (!ok) { 985 wpa_printf(MSG_WARNING, "RSN: Could not verify EAPOL-Key MIC " 986 "- dropping packet"); 987 return -1; 988 } 989 990 os_memcpy(peerkey->replay_counter, key->replay_counter, 991 WPA_REPLAY_COUNTER_LEN); 992 peerkey->replay_counter_set = 1; 993 return 0; 994} 995 996 997/** 998 * wpa_sm_stkstart - Send EAPOL-Key Request for STK handshake (STK M1) 999 * @sm: Pointer to WPA state machine data from wpa_sm_init() 1000 * @peer: MAC address of the peer STA 1001 * Returns: 0 on success, or -1 on failure 1002 * 1003 * Send an EAPOL-Key Request to the current authenticator to start STK 1004 * handshake with the peer. 1005 */ 1006int wpa_sm_stkstart(struct wpa_sm *sm, const u8 *peer) 1007{ 1008 size_t rlen, kde_len; 1009 struct wpa_eapol_key *req; 1010 int key_info, ver; 1011 u8 bssid[ETH_ALEN], *rbuf, *pos, *count_pos; 1012 u16 count; 1013 struct rsn_ie_hdr *hdr; 1014 struct wpa_peerkey *peerkey; 1015 struct wpa_ie_data ie; 1016 1017 if (sm->proto != WPA_PROTO_RSN || !sm->ptk_set || !sm->peerkey_enabled) 1018 return -1; 1019 1020 if (sm->ap_rsn_ie && 1021 wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &ie) == 0 && 1022 !(ie.capabilities & WPA_CAPABILITY_PEERKEY_ENABLED)) { 1023 wpa_printf(MSG_DEBUG, "RSN: Current AP does not support STK"); 1024 return -1; 1025 } 1026 1027 if (sm->pairwise_cipher != WPA_CIPHER_TKIP) 1028 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES; 1029 else 1030 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4; 1031 1032 if (wpa_sm_get_bssid(sm, bssid) < 0) { 1033 wpa_printf(MSG_WARNING, "Failed to read BSSID for EAPOL-Key " 1034 "SMK M1"); 1035 return -1; 1036 } 1037 1038 /* TODO: find existing entry and if found, use that instead of adding 1039 * a new one */ 1040 peerkey = os_zalloc(sizeof(*peerkey)); 1041 if (peerkey == NULL) 1042 return -1; 1043 peerkey->initiator = 1; 1044 os_memcpy(peerkey->addr, peer, ETH_ALEN); 1045#ifdef CONFIG_IEEE80211W 1046 if (wpa_key_mgmt_sha256(sm->key_mgmt)) 1047 peerkey->use_sha256 = 1; 1048#endif /* CONFIG_IEEE80211W */ 1049 1050 /* SMK M1: 1051 * EAPOL-Key(S=1, M=1, A=0, I=0, K=0, SM=1, KeyRSC=0, Nonce=INonce, 1052 * MIC=MIC, DataKDs=(RSNIE_I, MAC_P KDE)) 1053 */ 1054 1055 hdr = (struct rsn_ie_hdr *) peerkey->rsnie_i; 1056 hdr->elem_id = WLAN_EID_RSN; 1057 WPA_PUT_LE16(hdr->version, RSN_VERSION); 1058 pos = (u8 *) (hdr + 1); 1059 /* Group Suite can be anything for SMK RSN IE; receiver will just 1060 * ignore it. */ 1061 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); 1062 pos += RSN_SELECTOR_LEN; 1063 count_pos = pos; 1064 pos += 2; 1065 1066 count = 0; 1067 if (sm->allowed_pairwise_cipher & WPA_CIPHER_CCMP) { 1068 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); 1069 pos += RSN_SELECTOR_LEN; 1070 count++; 1071 } 1072 if (sm->allowed_pairwise_cipher & WPA_CIPHER_GCMP) { 1073 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP); 1074 pos += RSN_SELECTOR_LEN; 1075 count++; 1076 } 1077 if (sm->allowed_pairwise_cipher & WPA_CIPHER_TKIP) { 1078 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP); 1079 pos += RSN_SELECTOR_LEN; 1080 count++; 1081 } 1082 WPA_PUT_LE16(count_pos, count); 1083 1084 hdr->len = (pos - peerkey->rsnie_i) - 2; 1085 peerkey->rsnie_i_len = pos - peerkey->rsnie_i; 1086 wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake", 1087 peerkey->rsnie_i, peerkey->rsnie_i_len); 1088 1089 kde_len = peerkey->rsnie_i_len + 2 + RSN_SELECTOR_LEN + ETH_ALEN; 1090 1091 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL, 1092 sizeof(*req) + kde_len, &rlen, 1093 (void *) &req); 1094 if (rbuf == NULL) { 1095 wpa_supplicant_peerkey_free(sm, peerkey); 1096 return -1; 1097 } 1098 1099 req->type = EAPOL_KEY_TYPE_RSN; 1100 key_info = WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC | 1101 WPA_KEY_INFO_SECURE | WPA_KEY_INFO_REQUEST | ver; 1102 WPA_PUT_BE16(req->key_info, key_info); 1103 WPA_PUT_BE16(req->key_length, 0); 1104 os_memcpy(req->replay_counter, sm->request_counter, 1105 WPA_REPLAY_COUNTER_LEN); 1106 inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN); 1107 1108 if (random_get_bytes(peerkey->inonce, WPA_NONCE_LEN)) { 1109 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 1110 "WPA: Failed to get random data for INonce"); 1111 os_free(rbuf); 1112 wpa_supplicant_peerkey_free(sm, peerkey); 1113 return -1; 1114 } 1115 os_memcpy(req->key_nonce, peerkey->inonce, WPA_NONCE_LEN); 1116 wpa_hexdump(MSG_DEBUG, "WPA: INonce for SMK handshake", 1117 req->key_nonce, WPA_NONCE_LEN); 1118 1119 WPA_PUT_BE16(req->key_data_length, (u16) kde_len); 1120 pos = (u8 *) (req + 1); 1121 1122 /* Initiator RSN IE */ 1123 pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len); 1124 /* Peer MAC address KDE */ 1125 wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN); 1126 1127 wpa_printf(MSG_INFO, "RSN: Sending EAPOL-Key SMK M1 Request (peer " 1128 MACSTR ")", MAC2STR(peer)); 1129 wpa_eapol_key_send(sm, sm->ptk.kck, ver, bssid, ETH_P_EAPOL, 1130 rbuf, rlen, req->key_mic); 1131 1132 peerkey->next = sm->peerkey; 1133 sm->peerkey = peerkey; 1134 1135 return 0; 1136} 1137 1138 1139/** 1140 * peerkey_deinit - Free PeerKey values 1141 * @sm: Pointer to WPA state machine data from wpa_sm_init() 1142 */ 1143void peerkey_deinit(struct wpa_sm *sm) 1144{ 1145 struct wpa_peerkey *prev, *peerkey = sm->peerkey; 1146 while (peerkey) { 1147 prev = peerkey; 1148 peerkey = peerkey->next; 1149 os_free(prev); 1150 } 1151 sm->peerkey = NULL; 1152} 1153 1154 1155void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey, 1156 struct wpa_eapol_key *key, u16 key_info, u16 ver) 1157{ 1158 if ((key_info & (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) == 1159 (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) { 1160 /* 3/4 STK 4-Way Handshake */ 1161 wpa_supplicant_process_stk_3_of_4(sm, peerkey, key, ver); 1162 } else if (key_info & WPA_KEY_INFO_ACK) { 1163 /* 1/4 STK 4-Way Handshake */ 1164 wpa_supplicant_process_stk_1_of_4(sm, peerkey, key, ver); 1165 } else if (key_info & WPA_KEY_INFO_SECURE) { 1166 /* 4/4 STK 4-Way Handshake */ 1167 wpa_supplicant_process_stk_4_of_4(sm, peerkey, key, ver); 1168 } else { 1169 /* 2/4 STK 4-Way Handshake */ 1170 wpa_supplicant_process_stk_2_of_4(sm, peerkey, key, ver); 1171 } 1172} 1173 1174 1175void peerkey_rx_eapol_smk(struct wpa_sm *sm, const u8 *src_addr, 1176 struct wpa_eapol_key *key, size_t extra_len, 1177 u16 key_info, u16 ver) 1178{ 1179 if (key_info & WPA_KEY_INFO_ERROR) { 1180 /* SMK Error */ 1181 wpa_supplicant_process_smk_error(sm, src_addr, key, extra_len); 1182 } else if (key_info & WPA_KEY_INFO_ACK) { 1183 /* SMK M2 */ 1184 wpa_supplicant_process_smk_m2(sm, src_addr, key, extra_len, 1185 ver); 1186 } else { 1187 /* SMK M4 or M5 */ 1188 wpa_supplicant_process_smk_m45(sm, src_addr, key, extra_len, 1189 ver); 1190 } 1191} 1192 1193#endif /* CONFIG_PEERKEY */ 1194