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