wps_enrollee.c revision 4b06059785b935dd1f4f09314e4e12c417d2c6a4
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	wpa_printf(MSG_DEBUG, "WPS: Registrar trying to change Device Password "
846		   "ID from %u to %u", wps->dev_pw_id, id);
847
848	if (wps->alt_dev_password && wps->alt_dev_pw_id == id) {
849		wpa_printf(MSG_DEBUG, "WPS: Found a matching Device Password");
850		os_free(wps->dev_password);
851		wps->dev_pw_id = wps->alt_dev_pw_id;
852		wps->dev_password = wps->alt_dev_password;
853		wps->dev_password_len = wps->alt_dev_password_len;
854		wps->alt_dev_password = NULL;
855		wps->alt_dev_password_len = 0;
856		return 0;
857	}
858
859	return -1;
860}
861
862
863static enum wps_process_res wps_process_m2(struct wps_data *wps,
864					   const struct wpabuf *msg,
865					   struct wps_parse_attr *attr)
866{
867	wpa_printf(MSG_DEBUG, "WPS: Received M2");
868
869	if (wps->state != RECV_M2) {
870		wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
871			   "receiving M2", wps->state);
872		wps->state = SEND_WSC_NACK;
873		return WPS_CONTINUE;
874	}
875
876	if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
877	    wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
878	    wps_process_uuid_r(wps, attr->uuid_r) ||
879	    wps_process_dev_pw_id(wps, attr->dev_password_id)) {
880		wps->state = SEND_WSC_NACK;
881		return WPS_CONTINUE;
882	}
883
884	/*
885	 * Stop here on an AP as an Enrollee if AP Setup is locked unless the
886	 * special locked mode is used to allow protocol run up to M7 in order
887	 * to support external Registrars that only learn the current AP
888	 * configuration without changing it.
889	 */
890	if (wps->wps->ap &&
891	    ((wps->wps->ap_setup_locked && wps->wps->ap_setup_locked != 2) ||
892	     wps->dev_password == NULL)) {
893		wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse "
894			   "registration of a new Registrar");
895		wps->config_error = WPS_CFG_SETUP_LOCKED;
896		wps->state = SEND_WSC_NACK;
897		return WPS_CONTINUE;
898	}
899
900	if (wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
901	    wps_process_authenticator(wps, attr->authenticator, msg) ||
902	    wps_process_device_attrs(&wps->peer_dev, attr)) {
903		wps->state = SEND_WSC_NACK;
904		return WPS_CONTINUE;
905	}
906
907	wps->state = SEND_M3;
908	return WPS_CONTINUE;
909}
910
911
912static enum wps_process_res wps_process_m2d(struct wps_data *wps,
913					    struct wps_parse_attr *attr)
914{
915	wpa_printf(MSG_DEBUG, "WPS: Received M2D");
916
917	if (wps->state != RECV_M2) {
918		wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
919			   "receiving M2D", wps->state);
920		wps->state = SEND_WSC_NACK;
921		return WPS_CONTINUE;
922	}
923
924	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer",
925			  attr->manufacturer, attr->manufacturer_len);
926	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name",
927			  attr->model_name, attr->model_name_len);
928	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number",
929			  attr->model_number, attr->model_number_len);
930	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number",
931			  attr->serial_number, attr->serial_number_len);
932	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name",
933			  attr->dev_name, attr->dev_name_len);
934
935	if (wps->wps->event_cb) {
936		union wps_event_data data;
937		struct wps_event_m2d *m2d = &data.m2d;
938		os_memset(&data, 0, sizeof(data));
939		if (attr->config_methods)
940			m2d->config_methods =
941				WPA_GET_BE16(attr->config_methods);
942		m2d->manufacturer = attr->manufacturer;
943		m2d->manufacturer_len = attr->manufacturer_len;
944		m2d->model_name = attr->model_name;
945		m2d->model_name_len = attr->model_name_len;
946		m2d->model_number = attr->model_number;
947		m2d->model_number_len = attr->model_number_len;
948		m2d->serial_number = attr->serial_number;
949		m2d->serial_number_len = attr->serial_number_len;
950		m2d->dev_name = attr->dev_name;
951		m2d->dev_name_len = attr->dev_name_len;
952		m2d->primary_dev_type = attr->primary_dev_type;
953		if (attr->config_error)
954			m2d->config_error =
955				WPA_GET_BE16(attr->config_error);
956		if (attr->dev_password_id)
957			m2d->dev_password_id =
958				WPA_GET_BE16(attr->dev_password_id);
959		wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_M2D, &data);
960	}
961
962	wps->state = RECEIVED_M2D;
963	return WPS_CONTINUE;
964}
965
966
967static enum wps_process_res wps_process_m4(struct wps_data *wps,
968					   const struct wpabuf *msg,
969					   struct wps_parse_attr *attr)
970{
971	struct wpabuf *decrypted;
972	struct wps_parse_attr eattr;
973
974	wpa_printf(MSG_DEBUG, "WPS: Received M4");
975
976	if (wps->state != RECV_M4) {
977		wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
978			   "receiving M4", wps->state);
979		wps->state = SEND_WSC_NACK;
980		return WPS_CONTINUE;
981	}
982
983	if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
984	    wps_process_authenticator(wps, attr->authenticator, msg) ||
985	    wps_process_r_hash1(wps, attr->r_hash1) ||
986	    wps_process_r_hash2(wps, attr->r_hash2)) {
987		wps->state = SEND_WSC_NACK;
988		return WPS_CONTINUE;
989	}
990
991	decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
992					      attr->encr_settings_len);
993	if (decrypted == NULL) {
994		wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
995			   "Settings attribute");
996		wps->state = SEND_WSC_NACK;
997		return WPS_CONTINUE;
998	}
999
1000	if (wps_validate_m4_encr(decrypted, attr->version2 != NULL) < 0) {
1001		wpabuf_free(decrypted);
1002		wps->state = SEND_WSC_NACK;
1003		return WPS_CONTINUE;
1004	}
1005
1006	wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
1007		   "attribute");
1008	if (wps_parse_msg(decrypted, &eattr) < 0 ||
1009	    wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
1010	    wps_process_r_snonce1(wps, eattr.r_snonce1)) {
1011		wpabuf_free(decrypted);
1012		wps->state = SEND_WSC_NACK;
1013		return WPS_CONTINUE;
1014	}
1015	wpabuf_free(decrypted);
1016
1017	wps->state = SEND_M5;
1018	return WPS_CONTINUE;
1019}
1020
1021
1022static enum wps_process_res wps_process_m6(struct wps_data *wps,
1023					   const struct wpabuf *msg,
1024					   struct wps_parse_attr *attr)
1025{
1026	struct wpabuf *decrypted;
1027	struct wps_parse_attr eattr;
1028
1029	wpa_printf(MSG_DEBUG, "WPS: Received M6");
1030
1031	if (wps->state != RECV_M6) {
1032		wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1033			   "receiving M6", wps->state);
1034		wps->state = SEND_WSC_NACK;
1035		return WPS_CONTINUE;
1036	}
1037
1038	if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
1039	    wps_process_authenticator(wps, attr->authenticator, msg)) {
1040		wps->state = SEND_WSC_NACK;
1041		return WPS_CONTINUE;
1042	}
1043
1044	decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1045					      attr->encr_settings_len);
1046	if (decrypted == NULL) {
1047		wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
1048			   "Settings attribute");
1049		wps->state = SEND_WSC_NACK;
1050		return WPS_CONTINUE;
1051	}
1052
1053	if (wps_validate_m6_encr(decrypted, attr->version2 != NULL) < 0) {
1054		wpabuf_free(decrypted);
1055		wps->state = SEND_WSC_NACK;
1056		return WPS_CONTINUE;
1057	}
1058
1059	wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
1060		   "attribute");
1061	if (wps_parse_msg(decrypted, &eattr) < 0 ||
1062	    wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
1063	    wps_process_r_snonce2(wps, eattr.r_snonce2)) {
1064		wpabuf_free(decrypted);
1065		wps->state = SEND_WSC_NACK;
1066		return WPS_CONTINUE;
1067	}
1068	wpabuf_free(decrypted);
1069
1070	if (wps->wps->ap)
1071		wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_AP_PIN_SUCCESS,
1072				   NULL);
1073
1074	wps->state = SEND_M7;
1075	return WPS_CONTINUE;
1076}
1077
1078
1079static enum wps_process_res wps_process_m8(struct wps_data *wps,
1080					   const struct wpabuf *msg,
1081					   struct wps_parse_attr *attr)
1082{
1083	struct wpabuf *decrypted;
1084	struct wps_parse_attr eattr;
1085
1086	wpa_printf(MSG_DEBUG, "WPS: Received M8");
1087
1088	if (wps->state != RECV_M8) {
1089		wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1090			   "receiving M8", wps->state);
1091		wps->state = SEND_WSC_NACK;
1092		return WPS_CONTINUE;
1093	}
1094
1095	if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
1096	    wps_process_authenticator(wps, attr->authenticator, msg)) {
1097		wps->state = SEND_WSC_NACK;
1098		return WPS_CONTINUE;
1099	}
1100
1101	if (wps->wps->ap && wps->wps->ap_setup_locked) {
1102		/*
1103		 * Stop here if special ap_setup_locked == 2 mode allowed the
1104		 * protocol to continue beyond M2. This allows ER to learn the
1105		 * current AP settings without changing them.
1106		 */
1107		wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse "
1108			   "registration of a new Registrar");
1109		wps->config_error = WPS_CFG_SETUP_LOCKED;
1110		wps->state = SEND_WSC_NACK;
1111		return WPS_CONTINUE;
1112	}
1113
1114	decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1115					      attr->encr_settings_len);
1116	if (decrypted == NULL) {
1117		wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
1118			   "Settings attribute");
1119		wps->state = SEND_WSC_NACK;
1120		return WPS_CONTINUE;
1121	}
1122
1123	if (wps_validate_m8_encr(decrypted, wps->wps->ap,
1124				 attr->version2 != NULL) < 0) {
1125		wpabuf_free(decrypted);
1126		wps->state = SEND_WSC_NACK;
1127		return WPS_CONTINUE;
1128	}
1129
1130	wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
1131		   "attribute");
1132	if (wps_parse_msg(decrypted, &eattr) < 0 ||
1133	    wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
1134	    wps_process_creds(wps, eattr.cred, eattr.cred_len,
1135			      eattr.num_cred, attr->version2 != NULL) ||
1136	    wps_process_ap_settings_e(wps, &eattr, decrypted,
1137				      attr->version2 != NULL)) {
1138		wpabuf_free(decrypted);
1139		wps->state = SEND_WSC_NACK;
1140		return WPS_CONTINUE;
1141	}
1142	wpabuf_free(decrypted);
1143
1144	wps->state = WPS_MSG_DONE;
1145	return WPS_CONTINUE;
1146}
1147
1148
1149static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
1150						const struct wpabuf *msg)
1151{
1152	struct wps_parse_attr attr;
1153	enum wps_process_res ret = WPS_CONTINUE;
1154
1155	wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
1156
1157	if (wps_parse_msg(msg, &attr) < 0)
1158		return WPS_FAILURE;
1159
1160	if (attr.enrollee_nonce == NULL ||
1161	    os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
1162		wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1163		return WPS_FAILURE;
1164	}
1165
1166	if (attr.msg_type == NULL) {
1167		wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1168		wps->state = SEND_WSC_NACK;
1169		return WPS_CONTINUE;
1170	}
1171
1172	switch (*attr.msg_type) {
1173	case WPS_M2:
1174		if (wps_validate_m2(msg) < 0)
1175			return WPS_FAILURE;
1176		ret = wps_process_m2(wps, msg, &attr);
1177		break;
1178	case WPS_M2D:
1179		if (wps_validate_m2d(msg) < 0)
1180			return WPS_FAILURE;
1181		ret = wps_process_m2d(wps, &attr);
1182		break;
1183	case WPS_M4:
1184		if (wps_validate_m4(msg) < 0)
1185			return WPS_FAILURE;
1186		ret = wps_process_m4(wps, msg, &attr);
1187		if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
1188			wps_fail_event(wps->wps, WPS_M4, wps->config_error,
1189				       wps->error_indication);
1190		break;
1191	case WPS_M6:
1192		if (wps_validate_m6(msg) < 0)
1193			return WPS_FAILURE;
1194		ret = wps_process_m6(wps, msg, &attr);
1195		if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
1196			wps_fail_event(wps->wps, WPS_M6, wps->config_error,
1197				       wps->error_indication);
1198		break;
1199	case WPS_M8:
1200		if (wps_validate_m8(msg) < 0)
1201			return WPS_FAILURE;
1202		ret = wps_process_m8(wps, msg, &attr);
1203		if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
1204			wps_fail_event(wps->wps, WPS_M8, wps->config_error,
1205				       wps->error_indication);
1206		break;
1207	default:
1208		wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
1209			   *attr.msg_type);
1210		return WPS_FAILURE;
1211	}
1212
1213	/*
1214	 * Save a copy of the last message for Authenticator derivation if we
1215	 * are continuing. However, skip M2D since it is not authenticated and
1216	 * neither is the ACK/NACK response frame. This allows the possibly
1217	 * following M2 to be processed correctly by using the previously sent
1218	 * M1 in Authenticator derivation.
1219	 */
1220	if (ret == WPS_CONTINUE && *attr.msg_type != WPS_M2D) {
1221		/* Save a copy of the last message for Authenticator derivation
1222		 */
1223		wpabuf_free(wps->last_msg);
1224		wps->last_msg = wpabuf_dup(msg);
1225	}
1226
1227	return ret;
1228}
1229
1230
1231static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
1232						const struct wpabuf *msg)
1233{
1234	struct wps_parse_attr attr;
1235
1236	wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
1237
1238	if (wps_parse_msg(msg, &attr) < 0)
1239		return WPS_FAILURE;
1240
1241	if (attr.msg_type == NULL) {
1242		wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1243		return WPS_FAILURE;
1244	}
1245
1246	if (*attr.msg_type != WPS_WSC_ACK) {
1247		wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
1248			   *attr.msg_type);
1249		return WPS_FAILURE;
1250	}
1251
1252	if (attr.registrar_nonce == NULL ||
1253	    os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
1254	{
1255		wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
1256		return WPS_FAILURE;
1257	}
1258
1259	if (attr.enrollee_nonce == NULL ||
1260	    os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
1261		wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1262		return WPS_FAILURE;
1263	}
1264
1265	if (wps->state == RECV_ACK && wps->wps->ap) {
1266		wpa_printf(MSG_DEBUG, "WPS: External Registrar registration "
1267			   "completed successfully");
1268		wps_success_event(wps->wps);
1269		wps->state = WPS_FINISHED;
1270		return WPS_DONE;
1271	}
1272
1273	return WPS_FAILURE;
1274}
1275
1276
1277static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
1278						 const struct wpabuf *msg)
1279{
1280	struct wps_parse_attr attr;
1281	u16 config_error;
1282
1283	wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
1284
1285	if (wps_parse_msg(msg, &attr) < 0)
1286		return WPS_FAILURE;
1287
1288	if (attr.msg_type == NULL) {
1289		wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1290		return WPS_FAILURE;
1291	}
1292
1293	if (*attr.msg_type != WPS_WSC_NACK) {
1294		wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
1295			   *attr.msg_type);
1296		return WPS_FAILURE;
1297	}
1298
1299	if (attr.registrar_nonce == NULL ||
1300	    os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
1301	{
1302		wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
1303		wpa_hexdump(MSG_DEBUG, "WPS: Received Registrar Nonce",
1304			    attr.registrar_nonce, WPS_NONCE_LEN);
1305		wpa_hexdump(MSG_DEBUG, "WPS: Expected Registrar Nonce",
1306			    wps->nonce_r, WPS_NONCE_LEN);
1307		return WPS_FAILURE;
1308	}
1309
1310	if (attr.enrollee_nonce == NULL ||
1311	    os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
1312		wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1313		wpa_hexdump(MSG_DEBUG, "WPS: Received Enrollee Nonce",
1314			    attr.enrollee_nonce, WPS_NONCE_LEN);
1315		wpa_hexdump(MSG_DEBUG, "WPS: Expected Enrollee Nonce",
1316			    wps->nonce_e, WPS_NONCE_LEN);
1317		return WPS_FAILURE;
1318	}
1319
1320	if (attr.config_error == NULL) {
1321		wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
1322			   "in WSC_NACK");
1323		return WPS_FAILURE;
1324	}
1325
1326	config_error = WPA_GET_BE16(attr.config_error);
1327	wpa_printf(MSG_DEBUG, "WPS: Registrar terminated negotiation with "
1328		   "Configuration Error %d", config_error);
1329
1330	switch (wps->state) {
1331	case RECV_M4:
1332		wps_fail_event(wps->wps, WPS_M3, config_error,
1333			       wps->error_indication);
1334		break;
1335	case RECV_M6:
1336		wps_fail_event(wps->wps, WPS_M5, config_error,
1337			       wps->error_indication);
1338		break;
1339	case RECV_M8:
1340		wps_fail_event(wps->wps, WPS_M7, config_error,
1341			       wps->error_indication);
1342		break;
1343	default:
1344		break;
1345	}
1346
1347	/* Followed by NACK if Enrollee is Supplicant or EAP-Failure if
1348	 * Enrollee is Authenticator */
1349	wps->state = SEND_WSC_NACK;
1350
1351	return WPS_FAILURE;
1352}
1353
1354
1355enum wps_process_res wps_enrollee_process_msg(struct wps_data *wps,
1356					      enum wsc_op_code op_code,
1357					      const struct wpabuf *msg)
1358{
1359
1360	wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
1361		   "op_code=%d)",
1362		   (unsigned long) wpabuf_len(msg), op_code);
1363
1364	if (op_code == WSC_UPnP) {
1365		/* Determine the OpCode based on message type attribute */
1366		struct wps_parse_attr attr;
1367		if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type) {
1368			if (*attr.msg_type == WPS_WSC_ACK)
1369				op_code = WSC_ACK;
1370			else if (*attr.msg_type == WPS_WSC_NACK)
1371				op_code = WSC_NACK;
1372		}
1373	}
1374
1375	switch (op_code) {
1376	case WSC_MSG:
1377	case WSC_UPnP:
1378		return wps_process_wsc_msg(wps, msg);
1379	case WSC_ACK:
1380		if (wps_validate_wsc_ack(msg) < 0)
1381			return WPS_FAILURE;
1382		return wps_process_wsc_ack(wps, msg);
1383	case WSC_NACK:
1384		if (wps_validate_wsc_nack(msg) < 0)
1385			return WPS_FAILURE;
1386		return wps_process_wsc_nack(wps, msg);
1387	default:
1388		wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
1389		return WPS_FAILURE;
1390	}
1391}
1392