WPS: Parse Request Type from WPS IE in (Re)AssocReq and derive mgmt keys
[libeap.git] / src / wps / wps_enrollee.c
1 /*
2  * Wi-Fi Protected Setup - Enrollee
3  * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include "includes.h"
16
17 #include "common.h"
18 #include "sha256.h"
19 #include "ieee802_11_defs.h"
20 #include "wps_i.h"
21 #include "wps_dev_attr.h"
22
23
24 static int wps_build_req_type(struct wpabuf *msg, enum wps_request_type type)
25 {
26         wpa_printf(MSG_DEBUG, "WPS:  * Request Type");
27         wpabuf_put_be16(msg, ATTR_REQUEST_TYPE);
28         wpabuf_put_be16(msg, 1);
29         wpabuf_put_u8(msg, type);
30         return 0;
31 }
32
33
34 static int wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid)
35 {
36         wpa_printf(MSG_DEBUG, "WPS:  * UUID-E");
37         wpabuf_put_be16(msg, ATTR_UUID_E);
38         wpabuf_put_be16(msg, WPS_UUID_LEN);
39         wpabuf_put_data(msg, uuid, WPS_UUID_LEN);
40         return 0;
41 }
42
43
44 static int wps_build_mac_addr(struct wps_data *wps, struct wpabuf *msg)
45 {
46         wpa_printf(MSG_DEBUG, "WPS:  * MAC Address");
47         wpabuf_put_be16(msg, ATTR_MAC_ADDR);
48         wpabuf_put_be16(msg, ETH_ALEN);
49         wpabuf_put_data(msg, wps->mac_addr_e, ETH_ALEN);
50         return 0;
51 }
52
53
54 static int wps_build_config_methods(struct wpabuf *msg, u16 methods)
55 {
56         wpa_printf(MSG_DEBUG, "WPS:  * Config Methods");
57         wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
58         wpabuf_put_be16(msg, 2);
59         wpabuf_put_be16(msg, methods);
60         return 0;
61 }
62
63
64 static int wps_build_wps_state(struct wps_data *wps, struct wpabuf *msg)
65 {
66         wpa_printf(MSG_DEBUG, "WPS:  * Wi-Fi Protected Setup State");
67         wpabuf_put_be16(msg, ATTR_WPS_STATE);
68         wpabuf_put_be16(msg, 1);
69         wpabuf_put_u8(msg, WPS_STATE_CONFIGURED);
70         return 0;
71 }
72
73
74 static int wps_build_rf_bands(struct wps_data *wps, struct wpabuf *msg)
75 {
76         wpa_printf(MSG_DEBUG, "WPS:  * RF Bands");
77         wpabuf_put_be16(msg, ATTR_RF_BANDS);
78         wpabuf_put_be16(msg, 1);
79         wpabuf_put_u8(msg, WPS_RF_24GHZ | WPS_RF_50GHZ);
80         return 0;
81 }
82
83
84 static int wps_build_dev_password_id(struct wpabuf *msg, u16 id)
85 {
86         wpa_printf(MSG_DEBUG, "WPS:  * Device Password ID");
87         wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
88         wpabuf_put_be16(msg, 2);
89         wpabuf_put_be16(msg, id);
90         return 0;
91 }
92
93
94 static int wps_build_config_error(struct wps_data *wps, struct wpabuf *msg)
95 {
96         u16 err = WPS_CFG_NO_ERROR;
97         wpabuf_put_be16(msg, ATTR_CONFIG_ERROR);
98         wpabuf_put_be16(msg, 2);
99         if (wps && wps->authenticator && wps->wps->ap_setup_locked)
100                 err = WPS_CFG_SETUP_LOCKED;
101         wpa_printf(MSG_DEBUG, "WPS:  * Configuration Error (%d)", err);
102         wpabuf_put_be16(msg, err);
103         return 0;
104 }
105
106
107 static int wps_build_e_hash(struct wps_data *wps, struct wpabuf *msg)
108 {
109         u8 *hash;
110         const u8 *addr[4];
111         size_t len[4];
112
113         if (os_get_random(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
114                 return -1;
115         wpa_hexdump(MSG_DEBUG, "WPS: E-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
116         wpa_hexdump(MSG_DEBUG, "WPS: E-S2",
117                     wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
118
119         if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
120                 wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
121                            "E-Hash derivation");
122                 return -1;
123         }
124
125         wpa_printf(MSG_DEBUG, "WPS:  * E-Hash1");
126         wpabuf_put_be16(msg, ATTR_E_HASH1);
127         wpabuf_put_be16(msg, SHA256_MAC_LEN);
128         hash = wpabuf_put(msg, SHA256_MAC_LEN);
129         /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
130         addr[0] = wps->snonce;
131         len[0] = WPS_SECRET_NONCE_LEN;
132         addr[1] = wps->psk1;
133         len[1] = WPS_PSK_LEN;
134         addr[2] = wpabuf_head(wps->dh_pubkey_e);
135         len[2] = wpabuf_len(wps->dh_pubkey_e);
136         addr[3] = wpabuf_head(wps->dh_pubkey_r);
137         len[3] = wpabuf_len(wps->dh_pubkey_r);
138         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
139         wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", hash, SHA256_MAC_LEN);
140
141         wpa_printf(MSG_DEBUG, "WPS:  * E-Hash2");
142         wpabuf_put_be16(msg, ATTR_E_HASH2);
143         wpabuf_put_be16(msg, SHA256_MAC_LEN);
144         hash = wpabuf_put(msg, SHA256_MAC_LEN);
145         /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
146         addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
147         addr[1] = wps->psk2;
148         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
149         wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", hash, SHA256_MAC_LEN);
150
151         return 0;
152 }
153
154
155 static int wps_build_e_snonce1(struct wps_data *wps, struct wpabuf *msg)
156 {
157         wpa_printf(MSG_DEBUG, "WPS:  * E-SNonce1");
158         wpabuf_put_be16(msg, ATTR_E_SNONCE1);
159         wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
160         wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
161         return 0;
162 }
163
164
165 static int wps_build_e_snonce2(struct wps_data *wps, struct wpabuf *msg)
166 {
167         wpa_printf(MSG_DEBUG, "WPS:  * E-SNonce2");
168         wpabuf_put_be16(msg, ATTR_E_SNONCE2);
169         wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
170         wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
171                         WPS_SECRET_NONCE_LEN);
172         return 0;
173 }
174
175
176 static struct wpabuf * wps_build_m1(struct wps_data *wps)
177 {
178         struct wpabuf *msg;
179         u16 methods;
180
181         if (os_get_random(wps->nonce_e, WPS_NONCE_LEN) < 0)
182                 return NULL;
183         wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
184                     wps->nonce_e, WPS_NONCE_LEN);
185
186         wpa_printf(MSG_DEBUG, "WPS: Building Message M1");
187         msg = wpabuf_alloc(1000);
188         if (msg == NULL)
189                 return NULL;
190
191         methods = WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
192         if (wps->pbc)
193                 methods |= WPS_CONFIG_PUSHBUTTON;
194
195         if (wps_build_version(msg) ||
196             wps_build_msg_type(msg, WPS_M1) ||
197             wps_build_uuid_e(msg, wps->uuid_e) ||
198             wps_build_mac_addr(wps, msg) ||
199             wps_build_enrollee_nonce(wps, msg) ||
200             wps_build_public_key(wps, msg) ||
201             wps_build_auth_type_flags(wps, msg) ||
202             wps_build_encr_type_flags(wps, msg) ||
203             wps_build_conn_type_flags(wps, msg) ||
204             wps_build_config_methods(msg, methods) ||
205             wps_build_wps_state(wps, msg) ||
206             wps_build_device_attrs(&wps->wps->dev, msg) ||
207             wps_build_rf_bands(wps, msg) ||
208             wps_build_assoc_state(wps, msg) ||
209             wps_build_dev_password_id(msg, wps->dev_pw_id) ||
210             wps_build_config_error(wps, msg) ||
211             wps_build_os_version(&wps->wps->dev, msg)) {
212                 wpabuf_free(msg);
213                 return NULL;
214         }
215
216         wps->state = RECV_M2;
217         return msg;
218 }
219
220
221 static struct wpabuf * wps_build_m3(struct wps_data *wps)
222 {
223         struct wpabuf *msg;
224
225         wpa_printf(MSG_DEBUG, "WPS: Building Message M3");
226
227         if (wps->dev_password == NULL) {
228                 wpa_printf(MSG_DEBUG, "WPS: No Device Password available");
229                 return NULL;
230         }
231         wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);
232
233         msg = wpabuf_alloc(1000);
234         if (msg == NULL)
235                 return NULL;
236
237         if (wps_build_version(msg) ||
238             wps_build_msg_type(msg, WPS_M3) ||
239             wps_build_registrar_nonce(wps, msg) ||
240             wps_build_e_hash(wps, msg) ||
241             wps_build_authenticator(wps, msg)) {
242                 wpabuf_free(msg);
243                 return NULL;
244         }
245
246         wps->state = RECV_M4;
247         return msg;
248 }
249
250
251 static struct wpabuf * wps_build_m5(struct wps_data *wps)
252 {
253         struct wpabuf *msg, *plain;
254
255         wpa_printf(MSG_DEBUG, "WPS: Building Message M5");
256
257         plain = wpabuf_alloc(200);
258         if (plain == NULL)
259                 return NULL;
260
261         msg = wpabuf_alloc(1000);
262         if (msg == NULL) {
263                 wpabuf_free(plain);
264                 return NULL;
265         }
266
267         if (wps_build_version(msg) ||
268             wps_build_msg_type(msg, WPS_M5) ||
269             wps_build_registrar_nonce(wps, msg) ||
270             wps_build_e_snonce1(wps, plain) ||
271             wps_build_key_wrap_auth(wps, plain) ||
272             wps_build_encr_settings(wps, msg, plain) ||
273             wps_build_authenticator(wps, msg)) {
274                 wpabuf_free(plain);
275                 wpabuf_free(msg);
276                 return NULL;
277         }
278         wpabuf_free(plain);
279
280         wps->state = RECV_M6;
281         return msg;
282 }
283
284
285 static int wps_build_cred_ssid(struct wps_data *wps, struct wpabuf *msg)
286 {
287         wpa_printf(MSG_DEBUG, "WPS:  * SSID");
288         wpabuf_put_be16(msg, ATTR_SSID);
289         wpabuf_put_be16(msg, wps->wps->ssid_len);
290         wpabuf_put_data(msg, wps->wps->ssid, wps->wps->ssid_len);
291         return 0;
292 }
293
294
295 static int wps_build_cred_auth_type(struct wps_data *wps, struct wpabuf *msg)
296 {
297         wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type");
298         wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
299         wpabuf_put_be16(msg, 2);
300         wpabuf_put_be16(msg, wps->wps->auth_types);
301         return 0;
302 }
303
304
305 static int wps_build_cred_encr_type(struct wps_data *wps, struct wpabuf *msg)
306 {
307         wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type");
308         wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
309         wpabuf_put_be16(msg, 2);
310         wpabuf_put_be16(msg, wps->wps->encr_types);
311         return 0;
312 }
313
314
315 static int wps_build_cred_network_key(struct wps_data *wps, struct wpabuf *msg)
316 {
317         wpa_printf(MSG_DEBUG, "WPS:  * Network Key");
318         wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
319         wpabuf_put_be16(msg, wps->wps->network_key_len);
320         wpabuf_put_data(msg, wps->wps->network_key, wps->wps->network_key_len);
321         return 0;
322 }
323
324
325 static int wps_build_cred_mac_addr(struct wps_data *wps, struct wpabuf *msg)
326 {
327         wpa_printf(MSG_DEBUG, "WPS:  * MAC Address (AP BSSID)");
328         wpabuf_put_be16(msg, ATTR_MAC_ADDR);
329         wpabuf_put_be16(msg, ETH_ALEN);
330         wpabuf_put_data(msg, wps->wps->dev.mac_addr, ETH_ALEN);
331         return 0;
332 }
333
334
335 static struct wpabuf * wps_build_m7(struct wps_data *wps)
336 {
337         struct wpabuf *msg, *plain;
338
339         wpa_printf(MSG_DEBUG, "WPS: Building Message M7");
340
341         plain = wpabuf_alloc(500);
342         if (plain == NULL)
343                 return NULL;
344
345         msg = wpabuf_alloc(1000);
346         if (msg == NULL) {
347                 wpabuf_free(plain);
348                 return NULL;
349         }
350
351         if (wps_build_version(msg) ||
352             wps_build_msg_type(msg, WPS_M7) ||
353             wps_build_registrar_nonce(wps, msg) ||
354             wps_build_e_snonce2(wps, plain) ||
355             (wps->authenticator &&
356              (wps_build_cred_ssid(wps, plain) ||
357               wps_build_cred_mac_addr(wps, plain) ||
358               wps_build_cred_auth_type(wps, plain) ||
359               wps_build_cred_encr_type(wps, plain) ||
360               wps_build_cred_network_key(wps, plain))) ||
361             wps_build_key_wrap_auth(wps, plain) ||
362             wps_build_encr_settings(wps, msg, plain) ||
363             wps_build_authenticator(wps, msg)) {
364                 wpabuf_free(plain);
365                 wpabuf_free(msg);
366                 return NULL;
367         }
368         wpabuf_free(plain);
369
370         wps->state = RECV_M8;
371         return msg;
372 }
373
374
375 static struct wpabuf * wps_build_wsc_done(struct wps_data *wps)
376 {
377         struct wpabuf *msg;
378
379         wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_Done");
380
381         msg = wpabuf_alloc(1000);
382         if (msg == NULL)
383                 return NULL;
384
385         if (wps_build_version(msg) ||
386             wps_build_msg_type(msg, WPS_WSC_DONE) ||
387             wps_build_enrollee_nonce(wps, msg) ||
388             wps_build_registrar_nonce(wps, msg)) {
389                 wpabuf_free(msg);
390                 return NULL;
391         }
392
393         wps->state = wps->authenticator ? RECV_ACK : WPS_FINISHED;
394         return msg;
395 }
396
397
398 static struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
399 {
400         struct wpabuf *msg;
401
402         wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_ACK");
403
404         msg = wpabuf_alloc(1000);
405         if (msg == NULL)
406                 return NULL;
407
408         if (wps_build_version(msg) ||
409             wps_build_msg_type(msg, WPS_WSC_ACK) ||
410             wps_build_enrollee_nonce(wps, msg) ||
411             wps_build_registrar_nonce(wps, msg)) {
412                 wpabuf_free(msg);
413                 return NULL;
414         }
415
416         return msg;
417 }
418
419
420 static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
421 {
422         struct wpabuf *msg;
423
424         wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK");
425
426         msg = wpabuf_alloc(1000);
427         if (msg == NULL)
428                 return NULL;
429
430         if (wps_build_version(msg) ||
431             wps_build_msg_type(msg, WPS_WSC_NACK) ||
432             wps_build_enrollee_nonce(wps, msg) ||
433             wps_build_registrar_nonce(wps, msg) ||
434             wps_build_config_error(wps, msg)) {
435                 wpabuf_free(msg);
436                 return NULL;
437         }
438
439         return msg;
440 }
441
442
443 struct wpabuf * wps_enrollee_get_msg(struct wps_data *wps, u8 *op_code)
444 {
445         struct wpabuf *msg;
446
447         switch (wps->state) {
448         case SEND_M1:
449                 msg = wps_build_m1(wps);
450                 *op_code = WSC_MSG;
451                 break;
452         case SEND_M3:
453                 msg = wps_build_m3(wps);
454                 *op_code = WSC_MSG;
455                 break;
456         case SEND_M5:
457                 msg = wps_build_m5(wps);
458                 *op_code = WSC_MSG;
459                 break;
460         case SEND_M7:
461                 msg = wps_build_m7(wps);
462                 *op_code = WSC_MSG;
463                 break;
464         case RECEIVED_M2D:
465                 msg = wps_build_wsc_ack(wps);
466                 *op_code = WSC_ACK;
467                 if (msg) {
468                         /* Another M2/M2D may be received */
469                         wps->state = RECV_M2;
470                 }
471                 break;
472         case SEND_WSC_NACK:
473                 msg = wps_build_wsc_nack(wps);
474                 *op_code = WSC_NACK;
475                 break;
476         case WPS_MSG_DONE:
477                 msg = wps_build_wsc_done(wps);
478                 *op_code = WSC_Done;
479                 break;
480         default:
481                 wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
482                            "a message", wps->state);
483                 msg = NULL;
484                 break;
485         }
486
487         if (*op_code == WSC_MSG && msg) {
488                 /* Save a copy of the last message for Authenticator derivation
489                  */
490                 wpabuf_free(wps->last_msg);
491                 wps->last_msg = wpabuf_dup(msg);
492         }
493
494         return msg;
495 }
496
497
498 static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
499 {
500         if (r_nonce == NULL) {
501                 wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
502                 return -1;
503         }
504
505         os_memcpy(wps->nonce_r, r_nonce, WPS_NONCE_LEN);
506         wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
507                     wps->nonce_r, WPS_NONCE_LEN);
508
509         return 0;
510 }
511
512
513 static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
514 {
515         if (e_nonce == NULL) {
516                 wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
517                 return -1;
518         }
519
520         if (os_memcmp(wps->nonce_e, e_nonce, WPS_NONCE_LEN) != 0) {
521                 wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce received");
522                 return -1;
523         }
524
525         return 0;
526 }
527
528
529 static int wps_process_uuid_r(struct wps_data *wps, const u8 *uuid_r)
530 {
531         if (uuid_r == NULL) {
532                 wpa_printf(MSG_DEBUG, "WPS: No UUID-R received");
533                 return -1;
534         }
535
536         os_memcpy(wps->uuid_r, uuid_r, WPS_UUID_LEN);
537         wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
538
539         return 0;
540 }
541
542
543 static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
544                               size_t pk_len)
545 {
546         if (pk == NULL || pk_len == 0) {
547                 wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
548                 return -1;
549         }
550
551         wpabuf_free(wps->dh_pubkey_r);
552         wps->dh_pubkey_r = wpabuf_alloc_copy(pk, pk_len);
553         if (wps->dh_pubkey_r == NULL)
554                 return -1;
555
556         if (wps_derive_keys(wps) < 0)
557                 return -1;
558
559         if (wps->request_type == WPS_REQ_WLAN_MANAGER_REGISTRAR &&
560             wps_derive_mgmt_keys(wps) < 0)
561                 return -1;
562
563         return 0;
564 }
565
566
567 static int wps_process_r_hash1(struct wps_data *wps, const u8 *r_hash1)
568 {
569         if (r_hash1 == NULL) {
570                 wpa_printf(MSG_DEBUG, "WPS: No R-Hash1 received");
571                 return -1;
572         }
573
574         os_memcpy(wps->peer_hash1, r_hash1, WPS_HASH_LEN);
575         wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", wps->peer_hash1, WPS_HASH_LEN);
576
577         return 0;
578 }
579
580
581 static int wps_process_r_hash2(struct wps_data *wps, const u8 *r_hash2)
582 {
583         if (r_hash2 == NULL) {
584                 wpa_printf(MSG_DEBUG, "WPS: No R-Hash2 received");
585                 return -1;
586         }
587
588         os_memcpy(wps->peer_hash2, r_hash2, WPS_HASH_LEN);
589         wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", wps->peer_hash2, WPS_HASH_LEN);
590
591         return 0;
592 }
593
594
595 static int wps_process_r_snonce1(struct wps_data *wps, const u8 *r_snonce1)
596 {
597         u8 hash[SHA256_MAC_LEN];
598         const u8 *addr[4];
599         size_t len[4];
600
601         if (r_snonce1 == NULL) {
602                 wpa_printf(MSG_DEBUG, "WPS: No R-SNonce1 received");
603                 return -1;
604         }
605
606         wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce1", r_snonce1,
607                         WPS_SECRET_NONCE_LEN);
608
609         /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
610         addr[0] = r_snonce1;
611         len[0] = WPS_SECRET_NONCE_LEN;
612         addr[1] = wps->psk1;
613         len[1] = WPS_PSK_LEN;
614         addr[2] = wpabuf_head(wps->dh_pubkey_e);
615         len[2] = wpabuf_len(wps->dh_pubkey_e);
616         addr[3] = wpabuf_head(wps->dh_pubkey_r);
617         len[3] = wpabuf_len(wps->dh_pubkey_r);
618         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
619
620         if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
621                 wpa_printf(MSG_DEBUG, "WPS: R-Hash1 derived from R-S1 does "
622                            "not match with the pre-committed value");
623                 return -1;
624         }
625
626         wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the first "
627                    "half of the device password");
628
629         return 0;
630 }
631
632
633 static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2)
634 {
635         u8 hash[SHA256_MAC_LEN];
636         const u8 *addr[4];
637         size_t len[4];
638
639         if (r_snonce2 == NULL) {
640                 wpa_printf(MSG_DEBUG, "WPS: No R-SNonce2 received");
641                 return -1;
642         }
643
644         wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce2", r_snonce2,
645                         WPS_SECRET_NONCE_LEN);
646
647         /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
648         addr[0] = r_snonce2;
649         len[0] = WPS_SECRET_NONCE_LEN;
650         addr[1] = wps->psk2;
651         len[1] = WPS_PSK_LEN;
652         addr[2] = wpabuf_head(wps->dh_pubkey_e);
653         len[2] = wpabuf_len(wps->dh_pubkey_e);
654         addr[3] = wpabuf_head(wps->dh_pubkey_r);
655         len[3] = wpabuf_len(wps->dh_pubkey_r);
656         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
657
658         if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
659                 wpa_printf(MSG_DEBUG, "WPS: R-Hash2 derived from R-S2 does "
660                            "not match with the pre-committed value");
661                 return -1;
662         }
663
664         wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the second "
665                    "half of the device password");
666
667         return 0;
668 }
669
670
671 static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
672                               size_t cred_len)
673 {
674         struct wps_parse_attr attr;
675         struct wpabuf msg;
676
677         wpa_printf(MSG_DEBUG, "WPS: Received Credential");
678         os_memset(&wps->cred, 0, sizeof(wps->cred));
679         wpabuf_set(&msg, cred, cred_len);
680         if (wps_parse_msg(&msg, &attr) < 0 ||
681             wps_process_cred(&attr, &wps->cred))
682                 return -1;
683
684         if (wps->wps->cred_cb)
685                 wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
686
687         return 0;
688 }
689
690
691 static int wps_process_creds(struct wps_data *wps, const u8 *cred[],
692                              size_t cred_len[], size_t num_cred)
693 {
694         size_t i;
695
696         if (wps->authenticator)
697                 return 0;
698
699         if (num_cred == 0) {
700                 wpa_printf(MSG_DEBUG, "WPS: No Credential attributes "
701                            "received");
702                 return -1;
703         }
704
705         for (i = 0; i < num_cred; i++) {
706                 if (wps_process_cred_e(wps, cred[i], cred_len[i]))
707                         return -1;
708         }
709
710         return 0;
711 }
712
713
714 static int wps_process_ap_settings_e(struct wps_data *wps,
715                                      struct wps_parse_attr *attr)
716 {
717         struct wps_credential cred;
718
719         if (!wps->authenticator)
720                 return 0;
721
722         if (wps_process_ap_settings(attr, &cred) < 0)
723                 return -1;
724
725         wpa_printf(MSG_INFO, "WPS: Received new AP configuration from "
726                    "Registrar");
727
728         if (wps->wps->cred_cb)
729                 wps->wps->cred_cb(wps->wps->cb_ctx, &cred);
730
731         return 0;
732 }
733
734
735 static enum wps_process_res wps_process_m2(struct wps_data *wps,
736                                            const struct wpabuf *msg,
737                                            struct wps_parse_attr *attr)
738 {
739         wpa_printf(MSG_DEBUG, "WPS: Received M2");
740
741         if (wps->state != RECV_M2) {
742                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
743                            "receiving M2", wps->state);
744                 return WPS_FAILURE;
745         }
746
747         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
748             wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
749             wps_process_uuid_r(wps, attr->uuid_r) ||
750             wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
751             wps_process_authenticator(wps, attr->authenticator, msg))
752                 return WPS_FAILURE;
753
754         if (wps->authenticator && wps->wps->ap_setup_locked) {
755                 wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse "
756                            "registration of a new Registrar");
757                 wps->state = SEND_WSC_NACK;
758                 return WPS_CONTINUE;
759         }
760
761         wps->state = SEND_M3;
762         return WPS_CONTINUE;
763 }
764
765
766 static enum wps_process_res wps_process_m2d(struct wps_data *wps,
767                                             struct wps_parse_attr *attr)
768 {
769         wpa_printf(MSG_DEBUG, "WPS: Received M2D");
770
771         if (wps->state != RECV_M2) {
772                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
773                            "receiving M2D", wps->state);
774                 return WPS_FAILURE;
775         }
776
777         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer",
778                           attr->manufacturer, attr->manufacturer_len);
779         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name",
780                           attr->model_name, attr->model_name_len);
781         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number",
782                           attr->model_number, attr->model_number_len);
783         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number",
784                           attr->serial_number, attr->serial_number_len);
785         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name",
786                           attr->dev_name, attr->dev_name_len);
787
788         /*
789          * TODO: notify monitor programs (cli/gui/etc.) of the M2D and provide
790          * user information about the registrar properties.
791          */
792
793         wps->state = RECEIVED_M2D;
794         return WPS_FAILURE;
795 }
796
797
798 static enum wps_process_res wps_process_m4(struct wps_data *wps,
799                                            const struct wpabuf *msg,
800                                            struct wps_parse_attr *attr)
801 {
802         struct wpabuf *decrypted;
803         struct wps_parse_attr eattr;
804
805         wpa_printf(MSG_DEBUG, "WPS: Received M4");
806
807         if (wps->state != RECV_M4) {
808                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
809                            "receiving M4", wps->state);
810                 return WPS_FAILURE;
811         }
812
813         if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
814             wps_process_authenticator(wps, attr->authenticator, msg) ||
815             wps_process_r_hash1(wps, attr->r_hash1) ||
816             wps_process_r_hash2(wps, attr->r_hash2))
817                 return WPS_FAILURE;
818
819         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
820                                               attr->encr_settings_len);
821         if (decrypted == NULL) {
822                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
823                            "Settings attribute");
824                 return WPS_FAILURE;
825         }
826
827         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
828                    "attribute");
829         if (wps_parse_msg(decrypted, &eattr) < 0 ||
830             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
831             wps_process_r_snonce1(wps, eattr.r_snonce1)) {
832                 wpabuf_free(decrypted);
833                 return WPS_FAILURE;
834         }
835         wpabuf_free(decrypted);
836
837         wps->state = SEND_M5;
838         return WPS_CONTINUE;
839 }
840
841
842 static enum wps_process_res wps_process_m6(struct wps_data *wps,
843                                            const struct wpabuf *msg,
844                                            struct wps_parse_attr *attr)
845 {
846         struct wpabuf *decrypted;
847         struct wps_parse_attr eattr;
848
849         wpa_printf(MSG_DEBUG, "WPS: Received M6");
850
851         if (wps->state != RECV_M6) {
852                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
853                            "receiving M6", wps->state);
854                 return WPS_FAILURE;
855         }
856
857         if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
858             wps_process_authenticator(wps, attr->authenticator, msg))
859                 return WPS_FAILURE;
860
861         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
862                                               attr->encr_settings_len);
863         if (decrypted == NULL) {
864                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
865                            "Settings attribute");
866                 return WPS_FAILURE;
867         }
868
869         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
870                    "attribute");
871         if (wps_parse_msg(decrypted, &eattr) < 0 ||
872             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
873             wps_process_r_snonce2(wps, eattr.r_snonce2)) {
874                 wpabuf_free(decrypted);
875                 return WPS_FAILURE;
876         }
877         wpabuf_free(decrypted);
878
879         wps->state = SEND_M7;
880         return WPS_CONTINUE;
881 }
882
883
884 static enum wps_process_res wps_process_m8(struct wps_data *wps,
885                                            const struct wpabuf *msg,
886                                            struct wps_parse_attr *attr)
887 {
888         struct wpabuf *decrypted;
889         struct wps_parse_attr eattr;
890
891         wpa_printf(MSG_DEBUG, "WPS: Received M8");
892
893         if (wps->state != RECV_M8) {
894                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
895                            "receiving M8", wps->state);
896                 return WPS_FAILURE;
897         }
898
899         if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
900             wps_process_authenticator(wps, attr->authenticator, msg))
901                 return WPS_FAILURE;
902
903         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
904                                               attr->encr_settings_len);
905         if (decrypted == NULL) {
906                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
907                            "Settings attribute");
908                 return WPS_FAILURE;
909         }
910
911         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
912                    "attribute");
913         if (wps_parse_msg(decrypted, &eattr) < 0 ||
914             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
915             wps_process_creds(wps, eattr.cred, eattr.cred_len,
916                               eattr.num_cred) ||
917             wps_process_ap_settings_e(wps, &eattr)) {
918                 wpabuf_free(decrypted);
919                 return WPS_FAILURE;
920         }
921         wpabuf_free(decrypted);
922
923         wps->state = WPS_MSG_DONE;
924         return WPS_CONTINUE;
925 }
926
927
928 static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
929                                                 const struct wpabuf *msg)
930 {
931         struct wps_parse_attr attr;
932         enum wps_process_res ret = WPS_CONTINUE;
933
934         wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
935
936         if (wps_parse_msg(msg, &attr) < 0)
937                 return WPS_FAILURE;
938
939         if (attr.version == NULL || *attr.version != WPS_VERSION) {
940                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
941                            attr.version ? *attr.version : 0);
942                 return WPS_FAILURE;
943         }
944
945         if (attr.enrollee_nonce == NULL ||
946             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
947                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
948                 return WPS_FAILURE;
949         }
950
951         if (attr.msg_type == NULL) {
952                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
953                 return WPS_FAILURE;
954         }
955
956         switch (*attr.msg_type) {
957         case WPS_M2:
958                 ret = wps_process_m2(wps, msg, &attr);
959                 break;
960         case WPS_M2D:
961                 ret = wps_process_m2d(wps, &attr);
962                 break;
963         case WPS_M4:
964                 ret = wps_process_m4(wps, msg, &attr);
965                 break;
966         case WPS_M6:
967                 ret = wps_process_m6(wps, msg, &attr);
968                 break;
969         case WPS_M8:
970                 ret = wps_process_m8(wps, msg, &attr);
971                 break;
972         default:
973                 wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
974                            *attr.msg_type);
975                 return WPS_FAILURE;
976         }
977
978         if (ret == WPS_CONTINUE) {
979                 /* Save a copy of the last message for Authenticator derivation
980                  */
981                 wpabuf_free(wps->last_msg);
982                 wps->last_msg = wpabuf_dup(msg);
983         }
984
985         return ret;
986 }
987
988
989 static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
990                                                 const struct wpabuf *msg)
991 {
992         struct wps_parse_attr attr;
993
994         wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
995
996         if (wps_parse_msg(msg, &attr) < 0)
997                 return WPS_FAILURE;
998
999         if (attr.version == NULL || *attr.version != WPS_VERSION) {
1000                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
1001                            attr.version ? *attr.version : 0);
1002                 return WPS_FAILURE;
1003         }
1004
1005         if (attr.msg_type == NULL) {
1006                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1007                 return WPS_FAILURE;
1008         }
1009
1010         if (*attr.msg_type != WPS_WSC_ACK) {
1011                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
1012                            *attr.msg_type);
1013                 return WPS_FAILURE;
1014         }
1015
1016         if (attr.registrar_nonce == NULL ||
1017             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
1018         {
1019                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
1020                 return WPS_FAILURE;
1021         }
1022
1023         if (attr.enrollee_nonce == NULL ||
1024             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
1025                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1026                 return WPS_FAILURE;
1027         }
1028
1029         if (wps->state == RECV_ACK && wps->authenticator) {
1030                 wpa_printf(MSG_DEBUG, "WPS: External Registrar registration "
1031                            "completed successfully");
1032                 wps->state = WPS_FINISHED;
1033                 return WPS_DONE;
1034         }
1035
1036         return WPS_FAILURE;
1037 }
1038
1039
1040 static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
1041                                                  const struct wpabuf *msg)
1042 {
1043         struct wps_parse_attr attr;
1044
1045         wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
1046
1047         if (wps_parse_msg(msg, &attr) < 0)
1048                 return WPS_FAILURE;
1049
1050         if (attr.version == NULL || *attr.version != WPS_VERSION) {
1051                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
1052                            attr.version ? *attr.version : 0);
1053                 return WPS_FAILURE;
1054         }
1055
1056         if (attr.msg_type == NULL) {
1057                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1058                 return WPS_FAILURE;
1059         }
1060
1061         if (*attr.msg_type != WPS_WSC_NACK) {
1062                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
1063                            *attr.msg_type);
1064                 return WPS_FAILURE;
1065         }
1066
1067         if (attr.registrar_nonce == NULL ||
1068             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
1069         {
1070                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
1071                 wpa_hexdump(MSG_DEBUG, "WPS: Received Registrar Nonce",
1072                             attr.registrar_nonce, WPS_NONCE_LEN);
1073                 wpa_hexdump(MSG_DEBUG, "WPS: Expected Registrar Nonce",
1074                             wps->nonce_r, WPS_NONCE_LEN);
1075                 return WPS_FAILURE;
1076         }
1077
1078         if (attr.enrollee_nonce == NULL ||
1079             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
1080                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1081                 wpa_hexdump(MSG_DEBUG, "WPS: Received Enrollee Nonce",
1082                             attr.enrollee_nonce, WPS_NONCE_LEN);
1083                 wpa_hexdump(MSG_DEBUG, "WPS: Expected Enrollee Nonce",
1084                             wps->nonce_e, WPS_NONCE_LEN);
1085                 return WPS_FAILURE;
1086         }
1087
1088         if (attr.config_error == NULL) {
1089                 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
1090                            "in WSC_NACK");
1091                 return WPS_FAILURE;
1092         }
1093
1094         wpa_printf(MSG_DEBUG, "WPS: Enrollee terminated negotiation with "
1095                    "Configuration Error %d", WPA_GET_BE16(attr.config_error));
1096
1097         return WPS_FAILURE;
1098 }
1099
1100
1101 enum wps_process_res wps_enrollee_process_msg(struct wps_data *wps, u8 op_code,
1102                                               const struct wpabuf *msg)
1103 {
1104
1105         wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
1106                    "op_code=%d)",
1107                    (unsigned long) wpabuf_len(msg), op_code);
1108
1109         switch (op_code) {
1110         case WSC_MSG:
1111                 return wps_process_wsc_msg(wps, msg);
1112         case WSC_ACK:
1113                 return wps_process_wsc_ack(wps, msg);
1114         case WSC_NACK:
1115                 return wps_process_wsc_nack(wps, msg);
1116         default:
1117                 wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
1118                 return WPS_FAILURE;
1119         }
1120 }
1121
1122
1123 struct wpabuf * wps_enrollee_build_assoc_req_ie(void)
1124 {
1125         struct wpabuf *ie;
1126         u8 *len;
1127
1128         wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for (Re)Association "
1129                    "Request");
1130         ie = wpabuf_alloc(100);
1131         if (ie == NULL)
1132                 return NULL;
1133
1134         wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
1135         len = wpabuf_put(ie, 1);
1136         wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
1137
1138         if (wps_build_version(ie) ||
1139             wps_build_req_type(ie, WPS_REQ_ENROLLEE)) {
1140                 wpabuf_free(ie);
1141                 return NULL;
1142         }
1143
1144         *len = wpabuf_len(ie) - 2;
1145
1146         return ie;
1147 }
1148
1149
1150 struct wpabuf * wps_enrollee_build_probe_req_ie(int pbc, const u8 *uuid)
1151 {
1152         struct wpabuf *ie;
1153         u8 *len;
1154         u16 methods;
1155         struct wps_device_data dev;
1156
1157         wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for Probe Request");
1158
1159         /* TODO: get device data from caller */
1160         os_memset(&dev, 0, sizeof(dev));
1161         dev.categ = WPS_DEV_COMPUTER;
1162         dev.oui = WPS_DEV_OUI_WFA;
1163         dev.sub_categ = WPS_DEV_COMPUTER_PC;
1164
1165         ie = wpabuf_alloc(200);
1166         if (ie == NULL)
1167                 return NULL;
1168
1169         wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
1170         len = wpabuf_put(ie, 1);
1171         wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
1172
1173         if (pbc)
1174                 methods = WPS_CONFIG_PUSHBUTTON;
1175         else
1176                 methods = WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY |
1177                         WPS_CONFIG_KEYPAD;
1178
1179         if (wps_build_version(ie) ||
1180             wps_build_req_type(ie, WPS_REQ_ENROLLEE) ||
1181             wps_build_config_methods(ie, methods) ||
1182             wps_build_uuid_e(ie, uuid) ||
1183             wps_build_primary_dev_type(&dev, ie) ||
1184             wps_build_rf_bands(NULL, ie) ||
1185             wps_build_assoc_state(NULL, ie) ||
1186             wps_build_config_error(NULL, ie) ||
1187             wps_build_dev_password_id(ie, pbc ? DEV_PW_PUSHBUTTON :
1188                                       DEV_PW_DEFAULT)) {
1189                 wpabuf_free(ie);
1190                 return NULL;
1191         }
1192
1193         *len = wpabuf_len(ie) - 2;
1194
1195         return ie;
1196 }