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