Updated through tag hostap_2_5 from git://w1.fi/hostap.git
[mech_eap.git] / libeap / src / wps / wps_enrollee.c
1 /*
2  * Wi-Fi Protected Setup - Enrollee
3  * Copyright (c) 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 #include "common.h"
12 #include "crypto/crypto.h"
13 #include "crypto/sha256.h"
14 #include "crypto/random.h"
15 #include "wps_i.h"
16 #include "wps_dev_attr.h"
17
18
19 static int wps_build_wps_state(struct wps_data *wps, struct wpabuf *msg)
20 {
21         u8 state;
22         if (wps->wps->ap)
23                 state = wps->wps->wps_state;
24         else
25                 state = WPS_STATE_NOT_CONFIGURED;
26         wpa_printf(MSG_DEBUG, "WPS:  * Wi-Fi Protected Setup State (%d)",
27                    state);
28         wpabuf_put_be16(msg, ATTR_WPS_STATE);
29         wpabuf_put_be16(msg, 1);
30         wpabuf_put_u8(msg, state);
31         return 0;
32 }
33
34
35 static int wps_build_e_hash(struct wps_data *wps, struct wpabuf *msg)
36 {
37         u8 *hash;
38         const u8 *addr[4];
39         size_t len[4];
40
41         if (random_get_bytes(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
42                 return -1;
43         wpa_hexdump(MSG_DEBUG, "WPS: E-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
44         wpa_hexdump(MSG_DEBUG, "WPS: E-S2",
45                     wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
46
47         if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
48                 wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
49                            "E-Hash derivation");
50                 return -1;
51         }
52
53         wpa_printf(MSG_DEBUG, "WPS:  * E-Hash1");
54         wpabuf_put_be16(msg, ATTR_E_HASH1);
55         wpabuf_put_be16(msg, SHA256_MAC_LEN);
56         hash = wpabuf_put(msg, SHA256_MAC_LEN);
57         /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
58         addr[0] = wps->snonce;
59         len[0] = WPS_SECRET_NONCE_LEN;
60         addr[1] = wps->psk1;
61         len[1] = WPS_PSK_LEN;
62         addr[2] = wpabuf_head(wps->dh_pubkey_e);
63         len[2] = wpabuf_len(wps->dh_pubkey_e);
64         addr[3] = wpabuf_head(wps->dh_pubkey_r);
65         len[3] = wpabuf_len(wps->dh_pubkey_r);
66         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
67         wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", hash, SHA256_MAC_LEN);
68
69         wpa_printf(MSG_DEBUG, "WPS:  * E-Hash2");
70         wpabuf_put_be16(msg, ATTR_E_HASH2);
71         wpabuf_put_be16(msg, SHA256_MAC_LEN);
72         hash = wpabuf_put(msg, SHA256_MAC_LEN);
73         /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
74         addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
75         addr[1] = wps->psk2;
76         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
77         wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", hash, SHA256_MAC_LEN);
78
79         return 0;
80 }
81
82
83 static int wps_build_e_snonce1(struct wps_data *wps, struct wpabuf *msg)
84 {
85         wpa_printf(MSG_DEBUG, "WPS:  * E-SNonce1");
86         wpabuf_put_be16(msg, ATTR_E_SNONCE1);
87         wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
88         wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
89         return 0;
90 }
91
92
93 static int wps_build_e_snonce2(struct wps_data *wps, struct wpabuf *msg)
94 {
95         wpa_printf(MSG_DEBUG, "WPS:  * E-SNonce2");
96         wpabuf_put_be16(msg, ATTR_E_SNONCE2);
97         wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
98         wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
99                         WPS_SECRET_NONCE_LEN);
100         return 0;
101 }
102
103
104 static struct wpabuf * wps_build_m1(struct wps_data *wps)
105 {
106         struct wpabuf *msg;
107         u16 config_methods;
108
109         if (random_get_bytes(wps->nonce_e, WPS_NONCE_LEN) < 0)
110                 return NULL;
111         wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
112                     wps->nonce_e, WPS_NONCE_LEN);
113
114         wpa_printf(MSG_DEBUG, "WPS: Building Message M1");
115         msg = wpabuf_alloc(1000);
116         if (msg == NULL)
117                 return NULL;
118
119         config_methods = wps->wps->config_methods;
120         if (wps->wps->ap && !wps->pbc_in_m1 &&
121             (wps->dev_password_len != 0 ||
122              (config_methods & WPS_CONFIG_DISPLAY))) {
123                 /*
124                  * These are the methods that the AP supports as an Enrollee
125                  * for adding external Registrars, so remove PushButton.
126                  *
127                  * As a workaround for Windows 7 mechanism for probing WPS
128                  * capabilities from M1, leave PushButton option if no PIN
129                  * method is available or if WPS configuration enables PBC
130                  * workaround.
131                  */
132                 config_methods &= ~WPS_CONFIG_PUSHBUTTON;
133                 config_methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |
134                                     WPS_CONFIG_PHY_PUSHBUTTON);
135         }
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(msg, wps->mac_addr_e) ||
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, config_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->wps->rf_band_cb(wps->wps->cb_ctx)) ||
151             wps_build_assoc_state(wps, msg) ||
152             wps_build_dev_password_id(msg, wps->dev_pw_id) ||
153             wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
154             wps_build_os_version(&wps->wps->dev, msg) ||
155             wps_build_wfa_ext(msg, 0, NULL, 0) ||
156             wps_build_vendor_ext_m1(&wps->wps->dev, msg)) {
157                 wpabuf_free(msg);
158                 return NULL;
159         }
160
161         wps->state = RECV_M2;
162         return msg;
163 }
164
165
166 static struct wpabuf * wps_build_m3(struct wps_data *wps)
167 {
168         struct wpabuf *msg;
169
170         wpa_printf(MSG_DEBUG, "WPS: Building Message M3");
171
172         if (wps->dev_password == NULL) {
173                 wpa_printf(MSG_DEBUG, "WPS: No Device Password available");
174                 return NULL;
175         }
176         wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);
177
178         if (wps->wps->ap && random_pool_ready() != 1) {
179                 wpa_printf(MSG_INFO,
180                            "WPS: Not enough entropy in random pool to proceed - do not allow AP PIN to be used");
181                 return NULL;
182         }
183
184         msg = wpabuf_alloc(1000);
185         if (msg == NULL)
186                 return NULL;
187
188         if (wps_build_version(msg) ||
189             wps_build_msg_type(msg, WPS_M3) ||
190             wps_build_registrar_nonce(wps, msg) ||
191             wps_build_e_hash(wps, msg) ||
192             wps_build_wfa_ext(msg, 0, NULL, 0) ||
193             wps_build_authenticator(wps, msg)) {
194                 wpabuf_free(msg);
195                 return NULL;
196         }
197
198         wps->state = RECV_M4;
199         return msg;
200 }
201
202
203 static struct wpabuf * wps_build_m5(struct wps_data *wps)
204 {
205         struct wpabuf *msg, *plain;
206
207         wpa_printf(MSG_DEBUG, "WPS: Building Message M5");
208
209         plain = wpabuf_alloc(200);
210         if (plain == NULL)
211                 return NULL;
212
213         msg = wpabuf_alloc(1000);
214         if (msg == NULL) {
215                 wpabuf_free(plain);
216                 return NULL;
217         }
218
219         if (wps_build_version(msg) ||
220             wps_build_msg_type(msg, WPS_M5) ||
221             wps_build_registrar_nonce(wps, msg) ||
222             wps_build_e_snonce1(wps, plain) ||
223             wps_build_key_wrap_auth(wps, plain) ||
224             wps_build_encr_settings(wps, msg, plain) ||
225             wps_build_wfa_ext(msg, 0, NULL, 0) ||
226             wps_build_authenticator(wps, msg)) {
227                 wpabuf_free(plain);
228                 wpabuf_free(msg);
229                 return NULL;
230         }
231         wpabuf_free(plain);
232
233         wps->state = RECV_M6;
234         return msg;
235 }
236
237
238 static int wps_build_cred_ssid(struct wps_data *wps, struct wpabuf *msg)
239 {
240         wpa_printf(MSG_DEBUG, "WPS:  * SSID");
241         wpabuf_put_be16(msg, ATTR_SSID);
242         wpabuf_put_be16(msg, wps->wps->ssid_len);
243         wpabuf_put_data(msg, wps->wps->ssid, wps->wps->ssid_len);
244         return 0;
245 }
246
247
248 static int wps_build_cred_auth_type(struct wps_data *wps, struct wpabuf *msg)
249 {
250         u16 auth_type = wps->wps->ap_auth_type;
251
252         /*
253          * Work around issues with Windows 7 WPS implementation not liking
254          * multiple Authentication Type bits in M7 AP Settings attribute by
255          * showing only the most secure option from current configuration.
256          */
257         if (auth_type & WPS_AUTH_WPA2PSK)
258                 auth_type = WPS_AUTH_WPA2PSK;
259         else if (auth_type & WPS_AUTH_WPAPSK)
260                 auth_type = WPS_AUTH_WPAPSK;
261         else if (auth_type & WPS_AUTH_OPEN)
262                 auth_type = WPS_AUTH_OPEN;
263
264         wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type (0x%x)", auth_type);
265         wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
266         wpabuf_put_be16(msg, 2);
267         wpabuf_put_be16(msg, auth_type);
268         return 0;
269 }
270
271
272 static int wps_build_cred_encr_type(struct wps_data *wps, struct wpabuf *msg)
273 {
274         u16 encr_type = wps->wps->ap_encr_type;
275
276         /*
277          * Work around issues with Windows 7 WPS implementation not liking
278          * multiple Encryption Type bits in M7 AP Settings attribute by
279          * showing only the most secure option from current configuration.
280          */
281         if (wps->wps->ap_auth_type & (WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK)) {
282                 if (encr_type & WPS_ENCR_AES)
283                         encr_type = WPS_ENCR_AES;
284                 else if (encr_type & WPS_ENCR_TKIP)
285                         encr_type = WPS_ENCR_TKIP;
286         }
287
288         wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type (0x%x)", encr_type);
289         wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
290         wpabuf_put_be16(msg, 2);
291         wpabuf_put_be16(msg, encr_type);
292         return 0;
293 }
294
295
296 static int wps_build_cred_network_key(struct wps_data *wps, struct wpabuf *msg)
297 {
298         if ((wps->wps->ap_auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) &&
299             wps->wps->network_key_len == 0) {
300                 char hex[65];
301                 u8 psk[32];
302                 /* Generate a random per-device PSK */
303                 if (random_pool_ready() != 1 ||
304                     random_get_bytes(psk, sizeof(psk)) < 0) {
305                         wpa_printf(MSG_INFO,
306                                    "WPS: Could not generate random PSK");
307                         return -1;
308                 }
309                 wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
310                                 psk, sizeof(psk));
311                 wpa_printf(MSG_DEBUG, "WPS:  * Network Key (len=%u)",
312                            (unsigned int) wps->new_psk_len * 2);
313                 wpa_snprintf_hex(hex, sizeof(hex), psk, sizeof(psk));
314                 wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
315                 wpabuf_put_be16(msg, sizeof(psk) * 2);
316                 wpabuf_put_data(msg, hex, sizeof(psk) * 2);
317                 if (wps->wps->registrar) {
318                         wps_cb_new_psk(wps->wps->registrar,
319                                        wps->peer_dev.mac_addr,
320                                        wps->p2p_dev_addr, psk, sizeof(psk));
321                 }
322                 return 0;
323         }
324
325         wpa_printf(MSG_DEBUG, "WPS:  * Network Key (len=%u)",
326                    (unsigned int) wps->wps->network_key_len);
327         wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
328         wpabuf_put_be16(msg, wps->wps->network_key_len);
329         wpabuf_put_data(msg, wps->wps->network_key, wps->wps->network_key_len);
330         return 0;
331 }
332
333
334 static int wps_build_cred_mac_addr(struct wps_data *wps, struct wpabuf *msg)
335 {
336         wpa_printf(MSG_DEBUG, "WPS:  * MAC Address (AP BSSID)");
337         wpabuf_put_be16(msg, ATTR_MAC_ADDR);
338         wpabuf_put_be16(msg, ETH_ALEN);
339         wpabuf_put_data(msg, wps->wps->dev.mac_addr, ETH_ALEN);
340         return 0;
341 }
342
343
344 static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *plain)
345 {
346         const u8 *start, *end;
347         int ret;
348
349         if (wps->wps->ap_settings) {
350                 wpa_printf(MSG_DEBUG, "WPS:  * AP Settings (pre-configured)");
351                 wpabuf_put_data(plain, wps->wps->ap_settings,
352                                 wps->wps->ap_settings_len);
353                 return 0;
354         }
355
356         wpa_printf(MSG_DEBUG, "WPS:  * AP Settings based on current configuration");
357         start = wpabuf_put(plain, 0);
358         ret = wps_build_cred_ssid(wps, plain) ||
359                 wps_build_cred_mac_addr(wps, plain) ||
360                 wps_build_cred_auth_type(wps, plain) ||
361                 wps_build_cred_encr_type(wps, plain) ||
362                 wps_build_cred_network_key(wps, plain);
363         end = wpabuf_put(plain, 0);
364
365         wpa_hexdump_key(MSG_DEBUG, "WPS: Plaintext AP Settings",
366                         start, end - start);
367
368         return ret;
369 }
370
371
372 static struct wpabuf * wps_build_m7(struct wps_data *wps)
373 {
374         struct wpabuf *msg, *plain;
375
376         wpa_printf(MSG_DEBUG, "WPS: Building Message M7");
377
378         plain = wpabuf_alloc(500 + wps->wps->ap_settings_len);
379         if (plain == NULL)
380                 return NULL;
381
382         msg = wpabuf_alloc(1000 + wps->wps->ap_settings_len);
383         if (msg == NULL) {
384                 wpabuf_free(plain);
385                 return NULL;
386         }
387
388         if (wps_build_version(msg) ||
389             wps_build_msg_type(msg, WPS_M7) ||
390             wps_build_registrar_nonce(wps, msg) ||
391             wps_build_e_snonce2(wps, plain) ||
392             (wps->wps->ap && wps_build_ap_settings(wps, plain)) ||
393             wps_build_key_wrap_auth(wps, plain) ||
394             wps_build_encr_settings(wps, msg, plain) ||
395             wps_build_wfa_ext(msg, 0, NULL, 0) ||
396             wps_build_authenticator(wps, msg)) {
397                 wpabuf_free(plain);
398                 wpabuf_free(msg);
399                 return NULL;
400         }
401         wpabuf_free(plain);
402
403         if (wps->wps->ap && wps->wps->registrar) {
404                 /*
405                  * If the Registrar is only learning our current configuration,
406                  * it may not continue protocol run to successful completion.
407                  * Store information here to make sure it remains available.
408                  */
409                 wps_device_store(wps->wps->registrar, &wps->peer_dev,
410                                  wps->uuid_r);
411         }
412
413         wps->state = RECV_M8;
414         return msg;
415 }
416
417
418 static struct wpabuf * wps_build_wsc_done(struct wps_data *wps)
419 {
420         struct wpabuf *msg;
421
422         wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_Done");
423
424         msg = wpabuf_alloc(1000);
425         if (msg == NULL)
426                 return NULL;
427
428         if (wps_build_version(msg) ||
429             wps_build_msg_type(msg, WPS_WSC_DONE) ||
430             wps_build_enrollee_nonce(wps, msg) ||
431             wps_build_registrar_nonce(wps, msg) ||
432             wps_build_wfa_ext(msg, 0, NULL, 0)) {
433                 wpabuf_free(msg);
434                 return NULL;
435         }
436
437         if (wps->wps->ap)
438                 wps->state = RECV_ACK;
439         else {
440                 wps_success_event(wps->wps, wps->peer_dev.mac_addr);
441                 wps->state = WPS_FINISHED;
442         }
443         return msg;
444 }
445
446
447 struct wpabuf * wps_enrollee_get_msg(struct wps_data *wps,
448                                      enum wsc_op_code *op_code)
449 {
450         struct wpabuf *msg;
451
452         switch (wps->state) {
453         case SEND_M1:
454                 msg = wps_build_m1(wps);
455                 *op_code = WSC_MSG;
456                 break;
457         case SEND_M3:
458                 msg = wps_build_m3(wps);
459                 *op_code = WSC_MSG;
460                 break;
461         case SEND_M5:
462                 msg = wps_build_m5(wps);
463                 *op_code = WSC_MSG;
464                 break;
465         case SEND_M7:
466                 msg = wps_build_m7(wps);
467                 *op_code = WSC_MSG;
468                 break;
469         case RECEIVED_M2D:
470                 if (wps->wps->ap) {
471                         msg = wps_build_wsc_nack(wps);
472                         *op_code = WSC_NACK;
473                         break;
474                 }
475                 msg = wps_build_wsc_ack(wps);
476                 *op_code = WSC_ACK;
477                 if (msg) {
478                         /* Another M2/M2D may be received */
479                         wps->state = RECV_M2;
480                 }
481                 break;
482         case SEND_WSC_NACK:
483                 msg = wps_build_wsc_nack(wps);
484                 *op_code = WSC_NACK;
485                 break;
486         case WPS_MSG_DONE:
487                 msg = wps_build_wsc_done(wps);
488                 *op_code = WSC_Done;
489                 break;
490         default:
491                 wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
492                            "a message", wps->state);
493                 msg = NULL;
494                 break;
495         }
496
497         if (*op_code == WSC_MSG && msg) {
498                 /* Save a copy of the last message for Authenticator derivation
499                  */
500                 wpabuf_free(wps->last_msg);
501                 wps->last_msg = wpabuf_dup(msg);
502         }
503
504         return msg;
505 }
506
507
508 static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
509 {
510         if (r_nonce == NULL) {
511                 wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
512                 return -1;
513         }
514
515         os_memcpy(wps->nonce_r, r_nonce, WPS_NONCE_LEN);
516         wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
517                     wps->nonce_r, WPS_NONCE_LEN);
518
519         return 0;
520 }
521
522
523 static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
524 {
525         if (e_nonce == NULL) {
526                 wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
527                 return -1;
528         }
529
530         if (os_memcmp(wps->nonce_e, e_nonce, WPS_NONCE_LEN) != 0) {
531                 wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce received");
532                 return -1;
533         }
534
535         return 0;
536 }
537
538
539 static int wps_process_uuid_r(struct wps_data *wps, const u8 *uuid_r)
540 {
541         if (uuid_r == NULL) {
542                 wpa_printf(MSG_DEBUG, "WPS: No UUID-R received");
543                 return -1;
544         }
545
546         os_memcpy(wps->uuid_r, uuid_r, WPS_UUID_LEN);
547         wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
548
549         return 0;
550 }
551
552
553 static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
554                               size_t pk_len)
555 {
556         if (pk == NULL || pk_len == 0) {
557                 wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
558                 return -1;
559         }
560
561         if (wps->peer_pubkey_hash_set) {
562                 u8 hash[WPS_HASH_LEN];
563                 sha256_vector(1, &pk, &pk_len, hash);
564                 if (os_memcmp_const(hash, wps->peer_pubkey_hash,
565                                     WPS_OOB_PUBKEY_HASH_LEN) != 0) {
566                         wpa_printf(MSG_ERROR, "WPS: Public Key hash mismatch");
567                         wpa_hexdump(MSG_DEBUG, "WPS: Received public key",
568                                     pk, pk_len);
569                         wpa_hexdump(MSG_DEBUG, "WPS: Calculated public key "
570                                     "hash", hash, WPS_OOB_PUBKEY_HASH_LEN);
571                         wpa_hexdump(MSG_DEBUG, "WPS: Expected public key hash",
572                                     wps->peer_pubkey_hash,
573                                     WPS_OOB_PUBKEY_HASH_LEN);
574                         wps->config_error = WPS_CFG_PUBLIC_KEY_HASH_MISMATCH;
575                         return -1;
576                 }
577         }
578
579         wpabuf_free(wps->dh_pubkey_r);
580         wps->dh_pubkey_r = wpabuf_alloc_copy(pk, pk_len);
581         if (wps->dh_pubkey_r == NULL)
582                 return -1;
583
584         if (wps_derive_keys(wps) < 0)
585                 return -1;
586
587         return 0;
588 }
589
590
591 static int wps_process_r_hash1(struct wps_data *wps, const u8 *r_hash1)
592 {
593         if (r_hash1 == NULL) {
594                 wpa_printf(MSG_DEBUG, "WPS: No R-Hash1 received");
595                 return -1;
596         }
597
598         os_memcpy(wps->peer_hash1, r_hash1, WPS_HASH_LEN);
599         wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", wps->peer_hash1, WPS_HASH_LEN);
600
601         return 0;
602 }
603
604
605 static int wps_process_r_hash2(struct wps_data *wps, const u8 *r_hash2)
606 {
607         if (r_hash2 == NULL) {
608                 wpa_printf(MSG_DEBUG, "WPS: No R-Hash2 received");
609                 return -1;
610         }
611
612         os_memcpy(wps->peer_hash2, r_hash2, WPS_HASH_LEN);
613         wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", wps->peer_hash2, WPS_HASH_LEN);
614
615         return 0;
616 }
617
618
619 static int wps_process_r_snonce1(struct wps_data *wps, const u8 *r_snonce1)
620 {
621         u8 hash[SHA256_MAC_LEN];
622         const u8 *addr[4];
623         size_t len[4];
624
625         if (r_snonce1 == NULL) {
626                 wpa_printf(MSG_DEBUG, "WPS: No R-SNonce1 received");
627                 return -1;
628         }
629
630         wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce1", r_snonce1,
631                         WPS_SECRET_NONCE_LEN);
632
633         /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
634         addr[0] = r_snonce1;
635         len[0] = WPS_SECRET_NONCE_LEN;
636         addr[1] = wps->psk1;
637         len[1] = WPS_PSK_LEN;
638         addr[2] = wpabuf_head(wps->dh_pubkey_e);
639         len[2] = wpabuf_len(wps->dh_pubkey_e);
640         addr[3] = wpabuf_head(wps->dh_pubkey_r);
641         len[3] = wpabuf_len(wps->dh_pubkey_r);
642         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
643
644         if (os_memcmp_const(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
645                 wpa_printf(MSG_DEBUG, "WPS: R-Hash1 derived from R-S1 does "
646                            "not match with the pre-committed value");
647                 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
648                 wps_pwd_auth_fail_event(wps->wps, 1, 1, wps->peer_dev.mac_addr);
649                 return -1;
650         }
651
652         wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the first "
653                    "half of the device password");
654
655         return 0;
656 }
657
658
659 static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2)
660 {
661         u8 hash[SHA256_MAC_LEN];
662         const u8 *addr[4];
663         size_t len[4];
664
665         if (r_snonce2 == NULL) {
666                 wpa_printf(MSG_DEBUG, "WPS: No R-SNonce2 received");
667                 return -1;
668         }
669
670         wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce2", r_snonce2,
671                         WPS_SECRET_NONCE_LEN);
672
673         /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
674         addr[0] = r_snonce2;
675         len[0] = WPS_SECRET_NONCE_LEN;
676         addr[1] = wps->psk2;
677         len[1] = WPS_PSK_LEN;
678         addr[2] = wpabuf_head(wps->dh_pubkey_e);
679         len[2] = wpabuf_len(wps->dh_pubkey_e);
680         addr[3] = wpabuf_head(wps->dh_pubkey_r);
681         len[3] = wpabuf_len(wps->dh_pubkey_r);
682         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
683
684         if (os_memcmp_const(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
685                 wpa_printf(MSG_DEBUG, "WPS: R-Hash2 derived from R-S2 does "
686                            "not match with the pre-committed value");
687                 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
688                 wps_pwd_auth_fail_event(wps->wps, 1, 2, wps->peer_dev.mac_addr);
689                 return -1;
690         }
691
692         wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the second "
693                    "half of the device password");
694
695         return 0;
696 }
697
698
699 static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
700                               size_t cred_len, int wps2)
701 {
702         struct wps_parse_attr attr;
703         struct wpabuf msg;
704         int ret = 0;
705
706         wpa_printf(MSG_DEBUG, "WPS: Received Credential");
707         os_memset(&wps->cred, 0, sizeof(wps->cred));
708         wpabuf_set(&msg, cred, cred_len);
709         if (wps_parse_msg(&msg, &attr) < 0 ||
710             wps_process_cred(&attr, &wps->cred))
711                 return -1;
712
713         if (os_memcmp(wps->cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN) !=
714             0) {
715                 wpa_printf(MSG_DEBUG, "WPS: MAC Address in the Credential ("
716                            MACSTR ") does not match with own address (" MACSTR
717                            ")", MAC2STR(wps->cred.mac_addr),
718                            MAC2STR(wps->wps->dev.mac_addr));
719                 /*
720                  * In theory, this could be consider fatal error, but there are
721                  * number of deployed implementations using other address here
722                  * due to unclarity in the specification. For interoperability
723                  * reasons, allow this to be processed since we do not really
724                  * use the MAC Address information for anything.
725                  */
726 #ifdef CONFIG_WPS_STRICT
727                 if (wps2) {
728                         wpa_printf(MSG_INFO, "WPS: Do not accept incorrect "
729                                    "MAC Address in AP Settings");
730                         return -1;
731                 }
732 #endif /* CONFIG_WPS_STRICT */
733         }
734
735         if (!(wps->cred.encr_type &
736               (WPS_ENCR_NONE | WPS_ENCR_TKIP | WPS_ENCR_AES))) {
737                 if (wps->cred.encr_type & WPS_ENCR_WEP) {
738                         wpa_printf(MSG_INFO, "WPS: Reject Credential "
739                                    "due to WEP configuration");
740                         wps->error_indication = WPS_EI_SECURITY_WEP_PROHIBITED;
741                         return -2;
742                 }
743
744                 wpa_printf(MSG_INFO, "WPS: Reject Credential due to "
745                            "invalid encr_type 0x%x", wps->cred.encr_type);
746                 return -1;
747         }
748
749         if (wps->wps->cred_cb) {
750                 wps->cred.cred_attr = cred - 4;
751                 wps->cred.cred_attr_len = cred_len + 4;
752                 ret = wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
753                 wps->cred.cred_attr = NULL;
754                 wps->cred.cred_attr_len = 0;
755         }
756
757         return ret;
758 }
759
760
761 static int wps_process_creds(struct wps_data *wps, const u8 *cred[],
762                              u16 cred_len[], unsigned int num_cred, int wps2)
763 {
764         size_t i;
765         int ok = 0;
766
767         if (wps->wps->ap)
768                 return 0;
769
770         if (num_cred == 0) {
771                 wpa_printf(MSG_DEBUG, "WPS: No Credential attributes "
772                            "received");
773                 return -1;
774         }
775
776         for (i = 0; i < num_cred; i++) {
777                 int res;
778                 res = wps_process_cred_e(wps, cred[i], cred_len[i], wps2);
779                 if (res == 0)
780                         ok++;
781                 else if (res == -2)
782                         wpa_printf(MSG_DEBUG, "WPS: WEP credential skipped");
783                 else
784                         return -1;
785         }
786
787         if (ok == 0) {
788                 wpa_printf(MSG_DEBUG, "WPS: No valid Credential attribute "
789                            "received");
790                 return -1;
791         }
792
793         return 0;
794 }
795
796
797 static int wps_process_ap_settings_e(struct wps_data *wps,
798                                      struct wps_parse_attr *attr,
799                                      struct wpabuf *attrs, int wps2)
800 {
801         struct wps_credential cred;
802         int ret = 0;
803
804         if (!wps->wps->ap)
805                 return 0;
806
807         if (wps_process_ap_settings(attr, &cred) < 0)
808                 return -1;
809
810         wpa_printf(MSG_INFO, "WPS: Received new AP configuration from "
811                    "Registrar");
812
813         if (os_memcmp(cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN) !=
814             0) {
815                 wpa_printf(MSG_DEBUG, "WPS: MAC Address in the AP Settings ("
816                            MACSTR ") does not match with own address (" MACSTR
817                            ")", MAC2STR(cred.mac_addr),
818                            MAC2STR(wps->wps->dev.mac_addr));
819                 /*
820                  * In theory, this could be consider fatal error, but there are
821                  * number of deployed implementations using other address here
822                  * due to unclarity in the specification. For interoperability
823                  * reasons, allow this to be processed since we do not really
824                  * use the MAC Address information for anything.
825                  */
826 #ifdef CONFIG_WPS_STRICT
827                 if (wps2) {
828                         wpa_printf(MSG_INFO, "WPS: Do not accept incorrect "
829                                    "MAC Address in AP Settings");
830                         return -1;
831                 }
832 #endif /* CONFIG_WPS_STRICT */
833         }
834
835         if (!(cred.encr_type & (WPS_ENCR_NONE | WPS_ENCR_TKIP | WPS_ENCR_AES)))
836         {
837                 if (cred.encr_type & WPS_ENCR_WEP) {
838                         wpa_printf(MSG_INFO, "WPS: Reject new AP settings "
839                                    "due to WEP configuration");
840                         wps->error_indication = WPS_EI_SECURITY_WEP_PROHIBITED;
841                         return -1;
842                 }
843
844                 wpa_printf(MSG_INFO, "WPS: Reject new AP settings due to "
845                            "invalid encr_type 0x%x", cred.encr_type);
846                 return -1;
847         }
848
849 #ifdef CONFIG_WPS_STRICT
850         if (wps2) {
851                 if ((cred.encr_type & (WPS_ENCR_TKIP | WPS_ENCR_AES)) ==
852                     WPS_ENCR_TKIP ||
853                     (cred.auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) ==
854                     WPS_AUTH_WPAPSK) {
855                         wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC 2.0 "
856                                    "AP Settings: WPA-Personal/TKIP only");
857                         wps->error_indication =
858                                 WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED;
859                         return -1;
860                 }
861         }
862 #endif /* CONFIG_WPS_STRICT */
863
864         if ((cred.encr_type & (WPS_ENCR_TKIP | WPS_ENCR_AES)) == WPS_ENCR_TKIP)
865         {
866                 wpa_printf(MSG_DEBUG, "WPS: Upgrade encr_type TKIP -> "
867                            "TKIP+AES");
868                 cred.encr_type |= WPS_ENCR_AES;
869         }
870
871         if ((cred.auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) ==
872             WPS_AUTH_WPAPSK) {
873                 wpa_printf(MSG_DEBUG, "WPS: Upgrade auth_type WPAPSK -> "
874                            "WPAPSK+WPA2PSK");
875                 cred.auth_type |= WPS_AUTH_WPA2PSK;
876         }
877
878         if (wps->wps->cred_cb) {
879                 cred.cred_attr = wpabuf_head(attrs);
880                 cred.cred_attr_len = wpabuf_len(attrs);
881                 ret = wps->wps->cred_cb(wps->wps->cb_ctx, &cred);
882         }
883
884         return ret;
885 }
886
887
888 static int wps_process_dev_pw_id(struct wps_data *wps, const u8 *dev_pw_id)
889 {
890         u16 id;
891
892         if (dev_pw_id == NULL) {
893                 wpa_printf(MSG_DEBUG, "WPS: Device Password ID");
894                 return -1;
895         }
896
897         id = WPA_GET_BE16(dev_pw_id);
898         if (wps->dev_pw_id == id) {
899                 wpa_printf(MSG_DEBUG, "WPS: Device Password ID %u", id);
900                 return 0;
901         }
902
903 #ifdef CONFIG_P2P
904         if ((id == DEV_PW_DEFAULT &&
905              wps->dev_pw_id == DEV_PW_REGISTRAR_SPECIFIED) ||
906             (id == DEV_PW_REGISTRAR_SPECIFIED &&
907              wps->dev_pw_id == DEV_PW_DEFAULT)) {
908                 /*
909                  * Common P2P use cases indicate whether the PIN is from the
910                  * client or GO using Device Password Id in M1/M2 in a way that
911                  * does not look fully compliant with WSC specification. Anyway,
912                  * this is deployed and needs to be allowed, so ignore changes
913                  * between Registrar-Specified and Default PIN.
914                  */
915                 wpa_printf(MSG_DEBUG, "WPS: Allow PIN Device Password ID "
916                            "change");
917                 return 0;
918         }
919 #endif /* CONFIG_P2P */
920
921         wpa_printf(MSG_DEBUG, "WPS: Registrar trying to change Device Password "
922                    "ID from %u to %u", wps->dev_pw_id, id);
923
924         if (wps->dev_pw_id == DEV_PW_PUSHBUTTON && id == DEV_PW_DEFAULT) {
925                 wpa_printf(MSG_DEBUG,
926                            "WPS: Workaround - ignore PBC-to-PIN change");
927                 return 0;
928         }
929
930         if (wps->alt_dev_password && wps->alt_dev_pw_id == id) {
931                 wpa_printf(MSG_DEBUG, "WPS: Found a matching Device Password");
932                 bin_clear_free(wps->dev_password, wps->dev_password_len);
933                 wps->dev_pw_id = wps->alt_dev_pw_id;
934                 wps->dev_password = wps->alt_dev_password;
935                 wps->dev_password_len = wps->alt_dev_password_len;
936                 wps->alt_dev_password = NULL;
937                 wps->alt_dev_password_len = 0;
938                 return 0;
939         }
940
941         return -1;
942 }
943
944
945 static enum wps_process_res wps_process_m2(struct wps_data *wps,
946                                            const struct wpabuf *msg,
947                                            struct wps_parse_attr *attr)
948 {
949         wpa_printf(MSG_DEBUG, "WPS: Received M2");
950
951         if (wps->state != RECV_M2) {
952                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
953                            "receiving M2", wps->state);
954                 wps->state = SEND_WSC_NACK;
955                 return WPS_CONTINUE;
956         }
957
958         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
959             wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
960             wps_process_uuid_r(wps, attr->uuid_r) ||
961             wps_process_dev_pw_id(wps, attr->dev_password_id)) {
962                 wps->state = SEND_WSC_NACK;
963                 return WPS_CONTINUE;
964         }
965
966         /*
967          * Stop here on an AP as an Enrollee if AP Setup is locked unless the
968          * special locked mode is used to allow protocol run up to M7 in order
969          * to support external Registrars that only learn the current AP
970          * configuration without changing it.
971          */
972         if (wps->wps->ap &&
973             ((wps->wps->ap_setup_locked && wps->wps->ap_setup_locked != 2) ||
974              wps->dev_password == NULL)) {
975                 wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse "
976                            "registration of a new Registrar");
977                 wps->config_error = WPS_CFG_SETUP_LOCKED;
978                 wps->state = SEND_WSC_NACK;
979                 return WPS_CONTINUE;
980         }
981
982         if (wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
983             wps_process_authenticator(wps, attr->authenticator, msg) ||
984             wps_process_device_attrs(&wps->peer_dev, attr)) {
985                 wps->state = SEND_WSC_NACK;
986                 return WPS_CONTINUE;
987         }
988
989 #ifdef CONFIG_WPS_NFC
990         if (wps->peer_pubkey_hash_set) {
991                 struct wpabuf *decrypted;
992                 struct wps_parse_attr eattr;
993
994                 decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
995                                                       attr->encr_settings_len);
996                 if (decrypted == NULL) {
997                         wpa_printf(MSG_DEBUG, "WPS: Failed to decrypt "
998                                    "Encrypted Settings attribute");
999                         wps->state = SEND_WSC_NACK;
1000                         return WPS_CONTINUE;
1001                 }
1002
1003                 wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted "
1004                            "Settings attribute");
1005                 if (wps_parse_msg(decrypted, &eattr) < 0 ||
1006                     wps_process_key_wrap_auth(wps, decrypted,
1007                                               eattr.key_wrap_auth) ||
1008                     wps_process_creds(wps, eattr.cred, eattr.cred_len,
1009                                       eattr.num_cred, attr->version2 != NULL)) {
1010                         wpabuf_free(decrypted);
1011                         wps->state = SEND_WSC_NACK;
1012                         return WPS_CONTINUE;
1013                 }
1014                 wpabuf_free(decrypted);
1015
1016                 wps->state = WPS_MSG_DONE;
1017                 return WPS_CONTINUE;
1018         }
1019 #endif /* CONFIG_WPS_NFC */
1020
1021         wps->state = SEND_M3;
1022         return WPS_CONTINUE;
1023 }
1024
1025
1026 static enum wps_process_res wps_process_m2d(struct wps_data *wps,
1027                                             struct wps_parse_attr *attr)
1028 {
1029         wpa_printf(MSG_DEBUG, "WPS: Received M2D");
1030
1031         if (wps->state != RECV_M2) {
1032                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1033                            "receiving M2D", wps->state);
1034                 wps->state = SEND_WSC_NACK;
1035                 return WPS_CONTINUE;
1036         }
1037
1038         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer",
1039                           attr->manufacturer, attr->manufacturer_len);
1040         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name",
1041                           attr->model_name, attr->model_name_len);
1042         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number",
1043                           attr->model_number, attr->model_number_len);
1044         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number",
1045                           attr->serial_number, attr->serial_number_len);
1046         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name",
1047                           attr->dev_name, attr->dev_name_len);
1048
1049         if (wps->wps->event_cb) {
1050                 union wps_event_data data;
1051                 struct wps_event_m2d *m2d = &data.m2d;
1052                 os_memset(&data, 0, sizeof(data));
1053                 if (attr->config_methods)
1054                         m2d->config_methods =
1055                                 WPA_GET_BE16(attr->config_methods);
1056                 m2d->manufacturer = attr->manufacturer;
1057                 m2d->manufacturer_len = attr->manufacturer_len;
1058                 m2d->model_name = attr->model_name;
1059                 m2d->model_name_len = attr->model_name_len;
1060                 m2d->model_number = attr->model_number;
1061                 m2d->model_number_len = attr->model_number_len;
1062                 m2d->serial_number = attr->serial_number;
1063                 m2d->serial_number_len = attr->serial_number_len;
1064                 m2d->dev_name = attr->dev_name;
1065                 m2d->dev_name_len = attr->dev_name_len;
1066                 m2d->primary_dev_type = attr->primary_dev_type;
1067                 if (attr->config_error)
1068                         m2d->config_error =
1069                                 WPA_GET_BE16(attr->config_error);
1070                 if (attr->dev_password_id)
1071                         m2d->dev_password_id =
1072                                 WPA_GET_BE16(attr->dev_password_id);
1073                 wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_M2D, &data);
1074         }
1075
1076         wps->state = RECEIVED_M2D;
1077         return WPS_CONTINUE;
1078 }
1079
1080
1081 static enum wps_process_res wps_process_m4(struct wps_data *wps,
1082                                            const struct wpabuf *msg,
1083                                            struct wps_parse_attr *attr)
1084 {
1085         struct wpabuf *decrypted;
1086         struct wps_parse_attr eattr;
1087
1088         wpa_printf(MSG_DEBUG, "WPS: Received M4");
1089
1090         if (wps->state != RECV_M4) {
1091                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1092                            "receiving M4", wps->state);
1093                 wps->state = SEND_WSC_NACK;
1094                 return WPS_CONTINUE;
1095         }
1096
1097         if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
1098             wps_process_authenticator(wps, attr->authenticator, msg) ||
1099             wps_process_r_hash1(wps, attr->r_hash1) ||
1100             wps_process_r_hash2(wps, attr->r_hash2)) {
1101                 wps->state = SEND_WSC_NACK;
1102                 return WPS_CONTINUE;
1103         }
1104
1105         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1106                                               attr->encr_settings_len);
1107         if (decrypted == NULL) {
1108                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
1109                            "Settings attribute");
1110                 wps->state = SEND_WSC_NACK;
1111                 return WPS_CONTINUE;
1112         }
1113
1114         if (wps_validate_m4_encr(decrypted, attr->version2 != NULL) < 0) {
1115                 wpabuf_free(decrypted);
1116                 wps->state = SEND_WSC_NACK;
1117                 return WPS_CONTINUE;
1118         }
1119
1120         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
1121                    "attribute");
1122         if (wps_parse_msg(decrypted, &eattr) < 0 ||
1123             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
1124             wps_process_r_snonce1(wps, eattr.r_snonce1)) {
1125                 wpabuf_free(decrypted);
1126                 wps->state = SEND_WSC_NACK;
1127                 return WPS_CONTINUE;
1128         }
1129         wpabuf_free(decrypted);
1130
1131         wps->state = SEND_M5;
1132         return WPS_CONTINUE;
1133 }
1134
1135
1136 static enum wps_process_res wps_process_m6(struct wps_data *wps,
1137                                            const struct wpabuf *msg,
1138                                            struct wps_parse_attr *attr)
1139 {
1140         struct wpabuf *decrypted;
1141         struct wps_parse_attr eattr;
1142
1143         wpa_printf(MSG_DEBUG, "WPS: Received M6");
1144
1145         if (wps->state != RECV_M6) {
1146                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1147                            "receiving M6", wps->state);
1148                 wps->state = SEND_WSC_NACK;
1149                 return WPS_CONTINUE;
1150         }
1151
1152         if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
1153             wps_process_authenticator(wps, attr->authenticator, msg)) {
1154                 wps->state = SEND_WSC_NACK;
1155                 return WPS_CONTINUE;
1156         }
1157
1158         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1159                                               attr->encr_settings_len);
1160         if (decrypted == NULL) {
1161                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
1162                            "Settings attribute");
1163                 wps->state = SEND_WSC_NACK;
1164                 return WPS_CONTINUE;
1165         }
1166
1167         if (wps_validate_m6_encr(decrypted, attr->version2 != NULL) < 0) {
1168                 wpabuf_free(decrypted);
1169                 wps->state = SEND_WSC_NACK;
1170                 return WPS_CONTINUE;
1171         }
1172
1173         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
1174                    "attribute");
1175         if (wps_parse_msg(decrypted, &eattr) < 0 ||
1176             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
1177             wps_process_r_snonce2(wps, eattr.r_snonce2)) {
1178                 wpabuf_free(decrypted);
1179                 wps->state = SEND_WSC_NACK;
1180                 return WPS_CONTINUE;
1181         }
1182         wpabuf_free(decrypted);
1183
1184         if (wps->wps->ap)
1185                 wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_AP_PIN_SUCCESS,
1186                                    NULL);
1187
1188         wps->state = SEND_M7;
1189         return WPS_CONTINUE;
1190 }
1191
1192
1193 static enum wps_process_res wps_process_m8(struct wps_data *wps,
1194                                            const struct wpabuf *msg,
1195                                            struct wps_parse_attr *attr)
1196 {
1197         struct wpabuf *decrypted;
1198         struct wps_parse_attr eattr;
1199
1200         wpa_printf(MSG_DEBUG, "WPS: Received M8");
1201
1202         if (wps->state != RECV_M8) {
1203                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1204                            "receiving M8", wps->state);
1205                 wps->state = SEND_WSC_NACK;
1206                 return WPS_CONTINUE;
1207         }
1208
1209         if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
1210             wps_process_authenticator(wps, attr->authenticator, msg)) {
1211                 wps->state = SEND_WSC_NACK;
1212                 return WPS_CONTINUE;
1213         }
1214
1215         if (wps->wps->ap && wps->wps->ap_setup_locked) {
1216                 /*
1217                  * Stop here if special ap_setup_locked == 2 mode allowed the
1218                  * protocol to continue beyond M2. This allows ER to learn the
1219                  * current AP settings without changing them.
1220                  */
1221                 wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse "
1222                            "registration of a new Registrar");
1223                 wps->config_error = WPS_CFG_SETUP_LOCKED;
1224                 wps->state = SEND_WSC_NACK;
1225                 return WPS_CONTINUE;
1226         }
1227
1228         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1229                                               attr->encr_settings_len);
1230         if (decrypted == NULL) {
1231                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
1232                            "Settings attribute");
1233                 wps->state = SEND_WSC_NACK;
1234                 return WPS_CONTINUE;
1235         }
1236
1237         if (wps_validate_m8_encr(decrypted, wps->wps->ap,
1238                                  attr->version2 != NULL) < 0) {
1239                 wpabuf_free(decrypted);
1240                 wps->state = SEND_WSC_NACK;
1241                 return WPS_CONTINUE;
1242         }
1243
1244         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
1245                    "attribute");
1246         if (wps_parse_msg(decrypted, &eattr) < 0 ||
1247             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
1248             wps_process_creds(wps, eattr.cred, eattr.cred_len,
1249                               eattr.num_cred, attr->version2 != NULL) ||
1250             wps_process_ap_settings_e(wps, &eattr, decrypted,
1251                                       attr->version2 != NULL)) {
1252                 wpabuf_free(decrypted);
1253                 wps->state = SEND_WSC_NACK;
1254                 return WPS_CONTINUE;
1255         }
1256         wpabuf_free(decrypted);
1257
1258         wps->state = WPS_MSG_DONE;
1259         return WPS_CONTINUE;
1260 }
1261
1262
1263 static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
1264                                                 const struct wpabuf *msg)
1265 {
1266         struct wps_parse_attr attr;
1267         enum wps_process_res ret = WPS_CONTINUE;
1268
1269         wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
1270
1271         if (wps_parse_msg(msg, &attr) < 0)
1272                 return WPS_FAILURE;
1273
1274         if (attr.enrollee_nonce == NULL ||
1275             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
1276                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1277                 return WPS_FAILURE;
1278         }
1279
1280         if (attr.msg_type == NULL) {
1281                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1282                 wps->state = SEND_WSC_NACK;
1283                 return WPS_CONTINUE;
1284         }
1285
1286         switch (*attr.msg_type) {
1287         case WPS_M2:
1288                 if (wps_validate_m2(msg) < 0)
1289                         return WPS_FAILURE;
1290                 ret = wps_process_m2(wps, msg, &attr);
1291                 break;
1292         case WPS_M2D:
1293                 if (wps_validate_m2d(msg) < 0)
1294                         return WPS_FAILURE;
1295                 ret = wps_process_m2d(wps, &attr);
1296                 break;
1297         case WPS_M4:
1298                 if (wps_validate_m4(msg) < 0)
1299                         return WPS_FAILURE;
1300                 ret = wps_process_m4(wps, msg, &attr);
1301                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
1302                         wps_fail_event(wps->wps, WPS_M4, wps->config_error,
1303                                        wps->error_indication,
1304                                        wps->peer_dev.mac_addr);
1305                 break;
1306         case WPS_M6:
1307                 if (wps_validate_m6(msg) < 0)
1308                         return WPS_FAILURE;
1309                 ret = wps_process_m6(wps, msg, &attr);
1310                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
1311                         wps_fail_event(wps->wps, WPS_M6, wps->config_error,
1312                                        wps->error_indication,
1313                                        wps->peer_dev.mac_addr);
1314                 break;
1315         case WPS_M8:
1316                 if (wps_validate_m8(msg) < 0)
1317                         return WPS_FAILURE;
1318                 ret = wps_process_m8(wps, msg, &attr);
1319                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
1320                         wps_fail_event(wps->wps, WPS_M8, wps->config_error,
1321                                        wps->error_indication,
1322                                        wps->peer_dev.mac_addr);
1323                 break;
1324         default:
1325                 wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
1326                            *attr.msg_type);
1327                 return WPS_FAILURE;
1328         }
1329
1330         /*
1331          * Save a copy of the last message for Authenticator derivation if we
1332          * are continuing. However, skip M2D since it is not authenticated and
1333          * neither is the ACK/NACK response frame. This allows the possibly
1334          * following M2 to be processed correctly by using the previously sent
1335          * M1 in Authenticator derivation.
1336          */
1337         if (ret == WPS_CONTINUE && *attr.msg_type != WPS_M2D) {
1338                 /* Save a copy of the last message for Authenticator derivation
1339                  */
1340                 wpabuf_free(wps->last_msg);
1341                 wps->last_msg = wpabuf_dup(msg);
1342         }
1343
1344         return ret;
1345 }
1346
1347
1348 static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
1349                                                 const struct wpabuf *msg)
1350 {
1351         struct wps_parse_attr attr;
1352
1353         wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
1354
1355         if (wps_parse_msg(msg, &attr) < 0)
1356                 return WPS_FAILURE;
1357
1358         if (attr.msg_type == NULL) {
1359                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1360                 return WPS_FAILURE;
1361         }
1362
1363         if (*attr.msg_type != WPS_WSC_ACK) {
1364                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
1365                            *attr.msg_type);
1366                 return WPS_FAILURE;
1367         }
1368
1369         if (attr.registrar_nonce == NULL ||
1370             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
1371         {
1372                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
1373                 return WPS_FAILURE;
1374         }
1375
1376         if (attr.enrollee_nonce == NULL ||
1377             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
1378                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1379                 return WPS_FAILURE;
1380         }
1381
1382         if (wps->state == RECV_ACK && wps->wps->ap) {
1383                 wpa_printf(MSG_DEBUG, "WPS: External Registrar registration "
1384                            "completed successfully");
1385                 wps_success_event(wps->wps, wps->peer_dev.mac_addr);
1386                 wps->state = WPS_FINISHED;
1387                 return WPS_DONE;
1388         }
1389
1390         return WPS_FAILURE;
1391 }
1392
1393
1394 static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
1395                                                  const struct wpabuf *msg)
1396 {
1397         struct wps_parse_attr attr;
1398         u16 config_error;
1399
1400         wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
1401
1402         if (wps_parse_msg(msg, &attr) < 0)
1403                 return WPS_FAILURE;
1404
1405         if (attr.msg_type == NULL) {
1406                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1407                 return WPS_FAILURE;
1408         }
1409
1410         if (*attr.msg_type != WPS_WSC_NACK) {
1411                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
1412                            *attr.msg_type);
1413                 return WPS_FAILURE;
1414         }
1415
1416         if (attr.registrar_nonce == NULL ||
1417             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
1418         {
1419                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
1420                 wpa_hexdump(MSG_DEBUG, "WPS: Received Registrar Nonce",
1421                             attr.registrar_nonce, WPS_NONCE_LEN);
1422                 wpa_hexdump(MSG_DEBUG, "WPS: Expected Registrar Nonce",
1423                             wps->nonce_r, WPS_NONCE_LEN);
1424                 return WPS_FAILURE;
1425         }
1426
1427         if (attr.enrollee_nonce == NULL ||
1428             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
1429                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1430                 wpa_hexdump(MSG_DEBUG, "WPS: Received Enrollee Nonce",
1431                             attr.enrollee_nonce, WPS_NONCE_LEN);
1432                 wpa_hexdump(MSG_DEBUG, "WPS: Expected Enrollee Nonce",
1433                             wps->nonce_e, WPS_NONCE_LEN);
1434                 return WPS_FAILURE;
1435         }
1436
1437         if (attr.config_error == NULL) {
1438                 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
1439                            "in WSC_NACK");
1440                 return WPS_FAILURE;
1441         }
1442
1443         config_error = WPA_GET_BE16(attr.config_error);
1444         wpa_printf(MSG_DEBUG, "WPS: Registrar terminated negotiation with "
1445                    "Configuration Error %d", config_error);
1446
1447         switch (wps->state) {
1448         case RECV_M4:
1449                 wps_fail_event(wps->wps, WPS_M3, config_error,
1450                                wps->error_indication, wps->peer_dev.mac_addr);
1451                 break;
1452         case RECV_M6:
1453                 wps_fail_event(wps->wps, WPS_M5, config_error,
1454                                wps->error_indication, wps->peer_dev.mac_addr);
1455                 break;
1456         case RECV_M8:
1457                 wps_fail_event(wps->wps, WPS_M7, config_error,
1458                                wps->error_indication, wps->peer_dev.mac_addr);
1459                 break;
1460         default:
1461                 break;
1462         }
1463
1464         /* Followed by NACK if Enrollee is Supplicant or EAP-Failure if
1465          * Enrollee is Authenticator */
1466         wps->state = SEND_WSC_NACK;
1467
1468         return WPS_FAILURE;
1469 }
1470
1471
1472 enum wps_process_res wps_enrollee_process_msg(struct wps_data *wps,
1473                                               enum wsc_op_code op_code,
1474                                               const struct wpabuf *msg)
1475 {
1476
1477         wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
1478                    "op_code=%d)",
1479                    (unsigned long) wpabuf_len(msg), op_code);
1480
1481         if (op_code == WSC_UPnP) {
1482                 /* Determine the OpCode based on message type attribute */
1483                 struct wps_parse_attr attr;
1484                 if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type) {
1485                         if (*attr.msg_type == WPS_WSC_ACK)
1486                                 op_code = WSC_ACK;
1487                         else if (*attr.msg_type == WPS_WSC_NACK)
1488                                 op_code = WSC_NACK;
1489                 }
1490         }
1491
1492         switch (op_code) {
1493         case WSC_MSG:
1494         case WSC_UPnP:
1495                 return wps_process_wsc_msg(wps, msg);
1496         case WSC_ACK:
1497                 if (wps_validate_wsc_ack(msg) < 0)
1498                         return WPS_FAILURE;
1499                 return wps_process_wsc_ack(wps, msg);
1500         case WSC_NACK:
1501                 if (wps_validate_wsc_nack(msg) < 0)
1502                         return WPS_FAILURE;
1503                 return wps_process_wsc_nack(wps, msg);
1504         default:
1505                 wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
1506                 return WPS_FAILURE;
1507         }
1508 }