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