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