00001
00016 #include "includes.h"
00017
00018 #ifdef CONFIG_PEERKEY
00019
00020 #include "common.h"
00021 #include "sha1.h"
00022 #include "sha256.h"
00023 #include "eloop.h"
00024 #include "wpa.h"
00025 #include "wpa_i.h"
00026 #include "wpa_ie.h"
00027 #include "ieee802_11_defs.h"
00028 #include "peerkey.h"
00029
00030
00031 static u8 * wpa_add_ie(u8 *pos, const u8 *ie, size_t ie_len)
00032 {
00033 os_memcpy(pos, ie, ie_len);
00034 return pos + ie_len;
00035 }
00036
00037
00038 static u8 * wpa_add_kde(u8 *pos, u32 kde, const u8 *data, size_t data_len)
00039 {
00040 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
00041 *pos++ = RSN_SELECTOR_LEN + data_len;
00042 RSN_SELECTOR_PUT(pos, kde);
00043 pos += RSN_SELECTOR_LEN;
00044 os_memcpy(pos, data, data_len);
00045 pos += data_len;
00046 return pos;
00047 }
00048
00049
00050 static void wpa_supplicant_smk_timeout(void *eloop_ctx, void *timeout_ctx)
00051 {
00052 #if 0
00053 struct wpa_sm *sm = eloop_ctx;
00054 struct wpa_peerkey *peerkey = timeout_ctx;
00055 #endif
00056
00057 }
00058
00059
00060 static void wpa_supplicant_peerkey_free(struct wpa_sm *sm,
00061 struct wpa_peerkey *peerkey)
00062 {
00063 eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey);
00064 os_free(peerkey);
00065 }
00066
00067
00068 static int wpa_supplicant_send_smk_error(struct wpa_sm *sm, const u8 *dst,
00069 const u8 *peer,
00070 u16 mui, u16 error_type, int ver)
00071 {
00072 size_t rlen;
00073 struct wpa_eapol_key *err;
00074 struct rsn_error_kde error;
00075 u8 *rbuf, *pos;
00076 size_t kde_len;
00077 u16 key_info;
00078
00079 kde_len = 2 + RSN_SELECTOR_LEN + sizeof(error);
00080 if (peer)
00081 kde_len += 2 + RSN_SELECTOR_LEN + ETH_ALEN;
00082
00083 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
00084 NULL, sizeof(*err) + kde_len, &rlen,
00085 (void *) &err);
00086 if (rbuf == NULL)
00087 return -1;
00088
00089 err->type = EAPOL_KEY_TYPE_RSN;
00090 key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
00091 WPA_KEY_INFO_SECURE | WPA_KEY_INFO_ERROR |
00092 WPA_KEY_INFO_REQUEST;
00093 WPA_PUT_BE16(err->key_info, key_info);
00094 WPA_PUT_BE16(err->key_length, 0);
00095 os_memcpy(err->replay_counter, sm->request_counter,
00096 WPA_REPLAY_COUNTER_LEN);
00097 inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
00098
00099 WPA_PUT_BE16(err->key_data_length, (u16) kde_len);
00100 pos = (u8 *) (err + 1);
00101
00102 if (peer) {
00103
00104 pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN);
00105 }
00106
00107
00108 error.mui = host_to_be16(mui);
00109 error.error_type = host_to_be16(error_type);
00110 wpa_add_kde(pos, RSN_KEY_DATA_ERROR, (u8 *) &error, sizeof(error));
00111
00112 if (peer) {
00113 wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK Error (peer "
00114 MACSTR " mui %d error_type %d)",
00115 MAC2STR(peer), mui, error_type);
00116 } else {
00117 wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK Error "
00118 "(mui %d error_type %d)", mui, error_type);
00119 }
00120
00121 wpa_eapol_key_send(sm, sm->ptk.kck, ver, dst, ETH_P_EAPOL,
00122 rbuf, rlen, err->key_mic);
00123
00124 return 0;
00125 }
00126
00127
00128 static int wpa_supplicant_send_smk_m3(struct wpa_sm *sm,
00129 const unsigned char *src_addr,
00130 const struct wpa_eapol_key *key,
00131 int ver, struct wpa_peerkey *peerkey)
00132 {
00133 size_t rlen;
00134 struct wpa_eapol_key *reply;
00135 u8 *rbuf, *pos;
00136 size_t kde_len;
00137 u16 key_info;
00138
00139
00140 kde_len = peerkey->rsnie_p_len +
00141 2 + RSN_SELECTOR_LEN + ETH_ALEN +
00142 2 + RSN_SELECTOR_LEN + WPA_NONCE_LEN;
00143
00144 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
00145 NULL, sizeof(*reply) + kde_len, &rlen,
00146 (void *) &reply);
00147 if (rbuf == NULL)
00148 return -1;
00149
00150 reply->type = EAPOL_KEY_TYPE_RSN;
00151 key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
00152 WPA_KEY_INFO_SECURE;
00153 WPA_PUT_BE16(reply->key_info, key_info);
00154 WPA_PUT_BE16(reply->key_length, 0);
00155 os_memcpy(reply->replay_counter, key->replay_counter,
00156 WPA_REPLAY_COUNTER_LEN);
00157
00158 os_memcpy(reply->key_nonce, peerkey->pnonce, WPA_NONCE_LEN);
00159
00160 WPA_PUT_BE16(reply->key_data_length, (u16) kde_len);
00161 pos = (u8 *) (reply + 1);
00162
00163
00164 pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len);
00165
00166
00167 pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peerkey->addr, ETH_ALEN);
00168
00169
00170 wpa_add_kde(pos, RSN_KEY_DATA_NONCE, peerkey->inonce, WPA_NONCE_LEN);
00171
00172 wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK M3");
00173 wpa_eapol_key_send(sm, sm->ptk.kck, ver, src_addr, ETH_P_EAPOL,
00174 rbuf, rlen, reply->key_mic);
00175
00176 return 0;
00177 }
00178
00179
00180 static int wpa_supplicant_process_smk_m2(
00181 struct wpa_sm *sm, const unsigned char *src_addr,
00182 const struct wpa_eapol_key *key, size_t extra_len, int ver)
00183 {
00184 struct wpa_peerkey *peerkey;
00185 struct wpa_eapol_ie_parse kde;
00186 struct wpa_ie_data ie;
00187 int cipher;
00188 struct rsn_ie_hdr *hdr;
00189 u8 *pos;
00190
00191 wpa_printf(MSG_DEBUG, "RSN: Received SMK M2");
00192
00193 if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {
00194 wpa_printf(MSG_INFO, "RSN: SMK handshake not allowed for "
00195 "the current network");
00196 return -1;
00197 }
00198
00199 if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <
00200 0) {
00201 wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M2");
00202 return -1;
00203 }
00204
00205 if (kde.rsn_ie == NULL || kde.mac_addr == NULL ||
00206 kde.mac_addr_len < ETH_ALEN) {
00207 wpa_printf(MSG_INFO, "RSN: No RSN IE or MAC address KDE in "
00208 "SMK M2");
00209 return -1;
00210 }
00211
00212 wpa_printf(MSG_DEBUG, "RSN: SMK M2 - SMK initiator " MACSTR,
00213 MAC2STR(kde.mac_addr));
00214
00215 if (kde.rsn_ie_len > PEERKEY_MAX_IE_LEN) {
00216 wpa_printf(MSG_INFO, "RSN: Too long Initiator RSN IE in SMK "
00217 "M2");
00218 return -1;
00219 }
00220
00221 if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) {
00222 wpa_printf(MSG_INFO, "RSN: Failed to parse RSN IE in SMK M2");
00223 return -1;
00224 }
00225
00226 cipher = ie.pairwise_cipher & sm->allowed_pairwise_cipher;
00227 if (cipher & WPA_CIPHER_CCMP) {
00228 wpa_printf(MSG_DEBUG, "RSN: Using CCMP for PeerKey");
00229 cipher = WPA_CIPHER_CCMP;
00230 } else if (cipher & WPA_CIPHER_TKIP) {
00231 wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey");
00232 cipher = WPA_CIPHER_TKIP;
00233 } else {
00234 wpa_printf(MSG_INFO, "RSN: No acceptable cipher in SMK M2");
00235 wpa_supplicant_send_smk_error(sm, src_addr, kde.mac_addr,
00236 STK_MUI_SMK, STK_ERR_CPHR_NS,
00237 ver);
00238 return -1;
00239 }
00240
00241
00242
00243
00244 peerkey = os_zalloc(sizeof(*peerkey));
00245 if (peerkey == NULL)
00246 return -1;
00247 os_memcpy(peerkey->addr, kde.mac_addr, ETH_ALEN);
00248 os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN);
00249 os_memcpy(peerkey->rsnie_i, kde.rsn_ie, kde.rsn_ie_len);
00250 peerkey->rsnie_i_len = kde.rsn_ie_len;
00251 peerkey->cipher = cipher;
00252 #ifdef CONFIG_IEEE80211W
00253 if (ie.key_mgmt & (WPA_KEY_MGMT_IEEE8021X_SHA256 |
00254 WPA_KEY_MGMT_PSK_SHA256))
00255 peerkey->use_sha256 = 1;
00256 #endif
00257
00258 if (os_get_random(peerkey->pnonce, WPA_NONCE_LEN)) {
00259 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
00260 "WPA: Failed to get random data for PNonce");
00261 wpa_supplicant_peerkey_free(sm, peerkey);
00262 return -1;
00263 }
00264
00265 hdr = (struct rsn_ie_hdr *) peerkey->rsnie_p;
00266 hdr->elem_id = WLAN_EID_RSN;
00267 WPA_PUT_LE16(hdr->version, RSN_VERSION);
00268 pos = (u8 *) (hdr + 1);
00269
00270
00271 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
00272 pos += RSN_SELECTOR_LEN;
00273
00274 WPA_PUT_LE16(pos, 1);
00275 pos += 2;
00276 if (cipher == WPA_CIPHER_CCMP)
00277 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
00278 else if (cipher == WPA_CIPHER_TKIP)
00279 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
00280 pos += RSN_SELECTOR_LEN;
00281
00282 hdr->len = (pos - peerkey->rsnie_p) - 2;
00283 peerkey->rsnie_p_len = pos - peerkey->rsnie_p;
00284 wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake",
00285 peerkey->rsnie_p, peerkey->rsnie_p_len);
00286
00287 wpa_supplicant_send_smk_m3(sm, src_addr, key, ver, peerkey);
00288
00289 peerkey->next = sm->peerkey;
00290 sm->peerkey = peerkey;
00291
00292 return 0;
00293 }
00294
00295
00309 static void rsn_smkid(const u8 *smk, const u8 *pnonce, const u8 *mac_p,
00310 const u8 *inonce, const u8 *mac_i, u8 *smkid,
00311 int use_sha256)
00312 {
00313 char *title = "SMK Name";
00314 const u8 *addr[5];
00315 const size_t len[5] = { 8, WPA_NONCE_LEN, ETH_ALEN, WPA_NONCE_LEN,
00316 ETH_ALEN };
00317 unsigned char hash[SHA256_MAC_LEN];
00318
00319 addr[0] = (u8 *) title;
00320 addr[1] = pnonce;
00321 addr[2] = mac_p;
00322 addr[3] = inonce;
00323 addr[4] = mac_i;
00324
00325 #ifdef CONFIG_IEEE80211W
00326 if (use_sha256)
00327 hmac_sha256_vector(smk, PMK_LEN, 5, addr, len, hash);
00328 else
00329 #endif
00330 hmac_sha1_vector(smk, PMK_LEN, 5, addr, len, hash);
00331 os_memcpy(smkid, hash, PMKID_LEN);
00332 }
00333
00334
00335 static void wpa_supplicant_send_stk_1_of_4(struct wpa_sm *sm,
00336 struct wpa_peerkey *peerkey)
00337 {
00338 size_t mlen;
00339 struct wpa_eapol_key *msg;
00340 u8 *mbuf;
00341 size_t kde_len;
00342 u16 key_info, ver;
00343
00344 kde_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN;
00345
00346 mbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
00347 sizeof(*msg) + kde_len, &mlen,
00348 (void *) &msg);
00349 if (mbuf == NULL)
00350 return;
00351
00352 msg->type = EAPOL_KEY_TYPE_RSN;
00353
00354 if (peerkey->cipher == WPA_CIPHER_CCMP)
00355 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
00356 else
00357 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
00358
00359 key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK;
00360 WPA_PUT_BE16(msg->key_info, key_info);
00361
00362 if (peerkey->cipher == WPA_CIPHER_CCMP)
00363 WPA_PUT_BE16(msg->key_length, 16);
00364 else
00365 WPA_PUT_BE16(msg->key_length, 32);
00366
00367 os_memcpy(msg->replay_counter, peerkey->replay_counter,
00368 WPA_REPLAY_COUNTER_LEN);
00369 inc_byte_array(peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN);
00370
00371 WPA_PUT_BE16(msg->key_data_length, kde_len);
00372 wpa_add_kde((u8 *) (msg + 1), RSN_KEY_DATA_PMKID,
00373 peerkey->smkid, PMKID_LEN);
00374
00375 if (os_get_random(peerkey->inonce, WPA_NONCE_LEN)) {
00376 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
00377 "RSN: Failed to get random data for INonce (STK)");
00378 os_free(mbuf);
00379 return;
00380 }
00381 wpa_hexdump(MSG_DEBUG, "RSN: INonce for STK 4-Way Handshake",
00382 peerkey->inonce, WPA_NONCE_LEN);
00383 os_memcpy(msg->key_nonce, peerkey->inonce, WPA_NONCE_LEN);
00384
00385 wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 1/4 to " MACSTR,
00386 MAC2STR(peerkey->addr));
00387 wpa_eapol_key_send(sm, NULL, ver, peerkey->addr, ETH_P_EAPOL,
00388 mbuf, mlen, NULL);
00389 }
00390
00391
00392 static void wpa_supplicant_send_stk_3_of_4(struct wpa_sm *sm,
00393 struct wpa_peerkey *peerkey)
00394 {
00395 size_t mlen;
00396 struct wpa_eapol_key *msg;
00397 u8 *mbuf, *pos;
00398 size_t kde_len;
00399 u16 key_info, ver;
00400 be32 lifetime;
00401
00402 kde_len = peerkey->rsnie_i_len +
00403 2 + RSN_SELECTOR_LEN + sizeof(lifetime);
00404
00405 mbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
00406 sizeof(*msg) + kde_len, &mlen,
00407 (void *) &msg);
00408 if (mbuf == NULL)
00409 return;
00410
00411 msg->type = EAPOL_KEY_TYPE_RSN;
00412
00413 if (peerkey->cipher == WPA_CIPHER_CCMP)
00414 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
00415 else
00416 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
00417
00418 key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK |
00419 WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE;
00420 WPA_PUT_BE16(msg->key_info, key_info);
00421
00422 if (peerkey->cipher == WPA_CIPHER_CCMP)
00423 WPA_PUT_BE16(msg->key_length, 16);
00424 else
00425 WPA_PUT_BE16(msg->key_length, 32);
00426
00427 os_memcpy(msg->replay_counter, peerkey->replay_counter,
00428 WPA_REPLAY_COUNTER_LEN);
00429 inc_byte_array(peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN);
00430
00431 WPA_PUT_BE16(msg->key_data_length, kde_len);
00432 pos = (u8 *) (msg + 1);
00433 pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len);
00434 lifetime = host_to_be32(peerkey->lifetime);
00435 wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,
00436 (u8 *) &lifetime, sizeof(lifetime));
00437
00438 os_memcpy(msg->key_nonce, peerkey->inonce, WPA_NONCE_LEN);
00439
00440 wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 3/4 to " MACSTR,
00441 MAC2STR(peerkey->addr));
00442 wpa_eapol_key_send(sm, peerkey->stk.kck, ver, peerkey->addr,
00443 ETH_P_EAPOL, mbuf, mlen, msg->key_mic);
00444 }
00445
00446
00447 static int wpa_supplicant_process_smk_m4(struct wpa_peerkey *peerkey,
00448 struct wpa_eapol_ie_parse *kde)
00449 {
00450 wpa_printf(MSG_DEBUG, "RSN: Received SMK M4 (Initiator " MACSTR ")",
00451 MAC2STR(kde->mac_addr));
00452
00453 if (os_memcmp(kde->smk + PMK_LEN, peerkey->pnonce, WPA_NONCE_LEN) != 0)
00454 {
00455 wpa_printf(MSG_INFO, "RSN: PNonce in SMK KDE does not "
00456 "match with the one used in SMK M3");
00457 return -1;
00458 }
00459
00460 if (os_memcmp(kde->nonce, peerkey->inonce, WPA_NONCE_LEN) != 0) {
00461 wpa_printf(MSG_INFO, "RSN: INonce in SMK M4 did not "
00462 "match with the one received in SMK M2");
00463 return -1;
00464 }
00465
00466 return 0;
00467 }
00468
00469
00470 static int wpa_supplicant_process_smk_m5(struct wpa_sm *sm,
00471 const unsigned char *src_addr,
00472 const struct wpa_eapol_key *key,
00473 int ver,
00474 struct wpa_peerkey *peerkey,
00475 struct wpa_eapol_ie_parse *kde)
00476 {
00477 int cipher;
00478 struct wpa_ie_data ie;
00479
00480 wpa_printf(MSG_DEBUG, "RSN: Received SMK M5 (Peer " MACSTR ")",
00481 MAC2STR(kde->mac_addr));
00482 if (kde->rsn_ie == NULL || kde->rsn_ie_len > PEERKEY_MAX_IE_LEN ||
00483 wpa_parse_wpa_ie_rsn(kde->rsn_ie, kde->rsn_ie_len, &ie) < 0) {
00484 wpa_printf(MSG_INFO, "RSN: No RSN IE in SMK M5");
00485
00486 return -1;
00487 }
00488
00489 if (os_memcmp(key->key_nonce, peerkey->inonce, WPA_NONCE_LEN) != 0) {
00490 wpa_printf(MSG_INFO, "RSN: Key Nonce in SMK M5 does "
00491 "not match with INonce used in SMK M1");
00492 return -1;
00493 }
00494
00495 if (os_memcmp(kde->smk + PMK_LEN, peerkey->inonce, WPA_NONCE_LEN) != 0)
00496 {
00497 wpa_printf(MSG_INFO, "RSN: INonce in SMK KDE does not "
00498 "match with the one used in SMK M1");
00499 return -1;
00500 }
00501
00502 os_memcpy(peerkey->rsnie_p, kde->rsn_ie, kde->rsn_ie_len);
00503 peerkey->rsnie_p_len = kde->rsn_ie_len;
00504 os_memcpy(peerkey->pnonce, kde->nonce, WPA_NONCE_LEN);
00505
00506 cipher = ie.pairwise_cipher & sm->allowed_pairwise_cipher;
00507 if (cipher & WPA_CIPHER_CCMP) {
00508 wpa_printf(MSG_DEBUG, "RSN: Using CCMP for PeerKey");
00509 peerkey->cipher = WPA_CIPHER_CCMP;
00510 } else if (cipher & WPA_CIPHER_TKIP) {
00511 wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey");
00512 peerkey->cipher = WPA_CIPHER_TKIP;
00513 } else {
00514 wpa_printf(MSG_INFO, "RSN: SMK Peer STA " MACSTR " selected "
00515 "unacceptable cipher", MAC2STR(kde->mac_addr));
00516 wpa_supplicant_send_smk_error(sm, src_addr, kde->mac_addr,
00517 STK_MUI_SMK, STK_ERR_CPHR_NS,
00518 ver);
00519
00520 return -1;
00521 }
00522
00523 return 0;
00524 }
00525
00526
00527 static int wpa_supplicant_process_smk_m45(
00528 struct wpa_sm *sm, const unsigned char *src_addr,
00529 const struct wpa_eapol_key *key, size_t extra_len, int ver)
00530 {
00531 struct wpa_peerkey *peerkey;
00532 struct wpa_eapol_ie_parse kde;
00533 u32 lifetime;
00534 struct os_time now;
00535
00536 if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {
00537 wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for "
00538 "the current network");
00539 return -1;
00540 }
00541
00542 if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <
00543 0) {
00544 wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M4/M5");
00545 return -1;
00546 }
00547
00548 if (kde.mac_addr == NULL || kde.mac_addr_len < ETH_ALEN ||
00549 kde.nonce == NULL || kde.nonce_len < WPA_NONCE_LEN ||
00550 kde.smk == NULL || kde.smk_len < PMK_LEN + WPA_NONCE_LEN ||
00551 kde.lifetime == NULL || kde.lifetime_len < 4) {
00552 wpa_printf(MSG_INFO, "RSN: No MAC Address, Nonce, SMK, or "
00553 "Lifetime KDE in SMK M4/M5");
00554 return -1;
00555 }
00556
00557 for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
00558 if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) == 0 &&
00559 os_memcmp(peerkey->initiator ? peerkey->inonce :
00560 peerkey->pnonce,
00561 key->key_nonce, WPA_NONCE_LEN) == 0)
00562 break;
00563 }
00564 if (peerkey == NULL) {
00565 wpa_printf(MSG_INFO, "RSN: No matching SMK handshake found "
00566 "for SMK M4/M5: peer " MACSTR,
00567 MAC2STR(kde.mac_addr));
00568 return -1;
00569 }
00570
00571 if (peerkey->initiator) {
00572 if (wpa_supplicant_process_smk_m5(sm, src_addr, key, ver,
00573 peerkey, &kde) < 0)
00574 return -1;
00575 } else {
00576 if (wpa_supplicant_process_smk_m4(peerkey, &kde) < 0)
00577 return -1;
00578 }
00579
00580 os_memcpy(peerkey->smk, kde.smk, PMK_LEN);
00581 peerkey->smk_complete = 1;
00582 wpa_hexdump_key(MSG_DEBUG, "RSN: SMK", peerkey->smk, PMK_LEN);
00583 lifetime = WPA_GET_BE32(kde.lifetime);
00584 wpa_printf(MSG_DEBUG, "RSN: SMK lifetime %u seconds", lifetime);
00585 if (lifetime > 1000000000)
00586 lifetime = 1000000000;
00587 peerkey->lifetime = lifetime;
00588 os_get_time(&now);
00589 peerkey->expiration = now.sec + lifetime;
00590 eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout,
00591 sm, peerkey);
00592
00593 if (peerkey->initiator) {
00594 rsn_smkid(peerkey->smk, peerkey->pnonce, peerkey->addr,
00595 peerkey->inonce, sm->own_addr, peerkey->smkid,
00596 peerkey->use_sha256);
00597 wpa_supplicant_send_stk_1_of_4(sm, peerkey);
00598 } else {
00599 rsn_smkid(peerkey->smk, peerkey->pnonce, sm->own_addr,
00600 peerkey->inonce, peerkey->addr, peerkey->smkid,
00601 peerkey->use_sha256);
00602 }
00603 wpa_hexdump(MSG_DEBUG, "RSN: SMKID", peerkey->smkid, PMKID_LEN);
00604
00605 return 0;
00606 }
00607
00608
00609 static int wpa_supplicant_process_smk_error(
00610 struct wpa_sm *sm, const unsigned char *src_addr,
00611 const struct wpa_eapol_key *key, size_t extra_len)
00612 {
00613 struct wpa_eapol_ie_parse kde;
00614 struct rsn_error_kde error;
00615 u8 peer[ETH_ALEN];
00616 u16 error_type;
00617
00618 wpa_printf(MSG_DEBUG, "RSN: Received SMK Error");
00619
00620 if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {
00621 wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for "
00622 "the current network");
00623 return -1;
00624 }
00625
00626 if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <
00627 0) {
00628 wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK Error");
00629 return -1;
00630 }
00631
00632 if (kde.error == NULL || kde.error_len < sizeof(error)) {
00633 wpa_printf(MSG_INFO, "RSN: No Error KDE in SMK Error");
00634 return -1;
00635 }
00636
00637 if (kde.mac_addr && kde.mac_addr_len >= ETH_ALEN)
00638 os_memcpy(peer, kde.mac_addr, 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
00936 int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
00937 struct wpa_peerkey *peerkey,
00938 struct wpa_eapol_key *key, u16 ver,
00939 const u8 *buf, size_t len)
00940 {
00941 u8 mic[16];
00942 int ok = 0;
00943
00944 if (peerkey->initiator && !peerkey->stk_set) {
00945 wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion",
00946 sm->own_addr, peerkey->addr,
00947 peerkey->inonce, key->key_nonce,
00948 (u8 *) &peerkey->stk, sizeof(peerkey->stk),
00949 peerkey->use_sha256);
00950 peerkey->stk_set = 1;
00951 }
00952
00953 os_memcpy(mic, key->key_mic, 16);
00954 if (peerkey->tstk_set) {
00955 os_memset(key->key_mic, 0, 16);
00956 wpa_eapol_key_mic(peerkey->tstk.kck, ver, buf, len,
00957 key->key_mic);
00958 if (os_memcmp(mic, key->key_mic, 16) != 0) {
00959 wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
00960 "when using TSTK - ignoring TSTK");
00961 } else {
00962 ok = 1;
00963 peerkey->tstk_set = 0;
00964 peerkey->stk_set = 1;
00965 os_memcpy(&peerkey->stk, &peerkey->tstk,
00966 sizeof(peerkey->stk));
00967 }
00968 }
00969
00970 if (!ok && peerkey->stk_set) {
00971 os_memset(key->key_mic, 0, 16);
00972 wpa_eapol_key_mic(peerkey->stk.kck, ver, buf, len,
00973 key->key_mic);
00974 if (os_memcmp(mic, key->key_mic, 16) != 0) {
00975 wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
00976 "- dropping packet");
00977 return -1;
00978 }
00979 ok = 1;
00980 }
00981
00982 if (!ok) {
00983 wpa_printf(MSG_WARNING, "RSN: Could not verify EAPOL-Key MIC "
00984 "- dropping packet");
00985 return -1;
00986 }
00987
00988 os_memcpy(peerkey->replay_counter, key->replay_counter,
00989 WPA_REPLAY_COUNTER_LEN);
00990 peerkey->replay_counter_set = 1;
00991 return 0;
00992 }
00993
00994
01005 int wpa_sm_stkstart(struct wpa_sm *sm, const u8 *peer)
01006 {
01007 size_t rlen, kde_len;
01008 struct wpa_eapol_key *req;
01009 int key_info, ver;
01010 u8 bssid[ETH_ALEN], *rbuf, *pos, *count_pos;
01011 u16 count;
01012 struct rsn_ie_hdr *hdr;
01013 struct wpa_peerkey *peerkey;
01014 struct wpa_ie_data ie;
01015
01016 if (sm->proto != WPA_PROTO_RSN || !sm->ptk_set || !sm->peerkey_enabled)
01017 return -1;
01018
01019 if (sm->ap_rsn_ie &&
01020 wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &ie) == 0 &&
01021 !(ie.capabilities & WPA_CAPABILITY_PEERKEY_ENABLED)) {
01022 wpa_printf(MSG_DEBUG, "RSN: Current AP does not support STK");
01023 return -1;
01024 }
01025
01026 if (sm->pairwise_cipher == WPA_CIPHER_CCMP)
01027 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
01028 else
01029 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
01030
01031 if (wpa_sm_get_bssid(sm, bssid) < 0) {
01032 wpa_printf(MSG_WARNING, "Failed to read BSSID for EAPOL-Key "
01033 "SMK M1");
01034 return -1;
01035 }
01036
01037
01038
01039 peerkey = os_zalloc(sizeof(*peerkey));
01040 if (peerkey == NULL)
01041 return -1;
01042 peerkey->initiator = 1;
01043 os_memcpy(peerkey->addr, peer, ETH_ALEN);
01044 #ifdef CONFIG_IEEE80211W
01045 if (wpa_key_mgmt_sha256(sm->key_mgmt))
01046 peerkey->use_sha256 = 1;
01047 #endif
01048
01049
01050
01051
01052
01053
01054 hdr = (struct rsn_ie_hdr *) peerkey->rsnie_i;
01055 hdr->elem_id = WLAN_EID_RSN;
01056 WPA_PUT_LE16(hdr->version, RSN_VERSION);
01057 pos = (u8 *) (hdr + 1);
01058
01059
01060 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
01061 pos += RSN_SELECTOR_LEN;
01062 count_pos = pos;
01063 pos += 2;
01064
01065 count = 0;
01066 if (sm->allowed_pairwise_cipher & WPA_CIPHER_CCMP) {
01067 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
01068 pos += RSN_SELECTOR_LEN;
01069 count++;
01070 }
01071 if (sm->allowed_pairwise_cipher & WPA_CIPHER_TKIP) {
01072 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
01073 pos += RSN_SELECTOR_LEN;
01074 count++;
01075 }
01076 WPA_PUT_LE16(count_pos, count);
01077
01078 hdr->len = (pos - peerkey->rsnie_i) - 2;
01079 peerkey->rsnie_i_len = pos - peerkey->rsnie_i;
01080 wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake",
01081 peerkey->rsnie_i, peerkey->rsnie_i_len);
01082
01083 kde_len = peerkey->rsnie_i_len + 2 + RSN_SELECTOR_LEN + ETH_ALEN;
01084
01085 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
01086 sizeof(*req) + kde_len, &rlen,
01087 (void *) &req);
01088 if (rbuf == NULL) {
01089 wpa_supplicant_peerkey_free(sm, peerkey);
01090 return -1;
01091 }
01092
01093 req->type = EAPOL_KEY_TYPE_RSN;
01094 key_info = WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
01095 WPA_KEY_INFO_SECURE | WPA_KEY_INFO_REQUEST | ver;
01096 WPA_PUT_BE16(req->key_info, key_info);
01097 WPA_PUT_BE16(req->key_length, 0);
01098 os_memcpy(req->replay_counter, sm->request_counter,
01099 WPA_REPLAY_COUNTER_LEN);
01100 inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
01101
01102 if (os_get_random(peerkey->inonce, WPA_NONCE_LEN)) {
01103 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
01104 "WPA: Failed to get random data for INonce");
01105 os_free(rbuf);
01106 wpa_supplicant_peerkey_free(sm, peerkey);
01107 return -1;
01108 }
01109 os_memcpy(req->key_nonce, peerkey->inonce, WPA_NONCE_LEN);
01110 wpa_hexdump(MSG_DEBUG, "WPA: INonce for SMK handshake",
01111 req->key_nonce, WPA_NONCE_LEN);
01112
01113 WPA_PUT_BE16(req->key_data_length, (u16) kde_len);
01114 pos = (u8 *) (req + 1);
01115
01116
01117 pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len);
01118
01119 wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN);
01120
01121 wpa_printf(MSG_INFO, "RSN: Sending EAPOL-Key SMK M1 Request (peer "
01122 MACSTR ")", MAC2STR(peer));
01123 wpa_eapol_key_send(sm, sm->ptk.kck, ver, bssid, ETH_P_EAPOL,
01124 rbuf, rlen, req->key_mic);
01125
01126 peerkey->next = sm->peerkey;
01127 sm->peerkey = peerkey;
01128
01129 return 0;
01130 }
01131
01132
01138 void peerkey_deinit(struct wpa_sm *sm)
01139 {
01140 struct wpa_peerkey *prev, *peerkey = sm->peerkey;
01141 while (peerkey) {
01142 prev = peerkey;
01143 peerkey = peerkey->next;
01144 os_free(prev);
01145 }
01146 }
01147
01148
01149 void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey,
01150 struct wpa_eapol_key *key, u16 key_info, u16 ver)
01151 {
01152 if ((key_info & (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) ==
01153 (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) {
01154
01155 wpa_supplicant_process_stk_3_of_4(sm, peerkey, key, ver);
01156 } else if (key_info & WPA_KEY_INFO_ACK) {
01157
01158 wpa_supplicant_process_stk_1_of_4(sm, peerkey, key, ver);
01159 } else if (key_info & WPA_KEY_INFO_SECURE) {
01160
01161 wpa_supplicant_process_stk_4_of_4(sm, peerkey, key, ver);
01162 } else {
01163
01164 wpa_supplicant_process_stk_2_of_4(sm, peerkey, key, ver);
01165 }
01166 }
01167
01168
01169 void peerkey_rx_eapol_smk(struct wpa_sm *sm, const u8 *src_addr,
01170 struct wpa_eapol_key *key, size_t extra_len,
01171 u16 key_info, u16 ver)
01172 {
01173 if (key_info & WPA_KEY_INFO_ERROR) {
01174
01175 wpa_supplicant_process_smk_error(sm, src_addr, key, extra_len);
01176 } else if (key_info & WPA_KEY_INFO_ACK) {
01177
01178 wpa_supplicant_process_smk_m2(sm, src_addr, key, extra_len,
01179 ver);
01180 } else {
01181
01182 wpa_supplicant_process_smk_m45(sm, src_addr, key, extra_len,
01183 ver);
01184 }
01185 }
01186
01187 #endif
01188