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