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