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