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