00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
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
00103 pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN);
00104 }
00105
00106
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
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
00163 pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len);
00164
00165
00166 pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peerkey->addr, ETH_ALEN);
00167
00168
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
00241
00242
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
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
00269
00270 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
00271 pos += RSN_SELECTOR_LEN;
00272
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
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
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
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;
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
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
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
00709
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
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
00794
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
00845
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
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
01036
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
01046
01047
01048
01049
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
01057
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
01115 pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len);
01116
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
01152 wpa_supplicant_process_stk_3_of_4(sm, peerkey, key, ver);
01153 } else if (key_info & WPA_KEY_INFO_ACK) {
01154
01155 wpa_supplicant_process_stk_1_of_4(sm, peerkey, key, ver);
01156 } else if (key_info & WPA_KEY_INFO_SECURE) {
01157
01158 wpa_supplicant_process_stk_4_of_4(sm, peerkey, key, ver);
01159 } else {
01160
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
01172 wpa_supplicant_process_smk_error(sm, src_addr, key, extra_len);
01173 } else if (key_info & WPA_KEY_INFO_ACK) {
01174
01175 wpa_supplicant_process_smk_m2(sm, src_addr, key, extra_len,
01176 ver);
01177 } else {
01178
01179 wpa_supplicant_process_smk_m45(sm, src_addr, key, extra_len,
01180 ver);
01181 }
01182 }
01183
01184 #endif