$search
00001 /* 00002 * WPA Supplicant - PeerKey for Direct Link Setup (DLS) 00003 * Copyright (c) 2006-2008, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "includes.h" 00016 00017 #ifdef CONFIG_PEERKEY 00018 00019 #include "common.h" 00020 #include "eloop.h" 00021 #include "crypto/sha1.h" 00022 #include "crypto/sha256.h" 00023 #include "common/ieee802_11_defs.h" 00024 #include "wpa.h" 00025 #include "wpa_i.h" 00026 #include "wpa_ie.h" 00027 #include "peerkey.h" 00028 00029 00030 static u8 * wpa_add_ie(u8 *pos, const u8 *ie, size_t ie_len) 00031 { 00032 os_memcpy(pos, ie, ie_len); 00033 return pos + ie_len; 00034 } 00035 00036 00037 static u8 * wpa_add_kde(u8 *pos, u32 kde, const u8 *data, size_t data_len) 00038 { 00039 *pos++ = WLAN_EID_VENDOR_SPECIFIC; 00040 *pos++ = RSN_SELECTOR_LEN + data_len; 00041 RSN_SELECTOR_PUT(pos, kde); 00042 pos += RSN_SELECTOR_LEN; 00043 os_memcpy(pos, data, data_len); 00044 pos += data_len; 00045 return pos; 00046 } 00047 00048 00049 static void wpa_supplicant_smk_timeout(void *eloop_ctx, void *timeout_ctx) 00050 { 00051 #if 0 00052 struct wpa_sm *sm = eloop_ctx; 00053 struct wpa_peerkey *peerkey = timeout_ctx; 00054 #endif 00055 /* TODO: time out SMK and any STK that was generated using this SMK */ 00056 } 00057 00058 00059 static void wpa_supplicant_peerkey_free(struct wpa_sm *sm, 00060 struct wpa_peerkey *peerkey) 00061 { 00062 eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey); 00063 os_free(peerkey); 00064 } 00065 00066 00067 static int wpa_supplicant_send_smk_error(struct wpa_sm *sm, const u8 *dst, 00068 const u8 *peer, 00069 u16 mui, u16 error_type, int ver) 00070 { 00071 size_t rlen; 00072 struct wpa_eapol_key *err; 00073 struct rsn_error_kde error; 00074 u8 *rbuf, *pos; 00075 size_t kde_len; 00076 u16 key_info; 00077 00078 kde_len = 2 + RSN_SELECTOR_LEN + sizeof(error); 00079 if (peer) 00080 kde_len += 2 + RSN_SELECTOR_LEN + ETH_ALEN; 00081 00082 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, 00083 NULL, sizeof(*err) + kde_len, &rlen, 00084 (void *) &err); 00085 if (rbuf == NULL) 00086 return -1; 00087 00088 err->type = EAPOL_KEY_TYPE_RSN; 00089 key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC | 00090 WPA_KEY_INFO_SECURE | WPA_KEY_INFO_ERROR | 00091 WPA_KEY_INFO_REQUEST; 00092 WPA_PUT_BE16(err->key_info, key_info); 00093 WPA_PUT_BE16(err->key_length, 0); 00094 os_memcpy(err->replay_counter, sm->request_counter, 00095 WPA_REPLAY_COUNTER_LEN); 00096 inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN); 00097 00098 WPA_PUT_BE16(err->key_data_length, (u16) kde_len); 00099 pos = (u8 *) (err + 1); 00100 00101 if (peer) { 00102 /* Peer MAC Address KDE */ 00103 pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN); 00104 } 00105 00106 /* Error KDE */ 00107 error.mui = host_to_be16(mui); 00108 error.error_type = host_to_be16(error_type); 00109 wpa_add_kde(pos, RSN_KEY_DATA_ERROR, (u8 *) &error, sizeof(error)); 00110 00111 if (peer) { 00112 wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK Error (peer " 00113 MACSTR " mui %d error_type %d)", 00114 MAC2STR(peer), mui, error_type); 00115 } else { 00116 wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK Error " 00117 "(mui %d error_type %d)", mui, error_type); 00118 } 00119 00120 wpa_eapol_key_send(sm, sm->ptk.kck, ver, dst, ETH_P_EAPOL, 00121 rbuf, rlen, err->key_mic); 00122 00123 return 0; 00124 } 00125 00126 00127 static int wpa_supplicant_send_smk_m3(struct wpa_sm *sm, 00128 const unsigned char *src_addr, 00129 const struct wpa_eapol_key *key, 00130 int ver, struct wpa_peerkey *peerkey) 00131 { 00132 size_t rlen; 00133 struct wpa_eapol_key *reply; 00134 u8 *rbuf, *pos; 00135 size_t kde_len; 00136 u16 key_info; 00137 00138 /* KDEs: Peer RSN IE, Initiator MAC Address, Initiator Nonce */ 00139 kde_len = peerkey->rsnie_p_len + 00140 2 + RSN_SELECTOR_LEN + ETH_ALEN + 00141 2 + RSN_SELECTOR_LEN + WPA_NONCE_LEN; 00142 00143 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, 00144 NULL, sizeof(*reply) + kde_len, &rlen, 00145 (void *) &reply); 00146 if (rbuf == NULL) 00147 return -1; 00148 00149 reply->type = EAPOL_KEY_TYPE_RSN; 00150 key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC | 00151 WPA_KEY_INFO_SECURE; 00152 WPA_PUT_BE16(reply->key_info, key_info); 00153 WPA_PUT_BE16(reply->key_length, 0); 00154 os_memcpy(reply->replay_counter, key->replay_counter, 00155 WPA_REPLAY_COUNTER_LEN); 00156 00157 os_memcpy(reply->key_nonce, peerkey->pnonce, WPA_NONCE_LEN); 00158 00159 WPA_PUT_BE16(reply->key_data_length, (u16) kde_len); 00160 pos = (u8 *) (reply + 1); 00161 00162 /* Peer RSN IE */ 00163 pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len); 00164 00165 /* Initiator MAC Address KDE */ 00166 pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peerkey->addr, ETH_ALEN); 00167 00168 /* Initiator Nonce */ 00169 wpa_add_kde(pos, RSN_KEY_DATA_NONCE, peerkey->inonce, WPA_NONCE_LEN); 00170 00171 wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK M3"); 00172 wpa_eapol_key_send(sm, sm->ptk.kck, ver, src_addr, ETH_P_EAPOL, 00173 rbuf, rlen, reply->key_mic); 00174 00175 return 0; 00176 } 00177 00178 00179 static int wpa_supplicant_process_smk_m2( 00180 struct wpa_sm *sm, const unsigned char *src_addr, 00181 const struct wpa_eapol_key *key, size_t extra_len, int ver) 00182 { 00183 struct wpa_peerkey *peerkey; 00184 struct wpa_eapol_ie_parse kde; 00185 struct wpa_ie_data ie; 00186 int cipher; 00187 struct rsn_ie_hdr *hdr; 00188 u8 *pos; 00189 00190 wpa_printf(MSG_DEBUG, "RSN: Received SMK M2"); 00191 00192 if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) { 00193 wpa_printf(MSG_INFO, "RSN: SMK handshake not allowed for " 00194 "the current network"); 00195 return -1; 00196 } 00197 00198 if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) < 00199 0) { 00200 wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M2"); 00201 return -1; 00202 } 00203 00204 if (kde.rsn_ie == NULL || kde.mac_addr == NULL || 00205 kde.mac_addr_len < ETH_ALEN) { 00206 wpa_printf(MSG_INFO, "RSN: No RSN IE or MAC address KDE in " 00207 "SMK M2"); 00208 return -1; 00209 } 00210 00211 wpa_printf(MSG_DEBUG, "RSN: SMK M2 - SMK initiator " MACSTR, 00212 MAC2STR(kde.mac_addr)); 00213 00214 if (kde.rsn_ie_len > PEERKEY_MAX_IE_LEN) { 00215 wpa_printf(MSG_INFO, "RSN: Too long Initiator RSN IE in SMK " 00216 "M2"); 00217 return -1; 00218 } 00219 00220 if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) { 00221 wpa_printf(MSG_INFO, "RSN: Failed to parse RSN IE in SMK M2"); 00222 return -1; 00223 } 00224 00225 cipher = ie.pairwise_cipher & sm->allowed_pairwise_cipher; 00226 if (cipher & WPA_CIPHER_CCMP) { 00227 wpa_printf(MSG_DEBUG, "RSN: Using CCMP for PeerKey"); 00228 cipher = WPA_CIPHER_CCMP; 00229 } else if (cipher & WPA_CIPHER_TKIP) { 00230 wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey"); 00231 cipher = WPA_CIPHER_TKIP; 00232 } else { 00233 wpa_printf(MSG_INFO, "RSN: No acceptable cipher in SMK M2"); 00234 wpa_supplicant_send_smk_error(sm, src_addr, kde.mac_addr, 00235 STK_MUI_SMK, STK_ERR_CPHR_NS, 00236 ver); 00237 return -1; 00238 } 00239 00240 /* TODO: find existing entry and if found, use that instead of adding 00241 * a new one; how to handle the case where both ends initiate at the 00242 * same time? */ 00243 peerkey = os_zalloc(sizeof(*peerkey)); 00244 if (peerkey == NULL) 00245 return -1; 00246 os_memcpy(peerkey->addr, kde.mac_addr, ETH_ALEN); 00247 os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN); 00248 os_memcpy(peerkey->rsnie_i, kde.rsn_ie, kde.rsn_ie_len); 00249 peerkey->rsnie_i_len = kde.rsn_ie_len; 00250 peerkey->cipher = cipher; 00251 #ifdef CONFIG_IEEE80211W 00252 if (ie.key_mgmt & (WPA_KEY_MGMT_IEEE8021X_SHA256 | 00253 WPA_KEY_MGMT_PSK_SHA256)) 00254 peerkey->use_sha256 = 1; 00255 #endif /* CONFIG_IEEE80211W */ 00256 00257 if (os_get_random(peerkey->pnonce, WPA_NONCE_LEN)) { 00258 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 00259 "WPA: Failed to get random data for PNonce"); 00260 wpa_supplicant_peerkey_free(sm, peerkey); 00261 return -1; 00262 } 00263 00264 hdr = (struct rsn_ie_hdr *) peerkey->rsnie_p; 00265 hdr->elem_id = WLAN_EID_RSN; 00266 WPA_PUT_LE16(hdr->version, RSN_VERSION); 00267 pos = (u8 *) (hdr + 1); 00268 /* Group Suite can be anything for SMK RSN IE; receiver will just 00269 * ignore it. */ 00270 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); 00271 pos += RSN_SELECTOR_LEN; 00272 /* Include only the selected cipher in pairwise cipher suite */ 00273 WPA_PUT_LE16(pos, 1); 00274 pos += 2; 00275 if (cipher == WPA_CIPHER_CCMP) 00276 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); 00277 else if (cipher == WPA_CIPHER_TKIP) 00278 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP); 00279 pos += RSN_SELECTOR_LEN; 00280 00281 hdr->len = (pos - peerkey->rsnie_p) - 2; 00282 peerkey->rsnie_p_len = pos - peerkey->rsnie_p; 00283 wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake", 00284 peerkey->rsnie_p, peerkey->rsnie_p_len); 00285 00286 wpa_supplicant_send_smk_m3(sm, src_addr, key, ver, peerkey); 00287 00288 peerkey->next = sm->peerkey; 00289 sm->peerkey = peerkey; 00290 00291 return 0; 00292 } 00293 00294 00307 static void rsn_smkid(const u8 *smk, const u8 *pnonce, const u8 *mac_p, 00308 const u8 *inonce, const u8 *mac_i, u8 *smkid, 00309 int use_sha256) 00310 { 00311 char *title = "SMK Name"; 00312 const u8 *addr[5]; 00313 const size_t len[5] = { 8, WPA_NONCE_LEN, ETH_ALEN, WPA_NONCE_LEN, 00314 ETH_ALEN }; 00315 unsigned char hash[SHA256_MAC_LEN]; 00316 00317 addr[0] = (u8 *) title; 00318 addr[1] = pnonce; 00319 addr[2] = mac_p; 00320 addr[3] = inonce; 00321 addr[4] = mac_i; 00322 00323 #ifdef CONFIG_IEEE80211W 00324 if (use_sha256) 00325 hmac_sha256_vector(smk, PMK_LEN, 5, addr, len, hash); 00326 else 00327 #endif /* CONFIG_IEEE80211W */ 00328 hmac_sha1_vector(smk, PMK_LEN, 5, addr, len, hash); 00329 os_memcpy(smkid, hash, PMKID_LEN); 00330 } 00331 00332 00333 static void wpa_supplicant_send_stk_1_of_4(struct wpa_sm *sm, 00334 struct wpa_peerkey *peerkey) 00335 { 00336 size_t mlen; 00337 struct wpa_eapol_key *msg; 00338 u8 *mbuf; 00339 size_t kde_len; 00340 u16 key_info, ver; 00341 00342 kde_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN; 00343 00344 mbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL, 00345 sizeof(*msg) + kde_len, &mlen, 00346 (void *) &msg); 00347 if (mbuf == NULL) 00348 return; 00349 00350 msg->type = EAPOL_KEY_TYPE_RSN; 00351 00352 if (peerkey->cipher == WPA_CIPHER_CCMP) 00353 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES; 00354 else 00355 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4; 00356 00357 key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK; 00358 WPA_PUT_BE16(msg->key_info, key_info); 00359 00360 if (peerkey->cipher == WPA_CIPHER_CCMP) 00361 WPA_PUT_BE16(msg->key_length, 16); 00362 else 00363 WPA_PUT_BE16(msg->key_length, 32); 00364 00365 os_memcpy(msg->replay_counter, peerkey->replay_counter, 00366 WPA_REPLAY_COUNTER_LEN); 00367 inc_byte_array(peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN); 00368 00369 WPA_PUT_BE16(msg->key_data_length, kde_len); 00370 wpa_add_kde((u8 *) (msg + 1), RSN_KEY_DATA_PMKID, 00371 peerkey->smkid, PMKID_LEN); 00372 00373 if (os_get_random(peerkey->inonce, WPA_NONCE_LEN)) { 00374 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 00375 "RSN: Failed to get random data for INonce (STK)"); 00376 os_free(mbuf); 00377 return; 00378 } 00379 wpa_hexdump(MSG_DEBUG, "RSN: INonce for STK 4-Way Handshake", 00380 peerkey->inonce, WPA_NONCE_LEN); 00381 os_memcpy(msg->key_nonce, peerkey->inonce, WPA_NONCE_LEN); 00382 00383 wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 1/4 to " MACSTR, 00384 MAC2STR(peerkey->addr)); 00385 wpa_eapol_key_send(sm, NULL, ver, peerkey->addr, ETH_P_EAPOL, 00386 mbuf, mlen, NULL); 00387 } 00388 00389 00390 static void wpa_supplicant_send_stk_3_of_4(struct wpa_sm *sm, 00391 struct wpa_peerkey *peerkey) 00392 { 00393 size_t mlen; 00394 struct wpa_eapol_key *msg; 00395 u8 *mbuf, *pos; 00396 size_t kde_len; 00397 u16 key_info, ver; 00398 be32 lifetime; 00399 00400 kde_len = peerkey->rsnie_i_len + 00401 2 + RSN_SELECTOR_LEN + sizeof(lifetime); 00402 00403 mbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL, 00404 sizeof(*msg) + kde_len, &mlen, 00405 (void *) &msg); 00406 if (mbuf == NULL) 00407 return; 00408 00409 msg->type = EAPOL_KEY_TYPE_RSN; 00410 00411 if (peerkey->cipher == WPA_CIPHER_CCMP) 00412 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES; 00413 else 00414 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4; 00415 00416 key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK | 00417 WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE; 00418 WPA_PUT_BE16(msg->key_info, key_info); 00419 00420 if (peerkey->cipher == WPA_CIPHER_CCMP) 00421 WPA_PUT_BE16(msg->key_length, 16); 00422 else 00423 WPA_PUT_BE16(msg->key_length, 32); 00424 00425 os_memcpy(msg->replay_counter, peerkey->replay_counter, 00426 WPA_REPLAY_COUNTER_LEN); 00427 inc_byte_array(peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN); 00428 00429 WPA_PUT_BE16(msg->key_data_length, kde_len); 00430 pos = (u8 *) (msg + 1); 00431 pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len); 00432 lifetime = host_to_be32(peerkey->lifetime); 00433 wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME, 00434 (u8 *) &lifetime, sizeof(lifetime)); 00435 00436 os_memcpy(msg->key_nonce, peerkey->inonce, WPA_NONCE_LEN); 00437 00438 wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 3/4 to " MACSTR, 00439 MAC2STR(peerkey->addr)); 00440 wpa_eapol_key_send(sm, peerkey->stk.kck, ver, peerkey->addr, 00441 ETH_P_EAPOL, mbuf, mlen, msg->key_mic); 00442 } 00443 00444 00445 static int wpa_supplicant_process_smk_m4(struct wpa_peerkey *peerkey, 00446 struct wpa_eapol_ie_parse *kde) 00447 { 00448 wpa_printf(MSG_DEBUG, "RSN: Received SMK M4 (Initiator " MACSTR ")", 00449 MAC2STR(kde->mac_addr)); 00450 00451 if (os_memcmp(kde->smk + PMK_LEN, peerkey->pnonce, WPA_NONCE_LEN) != 0) 00452 { 00453 wpa_printf(MSG_INFO, "RSN: PNonce in SMK KDE does not " 00454 "match with the one used in SMK M3"); 00455 return -1; 00456 } 00457 00458 if (os_memcmp(kde->nonce, peerkey->inonce, WPA_NONCE_LEN) != 0) { 00459 wpa_printf(MSG_INFO, "RSN: INonce in SMK M4 did not " 00460 "match with the one received in SMK M2"); 00461 return -1; 00462 } 00463 00464 return 0; 00465 } 00466 00467 00468 static int wpa_supplicant_process_smk_m5(struct wpa_sm *sm, 00469 const unsigned char *src_addr, 00470 const struct wpa_eapol_key *key, 00471 int ver, 00472 struct wpa_peerkey *peerkey, 00473 struct wpa_eapol_ie_parse *kde) 00474 { 00475 int cipher; 00476 struct wpa_ie_data ie; 00477 00478 wpa_printf(MSG_DEBUG, "RSN: Received SMK M5 (Peer " MACSTR ")", 00479 MAC2STR(kde->mac_addr)); 00480 if (kde->rsn_ie == NULL || kde->rsn_ie_len > PEERKEY_MAX_IE_LEN || 00481 wpa_parse_wpa_ie_rsn(kde->rsn_ie, kde->rsn_ie_len, &ie) < 0) { 00482 wpa_printf(MSG_INFO, "RSN: No RSN IE in SMK M5"); 00483 /* TODO: abort negotiation */ 00484 return -1; 00485 } 00486 00487 if (os_memcmp(key->key_nonce, peerkey->inonce, WPA_NONCE_LEN) != 0) { 00488 wpa_printf(MSG_INFO, "RSN: Key Nonce in SMK M5 does " 00489 "not match with INonce used in SMK M1"); 00490 return -1; 00491 } 00492 00493 if (os_memcmp(kde->smk + PMK_LEN, peerkey->inonce, WPA_NONCE_LEN) != 0) 00494 { 00495 wpa_printf(MSG_INFO, "RSN: INonce in SMK KDE does not " 00496 "match with the one used in SMK M1"); 00497 return -1; 00498 } 00499 00500 os_memcpy(peerkey->rsnie_p, kde->rsn_ie, kde->rsn_ie_len); 00501 peerkey->rsnie_p_len = kde->rsn_ie_len; 00502 os_memcpy(peerkey->pnonce, kde->nonce, WPA_NONCE_LEN); 00503 00504 cipher = ie.pairwise_cipher & sm->allowed_pairwise_cipher; 00505 if (cipher & WPA_CIPHER_CCMP) { 00506 wpa_printf(MSG_DEBUG, "RSN: Using CCMP for PeerKey"); 00507 peerkey->cipher = WPA_CIPHER_CCMP; 00508 } else if (cipher & WPA_CIPHER_TKIP) { 00509 wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey"); 00510 peerkey->cipher = WPA_CIPHER_TKIP; 00511 } else { 00512 wpa_printf(MSG_INFO, "RSN: SMK Peer STA " MACSTR " selected " 00513 "unacceptable cipher", MAC2STR(kde->mac_addr)); 00514 wpa_supplicant_send_smk_error(sm, src_addr, kde->mac_addr, 00515 STK_MUI_SMK, STK_ERR_CPHR_NS, 00516 ver); 00517 /* TODO: abort negotiation */ 00518 return -1; 00519 } 00520 00521 return 0; 00522 } 00523 00524 00525 static int wpa_supplicant_process_smk_m45( 00526 struct wpa_sm *sm, const unsigned char *src_addr, 00527 const struct wpa_eapol_key *key, size_t extra_len, int ver) 00528 { 00529 struct wpa_peerkey *peerkey; 00530 struct wpa_eapol_ie_parse kde; 00531 u32 lifetime; 00532 struct os_time now; 00533 00534 if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) { 00535 wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for " 00536 "the current network"); 00537 return -1; 00538 } 00539 00540 if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) < 00541 0) { 00542 wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M4/M5"); 00543 return -1; 00544 } 00545 00546 if (kde.mac_addr == NULL || kde.mac_addr_len < ETH_ALEN || 00547 kde.nonce == NULL || kde.nonce_len < WPA_NONCE_LEN || 00548 kde.smk == NULL || kde.smk_len < PMK_LEN + WPA_NONCE_LEN || 00549 kde.lifetime == NULL || kde.lifetime_len < 4) { 00550 wpa_printf(MSG_INFO, "RSN: No MAC Address, Nonce, SMK, or " 00551 "Lifetime KDE in SMK M4/M5"); 00552 return -1; 00553 } 00554 00555 for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) { 00556 if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) == 0 && 00557 os_memcmp(peerkey->initiator ? peerkey->inonce : 00558 peerkey->pnonce, 00559 key->key_nonce, WPA_NONCE_LEN) == 0) 00560 break; 00561 } 00562 if (peerkey == NULL) { 00563 wpa_printf(MSG_INFO, "RSN: No matching SMK handshake found " 00564 "for SMK M4/M5: peer " MACSTR, 00565 MAC2STR(kde.mac_addr)); 00566 return -1; 00567 } 00568 00569 if (peerkey->initiator) { 00570 if (wpa_supplicant_process_smk_m5(sm, src_addr, key, ver, 00571 peerkey, &kde) < 0) 00572 return -1; 00573 } else { 00574 if (wpa_supplicant_process_smk_m4(peerkey, &kde) < 0) 00575 return -1; 00576 } 00577 00578 os_memcpy(peerkey->smk, kde.smk, PMK_LEN); 00579 peerkey->smk_complete = 1; 00580 wpa_hexdump_key(MSG_DEBUG, "RSN: SMK", peerkey->smk, PMK_LEN); 00581 lifetime = WPA_GET_BE32(kde.lifetime); 00582 wpa_printf(MSG_DEBUG, "RSN: SMK lifetime %u seconds", lifetime); 00583 if (lifetime > 1000000000) 00584 lifetime = 1000000000; /* avoid overflowing expiration time */ 00585 peerkey->lifetime = lifetime; 00586 os_get_time(&now); 00587 peerkey->expiration = now.sec + lifetime; 00588 eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout, 00589 sm, peerkey); 00590 00591 if (peerkey->initiator) { 00592 rsn_smkid(peerkey->smk, peerkey->pnonce, peerkey->addr, 00593 peerkey->inonce, sm->own_addr, peerkey->smkid, 00594 peerkey->use_sha256); 00595 wpa_supplicant_send_stk_1_of_4(sm, peerkey); 00596 } else { 00597 rsn_smkid(peerkey->smk, peerkey->pnonce, sm->own_addr, 00598 peerkey->inonce, peerkey->addr, peerkey->smkid, 00599 peerkey->use_sha256); 00600 } 00601 wpa_hexdump(MSG_DEBUG, "RSN: SMKID", peerkey->smkid, PMKID_LEN); 00602 00603 return 0; 00604 } 00605 00606 00607 static int wpa_supplicant_process_smk_error( 00608 struct wpa_sm *sm, const unsigned char *src_addr, 00609 const struct wpa_eapol_key *key, size_t extra_len) 00610 { 00611 struct wpa_eapol_ie_parse kde; 00612 struct rsn_error_kde error; 00613 u8 peer[ETH_ALEN]; 00614 u16 error_type; 00615 00616 wpa_printf(MSG_DEBUG, "RSN: Received SMK Error"); 00617 00618 if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) { 00619 wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for " 00620 "the current network"); 00621 return -1; 00622 } 00623 00624 if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) < 00625 0) { 00626 wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK Error"); 00627 return -1; 00628 } 00629 00630 if (kde.error == NULL || kde.error_len < sizeof(error)) { 00631 wpa_printf(MSG_INFO, "RSN: No Error KDE in SMK Error"); 00632 return -1; 00633 } 00634 00635 if (kde.mac_addr && kde.mac_addr_len >= ETH_ALEN) 00636 os_memcpy(peer, kde.mac_addr, ETH_ALEN); 00637 else 00638 os_memset(peer, 0, ETH_ALEN); 00639 os_memcpy(&error, kde.error, sizeof(error)); 00640 error_type = be_to_host16(error.error_type); 00641 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 00642 "RSN: SMK Error KDE received: MUI %d error_type %d peer " 00643 MACSTR, 00644 be_to_host16(error.mui), error_type, 00645 MAC2STR(peer)); 00646 00647 if (kde.mac_addr && 00648 (error_type == STK_ERR_STA_NR || error_type == STK_ERR_STA_NRSN || 00649 error_type == STK_ERR_CPHR_NS)) { 00650 struct wpa_peerkey *peerkey; 00651 00652 for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) { 00653 if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) == 00654 0) 00655 break; 00656 } 00657 if (peerkey == NULL) { 00658 wpa_printf(MSG_DEBUG, "RSN: No matching SMK handshake " 00659 "found for SMK Error"); 00660 return -1; 00661 } 00662 /* TODO: abort SMK/STK handshake and remove all related keys */ 00663 } 00664 00665 return 0; 00666 } 00667 00668 00669 static void wpa_supplicant_process_stk_1_of_4(struct wpa_sm *sm, 00670 struct wpa_peerkey *peerkey, 00671 const struct wpa_eapol_key *key, 00672 u16 ver) 00673 { 00674 struct wpa_eapol_ie_parse ie; 00675 const u8 *kde; 00676 size_t len, kde_buf_len; 00677 struct wpa_ptk *stk; 00678 u8 buf[8], *kde_buf, *pos; 00679 be32 lifetime; 00680 00681 wpa_printf(MSG_DEBUG, "RSN: RX message 1 of STK 4-Way Handshake from " 00682 MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver); 00683 00684 os_memset(&ie, 0, sizeof(ie)); 00685 00686 /* RSN: msg 1/4 should contain SMKID for the selected SMK */ 00687 kde = (const u8 *) (key + 1); 00688 len = WPA_GET_BE16(key->key_data_length); 00689 wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", kde, len); 00690 if (wpa_supplicant_parse_ies(kde, len, &ie) < 0 || ie.pmkid == NULL) { 00691 wpa_printf(MSG_DEBUG, "RSN: No SMKID in STK 1/4"); 00692 return; 00693 } 00694 if (os_memcmp(ie.pmkid, peerkey->smkid, PMKID_LEN) != 0) { 00695 wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 1/4", 00696 ie.pmkid, PMKID_LEN); 00697 return; 00698 } 00699 00700 if (os_get_random(peerkey->pnonce, WPA_NONCE_LEN)) { 00701 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 00702 "RSN: Failed to get random data for PNonce"); 00703 return; 00704 } 00705 wpa_hexdump(MSG_DEBUG, "WPA: Renewed PNonce", 00706 peerkey->pnonce, WPA_NONCE_LEN); 00707 00708 /* Calculate STK which will be stored as a temporary STK until it has 00709 * been verified when processing message 3/4. */ 00710 stk = &peerkey->tstk; 00711 wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion", 00712 sm->own_addr, peerkey->addr, 00713 peerkey->pnonce, key->key_nonce, 00714 (u8 *) stk, sizeof(*stk), 00715 peerkey->use_sha256); 00716 /* Supplicant: swap tx/rx Mic keys */ 00717 os_memcpy(buf, stk->u.auth.tx_mic_key, 8); 00718 os_memcpy(stk->u.auth.tx_mic_key, stk->u.auth.rx_mic_key, 8); 00719 os_memcpy(stk->u.auth.rx_mic_key, buf, 8); 00720 peerkey->tstk_set = 1; 00721 00722 kde_buf_len = peerkey->rsnie_p_len + 00723 2 + RSN_SELECTOR_LEN + sizeof(lifetime) + 00724 2 + RSN_SELECTOR_LEN + PMKID_LEN; 00725 kde_buf = os_malloc(kde_buf_len); 00726 if (kde_buf == NULL) 00727 return; 00728 pos = kde_buf; 00729 pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len); 00730 lifetime = host_to_be32(peerkey->lifetime); 00731 pos = wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME, 00732 (u8 *) &lifetime, sizeof(lifetime)); 00733 wpa_add_kde(pos, RSN_KEY_DATA_PMKID, peerkey->smkid, PMKID_LEN); 00734 00735 if (wpa_supplicant_send_2_of_4(sm, peerkey->addr, key, ver, 00736 peerkey->pnonce, kde_buf, kde_buf_len, 00737 stk)) { 00738 os_free(kde_buf); 00739 return; 00740 } 00741 os_free(kde_buf); 00742 00743 os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN); 00744 } 00745 00746 00747 static void wpa_supplicant_update_smk_lifetime(struct wpa_sm *sm, 00748 struct wpa_peerkey *peerkey, 00749 struct wpa_eapol_ie_parse *kde) 00750 { 00751 u32 lifetime; 00752 struct os_time now; 00753 00754 if (kde->lifetime == NULL || kde->lifetime_len < sizeof(lifetime)) 00755 return; 00756 00757 lifetime = WPA_GET_BE32(kde->lifetime); 00758 00759 if (lifetime >= peerkey->lifetime) { 00760 wpa_printf(MSG_DEBUG, "RSN: Peer used SMK lifetime %u seconds " 00761 "which is larger than or equal to own value %u " 00762 "seconds - ignored", lifetime, peerkey->lifetime); 00763 return; 00764 } 00765 00766 wpa_printf(MSG_DEBUG, "RSN: Peer used shorter SMK lifetime %u seconds " 00767 "(own was %u seconds) - updated", 00768 lifetime, peerkey->lifetime); 00769 peerkey->lifetime = lifetime; 00770 00771 os_get_time(&now); 00772 peerkey->expiration = now.sec + lifetime; 00773 eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey); 00774 eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout, 00775 sm, peerkey); 00776 } 00777 00778 00779 static void wpa_supplicant_process_stk_2_of_4(struct wpa_sm *sm, 00780 struct wpa_peerkey *peerkey, 00781 const struct wpa_eapol_key *key, 00782 u16 ver) 00783 { 00784 struct wpa_eapol_ie_parse kde; 00785 const u8 *keydata; 00786 size_t len; 00787 00788 wpa_printf(MSG_DEBUG, "RSN: RX message 2 of STK 4-Way Handshake from " 00789 MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver); 00790 00791 os_memset(&kde, 0, sizeof(kde)); 00792 00793 /* RSN: msg 2/4 should contain SMKID for the selected SMK and RSN IE 00794 * from the peer. It may also include Lifetime KDE. */ 00795 keydata = (const u8 *) (key + 1); 00796 len = WPA_GET_BE16(key->key_data_length); 00797 wpa_hexdump(MSG_DEBUG, "RSN: msg 2/4 key data", keydata, len); 00798 if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0 || 00799 kde.pmkid == NULL || kde.rsn_ie == NULL) { 00800 wpa_printf(MSG_DEBUG, "RSN: No SMKID or RSN IE in STK 2/4"); 00801 return; 00802 } 00803 00804 if (os_memcmp(kde.pmkid, peerkey->smkid, PMKID_LEN) != 0) { 00805 wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 2/4", 00806 kde.pmkid, PMKID_LEN); 00807 return; 00808 } 00809 00810 if (kde.rsn_ie_len != peerkey->rsnie_p_len || 00811 os_memcmp(kde.rsn_ie, peerkey->rsnie_p, kde.rsn_ie_len) != 0) { 00812 wpa_printf(MSG_INFO, "RSN: Peer RSN IE in SMK and STK " 00813 "handshakes did not match"); 00814 wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in SMK handshake", 00815 peerkey->rsnie_p, peerkey->rsnie_p_len); 00816 wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in STK handshake", 00817 kde.rsn_ie, kde.rsn_ie_len); 00818 return; 00819 } 00820 00821 wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde); 00822 00823 wpa_supplicant_send_stk_3_of_4(sm, peerkey); 00824 os_memcpy(peerkey->pnonce, key->key_nonce, WPA_NONCE_LEN); 00825 } 00826 00827 00828 static void wpa_supplicant_process_stk_3_of_4(struct wpa_sm *sm, 00829 struct wpa_peerkey *peerkey, 00830 const struct wpa_eapol_key *key, 00831 u16 ver) 00832 { 00833 struct wpa_eapol_ie_parse kde; 00834 const u8 *keydata; 00835 size_t len, key_len; 00836 const u8 *_key; 00837 u8 key_buf[32], rsc[6]; 00838 00839 wpa_printf(MSG_DEBUG, "RSN: RX message 3 of STK 4-Way Handshake from " 00840 MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver); 00841 00842 os_memset(&kde, 0, sizeof(kde)); 00843 00844 /* RSN: msg 3/4 should contain Initiator RSN IE. It may also include 00845 * Lifetime KDE. */ 00846 keydata = (const u8 *) (key + 1); 00847 len = WPA_GET_BE16(key->key_data_length); 00848 wpa_hexdump(MSG_DEBUG, "RSN: msg 3/4 key data", keydata, len); 00849 if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0) { 00850 wpa_printf(MSG_DEBUG, "RSN: Failed to parse key data in " 00851 "STK 3/4"); 00852 return; 00853 } 00854 00855 if (kde.rsn_ie_len != peerkey->rsnie_i_len || 00856 os_memcmp(kde.rsn_ie, peerkey->rsnie_i, kde.rsn_ie_len) != 0) { 00857 wpa_printf(MSG_INFO, "RSN: Initiator RSN IE in SMK and STK " 00858 "handshakes did not match"); 00859 wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in SMK " 00860 "handshake", 00861 peerkey->rsnie_i, peerkey->rsnie_i_len); 00862 wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in STK " 00863 "handshake", 00864 kde.rsn_ie, kde.rsn_ie_len); 00865 return; 00866 } 00867 00868 if (os_memcmp(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN) != 0) { 00869 wpa_printf(MSG_WARNING, "RSN: INonce from message 1 of STK " 00870 "4-Way Handshake differs from 3 of STK 4-Way " 00871 "Handshake - drop packet (src=" MACSTR ")", 00872 MAC2STR(peerkey->addr)); 00873 return; 00874 } 00875 00876 wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde); 00877 00878 if (wpa_supplicant_send_4_of_4(sm, peerkey->addr, key, ver, 00879 WPA_GET_BE16(key->key_info), 00880 NULL, 0, &peerkey->stk)) 00881 return; 00882 00883 _key = (u8 *) peerkey->stk.tk1; 00884 if (peerkey->cipher == WPA_CIPHER_TKIP) { 00885 /* Swap Tx/Rx keys for Michael MIC */ 00886 os_memcpy(key_buf, _key, 16); 00887 os_memcpy(key_buf + 16, peerkey->stk.u.auth.rx_mic_key, 8); 00888 os_memcpy(key_buf + 24, peerkey->stk.u.auth.tx_mic_key, 8); 00889 _key = key_buf; 00890 key_len = 32; 00891 } else 00892 key_len = 16; 00893 00894 os_memset(rsc, 0, 6); 00895 if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1, 00896 rsc, sizeof(rsc), _key, key_len) < 0) { 00897 wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the " 00898 "driver."); 00899 return; 00900 } 00901 } 00902 00903 00904 static void wpa_supplicant_process_stk_4_of_4(struct wpa_sm *sm, 00905 struct wpa_peerkey *peerkey, 00906 const struct wpa_eapol_key *key, 00907 u16 ver) 00908 { 00909 u8 rsc[6]; 00910 00911 wpa_printf(MSG_DEBUG, "RSN: RX message 4 of STK 4-Way Handshake from " 00912 MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver); 00913 00914 os_memset(rsc, 0, 6); 00915 if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1, 00916 rsc, sizeof(rsc), (u8 *) peerkey->stk.tk1, 00917 peerkey->cipher == WPA_CIPHER_TKIP ? 32 : 16) < 0) { 00918 wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the " 00919 "driver."); 00920 return; 00921 } 00922 } 00923 00924 00935 int peerkey_verify_eapol_key_mic(struct wpa_sm *sm, 00936 struct wpa_peerkey *peerkey, 00937 struct wpa_eapol_key *key, u16 ver, 00938 const u8 *buf, size_t len) 00939 { 00940 u8 mic[16]; 00941 int ok = 0; 00942 00943 if (peerkey->initiator && !peerkey->stk_set) { 00944 wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion", 00945 sm->own_addr, peerkey->addr, 00946 peerkey->inonce, key->key_nonce, 00947 (u8 *) &peerkey->stk, sizeof(peerkey->stk), 00948 peerkey->use_sha256); 00949 peerkey->stk_set = 1; 00950 } 00951 00952 os_memcpy(mic, key->key_mic, 16); 00953 if (peerkey->tstk_set) { 00954 os_memset(key->key_mic, 0, 16); 00955 wpa_eapol_key_mic(peerkey->tstk.kck, ver, buf, len, 00956 key->key_mic); 00957 if (os_memcmp(mic, key->key_mic, 16) != 0) { 00958 wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC " 00959 "when using TSTK - ignoring TSTK"); 00960 } else { 00961 ok = 1; 00962 peerkey->tstk_set = 0; 00963 peerkey->stk_set = 1; 00964 os_memcpy(&peerkey->stk, &peerkey->tstk, 00965 sizeof(peerkey->stk)); 00966 } 00967 } 00968 00969 if (!ok && peerkey->stk_set) { 00970 os_memset(key->key_mic, 0, 16); 00971 wpa_eapol_key_mic(peerkey->stk.kck, ver, buf, len, 00972 key->key_mic); 00973 if (os_memcmp(mic, key->key_mic, 16) != 0) { 00974 wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC " 00975 "- dropping packet"); 00976 return -1; 00977 } 00978 ok = 1; 00979 } 00980 00981 if (!ok) { 00982 wpa_printf(MSG_WARNING, "RSN: Could not verify EAPOL-Key MIC " 00983 "- dropping packet"); 00984 return -1; 00985 } 00986 00987 os_memcpy(peerkey->replay_counter, key->replay_counter, 00988 WPA_REPLAY_COUNTER_LEN); 00989 peerkey->replay_counter_set = 1; 00990 return 0; 00991 } 00992 00993 01003 int wpa_sm_stkstart(struct wpa_sm *sm, const u8 *peer) 01004 { 01005 size_t rlen, kde_len; 01006 struct wpa_eapol_key *req; 01007 int key_info, ver; 01008 u8 bssid[ETH_ALEN], *rbuf, *pos, *count_pos; 01009 u16 count; 01010 struct rsn_ie_hdr *hdr; 01011 struct wpa_peerkey *peerkey; 01012 struct wpa_ie_data ie; 01013 01014 if (sm->proto != WPA_PROTO_RSN || !sm->ptk_set || !sm->peerkey_enabled) 01015 return -1; 01016 01017 if (sm->ap_rsn_ie && 01018 wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &ie) == 0 && 01019 !(ie.capabilities & WPA_CAPABILITY_PEERKEY_ENABLED)) { 01020 wpa_printf(MSG_DEBUG, "RSN: Current AP does not support STK"); 01021 return -1; 01022 } 01023 01024 if (sm->pairwise_cipher == WPA_CIPHER_CCMP) 01025 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES; 01026 else 01027 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4; 01028 01029 if (wpa_sm_get_bssid(sm, bssid) < 0) { 01030 wpa_printf(MSG_WARNING, "Failed to read BSSID for EAPOL-Key " 01031 "SMK M1"); 01032 return -1; 01033 } 01034 01035 /* TODO: find existing entry and if found, use that instead of adding 01036 * a new one */ 01037 peerkey = os_zalloc(sizeof(*peerkey)); 01038 if (peerkey == NULL) 01039 return -1; 01040 peerkey->initiator = 1; 01041 os_memcpy(peerkey->addr, peer, ETH_ALEN); 01042 #ifdef CONFIG_IEEE80211W 01043 if (wpa_key_mgmt_sha256(sm->key_mgmt)) 01044 peerkey->use_sha256 = 1; 01045 #endif /* CONFIG_IEEE80211W */ 01046 01047 /* SMK M1: 01048 * EAPOL-Key(S=1, M=1, A=0, I=0, K=0, SM=1, KeyRSC=0, Nonce=INonce, 01049 * MIC=MIC, DataKDs=(RSNIE_I, MAC_P KDE)) 01050 */ 01051 01052 hdr = (struct rsn_ie_hdr *) peerkey->rsnie_i; 01053 hdr->elem_id = WLAN_EID_RSN; 01054 WPA_PUT_LE16(hdr->version, RSN_VERSION); 01055 pos = (u8 *) (hdr + 1); 01056 /* Group Suite can be anything for SMK RSN IE; receiver will just 01057 * ignore it. */ 01058 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); 01059 pos += RSN_SELECTOR_LEN; 01060 count_pos = pos; 01061 pos += 2; 01062 01063 count = 0; 01064 if (sm->allowed_pairwise_cipher & WPA_CIPHER_CCMP) { 01065 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); 01066 pos += RSN_SELECTOR_LEN; 01067 count++; 01068 } 01069 if (sm->allowed_pairwise_cipher & WPA_CIPHER_TKIP) { 01070 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP); 01071 pos += RSN_SELECTOR_LEN; 01072 count++; 01073 } 01074 WPA_PUT_LE16(count_pos, count); 01075 01076 hdr->len = (pos - peerkey->rsnie_i) - 2; 01077 peerkey->rsnie_i_len = pos - peerkey->rsnie_i; 01078 wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake", 01079 peerkey->rsnie_i, peerkey->rsnie_i_len); 01080 01081 kde_len = peerkey->rsnie_i_len + 2 + RSN_SELECTOR_LEN + ETH_ALEN; 01082 01083 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL, 01084 sizeof(*req) + kde_len, &rlen, 01085 (void *) &req); 01086 if (rbuf == NULL) { 01087 wpa_supplicant_peerkey_free(sm, peerkey); 01088 return -1; 01089 } 01090 01091 req->type = EAPOL_KEY_TYPE_RSN; 01092 key_info = WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC | 01093 WPA_KEY_INFO_SECURE | WPA_KEY_INFO_REQUEST | ver; 01094 WPA_PUT_BE16(req->key_info, key_info); 01095 WPA_PUT_BE16(req->key_length, 0); 01096 os_memcpy(req->replay_counter, sm->request_counter, 01097 WPA_REPLAY_COUNTER_LEN); 01098 inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN); 01099 01100 if (os_get_random(peerkey->inonce, WPA_NONCE_LEN)) { 01101 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 01102 "WPA: Failed to get random data for INonce"); 01103 os_free(rbuf); 01104 wpa_supplicant_peerkey_free(sm, peerkey); 01105 return -1; 01106 } 01107 os_memcpy(req->key_nonce, peerkey->inonce, WPA_NONCE_LEN); 01108 wpa_hexdump(MSG_DEBUG, "WPA: INonce for SMK handshake", 01109 req->key_nonce, WPA_NONCE_LEN); 01110 01111 WPA_PUT_BE16(req->key_data_length, (u16) kde_len); 01112 pos = (u8 *) (req + 1); 01113 01114 /* Initiator RSN IE */ 01115 pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len); 01116 /* Peer MAC address KDE */ 01117 wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN); 01118 01119 wpa_printf(MSG_INFO, "RSN: Sending EAPOL-Key SMK M1 Request (peer " 01120 MACSTR ")", MAC2STR(peer)); 01121 wpa_eapol_key_send(sm, sm->ptk.kck, ver, bssid, ETH_P_EAPOL, 01122 rbuf, rlen, req->key_mic); 01123 01124 peerkey->next = sm->peerkey; 01125 sm->peerkey = peerkey; 01126 01127 return 0; 01128 } 01129 01130 01135 void peerkey_deinit(struct wpa_sm *sm) 01136 { 01137 struct wpa_peerkey *prev, *peerkey = sm->peerkey; 01138 while (peerkey) { 01139 prev = peerkey; 01140 peerkey = peerkey->next; 01141 os_free(prev); 01142 } 01143 } 01144 01145 01146 void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey, 01147 struct wpa_eapol_key *key, u16 key_info, u16 ver) 01148 { 01149 if ((key_info & (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) == 01150 (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) { 01151 /* 3/4 STK 4-Way Handshake */ 01152 wpa_supplicant_process_stk_3_of_4(sm, peerkey, key, ver); 01153 } else if (key_info & WPA_KEY_INFO_ACK) { 01154 /* 1/4 STK 4-Way Handshake */ 01155 wpa_supplicant_process_stk_1_of_4(sm, peerkey, key, ver); 01156 } else if (key_info & WPA_KEY_INFO_SECURE) { 01157 /* 4/4 STK 4-Way Handshake */ 01158 wpa_supplicant_process_stk_4_of_4(sm, peerkey, key, ver); 01159 } else { 01160 /* 2/4 STK 4-Way Handshake */ 01161 wpa_supplicant_process_stk_2_of_4(sm, peerkey, key, ver); 01162 } 01163 } 01164 01165 01166 void peerkey_rx_eapol_smk(struct wpa_sm *sm, const u8 *src_addr, 01167 struct wpa_eapol_key *key, size_t extra_len, 01168 u16 key_info, u16 ver) 01169 { 01170 if (key_info & WPA_KEY_INFO_ERROR) { 01171 /* SMK Error */ 01172 wpa_supplicant_process_smk_error(sm, src_addr, key, extra_len); 01173 } else if (key_info & WPA_KEY_INFO_ACK) { 01174 /* SMK M2 */ 01175 wpa_supplicant_process_smk_m2(sm, src_addr, key, extra_len, 01176 ver); 01177 } else { 01178 /* SMK M4 or M5 */ 01179 wpa_supplicant_process_smk_m45(sm, src_addr, key, extra_len, 01180 ver); 01181 } 01182 } 01183 01184 #endif /* CONFIG_PEERKEY */