OSDN Git Service

am 61d9df3e: wpa_supplicant: Update to 29-Aug-2012 TOT
[android-x86/external-wpa_supplicant_8.git] / src / rsn_supp / peerkey.c
1 /*
2  * WPA Supplicant - PeerKey for Direct Link Setup (DLS)
3  * Copyright (c) 2006-2008, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8
9 #include "includes.h"
10
11 #ifdef CONFIG_PEERKEY
12
13 #include "common.h"
14 #include "eloop.h"
15 #include "crypto/sha1.h"
16 #include "crypto/sha256.h"
17 #include "crypto/random.h"
18 #include "common/ieee802_11_defs.h"
19 #include "wpa.h"
20 #include "wpa_i.h"
21 #include "wpa_ie.h"
22 #include "peerkey.h"
23
24
25 static u8 * wpa_add_ie(u8 *pos, const u8 *ie, size_t ie_len)
26 {
27         os_memcpy(pos, ie, ie_len);
28         return pos + ie_len;
29 }
30
31
32 static u8 * wpa_add_kde(u8 *pos, u32 kde, const u8 *data, size_t data_len)
33 {
34         *pos++ = WLAN_EID_VENDOR_SPECIFIC;
35         *pos++ = RSN_SELECTOR_LEN + data_len;
36         RSN_SELECTOR_PUT(pos, kde);
37         pos += RSN_SELECTOR_LEN;
38         os_memcpy(pos, data, data_len);
39         pos += data_len;
40         return pos;
41 }
42
43
44 static void wpa_supplicant_smk_timeout(void *eloop_ctx, void *timeout_ctx)
45 {
46 #if 0
47         struct wpa_sm *sm = eloop_ctx;
48         struct wpa_peerkey *peerkey = timeout_ctx;
49 #endif
50         /* TODO: time out SMK and any STK that was generated using this SMK */
51 }
52
53
54 static void wpa_supplicant_peerkey_free(struct wpa_sm *sm,
55                                         struct wpa_peerkey *peerkey)
56 {
57         eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey);
58         os_free(peerkey);
59 }
60
61
62 static int wpa_supplicant_send_smk_error(struct wpa_sm *sm, const u8 *dst,
63                                          const u8 *peer,
64                                          u16 mui, u16 error_type, int ver)
65 {
66         size_t rlen;
67         struct wpa_eapol_key *err;
68         struct rsn_error_kde error;
69         u8 *rbuf, *pos;
70         size_t kde_len;
71         u16 key_info;
72
73         kde_len = 2 + RSN_SELECTOR_LEN + sizeof(error);
74         if (peer)
75                 kde_len += 2 + RSN_SELECTOR_LEN + ETH_ALEN;
76
77         rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
78                                   NULL, sizeof(*err) + kde_len, &rlen,
79                                   (void *) &err);
80         if (rbuf == NULL)
81                 return -1;
82
83         err->type = EAPOL_KEY_TYPE_RSN;
84         key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
85                 WPA_KEY_INFO_SECURE | WPA_KEY_INFO_ERROR |
86                 WPA_KEY_INFO_REQUEST;
87         WPA_PUT_BE16(err->key_info, key_info);
88         WPA_PUT_BE16(err->key_length, 0);
89         os_memcpy(err->replay_counter, sm->request_counter,
90                   WPA_REPLAY_COUNTER_LEN);
91         inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
92
93         WPA_PUT_BE16(err->key_data_length, (u16) kde_len);
94         pos = (u8 *) (err + 1);
95
96         if (peer) {
97                 /* Peer MAC Address KDE */
98                 pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN);
99         }
100
101         /* Error KDE */
102         error.mui = host_to_be16(mui);
103         error.error_type = host_to_be16(error_type);
104         wpa_add_kde(pos, RSN_KEY_DATA_ERROR, (u8 *) &error, sizeof(error));
105
106         if (peer) {
107                 wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK Error (peer "
108                            MACSTR " mui %d error_type %d)",
109                            MAC2STR(peer), mui, error_type);
110         } else {
111                 wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK Error "
112                            "(mui %d error_type %d)", mui, error_type);
113         }
114
115         wpa_eapol_key_send(sm, sm->ptk.kck, ver, dst, ETH_P_EAPOL,
116                            rbuf, rlen, err->key_mic);
117
118         return 0;
119 }
120
121
122 static int wpa_supplicant_send_smk_m3(struct wpa_sm *sm,
123                                       const unsigned char *src_addr,
124                                       const struct wpa_eapol_key *key,
125                                       int ver, struct wpa_peerkey *peerkey)
126 {
127         size_t rlen;
128         struct wpa_eapol_key *reply;
129         u8 *rbuf, *pos;
130         size_t kde_len;
131         u16 key_info;
132
133         /* KDEs: Peer RSN IE, Initiator MAC Address, Initiator Nonce */
134         kde_len = peerkey->rsnie_p_len +
135                 2 + RSN_SELECTOR_LEN + ETH_ALEN +
136                 2 + RSN_SELECTOR_LEN + WPA_NONCE_LEN;
137
138         rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
139                                   NULL, sizeof(*reply) + kde_len, &rlen,
140                                   (void *) &reply);
141         if (rbuf == NULL)
142                 return -1;
143
144         reply->type = EAPOL_KEY_TYPE_RSN;
145         key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
146                 WPA_KEY_INFO_SECURE;
147         WPA_PUT_BE16(reply->key_info, key_info);
148         WPA_PUT_BE16(reply->key_length, 0);
149         os_memcpy(reply->replay_counter, key->replay_counter,
150                   WPA_REPLAY_COUNTER_LEN);
151
152         os_memcpy(reply->key_nonce, peerkey->pnonce, WPA_NONCE_LEN);
153
154         WPA_PUT_BE16(reply->key_data_length, (u16) kde_len);
155         pos = (u8 *) (reply + 1);
156
157         /* Peer RSN IE */
158         pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len);
159
160         /* Initiator MAC Address KDE */
161         pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peerkey->addr, ETH_ALEN);
162
163         /* Initiator Nonce */
164         wpa_add_kde(pos, RSN_KEY_DATA_NONCE, peerkey->inonce, WPA_NONCE_LEN);
165
166         wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK M3");
167         wpa_eapol_key_send(sm, sm->ptk.kck, ver, src_addr, ETH_P_EAPOL,
168                            rbuf, rlen, reply->key_mic);
169
170         return 0;
171 }
172
173
174 static int wpa_supplicant_process_smk_m2(
175         struct wpa_sm *sm, const unsigned char *src_addr,
176         const struct wpa_eapol_key *key, size_t extra_len, int ver)
177 {
178         struct wpa_peerkey *peerkey;
179         struct wpa_eapol_ie_parse kde;
180         struct wpa_ie_data ie;
181         int cipher;
182         struct rsn_ie_hdr *hdr;
183         u8 *pos;
184
185         wpa_printf(MSG_DEBUG, "RSN: Received SMK M2");
186
187         if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {
188                 wpa_printf(MSG_INFO, "RSN: SMK handshake not allowed for "
189                            "the current network");
190                 return -1;
191         }
192
193         if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <
194             0) {
195                 wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M2");
196                 return -1;
197         }
198
199         if (kde.rsn_ie == NULL || kde.mac_addr == NULL ||
200             kde.mac_addr_len < ETH_ALEN) {
201                 wpa_printf(MSG_INFO, "RSN: No RSN IE or MAC address KDE in "
202                            "SMK M2");
203                 return -1;
204         }
205
206         wpa_printf(MSG_DEBUG, "RSN: SMK M2 - SMK initiator " MACSTR,
207                    MAC2STR(kde.mac_addr));
208
209         if (kde.rsn_ie_len > PEERKEY_MAX_IE_LEN) {
210                 wpa_printf(MSG_INFO, "RSN: Too long Initiator RSN IE in SMK "
211                            "M2");
212                 return -1;
213         }
214
215         if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) {
216                 wpa_printf(MSG_INFO, "RSN: Failed to parse RSN IE in SMK M2");
217                 return -1;
218         }
219
220         cipher = ie.pairwise_cipher & sm->allowed_pairwise_cipher;
221         if (cipher & WPA_CIPHER_CCMP) {
222                 wpa_printf(MSG_DEBUG, "RSN: Using CCMP for PeerKey");
223                 cipher = WPA_CIPHER_CCMP;
224         } else if (cipher & WPA_CIPHER_GCMP) {
225                 wpa_printf(MSG_DEBUG, "RSN: Using GCMP for PeerKey");
226                 cipher = WPA_CIPHER_GCMP;
227         } else if (cipher & WPA_CIPHER_TKIP) {
228                 wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey");
229                 cipher = WPA_CIPHER_TKIP;
230         } else {
231                 wpa_printf(MSG_INFO, "RSN: No acceptable cipher in SMK M2");
232                 wpa_supplicant_send_smk_error(sm, src_addr, kde.mac_addr,
233                                               STK_MUI_SMK, STK_ERR_CPHR_NS,
234                                               ver);
235                 return -1;
236         }
237
238         /* TODO: find existing entry and if found, use that instead of adding
239          * a new one; how to handle the case where both ends initiate at the
240          * same time? */
241         peerkey = os_zalloc(sizeof(*peerkey));
242         if (peerkey == NULL)
243                 return -1;
244         os_memcpy(peerkey->addr, kde.mac_addr, ETH_ALEN);
245         os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN);
246         os_memcpy(peerkey->rsnie_i, kde.rsn_ie, kde.rsn_ie_len);
247         peerkey->rsnie_i_len = kde.rsn_ie_len;
248         peerkey->cipher = cipher;
249 #ifdef CONFIG_IEEE80211W
250         if (ie.key_mgmt & (WPA_KEY_MGMT_IEEE8021X_SHA256 |
251                            WPA_KEY_MGMT_PSK_SHA256))
252                 peerkey->use_sha256 = 1;
253 #endif /* CONFIG_IEEE80211W */
254
255         if (random_get_bytes(peerkey->pnonce, WPA_NONCE_LEN)) {
256                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
257                         "WPA: Failed to get random data for PNonce");
258                 wpa_supplicant_peerkey_free(sm, peerkey);
259                 return -1;
260         }
261
262         hdr = (struct rsn_ie_hdr *) peerkey->rsnie_p;
263         hdr->elem_id = WLAN_EID_RSN;
264         WPA_PUT_LE16(hdr->version, RSN_VERSION);
265         pos = (u8 *) (hdr + 1);
266         /* Group Suite can be anything for SMK RSN IE; receiver will just
267          * ignore it. */
268         RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
269         pos += RSN_SELECTOR_LEN;
270         /* Include only the selected cipher in pairwise cipher suite */
271         WPA_PUT_LE16(pos, 1);
272         pos += 2;
273         if (cipher == WPA_CIPHER_CCMP)
274                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
275         else if (cipher == WPA_CIPHER_GCMP)
276                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP);
277         else if (cipher == WPA_CIPHER_TKIP)
278                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
279         pos += RSN_SELECTOR_LEN;
280
281         hdr->len = (pos - peerkey->rsnie_p) - 2;
282         peerkey->rsnie_p_len = pos - peerkey->rsnie_p;
283         wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake",
284                     peerkey->rsnie_p, peerkey->rsnie_p_len);
285
286         wpa_supplicant_send_smk_m3(sm, src_addr, key, ver, peerkey);
287
288         peerkey->next = sm->peerkey;
289         sm->peerkey = peerkey;
290
291         return 0;
292 }
293
294
295 /**
296  * rsn_smkid - Derive SMK identifier
297  * @smk: Station master key (32 bytes)
298  * @pnonce: Peer Nonce
299  * @mac_p: Peer MAC address
300  * @inonce: Initiator Nonce
301  * @mac_i: Initiator MAC address
302  * @use_sha256: Whether to use SHA256-based KDF
303  *
304  * 8.5.1.4 Station to station (STK) key hierarchy
305  * SMKID = HMAC-SHA1-128(SMK, "SMK Name" || PNonce || MAC_P || INonce || MAC_I)
306  */
307 static void rsn_smkid(const u8 *smk, const u8 *pnonce, const u8 *mac_p,
308                       const u8 *inonce, const u8 *mac_i, u8 *smkid,
309                       int use_sha256)
310 {
311         char *title = "SMK Name";
312         const u8 *addr[5];
313         const size_t len[5] = { 8, WPA_NONCE_LEN, ETH_ALEN, WPA_NONCE_LEN,
314                                 ETH_ALEN };
315         unsigned char hash[SHA256_MAC_LEN];
316
317         addr[0] = (u8 *) title;
318         addr[1] = pnonce;
319         addr[2] = mac_p;
320         addr[3] = inonce;
321         addr[4] = mac_i;
322
323 #ifdef CONFIG_IEEE80211W
324         if (use_sha256)
325                 hmac_sha256_vector(smk, PMK_LEN, 5, addr, len, hash);
326         else
327 #endif /* CONFIG_IEEE80211W */
328                 hmac_sha1_vector(smk, PMK_LEN, 5, addr, len, hash);
329         os_memcpy(smkid, hash, PMKID_LEN);
330 }
331
332
333 static void wpa_supplicant_send_stk_1_of_4(struct wpa_sm *sm,
334                                            struct wpa_peerkey *peerkey)
335 {
336         size_t mlen;
337         struct wpa_eapol_key *msg;
338         u8 *mbuf;
339         size_t kde_len;
340         u16 key_info, ver;
341
342         kde_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN;
343
344         mbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
345                                   sizeof(*msg) + kde_len, &mlen,
346                                   (void *) &msg);
347         if (mbuf == NULL)
348                 return;
349
350         msg->type = EAPOL_KEY_TYPE_RSN;
351
352         if (peerkey->cipher != WPA_CIPHER_TKIP)
353                 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
354         else
355                 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
356
357         key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK;
358         WPA_PUT_BE16(msg->key_info, key_info);
359
360         if (peerkey->cipher != WPA_CIPHER_TKIP)
361                 WPA_PUT_BE16(msg->key_length, 16);
362         else
363                 WPA_PUT_BE16(msg->key_length, 32);
364
365         os_memcpy(msg->replay_counter, peerkey->replay_counter,
366                   WPA_REPLAY_COUNTER_LEN);
367         inc_byte_array(peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN);
368
369         WPA_PUT_BE16(msg->key_data_length, kde_len);
370         wpa_add_kde((u8 *) (msg + 1), RSN_KEY_DATA_PMKID,
371                     peerkey->smkid, PMKID_LEN);
372
373         if (random_get_bytes(peerkey->inonce, WPA_NONCE_LEN)) {
374                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
375                         "RSN: Failed to get random data for INonce (STK)");
376                 os_free(mbuf);
377                 return;
378         }
379         wpa_hexdump(MSG_DEBUG, "RSN: INonce for STK 4-Way Handshake",
380                     peerkey->inonce, WPA_NONCE_LEN);
381         os_memcpy(msg->key_nonce, peerkey->inonce, WPA_NONCE_LEN);
382
383         wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 1/4 to " MACSTR,
384                    MAC2STR(peerkey->addr));
385         wpa_eapol_key_send(sm, NULL, ver, peerkey->addr, ETH_P_EAPOL,
386                            mbuf, mlen, NULL);
387 }
388
389
390 static void wpa_supplicant_send_stk_3_of_4(struct wpa_sm *sm,
391                                            struct wpa_peerkey *peerkey)
392 {
393         size_t mlen;
394         struct wpa_eapol_key *msg;
395         u8 *mbuf, *pos;
396         size_t kde_len;
397         u16 key_info, ver;
398         be32 lifetime;
399
400         kde_len = peerkey->rsnie_i_len +
401                 2 + RSN_SELECTOR_LEN + sizeof(lifetime);
402
403         mbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
404                                   sizeof(*msg) + kde_len, &mlen,
405                                   (void *) &msg);
406         if (mbuf == NULL)
407                 return;
408
409         msg->type = EAPOL_KEY_TYPE_RSN;
410
411         if (peerkey->cipher != WPA_CIPHER_TKIP)
412                 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
413         else
414                 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
415
416         key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK |
417                 WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE;
418         WPA_PUT_BE16(msg->key_info, key_info);
419
420         if (peerkey->cipher != WPA_CIPHER_TKIP)
421                 WPA_PUT_BE16(msg->key_length, 16);
422         else
423                 WPA_PUT_BE16(msg->key_length, 32);
424
425         os_memcpy(msg->replay_counter, peerkey->replay_counter,
426                   WPA_REPLAY_COUNTER_LEN);
427         inc_byte_array(peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN);
428
429         WPA_PUT_BE16(msg->key_data_length, kde_len);
430         pos = (u8 *) (msg + 1);
431         pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len);
432         lifetime = host_to_be32(peerkey->lifetime);
433         wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,
434                     (u8 *) &lifetime, sizeof(lifetime));
435
436         os_memcpy(msg->key_nonce, peerkey->inonce, WPA_NONCE_LEN);
437
438         wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 3/4 to " MACSTR,
439                    MAC2STR(peerkey->addr));
440         wpa_eapol_key_send(sm, peerkey->stk.kck, ver, peerkey->addr,
441                            ETH_P_EAPOL, mbuf, mlen, msg->key_mic);
442 }
443
444
445 static int wpa_supplicant_process_smk_m4(struct wpa_peerkey *peerkey,
446                                          struct wpa_eapol_ie_parse *kde)
447 {
448         wpa_printf(MSG_DEBUG, "RSN: Received SMK M4 (Initiator " MACSTR ")",
449                    MAC2STR(kde->mac_addr));
450
451         if (os_memcmp(kde->smk + PMK_LEN, peerkey->pnonce, WPA_NONCE_LEN) != 0)
452         {
453                 wpa_printf(MSG_INFO, "RSN: PNonce in SMK KDE does not "
454                            "match with the one used in SMK M3");
455                 return -1;
456         }
457
458         if (os_memcmp(kde->nonce, peerkey->inonce, WPA_NONCE_LEN) != 0) {
459                 wpa_printf(MSG_INFO, "RSN: INonce in SMK M4 did not "
460                            "match with the one received in SMK M2");
461                 return -1;
462         }
463
464         return 0;
465 }
466
467
468 static int wpa_supplicant_process_smk_m5(struct wpa_sm *sm,
469                                          const unsigned char *src_addr,
470                                          const struct wpa_eapol_key *key,
471                                          int ver,
472                                          struct wpa_peerkey *peerkey,
473                                          struct wpa_eapol_ie_parse *kde)
474 {
475         int cipher;
476         struct wpa_ie_data ie;
477
478         wpa_printf(MSG_DEBUG, "RSN: Received SMK M5 (Peer " MACSTR ")",
479                    MAC2STR(kde->mac_addr));
480         if (kde->rsn_ie == NULL || kde->rsn_ie_len > PEERKEY_MAX_IE_LEN ||
481             wpa_parse_wpa_ie_rsn(kde->rsn_ie, kde->rsn_ie_len, &ie) < 0) {
482                 wpa_printf(MSG_INFO, "RSN: No RSN IE in SMK M5");
483                 /* TODO: abort negotiation */
484                 return -1;
485         }
486
487         if (os_memcmp(key->key_nonce, peerkey->inonce, WPA_NONCE_LEN) != 0) {
488                 wpa_printf(MSG_INFO, "RSN: Key Nonce in SMK M5 does "
489                            "not match with INonce used in SMK M1");
490                 return -1;
491         }
492
493         if (os_memcmp(kde->smk + PMK_LEN, peerkey->inonce, WPA_NONCE_LEN) != 0)
494         {
495                 wpa_printf(MSG_INFO, "RSN: INonce in SMK KDE does not "
496                            "match with the one used in SMK M1");
497                 return -1;
498         }
499
500         os_memcpy(peerkey->rsnie_p, kde->rsn_ie, kde->rsn_ie_len);
501         peerkey->rsnie_p_len = kde->rsn_ie_len;
502         os_memcpy(peerkey->pnonce, kde->nonce, WPA_NONCE_LEN);
503
504         cipher = ie.pairwise_cipher & sm->allowed_pairwise_cipher;
505         if (cipher & WPA_CIPHER_CCMP) {
506                 wpa_printf(MSG_DEBUG, "RSN: Using CCMP for PeerKey");
507                 peerkey->cipher = WPA_CIPHER_CCMP;
508         } else if (cipher & WPA_CIPHER_GCMP) {
509                 wpa_printf(MSG_DEBUG, "RSN: Using GCMP for PeerKey");
510                 peerkey->cipher = WPA_CIPHER_GCMP;
511         } else if (cipher & WPA_CIPHER_TKIP) {
512                 wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey");
513                 peerkey->cipher = WPA_CIPHER_TKIP;
514         } else {
515                 wpa_printf(MSG_INFO, "RSN: SMK Peer STA " MACSTR " selected "
516                            "unacceptable cipher", MAC2STR(kde->mac_addr));
517                 wpa_supplicant_send_smk_error(sm, src_addr, kde->mac_addr,
518                                               STK_MUI_SMK, STK_ERR_CPHR_NS,
519                                               ver);
520                 /* TODO: abort negotiation */
521                 return -1;
522         }
523
524         return 0;
525 }
526
527
528 static int wpa_supplicant_process_smk_m45(
529         struct wpa_sm *sm, const unsigned char *src_addr,
530         const struct wpa_eapol_key *key, size_t extra_len, int ver)
531 {
532         struct wpa_peerkey *peerkey;
533         struct wpa_eapol_ie_parse kde;
534         u32 lifetime;
535         struct os_time now;
536
537         if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {
538                 wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for "
539                            "the current network");
540                 return -1;
541         }
542
543         if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <
544             0) {
545                 wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M4/M5");
546                 return -1;
547         }
548
549         if (kde.mac_addr == NULL || kde.mac_addr_len < ETH_ALEN ||
550             kde.nonce == NULL || kde.nonce_len < WPA_NONCE_LEN ||
551             kde.smk == NULL || kde.smk_len < PMK_LEN + WPA_NONCE_LEN ||
552             kde.lifetime == NULL || kde.lifetime_len < 4) {
553                 wpa_printf(MSG_INFO, "RSN: No MAC Address, Nonce, SMK, or "
554                            "Lifetime KDE in SMK M4/M5");
555                 return -1;
556         }
557
558         for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
559                 if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) == 0 &&
560                     os_memcmp(peerkey->initiator ? peerkey->inonce :
561                            peerkey->pnonce,
562                            key->key_nonce, WPA_NONCE_LEN) == 0)
563                         break;
564         }
565         if (peerkey == NULL) {
566                 wpa_printf(MSG_INFO, "RSN: No matching SMK handshake found "
567                            "for SMK M4/M5: peer " MACSTR,
568                            MAC2STR(kde.mac_addr));
569                 return -1;
570         }
571
572         if (peerkey->initiator) {
573                 if (wpa_supplicant_process_smk_m5(sm, src_addr, key, ver,
574                                                   peerkey, &kde) < 0)
575                         return -1;
576         } else {
577                 if (wpa_supplicant_process_smk_m4(peerkey, &kde) < 0)
578                         return -1;
579         }
580
581         os_memcpy(peerkey->smk, kde.smk, PMK_LEN);
582         peerkey->smk_complete = 1;
583         wpa_hexdump_key(MSG_DEBUG, "RSN: SMK", peerkey->smk, PMK_LEN);
584         lifetime = WPA_GET_BE32(kde.lifetime);
585         wpa_printf(MSG_DEBUG, "RSN: SMK lifetime %u seconds", lifetime);
586         if (lifetime > 1000000000)
587                 lifetime = 1000000000; /* avoid overflowing expiration time */
588         peerkey->lifetime = lifetime;
589         os_get_time(&now);
590         peerkey->expiration = now.sec + lifetime;
591         eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout,
592                                sm, peerkey);
593
594         if (peerkey->initiator) {
595                 rsn_smkid(peerkey->smk, peerkey->pnonce, peerkey->addr,
596                           peerkey->inonce, sm->own_addr, peerkey->smkid,
597                           peerkey->use_sha256);
598                 wpa_supplicant_send_stk_1_of_4(sm, peerkey);
599         } else {
600                 rsn_smkid(peerkey->smk, peerkey->pnonce, sm->own_addr,
601                           peerkey->inonce, peerkey->addr, peerkey->smkid,
602                           peerkey->use_sha256);
603         }
604         wpa_hexdump(MSG_DEBUG, "RSN: SMKID", peerkey->smkid, PMKID_LEN);
605
606         return 0;
607 }
608
609
610 static int wpa_supplicant_process_smk_error(
611         struct wpa_sm *sm, const unsigned char *src_addr,
612         const struct wpa_eapol_key *key, size_t extra_len)
613 {
614         struct wpa_eapol_ie_parse kde;
615         struct rsn_error_kde error;
616         u8 peer[ETH_ALEN];
617         u16 error_type;
618
619         wpa_printf(MSG_DEBUG, "RSN: Received SMK Error");
620
621         if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {
622                 wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for "
623                            "the current network");
624                 return -1;
625         }
626
627         if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <
628             0) {
629                 wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK Error");
630                 return -1;
631         }
632
633         if (kde.error == NULL || kde.error_len < sizeof(error)) {
634                 wpa_printf(MSG_INFO, "RSN: No Error KDE in SMK Error");
635                 return -1;
636         }
637
638         if (kde.mac_addr && kde.mac_addr_len >= ETH_ALEN)
639                 os_memcpy(peer, kde.mac_addr, ETH_ALEN);
640         else
641                 os_memset(peer, 0, ETH_ALEN);
642         os_memcpy(&error, kde.error, sizeof(error));
643         error_type = be_to_host16(error.error_type);
644         wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
645                 "RSN: SMK Error KDE received: MUI %d error_type %d peer "
646                 MACSTR,
647                 be_to_host16(error.mui), error_type,
648                 MAC2STR(peer));
649
650         if (kde.mac_addr &&
651             (error_type == STK_ERR_STA_NR || error_type == STK_ERR_STA_NRSN ||
652              error_type == STK_ERR_CPHR_NS)) {
653                 struct wpa_peerkey *peerkey;
654
655                 for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
656                         if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) ==
657                             0)
658                                 break;
659                 }
660                 if (peerkey == NULL) {
661                         wpa_printf(MSG_DEBUG, "RSN: No matching SMK handshake "
662                                    "found for SMK Error");
663                         return -1;
664                 }
665                 /* TODO: abort SMK/STK handshake and remove all related keys */
666         }
667
668         return 0;
669 }
670
671
672 static void wpa_supplicant_process_stk_1_of_4(struct wpa_sm *sm,
673                                               struct wpa_peerkey *peerkey,
674                                               const struct wpa_eapol_key *key,
675                                               u16 ver)
676 {
677         struct wpa_eapol_ie_parse ie;
678         const u8 *kde;
679         size_t len, kde_buf_len;
680         struct wpa_ptk *stk;
681         u8 buf[8], *kde_buf, *pos;
682         be32 lifetime;
683
684         wpa_printf(MSG_DEBUG, "RSN: RX message 1 of STK 4-Way Handshake from "
685                    MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
686
687         os_memset(&ie, 0, sizeof(ie));
688
689         /* RSN: msg 1/4 should contain SMKID for the selected SMK */
690         kde = (const u8 *) (key + 1);
691         len = WPA_GET_BE16(key->key_data_length);
692         wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", kde, len);
693         if (wpa_supplicant_parse_ies(kde, len, &ie) < 0 || ie.pmkid == NULL) {
694                 wpa_printf(MSG_DEBUG, "RSN: No SMKID in STK 1/4");
695                 return;
696         }
697         if (os_memcmp(ie.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
698                 wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 1/4",
699                             ie.pmkid, PMKID_LEN);
700                 return;
701         }
702
703         if (random_get_bytes(peerkey->pnonce, WPA_NONCE_LEN)) {
704                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
705                         "RSN: Failed to get random data for PNonce");
706                 return;
707         }
708         wpa_hexdump(MSG_DEBUG, "WPA: Renewed PNonce",
709                     peerkey->pnonce, WPA_NONCE_LEN);
710
711         /* Calculate STK which will be stored as a temporary STK until it has
712          * been verified when processing message 3/4. */
713         stk = &peerkey->tstk;
714         wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion",
715                        sm->own_addr, peerkey->addr,
716                        peerkey->pnonce, key->key_nonce,
717                        (u8 *) stk, sizeof(*stk),
718                        peerkey->use_sha256);
719         /* Supplicant: swap tx/rx Mic keys */
720         os_memcpy(buf, stk->u.auth.tx_mic_key, 8);
721         os_memcpy(stk->u.auth.tx_mic_key, stk->u.auth.rx_mic_key, 8);
722         os_memcpy(stk->u.auth.rx_mic_key, buf, 8);
723         peerkey->tstk_set = 1;
724
725         kde_buf_len = peerkey->rsnie_p_len +
726                 2 + RSN_SELECTOR_LEN + sizeof(lifetime) +
727                 2 + RSN_SELECTOR_LEN + PMKID_LEN;
728         kde_buf = os_malloc(kde_buf_len);
729         if (kde_buf == NULL)
730                 return;
731         pos = kde_buf;
732         pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len);
733         lifetime = host_to_be32(peerkey->lifetime);
734         pos = wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,
735                           (u8 *) &lifetime, sizeof(lifetime));
736         wpa_add_kde(pos, RSN_KEY_DATA_PMKID, peerkey->smkid, PMKID_LEN);
737
738         if (wpa_supplicant_send_2_of_4(sm, peerkey->addr, key, ver,
739                                        peerkey->pnonce, kde_buf, kde_buf_len,
740                                        stk)) {
741                 os_free(kde_buf);
742                 return;
743         }
744         os_free(kde_buf);
745
746         os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN);
747 }
748
749
750 static void wpa_supplicant_update_smk_lifetime(struct wpa_sm *sm,
751                                                struct wpa_peerkey *peerkey,
752                                                struct wpa_eapol_ie_parse *kde)
753 {
754         u32 lifetime;
755         struct os_time now;
756
757         if (kde->lifetime == NULL || kde->lifetime_len < sizeof(lifetime))
758                 return;
759
760         lifetime = WPA_GET_BE32(kde->lifetime);
761
762         if (lifetime >= peerkey->lifetime) {
763                 wpa_printf(MSG_DEBUG, "RSN: Peer used SMK lifetime %u seconds "
764                            "which is larger than or equal to own value %u "
765                            "seconds - ignored", lifetime, peerkey->lifetime);
766                 return;
767         }
768
769         wpa_printf(MSG_DEBUG, "RSN: Peer used shorter SMK lifetime %u seconds "
770                    "(own was %u seconds) - updated",
771                    lifetime, peerkey->lifetime);
772         peerkey->lifetime = lifetime;
773
774         os_get_time(&now);
775         peerkey->expiration = now.sec + lifetime;
776         eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey);
777         eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout,
778                                sm, peerkey);
779 }
780
781
782 static void wpa_supplicant_process_stk_2_of_4(struct wpa_sm *sm,
783                                               struct wpa_peerkey *peerkey,
784                                               const struct wpa_eapol_key *key,
785                                               u16 ver)
786 {
787         struct wpa_eapol_ie_parse kde;
788         const u8 *keydata;
789         size_t len;
790
791         wpa_printf(MSG_DEBUG, "RSN: RX message 2 of STK 4-Way Handshake from "
792                    MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
793
794         os_memset(&kde, 0, sizeof(kde));
795
796         /* RSN: msg 2/4 should contain SMKID for the selected SMK and RSN IE
797          * from the peer. It may also include Lifetime KDE. */
798         keydata = (const u8 *) (key + 1);
799         len = WPA_GET_BE16(key->key_data_length);
800         wpa_hexdump(MSG_DEBUG, "RSN: msg 2/4 key data", keydata, len);
801         if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0 ||
802             kde.pmkid == NULL || kde.rsn_ie == NULL) {
803                 wpa_printf(MSG_DEBUG, "RSN: No SMKID or RSN IE in STK 2/4");
804                 return;
805         }
806
807         if (os_memcmp(kde.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
808                 wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 2/4",
809                             kde.pmkid, PMKID_LEN);
810                 return;
811         }
812
813         if (kde.rsn_ie_len != peerkey->rsnie_p_len ||
814             os_memcmp(kde.rsn_ie, peerkey->rsnie_p, kde.rsn_ie_len) != 0) {
815                 wpa_printf(MSG_INFO, "RSN: Peer RSN IE in SMK and STK "
816                            "handshakes did not match");
817                 wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in SMK handshake",
818                             peerkey->rsnie_p, peerkey->rsnie_p_len);
819                 wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in STK handshake",
820                             kde.rsn_ie, kde.rsn_ie_len);
821                 return;
822         }
823
824         wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde);
825
826         wpa_supplicant_send_stk_3_of_4(sm, peerkey);
827         os_memcpy(peerkey->pnonce, key->key_nonce, WPA_NONCE_LEN);
828 }
829
830
831 static void wpa_supplicant_process_stk_3_of_4(struct wpa_sm *sm,
832                                               struct wpa_peerkey *peerkey,
833                                               const struct wpa_eapol_key *key,
834                                               u16 ver)
835 {
836         struct wpa_eapol_ie_parse kde;
837         const u8 *keydata;
838         size_t len, key_len;
839         const u8 *_key;
840         u8 key_buf[32], rsc[6];
841
842         wpa_printf(MSG_DEBUG, "RSN: RX message 3 of STK 4-Way Handshake from "
843                    MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
844
845         os_memset(&kde, 0, sizeof(kde));
846
847         /* RSN: msg 3/4 should contain Initiator RSN IE. It may also include
848          * Lifetime KDE. */
849         keydata = (const u8 *) (key + 1);
850         len = WPA_GET_BE16(key->key_data_length);
851         wpa_hexdump(MSG_DEBUG, "RSN: msg 3/4 key data", keydata, len);
852         if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0) {
853                 wpa_printf(MSG_DEBUG, "RSN: Failed to parse key data in "
854                            "STK 3/4");
855                 return;
856         }
857
858         if (kde.rsn_ie_len != peerkey->rsnie_i_len ||
859             os_memcmp(kde.rsn_ie, peerkey->rsnie_i, kde.rsn_ie_len) != 0) {
860                 wpa_printf(MSG_INFO, "RSN: Initiator RSN IE in SMK and STK "
861                            "handshakes did not match");
862                 wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in SMK "
863                             "handshake",
864                             peerkey->rsnie_i, peerkey->rsnie_i_len);
865                 wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in STK "
866                             "handshake",
867                             kde.rsn_ie, kde.rsn_ie_len);
868                 return;
869         }
870
871         if (os_memcmp(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
872                 wpa_printf(MSG_WARNING, "RSN: INonce from message 1 of STK "
873                            "4-Way Handshake differs from 3 of STK 4-Way "
874                            "Handshake - drop packet (src=" MACSTR ")",
875                            MAC2STR(peerkey->addr));
876                 return;
877         }
878
879         wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde);
880
881         if (wpa_supplicant_send_4_of_4(sm, peerkey->addr, key, ver,
882                                        WPA_GET_BE16(key->key_info),
883                                        NULL, 0, &peerkey->stk))
884                 return;
885
886         _key = (u8 *) peerkey->stk.tk1;
887         if (peerkey->cipher == WPA_CIPHER_TKIP) {
888                 /* Swap Tx/Rx keys for Michael MIC */
889                 os_memcpy(key_buf, _key, 16);
890                 os_memcpy(key_buf + 16, peerkey->stk.u.auth.rx_mic_key, 8);
891                 os_memcpy(key_buf + 24, peerkey->stk.u.auth.tx_mic_key, 8);
892                 _key = key_buf;
893                 key_len = 32;
894         } else
895                 key_len = 16;
896
897         os_memset(rsc, 0, 6);
898         if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1,
899                            rsc, sizeof(rsc), _key, key_len) < 0) {
900                 wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the "
901                            "driver.");
902                 return;
903         }
904 }
905
906
907 static void wpa_supplicant_process_stk_4_of_4(struct wpa_sm *sm,
908                                               struct wpa_peerkey *peerkey,
909                                               const struct wpa_eapol_key *key,
910                                               u16 ver)
911 {
912         u8 rsc[6];
913
914         wpa_printf(MSG_DEBUG, "RSN: RX message 4 of STK 4-Way Handshake from "
915                    MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
916
917         os_memset(rsc, 0, 6);
918         if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1,
919                            rsc, sizeof(rsc), (u8 *) peerkey->stk.tk1,
920                            peerkey->cipher == WPA_CIPHER_TKIP ? 32 : 16) < 0) {
921                 wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the "
922                            "driver.");
923                 return;
924         }
925 }
926
927
928 /**
929  * peerkey_verify_eapol_key_mic - Verify PeerKey MIC
930  * @sm: Pointer to WPA state machine data from wpa_sm_init()
931  * @peerkey: Pointer to the PeerKey data for the peer
932  * @key: Pointer to the EAPOL-Key frame header
933  * @ver: Version bits from EAPOL-Key Key Info
934  * @buf: Pointer to the beginning of EAPOL-Key frame
935  * @len: Length of the EAPOL-Key frame
936  * Returns: 0 on success, -1 on failure
937  */
938 int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
939                                  struct wpa_peerkey *peerkey,
940                                  struct wpa_eapol_key *key, u16 ver,
941                                  const u8 *buf, size_t len)
942 {
943         u8 mic[16];
944         int ok = 0;
945
946         if (peerkey->initiator && !peerkey->stk_set) {
947                 wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion",
948                                sm->own_addr, peerkey->addr,
949                                peerkey->inonce, key->key_nonce,
950                                (u8 *) &peerkey->stk, sizeof(peerkey->stk),
951                                peerkey->use_sha256);
952                 peerkey->stk_set = 1;
953         }
954
955         os_memcpy(mic, key->key_mic, 16);
956         if (peerkey->tstk_set) {
957                 os_memset(key->key_mic, 0, 16);
958                 wpa_eapol_key_mic(peerkey->tstk.kck, ver, buf, len,
959                                   key->key_mic);
960                 if (os_memcmp(mic, key->key_mic, 16) != 0) {
961                         wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
962                                    "when using TSTK - ignoring TSTK");
963                 } else {
964                         ok = 1;
965                         peerkey->tstk_set = 0;
966                         peerkey->stk_set = 1;
967                         os_memcpy(&peerkey->stk, &peerkey->tstk,
968                                   sizeof(peerkey->stk));
969                 }
970         }
971
972         if (!ok && peerkey->stk_set) {
973                 os_memset(key->key_mic, 0, 16);
974                 wpa_eapol_key_mic(peerkey->stk.kck, ver, buf, len,
975                                   key->key_mic);
976                 if (os_memcmp(mic, key->key_mic, 16) != 0) {
977                         wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
978                                    "- dropping packet");
979                         return -1;
980                 }
981                 ok = 1;
982         }
983
984         if (!ok) {
985                 wpa_printf(MSG_WARNING, "RSN: Could not verify EAPOL-Key MIC "
986                            "- dropping packet");
987                 return -1;
988         }
989
990         os_memcpy(peerkey->replay_counter, key->replay_counter,
991                   WPA_REPLAY_COUNTER_LEN);
992         peerkey->replay_counter_set = 1;
993         return 0;
994 }
995
996
997 /**
998  * wpa_sm_stkstart - Send EAPOL-Key Request for STK handshake (STK M1)
999  * @sm: Pointer to WPA state machine data from wpa_sm_init()
1000  * @peer: MAC address of the peer STA
1001  * Returns: 0 on success, or -1 on failure
1002  *
1003  * Send an EAPOL-Key Request to the current authenticator to start STK
1004  * handshake with the peer.
1005  */
1006 int wpa_sm_stkstart(struct wpa_sm *sm, const u8 *peer)
1007 {
1008         size_t rlen, kde_len;
1009         struct wpa_eapol_key *req;
1010         int key_info, ver;
1011         u8 bssid[ETH_ALEN], *rbuf, *pos, *count_pos;
1012         u16 count;
1013         struct rsn_ie_hdr *hdr;
1014         struct wpa_peerkey *peerkey;
1015         struct wpa_ie_data ie;
1016
1017         if (sm->proto != WPA_PROTO_RSN || !sm->ptk_set || !sm->peerkey_enabled)
1018                 return -1;
1019
1020         if (sm->ap_rsn_ie &&
1021             wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &ie) == 0 &&
1022             !(ie.capabilities & WPA_CAPABILITY_PEERKEY_ENABLED)) {
1023                 wpa_printf(MSG_DEBUG, "RSN: Current AP does not support STK");
1024                 return -1;
1025         }
1026
1027         if (sm->pairwise_cipher != WPA_CIPHER_TKIP)
1028                 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
1029         else
1030                 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
1031
1032         if (wpa_sm_get_bssid(sm, bssid) < 0) {
1033                 wpa_printf(MSG_WARNING, "Failed to read BSSID for EAPOL-Key "
1034                            "SMK M1");
1035                 return -1;
1036         }
1037
1038         /* TODO: find existing entry and if found, use that instead of adding
1039          * a new one */
1040         peerkey = os_zalloc(sizeof(*peerkey));
1041         if (peerkey == NULL)
1042                 return -1;
1043         peerkey->initiator = 1;
1044         os_memcpy(peerkey->addr, peer, ETH_ALEN);
1045 #ifdef CONFIG_IEEE80211W
1046         if (wpa_key_mgmt_sha256(sm->key_mgmt))
1047                 peerkey->use_sha256 = 1;
1048 #endif /* CONFIG_IEEE80211W */
1049
1050         /* SMK M1:
1051          * EAPOL-Key(S=1, M=1, A=0, I=0, K=0, SM=1, KeyRSC=0, Nonce=INonce,
1052          *           MIC=MIC, DataKDs=(RSNIE_I, MAC_P KDE))
1053          */
1054
1055         hdr = (struct rsn_ie_hdr *) peerkey->rsnie_i;
1056         hdr->elem_id = WLAN_EID_RSN;
1057         WPA_PUT_LE16(hdr->version, RSN_VERSION);
1058         pos = (u8 *) (hdr + 1);
1059         /* Group Suite can be anything for SMK RSN IE; receiver will just
1060          * ignore it. */
1061         RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
1062         pos += RSN_SELECTOR_LEN;
1063         count_pos = pos;
1064         pos += 2;
1065
1066         count = 0;
1067         if (sm->allowed_pairwise_cipher & WPA_CIPHER_CCMP) {
1068                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
1069                 pos += RSN_SELECTOR_LEN;
1070                 count++;
1071         }
1072         if (sm->allowed_pairwise_cipher & WPA_CIPHER_GCMP) {
1073                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP);
1074                 pos += RSN_SELECTOR_LEN;
1075                 count++;
1076         }
1077         if (sm->allowed_pairwise_cipher & WPA_CIPHER_TKIP) {
1078                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
1079                 pos += RSN_SELECTOR_LEN;
1080                 count++;
1081         }
1082         WPA_PUT_LE16(count_pos, count);
1083
1084         hdr->len = (pos - peerkey->rsnie_i) - 2;
1085         peerkey->rsnie_i_len = pos - peerkey->rsnie_i;
1086         wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake",
1087                     peerkey->rsnie_i, peerkey->rsnie_i_len);
1088
1089         kde_len = peerkey->rsnie_i_len + 2 + RSN_SELECTOR_LEN + ETH_ALEN;
1090
1091         rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
1092                                   sizeof(*req) + kde_len, &rlen,
1093                                   (void *) &req);
1094         if (rbuf == NULL) {
1095                 wpa_supplicant_peerkey_free(sm, peerkey);
1096                 return -1;
1097         }
1098
1099         req->type = EAPOL_KEY_TYPE_RSN;
1100         key_info = WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
1101                 WPA_KEY_INFO_SECURE | WPA_KEY_INFO_REQUEST | ver;
1102         WPA_PUT_BE16(req->key_info, key_info);
1103         WPA_PUT_BE16(req->key_length, 0);
1104         os_memcpy(req->replay_counter, sm->request_counter,
1105                   WPA_REPLAY_COUNTER_LEN);
1106         inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
1107
1108         if (random_get_bytes(peerkey->inonce, WPA_NONCE_LEN)) {
1109                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1110                         "WPA: Failed to get random data for INonce");
1111                 os_free(rbuf);
1112                 wpa_supplicant_peerkey_free(sm, peerkey);
1113                 return -1;
1114         }
1115         os_memcpy(req->key_nonce, peerkey->inonce, WPA_NONCE_LEN);
1116         wpa_hexdump(MSG_DEBUG, "WPA: INonce for SMK handshake",
1117                     req->key_nonce, WPA_NONCE_LEN);
1118
1119         WPA_PUT_BE16(req->key_data_length, (u16) kde_len);
1120         pos = (u8 *) (req + 1);
1121
1122         /* Initiator RSN IE */
1123         pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len);
1124         /* Peer MAC address KDE */
1125         wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN);
1126
1127         wpa_printf(MSG_INFO, "RSN: Sending EAPOL-Key SMK M1 Request (peer "
1128                    MACSTR ")", MAC2STR(peer));
1129         wpa_eapol_key_send(sm, sm->ptk.kck, ver, bssid, ETH_P_EAPOL,
1130                            rbuf, rlen, req->key_mic);
1131
1132         peerkey->next = sm->peerkey;
1133         sm->peerkey = peerkey;
1134
1135         return 0;
1136 }
1137
1138
1139 /**
1140  * peerkey_deinit - Free PeerKey values
1141  * @sm: Pointer to WPA state machine data from wpa_sm_init()
1142  */
1143 void peerkey_deinit(struct wpa_sm *sm)
1144 {
1145         struct wpa_peerkey *prev, *peerkey = sm->peerkey;
1146         while (peerkey) {
1147                 prev = peerkey;
1148                 peerkey = peerkey->next;
1149                 os_free(prev);
1150         }
1151         sm->peerkey = NULL;
1152 }
1153
1154
1155 void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey,
1156                            struct wpa_eapol_key *key, u16 key_info, u16 ver)
1157 {
1158         if ((key_info & (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) ==
1159             (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) {
1160                 /* 3/4 STK 4-Way Handshake */
1161                 wpa_supplicant_process_stk_3_of_4(sm, peerkey, key, ver);
1162         } else if (key_info & WPA_KEY_INFO_ACK) {
1163                 /* 1/4 STK 4-Way Handshake */
1164                 wpa_supplicant_process_stk_1_of_4(sm, peerkey, key, ver);
1165         } else if (key_info & WPA_KEY_INFO_SECURE) {
1166                 /* 4/4 STK 4-Way Handshake */
1167                 wpa_supplicant_process_stk_4_of_4(sm, peerkey, key, ver);
1168         } else {
1169                 /* 2/4 STK 4-Way Handshake */
1170                 wpa_supplicant_process_stk_2_of_4(sm, peerkey, key, ver);
1171         }
1172 }
1173
1174
1175 void peerkey_rx_eapol_smk(struct wpa_sm *sm, const u8 *src_addr,
1176                           struct wpa_eapol_key *key, size_t extra_len,
1177                           u16 key_info, u16 ver)
1178 {
1179         if (key_info & WPA_KEY_INFO_ERROR) {
1180                 /* SMK Error */
1181                 wpa_supplicant_process_smk_error(sm, src_addr, key, extra_len);
1182         } else if (key_info & WPA_KEY_INFO_ACK) {
1183                 /* SMK M2 */
1184                 wpa_supplicant_process_smk_m2(sm, src_addr, key, extra_len,
1185                                               ver);
1186         } else {
1187                 /* SMK M4 or M5 */
1188                 wpa_supplicant_process_smk_m45(sm, src_addr, key, extra_len,
1189                                                ver);
1190         }
1191 }
1192
1193 #endif /* CONFIG_PEERKEY */