wps_registrar.c revision c5ec7f57ead87efa365800228aa0b09a12d9e6c4
1/*
2 * Wi-Fi Protected Setup - Registrar
3 * Copyright (c) 2008-2009, 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 "utils/includes.h"
10
11#include "utils/common.h"
12#include "utils/base64.h"
13#include "utils/eloop.h"
14#include "utils/uuid.h"
15#include "utils/list.h"
16#include "crypto/crypto.h"
17#include "crypto/sha256.h"
18#include "crypto/random.h"
19#include "common/ieee802_11_defs.h"
20#include "wps_i.h"
21#include "wps_dev_attr.h"
22#include "wps_upnp.h"
23#include "wps_upnp_i.h"
24
25#ifndef CONFIG_WPS_STRICT
26#define WPS_WORKAROUNDS
27#endif /* CONFIG_WPS_STRICT */
28
29struct wps_uuid_pin {
30	struct dl_list list;
31	u8 uuid[WPS_UUID_LEN];
32	int wildcard_uuid;
33	u8 *pin;
34	size_t pin_len;
35#define PIN_LOCKED BIT(0)
36#define PIN_EXPIRES BIT(1)
37	int flags;
38	struct os_time expiration;
39	u8 enrollee_addr[ETH_ALEN];
40};
41
42
43static void wps_free_pin(struct wps_uuid_pin *pin)
44{
45	os_free(pin->pin);
46	os_free(pin);
47}
48
49
50static void wps_remove_pin(struct wps_uuid_pin *pin)
51{
52	dl_list_del(&pin->list);
53	wps_free_pin(pin);
54}
55
56
57static void wps_free_pins(struct dl_list *pins)
58{
59	struct wps_uuid_pin *pin, *prev;
60	dl_list_for_each_safe(pin, prev, pins, struct wps_uuid_pin, list)
61		wps_remove_pin(pin);
62}
63
64
65struct wps_pbc_session {
66	struct wps_pbc_session *next;
67	u8 addr[ETH_ALEN];
68	u8 uuid_e[WPS_UUID_LEN];
69	struct os_time timestamp;
70};
71
72
73static void wps_free_pbc_sessions(struct wps_pbc_session *pbc)
74{
75	struct wps_pbc_session *prev;
76
77	while (pbc) {
78		prev = pbc;
79		pbc = pbc->next;
80		os_free(prev);
81	}
82}
83
84
85struct wps_registrar_device {
86	struct wps_registrar_device *next;
87	struct wps_device_data dev;
88	u8 uuid[WPS_UUID_LEN];
89};
90
91
92struct wps_registrar {
93	struct wps_context *wps;
94
95	int pbc;
96	int selected_registrar;
97
98	int (*new_psk_cb)(void *ctx, const u8 *mac_addr, const u8 *psk,
99			  size_t psk_len);
100	int (*set_ie_cb)(void *ctx, struct wpabuf *beacon_ie,
101			 struct wpabuf *probe_resp_ie);
102	void (*pin_needed_cb)(void *ctx, const u8 *uuid_e,
103			      const struct wps_device_data *dev);
104	void (*reg_success_cb)(void *ctx, const u8 *mac_addr,
105			       const u8 *uuid_e);
106	void (*set_sel_reg_cb)(void *ctx, int sel_reg, u16 dev_passwd_id,
107			       u16 sel_reg_config_methods);
108	void (*enrollee_seen_cb)(void *ctx, const u8 *addr, const u8 *uuid_e,
109				 const u8 *pri_dev_type, u16 config_methods,
110				 u16 dev_password_id, u8 request_type,
111				 const char *dev_name);
112	void *cb_ctx;
113
114	struct dl_list pins;
115	struct wps_pbc_session *pbc_sessions;
116
117	int skip_cred_build;
118	struct wpabuf *extra_cred;
119	int disable_auto_conf;
120	int sel_reg_union;
121	int sel_reg_dev_password_id_override;
122	int sel_reg_config_methods_override;
123	int static_wep_only;
124	int dualband;
125
126	struct wps_registrar_device *devices;
127
128	int force_pbc_overlap;
129
130	u8 authorized_macs[WPS_MAX_AUTHORIZED_MACS][ETH_ALEN];
131	u8 authorized_macs_union[WPS_MAX_AUTHORIZED_MACS][ETH_ALEN];
132
133	u8 p2p_dev_addr[ETH_ALEN];
134};
135
136
137static int wps_set_ie(struct wps_registrar *reg);
138static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx);
139static void wps_registrar_set_selected_timeout(void *eloop_ctx,
140					       void *timeout_ctx);
141
142
143static void wps_registrar_add_authorized_mac(struct wps_registrar *reg,
144					     const u8 *addr)
145{
146	int i;
147	wpa_printf(MSG_DEBUG, "WPS: Add authorized MAC " MACSTR,
148		   MAC2STR(addr));
149	for (i = 0; i < WPS_MAX_AUTHORIZED_MACS; i++)
150		if (os_memcmp(reg->authorized_macs[i], addr, ETH_ALEN) == 0) {
151			wpa_printf(MSG_DEBUG, "WPS: Authorized MAC was "
152				   "already in the list");
153			return; /* already in list */
154		}
155	for (i = WPS_MAX_AUTHORIZED_MACS - 1; i > 0; i--)
156		os_memcpy(reg->authorized_macs[i], reg->authorized_macs[i - 1],
157			  ETH_ALEN);
158	os_memcpy(reg->authorized_macs[0], addr, ETH_ALEN);
159	wpa_hexdump(MSG_DEBUG, "WPS: Authorized MACs",
160		    (u8 *) reg->authorized_macs, sizeof(reg->authorized_macs));
161}
162
163
164static void wps_registrar_remove_authorized_mac(struct wps_registrar *reg,
165						const u8 *addr)
166{
167	int i;
168	wpa_printf(MSG_DEBUG, "WPS: Remove authorized MAC " MACSTR,
169		   MAC2STR(addr));
170	for (i = 0; i < WPS_MAX_AUTHORIZED_MACS; i++) {
171		if (os_memcmp(reg->authorized_macs, addr, ETH_ALEN) == 0)
172			break;
173	}
174	if (i == WPS_MAX_AUTHORIZED_MACS) {
175		wpa_printf(MSG_DEBUG, "WPS: Authorized MAC was not in the "
176			   "list");
177		return; /* not in the list */
178	}
179	for (; i + 1 < WPS_MAX_AUTHORIZED_MACS; i++)
180		os_memcpy(reg->authorized_macs[i], reg->authorized_macs[i + 1],
181			  ETH_ALEN);
182	os_memset(reg->authorized_macs[WPS_MAX_AUTHORIZED_MACS - 1], 0,
183		  ETH_ALEN);
184	wpa_hexdump(MSG_DEBUG, "WPS: Authorized MACs",
185		    (u8 *) reg->authorized_macs, sizeof(reg->authorized_macs));
186}
187
188
189static void wps_free_devices(struct wps_registrar_device *dev)
190{
191	struct wps_registrar_device *prev;
192
193	while (dev) {
194		prev = dev;
195		dev = dev->next;
196		wps_device_data_free(&prev->dev);
197		os_free(prev);
198	}
199}
200
201
202static struct wps_registrar_device * wps_device_get(struct wps_registrar *reg,
203						    const u8 *addr)
204{
205	struct wps_registrar_device *dev;
206
207	for (dev = reg->devices; dev; dev = dev->next) {
208		if (os_memcmp(dev->dev.mac_addr, addr, ETH_ALEN) == 0)
209			return dev;
210	}
211	return NULL;
212}
213
214
215static void wps_device_clone_data(struct wps_device_data *dst,
216				  struct wps_device_data *src)
217{
218	os_memcpy(dst->mac_addr, src->mac_addr, ETH_ALEN);
219	os_memcpy(dst->pri_dev_type, src->pri_dev_type, WPS_DEV_TYPE_LEN);
220
221#define WPS_STRDUP(n) \
222	os_free(dst->n); \
223	dst->n = src->n ? os_strdup(src->n) : NULL
224
225	WPS_STRDUP(device_name);
226	WPS_STRDUP(manufacturer);
227	WPS_STRDUP(model_name);
228	WPS_STRDUP(model_number);
229	WPS_STRDUP(serial_number);
230#undef WPS_STRDUP
231}
232
233
234int wps_device_store(struct wps_registrar *reg,
235		     struct wps_device_data *dev, const u8 *uuid)
236{
237	struct wps_registrar_device *d;
238
239	d = wps_device_get(reg, dev->mac_addr);
240	if (d == NULL) {
241		d = os_zalloc(sizeof(*d));
242		if (d == NULL)
243			return -1;
244		d->next = reg->devices;
245		reg->devices = d;
246	}
247
248	wps_device_clone_data(&d->dev, dev);
249	os_memcpy(d->uuid, uuid, WPS_UUID_LEN);
250
251	return 0;
252}
253
254
255static void wps_registrar_add_pbc_session(struct wps_registrar *reg,
256					  const u8 *addr, const u8 *uuid_e)
257{
258	struct wps_pbc_session *pbc, *prev = NULL;
259	struct os_time now;
260
261	os_get_time(&now);
262
263	pbc = reg->pbc_sessions;
264	while (pbc) {
265		if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&
266		    os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {
267			if (prev)
268				prev->next = pbc->next;
269			else
270				reg->pbc_sessions = pbc->next;
271			break;
272		}
273		prev = pbc;
274		pbc = pbc->next;
275	}
276
277	if (!pbc) {
278		pbc = os_zalloc(sizeof(*pbc));
279		if (pbc == NULL)
280			return;
281		os_memcpy(pbc->addr, addr, ETH_ALEN);
282		if (uuid_e)
283			os_memcpy(pbc->uuid_e, uuid_e, WPS_UUID_LEN);
284	}
285
286	pbc->next = reg->pbc_sessions;
287	reg->pbc_sessions = pbc;
288	pbc->timestamp = now;
289
290	/* remove entries that have timed out */
291	prev = pbc;
292	pbc = pbc->next;
293
294	while (pbc) {
295		if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME) {
296			prev->next = NULL;
297			wps_free_pbc_sessions(pbc);
298			break;
299		}
300		prev = pbc;
301		pbc = pbc->next;
302	}
303}
304
305
306static void wps_registrar_remove_pbc_session(struct wps_registrar *reg,
307					     const u8 *uuid_e,
308					     const u8 *p2p_dev_addr)
309{
310	struct wps_pbc_session *pbc, *prev = NULL, *tmp;
311
312	pbc = reg->pbc_sessions;
313	while (pbc) {
314		if (os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0 ||
315		    (p2p_dev_addr && !is_zero_ether_addr(reg->p2p_dev_addr) &&
316		     os_memcmp(reg->p2p_dev_addr, p2p_dev_addr, ETH_ALEN) ==
317		     0)) {
318			if (prev)
319				prev->next = pbc->next;
320			else
321				reg->pbc_sessions = pbc->next;
322			tmp = pbc;
323			pbc = pbc->next;
324			wpa_printf(MSG_DEBUG, "WPS: Removing PBC session for "
325				   "addr=" MACSTR, MAC2STR(tmp->addr));
326			wpa_hexdump(MSG_DEBUG, "WPS: Removed UUID-E",
327				    tmp->uuid_e, WPS_UUID_LEN);
328			os_free(tmp);
329			continue;
330		}
331		prev = pbc;
332		pbc = pbc->next;
333	}
334}
335
336
337int wps_registrar_pbc_overlap(struct wps_registrar *reg,
338			      const u8 *addr, const u8 *uuid_e)
339{
340	int count = 0;
341	struct wps_pbc_session *pbc;
342	struct wps_pbc_session *first = NULL;
343	struct os_time now;
344
345	os_get_time(&now);
346
347	wpa_printf(MSG_DEBUG, "WPS: Checking active PBC sessions for overlap");
348
349	if (uuid_e) {
350		wpa_printf(MSG_DEBUG, "WPS: Add one for the requested UUID");
351		wpa_hexdump(MSG_DEBUG, "WPS: Requested UUID",
352			    uuid_e, WPS_UUID_LEN);
353		count++;
354	}
355
356	for (pbc = reg->pbc_sessions; pbc; pbc = pbc->next) {
357		wpa_printf(MSG_DEBUG, "WPS: Consider PBC session with " MACSTR,
358			   MAC2STR(pbc->addr));
359		wpa_hexdump(MSG_DEBUG, "WPS: UUID-E",
360			    pbc->uuid_e, WPS_UUID_LEN);
361		if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME) {
362			wpa_printf(MSG_DEBUG, "WPS: PBC walk time has "
363				   "expired");
364			break;
365		}
366		if (first &&
367		    os_memcmp(pbc->uuid_e, first->uuid_e, WPS_UUID_LEN) == 0) {
368			wpa_printf(MSG_DEBUG, "WPS: Same Enrollee");
369			continue; /* same Enrollee */
370		}
371		if (uuid_e == NULL ||
372		    os_memcmp(uuid_e, pbc->uuid_e, WPS_UUID_LEN)) {
373			wpa_printf(MSG_DEBUG, "WPS: New Enrollee");
374			count++;
375		}
376		if (first == NULL)
377			first = pbc;
378	}
379
380	wpa_printf(MSG_DEBUG, "WPS: %u active PBC session(s) found", count);
381
382	return count > 1 ? 1 : 0;
383}
384
385
386static int wps_build_wps_state(struct wps_context *wps, struct wpabuf *msg)
387{
388	wpa_printf(MSG_DEBUG, "WPS:  * Wi-Fi Protected Setup State (%d)",
389		   wps->wps_state);
390	wpabuf_put_be16(msg, ATTR_WPS_STATE);
391	wpabuf_put_be16(msg, 1);
392	wpabuf_put_u8(msg, wps->wps_state);
393	return 0;
394}
395
396
397#ifdef CONFIG_WPS_UPNP
398static void wps_registrar_free_pending_m2(struct wps_context *wps)
399{
400	struct upnp_pending_message *p, *p2, *prev = NULL;
401	p = wps->upnp_msgs;
402	while (p) {
403		if (p->type == WPS_M2 || p->type == WPS_M2D) {
404			if (prev == NULL)
405				wps->upnp_msgs = p->next;
406			else
407				prev->next = p->next;
408			wpa_printf(MSG_DEBUG, "WPS UPnP: Drop pending M2/M2D");
409			p2 = p;
410			p = p->next;
411			wpabuf_free(p2->msg);
412			os_free(p2);
413			continue;
414		}
415		prev = p;
416		p = p->next;
417	}
418}
419#endif /* CONFIG_WPS_UPNP */
420
421
422static int wps_build_ap_setup_locked(struct wps_context *wps,
423				     struct wpabuf *msg)
424{
425	if (wps->ap_setup_locked && wps->ap_setup_locked != 2) {
426		wpa_printf(MSG_DEBUG, "WPS:  * AP Setup Locked");
427		wpabuf_put_be16(msg, ATTR_AP_SETUP_LOCKED);
428		wpabuf_put_be16(msg, 1);
429		wpabuf_put_u8(msg, 1);
430	}
431	return 0;
432}
433
434
435static int wps_build_selected_registrar(struct wps_registrar *reg,
436					struct wpabuf *msg)
437{
438	if (!reg->sel_reg_union)
439		return 0;
440	wpa_printf(MSG_DEBUG, "WPS:  * Selected Registrar");
441	wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR);
442	wpabuf_put_be16(msg, 1);
443	wpabuf_put_u8(msg, 1);
444	return 0;
445}
446
447
448static int wps_build_sel_reg_dev_password_id(struct wps_registrar *reg,
449					     struct wpabuf *msg)
450{
451	u16 id = reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT;
452	if (!reg->sel_reg_union)
453		return 0;
454	if (reg->sel_reg_dev_password_id_override >= 0)
455		id = reg->sel_reg_dev_password_id_override;
456	wpa_printf(MSG_DEBUG, "WPS:  * Device Password ID (%d)", id);
457	wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
458	wpabuf_put_be16(msg, 2);
459	wpabuf_put_be16(msg, id);
460	return 0;
461}
462
463
464static int wps_build_sel_pbc_reg_uuid_e(struct wps_registrar *reg,
465					struct wpabuf *msg)
466{
467	u16 id = reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT;
468	if (!reg->sel_reg_union)
469		return 0;
470	if (reg->sel_reg_dev_password_id_override >= 0)
471		id = reg->sel_reg_dev_password_id_override;
472	if (id != DEV_PW_PUSHBUTTON || !reg->dualband)
473		return 0;
474	return wps_build_uuid_e(msg, reg->wps->uuid);
475}
476
477
478static void wps_set_pushbutton(u16 *methods, u16 conf_methods)
479{
480	*methods |= WPS_CONFIG_PUSHBUTTON;
481#ifdef CONFIG_WPS2
482	if (conf_methods & WPS_CONFIG_VIRT_PUSHBUTTON)
483		*methods |= WPS_CONFIG_VIRT_PUSHBUTTON;
484	if (conf_methods & WPS_CONFIG_PHY_PUSHBUTTON)
485		*methods |= WPS_CONFIG_PHY_PUSHBUTTON;
486	if (!(*methods & (WPS_CONFIG_VIRT_PUSHBUTTON |
487			  WPS_CONFIG_PHY_PUSHBUTTON))) {
488		/*
489		 * Required to include virtual/physical flag, but we were not
490		 * configured with push button type, so have to default to one
491		 * of them.
492		 */
493		*methods |= WPS_CONFIG_PHY_PUSHBUTTON;
494	}
495#endif /* CONFIG_WPS2 */
496}
497
498
499static int wps_build_sel_reg_config_methods(struct wps_registrar *reg,
500					    struct wpabuf *msg)
501{
502	u16 methods;
503	if (!reg->sel_reg_union)
504		return 0;
505	methods = reg->wps->config_methods;
506	methods &= ~WPS_CONFIG_PUSHBUTTON;
507#ifdef CONFIG_WPS2
508	methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |
509		     WPS_CONFIG_PHY_PUSHBUTTON);
510#endif /* CONFIG_WPS2 */
511	if (reg->pbc)
512		wps_set_pushbutton(&methods, reg->wps->config_methods);
513	if (reg->sel_reg_config_methods_override >= 0)
514		methods = reg->sel_reg_config_methods_override;
515	wpa_printf(MSG_DEBUG, "WPS:  * Selected Registrar Config Methods (%x)",
516		   methods);
517	wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS);
518	wpabuf_put_be16(msg, 2);
519	wpabuf_put_be16(msg, methods);
520	return 0;
521}
522
523
524static int wps_build_probe_config_methods(struct wps_registrar *reg,
525					  struct wpabuf *msg)
526{
527	u16 methods;
528	/*
529	 * These are the methods that the AP supports as an Enrollee for adding
530	 * external Registrars.
531	 */
532	methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
533#ifdef CONFIG_WPS2
534	methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |
535		     WPS_CONFIG_PHY_PUSHBUTTON);
536#endif /* CONFIG_WPS2 */
537	wpa_printf(MSG_DEBUG, "WPS:  * Config Methods (%x)", methods);
538	wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
539	wpabuf_put_be16(msg, 2);
540	wpabuf_put_be16(msg, methods);
541	return 0;
542}
543
544
545static int wps_build_config_methods_r(struct wps_registrar *reg,
546				      struct wpabuf *msg)
547{
548	return wps_build_config_methods(msg, reg->wps->config_methods);
549}
550
551
552const u8 * wps_authorized_macs(struct wps_registrar *reg, size_t *count)
553{
554	*count = 0;
555
556#ifdef CONFIG_WPS2
557	while (*count < WPS_MAX_AUTHORIZED_MACS) {
558		if (is_zero_ether_addr(reg->authorized_macs_union[*count]))
559			break;
560		(*count)++;
561	}
562#endif /* CONFIG_WPS2 */
563
564	return (const u8 *) reg->authorized_macs_union;
565}
566
567
568/**
569 * wps_registrar_init - Initialize WPS Registrar data
570 * @wps: Pointer to longterm WPS context
571 * @cfg: Registrar configuration
572 * Returns: Pointer to allocated Registrar data or %NULL on failure
573 *
574 * This function is used to initialize WPS Registrar functionality. It can be
575 * used for a single Registrar run (e.g., when run in a supplicant) or multiple
576 * runs (e.g., when run as an internal Registrar in an AP). Caller is
577 * responsible for freeing the returned data with wps_registrar_deinit() when
578 * Registrar functionality is not needed anymore.
579 */
580struct wps_registrar *
581wps_registrar_init(struct wps_context *wps,
582		   const struct wps_registrar_config *cfg)
583{
584	struct wps_registrar *reg = os_zalloc(sizeof(*reg));
585	if (reg == NULL)
586		return NULL;
587
588	dl_list_init(&reg->pins);
589	reg->wps = wps;
590	reg->new_psk_cb = cfg->new_psk_cb;
591	reg->set_ie_cb = cfg->set_ie_cb;
592	reg->pin_needed_cb = cfg->pin_needed_cb;
593	reg->reg_success_cb = cfg->reg_success_cb;
594	reg->set_sel_reg_cb = cfg->set_sel_reg_cb;
595	reg->enrollee_seen_cb = cfg->enrollee_seen_cb;
596	reg->cb_ctx = cfg->cb_ctx;
597	reg->skip_cred_build = cfg->skip_cred_build;
598	if (cfg->extra_cred) {
599		reg->extra_cred = wpabuf_alloc_copy(cfg->extra_cred,
600						    cfg->extra_cred_len);
601		if (reg->extra_cred == NULL) {
602			os_free(reg);
603			return NULL;
604		}
605	}
606	reg->disable_auto_conf = cfg->disable_auto_conf;
607	reg->sel_reg_dev_password_id_override = -1;
608	reg->sel_reg_config_methods_override = -1;
609	reg->static_wep_only = cfg->static_wep_only;
610	reg->dualband = cfg->dualband;
611
612	if (wps_set_ie(reg)) {
613		wps_registrar_deinit(reg);
614		return NULL;
615	}
616
617	return reg;
618}
619
620
621/**
622 * wps_registrar_deinit - Deinitialize WPS Registrar data
623 * @reg: Registrar data from wps_registrar_init()
624 */
625void wps_registrar_deinit(struct wps_registrar *reg)
626{
627	if (reg == NULL)
628		return;
629	eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
630	eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
631	wps_free_pins(&reg->pins);
632	wps_free_pbc_sessions(reg->pbc_sessions);
633	wpabuf_free(reg->extra_cred);
634	wps_free_devices(reg->devices);
635	os_free(reg);
636}
637
638
639/**
640 * wps_registrar_add_pin - Configure a new PIN for Registrar
641 * @reg: Registrar data from wps_registrar_init()
642 * @addr: Enrollee MAC address or %NULL if not known
643 * @uuid: UUID-E or %NULL for wildcard (any UUID)
644 * @pin: PIN (Device Password)
645 * @pin_len: Length of pin in octets
646 * @timeout: Time (in seconds) when the PIN will be invalidated; 0 = no timeout
647 * Returns: 0 on success, -1 on failure
648 */
649int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *addr,
650			  const u8 *uuid, const u8 *pin, size_t pin_len,
651			  int timeout)
652{
653	struct wps_uuid_pin *p;
654
655	p = os_zalloc(sizeof(*p));
656	if (p == NULL)
657		return -1;
658	if (addr)
659		os_memcpy(p->enrollee_addr, addr, ETH_ALEN);
660	if (uuid == NULL)
661		p->wildcard_uuid = 1;
662	else
663		os_memcpy(p->uuid, uuid, WPS_UUID_LEN);
664	p->pin = os_malloc(pin_len);
665	if (p->pin == NULL) {
666		os_free(p);
667		return -1;
668	}
669	os_memcpy(p->pin, pin, pin_len);
670	p->pin_len = pin_len;
671
672	if (timeout) {
673		p->flags |= PIN_EXPIRES;
674		os_get_time(&p->expiration);
675		p->expiration.sec += timeout;
676	}
677
678	dl_list_add(&reg->pins, &p->list);
679
680	wpa_printf(MSG_DEBUG, "WPS: A new PIN configured (timeout=%d)",
681		   timeout);
682	wpa_hexdump(MSG_DEBUG, "WPS: UUID", uuid, WPS_UUID_LEN);
683	wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: PIN", pin, pin_len);
684	reg->selected_registrar = 1;
685	reg->pbc = 0;
686	if (addr)
687		wps_registrar_add_authorized_mac(reg, addr);
688	else
689		wps_registrar_add_authorized_mac(
690			reg, (u8 *) "\xff\xff\xff\xff\xff\xff");
691	wps_registrar_selected_registrar_changed(reg);
692	eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
693	eloop_register_timeout(WPS_PBC_WALK_TIME, 0,
694			       wps_registrar_set_selected_timeout,
695			       reg, NULL);
696
697	return 0;
698}
699
700
701static void wps_registrar_remove_pin(struct wps_registrar *reg,
702				     struct wps_uuid_pin *pin)
703{
704	u8 *addr;
705	u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
706
707	if (is_zero_ether_addr(pin->enrollee_addr))
708		addr = bcast;
709	else
710		addr = pin->enrollee_addr;
711	wps_registrar_remove_authorized_mac(reg, addr);
712	wps_remove_pin(pin);
713	wps_registrar_selected_registrar_changed(reg);
714}
715
716
717static void wps_registrar_expire_pins(struct wps_registrar *reg)
718{
719	struct wps_uuid_pin *pin, *prev;
720	struct os_time now;
721
722	os_get_time(&now);
723	dl_list_for_each_safe(pin, prev, &reg->pins, struct wps_uuid_pin, list)
724	{
725		if ((pin->flags & PIN_EXPIRES) &&
726		    os_time_before(&pin->expiration, &now)) {
727			wpa_hexdump(MSG_DEBUG, "WPS: Expired PIN for UUID",
728				    pin->uuid, WPS_UUID_LEN);
729			wps_registrar_remove_pin(reg, pin);
730		}
731	}
732}
733
734
735/**
736 * wps_registrar_invalidate_wildcard_pin - Invalidate a wildcard PIN
737 * @reg: Registrar data from wps_registrar_init()
738 * Returns: 0 on success, -1 if not wildcard PIN is enabled
739 */
740static int wps_registrar_invalidate_wildcard_pin(struct wps_registrar *reg)
741{
742	struct wps_uuid_pin *pin, *prev;
743
744	dl_list_for_each_safe(pin, prev, &reg->pins, struct wps_uuid_pin, list)
745	{
746		if (pin->wildcard_uuid) {
747			wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID",
748				    pin->uuid, WPS_UUID_LEN);
749			wps_registrar_remove_pin(reg, pin);
750			return 0;
751		}
752	}
753
754	return -1;
755}
756
757
758/**
759 * wps_registrar_invalidate_pin - Invalidate a PIN for a specific UUID-E
760 * @reg: Registrar data from wps_registrar_init()
761 * @uuid: UUID-E
762 * Returns: 0 on success, -1 on failure (e.g., PIN not found)
763 */
764int wps_registrar_invalidate_pin(struct wps_registrar *reg, const u8 *uuid)
765{
766	struct wps_uuid_pin *pin, *prev;
767
768	dl_list_for_each_safe(pin, prev, &reg->pins, struct wps_uuid_pin, list)
769	{
770		if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
771			wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID",
772				    pin->uuid, WPS_UUID_LEN);
773			wps_registrar_remove_pin(reg, pin);
774			return 0;
775		}
776	}
777
778	return -1;
779}
780
781
782static const u8 * wps_registrar_get_pin(struct wps_registrar *reg,
783					const u8 *uuid, size_t *pin_len)
784{
785	struct wps_uuid_pin *pin, *found = NULL;
786
787	wps_registrar_expire_pins(reg);
788
789	dl_list_for_each(pin, &reg->pins, struct wps_uuid_pin, list) {
790		if (!pin->wildcard_uuid &&
791		    os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
792			found = pin;
793			break;
794		}
795	}
796
797	if (!found) {
798		/* Check for wildcard UUIDs since none of the UUID-specific
799		 * PINs matched */
800		dl_list_for_each(pin, &reg->pins, struct wps_uuid_pin, list) {
801			if (pin->wildcard_uuid == 1 ||
802			    pin->wildcard_uuid == 2) {
803				wpa_printf(MSG_DEBUG, "WPS: Found a wildcard "
804					   "PIN. Assigned it for this UUID-E");
805				pin->wildcard_uuid++;
806				os_memcpy(pin->uuid, uuid, WPS_UUID_LEN);
807				found = pin;
808				break;
809			}
810		}
811	}
812
813	if (!found)
814		return NULL;
815
816	/*
817	 * Lock the PIN to avoid attacks based on concurrent re-use of the PIN
818	 * that could otherwise avoid PIN invalidations.
819	 */
820	if (found->flags & PIN_LOCKED) {
821		wpa_printf(MSG_DEBUG, "WPS: Selected PIN locked - do not "
822			   "allow concurrent re-use");
823		return NULL;
824	}
825	*pin_len = found->pin_len;
826	found->flags |= PIN_LOCKED;
827	return found->pin;
828}
829
830
831/**
832 * wps_registrar_unlock_pin - Unlock a PIN for a specific UUID-E
833 * @reg: Registrar data from wps_registrar_init()
834 * @uuid: UUID-E
835 * Returns: 0 on success, -1 on failure
836 *
837 * PINs are locked to enforce only one concurrent use. This function unlocks a
838 * PIN to allow it to be used again. If the specified PIN was configured using
839 * a wildcard UUID, it will be removed instead of allowing multiple uses.
840 */
841int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid)
842{
843	struct wps_uuid_pin *pin;
844
845	dl_list_for_each(pin, &reg->pins, struct wps_uuid_pin, list) {
846		if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
847			if (pin->wildcard_uuid == 3) {
848				wpa_printf(MSG_DEBUG, "WPS: Invalidating used "
849					   "wildcard PIN");
850				return wps_registrar_invalidate_pin(reg, uuid);
851			}
852			pin->flags &= ~PIN_LOCKED;
853			return 0;
854		}
855	}
856
857	return -1;
858}
859
860
861static void wps_registrar_stop_pbc(struct wps_registrar *reg)
862{
863	reg->selected_registrar = 0;
864	reg->pbc = 0;
865	os_memset(reg->p2p_dev_addr, 0, ETH_ALEN);
866	wps_registrar_remove_authorized_mac(reg,
867					    (u8 *) "\xff\xff\xff\xff\xff\xff");
868	wps_registrar_selected_registrar_changed(reg);
869}
870
871
872static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx)
873{
874	struct wps_registrar *reg = eloop_ctx;
875
876	wpa_printf(MSG_DEBUG, "WPS: PBC timed out - disable PBC mode");
877	wps_pbc_timeout_event(reg->wps);
878	wps_registrar_stop_pbc(reg);
879}
880
881
882/**
883 * wps_registrar_button_pushed - Notify Registrar that AP button was pushed
884 * @reg: Registrar data from wps_registrar_init()
885 * @p2p_dev_addr: Limit allowed PBC devices to the specified P2P device, %NULL
886 *	indicates no such filtering
887 * Returns: 0 on success, -1 on failure, -2 on session overlap
888 *
889 * This function is called on an AP when a push button is pushed to activate
890 * PBC mode. The PBC mode will be stopped after walk time (2 minutes) timeout
891 * or when a PBC registration is completed. If more than one Enrollee in active
892 * PBC mode has been detected during the monitor time (previous 2 minutes), the
893 * PBC mode is not activated and -2 is returned to indicate session overlap.
894 * This is skipped if a specific Enrollee is selected.
895 */
896int wps_registrar_button_pushed(struct wps_registrar *reg,
897				const u8 *p2p_dev_addr)
898{
899	if (p2p_dev_addr == NULL &&
900	    wps_registrar_pbc_overlap(reg, NULL, NULL)) {
901		wpa_printf(MSG_DEBUG, "WPS: PBC overlap - do not start PBC "
902			   "mode");
903		wps_pbc_overlap_event(reg->wps);
904		return -2;
905	}
906	wpa_printf(MSG_DEBUG, "WPS: Button pushed - PBC mode started");
907	reg->force_pbc_overlap = 0;
908	reg->selected_registrar = 1;
909	reg->pbc = 1;
910	if (p2p_dev_addr)
911		os_memcpy(reg->p2p_dev_addr, p2p_dev_addr, ETH_ALEN);
912	else
913		os_memset(reg->p2p_dev_addr, 0, ETH_ALEN);
914	wps_registrar_add_authorized_mac(reg,
915					 (u8 *) "\xff\xff\xff\xff\xff\xff");
916	wps_registrar_selected_registrar_changed(reg);
917
918	eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
919	eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
920	eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wps_registrar_pbc_timeout,
921			       reg, NULL);
922	return 0;
923}
924
925
926static void wps_registrar_pbc_completed(struct wps_registrar *reg)
927{
928	wpa_printf(MSG_DEBUG, "WPS: PBC completed - stopping PBC mode");
929	eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
930	wps_registrar_stop_pbc(reg);
931}
932
933
934static void wps_registrar_pin_completed(struct wps_registrar *reg)
935{
936	wpa_printf(MSG_DEBUG, "WPS: PIN completed using internal Registrar");
937	eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
938	reg->selected_registrar = 0;
939	wps_registrar_selected_registrar_changed(reg);
940}
941
942
943void wps_registrar_complete(struct wps_registrar *registrar, const u8 *uuid_e)
944{
945	if (registrar->pbc) {
946		wps_registrar_remove_pbc_session(registrar,
947						 uuid_e, NULL);
948		wps_registrar_pbc_completed(registrar);
949	} else {
950		wps_registrar_pin_completed(registrar);
951	}
952}
953
954
955int wps_registrar_wps_cancel(struct wps_registrar *reg)
956{
957	if (reg->pbc) {
958		wpa_printf(MSG_DEBUG, "WPS: PBC is set - cancelling it");
959		wps_registrar_pbc_timeout(reg, NULL);
960		eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
961		return 1;
962	} else if (reg->selected_registrar) {
963		/* PIN Method */
964		wpa_printf(MSG_DEBUG, "WPS: PIN is set - cancelling it");
965		wps_registrar_pin_completed(reg);
966		wps_registrar_invalidate_wildcard_pin(reg);
967		return 1;
968	}
969	return 0;
970}
971
972
973/**
974 * wps_registrar_probe_req_rx - Notify Registrar of Probe Request
975 * @reg: Registrar data from wps_registrar_init()
976 * @addr: MAC address of the Probe Request sender
977 * @wps_data: WPS IE contents
978 *
979 * This function is called on an AP when a Probe Request with WPS IE is
980 * received. This is used to track PBC mode use and to detect possible overlap
981 * situation with other WPS APs.
982 */
983void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
984				const struct wpabuf *wps_data,
985				int p2p_wildcard)
986{
987	struct wps_parse_attr attr;
988
989	wpa_hexdump_buf(MSG_MSGDUMP,
990			"WPS: Probe Request with WPS data received",
991			wps_data);
992
993	if (wps_parse_msg(wps_data, &attr) < 0)
994		return;
995
996	if (attr.config_methods == NULL) {
997		wpa_printf(MSG_DEBUG, "WPS: No Config Methods attribute in "
998			   "Probe Request");
999		return;
1000	}
1001
1002	if (attr.dev_password_id == NULL) {
1003		wpa_printf(MSG_DEBUG, "WPS: No Device Password Id attribute "
1004			   "in Probe Request");
1005		return;
1006	}
1007
1008	if (reg->enrollee_seen_cb && attr.uuid_e &&
1009	    attr.primary_dev_type && attr.request_type && !p2p_wildcard) {
1010		char *dev_name = NULL;
1011		if (attr.dev_name) {
1012			dev_name = os_zalloc(attr.dev_name_len + 1);
1013			if (dev_name) {
1014				os_memcpy(dev_name, attr.dev_name,
1015					  attr.dev_name_len);
1016			}
1017		}
1018		reg->enrollee_seen_cb(reg->cb_ctx, addr, attr.uuid_e,
1019				      attr.primary_dev_type,
1020				      WPA_GET_BE16(attr.config_methods),
1021				      WPA_GET_BE16(attr.dev_password_id),
1022				      *attr.request_type, dev_name);
1023		os_free(dev_name);
1024	}
1025
1026	if (WPA_GET_BE16(attr.dev_password_id) != DEV_PW_PUSHBUTTON)
1027		return; /* Not PBC */
1028
1029	wpa_printf(MSG_DEBUG, "WPS: Probe Request for PBC received from "
1030		   MACSTR, MAC2STR(addr));
1031	if (attr.uuid_e == NULL) {
1032		wpa_printf(MSG_DEBUG, "WPS: Invalid Probe Request WPS IE: No "
1033			   "UUID-E included");
1034		return;
1035	}
1036	wpa_hexdump(MSG_DEBUG, "WPS: UUID-E from Probe Request", attr.uuid_e,
1037		    WPS_UUID_LEN);
1038
1039	wps_registrar_add_pbc_session(reg, addr, attr.uuid_e);
1040	if (wps_registrar_pbc_overlap(reg, addr, attr.uuid_e)) {
1041		wpa_printf(MSG_DEBUG, "WPS: PBC session overlap detected");
1042		reg->force_pbc_overlap = 1;
1043		wps_pbc_overlap_event(reg->wps);
1044	}
1045}
1046
1047
1048static int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr,
1049			  const u8 *psk, size_t psk_len)
1050{
1051	if (reg->new_psk_cb == NULL)
1052		return 0;
1053
1054	return reg->new_psk_cb(reg->cb_ctx, mac_addr, psk, psk_len);
1055}
1056
1057
1058static void wps_cb_pin_needed(struct wps_registrar *reg, const u8 *uuid_e,
1059			      const struct wps_device_data *dev)
1060{
1061	if (reg->pin_needed_cb == NULL)
1062		return;
1063
1064	reg->pin_needed_cb(reg->cb_ctx, uuid_e, dev);
1065}
1066
1067
1068static void wps_cb_reg_success(struct wps_registrar *reg, const u8 *mac_addr,
1069			       const u8 *uuid_e)
1070{
1071	if (reg->reg_success_cb == NULL)
1072		return;
1073
1074	reg->reg_success_cb(reg->cb_ctx, mac_addr, uuid_e);
1075}
1076
1077
1078static int wps_cb_set_ie(struct wps_registrar *reg, struct wpabuf *beacon_ie,
1079			 struct wpabuf *probe_resp_ie)
1080{
1081	return reg->set_ie_cb(reg->cb_ctx, beacon_ie, probe_resp_ie);
1082}
1083
1084
1085static void wps_cb_set_sel_reg(struct wps_registrar *reg)
1086{
1087	u16 methods = 0;
1088	if (reg->set_sel_reg_cb == NULL)
1089		return;
1090
1091	if (reg->selected_registrar) {
1092		methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
1093#ifdef CONFIG_WPS2
1094		methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |
1095			     WPS_CONFIG_PHY_PUSHBUTTON);
1096#endif /* CONFIG_WPS2 */
1097		if (reg->pbc)
1098			wps_set_pushbutton(&methods, reg->wps->config_methods);
1099	}
1100
1101	wpa_printf(MSG_DEBUG, "WPS: wps_cb_set_sel_reg: sel_reg=%d "
1102		   "config_methods=0x%x pbc=%d methods=0x%x",
1103		   reg->selected_registrar, reg->wps->config_methods,
1104		   reg->pbc, methods);
1105
1106	reg->set_sel_reg_cb(reg->cb_ctx, reg->selected_registrar,
1107			    reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT,
1108			    methods);
1109}
1110
1111
1112static int wps_set_ie(struct wps_registrar *reg)
1113{
1114	struct wpabuf *beacon;
1115	struct wpabuf *probe;
1116	const u8 *auth_macs;
1117	size_t count;
1118	size_t vendor_len = 0;
1119	int i;
1120
1121	if (reg->set_ie_cb == NULL)
1122		return 0;
1123
1124	for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
1125		if (reg->wps->dev.vendor_ext[i]) {
1126			vendor_len += 2 + 2;
1127			vendor_len += wpabuf_len(reg->wps->dev.vendor_ext[i]);
1128		}
1129	}
1130
1131	beacon = wpabuf_alloc(400 + vendor_len);
1132	if (beacon == NULL)
1133		return -1;
1134	probe = wpabuf_alloc(500 + vendor_len);
1135	if (probe == NULL) {
1136		wpabuf_free(beacon);
1137		return -1;
1138	}
1139
1140	auth_macs = wps_authorized_macs(reg, &count);
1141
1142	wpa_printf(MSG_DEBUG, "WPS: Build Beacon IEs");
1143
1144	if (wps_build_version(beacon) ||
1145	    wps_build_wps_state(reg->wps, beacon) ||
1146	    wps_build_ap_setup_locked(reg->wps, beacon) ||
1147	    wps_build_selected_registrar(reg, beacon) ||
1148	    wps_build_sel_reg_dev_password_id(reg, beacon) ||
1149	    wps_build_sel_reg_config_methods(reg, beacon) ||
1150	    wps_build_sel_pbc_reg_uuid_e(reg, beacon) ||
1151	    (reg->dualband && wps_build_rf_bands(&reg->wps->dev, beacon)) ||
1152	    wps_build_wfa_ext(beacon, 0, auth_macs, count) ||
1153	    wps_build_vendor_ext(&reg->wps->dev, beacon)) {
1154		wpabuf_free(beacon);
1155		wpabuf_free(probe);
1156		return -1;
1157	}
1158
1159#ifdef CONFIG_P2P
1160	if (wps_build_dev_name(&reg->wps->dev, beacon) ||
1161	    wps_build_primary_dev_type(&reg->wps->dev, beacon)) {
1162		wpabuf_free(beacon);
1163		wpabuf_free(probe);
1164		return -1;
1165	}
1166#endif /* CONFIG_P2P */
1167
1168	wpa_printf(MSG_DEBUG, "WPS: Build Probe Response IEs");
1169
1170	if (wps_build_version(probe) ||
1171	    wps_build_wps_state(reg->wps, probe) ||
1172	    wps_build_ap_setup_locked(reg->wps, probe) ||
1173	    wps_build_selected_registrar(reg, probe) ||
1174	    wps_build_sel_reg_dev_password_id(reg, probe) ||
1175	    wps_build_sel_reg_config_methods(reg, probe) ||
1176	    wps_build_resp_type(probe, reg->wps->ap ? WPS_RESP_AP :
1177				WPS_RESP_REGISTRAR) ||
1178	    wps_build_uuid_e(probe, reg->wps->uuid) ||
1179	    wps_build_device_attrs(&reg->wps->dev, probe) ||
1180	    wps_build_probe_config_methods(reg, probe) ||
1181	    wps_build_rf_bands(&reg->wps->dev, probe) ||
1182	    wps_build_wfa_ext(probe, 0, auth_macs, count) ||
1183	    wps_build_vendor_ext(&reg->wps->dev, probe)) {
1184		wpabuf_free(beacon);
1185		wpabuf_free(probe);
1186		return -1;
1187	}
1188
1189	beacon = wps_ie_encapsulate(beacon);
1190	probe = wps_ie_encapsulate(probe);
1191
1192	if (!beacon || !probe) {
1193		wpabuf_free(beacon);
1194		wpabuf_free(probe);
1195		return -1;
1196	}
1197
1198	if (reg->static_wep_only) {
1199		/*
1200		 * Windows XP and Vista clients can get confused about
1201		 * EAP-Identity/Request when they probe the network with
1202		 * EAPOL-Start. In such a case, they may assume the network is
1203		 * using IEEE 802.1X and prompt user for a certificate while
1204		 * the correct (non-WPS) behavior would be to ask for the
1205		 * static WEP key. As a workaround, use Microsoft Provisioning
1206		 * IE to advertise that legacy 802.1X is not supported.
1207		 */
1208		const u8 ms_wps[7] = {
1209			WLAN_EID_VENDOR_SPECIFIC, 5,
1210			/* Microsoft Provisioning IE (00:50:f2:5) */
1211			0x00, 0x50, 0xf2, 5,
1212			0x00 /* no legacy 802.1X or MS WPS */
1213		};
1214		wpa_printf(MSG_DEBUG, "WPS: Add Microsoft Provisioning IE "
1215			   "into Beacon/Probe Response frames");
1216		wpabuf_put_data(beacon, ms_wps, sizeof(ms_wps));
1217		wpabuf_put_data(probe, ms_wps, sizeof(ms_wps));
1218	}
1219
1220	return wps_cb_set_ie(reg, beacon, probe);
1221}
1222
1223
1224static int wps_get_dev_password(struct wps_data *wps)
1225{
1226	const u8 *pin;
1227	size_t pin_len = 0;
1228
1229	os_free(wps->dev_password);
1230	wps->dev_password = NULL;
1231
1232	if (wps->pbc) {
1233		wpa_printf(MSG_DEBUG, "WPS: Use default PIN for PBC");
1234		pin = (const u8 *) "00000000";
1235		pin_len = 8;
1236	} else {
1237		pin = wps_registrar_get_pin(wps->wps->registrar, wps->uuid_e,
1238					    &pin_len);
1239	}
1240	if (pin == NULL) {
1241		wpa_printf(MSG_DEBUG, "WPS: No Device Password available for "
1242			   "the Enrollee");
1243		wps_cb_pin_needed(wps->wps->registrar, wps->uuid_e,
1244				  &wps->peer_dev);
1245		return -1;
1246	}
1247
1248	wps->dev_password = os_malloc(pin_len);
1249	if (wps->dev_password == NULL)
1250		return -1;
1251	os_memcpy(wps->dev_password, pin, pin_len);
1252	wps->dev_password_len = pin_len;
1253
1254	return 0;
1255}
1256
1257
1258static int wps_build_uuid_r(struct wps_data *wps, struct wpabuf *msg)
1259{
1260	wpa_printf(MSG_DEBUG, "WPS:  * UUID-R");
1261	wpabuf_put_be16(msg, ATTR_UUID_R);
1262	wpabuf_put_be16(msg, WPS_UUID_LEN);
1263	wpabuf_put_data(msg, wps->uuid_r, WPS_UUID_LEN);
1264	return 0;
1265}
1266
1267
1268static int wps_build_r_hash(struct wps_data *wps, struct wpabuf *msg)
1269{
1270	u8 *hash;
1271	const u8 *addr[4];
1272	size_t len[4];
1273
1274	if (random_get_bytes(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
1275		return -1;
1276	wpa_hexdump(MSG_DEBUG, "WPS: R-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
1277	wpa_hexdump(MSG_DEBUG, "WPS: R-S2",
1278		    wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
1279
1280	if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
1281		wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
1282			   "R-Hash derivation");
1283		return -1;
1284	}
1285
1286	wpa_printf(MSG_DEBUG, "WPS:  * R-Hash1");
1287	wpabuf_put_be16(msg, ATTR_R_HASH1);
1288	wpabuf_put_be16(msg, SHA256_MAC_LEN);
1289	hash = wpabuf_put(msg, SHA256_MAC_LEN);
1290	/* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
1291	addr[0] = wps->snonce;
1292	len[0] = WPS_SECRET_NONCE_LEN;
1293	addr[1] = wps->psk1;
1294	len[1] = WPS_PSK_LEN;
1295	addr[2] = wpabuf_head(wps->dh_pubkey_e);
1296	len[2] = wpabuf_len(wps->dh_pubkey_e);
1297	addr[3] = wpabuf_head(wps->dh_pubkey_r);
1298	len[3] = wpabuf_len(wps->dh_pubkey_r);
1299	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
1300	wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", hash, SHA256_MAC_LEN);
1301
1302	wpa_printf(MSG_DEBUG, "WPS:  * R-Hash2");
1303	wpabuf_put_be16(msg, ATTR_R_HASH2);
1304	wpabuf_put_be16(msg, SHA256_MAC_LEN);
1305	hash = wpabuf_put(msg, SHA256_MAC_LEN);
1306	/* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
1307	addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
1308	addr[1] = wps->psk2;
1309	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
1310	wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", hash, SHA256_MAC_LEN);
1311
1312	return 0;
1313}
1314
1315
1316static int wps_build_r_snonce1(struct wps_data *wps, struct wpabuf *msg)
1317{
1318	wpa_printf(MSG_DEBUG, "WPS:  * R-SNonce1");
1319	wpabuf_put_be16(msg, ATTR_R_SNONCE1);
1320	wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
1321	wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
1322	return 0;
1323}
1324
1325
1326static int wps_build_r_snonce2(struct wps_data *wps, struct wpabuf *msg)
1327{
1328	wpa_printf(MSG_DEBUG, "WPS:  * R-SNonce2");
1329	wpabuf_put_be16(msg, ATTR_R_SNONCE2);
1330	wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
1331	wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
1332			WPS_SECRET_NONCE_LEN);
1333	return 0;
1334}
1335
1336
1337static int wps_build_cred_network_idx(struct wpabuf *msg,
1338				      const struct wps_credential *cred)
1339{
1340	wpa_printf(MSG_DEBUG, "WPS:  * Network Index (1)");
1341	wpabuf_put_be16(msg, ATTR_NETWORK_INDEX);
1342	wpabuf_put_be16(msg, 1);
1343	wpabuf_put_u8(msg, 1);
1344	return 0;
1345}
1346
1347
1348static int wps_build_cred_ssid(struct wpabuf *msg,
1349			       const struct wps_credential *cred)
1350{
1351	wpa_printf(MSG_DEBUG, "WPS:  * SSID");
1352	wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID for Credential",
1353			  cred->ssid, cred->ssid_len);
1354	wpabuf_put_be16(msg, ATTR_SSID);
1355	wpabuf_put_be16(msg, cred->ssid_len);
1356	wpabuf_put_data(msg, cred->ssid, cred->ssid_len);
1357	return 0;
1358}
1359
1360
1361static int wps_build_cred_auth_type(struct wpabuf *msg,
1362				    const struct wps_credential *cred)
1363{
1364	wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type (0x%x)",
1365		   cred->auth_type);
1366	wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
1367	wpabuf_put_be16(msg, 2);
1368	wpabuf_put_be16(msg, cred->auth_type);
1369	return 0;
1370}
1371
1372
1373static int wps_build_cred_encr_type(struct wpabuf *msg,
1374				    const struct wps_credential *cred)
1375{
1376	wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type (0x%x)",
1377		   cred->encr_type);
1378	wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
1379	wpabuf_put_be16(msg, 2);
1380	wpabuf_put_be16(msg, cred->encr_type);
1381	return 0;
1382}
1383
1384
1385static int wps_build_cred_network_key(struct wpabuf *msg,
1386				      const struct wps_credential *cred)
1387{
1388	wpa_printf(MSG_DEBUG, "WPS:  * Network Key (len=%d)",
1389		   (int) cred->key_len);
1390	wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key",
1391			cred->key, cred->key_len);
1392	wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
1393	wpabuf_put_be16(msg, cred->key_len);
1394	wpabuf_put_data(msg, cred->key, cred->key_len);
1395	return 0;
1396}
1397
1398
1399static int wps_build_cred_mac_addr(struct wpabuf *msg,
1400				   const struct wps_credential *cred)
1401{
1402	wpa_printf(MSG_DEBUG, "WPS:  * MAC Address (" MACSTR ")",
1403		   MAC2STR(cred->mac_addr));
1404	wpabuf_put_be16(msg, ATTR_MAC_ADDR);
1405	wpabuf_put_be16(msg, ETH_ALEN);
1406	wpabuf_put_data(msg, cred->mac_addr, ETH_ALEN);
1407	return 0;
1408}
1409
1410
1411static int wps_build_credential(struct wpabuf *msg,
1412				const struct wps_credential *cred)
1413{
1414	if (wps_build_cred_network_idx(msg, cred) ||
1415	    wps_build_cred_ssid(msg, cred) ||
1416	    wps_build_cred_auth_type(msg, cred) ||
1417	    wps_build_cred_encr_type(msg, cred) ||
1418	    wps_build_cred_network_key(msg, cred) ||
1419	    wps_build_cred_mac_addr(msg, cred))
1420		return -1;
1421	return 0;
1422}
1423
1424
1425int wps_build_credential_wrap(struct wpabuf *msg,
1426			      const struct wps_credential *cred)
1427{
1428	struct wpabuf *wbuf;
1429	wbuf = wpabuf_alloc(200);
1430	if (wbuf == NULL)
1431		return -1;
1432	if (wps_build_credential(wbuf, cred)) {
1433		wpabuf_free(wbuf);
1434		return -1;
1435	}
1436	wpabuf_put_be16(msg, ATTR_CRED);
1437	wpabuf_put_be16(msg, wpabuf_len(wbuf));
1438	wpabuf_put_buf(msg, wbuf);
1439	wpabuf_free(wbuf);
1440	return 0;
1441}
1442
1443
1444int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
1445{
1446	struct wpabuf *cred;
1447
1448	if (wps->wps->registrar->skip_cred_build)
1449		goto skip_cred_build;
1450
1451	wpa_printf(MSG_DEBUG, "WPS:  * Credential");
1452	if (wps->use_cred) {
1453		os_memcpy(&wps->cred, wps->use_cred, sizeof(wps->cred));
1454		goto use_provided;
1455	}
1456	os_memset(&wps->cred, 0, sizeof(wps->cred));
1457
1458	os_memcpy(wps->cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
1459	wps->cred.ssid_len = wps->wps->ssid_len;
1460
1461	/* Select the best authentication and encryption type */
1462	if (wps->auth_type & WPS_AUTH_WPA2PSK)
1463		wps->auth_type = WPS_AUTH_WPA2PSK;
1464	else if (wps->auth_type & WPS_AUTH_WPAPSK)
1465		wps->auth_type = WPS_AUTH_WPAPSK;
1466	else if (wps->auth_type & WPS_AUTH_OPEN)
1467		wps->auth_type = WPS_AUTH_OPEN;
1468	else if (wps->auth_type & WPS_AUTH_SHARED)
1469		wps->auth_type = WPS_AUTH_SHARED;
1470	else {
1471		wpa_printf(MSG_DEBUG, "WPS: Unsupported auth_type 0x%x",
1472			   wps->auth_type);
1473		return -1;
1474	}
1475	wps->cred.auth_type = wps->auth_type;
1476
1477	if (wps->auth_type == WPS_AUTH_WPA2PSK ||
1478	    wps->auth_type == WPS_AUTH_WPAPSK) {
1479		if (wps->encr_type & WPS_ENCR_AES)
1480			wps->encr_type = WPS_ENCR_AES;
1481		else if (wps->encr_type & WPS_ENCR_TKIP)
1482			wps->encr_type = WPS_ENCR_TKIP;
1483		else {
1484			wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
1485				   "type for WPA/WPA2");
1486			return -1;
1487		}
1488	} else {
1489		if (wps->encr_type & WPS_ENCR_WEP)
1490			wps->encr_type = WPS_ENCR_WEP;
1491		else if (wps->encr_type & WPS_ENCR_NONE)
1492			wps->encr_type = WPS_ENCR_NONE;
1493		else {
1494			wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
1495				   "type for non-WPA/WPA2 mode");
1496			return -1;
1497		}
1498	}
1499	wps->cred.encr_type = wps->encr_type;
1500	/*
1501	 * Set MAC address in the Credential to be the Enrollee's MAC address
1502	 */
1503	os_memcpy(wps->cred.mac_addr, wps->mac_addr_e, ETH_ALEN);
1504
1505	if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap &&
1506	    !wps->wps->registrar->disable_auto_conf) {
1507		u8 r[16];
1508		/* Generate a random passphrase */
1509		if (random_get_bytes(r, sizeof(r)) < 0)
1510			return -1;
1511		os_free(wps->new_psk);
1512		wps->new_psk = base64_encode(r, sizeof(r), &wps->new_psk_len);
1513		if (wps->new_psk == NULL)
1514			return -1;
1515		wps->new_psk_len--; /* remove newline */
1516		while (wps->new_psk_len &&
1517		       wps->new_psk[wps->new_psk_len - 1] == '=')
1518			wps->new_psk_len--;
1519		wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Generated passphrase",
1520				      wps->new_psk, wps->new_psk_len);
1521		os_memcpy(wps->cred.key, wps->new_psk, wps->new_psk_len);
1522		wps->cred.key_len = wps->new_psk_len;
1523	} else if (wps->use_psk_key && wps->wps->psk_set) {
1524		char hex[65];
1525		wpa_printf(MSG_DEBUG, "WPS: Use PSK format for Network Key");
1526		wpa_snprintf_hex(hex, sizeof(hex), wps->wps->psk, 32);
1527		os_memcpy(wps->cred.key, hex, 32 * 2);
1528		wps->cred.key_len = 32 * 2;
1529	} else if (wps->wps->network_key) {
1530		os_memcpy(wps->cred.key, wps->wps->network_key,
1531			  wps->wps->network_key_len);
1532		wps->cred.key_len = wps->wps->network_key_len;
1533	} else if (wps->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
1534		char hex[65];
1535		/* Generate a random per-device PSK */
1536		os_free(wps->new_psk);
1537		wps->new_psk_len = 32;
1538		wps->new_psk = os_malloc(wps->new_psk_len);
1539		if (wps->new_psk == NULL)
1540			return -1;
1541		if (random_get_bytes(wps->new_psk, wps->new_psk_len) < 0) {
1542			os_free(wps->new_psk);
1543			wps->new_psk = NULL;
1544			return -1;
1545		}
1546		wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
1547				wps->new_psk, wps->new_psk_len);
1548		wpa_snprintf_hex(hex, sizeof(hex), wps->new_psk,
1549				 wps->new_psk_len);
1550		os_memcpy(wps->cred.key, hex, wps->new_psk_len * 2);
1551		wps->cred.key_len = wps->new_psk_len * 2;
1552	}
1553
1554use_provided:
1555#ifdef CONFIG_WPS_TESTING
1556	if (wps_testing_dummy_cred)
1557		cred = wpabuf_alloc(200);
1558	else
1559		cred = NULL;
1560	if (cred) {
1561		struct wps_credential dummy;
1562		wpa_printf(MSG_DEBUG, "WPS: Add dummy credential");
1563		os_memset(&dummy, 0, sizeof(dummy));
1564		os_memcpy(dummy.ssid, "dummy", 5);
1565		dummy.ssid_len = 5;
1566		dummy.auth_type = WPS_AUTH_WPA2PSK;
1567		dummy.encr_type = WPS_ENCR_AES;
1568		os_memcpy(dummy.key, "dummy psk", 9);
1569		dummy.key_len = 9;
1570		os_memcpy(dummy.mac_addr, wps->mac_addr_e, ETH_ALEN);
1571		wps_build_credential(cred, &dummy);
1572		wpa_hexdump_buf(MSG_DEBUG, "WPS: Dummy Credential", cred);
1573
1574		wpabuf_put_be16(msg, ATTR_CRED);
1575		wpabuf_put_be16(msg, wpabuf_len(cred));
1576		wpabuf_put_buf(msg, cred);
1577
1578		wpabuf_free(cred);
1579	}
1580#endif /* CONFIG_WPS_TESTING */
1581
1582	cred = wpabuf_alloc(200);
1583	if (cred == NULL)
1584		return -1;
1585
1586	if (wps_build_credential(cred, &wps->cred)) {
1587		wpabuf_free(cred);
1588		return -1;
1589	}
1590
1591	wpabuf_put_be16(msg, ATTR_CRED);
1592	wpabuf_put_be16(msg, wpabuf_len(cred));
1593	wpabuf_put_buf(msg, cred);
1594	wpabuf_free(cred);
1595
1596skip_cred_build:
1597	if (wps->wps->registrar->extra_cred) {
1598		wpa_printf(MSG_DEBUG, "WPS:  * Credential (pre-configured)");
1599		wpabuf_put_buf(msg, wps->wps->registrar->extra_cred);
1600	}
1601
1602	return 0;
1603}
1604
1605
1606static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *msg)
1607{
1608	wpa_printf(MSG_DEBUG, "WPS:  * AP Settings");
1609
1610	if (wps_build_credential(msg, &wps->cred))
1611		return -1;
1612
1613	return 0;
1614}
1615
1616
1617static struct wpabuf * wps_build_ap_cred(struct wps_data *wps)
1618{
1619	struct wpabuf *msg, *plain;
1620
1621	msg = wpabuf_alloc(1000);
1622	if (msg == NULL)
1623		return NULL;
1624
1625	plain = wpabuf_alloc(200);
1626	if (plain == NULL) {
1627		wpabuf_free(msg);
1628		return NULL;
1629	}
1630
1631	if (wps_build_ap_settings(wps, plain)) {
1632		wpabuf_free(plain);
1633		wpabuf_free(msg);
1634		return NULL;
1635	}
1636
1637	wpabuf_put_be16(msg, ATTR_CRED);
1638	wpabuf_put_be16(msg, wpabuf_len(plain));
1639	wpabuf_put_buf(msg, plain);
1640	wpabuf_free(plain);
1641
1642	return msg;
1643}
1644
1645
1646static struct wpabuf * wps_build_m2(struct wps_data *wps)
1647{
1648	struct wpabuf *msg;
1649
1650	if (random_get_bytes(wps->nonce_r, WPS_NONCE_LEN) < 0)
1651		return NULL;
1652	wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
1653		    wps->nonce_r, WPS_NONCE_LEN);
1654	wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
1655
1656	wpa_printf(MSG_DEBUG, "WPS: Building Message M2");
1657	msg = wpabuf_alloc(1000);
1658	if (msg == NULL)
1659		return NULL;
1660
1661	if (wps_build_version(msg) ||
1662	    wps_build_msg_type(msg, WPS_M2) ||
1663	    wps_build_enrollee_nonce(wps, msg) ||
1664	    wps_build_registrar_nonce(wps, msg) ||
1665	    wps_build_uuid_r(wps, msg) ||
1666	    wps_build_public_key(wps, msg) ||
1667	    wps_derive_keys(wps) ||
1668	    wps_build_auth_type_flags(wps, msg) ||
1669	    wps_build_encr_type_flags(wps, msg) ||
1670	    wps_build_conn_type_flags(wps, msg) ||
1671	    wps_build_config_methods_r(wps->wps->registrar, msg) ||
1672	    wps_build_device_attrs(&wps->wps->dev, msg) ||
1673	    wps_build_rf_bands(&wps->wps->dev, msg) ||
1674	    wps_build_assoc_state(wps, msg) ||
1675	    wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
1676	    wps_build_dev_password_id(msg, wps->dev_pw_id) ||
1677	    wps_build_os_version(&wps->wps->dev, msg) ||
1678	    wps_build_wfa_ext(msg, 0, NULL, 0) ||
1679	    wps_build_authenticator(wps, msg)) {
1680		wpabuf_free(msg);
1681		return NULL;
1682	}
1683
1684	wps->int_reg = 1;
1685	wps->state = RECV_M3;
1686	return msg;
1687}
1688
1689
1690static struct wpabuf * wps_build_m2d(struct wps_data *wps)
1691{
1692	struct wpabuf *msg;
1693	u16 err = wps->config_error;
1694
1695	wpa_printf(MSG_DEBUG, "WPS: Building Message M2D");
1696	msg = wpabuf_alloc(1000);
1697	if (msg == NULL)
1698		return NULL;
1699
1700	if (wps->wps->ap && wps->wps->ap_setup_locked &&
1701	    err == WPS_CFG_NO_ERROR)
1702		err = WPS_CFG_SETUP_LOCKED;
1703
1704	if (wps_build_version(msg) ||
1705	    wps_build_msg_type(msg, WPS_M2D) ||
1706	    wps_build_enrollee_nonce(wps, msg) ||
1707	    wps_build_registrar_nonce(wps, msg) ||
1708	    wps_build_uuid_r(wps, msg) ||
1709	    wps_build_auth_type_flags(wps, msg) ||
1710	    wps_build_encr_type_flags(wps, msg) ||
1711	    wps_build_conn_type_flags(wps, msg) ||
1712	    wps_build_config_methods_r(wps->wps->registrar, msg) ||
1713	    wps_build_device_attrs(&wps->wps->dev, msg) ||
1714	    wps_build_rf_bands(&wps->wps->dev, msg) ||
1715	    wps_build_assoc_state(wps, msg) ||
1716	    wps_build_config_error(msg, err) ||
1717	    wps_build_os_version(&wps->wps->dev, msg) ||
1718	    wps_build_wfa_ext(msg, 0, NULL, 0)) {
1719		wpabuf_free(msg);
1720		return NULL;
1721	}
1722
1723	wps->state = RECV_M2D_ACK;
1724	return msg;
1725}
1726
1727
1728static struct wpabuf * wps_build_m4(struct wps_data *wps)
1729{
1730	struct wpabuf *msg, *plain;
1731
1732	wpa_printf(MSG_DEBUG, "WPS: Building Message M4");
1733
1734	wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);
1735
1736	plain = wpabuf_alloc(200);
1737	if (plain == NULL)
1738		return NULL;
1739
1740	msg = wpabuf_alloc(1000);
1741	if (msg == NULL) {
1742		wpabuf_free(plain);
1743		return NULL;
1744	}
1745
1746	if (wps_build_version(msg) ||
1747	    wps_build_msg_type(msg, WPS_M4) ||
1748	    wps_build_enrollee_nonce(wps, msg) ||
1749	    wps_build_r_hash(wps, msg) ||
1750	    wps_build_r_snonce1(wps, plain) ||
1751	    wps_build_key_wrap_auth(wps, plain) ||
1752	    wps_build_encr_settings(wps, msg, plain) ||
1753	    wps_build_wfa_ext(msg, 0, NULL, 0) ||
1754	    wps_build_authenticator(wps, msg)) {
1755		wpabuf_free(plain);
1756		wpabuf_free(msg);
1757		return NULL;
1758	}
1759	wpabuf_free(plain);
1760
1761	wps->state = RECV_M5;
1762	return msg;
1763}
1764
1765
1766static struct wpabuf * wps_build_m6(struct wps_data *wps)
1767{
1768	struct wpabuf *msg, *plain;
1769
1770	wpa_printf(MSG_DEBUG, "WPS: Building Message M6");
1771
1772	plain = wpabuf_alloc(200);
1773	if (plain == NULL)
1774		return NULL;
1775
1776	msg = wpabuf_alloc(1000);
1777	if (msg == NULL) {
1778		wpabuf_free(plain);
1779		return NULL;
1780	}
1781
1782	if (wps_build_version(msg) ||
1783	    wps_build_msg_type(msg, WPS_M6) ||
1784	    wps_build_enrollee_nonce(wps, msg) ||
1785	    wps_build_r_snonce2(wps, plain) ||
1786	    wps_build_key_wrap_auth(wps, plain) ||
1787	    wps_build_encr_settings(wps, msg, plain) ||
1788	    wps_build_wfa_ext(msg, 0, NULL, 0) ||
1789	    wps_build_authenticator(wps, msg)) {
1790		wpabuf_free(plain);
1791		wpabuf_free(msg);
1792		return NULL;
1793	}
1794	wpabuf_free(plain);
1795
1796	wps->wps_pin_revealed = 1;
1797	wps->state = RECV_M7;
1798	return msg;
1799}
1800
1801
1802static struct wpabuf * wps_build_m8(struct wps_data *wps)
1803{
1804	struct wpabuf *msg, *plain;
1805
1806	wpa_printf(MSG_DEBUG, "WPS: Building Message M8");
1807
1808	plain = wpabuf_alloc(500);
1809	if (plain == NULL)
1810		return NULL;
1811
1812	msg = wpabuf_alloc(1000);
1813	if (msg == NULL) {
1814		wpabuf_free(plain);
1815		return NULL;
1816	}
1817
1818	if (wps_build_version(msg) ||
1819	    wps_build_msg_type(msg, WPS_M8) ||
1820	    wps_build_enrollee_nonce(wps, msg) ||
1821	    ((wps->wps->ap || wps->er) && wps_build_cred(wps, plain)) ||
1822	    (!wps->wps->ap && !wps->er && wps_build_ap_settings(wps, plain)) ||
1823	    wps_build_key_wrap_auth(wps, plain) ||
1824	    wps_build_encr_settings(wps, msg, plain) ||
1825	    wps_build_wfa_ext(msg, 0, NULL, 0) ||
1826	    wps_build_authenticator(wps, msg)) {
1827		wpabuf_free(plain);
1828		wpabuf_free(msg);
1829		return NULL;
1830	}
1831	wpabuf_free(plain);
1832
1833	wps->state = RECV_DONE;
1834	return msg;
1835}
1836
1837
1838struct wpabuf * wps_registrar_get_msg(struct wps_data *wps,
1839				      enum wsc_op_code *op_code)
1840{
1841	struct wpabuf *msg;
1842
1843#ifdef CONFIG_WPS_UPNP
1844	if (!wps->int_reg && wps->wps->wps_upnp) {
1845		struct upnp_pending_message *p, *prev = NULL;
1846		if (wps->ext_reg > 1)
1847			wps_registrar_free_pending_m2(wps->wps);
1848		p = wps->wps->upnp_msgs;
1849		/* TODO: check pending message MAC address */
1850		while (p && p->next) {
1851			prev = p;
1852			p = p->next;
1853		}
1854		if (p) {
1855			wpa_printf(MSG_DEBUG, "WPS: Use pending message from "
1856				   "UPnP");
1857			if (prev)
1858				prev->next = NULL;
1859			else
1860				wps->wps->upnp_msgs = NULL;
1861			msg = p->msg;
1862			switch (p->type) {
1863			case WPS_WSC_ACK:
1864				*op_code = WSC_ACK;
1865				break;
1866			case WPS_WSC_NACK:
1867				*op_code = WSC_NACK;
1868				break;
1869			default:
1870				*op_code = WSC_MSG;
1871				break;
1872			}
1873			os_free(p);
1874			if (wps->ext_reg == 0)
1875				wps->ext_reg = 1;
1876			return msg;
1877		}
1878	}
1879	if (wps->ext_reg) {
1880		wpa_printf(MSG_DEBUG, "WPS: Using external Registrar, but no "
1881			   "pending message available");
1882		return NULL;
1883	}
1884#endif /* CONFIG_WPS_UPNP */
1885
1886	switch (wps->state) {
1887	case SEND_M2:
1888		if (wps_get_dev_password(wps) < 0)
1889			msg = wps_build_m2d(wps);
1890		else
1891			msg = wps_build_m2(wps);
1892		*op_code = WSC_MSG;
1893		break;
1894	case SEND_M2D:
1895		msg = wps_build_m2d(wps);
1896		*op_code = WSC_MSG;
1897		break;
1898	case SEND_M4:
1899		msg = wps_build_m4(wps);
1900		*op_code = WSC_MSG;
1901		break;
1902	case SEND_M6:
1903		msg = wps_build_m6(wps);
1904		*op_code = WSC_MSG;
1905		break;
1906	case SEND_M8:
1907		msg = wps_build_m8(wps);
1908		*op_code = WSC_MSG;
1909		break;
1910	case RECV_DONE:
1911		msg = wps_build_wsc_ack(wps);
1912		*op_code = WSC_ACK;
1913		break;
1914	case SEND_WSC_NACK:
1915		msg = wps_build_wsc_nack(wps);
1916		*op_code = WSC_NACK;
1917		break;
1918	default:
1919		wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
1920			   "a message", wps->state);
1921		msg = NULL;
1922		break;
1923	}
1924
1925	if (*op_code == WSC_MSG && msg) {
1926		/* Save a copy of the last message for Authenticator derivation
1927		 */
1928		wpabuf_free(wps->last_msg);
1929		wps->last_msg = wpabuf_dup(msg);
1930	}
1931
1932	return msg;
1933}
1934
1935
1936static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
1937{
1938	if (e_nonce == NULL) {
1939		wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
1940		return -1;
1941	}
1942
1943	os_memcpy(wps->nonce_e, e_nonce, WPS_NONCE_LEN);
1944	wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
1945		    wps->nonce_e, WPS_NONCE_LEN);
1946
1947	return 0;
1948}
1949
1950
1951static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
1952{
1953	if (r_nonce == NULL) {
1954		wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
1955		return -1;
1956	}
1957
1958	if (os_memcmp(wps->nonce_r, r_nonce, WPS_NONCE_LEN) != 0) {
1959		wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce received");
1960		return -1;
1961	}
1962
1963	return 0;
1964}
1965
1966
1967static int wps_process_uuid_e(struct wps_data *wps, const u8 *uuid_e)
1968{
1969	if (uuid_e == NULL) {
1970		wpa_printf(MSG_DEBUG, "WPS: No UUID-E received");
1971		return -1;
1972	}
1973
1974	os_memcpy(wps->uuid_e, uuid_e, WPS_UUID_LEN);
1975	wpa_hexdump(MSG_DEBUG, "WPS: UUID-E", wps->uuid_e, WPS_UUID_LEN);
1976
1977	return 0;
1978}
1979
1980
1981static int wps_process_dev_password_id(struct wps_data *wps, const u8 *pw_id)
1982{
1983	if (pw_id == NULL) {
1984		wpa_printf(MSG_DEBUG, "WPS: No Device Password ID received");
1985		return -1;
1986	}
1987
1988	wps->dev_pw_id = WPA_GET_BE16(pw_id);
1989	wpa_printf(MSG_DEBUG, "WPS: Device Password ID %d", wps->dev_pw_id);
1990
1991	return 0;
1992}
1993
1994
1995static int wps_process_e_hash1(struct wps_data *wps, const u8 *e_hash1)
1996{
1997	if (e_hash1 == NULL) {
1998		wpa_printf(MSG_DEBUG, "WPS: No E-Hash1 received");
1999		return -1;
2000	}
2001
2002	os_memcpy(wps->peer_hash1, e_hash1, WPS_HASH_LEN);
2003	wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", wps->peer_hash1, WPS_HASH_LEN);
2004
2005	return 0;
2006}
2007
2008
2009static int wps_process_e_hash2(struct wps_data *wps, const u8 *e_hash2)
2010{
2011	if (e_hash2 == NULL) {
2012		wpa_printf(MSG_DEBUG, "WPS: No E-Hash2 received");
2013		return -1;
2014	}
2015
2016	os_memcpy(wps->peer_hash2, e_hash2, WPS_HASH_LEN);
2017	wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", wps->peer_hash2, WPS_HASH_LEN);
2018
2019	return 0;
2020}
2021
2022
2023static int wps_process_e_snonce1(struct wps_data *wps, const u8 *e_snonce1)
2024{
2025	u8 hash[SHA256_MAC_LEN];
2026	const u8 *addr[4];
2027	size_t len[4];
2028
2029	if (e_snonce1 == NULL) {
2030		wpa_printf(MSG_DEBUG, "WPS: No E-SNonce1 received");
2031		return -1;
2032	}
2033
2034	wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce1", e_snonce1,
2035			WPS_SECRET_NONCE_LEN);
2036
2037	/* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
2038	addr[0] = e_snonce1;
2039	len[0] = WPS_SECRET_NONCE_LEN;
2040	addr[1] = wps->psk1;
2041	len[1] = WPS_PSK_LEN;
2042	addr[2] = wpabuf_head(wps->dh_pubkey_e);
2043	len[2] = wpabuf_len(wps->dh_pubkey_e);
2044	addr[3] = wpabuf_head(wps->dh_pubkey_r);
2045	len[3] = wpabuf_len(wps->dh_pubkey_r);
2046	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
2047
2048	if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
2049		wpa_printf(MSG_DEBUG, "WPS: E-Hash1 derived from E-S1 does "
2050			   "not match with the pre-committed value");
2051		wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
2052		wps_pwd_auth_fail_event(wps->wps, 0, 1);
2053		return -1;
2054	}
2055
2056	wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the first "
2057		   "half of the device password");
2058
2059	return 0;
2060}
2061
2062
2063static int wps_process_e_snonce2(struct wps_data *wps, const u8 *e_snonce2)
2064{
2065	u8 hash[SHA256_MAC_LEN];
2066	const u8 *addr[4];
2067	size_t len[4];
2068
2069	if (e_snonce2 == NULL) {
2070		wpa_printf(MSG_DEBUG, "WPS: No E-SNonce2 received");
2071		return -1;
2072	}
2073
2074	wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce2", e_snonce2,
2075			WPS_SECRET_NONCE_LEN);
2076
2077	/* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
2078	addr[0] = e_snonce2;
2079	len[0] = WPS_SECRET_NONCE_LEN;
2080	addr[1] = wps->psk2;
2081	len[1] = WPS_PSK_LEN;
2082	addr[2] = wpabuf_head(wps->dh_pubkey_e);
2083	len[2] = wpabuf_len(wps->dh_pubkey_e);
2084	addr[3] = wpabuf_head(wps->dh_pubkey_r);
2085	len[3] = wpabuf_len(wps->dh_pubkey_r);
2086	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
2087
2088	if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
2089		wpa_printf(MSG_DEBUG, "WPS: E-Hash2 derived from E-S2 does "
2090			   "not match with the pre-committed value");
2091		wps_registrar_invalidate_pin(wps->wps->registrar, wps->uuid_e);
2092		wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
2093		wps_pwd_auth_fail_event(wps->wps, 0, 2);
2094		return -1;
2095	}
2096
2097	wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the second "
2098		   "half of the device password");
2099	wps->wps_pin_revealed = 0;
2100	wps_registrar_unlock_pin(wps->wps->registrar, wps->uuid_e);
2101
2102	/*
2103	 * In case wildcard PIN is used and WPS handshake succeeds in the first
2104	 * attempt, wps_registrar_unlock_pin() would not free the PIN, so make
2105	 * sure the PIN gets invalidated here.
2106	 */
2107	wps_registrar_invalidate_pin(wps->wps->registrar, wps->uuid_e);
2108
2109	return 0;
2110}
2111
2112
2113static int wps_process_mac_addr(struct wps_data *wps, const u8 *mac_addr)
2114{
2115	if (mac_addr == NULL) {
2116		wpa_printf(MSG_DEBUG, "WPS: No MAC Address received");
2117		return -1;
2118	}
2119
2120	wpa_printf(MSG_DEBUG, "WPS: Enrollee MAC Address " MACSTR,
2121		   MAC2STR(mac_addr));
2122	os_memcpy(wps->mac_addr_e, mac_addr, ETH_ALEN);
2123	os_memcpy(wps->peer_dev.mac_addr, mac_addr, ETH_ALEN);
2124
2125	return 0;
2126}
2127
2128
2129static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
2130			      size_t pk_len)
2131{
2132	if (pk == NULL || pk_len == 0) {
2133		wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
2134		return -1;
2135	}
2136
2137#ifdef CONFIG_WPS_OOB
2138	if (wps->wps->oob_conf.pubkey_hash != NULL) {
2139		const u8 *addr[1];
2140		u8 hash[WPS_HASH_LEN];
2141
2142		addr[0] = pk;
2143		sha256_vector(1, addr, &pk_len, hash);
2144		if (os_memcmp(hash,
2145			      wpabuf_head(wps->wps->oob_conf.pubkey_hash),
2146			      WPS_OOB_PUBKEY_HASH_LEN) != 0) {
2147			wpa_printf(MSG_ERROR, "WPS: Public Key hash error");
2148			return -1;
2149		}
2150	}
2151#endif /* CONFIG_WPS_OOB */
2152
2153	wpabuf_free(wps->dh_pubkey_e);
2154	wps->dh_pubkey_e = wpabuf_alloc_copy(pk, pk_len);
2155	if (wps->dh_pubkey_e == NULL)
2156		return -1;
2157
2158	return 0;
2159}
2160
2161
2162static int wps_process_auth_type_flags(struct wps_data *wps, const u8 *auth)
2163{
2164	u16 auth_types;
2165
2166	if (auth == NULL) {
2167		wpa_printf(MSG_DEBUG, "WPS: No Authentication Type flags "
2168			   "received");
2169		return -1;
2170	}
2171
2172	auth_types = WPA_GET_BE16(auth);
2173
2174	wpa_printf(MSG_DEBUG, "WPS: Enrollee Authentication Type flags 0x%x",
2175		   auth_types);
2176	wps->auth_type = wps->wps->auth_types & auth_types;
2177	if (wps->auth_type == 0) {
2178		wpa_printf(MSG_DEBUG, "WPS: No match in supported "
2179			   "authentication types (own 0x%x Enrollee 0x%x)",
2180			   wps->wps->auth_types, auth_types);
2181#ifdef WPS_WORKAROUNDS
2182		/*
2183		 * Some deployed implementations seem to advertise incorrect
2184		 * information in this attribute. For example, Linksys WRT350N
2185		 * seems to have a byteorder bug that breaks this negotiation.
2186		 * In order to interoperate with existing implementations,
2187		 * assume that the Enrollee supports everything we do.
2188		 */
2189		wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
2190			   "does not advertise supported authentication types "
2191			   "correctly");
2192		wps->auth_type = wps->wps->auth_types;
2193#else /* WPS_WORKAROUNDS */
2194		return -1;
2195#endif /* WPS_WORKAROUNDS */
2196	}
2197
2198	return 0;
2199}
2200
2201
2202static int wps_process_encr_type_flags(struct wps_data *wps, const u8 *encr)
2203{
2204	u16 encr_types;
2205
2206	if (encr == NULL) {
2207		wpa_printf(MSG_DEBUG, "WPS: No Encryption Type flags "
2208			   "received");
2209		return -1;
2210	}
2211
2212	encr_types = WPA_GET_BE16(encr);
2213
2214	wpa_printf(MSG_DEBUG, "WPS: Enrollee Encryption Type flags 0x%x",
2215		   encr_types);
2216	wps->encr_type = wps->wps->encr_types & encr_types;
2217	if (wps->encr_type == 0) {
2218		wpa_printf(MSG_DEBUG, "WPS: No match in supported "
2219			   "encryption types (own 0x%x Enrollee 0x%x)",
2220			   wps->wps->encr_types, encr_types);
2221#ifdef WPS_WORKAROUNDS
2222		/*
2223		 * Some deployed implementations seem to advertise incorrect
2224		 * information in this attribute. For example, Linksys WRT350N
2225		 * seems to have a byteorder bug that breaks this negotiation.
2226		 * In order to interoperate with existing implementations,
2227		 * assume that the Enrollee supports everything we do.
2228		 */
2229		wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
2230			   "does not advertise supported encryption types "
2231			   "correctly");
2232		wps->encr_type = wps->wps->encr_types;
2233#else /* WPS_WORKAROUNDS */
2234		return -1;
2235#endif /* WPS_WORKAROUNDS */
2236	}
2237
2238	return 0;
2239}
2240
2241
2242static int wps_process_conn_type_flags(struct wps_data *wps, const u8 *conn)
2243{
2244	if (conn == NULL) {
2245		wpa_printf(MSG_DEBUG, "WPS: No Connection Type flags "
2246			   "received");
2247		return -1;
2248	}
2249
2250	wpa_printf(MSG_DEBUG, "WPS: Enrollee Connection Type flags 0x%x",
2251		   *conn);
2252
2253	return 0;
2254}
2255
2256
2257static int wps_process_config_methods(struct wps_data *wps, const u8 *methods)
2258{
2259	u16 m;
2260
2261	if (methods == NULL) {
2262		wpa_printf(MSG_DEBUG, "WPS: No Config Methods received");
2263		return -1;
2264	}
2265
2266	m = WPA_GET_BE16(methods);
2267
2268	wpa_printf(MSG_DEBUG, "WPS: Enrollee Config Methods 0x%x"
2269		   "%s%s%s%s%s%s%s%s%s", m,
2270		   m & WPS_CONFIG_USBA ? " [USBA]" : "",
2271		   m & WPS_CONFIG_ETHERNET ? " [Ethernet]" : "",
2272		   m & WPS_CONFIG_LABEL ? " [Label]" : "",
2273		   m & WPS_CONFIG_DISPLAY ? " [Display]" : "",
2274		   m & WPS_CONFIG_EXT_NFC_TOKEN ? " [Ext NFC Token]" : "",
2275		   m & WPS_CONFIG_INT_NFC_TOKEN ? " [Int NFC Token]" : "",
2276		   m & WPS_CONFIG_NFC_INTERFACE ? " [NFC]" : "",
2277		   m & WPS_CONFIG_PUSHBUTTON ? " [PBC]" : "",
2278		   m & WPS_CONFIG_KEYPAD ? " [Keypad]" : "");
2279
2280	if (!(m & WPS_CONFIG_DISPLAY) && !wps->use_psk_key) {
2281		/*
2282		 * The Enrollee does not have a display so it is unlikely to be
2283		 * able to show the passphrase to a user and as such, could
2284		 * benefit from receiving PSK to reduce key derivation time.
2285		 */
2286		wpa_printf(MSG_DEBUG, "WPS: Prefer PSK format key due to "
2287			   "Enrollee not supporting display");
2288		wps->use_psk_key = 1;
2289	}
2290
2291	return 0;
2292}
2293
2294
2295static int wps_process_wps_state(struct wps_data *wps, const u8 *state)
2296{
2297	if (state == NULL) {
2298		wpa_printf(MSG_DEBUG, "WPS: No Wi-Fi Protected Setup State "
2299			   "received");
2300		return -1;
2301	}
2302
2303	wpa_printf(MSG_DEBUG, "WPS: Enrollee Wi-Fi Protected Setup State %d",
2304		   *state);
2305
2306	return 0;
2307}
2308
2309
2310static int wps_process_assoc_state(struct wps_data *wps, const u8 *assoc)
2311{
2312	u16 a;
2313
2314	if (assoc == NULL) {
2315		wpa_printf(MSG_DEBUG, "WPS: No Association State received");
2316		return -1;
2317	}
2318
2319	a = WPA_GET_BE16(assoc);
2320	wpa_printf(MSG_DEBUG, "WPS: Enrollee Association State %d", a);
2321
2322	return 0;
2323}
2324
2325
2326static int wps_process_config_error(struct wps_data *wps, const u8 *err)
2327{
2328	u16 e;
2329
2330	if (err == NULL) {
2331		wpa_printf(MSG_DEBUG, "WPS: No Configuration Error received");
2332		return -1;
2333	}
2334
2335	e = WPA_GET_BE16(err);
2336	wpa_printf(MSG_DEBUG, "WPS: Enrollee Configuration Error %d", e);
2337
2338	return 0;
2339}
2340
2341
2342static int wps_registrar_p2p_dev_addr_match(struct wps_data *wps)
2343{
2344#ifdef CONFIG_P2P
2345	struct wps_registrar *reg = wps->wps->registrar;
2346
2347	if (is_zero_ether_addr(reg->p2p_dev_addr))
2348		return 1; /* no filtering in use */
2349
2350	if (os_memcmp(reg->p2p_dev_addr, wps->p2p_dev_addr, ETH_ALEN) != 0) {
2351		wpa_printf(MSG_DEBUG, "WPS: No match on P2P Device Address "
2352			   "filtering for PBC: expected " MACSTR " was "
2353			   MACSTR " - indicate PBC session overlap",
2354			   MAC2STR(reg->p2p_dev_addr),
2355			   MAC2STR(wps->p2p_dev_addr));
2356		return 0;
2357	}
2358#endif /* CONFIG_P2P */
2359	return 1;
2360}
2361
2362
2363static int wps_registrar_skip_overlap(struct wps_data *wps)
2364{
2365#ifdef CONFIG_P2P
2366	struct wps_registrar *reg = wps->wps->registrar;
2367
2368	if (is_zero_ether_addr(reg->p2p_dev_addr))
2369		return 0; /* no specific Enrollee selected */
2370
2371	if (os_memcmp(reg->p2p_dev_addr, wps->p2p_dev_addr, ETH_ALEN) == 0) {
2372		wpa_printf(MSG_DEBUG, "WPS: Skip PBC overlap due to selected "
2373			   "Enrollee match");
2374		return 1;
2375	}
2376#endif /* CONFIG_P2P */
2377	return 0;
2378}
2379
2380
2381static enum wps_process_res wps_process_m1(struct wps_data *wps,
2382					   struct wps_parse_attr *attr)
2383{
2384	wpa_printf(MSG_DEBUG, "WPS: Received M1");
2385
2386	if (wps->state != RECV_M1) {
2387		wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2388			   "receiving M1", wps->state);
2389		return WPS_FAILURE;
2390	}
2391
2392	if (wps_process_uuid_e(wps, attr->uuid_e) ||
2393	    wps_process_mac_addr(wps, attr->mac_addr) ||
2394	    wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
2395	    wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
2396	    wps_process_auth_type_flags(wps, attr->auth_type_flags) ||
2397	    wps_process_encr_type_flags(wps, attr->encr_type_flags) ||
2398	    wps_process_conn_type_flags(wps, attr->conn_type_flags) ||
2399	    wps_process_config_methods(wps, attr->config_methods) ||
2400	    wps_process_wps_state(wps, attr->wps_state) ||
2401	    wps_process_device_attrs(&wps->peer_dev, attr) ||
2402	    wps_process_rf_bands(&wps->peer_dev, attr->rf_bands) ||
2403	    wps_process_assoc_state(wps, attr->assoc_state) ||
2404	    wps_process_dev_password_id(wps, attr->dev_password_id) ||
2405	    wps_process_config_error(wps, attr->config_error) ||
2406	    wps_process_os_version(&wps->peer_dev, attr->os_version))
2407		return WPS_FAILURE;
2408
2409	if (wps->dev_pw_id < 0x10 &&
2410	    wps->dev_pw_id != DEV_PW_DEFAULT &&
2411	    wps->dev_pw_id != DEV_PW_USER_SPECIFIED &&
2412	    wps->dev_pw_id != DEV_PW_MACHINE_SPECIFIED &&
2413	    wps->dev_pw_id != DEV_PW_REGISTRAR_SPECIFIED &&
2414	    (wps->dev_pw_id != DEV_PW_PUSHBUTTON ||
2415	     !wps->wps->registrar->pbc)) {
2416		wpa_printf(MSG_DEBUG, "WPS: Unsupported Device Password ID %d",
2417			   wps->dev_pw_id);
2418		wps->state = SEND_M2D;
2419		return WPS_CONTINUE;
2420	}
2421
2422#ifdef CONFIG_WPS_OOB
2423	if (wps->dev_pw_id >= 0x10 &&
2424	    wps->dev_pw_id != wps->wps->oob_dev_pw_id) {
2425		wpa_printf(MSG_DEBUG, "WPS: OOB Device Password ID "
2426			   "%d mismatch", wps->dev_pw_id);
2427		wps->state = SEND_M2D;
2428		return WPS_CONTINUE;
2429	}
2430#endif /* CONFIG_WPS_OOB */
2431
2432	if (wps->dev_pw_id == DEV_PW_PUSHBUTTON) {
2433		if ((wps->wps->registrar->force_pbc_overlap ||
2434		     wps_registrar_pbc_overlap(wps->wps->registrar,
2435					       wps->mac_addr_e, wps->uuid_e) ||
2436		     !wps_registrar_p2p_dev_addr_match(wps)) &&
2437		    !wps_registrar_skip_overlap(wps)) {
2438			wpa_printf(MSG_DEBUG, "WPS: PBC overlap - deny PBC "
2439				   "negotiation");
2440			wps->state = SEND_M2D;
2441			wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2442			wps_pbc_overlap_event(wps->wps);
2443			wps_fail_event(wps->wps, WPS_M1,
2444				       WPS_CFG_MULTIPLE_PBC_DETECTED,
2445				       WPS_EI_NO_ERROR);
2446			wps->wps->registrar->force_pbc_overlap = 1;
2447			return WPS_CONTINUE;
2448		}
2449		wps_registrar_add_pbc_session(wps->wps->registrar,
2450					      wps->mac_addr_e, wps->uuid_e);
2451		wps->pbc = 1;
2452	}
2453
2454#ifdef WPS_WORKAROUNDS
2455	/*
2456	 * It looks like Mac OS X 10.6.3 and 10.6.4 do not like Network Key in
2457	 * passphrase format. To avoid interop issues, force PSK format to be
2458	 * used.
2459	 */
2460	if (!wps->use_psk_key &&
2461	    wps->peer_dev.manufacturer &&
2462	    os_strncmp(wps->peer_dev.manufacturer, "Apple ", 6) == 0 &&
2463	    wps->peer_dev.model_name &&
2464	    os_strcmp(wps->peer_dev.model_name, "AirPort") == 0) {
2465		wpa_printf(MSG_DEBUG, "WPS: Workaround - Force Network Key in "
2466			   "PSK format");
2467		wps->use_psk_key = 1;
2468	}
2469#endif /* WPS_WORKAROUNDS */
2470
2471	wps->state = SEND_M2;
2472	return WPS_CONTINUE;
2473}
2474
2475
2476static enum wps_process_res wps_process_m3(struct wps_data *wps,
2477					   const struct wpabuf *msg,
2478					   struct wps_parse_attr *attr)
2479{
2480	wpa_printf(MSG_DEBUG, "WPS: Received M3");
2481
2482	if (wps->state != RECV_M3) {
2483		wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2484			   "receiving M3", wps->state);
2485		wps->state = SEND_WSC_NACK;
2486		return WPS_CONTINUE;
2487	}
2488
2489	if (wps->pbc && wps->wps->registrar->force_pbc_overlap &&
2490	    !wps_registrar_skip_overlap(wps)) {
2491		wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
2492			   "session overlap");
2493		wps->state = SEND_WSC_NACK;
2494		wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2495		return WPS_CONTINUE;
2496	}
2497
2498	if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
2499	    wps_process_authenticator(wps, attr->authenticator, msg) ||
2500	    wps_process_e_hash1(wps, attr->e_hash1) ||
2501	    wps_process_e_hash2(wps, attr->e_hash2)) {
2502		wps->state = SEND_WSC_NACK;
2503		return WPS_CONTINUE;
2504	}
2505
2506	wps->state = SEND_M4;
2507	return WPS_CONTINUE;
2508}
2509
2510
2511static enum wps_process_res wps_process_m5(struct wps_data *wps,
2512					   const struct wpabuf *msg,
2513					   struct wps_parse_attr *attr)
2514{
2515	struct wpabuf *decrypted;
2516	struct wps_parse_attr eattr;
2517
2518	wpa_printf(MSG_DEBUG, "WPS: Received M5");
2519
2520	if (wps->state != RECV_M5) {
2521		wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2522			   "receiving M5", wps->state);
2523		wps->state = SEND_WSC_NACK;
2524		return WPS_CONTINUE;
2525	}
2526
2527	if (wps->pbc && wps->wps->registrar->force_pbc_overlap &&
2528	    !wps_registrar_skip_overlap(wps)) {
2529		wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
2530			   "session overlap");
2531		wps->state = SEND_WSC_NACK;
2532		wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2533		return WPS_CONTINUE;
2534	}
2535
2536	if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
2537	    wps_process_authenticator(wps, attr->authenticator, msg)) {
2538		wps->state = SEND_WSC_NACK;
2539		return WPS_CONTINUE;
2540	}
2541
2542	decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
2543					      attr->encr_settings_len);
2544	if (decrypted == NULL) {
2545		wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
2546			   "Settings attribute");
2547		wps->state = SEND_WSC_NACK;
2548		return WPS_CONTINUE;
2549	}
2550
2551	if (wps_validate_m5_encr(decrypted, attr->version2 != NULL) < 0) {
2552		wpabuf_free(decrypted);
2553		wps->state = SEND_WSC_NACK;
2554		return WPS_CONTINUE;
2555	}
2556
2557	wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
2558		   "attribute");
2559	if (wps_parse_msg(decrypted, &eattr) < 0 ||
2560	    wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
2561	    wps_process_e_snonce1(wps, eattr.e_snonce1)) {
2562		wpabuf_free(decrypted);
2563		wps->state = SEND_WSC_NACK;
2564		return WPS_CONTINUE;
2565	}
2566	wpabuf_free(decrypted);
2567
2568	wps->state = SEND_M6;
2569	return WPS_CONTINUE;
2570}
2571
2572
2573static void wps_sta_cred_cb(struct wps_data *wps)
2574{
2575	/*
2576	 * Update credential to only include a single authentication and
2577	 * encryption type in case the AP configuration includes more than one
2578	 * option.
2579	 */
2580	if (wps->cred.auth_type & WPS_AUTH_WPA2PSK)
2581		wps->cred.auth_type = WPS_AUTH_WPA2PSK;
2582	else if (wps->cred.auth_type & WPS_AUTH_WPAPSK)
2583		wps->cred.auth_type = WPS_AUTH_WPAPSK;
2584	if (wps->cred.encr_type & WPS_ENCR_AES)
2585		wps->cred.encr_type = WPS_ENCR_AES;
2586	else if (wps->cred.encr_type & WPS_ENCR_TKIP)
2587		wps->cred.encr_type = WPS_ENCR_TKIP;
2588	wpa_printf(MSG_DEBUG, "WPS: Update local configuration based on the "
2589		   "AP configuration");
2590	if (wps->wps->cred_cb)
2591		wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
2592}
2593
2594
2595static void wps_cred_update(struct wps_credential *dst,
2596			    struct wps_credential *src)
2597{
2598	os_memcpy(dst->ssid, src->ssid, sizeof(dst->ssid));
2599	dst->ssid_len = src->ssid_len;
2600	dst->auth_type = src->auth_type;
2601	dst->encr_type = src->encr_type;
2602	dst->key_idx = src->key_idx;
2603	os_memcpy(dst->key, src->key, sizeof(dst->key));
2604	dst->key_len = src->key_len;
2605}
2606
2607
2608static int wps_process_ap_settings_r(struct wps_data *wps,
2609				     struct wps_parse_attr *attr)
2610{
2611	struct wpabuf *msg;
2612
2613	if (wps->wps->ap || wps->er)
2614		return 0;
2615
2616	/* AP Settings Attributes in M7 when Enrollee is an AP */
2617	if (wps_process_ap_settings(attr, &wps->cred) < 0)
2618		return -1;
2619
2620	wpa_printf(MSG_INFO, "WPS: Received old AP configuration from AP");
2621
2622	if (wps->new_ap_settings) {
2623		wpa_printf(MSG_INFO, "WPS: Update AP configuration based on "
2624			   "new settings");
2625		wps_cred_update(&wps->cred, wps->new_ap_settings);
2626		return 0;
2627	} else {
2628		/*
2629		 * Use the AP PIN only to receive the current AP settings, not
2630		 * to reconfigure the AP.
2631		 */
2632
2633		/*
2634		 * Clear selected registrar here since we do not get to
2635		 * WSC_Done in this protocol run.
2636		 */
2637		wps_registrar_pin_completed(wps->wps->registrar);
2638
2639		msg = wps_build_ap_cred(wps);
2640		if (msg == NULL)
2641			return -1;
2642		wps->cred.cred_attr = wpabuf_head(msg);
2643		wps->cred.cred_attr_len = wpabuf_len(msg);
2644
2645		if (wps->ap_settings_cb) {
2646			wps->ap_settings_cb(wps->ap_settings_cb_ctx,
2647					    &wps->cred);
2648			wpabuf_free(msg);
2649			return 1;
2650		}
2651		wps_sta_cred_cb(wps);
2652
2653		wps->cred.cred_attr = NULL;
2654		wps->cred.cred_attr_len = 0;
2655		wpabuf_free(msg);
2656
2657		return 1;
2658	}
2659}
2660
2661
2662static enum wps_process_res wps_process_m7(struct wps_data *wps,
2663					   const struct wpabuf *msg,
2664					   struct wps_parse_attr *attr)
2665{
2666	struct wpabuf *decrypted;
2667	struct wps_parse_attr eattr;
2668
2669	wpa_printf(MSG_DEBUG, "WPS: Received M7");
2670
2671	if (wps->state != RECV_M7) {
2672		wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2673			   "receiving M7", wps->state);
2674		wps->state = SEND_WSC_NACK;
2675		return WPS_CONTINUE;
2676	}
2677
2678	if (wps->pbc && wps->wps->registrar->force_pbc_overlap &&
2679	    !wps_registrar_skip_overlap(wps)) {
2680		wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
2681			   "session overlap");
2682		wps->state = SEND_WSC_NACK;
2683		wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2684		return WPS_CONTINUE;
2685	}
2686
2687	if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
2688	    wps_process_authenticator(wps, attr->authenticator, msg)) {
2689		wps->state = SEND_WSC_NACK;
2690		return WPS_CONTINUE;
2691	}
2692
2693	decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
2694					      attr->encr_settings_len);
2695	if (decrypted == NULL) {
2696		wpa_printf(MSG_DEBUG, "WPS: Failed to decrypt Encrypted "
2697			   "Settings attribute");
2698		wps->state = SEND_WSC_NACK;
2699		return WPS_CONTINUE;
2700	}
2701
2702	if (wps_validate_m7_encr(decrypted, wps->wps->ap || wps->er,
2703				 attr->version2 != NULL) < 0) {
2704		wpabuf_free(decrypted);
2705		wps->state = SEND_WSC_NACK;
2706		return WPS_CONTINUE;
2707	}
2708
2709	wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
2710		   "attribute");
2711	if (wps_parse_msg(decrypted, &eattr) < 0 ||
2712	    wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
2713	    wps_process_e_snonce2(wps, eattr.e_snonce2) ||
2714	    wps_process_ap_settings_r(wps, &eattr)) {
2715		wpabuf_free(decrypted);
2716		wps->state = SEND_WSC_NACK;
2717		return WPS_CONTINUE;
2718	}
2719
2720	wpabuf_free(decrypted);
2721
2722	wps->state = SEND_M8;
2723	return WPS_CONTINUE;
2724}
2725
2726
2727static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
2728						const struct wpabuf *msg)
2729{
2730	struct wps_parse_attr attr;
2731	enum wps_process_res ret = WPS_CONTINUE;
2732
2733	wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
2734
2735	if (wps_parse_msg(msg, &attr) < 0)
2736		return WPS_FAILURE;
2737
2738	if (attr.msg_type == NULL) {
2739		wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2740		wps->state = SEND_WSC_NACK;
2741		return WPS_CONTINUE;
2742	}
2743
2744	if (*attr.msg_type != WPS_M1 &&
2745	    (attr.registrar_nonce == NULL ||
2746	     os_memcmp(wps->nonce_r, attr.registrar_nonce,
2747		       WPS_NONCE_LEN != 0))) {
2748		wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2749		return WPS_FAILURE;
2750	}
2751
2752	switch (*attr.msg_type) {
2753	case WPS_M1:
2754		if (wps_validate_m1(msg) < 0)
2755			return WPS_FAILURE;
2756#ifdef CONFIG_WPS_UPNP
2757		if (wps->wps->wps_upnp && attr.mac_addr) {
2758			/* Remove old pending messages when starting new run */
2759			wps_free_pending_msgs(wps->wps->upnp_msgs);
2760			wps->wps->upnp_msgs = NULL;
2761
2762			upnp_wps_device_send_wlan_event(
2763				wps->wps->wps_upnp, attr.mac_addr,
2764				UPNP_WPS_WLANEVENT_TYPE_EAP, msg);
2765		}
2766#endif /* CONFIG_WPS_UPNP */
2767		ret = wps_process_m1(wps, &attr);
2768		break;
2769	case WPS_M3:
2770		if (wps_validate_m3(msg) < 0)
2771			return WPS_FAILURE;
2772		ret = wps_process_m3(wps, msg, &attr);
2773		if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
2774			wps_fail_event(wps->wps, WPS_M3, wps->config_error,
2775				       wps->error_indication);
2776		break;
2777	case WPS_M5:
2778		if (wps_validate_m5(msg) < 0)
2779			return WPS_FAILURE;
2780		ret = wps_process_m5(wps, msg, &attr);
2781		if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
2782			wps_fail_event(wps->wps, WPS_M5, wps->config_error,
2783				       wps->error_indication);
2784		break;
2785	case WPS_M7:
2786		if (wps_validate_m7(msg) < 0)
2787			return WPS_FAILURE;
2788		ret = wps_process_m7(wps, msg, &attr);
2789		if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
2790			wps_fail_event(wps->wps, WPS_M7, wps->config_error,
2791				       wps->error_indication);
2792		break;
2793	default:
2794		wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
2795			   *attr.msg_type);
2796		return WPS_FAILURE;
2797	}
2798
2799	if (ret == WPS_CONTINUE) {
2800		/* Save a copy of the last message for Authenticator derivation
2801		 */
2802		wpabuf_free(wps->last_msg);
2803		wps->last_msg = wpabuf_dup(msg);
2804	}
2805
2806	return ret;
2807}
2808
2809
2810static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
2811						const struct wpabuf *msg)
2812{
2813	struct wps_parse_attr attr;
2814
2815	wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
2816
2817	if (wps_parse_msg(msg, &attr) < 0)
2818		return WPS_FAILURE;
2819
2820	if (attr.msg_type == NULL) {
2821		wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2822		return WPS_FAILURE;
2823	}
2824
2825	if (*attr.msg_type != WPS_WSC_ACK) {
2826		wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
2827			   *attr.msg_type);
2828		return WPS_FAILURE;
2829	}
2830
2831#ifdef CONFIG_WPS_UPNP
2832	if (wps->wps->wps_upnp && wps->ext_reg && wps->state == RECV_M2D_ACK &&
2833	    upnp_wps_subscribers(wps->wps->wps_upnp)) {
2834		if (wps->wps->upnp_msgs)
2835			return WPS_CONTINUE;
2836		wpa_printf(MSG_DEBUG, "WPS: Wait for response from an "
2837			   "external Registrar");
2838		return WPS_PENDING;
2839	}
2840#endif /* CONFIG_WPS_UPNP */
2841
2842	if (attr.registrar_nonce == NULL ||
2843	    os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
2844	{
2845		wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2846		return WPS_FAILURE;
2847	}
2848
2849	if (attr.enrollee_nonce == NULL ||
2850	    os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
2851		wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
2852		return WPS_FAILURE;
2853	}
2854
2855	if (wps->state == RECV_M2D_ACK) {
2856#ifdef CONFIG_WPS_UPNP
2857		if (wps->wps->wps_upnp &&
2858		    upnp_wps_subscribers(wps->wps->wps_upnp)) {
2859			if (wps->wps->upnp_msgs)
2860				return WPS_CONTINUE;
2861			if (wps->ext_reg == 0)
2862				wps->ext_reg = 1;
2863			wpa_printf(MSG_DEBUG, "WPS: Wait for response from an "
2864				   "external Registrar");
2865			return WPS_PENDING;
2866		}
2867#endif /* CONFIG_WPS_UPNP */
2868
2869		wpa_printf(MSG_DEBUG, "WPS: No more registrars available - "
2870			   "terminate negotiation");
2871	}
2872
2873	return WPS_FAILURE;
2874}
2875
2876
2877static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
2878						 const struct wpabuf *msg)
2879{
2880	struct wps_parse_attr attr;
2881	int old_state;
2882	u16 config_error;
2883
2884	wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
2885
2886	old_state = wps->state;
2887	wps->state = SEND_WSC_NACK;
2888
2889	if (wps_parse_msg(msg, &attr) < 0)
2890		return WPS_FAILURE;
2891
2892	if (attr.msg_type == NULL) {
2893		wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2894		return WPS_FAILURE;
2895	}
2896
2897	if (*attr.msg_type != WPS_WSC_NACK) {
2898		wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
2899			   *attr.msg_type);
2900		return WPS_FAILURE;
2901	}
2902
2903#ifdef CONFIG_WPS_UPNP
2904	if (wps->wps->wps_upnp && wps->ext_reg) {
2905		wpa_printf(MSG_DEBUG, "WPS: Negotiation using external "
2906			   "Registrar terminated by the Enrollee");
2907		return WPS_FAILURE;
2908	}
2909#endif /* CONFIG_WPS_UPNP */
2910
2911	if (attr.registrar_nonce == NULL ||
2912	    os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
2913	{
2914		wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2915		return WPS_FAILURE;
2916	}
2917
2918	if (attr.enrollee_nonce == NULL ||
2919	    os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
2920		wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
2921		return WPS_FAILURE;
2922	}
2923
2924	if (attr.config_error == NULL) {
2925		wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
2926			   "in WSC_NACK");
2927		return WPS_FAILURE;
2928	}
2929
2930	config_error = WPA_GET_BE16(attr.config_error);
2931	wpa_printf(MSG_DEBUG, "WPS: Enrollee terminated negotiation with "
2932		   "Configuration Error %d", config_error);
2933
2934	switch (old_state) {
2935	case RECV_M3:
2936		wps_fail_event(wps->wps, WPS_M2, config_error,
2937			       wps->error_indication);
2938		break;
2939	case RECV_M5:
2940		wps_fail_event(wps->wps, WPS_M4, config_error,
2941			       wps->error_indication);
2942		break;
2943	case RECV_M7:
2944		wps_fail_event(wps->wps, WPS_M6, config_error,
2945			       wps->error_indication);
2946		break;
2947	case RECV_DONE:
2948		wps_fail_event(wps->wps, WPS_M8, config_error,
2949			       wps->error_indication);
2950		break;
2951	default:
2952		break;
2953	}
2954
2955	return WPS_FAILURE;
2956}
2957
2958
2959static enum wps_process_res wps_process_wsc_done(struct wps_data *wps,
2960						 const struct wpabuf *msg)
2961{
2962	struct wps_parse_attr attr;
2963
2964	wpa_printf(MSG_DEBUG, "WPS: Received WSC_Done");
2965
2966	if (wps->state != RECV_DONE &&
2967	    (!wps->wps->wps_upnp || !wps->ext_reg)) {
2968		wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2969			   "receiving WSC_Done", wps->state);
2970		return WPS_FAILURE;
2971	}
2972
2973	if (wps_parse_msg(msg, &attr) < 0)
2974		return WPS_FAILURE;
2975
2976	if (attr.msg_type == NULL) {
2977		wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2978		return WPS_FAILURE;
2979	}
2980
2981	if (*attr.msg_type != WPS_WSC_DONE) {
2982		wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
2983			   *attr.msg_type);
2984		return WPS_FAILURE;
2985	}
2986
2987#ifdef CONFIG_WPS_UPNP
2988	if (wps->wps->wps_upnp && wps->ext_reg) {
2989		wpa_printf(MSG_DEBUG, "WPS: Negotiation using external "
2990			   "Registrar completed successfully");
2991		wps_device_store(wps->wps->registrar, &wps->peer_dev,
2992				 wps->uuid_e);
2993		return WPS_DONE;
2994	}
2995#endif /* CONFIG_WPS_UPNP */
2996
2997	if (attr.registrar_nonce == NULL ||
2998	    os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
2999	{
3000		wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
3001		return WPS_FAILURE;
3002	}
3003
3004	if (attr.enrollee_nonce == NULL ||
3005	    os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
3006		wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
3007		return WPS_FAILURE;
3008	}
3009
3010	wpa_printf(MSG_DEBUG, "WPS: Negotiation completed successfully");
3011	wps_device_store(wps->wps->registrar, &wps->peer_dev,
3012			 wps->uuid_e);
3013
3014	if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->new_psk &&
3015	    wps->wps->ap && !wps->wps->registrar->disable_auto_conf) {
3016		struct wps_credential cred;
3017
3018		wpa_printf(MSG_DEBUG, "WPS: Moving to Configured state based "
3019			   "on first Enrollee connection");
3020
3021		os_memset(&cred, 0, sizeof(cred));
3022		os_memcpy(cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
3023		cred.ssid_len = wps->wps->ssid_len;
3024		cred.auth_type = WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK;
3025		cred.encr_type = WPS_ENCR_TKIP | WPS_ENCR_AES;
3026		os_memcpy(cred.key, wps->new_psk, wps->new_psk_len);
3027		cred.key_len = wps->new_psk_len;
3028
3029		wps->wps->wps_state = WPS_STATE_CONFIGURED;
3030		wpa_hexdump_ascii_key(MSG_DEBUG,
3031				      "WPS: Generated random passphrase",
3032				      wps->new_psk, wps->new_psk_len);
3033		if (wps->wps->cred_cb)
3034			wps->wps->cred_cb(wps->wps->cb_ctx, &cred);
3035
3036		os_free(wps->new_psk);
3037		wps->new_psk = NULL;
3038	}
3039
3040	if (!wps->wps->ap && !wps->er)
3041		wps_sta_cred_cb(wps);
3042
3043	if (wps->new_psk) {
3044		if (wps_cb_new_psk(wps->wps->registrar, wps->mac_addr_e,
3045				   wps->new_psk, wps->new_psk_len)) {
3046			wpa_printf(MSG_DEBUG, "WPS: Failed to configure the "
3047				   "new PSK");
3048		}
3049		os_free(wps->new_psk);
3050		wps->new_psk = NULL;
3051	}
3052
3053	wps_cb_reg_success(wps->wps->registrar, wps->mac_addr_e, wps->uuid_e);
3054
3055	if (wps->pbc) {
3056		wps_registrar_remove_pbc_session(wps->wps->registrar,
3057						 wps->uuid_e,
3058						 wps->p2p_dev_addr);
3059		wps_registrar_pbc_completed(wps->wps->registrar);
3060	} else {
3061		wps_registrar_pin_completed(wps->wps->registrar);
3062	}
3063	/* TODO: maintain AuthorizedMACs somewhere separately for each ER and
3064	 * merge them into APs own list.. */
3065
3066	wps_success_event(wps->wps);
3067
3068	return WPS_DONE;
3069}
3070
3071
3072enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
3073					       enum wsc_op_code op_code,
3074					       const struct wpabuf *msg)
3075{
3076	enum wps_process_res ret;
3077
3078	wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
3079		   "op_code=%d)",
3080		   (unsigned long) wpabuf_len(msg), op_code);
3081
3082#ifdef CONFIG_WPS_UPNP
3083	if (wps->wps->wps_upnp && op_code == WSC_MSG && wps->ext_reg == 1) {
3084		struct wps_parse_attr attr;
3085		if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type &&
3086		    *attr.msg_type == WPS_M3)
3087			wps->ext_reg = 2; /* past M2/M2D phase */
3088	}
3089	if (wps->ext_reg > 1)
3090		wps_registrar_free_pending_m2(wps->wps);
3091	if (wps->wps->wps_upnp && wps->ext_reg &&
3092	    wps->wps->upnp_msgs == NULL &&
3093	    (op_code == WSC_MSG || op_code == WSC_Done || op_code == WSC_NACK))
3094	{
3095		struct wps_parse_attr attr;
3096		int type;
3097		if (wps_parse_msg(msg, &attr) < 0 || attr.msg_type == NULL)
3098			type = -1;
3099		else
3100			type = *attr.msg_type;
3101		wpa_printf(MSG_DEBUG, "WPS: Sending received message (type %d)"
3102			   " to external Registrar for processing", type);
3103		upnp_wps_device_send_wlan_event(wps->wps->wps_upnp,
3104						wps->mac_addr_e,
3105						UPNP_WPS_WLANEVENT_TYPE_EAP,
3106						msg);
3107		if (op_code == WSC_MSG)
3108			return WPS_PENDING;
3109	} else if (wps->wps->wps_upnp && wps->ext_reg && op_code == WSC_MSG) {
3110		wpa_printf(MSG_DEBUG, "WPS: Skip internal processing - using "
3111			   "external Registrar");
3112		return WPS_CONTINUE;
3113	}
3114#endif /* CONFIG_WPS_UPNP */
3115
3116	switch (op_code) {
3117	case WSC_MSG:
3118		return wps_process_wsc_msg(wps, msg);
3119	case WSC_ACK:
3120		if (wps_validate_wsc_ack(msg) < 0)
3121			return WPS_FAILURE;
3122		return wps_process_wsc_ack(wps, msg);
3123	case WSC_NACK:
3124		if (wps_validate_wsc_nack(msg) < 0)
3125			return WPS_FAILURE;
3126		return wps_process_wsc_nack(wps, msg);
3127	case WSC_Done:
3128		if (wps_validate_wsc_done(msg) < 0)
3129			return WPS_FAILURE;
3130		ret = wps_process_wsc_done(wps, msg);
3131		if (ret == WPS_FAILURE) {
3132			wps->state = SEND_WSC_NACK;
3133			wps_fail_event(wps->wps, WPS_WSC_DONE,
3134				       wps->config_error,
3135				       wps->error_indication);
3136		}
3137		return ret;
3138	default:
3139		wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
3140		return WPS_FAILURE;
3141	}
3142}
3143
3144
3145int wps_registrar_update_ie(struct wps_registrar *reg)
3146{
3147	return wps_set_ie(reg);
3148}
3149
3150
3151static void wps_registrar_set_selected_timeout(void *eloop_ctx,
3152					       void *timeout_ctx)
3153{
3154	struct wps_registrar *reg = eloop_ctx;
3155
3156	wpa_printf(MSG_DEBUG, "WPS: Selected Registrar timeout - "
3157		   "unselect internal Registrar");
3158	reg->selected_registrar = 0;
3159	reg->pbc = 0;
3160	wps_registrar_selected_registrar_changed(reg);
3161}
3162
3163
3164#ifdef CONFIG_WPS_UPNP
3165static void wps_registrar_sel_reg_add(struct wps_registrar *reg,
3166				      struct subscription *s)
3167{
3168	int i, j;
3169	wpa_printf(MSG_DEBUG, "WPS: External Registrar selected (dev_pw_id=%d "
3170		   "config_methods=0x%x)",
3171		   s->dev_password_id, s->config_methods);
3172	reg->sel_reg_union = 1;
3173	if (reg->sel_reg_dev_password_id_override != DEV_PW_PUSHBUTTON)
3174		reg->sel_reg_dev_password_id_override = s->dev_password_id;
3175	if (reg->sel_reg_config_methods_override == -1)
3176		reg->sel_reg_config_methods_override = 0;
3177	reg->sel_reg_config_methods_override |= s->config_methods;
3178	for (i = 0; i < WPS_MAX_AUTHORIZED_MACS; i++)
3179		if (is_zero_ether_addr(reg->authorized_macs_union[i]))
3180			break;
3181	for (j = 0; i < WPS_MAX_AUTHORIZED_MACS && j < WPS_MAX_AUTHORIZED_MACS;
3182	     j++) {
3183		if (is_zero_ether_addr(s->authorized_macs[j]))
3184			break;
3185		wpa_printf(MSG_DEBUG, "WPS: Add authorized MAC into union: "
3186			   MACSTR, MAC2STR(s->authorized_macs[j]));
3187		os_memcpy(reg->authorized_macs_union[i],
3188			  s->authorized_macs[j], ETH_ALEN);
3189		i++;
3190	}
3191	wpa_hexdump(MSG_DEBUG, "WPS: Authorized MACs union",
3192		    (u8 *) reg->authorized_macs_union,
3193		    sizeof(reg->authorized_macs_union));
3194}
3195#endif /* CONFIG_WPS_UPNP */
3196
3197
3198static void wps_registrar_sel_reg_union(struct wps_registrar *reg)
3199{
3200#ifdef CONFIG_WPS_UPNP
3201	struct subscription *s;
3202
3203	if (reg->wps->wps_upnp == NULL)
3204		return;
3205
3206	dl_list_for_each(s, &reg->wps->wps_upnp->subscriptions,
3207			 struct subscription, list) {
3208		struct subscr_addr *sa;
3209		sa = dl_list_first(&s->addr_list, struct subscr_addr, list);
3210		if (sa) {
3211			wpa_printf(MSG_DEBUG, "WPS: External Registrar %s:%d",
3212				   inet_ntoa(sa->saddr.sin_addr),
3213				   ntohs(sa->saddr.sin_port));
3214		}
3215		if (s->selected_registrar)
3216			wps_registrar_sel_reg_add(reg, s);
3217		else
3218			wpa_printf(MSG_DEBUG, "WPS: External Registrar not "
3219				   "selected");
3220	}
3221#endif /* CONFIG_WPS_UPNP */
3222}
3223
3224
3225/**
3226 * wps_registrar_selected_registrar_changed - SetSelectedRegistrar change
3227 * @reg: Registrar data from wps_registrar_init()
3228 *
3229 * This function is called when selected registrar state changes, e.g., when an
3230 * AP receives a SetSelectedRegistrar UPnP message.
3231 */
3232void wps_registrar_selected_registrar_changed(struct wps_registrar *reg)
3233{
3234	wpa_printf(MSG_DEBUG, "WPS: Selected registrar information changed");
3235
3236	reg->sel_reg_union = reg->selected_registrar;
3237	reg->sel_reg_dev_password_id_override = -1;
3238	reg->sel_reg_config_methods_override = -1;
3239	os_memcpy(reg->authorized_macs_union, reg->authorized_macs,
3240		  WPS_MAX_AUTHORIZED_MACS * ETH_ALEN);
3241	wpa_hexdump(MSG_DEBUG, "WPS: Authorized MACs union (start with own)",
3242		    (u8 *) reg->authorized_macs_union,
3243		    sizeof(reg->authorized_macs_union));
3244	if (reg->selected_registrar) {
3245		u16 methods;
3246
3247		methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
3248#ifdef CONFIG_WPS2
3249		methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |
3250			     WPS_CONFIG_PHY_PUSHBUTTON);
3251#endif /* CONFIG_WPS2 */
3252		if (reg->pbc) {
3253			reg->sel_reg_dev_password_id_override =
3254				DEV_PW_PUSHBUTTON;
3255			wps_set_pushbutton(&methods, reg->wps->config_methods);
3256		}
3257		wpa_printf(MSG_DEBUG, "WPS: Internal Registrar selected "
3258			   "(pbc=%d)", reg->pbc);
3259		reg->sel_reg_config_methods_override = methods;
3260	} else
3261		wpa_printf(MSG_DEBUG, "WPS: Internal Registrar not selected");
3262
3263	wps_registrar_sel_reg_union(reg);
3264
3265	wps_set_ie(reg);
3266	wps_cb_set_sel_reg(reg);
3267}
3268
3269
3270int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr,
3271			   char *buf, size_t buflen)
3272{
3273	struct wps_registrar_device *d;
3274	int len = 0, ret;
3275	char uuid[40];
3276	char devtype[WPS_DEV_TYPE_BUFSIZE];
3277
3278	d = wps_device_get(reg, addr);
3279	if (d == NULL)
3280		return 0;
3281	if (uuid_bin2str(d->uuid, uuid, sizeof(uuid)))
3282		return 0;
3283
3284	ret = os_snprintf(buf + len, buflen - len,
3285			  "wpsUuid=%s\n"
3286			  "wpsPrimaryDeviceType=%s\n"
3287			  "wpsDeviceName=%s\n"
3288			  "wpsManufacturer=%s\n"
3289			  "wpsModelName=%s\n"
3290			  "wpsModelNumber=%s\n"
3291			  "wpsSerialNumber=%s\n",
3292			  uuid,
3293			  wps_dev_type_bin2str(d->dev.pri_dev_type, devtype,
3294					       sizeof(devtype)),
3295			  d->dev.device_name ? d->dev.device_name : "",
3296			  d->dev.manufacturer ? d->dev.manufacturer : "",
3297			  d->dev.model_name ? d->dev.model_name : "",
3298			  d->dev.model_number ? d->dev.model_number : "",
3299			  d->dev.serial_number ? d->dev.serial_number : "");
3300	if (ret < 0 || (size_t) ret >= buflen - len)
3301		return len;
3302	len += ret;
3303
3304	return len;
3305}
3306
3307
3308int wps_registrar_config_ap(struct wps_registrar *reg,
3309			    struct wps_credential *cred)
3310{
3311#ifdef CONFIG_WPS2
3312	printf("encr_type=0x%x\n", cred->encr_type);
3313	if (!(cred->encr_type & (WPS_ENCR_NONE | WPS_ENCR_TKIP |
3314				 WPS_ENCR_AES))) {
3315		if (cred->encr_type & WPS_ENCR_WEP) {
3316			wpa_printf(MSG_INFO, "WPS: Reject new AP settings "
3317				   "due to WEP configuration");
3318			return -1;
3319		}
3320
3321		wpa_printf(MSG_INFO, "WPS: Reject new AP settings due to "
3322			   "invalid encr_type 0x%x", cred->encr_type);
3323		return -1;
3324	}
3325
3326	if ((cred->encr_type & (WPS_ENCR_TKIP | WPS_ENCR_AES)) ==
3327	    WPS_ENCR_TKIP) {
3328		wpa_printf(MSG_DEBUG, "WPS: Upgrade encr_type TKIP -> "
3329			   "TKIP+AES");
3330		cred->encr_type |= WPS_ENCR_AES;
3331	}
3332
3333	if ((cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) ==
3334	    WPS_AUTH_WPAPSK) {
3335		wpa_printf(MSG_DEBUG, "WPS: Upgrade auth_type WPAPSK -> "
3336			   "WPAPSK+WPA2PSK");
3337		cred->auth_type |= WPS_AUTH_WPA2PSK;
3338	}
3339#endif /* CONFIG_WPS2 */
3340
3341	if (reg->wps->cred_cb)
3342		return reg->wps->cred_cb(reg->wps->cb_ctx, cred);
3343
3344	return -1;
3345}
3346