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