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