2 * Wi-Fi Protected Setup - Registrar
3 * Copyright (c) 2008-2013, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #include "utils/common.h"
12 #include "utils/base64.h"
13 #include "utils/eloop.h"
14 #include "utils/uuid.h"
15 #include "utils/list.h"
16 #include "crypto/crypto.h"
17 #include "crypto/sha256.h"
18 #include "crypto/random.h"
19 #include "common/ieee802_11_defs.h"
21 #include "wps_dev_attr.h"
23 #include "wps_upnp_i.h"
25 #ifndef CONFIG_WPS_STRICT
26 #define WPS_WORKAROUNDS
27 #endif /* CONFIG_WPS_STRICT */
31 struct wps_nfc_pw_token {
33 u8 pubkey_hash[WPS_OOB_PUBKEY_HASH_LEN];
35 u8 dev_pw[WPS_OOB_DEVICE_PASSWORD_LEN * 2 + 1];
40 static void wps_remove_nfc_pw_token(struct wps_nfc_pw_token *token)
42 dl_list_del(&token->list);
47 static void wps_free_nfc_pw_tokens(struct dl_list *tokens, u16 pw_id)
49 struct wps_nfc_pw_token *token, *prev;
50 dl_list_for_each_safe(token, prev, tokens, struct wps_nfc_pw_token,
52 if (pw_id == 0 || pw_id == token->pw_id)
53 wps_remove_nfc_pw_token(token);
58 static struct wps_nfc_pw_token * wps_get_nfc_pw_token(struct dl_list *tokens,
61 struct wps_nfc_pw_token *token;
62 dl_list_for_each(token, tokens, struct wps_nfc_pw_token, list) {
63 if (pw_id == token->pw_id)
69 #else /* CONFIG_WPS_NFC */
71 #define wps_free_nfc_pw_tokens(t, p) do { } while (0)
73 #endif /* CONFIG_WPS_NFC */
78 u8 uuid[WPS_UUID_LEN];
82 #define PIN_LOCKED BIT(0)
83 #define PIN_EXPIRES BIT(1)
85 struct os_reltime expiration;
86 u8 enrollee_addr[ETH_ALEN];
90 static void wps_free_pin(struct wps_uuid_pin *pin)
97 static void wps_remove_pin(struct wps_uuid_pin *pin)
99 dl_list_del(&pin->list);
104 static void wps_free_pins(struct dl_list *pins)
106 struct wps_uuid_pin *pin, *prev;
107 dl_list_for_each_safe(pin, prev, pins, struct wps_uuid_pin, list)
112 struct wps_pbc_session {
113 struct wps_pbc_session *next;
115 u8 uuid_e[WPS_UUID_LEN];
116 struct os_reltime timestamp;
120 static void wps_free_pbc_sessions(struct wps_pbc_session *pbc)
122 struct wps_pbc_session *prev;
132 struct wps_registrar_device {
133 struct wps_registrar_device *next;
134 struct wps_device_data dev;
135 u8 uuid[WPS_UUID_LEN];
139 struct wps_registrar {
140 struct wps_context *wps;
143 int selected_registrar;
145 int (*new_psk_cb)(void *ctx, const u8 *mac_addr, const u8 *p2p_dev_addr,
146 const u8 *psk, size_t psk_len);
147 int (*set_ie_cb)(void *ctx, struct wpabuf *beacon_ie,
148 struct wpabuf *probe_resp_ie);
149 void (*pin_needed_cb)(void *ctx, const u8 *uuid_e,
150 const struct wps_device_data *dev);
151 void (*reg_success_cb)(void *ctx, const u8 *mac_addr,
152 const u8 *uuid_e, const u8 *dev_pw,
154 void (*set_sel_reg_cb)(void *ctx, int sel_reg, u16 dev_passwd_id,
155 u16 sel_reg_config_methods);
156 void (*enrollee_seen_cb)(void *ctx, const u8 *addr, const u8 *uuid_e,
157 const u8 *pri_dev_type, u16 config_methods,
158 u16 dev_password_id, u8 request_type,
159 const char *dev_name);
163 struct dl_list nfc_pw_tokens;
164 struct wps_pbc_session *pbc_sessions;
167 struct wpabuf *extra_cred;
168 int disable_auto_conf;
170 int sel_reg_dev_password_id_override;
171 int sel_reg_config_methods_override;
174 int force_per_enrollee_psk;
176 struct wps_registrar_device *devices;
178 int force_pbc_overlap;
180 u8 authorized_macs[WPS_MAX_AUTHORIZED_MACS][ETH_ALEN];
181 u8 authorized_macs_union[WPS_MAX_AUTHORIZED_MACS][ETH_ALEN];
183 u8 p2p_dev_addr[ETH_ALEN];
185 u8 pbc_ignore_uuid[WPS_UUID_LEN];
186 struct os_time pbc_ignore_start;
190 static int wps_set_ie(struct wps_registrar *reg);
191 static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx);
192 static void wps_registrar_set_selected_timeout(void *eloop_ctx,
194 static void wps_registrar_remove_pin(struct wps_registrar *reg,
195 struct wps_uuid_pin *pin);
198 static void wps_registrar_add_authorized_mac(struct wps_registrar *reg,
202 wpa_printf(MSG_DEBUG, "WPS: Add authorized MAC " MACSTR,
204 for (i = 0; i < WPS_MAX_AUTHORIZED_MACS; i++)
205 if (os_memcmp(reg->authorized_macs[i], addr, ETH_ALEN) == 0) {
206 wpa_printf(MSG_DEBUG, "WPS: Authorized MAC was "
207 "already in the list");
208 return; /* already in list */
210 for (i = WPS_MAX_AUTHORIZED_MACS - 1; i > 0; i--)
211 os_memcpy(reg->authorized_macs[i], reg->authorized_macs[i - 1],
213 os_memcpy(reg->authorized_macs[0], addr, ETH_ALEN);
214 wpa_hexdump(MSG_DEBUG, "WPS: Authorized MACs",
215 (u8 *) reg->authorized_macs, sizeof(reg->authorized_macs));
219 static void wps_registrar_remove_authorized_mac(struct wps_registrar *reg,
223 wpa_printf(MSG_DEBUG, "WPS: Remove authorized MAC " MACSTR,
225 for (i = 0; i < WPS_MAX_AUTHORIZED_MACS; i++) {
226 if (os_memcmp(reg->authorized_macs, addr, ETH_ALEN) == 0)
229 if (i == WPS_MAX_AUTHORIZED_MACS) {
230 wpa_printf(MSG_DEBUG, "WPS: Authorized MAC was not in the "
232 return; /* not in the list */
234 for (; i + 1 < WPS_MAX_AUTHORIZED_MACS; i++)
235 os_memcpy(reg->authorized_macs[i], reg->authorized_macs[i + 1],
237 os_memset(reg->authorized_macs[WPS_MAX_AUTHORIZED_MACS - 1], 0,
239 wpa_hexdump(MSG_DEBUG, "WPS: Authorized MACs",
240 (u8 *) reg->authorized_macs, sizeof(reg->authorized_macs));
244 static void wps_free_devices(struct wps_registrar_device *dev)
246 struct wps_registrar_device *prev;
251 wps_device_data_free(&prev->dev);
257 static struct wps_registrar_device * wps_device_get(struct wps_registrar *reg,
260 struct wps_registrar_device *dev;
262 for (dev = reg->devices; dev; dev = dev->next) {
263 if (os_memcmp(dev->dev.mac_addr, addr, ETH_ALEN) == 0)
270 static void wps_device_clone_data(struct wps_device_data *dst,
271 struct wps_device_data *src)
273 os_memcpy(dst->mac_addr, src->mac_addr, ETH_ALEN);
274 os_memcpy(dst->pri_dev_type, src->pri_dev_type, WPS_DEV_TYPE_LEN);
276 #define WPS_STRDUP(n) \
278 dst->n = src->n ? os_strdup(src->n) : NULL
280 WPS_STRDUP(device_name);
281 WPS_STRDUP(manufacturer);
282 WPS_STRDUP(model_name);
283 WPS_STRDUP(model_number);
284 WPS_STRDUP(serial_number);
289 int wps_device_store(struct wps_registrar *reg,
290 struct wps_device_data *dev, const u8 *uuid)
292 struct wps_registrar_device *d;
294 d = wps_device_get(reg, dev->mac_addr);
296 d = os_zalloc(sizeof(*d));
299 d->next = reg->devices;
303 wps_device_clone_data(&d->dev, dev);
304 os_memcpy(d->uuid, uuid, WPS_UUID_LEN);
310 static void wps_registrar_add_pbc_session(struct wps_registrar *reg,
311 const u8 *addr, const u8 *uuid_e)
313 struct wps_pbc_session *pbc, *prev = NULL;
314 struct os_reltime now;
316 os_get_reltime(&now);
318 pbc = reg->pbc_sessions;
320 if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&
321 os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {
323 prev->next = pbc->next;
325 reg->pbc_sessions = pbc->next;
333 pbc = os_zalloc(sizeof(*pbc));
336 os_memcpy(pbc->addr, addr, ETH_ALEN);
338 os_memcpy(pbc->uuid_e, uuid_e, WPS_UUID_LEN);
341 pbc->next = reg->pbc_sessions;
342 reg->pbc_sessions = pbc;
343 pbc->timestamp = now;
345 /* remove entries that have timed out */
350 if (os_reltime_expired(&now, &pbc->timestamp,
351 WPS_PBC_WALK_TIME)) {
353 wps_free_pbc_sessions(pbc);
362 static void wps_registrar_remove_pbc_session(struct wps_registrar *reg,
364 const u8 *p2p_dev_addr)
366 struct wps_pbc_session *pbc, *prev = NULL, *tmp;
368 pbc = reg->pbc_sessions;
370 if (os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0 ||
371 (p2p_dev_addr && !is_zero_ether_addr(reg->p2p_dev_addr) &&
372 os_memcmp(reg->p2p_dev_addr, p2p_dev_addr, ETH_ALEN) ==
375 prev->next = pbc->next;
377 reg->pbc_sessions = pbc->next;
380 wpa_printf(MSG_DEBUG, "WPS: Removing PBC session for "
381 "addr=" MACSTR, MAC2STR(tmp->addr));
382 wpa_hexdump(MSG_DEBUG, "WPS: Removed UUID-E",
383 tmp->uuid_e, WPS_UUID_LEN);
393 int wps_registrar_pbc_overlap(struct wps_registrar *reg,
394 const u8 *addr, const u8 *uuid_e)
397 struct wps_pbc_session *pbc;
398 struct wps_pbc_session *first = NULL;
399 struct os_reltime now;
401 os_get_reltime(&now);
403 wpa_printf(MSG_DEBUG, "WPS: Checking active PBC sessions for overlap");
406 wpa_printf(MSG_DEBUG, "WPS: Add one for the requested UUID");
407 wpa_hexdump(MSG_DEBUG, "WPS: Requested UUID",
408 uuid_e, WPS_UUID_LEN);
412 for (pbc = reg->pbc_sessions; pbc; pbc = pbc->next) {
413 wpa_printf(MSG_DEBUG, "WPS: Consider PBC session with " MACSTR,
415 wpa_hexdump(MSG_DEBUG, "WPS: UUID-E",
416 pbc->uuid_e, WPS_UUID_LEN);
417 if (os_reltime_expired(&now, &pbc->timestamp,
418 WPS_PBC_WALK_TIME)) {
419 wpa_printf(MSG_DEBUG, "WPS: PBC walk time has expired");
423 os_memcmp(pbc->uuid_e, first->uuid_e, WPS_UUID_LEN) == 0) {
424 wpa_printf(MSG_DEBUG, "WPS: Same Enrollee");
425 continue; /* same Enrollee */
427 if (uuid_e == NULL ||
428 os_memcmp(uuid_e, pbc->uuid_e, WPS_UUID_LEN)) {
429 wpa_printf(MSG_DEBUG, "WPS: New Enrollee");
436 wpa_printf(MSG_DEBUG, "WPS: %u active PBC session(s) found", count);
438 return count > 1 ? 1 : 0;
442 static int wps_build_wps_state(struct wps_context *wps, struct wpabuf *msg)
444 wpa_printf(MSG_DEBUG, "WPS: * Wi-Fi Protected Setup State (%d)",
446 wpabuf_put_be16(msg, ATTR_WPS_STATE);
447 wpabuf_put_be16(msg, 1);
448 wpabuf_put_u8(msg, wps->wps_state);
453 #ifdef CONFIG_WPS_UPNP
454 static void wps_registrar_free_pending_m2(struct wps_context *wps)
456 struct upnp_pending_message *p, *p2, *prev = NULL;
459 if (p->type == WPS_M2 || p->type == WPS_M2D) {
461 wps->upnp_msgs = p->next;
463 prev->next = p->next;
464 wpa_printf(MSG_DEBUG, "WPS UPnP: Drop pending M2/M2D");
467 wpabuf_free(p2->msg);
475 #endif /* CONFIG_WPS_UPNP */
478 static int wps_build_ap_setup_locked(struct wps_context *wps,
481 if (wps->ap_setup_locked && wps->ap_setup_locked != 2) {
482 wpa_printf(MSG_DEBUG, "WPS: * AP Setup Locked");
483 wpabuf_put_be16(msg, ATTR_AP_SETUP_LOCKED);
484 wpabuf_put_be16(msg, 1);
485 wpabuf_put_u8(msg, 1);
491 static int wps_build_selected_registrar(struct wps_registrar *reg,
494 if (!reg->sel_reg_union)
496 wpa_printf(MSG_DEBUG, "WPS: * Selected Registrar");
497 wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR);
498 wpabuf_put_be16(msg, 1);
499 wpabuf_put_u8(msg, 1);
504 static int wps_build_sel_reg_dev_password_id(struct wps_registrar *reg,
507 u16 id = reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT;
508 if (!reg->sel_reg_union)
510 if (reg->sel_reg_dev_password_id_override >= 0)
511 id = reg->sel_reg_dev_password_id_override;
512 wpa_printf(MSG_DEBUG, "WPS: * Device Password ID (%d)", id);
513 wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
514 wpabuf_put_be16(msg, 2);
515 wpabuf_put_be16(msg, id);
520 static int wps_build_sel_pbc_reg_uuid_e(struct wps_registrar *reg,
523 u16 id = reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT;
524 if (!reg->sel_reg_union)
526 if (reg->sel_reg_dev_password_id_override >= 0)
527 id = reg->sel_reg_dev_password_id_override;
528 if (id != DEV_PW_PUSHBUTTON || !reg->dualband)
530 return wps_build_uuid_e(msg, reg->wps->uuid);
534 static void wps_set_pushbutton(u16 *methods, u16 conf_methods)
536 *methods |= WPS_CONFIG_PUSHBUTTON;
538 if ((conf_methods & WPS_CONFIG_VIRT_PUSHBUTTON) ==
539 WPS_CONFIG_VIRT_PUSHBUTTON)
540 *methods |= WPS_CONFIG_VIRT_PUSHBUTTON;
541 if ((conf_methods & WPS_CONFIG_PHY_PUSHBUTTON) ==
542 WPS_CONFIG_PHY_PUSHBUTTON)
543 *methods |= WPS_CONFIG_PHY_PUSHBUTTON;
544 if ((*methods & WPS_CONFIG_VIRT_PUSHBUTTON) !=
545 WPS_CONFIG_VIRT_PUSHBUTTON &&
546 (*methods & WPS_CONFIG_PHY_PUSHBUTTON) !=
547 WPS_CONFIG_PHY_PUSHBUTTON) {
549 * Required to include virtual/physical flag, but we were not
550 * configured with push button type, so have to default to one
553 *methods |= WPS_CONFIG_PHY_PUSHBUTTON;
555 #endif /* CONFIG_WPS2 */
559 static int wps_build_sel_reg_config_methods(struct wps_registrar *reg,
563 if (!reg->sel_reg_union)
565 methods = reg->wps->config_methods;
566 methods &= ~WPS_CONFIG_PUSHBUTTON;
568 methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |
569 WPS_CONFIG_PHY_PUSHBUTTON);
570 #endif /* CONFIG_WPS2 */
572 wps_set_pushbutton(&methods, reg->wps->config_methods);
573 if (reg->sel_reg_config_methods_override >= 0)
574 methods = reg->sel_reg_config_methods_override;
575 wpa_printf(MSG_DEBUG, "WPS: * Selected Registrar Config Methods (%x)",
577 wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS);
578 wpabuf_put_be16(msg, 2);
579 wpabuf_put_be16(msg, methods);
584 static int wps_build_probe_config_methods(struct wps_registrar *reg,
589 * These are the methods that the AP supports as an Enrollee for adding
590 * external Registrars.
592 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
594 methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |
595 WPS_CONFIG_PHY_PUSHBUTTON);
596 #endif /* CONFIG_WPS2 */
597 wpa_printf(MSG_DEBUG, "WPS: * Config Methods (%x)", methods);
598 wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
599 wpabuf_put_be16(msg, 2);
600 wpabuf_put_be16(msg, methods);
605 static int wps_build_config_methods_r(struct wps_registrar *reg,
608 return wps_build_config_methods(msg, reg->wps->config_methods);
612 const u8 * wps_authorized_macs(struct wps_registrar *reg, size_t *count)
617 while (*count < WPS_MAX_AUTHORIZED_MACS) {
618 if (is_zero_ether_addr(reg->authorized_macs_union[*count]))
622 #endif /* CONFIG_WPS2 */
624 return (const u8 *) reg->authorized_macs_union;
629 * wps_registrar_init - Initialize WPS Registrar data
630 * @wps: Pointer to longterm WPS context
631 * @cfg: Registrar configuration
632 * Returns: Pointer to allocated Registrar data or %NULL on failure
634 * This function is used to initialize WPS Registrar functionality. It can be
635 * used for a single Registrar run (e.g., when run in a supplicant) or multiple
636 * runs (e.g., when run as an internal Registrar in an AP). Caller is
637 * responsible for freeing the returned data with wps_registrar_deinit() when
638 * Registrar functionality is not needed anymore.
640 struct wps_registrar *
641 wps_registrar_init(struct wps_context *wps,
642 const struct wps_registrar_config *cfg)
644 struct wps_registrar *reg = os_zalloc(sizeof(*reg));
648 dl_list_init(®->pins);
649 dl_list_init(®->nfc_pw_tokens);
651 reg->new_psk_cb = cfg->new_psk_cb;
652 reg->set_ie_cb = cfg->set_ie_cb;
653 reg->pin_needed_cb = cfg->pin_needed_cb;
654 reg->reg_success_cb = cfg->reg_success_cb;
655 reg->set_sel_reg_cb = cfg->set_sel_reg_cb;
656 reg->enrollee_seen_cb = cfg->enrollee_seen_cb;
657 reg->cb_ctx = cfg->cb_ctx;
658 reg->skip_cred_build = cfg->skip_cred_build;
659 if (cfg->extra_cred) {
660 reg->extra_cred = wpabuf_alloc_copy(cfg->extra_cred,
661 cfg->extra_cred_len);
662 if (reg->extra_cred == NULL) {
667 reg->disable_auto_conf = cfg->disable_auto_conf;
668 reg->sel_reg_dev_password_id_override = -1;
669 reg->sel_reg_config_methods_override = -1;
670 reg->static_wep_only = cfg->static_wep_only;
671 reg->dualband = cfg->dualband;
672 reg->force_per_enrollee_psk = cfg->force_per_enrollee_psk;
674 if (wps_set_ie(reg)) {
675 wps_registrar_deinit(reg);
684 * wps_registrar_deinit - Deinitialize WPS Registrar data
685 * @reg: Registrar data from wps_registrar_init()
687 void wps_registrar_deinit(struct wps_registrar *reg)
691 eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
692 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
693 wps_free_pins(®->pins);
694 wps_free_nfc_pw_tokens(®->nfc_pw_tokens, 0);
695 wps_free_pbc_sessions(reg->pbc_sessions);
696 wpabuf_free(reg->extra_cred);
697 wps_free_devices(reg->devices);
702 static void wps_registrar_invalidate_unused(struct wps_registrar *reg)
704 struct wps_uuid_pin *pin;
706 dl_list_for_each(pin, ®->pins, struct wps_uuid_pin, list) {
707 if (pin->wildcard_uuid == 1 && !(pin->flags & PIN_LOCKED)) {
708 wpa_printf(MSG_DEBUG, "WPS: Invalidate previously "
709 "configured wildcard PIN");
710 wps_registrar_remove_pin(reg, pin);
718 * wps_registrar_add_pin - Configure a new PIN for Registrar
719 * @reg: Registrar data from wps_registrar_init()
720 * @addr: Enrollee MAC address or %NULL if not known
721 * @uuid: UUID-E or %NULL for wildcard (any UUID)
722 * @pin: PIN (Device Password)
723 * @pin_len: Length of pin in octets
724 * @timeout: Time (in seconds) when the PIN will be invalidated; 0 = no timeout
725 * Returns: 0 on success, -1 on failure
727 int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *addr,
728 const u8 *uuid, const u8 *pin, size_t pin_len,
731 struct wps_uuid_pin *p;
733 p = os_zalloc(sizeof(*p));
737 os_memcpy(p->enrollee_addr, addr, ETH_ALEN);
739 p->wildcard_uuid = 1;
741 os_memcpy(p->uuid, uuid, WPS_UUID_LEN);
742 p->pin = os_malloc(pin_len);
743 if (p->pin == NULL) {
747 os_memcpy(p->pin, pin, pin_len);
748 p->pin_len = pin_len;
751 p->flags |= PIN_EXPIRES;
752 os_get_reltime(&p->expiration);
753 p->expiration.sec += timeout;
756 if (p->wildcard_uuid)
757 wps_registrar_invalidate_unused(reg);
759 dl_list_add(®->pins, &p->list);
761 wpa_printf(MSG_DEBUG, "WPS: A new PIN configured (timeout=%d)",
763 wpa_hexdump(MSG_DEBUG, "WPS: UUID", uuid, WPS_UUID_LEN);
764 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: PIN", pin, pin_len);
765 reg->selected_registrar = 1;
768 wps_registrar_add_authorized_mac(reg, addr);
770 wps_registrar_add_authorized_mac(
771 reg, (u8 *) "\xff\xff\xff\xff\xff\xff");
772 wps_registrar_selected_registrar_changed(reg, 0);
773 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
774 eloop_register_timeout(WPS_PBC_WALK_TIME, 0,
775 wps_registrar_set_selected_timeout,
782 static void wps_registrar_remove_pin(struct wps_registrar *reg,
783 struct wps_uuid_pin *pin)
786 u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
788 if (is_zero_ether_addr(pin->enrollee_addr))
791 addr = pin->enrollee_addr;
792 wps_registrar_remove_authorized_mac(reg, addr);
794 wps_registrar_selected_registrar_changed(reg, 0);
798 static void wps_registrar_expire_pins(struct wps_registrar *reg)
800 struct wps_uuid_pin *pin, *prev;
801 struct os_reltime now;
803 os_get_reltime(&now);
804 dl_list_for_each_safe(pin, prev, ®->pins, struct wps_uuid_pin, list)
806 if ((pin->flags & PIN_EXPIRES) &&
807 os_reltime_before(&pin->expiration, &now)) {
808 wpa_hexdump(MSG_DEBUG, "WPS: Expired PIN for UUID",
809 pin->uuid, WPS_UUID_LEN);
810 wps_registrar_remove_pin(reg, pin);
817 * wps_registrar_invalidate_wildcard_pin - Invalidate a wildcard PIN
818 * @reg: Registrar data from wps_registrar_init()
819 * @dev_pw: PIN to search for or %NULL to match any
820 * @dev_pw_len: Length of dev_pw in octets
821 * Returns: 0 on success, -1 if not wildcard PIN is enabled
823 static int wps_registrar_invalidate_wildcard_pin(struct wps_registrar *reg,
827 struct wps_uuid_pin *pin, *prev;
829 dl_list_for_each_safe(pin, prev, ®->pins, struct wps_uuid_pin, list)
831 if (dev_pw && pin->pin &&
832 (dev_pw_len != pin->pin_len ||
833 os_memcmp(dev_pw, pin->pin, dev_pw_len) != 0))
834 continue; /* different PIN */
835 if (pin->wildcard_uuid) {
836 wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID",
837 pin->uuid, WPS_UUID_LEN);
838 wps_registrar_remove_pin(reg, pin);
848 * wps_registrar_invalidate_pin - Invalidate a PIN for a specific UUID-E
849 * @reg: Registrar data from wps_registrar_init()
851 * Returns: 0 on success, -1 on failure (e.g., PIN not found)
853 int wps_registrar_invalidate_pin(struct wps_registrar *reg, const u8 *uuid)
855 struct wps_uuid_pin *pin, *prev;
857 dl_list_for_each_safe(pin, prev, ®->pins, struct wps_uuid_pin, list)
859 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
860 wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID",
861 pin->uuid, WPS_UUID_LEN);
862 wps_registrar_remove_pin(reg, pin);
871 static const u8 * wps_registrar_get_pin(struct wps_registrar *reg,
872 const u8 *uuid, size_t *pin_len)
874 struct wps_uuid_pin *pin, *found = NULL;
876 wps_registrar_expire_pins(reg);
878 dl_list_for_each(pin, ®->pins, struct wps_uuid_pin, list) {
879 if (!pin->wildcard_uuid &&
880 os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
887 /* Check for wildcard UUIDs since none of the UUID-specific
889 dl_list_for_each(pin, ®->pins, struct wps_uuid_pin, list) {
890 if (pin->wildcard_uuid == 1 ||
891 pin->wildcard_uuid == 2) {
892 wpa_printf(MSG_DEBUG, "WPS: Found a wildcard "
893 "PIN. Assigned it for this UUID-E");
894 pin->wildcard_uuid++;
895 os_memcpy(pin->uuid, uuid, WPS_UUID_LEN);
906 * Lock the PIN to avoid attacks based on concurrent re-use of the PIN
907 * that could otherwise avoid PIN invalidations.
909 if (found->flags & PIN_LOCKED) {
910 wpa_printf(MSG_DEBUG, "WPS: Selected PIN locked - do not "
911 "allow concurrent re-use");
914 *pin_len = found->pin_len;
915 found->flags |= PIN_LOCKED;
921 * wps_registrar_unlock_pin - Unlock a PIN for a specific UUID-E
922 * @reg: Registrar data from wps_registrar_init()
924 * Returns: 0 on success, -1 on failure
926 * PINs are locked to enforce only one concurrent use. This function unlocks a
927 * PIN to allow it to be used again. If the specified PIN was configured using
928 * a wildcard UUID, it will be removed instead of allowing multiple uses.
930 int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid)
932 struct wps_uuid_pin *pin;
934 dl_list_for_each(pin, ®->pins, struct wps_uuid_pin, list) {
935 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
936 if (pin->wildcard_uuid == 3) {
937 wpa_printf(MSG_DEBUG, "WPS: Invalidating used "
939 return wps_registrar_invalidate_pin(reg, uuid);
941 pin->flags &= ~PIN_LOCKED;
950 static void wps_registrar_stop_pbc(struct wps_registrar *reg)
952 reg->selected_registrar = 0;
954 os_memset(reg->p2p_dev_addr, 0, ETH_ALEN);
955 wps_registrar_remove_authorized_mac(reg,
956 (u8 *) "\xff\xff\xff\xff\xff\xff");
957 wps_registrar_selected_registrar_changed(reg, 0);
961 static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx)
963 struct wps_registrar *reg = eloop_ctx;
965 wpa_printf(MSG_DEBUG, "WPS: PBC timed out - disable PBC mode");
966 wps_pbc_timeout_event(reg->wps);
967 wps_registrar_stop_pbc(reg);
972 * wps_registrar_button_pushed - Notify Registrar that AP button was pushed
973 * @reg: Registrar data from wps_registrar_init()
974 * @p2p_dev_addr: Limit allowed PBC devices to the specified P2P device, %NULL
975 * indicates no such filtering
976 * Returns: 0 on success, -1 on failure, -2 on session overlap
978 * This function is called on an AP when a push button is pushed to activate
979 * PBC mode. The PBC mode will be stopped after walk time (2 minutes) timeout
980 * or when a PBC registration is completed. If more than one Enrollee in active
981 * PBC mode has been detected during the monitor time (previous 2 minutes), the
982 * PBC mode is not activated and -2 is returned to indicate session overlap.
983 * This is skipped if a specific Enrollee is selected.
985 int wps_registrar_button_pushed(struct wps_registrar *reg,
986 const u8 *p2p_dev_addr)
988 if (p2p_dev_addr == NULL &&
989 wps_registrar_pbc_overlap(reg, NULL, NULL)) {
990 wpa_printf(MSG_DEBUG, "WPS: PBC overlap - do not start PBC "
992 wps_pbc_overlap_event(reg->wps);
995 wpa_printf(MSG_DEBUG, "WPS: Button pushed - PBC mode started");
996 reg->force_pbc_overlap = 0;
997 reg->selected_registrar = 1;
1000 os_memcpy(reg->p2p_dev_addr, p2p_dev_addr, ETH_ALEN);
1002 os_memset(reg->p2p_dev_addr, 0, ETH_ALEN);
1003 wps_registrar_add_authorized_mac(reg,
1004 (u8 *) "\xff\xff\xff\xff\xff\xff");
1005 wps_registrar_selected_registrar_changed(reg, 0);
1007 wps_pbc_active_event(reg->wps);
1008 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
1009 eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
1010 eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wps_registrar_pbc_timeout,
1016 static void wps_registrar_pbc_completed(struct wps_registrar *reg)
1018 wpa_printf(MSG_DEBUG, "WPS: PBC completed - stopping PBC mode");
1019 eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
1020 wps_registrar_stop_pbc(reg);
1021 wps_pbc_disable_event(reg->wps);
1025 static void wps_registrar_pin_completed(struct wps_registrar *reg)
1027 wpa_printf(MSG_DEBUG, "WPS: PIN completed using internal Registrar");
1028 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
1029 reg->selected_registrar = 0;
1030 wps_registrar_selected_registrar_changed(reg, 0);
1034 void wps_registrar_complete(struct wps_registrar *registrar, const u8 *uuid_e,
1035 const u8 *dev_pw, size_t dev_pw_len)
1037 if (registrar->pbc) {
1038 wps_registrar_remove_pbc_session(registrar,
1040 wps_registrar_pbc_completed(registrar);
1041 os_get_time(®istrar->pbc_ignore_start);
1042 os_memcpy(registrar->pbc_ignore_uuid, uuid_e, WPS_UUID_LEN);
1044 wps_registrar_pin_completed(registrar);
1048 wps_registrar_invalidate_wildcard_pin(registrar, dev_pw,
1050 wpa_hexdump_key(MSG_DEBUG, "WPS: Invalidated wildcard PIN",
1051 dev_pw, dev_pw_len);
1056 int wps_registrar_wps_cancel(struct wps_registrar *reg)
1059 wpa_printf(MSG_DEBUG, "WPS: PBC is set - cancelling it");
1060 wps_registrar_pbc_timeout(reg, NULL);
1061 eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
1063 } else if (reg->selected_registrar) {
1065 wpa_printf(MSG_DEBUG, "WPS: PIN is set - cancelling it");
1066 wps_registrar_pin_completed(reg);
1067 wps_registrar_invalidate_wildcard_pin(reg, NULL, 0);
1075 * wps_registrar_probe_req_rx - Notify Registrar of Probe Request
1076 * @reg: Registrar data from wps_registrar_init()
1077 * @addr: MAC address of the Probe Request sender
1078 * @wps_data: WPS IE contents
1080 * This function is called on an AP when a Probe Request with WPS IE is
1081 * received. This is used to track PBC mode use and to detect possible overlap
1082 * situation with other WPS APs.
1084 void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
1085 const struct wpabuf *wps_data,
1088 struct wps_parse_attr attr;
1091 wpa_hexdump_buf(MSG_MSGDUMP,
1092 "WPS: Probe Request with WPS data received",
1095 if (wps_parse_msg(wps_data, &attr) < 0)
1098 if (attr.config_methods == NULL) {
1099 wpa_printf(MSG_DEBUG, "WPS: No Config Methods attribute in "
1104 if (attr.dev_password_id == NULL) {
1105 wpa_printf(MSG_DEBUG, "WPS: No Device Password Id attribute "
1106 "in Probe Request");
1110 if (reg->enrollee_seen_cb && attr.uuid_e &&
1111 attr.primary_dev_type && attr.request_type && !p2p_wildcard) {
1112 char *dev_name = NULL;
1113 if (attr.dev_name) {
1114 dev_name = os_zalloc(attr.dev_name_len + 1);
1116 os_memcpy(dev_name, attr.dev_name,
1120 reg->enrollee_seen_cb(reg->cb_ctx, addr, attr.uuid_e,
1121 attr.primary_dev_type,
1122 WPA_GET_BE16(attr.config_methods),
1123 WPA_GET_BE16(attr.dev_password_id),
1124 *attr.request_type, dev_name);
1128 if (WPA_GET_BE16(attr.dev_password_id) != DEV_PW_PUSHBUTTON)
1129 return; /* Not PBC */
1131 wpa_printf(MSG_DEBUG, "WPS: Probe Request for PBC received from "
1132 MACSTR, MAC2STR(addr));
1133 if (attr.uuid_e == NULL) {
1134 wpa_printf(MSG_DEBUG, "WPS: Invalid Probe Request WPS IE: No "
1138 wpa_hexdump(MSG_DEBUG, "WPS: UUID-E from Probe Request", attr.uuid_e,
1141 #ifdef WPS_WORKAROUNDS
1142 if (reg->pbc_ignore_start.sec &&
1143 os_memcmp(attr.uuid_e, reg->pbc_ignore_uuid, WPS_UUID_LEN) == 0) {
1144 struct os_time now, dur;
1146 os_time_sub(&now, ®->pbc_ignore_start, &dur);
1147 if (dur.sec >= 0 && dur.sec < 5) {
1148 wpa_printf(MSG_DEBUG, "WPS: Ignore PBC activation "
1149 "based on Probe Request from the Enrollee "
1150 "that just completed PBC provisioning");
1153 reg->pbc_ignore_start.sec = 0;
1155 #endif /* WPS_WORKAROUNDS */
1158 wps_registrar_add_pbc_session(reg, addr, attr.uuid_e);
1159 if (wps_registrar_pbc_overlap(reg, addr, attr.uuid_e)) {
1160 wpa_printf(MSG_DEBUG, "WPS: PBC session overlap detected");
1161 reg->force_pbc_overlap = 1;
1162 wps_pbc_overlap_event(reg->wps);
1167 static int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr,
1168 const u8 *p2p_dev_addr, const u8 *psk, size_t psk_len)
1170 if (reg->new_psk_cb == NULL)
1173 return reg->new_psk_cb(reg->cb_ctx, mac_addr, p2p_dev_addr, psk,
1178 static void wps_cb_pin_needed(struct wps_registrar *reg, const u8 *uuid_e,
1179 const struct wps_device_data *dev)
1181 if (reg->pin_needed_cb == NULL)
1184 reg->pin_needed_cb(reg->cb_ctx, uuid_e, dev);
1188 static void wps_cb_reg_success(struct wps_registrar *reg, const u8 *mac_addr,
1189 const u8 *uuid_e, const u8 *dev_pw,
1192 if (reg->reg_success_cb == NULL)
1195 reg->reg_success_cb(reg->cb_ctx, mac_addr, uuid_e, dev_pw, dev_pw_len);
1199 static int wps_cb_set_ie(struct wps_registrar *reg, struct wpabuf *beacon_ie,
1200 struct wpabuf *probe_resp_ie)
1202 return reg->set_ie_cb(reg->cb_ctx, beacon_ie, probe_resp_ie);
1206 static void wps_cb_set_sel_reg(struct wps_registrar *reg)
1209 if (reg->set_sel_reg_cb == NULL)
1212 if (reg->selected_registrar) {
1213 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
1215 methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |
1216 WPS_CONFIG_PHY_PUSHBUTTON);
1217 #endif /* CONFIG_WPS2 */
1219 wps_set_pushbutton(&methods, reg->wps->config_methods);
1222 wpa_printf(MSG_DEBUG, "WPS: wps_cb_set_sel_reg: sel_reg=%d "
1223 "config_methods=0x%x pbc=%d methods=0x%x",
1224 reg->selected_registrar, reg->wps->config_methods,
1227 reg->set_sel_reg_cb(reg->cb_ctx, reg->selected_registrar,
1228 reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT,
1233 static int wps_set_ie(struct wps_registrar *reg)
1235 struct wpabuf *beacon;
1236 struct wpabuf *probe;
1237 const u8 *auth_macs;
1239 size_t vendor_len = 0;
1242 if (reg->set_ie_cb == NULL)
1245 for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
1246 if (reg->wps->dev.vendor_ext[i]) {
1247 vendor_len += 2 + 2;
1248 vendor_len += wpabuf_len(reg->wps->dev.vendor_ext[i]);
1252 beacon = wpabuf_alloc(400 + vendor_len);
1255 probe = wpabuf_alloc(500 + vendor_len);
1256 if (probe == NULL) {
1257 wpabuf_free(beacon);
1261 auth_macs = wps_authorized_macs(reg, &count);
1263 wpa_printf(MSG_DEBUG, "WPS: Build Beacon IEs");
1265 if (wps_build_version(beacon) ||
1266 wps_build_wps_state(reg->wps, beacon) ||
1267 wps_build_ap_setup_locked(reg->wps, beacon) ||
1268 wps_build_selected_registrar(reg, beacon) ||
1269 wps_build_sel_reg_dev_password_id(reg, beacon) ||
1270 wps_build_sel_reg_config_methods(reg, beacon) ||
1271 wps_build_sel_pbc_reg_uuid_e(reg, beacon) ||
1272 (reg->dualband && wps_build_rf_bands(®->wps->dev, beacon, 0)) ||
1273 wps_build_wfa_ext(beacon, 0, auth_macs, count) ||
1274 wps_build_vendor_ext(®->wps->dev, beacon)) {
1275 wpabuf_free(beacon);
1281 if (wps_build_dev_name(®->wps->dev, beacon) ||
1282 wps_build_primary_dev_type(®->wps->dev, beacon)) {
1283 wpabuf_free(beacon);
1287 #endif /* CONFIG_P2P */
1289 wpa_printf(MSG_DEBUG, "WPS: Build Probe Response IEs");
1291 if (wps_build_version(probe) ||
1292 wps_build_wps_state(reg->wps, probe) ||
1293 wps_build_ap_setup_locked(reg->wps, probe) ||
1294 wps_build_selected_registrar(reg, probe) ||
1295 wps_build_sel_reg_dev_password_id(reg, probe) ||
1296 wps_build_sel_reg_config_methods(reg, probe) ||
1297 wps_build_resp_type(probe, reg->wps->ap ? WPS_RESP_AP :
1298 WPS_RESP_REGISTRAR) ||
1299 wps_build_uuid_e(probe, reg->wps->uuid) ||
1300 wps_build_device_attrs(®->wps->dev, probe) ||
1301 wps_build_probe_config_methods(reg, probe) ||
1302 (reg->dualband && wps_build_rf_bands(®->wps->dev, probe, 0)) ||
1303 wps_build_wfa_ext(probe, 0, auth_macs, count) ||
1304 wps_build_vendor_ext(®->wps->dev, probe)) {
1305 wpabuf_free(beacon);
1310 beacon = wps_ie_encapsulate(beacon);
1311 probe = wps_ie_encapsulate(probe);
1313 if (!beacon || !probe) {
1314 wpabuf_free(beacon);
1319 if (reg->static_wep_only) {
1321 * Windows XP and Vista clients can get confused about
1322 * EAP-Identity/Request when they probe the network with
1323 * EAPOL-Start. In such a case, they may assume the network is
1324 * using IEEE 802.1X and prompt user for a certificate while
1325 * the correct (non-WPS) behavior would be to ask for the
1326 * static WEP key. As a workaround, use Microsoft Provisioning
1327 * IE to advertise that legacy 802.1X is not supported.
1329 const u8 ms_wps[7] = {
1330 WLAN_EID_VENDOR_SPECIFIC, 5,
1331 /* Microsoft Provisioning IE (00:50:f2:5) */
1332 0x00, 0x50, 0xf2, 5,
1333 0x00 /* no legacy 802.1X or MS WPS */
1335 wpa_printf(MSG_DEBUG, "WPS: Add Microsoft Provisioning IE "
1336 "into Beacon/Probe Response frames");
1337 wpabuf_put_data(beacon, ms_wps, sizeof(ms_wps));
1338 wpabuf_put_data(probe, ms_wps, sizeof(ms_wps));
1341 return wps_cb_set_ie(reg, beacon, probe);
1345 static int wps_get_dev_password(struct wps_data *wps)
1350 os_free(wps->dev_password);
1351 wps->dev_password = NULL;
1354 wpa_printf(MSG_DEBUG, "WPS: Use default PIN for PBC");
1355 pin = (const u8 *) "00000000";
1357 #ifdef CONFIG_WPS_NFC
1358 } else if (wps->nfc_pw_token) {
1359 wpa_printf(MSG_DEBUG, "WPS: Use OOB Device Password from NFC "
1361 pin = wps->nfc_pw_token->dev_pw;
1362 pin_len = wps->nfc_pw_token->dev_pw_len;
1363 #endif /* CONFIG_WPS_NFC */
1365 pin = wps_registrar_get_pin(wps->wps->registrar, wps->uuid_e,
1367 if (pin && wps->dev_pw_id >= 0x10) {
1368 wpa_printf(MSG_DEBUG, "WPS: No match for OOB Device "
1369 "Password ID, but PIN found");
1371 * See whether Enrollee is willing to use PIN instead.
1373 wps->dev_pw_id = DEV_PW_DEFAULT;
1377 wpa_printf(MSG_DEBUG, "WPS: No Device Password available for "
1378 "the Enrollee (context %p registrar %p)",
1379 wps->wps, wps->wps->registrar);
1380 wps_cb_pin_needed(wps->wps->registrar, wps->uuid_e,
1385 wps->dev_password = os_malloc(pin_len);
1386 if (wps->dev_password == NULL)
1388 os_memcpy(wps->dev_password, pin, pin_len);
1389 wps->dev_password_len = pin_len;
1395 static int wps_build_uuid_r(struct wps_data *wps, struct wpabuf *msg)
1397 wpa_printf(MSG_DEBUG, "WPS: * UUID-R");
1398 wpabuf_put_be16(msg, ATTR_UUID_R);
1399 wpabuf_put_be16(msg, WPS_UUID_LEN);
1400 wpabuf_put_data(msg, wps->uuid_r, WPS_UUID_LEN);
1405 static int wps_build_r_hash(struct wps_data *wps, struct wpabuf *msg)
1411 if (random_get_bytes(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
1413 wpa_hexdump(MSG_DEBUG, "WPS: R-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
1414 wpa_hexdump(MSG_DEBUG, "WPS: R-S2",
1415 wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
1417 if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
1418 wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
1419 "R-Hash derivation");
1423 wpa_printf(MSG_DEBUG, "WPS: * R-Hash1");
1424 wpabuf_put_be16(msg, ATTR_R_HASH1);
1425 wpabuf_put_be16(msg, SHA256_MAC_LEN);
1426 hash = wpabuf_put(msg, SHA256_MAC_LEN);
1427 /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
1428 addr[0] = wps->snonce;
1429 len[0] = WPS_SECRET_NONCE_LEN;
1430 addr[1] = wps->psk1;
1431 len[1] = WPS_PSK_LEN;
1432 addr[2] = wpabuf_head(wps->dh_pubkey_e);
1433 len[2] = wpabuf_len(wps->dh_pubkey_e);
1434 addr[3] = wpabuf_head(wps->dh_pubkey_r);
1435 len[3] = wpabuf_len(wps->dh_pubkey_r);
1436 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
1437 wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", hash, SHA256_MAC_LEN);
1439 wpa_printf(MSG_DEBUG, "WPS: * R-Hash2");
1440 wpabuf_put_be16(msg, ATTR_R_HASH2);
1441 wpabuf_put_be16(msg, SHA256_MAC_LEN);
1442 hash = wpabuf_put(msg, SHA256_MAC_LEN);
1443 /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
1444 addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
1445 addr[1] = wps->psk2;
1446 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
1447 wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", hash, SHA256_MAC_LEN);
1453 static int wps_build_r_snonce1(struct wps_data *wps, struct wpabuf *msg)
1455 wpa_printf(MSG_DEBUG, "WPS: * R-SNonce1");
1456 wpabuf_put_be16(msg, ATTR_R_SNONCE1);
1457 wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
1458 wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
1463 static int wps_build_r_snonce2(struct wps_data *wps, struct wpabuf *msg)
1465 wpa_printf(MSG_DEBUG, "WPS: * R-SNonce2");
1466 wpabuf_put_be16(msg, ATTR_R_SNONCE2);
1467 wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
1468 wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
1469 WPS_SECRET_NONCE_LEN);
1474 static int wps_build_cred_network_idx(struct wpabuf *msg,
1475 const struct wps_credential *cred)
1477 wpa_printf(MSG_DEBUG, "WPS: * Network Index (1)");
1478 wpabuf_put_be16(msg, ATTR_NETWORK_INDEX);
1479 wpabuf_put_be16(msg, 1);
1480 wpabuf_put_u8(msg, 1);
1485 static int wps_build_cred_ssid(struct wpabuf *msg,
1486 const struct wps_credential *cred)
1488 wpa_printf(MSG_DEBUG, "WPS: * SSID");
1489 wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID for Credential",
1490 cred->ssid, cred->ssid_len);
1491 wpabuf_put_be16(msg, ATTR_SSID);
1492 wpabuf_put_be16(msg, cred->ssid_len);
1493 wpabuf_put_data(msg, cred->ssid, cred->ssid_len);
1498 static int wps_build_cred_auth_type(struct wpabuf *msg,
1499 const struct wps_credential *cred)
1501 wpa_printf(MSG_DEBUG, "WPS: * Authentication Type (0x%x)",
1503 wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
1504 wpabuf_put_be16(msg, 2);
1505 wpabuf_put_be16(msg, cred->auth_type);
1510 static int wps_build_cred_encr_type(struct wpabuf *msg,
1511 const struct wps_credential *cred)
1513 wpa_printf(MSG_DEBUG, "WPS: * Encryption Type (0x%x)",
1515 wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
1516 wpabuf_put_be16(msg, 2);
1517 wpabuf_put_be16(msg, cred->encr_type);
1522 static int wps_build_cred_network_key(struct wpabuf *msg,
1523 const struct wps_credential *cred)
1525 wpa_printf(MSG_DEBUG, "WPS: * Network Key (len=%d)",
1526 (int) cred->key_len);
1527 wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key",
1528 cred->key, cred->key_len);
1529 wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
1530 wpabuf_put_be16(msg, cred->key_len);
1531 wpabuf_put_data(msg, cred->key, cred->key_len);
1536 static int wps_build_credential(struct wpabuf *msg,
1537 const struct wps_credential *cred)
1539 if (wps_build_cred_network_idx(msg, cred) ||
1540 wps_build_cred_ssid(msg, cred) ||
1541 wps_build_cred_auth_type(msg, cred) ||
1542 wps_build_cred_encr_type(msg, cred) ||
1543 wps_build_cred_network_key(msg, cred) ||
1544 wps_build_mac_addr(msg, cred->mac_addr))
1550 int wps_build_credential_wrap(struct wpabuf *msg,
1551 const struct wps_credential *cred)
1553 struct wpabuf *wbuf;
1554 wbuf = wpabuf_alloc(200);
1557 if (wps_build_credential(wbuf, cred)) {
1561 wpabuf_put_be16(msg, ATTR_CRED);
1562 wpabuf_put_be16(msg, wpabuf_len(wbuf));
1563 wpabuf_put_buf(msg, wbuf);
1569 int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
1571 struct wpabuf *cred;
1573 if (wps->wps->registrar->skip_cred_build)
1574 goto skip_cred_build;
1576 wpa_printf(MSG_DEBUG, "WPS: * Credential");
1577 if (wps->use_cred) {
1578 os_memcpy(&wps->cred, wps->use_cred, sizeof(wps->cred));
1581 os_memset(&wps->cred, 0, sizeof(wps->cred));
1583 os_memcpy(wps->cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
1584 wps->cred.ssid_len = wps->wps->ssid_len;
1586 /* Select the best authentication and encryption type */
1587 if (wps->auth_type & WPS_AUTH_WPA2PSK)
1588 wps->auth_type = WPS_AUTH_WPA2PSK;
1589 else if (wps->auth_type & WPS_AUTH_WPAPSK)
1590 wps->auth_type = WPS_AUTH_WPAPSK;
1591 else if (wps->auth_type & WPS_AUTH_OPEN)
1592 wps->auth_type = WPS_AUTH_OPEN;
1593 else if (wps->auth_type & WPS_AUTH_SHARED)
1594 wps->auth_type = WPS_AUTH_SHARED;
1596 wpa_printf(MSG_DEBUG, "WPS: Unsupported auth_type 0x%x",
1600 wps->cred.auth_type = wps->auth_type;
1602 if (wps->auth_type == WPS_AUTH_WPA2PSK ||
1603 wps->auth_type == WPS_AUTH_WPAPSK) {
1604 if (wps->encr_type & WPS_ENCR_AES)
1605 wps->encr_type = WPS_ENCR_AES;
1606 else if (wps->encr_type & WPS_ENCR_TKIP)
1607 wps->encr_type = WPS_ENCR_TKIP;
1609 wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
1610 "type for WPA/WPA2");
1614 if (wps->encr_type & WPS_ENCR_WEP)
1615 wps->encr_type = WPS_ENCR_WEP;
1616 else if (wps->encr_type & WPS_ENCR_NONE)
1617 wps->encr_type = WPS_ENCR_NONE;
1619 wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
1620 "type for non-WPA/WPA2 mode");
1624 wps->cred.encr_type = wps->encr_type;
1626 * Set MAC address in the Credential to be the Enrollee's MAC address
1628 os_memcpy(wps->cred.mac_addr, wps->mac_addr_e, ETH_ALEN);
1630 if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap &&
1631 !wps->wps->registrar->disable_auto_conf) {
1633 /* Generate a random passphrase */
1634 if (random_get_bytes(r, sizeof(r)) < 0)
1636 os_free(wps->new_psk);
1637 wps->new_psk = base64_encode(r, sizeof(r), &wps->new_psk_len);
1638 if (wps->new_psk == NULL)
1640 wps->new_psk_len--; /* remove newline */
1641 while (wps->new_psk_len &&
1642 wps->new_psk[wps->new_psk_len - 1] == '=')
1644 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Generated passphrase",
1645 wps->new_psk, wps->new_psk_len);
1646 os_memcpy(wps->cred.key, wps->new_psk, wps->new_psk_len);
1647 wps->cred.key_len = wps->new_psk_len;
1648 } else if (!wps->wps->registrar->force_per_enrollee_psk &&
1649 wps->use_psk_key && wps->wps->psk_set) {
1651 wpa_printf(MSG_DEBUG, "WPS: Use PSK format for Network Key");
1652 wpa_snprintf_hex(hex, sizeof(hex), wps->wps->psk, 32);
1653 os_memcpy(wps->cred.key, hex, 32 * 2);
1654 wps->cred.key_len = 32 * 2;
1655 } else if (!wps->wps->registrar->force_per_enrollee_psk &&
1656 wps->wps->network_key) {
1657 os_memcpy(wps->cred.key, wps->wps->network_key,
1658 wps->wps->network_key_len);
1659 wps->cred.key_len = wps->wps->network_key_len;
1660 } else if (wps->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
1662 /* Generate a random per-device PSK */
1663 os_free(wps->new_psk);
1664 wps->new_psk_len = 32;
1665 wps->new_psk = os_malloc(wps->new_psk_len);
1666 if (wps->new_psk == NULL)
1668 if (random_get_bytes(wps->new_psk, wps->new_psk_len) < 0) {
1669 os_free(wps->new_psk);
1670 wps->new_psk = NULL;
1673 wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
1674 wps->new_psk, wps->new_psk_len);
1675 wpa_snprintf_hex(hex, sizeof(hex), wps->new_psk,
1677 os_memcpy(wps->cred.key, hex, wps->new_psk_len * 2);
1678 wps->cred.key_len = wps->new_psk_len * 2;
1682 #ifdef CONFIG_WPS_TESTING
1683 if (wps_testing_dummy_cred)
1684 cred = wpabuf_alloc(200);
1688 struct wps_credential dummy;
1689 wpa_printf(MSG_DEBUG, "WPS: Add dummy credential");
1690 os_memset(&dummy, 0, sizeof(dummy));
1691 os_memcpy(dummy.ssid, "dummy", 5);
1693 dummy.auth_type = WPS_AUTH_WPA2PSK;
1694 dummy.encr_type = WPS_ENCR_AES;
1695 os_memcpy(dummy.key, "dummy psk", 9);
1697 os_memcpy(dummy.mac_addr, wps->mac_addr_e, ETH_ALEN);
1698 wps_build_credential(cred, &dummy);
1699 wpa_hexdump_buf(MSG_DEBUG, "WPS: Dummy Credential", cred);
1701 wpabuf_put_be16(msg, ATTR_CRED);
1702 wpabuf_put_be16(msg, wpabuf_len(cred));
1703 wpabuf_put_buf(msg, cred);
1707 #endif /* CONFIG_WPS_TESTING */
1709 cred = wpabuf_alloc(200);
1713 if (wps_build_credential(cred, &wps->cred)) {
1718 wpabuf_put_be16(msg, ATTR_CRED);
1719 wpabuf_put_be16(msg, wpabuf_len(cred));
1720 wpabuf_put_buf(msg, cred);
1724 if (wps->wps->registrar->extra_cred) {
1725 wpa_printf(MSG_DEBUG, "WPS: * Credential (pre-configured)");
1726 wpabuf_put_buf(msg, wps->wps->registrar->extra_cred);
1733 static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *msg)
1735 wpa_printf(MSG_DEBUG, "WPS: * AP Settings");
1737 if (wps_build_credential(msg, &wps->cred))
1744 static struct wpabuf * wps_build_ap_cred(struct wps_data *wps)
1746 struct wpabuf *msg, *plain;
1748 msg = wpabuf_alloc(1000);
1752 plain = wpabuf_alloc(200);
1753 if (plain == NULL) {
1758 if (wps_build_ap_settings(wps, plain)) {
1764 wpabuf_put_be16(msg, ATTR_CRED);
1765 wpabuf_put_be16(msg, wpabuf_len(plain));
1766 wpabuf_put_buf(msg, plain);
1773 static struct wpabuf * wps_build_m2(struct wps_data *wps)
1777 if (random_get_bytes(wps->nonce_r, WPS_NONCE_LEN) < 0)
1779 wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
1780 wps->nonce_r, WPS_NONCE_LEN);
1781 wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
1783 wpa_printf(MSG_DEBUG, "WPS: Building Message M2");
1784 msg = wpabuf_alloc(1000);
1788 if (wps_build_version(msg) ||
1789 wps_build_msg_type(msg, WPS_M2) ||
1790 wps_build_enrollee_nonce(wps, msg) ||
1791 wps_build_registrar_nonce(wps, msg) ||
1792 wps_build_uuid_r(wps, msg) ||
1793 wps_build_public_key(wps, msg) ||
1794 wps_derive_keys(wps) ||
1795 wps_build_auth_type_flags(wps, msg) ||
1796 wps_build_encr_type_flags(wps, msg) ||
1797 wps_build_conn_type_flags(wps, msg) ||
1798 wps_build_config_methods_r(wps->wps->registrar, msg) ||
1799 wps_build_device_attrs(&wps->wps->dev, msg) ||
1800 wps_build_rf_bands(&wps->wps->dev, msg,
1801 wps->wps->rf_band_cb(wps->wps->cb_ctx)) ||
1802 wps_build_assoc_state(wps, msg) ||
1803 wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
1804 wps_build_dev_password_id(msg, wps->dev_pw_id) ||
1805 wps_build_os_version(&wps->wps->dev, msg) ||
1806 wps_build_wfa_ext(msg, 0, NULL, 0) ||
1807 wps_build_authenticator(wps, msg)) {
1813 wps->state = RECV_M3;
1818 static struct wpabuf * wps_build_m2d(struct wps_data *wps)
1821 u16 err = wps->config_error;
1823 wpa_printf(MSG_DEBUG, "WPS: Building Message M2D");
1824 msg = wpabuf_alloc(1000);
1828 if (wps->wps->ap && wps->wps->ap_setup_locked &&
1829 err == WPS_CFG_NO_ERROR)
1830 err = WPS_CFG_SETUP_LOCKED;
1832 if (wps_build_version(msg) ||
1833 wps_build_msg_type(msg, WPS_M2D) ||
1834 wps_build_enrollee_nonce(wps, msg) ||
1835 wps_build_registrar_nonce(wps, msg) ||
1836 wps_build_uuid_r(wps, msg) ||
1837 wps_build_auth_type_flags(wps, msg) ||
1838 wps_build_encr_type_flags(wps, msg) ||
1839 wps_build_conn_type_flags(wps, msg) ||
1840 wps_build_config_methods_r(wps->wps->registrar, msg) ||
1841 wps_build_device_attrs(&wps->wps->dev, msg) ||
1842 wps_build_rf_bands(&wps->wps->dev, msg,
1843 wps->wps->rf_band_cb(wps->wps->cb_ctx)) ||
1844 wps_build_assoc_state(wps, msg) ||
1845 wps_build_config_error(msg, err) ||
1846 wps_build_os_version(&wps->wps->dev, msg) ||
1847 wps_build_wfa_ext(msg, 0, NULL, 0)) {
1852 wps->state = RECV_M2D_ACK;
1857 static struct wpabuf * wps_build_m4(struct wps_data *wps)
1859 struct wpabuf *msg, *plain;
1861 wpa_printf(MSG_DEBUG, "WPS: Building Message M4");
1863 wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);
1865 plain = wpabuf_alloc(200);
1869 msg = wpabuf_alloc(1000);
1875 if (wps_build_version(msg) ||
1876 wps_build_msg_type(msg, WPS_M4) ||
1877 wps_build_enrollee_nonce(wps, msg) ||
1878 wps_build_r_hash(wps, msg) ||
1879 wps_build_r_snonce1(wps, plain) ||
1880 wps_build_key_wrap_auth(wps, plain) ||
1881 wps_build_encr_settings(wps, msg, plain) ||
1882 wps_build_wfa_ext(msg, 0, NULL, 0) ||
1883 wps_build_authenticator(wps, msg)) {
1890 wps->state = RECV_M5;
1895 static struct wpabuf * wps_build_m6(struct wps_data *wps)
1897 struct wpabuf *msg, *plain;
1899 wpa_printf(MSG_DEBUG, "WPS: Building Message M6");
1901 plain = wpabuf_alloc(200);
1905 msg = wpabuf_alloc(1000);
1911 if (wps_build_version(msg) ||
1912 wps_build_msg_type(msg, WPS_M6) ||
1913 wps_build_enrollee_nonce(wps, msg) ||
1914 wps_build_r_snonce2(wps, plain) ||
1915 wps_build_key_wrap_auth(wps, plain) ||
1916 wps_build_encr_settings(wps, msg, plain) ||
1917 wps_build_wfa_ext(msg, 0, NULL, 0) ||
1918 wps_build_authenticator(wps, msg)) {
1925 wps->wps_pin_revealed = 1;
1926 wps->state = RECV_M7;
1931 static struct wpabuf * wps_build_m8(struct wps_data *wps)
1933 struct wpabuf *msg, *plain;
1935 wpa_printf(MSG_DEBUG, "WPS: Building Message M8");
1937 plain = wpabuf_alloc(500);
1941 msg = wpabuf_alloc(1000);
1947 if (wps_build_version(msg) ||
1948 wps_build_msg_type(msg, WPS_M8) ||
1949 wps_build_enrollee_nonce(wps, msg) ||
1950 ((wps->wps->ap || wps->er) && wps_build_cred(wps, plain)) ||
1951 (!wps->wps->ap && !wps->er && wps_build_ap_settings(wps, plain)) ||
1952 wps_build_key_wrap_auth(wps, plain) ||
1953 wps_build_encr_settings(wps, msg, plain) ||
1954 wps_build_wfa_ext(msg, 0, NULL, 0) ||
1955 wps_build_authenticator(wps, msg)) {
1962 wps->state = RECV_DONE;
1967 struct wpabuf * wps_registrar_get_msg(struct wps_data *wps,
1968 enum wsc_op_code *op_code)
1972 #ifdef CONFIG_WPS_UPNP
1973 if (!wps->int_reg && wps->wps->wps_upnp) {
1974 struct upnp_pending_message *p, *prev = NULL;
1975 if (wps->ext_reg > 1)
1976 wps_registrar_free_pending_m2(wps->wps);
1977 p = wps->wps->upnp_msgs;
1978 /* TODO: check pending message MAC address */
1979 while (p && p->next) {
1984 wpa_printf(MSG_DEBUG, "WPS: Use pending message from "
1989 wps->wps->upnp_msgs = NULL;
1996 *op_code = WSC_NACK;
2003 if (wps->ext_reg == 0)
2009 wpa_printf(MSG_DEBUG, "WPS: Using external Registrar, but no "
2010 "pending message available");
2013 #endif /* CONFIG_WPS_UPNP */
2015 switch (wps->state) {
2017 if (wps_get_dev_password(wps) < 0)
2018 msg = wps_build_m2d(wps);
2020 msg = wps_build_m2(wps);
2024 msg = wps_build_m2d(wps);
2028 msg = wps_build_m4(wps);
2032 msg = wps_build_m6(wps);
2036 msg = wps_build_m8(wps);
2040 msg = wps_build_wsc_ack(wps);
2044 msg = wps_build_wsc_nack(wps);
2045 *op_code = WSC_NACK;
2048 wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
2049 "a message", wps->state);
2054 if (*op_code == WSC_MSG && msg) {
2055 /* Save a copy of the last message for Authenticator derivation
2057 wpabuf_free(wps->last_msg);
2058 wps->last_msg = wpabuf_dup(msg);
2065 static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
2067 if (e_nonce == NULL) {
2068 wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
2072 os_memcpy(wps->nonce_e, e_nonce, WPS_NONCE_LEN);
2073 wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
2074 wps->nonce_e, WPS_NONCE_LEN);
2080 static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
2082 if (r_nonce == NULL) {
2083 wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
2087 if (os_memcmp(wps->nonce_r, r_nonce, WPS_NONCE_LEN) != 0) {
2088 wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce received");
2096 static int wps_process_uuid_e(struct wps_data *wps, const u8 *uuid_e)
2098 if (uuid_e == NULL) {
2099 wpa_printf(MSG_DEBUG, "WPS: No UUID-E received");
2103 os_memcpy(wps->uuid_e, uuid_e, WPS_UUID_LEN);
2104 wpa_hexdump(MSG_DEBUG, "WPS: UUID-E", wps->uuid_e, WPS_UUID_LEN);
2110 static int wps_process_dev_password_id(struct wps_data *wps, const u8 *pw_id)
2112 if (pw_id == NULL) {
2113 wpa_printf(MSG_DEBUG, "WPS: No Device Password ID received");
2117 wps->dev_pw_id = WPA_GET_BE16(pw_id);
2118 wpa_printf(MSG_DEBUG, "WPS: Device Password ID %d", wps->dev_pw_id);
2124 static int wps_process_e_hash1(struct wps_data *wps, const u8 *e_hash1)
2126 if (e_hash1 == NULL) {
2127 wpa_printf(MSG_DEBUG, "WPS: No E-Hash1 received");
2131 os_memcpy(wps->peer_hash1, e_hash1, WPS_HASH_LEN);
2132 wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", wps->peer_hash1, WPS_HASH_LEN);
2138 static int wps_process_e_hash2(struct wps_data *wps, const u8 *e_hash2)
2140 if (e_hash2 == NULL) {
2141 wpa_printf(MSG_DEBUG, "WPS: No E-Hash2 received");
2145 os_memcpy(wps->peer_hash2, e_hash2, WPS_HASH_LEN);
2146 wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", wps->peer_hash2, WPS_HASH_LEN);
2152 static int wps_process_e_snonce1(struct wps_data *wps, const u8 *e_snonce1)
2154 u8 hash[SHA256_MAC_LEN];
2158 if (e_snonce1 == NULL) {
2159 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce1 received");
2163 wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce1", e_snonce1,
2164 WPS_SECRET_NONCE_LEN);
2166 /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
2167 addr[0] = e_snonce1;
2168 len[0] = WPS_SECRET_NONCE_LEN;
2169 addr[1] = wps->psk1;
2170 len[1] = WPS_PSK_LEN;
2171 addr[2] = wpabuf_head(wps->dh_pubkey_e);
2172 len[2] = wpabuf_len(wps->dh_pubkey_e);
2173 addr[3] = wpabuf_head(wps->dh_pubkey_r);
2174 len[3] = wpabuf_len(wps->dh_pubkey_r);
2175 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
2177 if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
2178 wpa_printf(MSG_DEBUG, "WPS: E-Hash1 derived from E-S1 does "
2179 "not match with the pre-committed value");
2180 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
2181 wps_pwd_auth_fail_event(wps->wps, 0, 1, wps->mac_addr_e);
2185 wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the first "
2186 "half of the device password");
2192 static int wps_process_e_snonce2(struct wps_data *wps, const u8 *e_snonce2)
2194 u8 hash[SHA256_MAC_LEN];
2198 if (e_snonce2 == NULL) {
2199 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce2 received");
2203 wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce2", e_snonce2,
2204 WPS_SECRET_NONCE_LEN);
2206 /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
2207 addr[0] = e_snonce2;
2208 len[0] = WPS_SECRET_NONCE_LEN;
2209 addr[1] = wps->psk2;
2210 len[1] = WPS_PSK_LEN;
2211 addr[2] = wpabuf_head(wps->dh_pubkey_e);
2212 len[2] = wpabuf_len(wps->dh_pubkey_e);
2213 addr[3] = wpabuf_head(wps->dh_pubkey_r);
2214 len[3] = wpabuf_len(wps->dh_pubkey_r);
2215 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
2217 if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
2218 wpa_printf(MSG_DEBUG, "WPS: E-Hash2 derived from E-S2 does "
2219 "not match with the pre-committed value");
2220 wps_registrar_invalidate_pin(wps->wps->registrar, wps->uuid_e);
2221 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
2222 wps_pwd_auth_fail_event(wps->wps, 0, 2, wps->mac_addr_e);
2226 wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the second "
2227 "half of the device password");
2228 wps->wps_pin_revealed = 0;
2229 wps_registrar_unlock_pin(wps->wps->registrar, wps->uuid_e);
2232 * In case wildcard PIN is used and WPS handshake succeeds in the first
2233 * attempt, wps_registrar_unlock_pin() would not free the PIN, so make
2234 * sure the PIN gets invalidated here.
2236 wps_registrar_invalidate_pin(wps->wps->registrar, wps->uuid_e);
2242 static int wps_process_mac_addr(struct wps_data *wps, const u8 *mac_addr)
2244 if (mac_addr == NULL) {
2245 wpa_printf(MSG_DEBUG, "WPS: No MAC Address received");
2249 wpa_printf(MSG_DEBUG, "WPS: Enrollee MAC Address " MACSTR,
2251 os_memcpy(wps->mac_addr_e, mac_addr, ETH_ALEN);
2252 os_memcpy(wps->peer_dev.mac_addr, mac_addr, ETH_ALEN);
2258 static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
2261 if (pk == NULL || pk_len == 0) {
2262 wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
2266 wpabuf_free(wps->dh_pubkey_e);
2267 wps->dh_pubkey_e = wpabuf_alloc_copy(pk, pk_len);
2268 if (wps->dh_pubkey_e == NULL)
2275 static int wps_process_auth_type_flags(struct wps_data *wps, const u8 *auth)
2280 wpa_printf(MSG_DEBUG, "WPS: No Authentication Type flags "
2285 auth_types = WPA_GET_BE16(auth);
2287 wpa_printf(MSG_DEBUG, "WPS: Enrollee Authentication Type flags 0x%x",
2289 wps->auth_type = wps->wps->auth_types & auth_types;
2290 if (wps->auth_type == 0) {
2291 wpa_printf(MSG_DEBUG, "WPS: No match in supported "
2292 "authentication types (own 0x%x Enrollee 0x%x)",
2293 wps->wps->auth_types, auth_types);
2294 #ifdef WPS_WORKAROUNDS
2296 * Some deployed implementations seem to advertise incorrect
2297 * information in this attribute. For example, Linksys WRT350N
2298 * seems to have a byteorder bug that breaks this negotiation.
2299 * In order to interoperate with existing implementations,
2300 * assume that the Enrollee supports everything we do.
2302 wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
2303 "does not advertise supported authentication types "
2305 wps->auth_type = wps->wps->auth_types;
2306 #else /* WPS_WORKAROUNDS */
2308 #endif /* WPS_WORKAROUNDS */
2315 static int wps_process_encr_type_flags(struct wps_data *wps, const u8 *encr)
2320 wpa_printf(MSG_DEBUG, "WPS: No Encryption Type flags "
2325 encr_types = WPA_GET_BE16(encr);
2327 wpa_printf(MSG_DEBUG, "WPS: Enrollee Encryption Type flags 0x%x",
2329 wps->encr_type = wps->wps->encr_types & encr_types;
2330 if (wps->encr_type == 0) {
2331 wpa_printf(MSG_DEBUG, "WPS: No match in supported "
2332 "encryption types (own 0x%x Enrollee 0x%x)",
2333 wps->wps->encr_types, encr_types);
2334 #ifdef WPS_WORKAROUNDS
2336 * Some deployed implementations seem to advertise incorrect
2337 * information in this attribute. For example, Linksys WRT350N
2338 * seems to have a byteorder bug that breaks this negotiation.
2339 * In order to interoperate with existing implementations,
2340 * assume that the Enrollee supports everything we do.
2342 wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
2343 "does not advertise supported encryption types "
2345 wps->encr_type = wps->wps->encr_types;
2346 #else /* WPS_WORKAROUNDS */
2348 #endif /* WPS_WORKAROUNDS */
2355 static int wps_process_conn_type_flags(struct wps_data *wps, const u8 *conn)
2358 wpa_printf(MSG_DEBUG, "WPS: No Connection Type flags "
2363 wpa_printf(MSG_DEBUG, "WPS: Enrollee Connection Type flags 0x%x",
2370 static int wps_process_config_methods(struct wps_data *wps, const u8 *methods)
2374 if (methods == NULL) {
2375 wpa_printf(MSG_DEBUG, "WPS: No Config Methods received");
2379 m = WPA_GET_BE16(methods);
2381 wpa_printf(MSG_DEBUG, "WPS: Enrollee Config Methods 0x%x"
2382 "%s%s%s%s%s%s%s%s%s", m,
2383 m & WPS_CONFIG_USBA ? " [USBA]" : "",
2384 m & WPS_CONFIG_ETHERNET ? " [Ethernet]" : "",
2385 m & WPS_CONFIG_LABEL ? " [Label]" : "",
2386 m & WPS_CONFIG_DISPLAY ? " [Display]" : "",
2387 m & WPS_CONFIG_EXT_NFC_TOKEN ? " [Ext NFC Token]" : "",
2388 m & WPS_CONFIG_INT_NFC_TOKEN ? " [Int NFC Token]" : "",
2389 m & WPS_CONFIG_NFC_INTERFACE ? " [NFC]" : "",
2390 m & WPS_CONFIG_PUSHBUTTON ? " [PBC]" : "",
2391 m & WPS_CONFIG_KEYPAD ? " [Keypad]" : "");
2393 if (!(m & WPS_CONFIG_DISPLAY) && !wps->use_psk_key) {
2395 * The Enrollee does not have a display so it is unlikely to be
2396 * able to show the passphrase to a user and as such, could
2397 * benefit from receiving PSK to reduce key derivation time.
2399 wpa_printf(MSG_DEBUG, "WPS: Prefer PSK format key due to "
2400 "Enrollee not supporting display");
2401 wps->use_psk_key = 1;
2408 static int wps_process_wps_state(struct wps_data *wps, const u8 *state)
2410 if (state == NULL) {
2411 wpa_printf(MSG_DEBUG, "WPS: No Wi-Fi Protected Setup State "
2416 wpa_printf(MSG_DEBUG, "WPS: Enrollee Wi-Fi Protected Setup State %d",
2423 static int wps_process_assoc_state(struct wps_data *wps, const u8 *assoc)
2427 if (assoc == NULL) {
2428 wpa_printf(MSG_DEBUG, "WPS: No Association State received");
2432 a = WPA_GET_BE16(assoc);
2433 wpa_printf(MSG_DEBUG, "WPS: Enrollee Association State %d", a);
2439 static int wps_process_config_error(struct wps_data *wps, const u8 *err)
2444 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error received");
2448 e = WPA_GET_BE16(err);
2449 wpa_printf(MSG_DEBUG, "WPS: Enrollee Configuration Error %d", e);
2455 static int wps_registrar_p2p_dev_addr_match(struct wps_data *wps)
2458 struct wps_registrar *reg = wps->wps->registrar;
2460 if (is_zero_ether_addr(reg->p2p_dev_addr))
2461 return 1; /* no filtering in use */
2463 if (os_memcmp(reg->p2p_dev_addr, wps->p2p_dev_addr, ETH_ALEN) != 0) {
2464 wpa_printf(MSG_DEBUG, "WPS: No match on P2P Device Address "
2465 "filtering for PBC: expected " MACSTR " was "
2466 MACSTR " - indicate PBC session overlap",
2467 MAC2STR(reg->p2p_dev_addr),
2468 MAC2STR(wps->p2p_dev_addr));
2471 #endif /* CONFIG_P2P */
2476 static int wps_registrar_skip_overlap(struct wps_data *wps)
2479 struct wps_registrar *reg = wps->wps->registrar;
2481 if (is_zero_ether_addr(reg->p2p_dev_addr))
2482 return 0; /* no specific Enrollee selected */
2484 if (os_memcmp(reg->p2p_dev_addr, wps->p2p_dev_addr, ETH_ALEN) == 0) {
2485 wpa_printf(MSG_DEBUG, "WPS: Skip PBC overlap due to selected "
2489 #endif /* CONFIG_P2P */
2494 static enum wps_process_res wps_process_m1(struct wps_data *wps,
2495 struct wps_parse_attr *attr)
2497 wpa_printf(MSG_DEBUG, "WPS: Received M1");
2499 if (wps->state != RECV_M1) {
2500 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2501 "receiving M1", wps->state);
2505 if (wps_process_uuid_e(wps, attr->uuid_e) ||
2506 wps_process_mac_addr(wps, attr->mac_addr) ||
2507 wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
2508 wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
2509 wps_process_auth_type_flags(wps, attr->auth_type_flags) ||
2510 wps_process_encr_type_flags(wps, attr->encr_type_flags) ||
2511 wps_process_conn_type_flags(wps, attr->conn_type_flags) ||
2512 wps_process_config_methods(wps, attr->config_methods) ||
2513 wps_process_wps_state(wps, attr->wps_state) ||
2514 wps_process_device_attrs(&wps->peer_dev, attr) ||
2515 wps_process_rf_bands(&wps->peer_dev, attr->rf_bands) ||
2516 wps_process_assoc_state(wps, attr->assoc_state) ||
2517 wps_process_dev_password_id(wps, attr->dev_password_id) ||
2518 wps_process_config_error(wps, attr->config_error) ||
2519 wps_process_os_version(&wps->peer_dev, attr->os_version))
2522 if (wps->dev_pw_id < 0x10 &&
2523 wps->dev_pw_id != DEV_PW_DEFAULT &&
2524 wps->dev_pw_id != DEV_PW_USER_SPECIFIED &&
2525 wps->dev_pw_id != DEV_PW_MACHINE_SPECIFIED &&
2526 wps->dev_pw_id != DEV_PW_REGISTRAR_SPECIFIED &&
2527 (wps->dev_pw_id != DEV_PW_PUSHBUTTON ||
2528 !wps->wps->registrar->pbc)) {
2529 wpa_printf(MSG_DEBUG, "WPS: Unsupported Device Password ID %d",
2531 wps->state = SEND_M2D;
2532 return WPS_CONTINUE;
2535 #ifdef CONFIG_WPS_NFC
2536 if (wps->dev_pw_id >= 0x10) {
2537 struct wps_nfc_pw_token *token;
2539 u8 hash[WPS_HASH_LEN];
2541 wpa_printf(MSG_DEBUG, "WPS: Searching for NFC token match for id=%d (ctx %p registrar %p)",
2542 wps->dev_pw_id, wps->wps, wps->wps->registrar);
2543 token = wps_get_nfc_pw_token(
2544 &wps->wps->registrar->nfc_pw_tokens, wps->dev_pw_id);
2546 wpa_printf(MSG_DEBUG, "WPS: Found matching NFC "
2548 dl_list_del(&token->list);
2549 wps->nfc_pw_token = token;
2551 addr[0] = attr->public_key;
2552 sha256_vector(1, addr, &attr->public_key_len, hash);
2553 if (os_memcmp(hash, wps->nfc_pw_token->pubkey_hash,
2554 WPS_OOB_PUBKEY_HASH_LEN) != 0) {
2555 wpa_printf(MSG_ERROR, "WPS: Public Key hash "
2561 #endif /* CONFIG_WPS_NFC */
2563 if (wps->dev_pw_id == DEV_PW_PUSHBUTTON) {
2564 if ((wps->wps->registrar->force_pbc_overlap ||
2565 wps_registrar_pbc_overlap(wps->wps->registrar,
2566 wps->mac_addr_e, wps->uuid_e) ||
2567 !wps_registrar_p2p_dev_addr_match(wps)) &&
2568 !wps_registrar_skip_overlap(wps)) {
2569 wpa_printf(MSG_DEBUG, "WPS: PBC overlap - deny PBC "
2571 wps->state = SEND_M2D;
2572 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2573 wps_pbc_overlap_event(wps->wps);
2574 wps_fail_event(wps->wps, WPS_M1,
2575 WPS_CFG_MULTIPLE_PBC_DETECTED,
2576 WPS_EI_NO_ERROR, wps->mac_addr_e);
2577 wps->wps->registrar->force_pbc_overlap = 1;
2578 return WPS_CONTINUE;
2580 wps_registrar_add_pbc_session(wps->wps->registrar,
2581 wps->mac_addr_e, wps->uuid_e);
2585 #ifdef WPS_WORKAROUNDS
2587 * It looks like Mac OS X 10.6.3 and 10.6.4 do not like Network Key in
2588 * passphrase format. To avoid interop issues, force PSK format to be
2591 if (!wps->use_psk_key &&
2592 wps->peer_dev.manufacturer &&
2593 os_strncmp(wps->peer_dev.manufacturer, "Apple ", 6) == 0 &&
2594 wps->peer_dev.model_name &&
2595 os_strcmp(wps->peer_dev.model_name, "AirPort") == 0) {
2596 wpa_printf(MSG_DEBUG, "WPS: Workaround - Force Network Key in "
2598 wps->use_psk_key = 1;
2600 #endif /* WPS_WORKAROUNDS */
2602 wps->state = SEND_M2;
2603 return WPS_CONTINUE;
2607 static enum wps_process_res wps_process_m3(struct wps_data *wps,
2608 const struct wpabuf *msg,
2609 struct wps_parse_attr *attr)
2611 wpa_printf(MSG_DEBUG, "WPS: Received M3");
2613 if (wps->state != RECV_M3) {
2614 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2615 "receiving M3", wps->state);
2616 wps->state = SEND_WSC_NACK;
2617 return WPS_CONTINUE;
2620 if (wps->pbc && wps->wps->registrar->force_pbc_overlap &&
2621 !wps_registrar_skip_overlap(wps)) {
2622 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
2624 wps->state = SEND_WSC_NACK;
2625 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2626 return WPS_CONTINUE;
2629 if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
2630 wps_process_authenticator(wps, attr->authenticator, msg) ||
2631 wps_process_e_hash1(wps, attr->e_hash1) ||
2632 wps_process_e_hash2(wps, attr->e_hash2)) {
2633 wps->state = SEND_WSC_NACK;
2634 return WPS_CONTINUE;
2637 wps->state = SEND_M4;
2638 return WPS_CONTINUE;
2642 static enum wps_process_res wps_process_m5(struct wps_data *wps,
2643 const struct wpabuf *msg,
2644 struct wps_parse_attr *attr)
2646 struct wpabuf *decrypted;
2647 struct wps_parse_attr eattr;
2649 wpa_printf(MSG_DEBUG, "WPS: Received M5");
2651 if (wps->state != RECV_M5) {
2652 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2653 "receiving M5", wps->state);
2654 wps->state = SEND_WSC_NACK;
2655 return WPS_CONTINUE;
2658 if (wps->pbc && wps->wps->registrar->force_pbc_overlap &&
2659 !wps_registrar_skip_overlap(wps)) {
2660 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
2662 wps->state = SEND_WSC_NACK;
2663 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2664 return WPS_CONTINUE;
2667 if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
2668 wps_process_authenticator(wps, attr->authenticator, msg)) {
2669 wps->state = SEND_WSC_NACK;
2670 return WPS_CONTINUE;
2673 decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
2674 attr->encr_settings_len);
2675 if (decrypted == NULL) {
2676 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
2677 "Settings attribute");
2678 wps->state = SEND_WSC_NACK;
2679 return WPS_CONTINUE;
2682 if (wps_validate_m5_encr(decrypted, attr->version2 != NULL) < 0) {
2683 wpabuf_free(decrypted);
2684 wps->state = SEND_WSC_NACK;
2685 return WPS_CONTINUE;
2688 wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
2690 if (wps_parse_msg(decrypted, &eattr) < 0 ||
2691 wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
2692 wps_process_e_snonce1(wps, eattr.e_snonce1)) {
2693 wpabuf_free(decrypted);
2694 wps->state = SEND_WSC_NACK;
2695 return WPS_CONTINUE;
2697 wpabuf_free(decrypted);
2699 wps->state = SEND_M6;
2700 return WPS_CONTINUE;
2704 static void wps_sta_cred_cb(struct wps_data *wps)
2707 * Update credential to only include a single authentication and
2708 * encryption type in case the AP configuration includes more than one
2711 if (wps->cred.auth_type & WPS_AUTH_WPA2PSK)
2712 wps->cred.auth_type = WPS_AUTH_WPA2PSK;
2713 else if (wps->cred.auth_type & WPS_AUTH_WPAPSK)
2714 wps->cred.auth_type = WPS_AUTH_WPAPSK;
2715 if (wps->cred.encr_type & WPS_ENCR_AES)
2716 wps->cred.encr_type = WPS_ENCR_AES;
2717 else if (wps->cred.encr_type & WPS_ENCR_TKIP)
2718 wps->cred.encr_type = WPS_ENCR_TKIP;
2719 wpa_printf(MSG_DEBUG, "WPS: Update local configuration based on the "
2720 "AP configuration");
2721 if (wps->wps->cred_cb)
2722 wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
2726 static void wps_cred_update(struct wps_credential *dst,
2727 struct wps_credential *src)
2729 os_memcpy(dst->ssid, src->ssid, sizeof(dst->ssid));
2730 dst->ssid_len = src->ssid_len;
2731 dst->auth_type = src->auth_type;
2732 dst->encr_type = src->encr_type;
2733 dst->key_idx = src->key_idx;
2734 os_memcpy(dst->key, src->key, sizeof(dst->key));
2735 dst->key_len = src->key_len;
2739 static int wps_process_ap_settings_r(struct wps_data *wps,
2740 struct wps_parse_attr *attr)
2744 if (wps->wps->ap || wps->er)
2747 /* AP Settings Attributes in M7 when Enrollee is an AP */
2748 if (wps_process_ap_settings(attr, &wps->cred) < 0)
2751 wpa_printf(MSG_INFO, "WPS: Received old AP configuration from AP");
2753 if (wps->new_ap_settings) {
2754 wpa_printf(MSG_INFO, "WPS: Update AP configuration based on "
2756 wps_cred_update(&wps->cred, wps->new_ap_settings);
2760 * Use the AP PIN only to receive the current AP settings, not
2761 * to reconfigure the AP.
2765 * Clear selected registrar here since we do not get to
2766 * WSC_Done in this protocol run.
2768 wps_registrar_pin_completed(wps->wps->registrar);
2770 msg = wps_build_ap_cred(wps);
2773 wps->cred.cred_attr = wpabuf_head(msg);
2774 wps->cred.cred_attr_len = wpabuf_len(msg);
2776 if (wps->ap_settings_cb) {
2777 wps->ap_settings_cb(wps->ap_settings_cb_ctx,
2782 wps_sta_cred_cb(wps);
2784 wps->cred.cred_attr = NULL;
2785 wps->cred.cred_attr_len = 0;
2793 static enum wps_process_res wps_process_m7(struct wps_data *wps,
2794 const struct wpabuf *msg,
2795 struct wps_parse_attr *attr)
2797 struct wpabuf *decrypted;
2798 struct wps_parse_attr eattr;
2800 wpa_printf(MSG_DEBUG, "WPS: Received M7");
2802 if (wps->state != RECV_M7) {
2803 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2804 "receiving M7", wps->state);
2805 wps->state = SEND_WSC_NACK;
2806 return WPS_CONTINUE;
2809 if (wps->pbc && wps->wps->registrar->force_pbc_overlap &&
2810 !wps_registrar_skip_overlap(wps)) {
2811 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
2813 wps->state = SEND_WSC_NACK;
2814 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2815 return WPS_CONTINUE;
2818 if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
2819 wps_process_authenticator(wps, attr->authenticator, msg)) {
2820 wps->state = SEND_WSC_NACK;
2821 return WPS_CONTINUE;
2824 decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
2825 attr->encr_settings_len);
2826 if (decrypted == NULL) {
2827 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypt Encrypted "
2828 "Settings attribute");
2829 wps->state = SEND_WSC_NACK;
2830 return WPS_CONTINUE;
2833 if (wps_validate_m7_encr(decrypted, wps->wps->ap || wps->er,
2834 attr->version2 != NULL) < 0) {
2835 wpabuf_free(decrypted);
2836 wps->state = SEND_WSC_NACK;
2837 return WPS_CONTINUE;
2840 wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
2842 if (wps_parse_msg(decrypted, &eattr) < 0 ||
2843 wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
2844 wps_process_e_snonce2(wps, eattr.e_snonce2) ||
2845 wps_process_ap_settings_r(wps, &eattr)) {
2846 wpabuf_free(decrypted);
2847 wps->state = SEND_WSC_NACK;
2848 return WPS_CONTINUE;
2851 wpabuf_free(decrypted);
2853 wps->state = SEND_M8;
2854 return WPS_CONTINUE;
2858 static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
2859 const struct wpabuf *msg)
2861 struct wps_parse_attr attr;
2862 enum wps_process_res ret = WPS_CONTINUE;
2864 wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
2866 if (wps_parse_msg(msg, &attr) < 0)
2869 if (attr.msg_type == NULL) {
2870 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2871 wps->state = SEND_WSC_NACK;
2872 return WPS_CONTINUE;
2875 if (*attr.msg_type != WPS_M1 &&
2876 (attr.registrar_nonce == NULL ||
2877 os_memcmp(wps->nonce_r, attr.registrar_nonce,
2878 WPS_NONCE_LEN) != 0)) {
2879 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2883 switch (*attr.msg_type) {
2885 if (wps_validate_m1(msg) < 0)
2887 #ifdef CONFIG_WPS_UPNP
2888 if (wps->wps->wps_upnp && attr.mac_addr) {
2889 /* Remove old pending messages when starting new run */
2890 wps_free_pending_msgs(wps->wps->upnp_msgs);
2891 wps->wps->upnp_msgs = NULL;
2893 upnp_wps_device_send_wlan_event(
2894 wps->wps->wps_upnp, attr.mac_addr,
2895 UPNP_WPS_WLANEVENT_TYPE_EAP, msg);
2897 #endif /* CONFIG_WPS_UPNP */
2898 ret = wps_process_m1(wps, &attr);
2901 if (wps_validate_m3(msg) < 0)
2903 ret = wps_process_m3(wps, msg, &attr);
2904 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
2905 wps_fail_event(wps->wps, WPS_M3, wps->config_error,
2906 wps->error_indication, wps->mac_addr_e);
2909 if (wps_validate_m5(msg) < 0)
2911 ret = wps_process_m5(wps, msg, &attr);
2912 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
2913 wps_fail_event(wps->wps, WPS_M5, wps->config_error,
2914 wps->error_indication, wps->mac_addr_e);
2917 if (wps_validate_m7(msg) < 0)
2919 ret = wps_process_m7(wps, msg, &attr);
2920 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
2921 wps_fail_event(wps->wps, WPS_M7, wps->config_error,
2922 wps->error_indication, wps->mac_addr_e);
2925 wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
2930 if (ret == WPS_CONTINUE) {
2931 /* Save a copy of the last message for Authenticator derivation
2933 wpabuf_free(wps->last_msg);
2934 wps->last_msg = wpabuf_dup(msg);
2941 static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
2942 const struct wpabuf *msg)
2944 struct wps_parse_attr attr;
2946 wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
2948 if (wps_parse_msg(msg, &attr) < 0)
2951 if (attr.msg_type == NULL) {
2952 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2956 if (*attr.msg_type != WPS_WSC_ACK) {
2957 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
2962 #ifdef CONFIG_WPS_UPNP
2963 if (wps->wps->wps_upnp && wps->ext_reg && wps->state == RECV_M2D_ACK &&
2964 upnp_wps_subscribers(wps->wps->wps_upnp)) {
2965 if (wps->wps->upnp_msgs)
2966 return WPS_CONTINUE;
2967 wpa_printf(MSG_DEBUG, "WPS: Wait for response from an "
2968 "external Registrar");
2971 #endif /* CONFIG_WPS_UPNP */
2973 if (attr.registrar_nonce == NULL ||
2974 os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
2976 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2980 if (attr.enrollee_nonce == NULL ||
2981 os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
2982 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
2986 if (wps->state == RECV_M2D_ACK) {
2987 #ifdef CONFIG_WPS_UPNP
2988 if (wps->wps->wps_upnp &&
2989 upnp_wps_subscribers(wps->wps->wps_upnp)) {
2990 if (wps->wps->upnp_msgs)
2991 return WPS_CONTINUE;
2992 if (wps->ext_reg == 0)
2994 wpa_printf(MSG_DEBUG, "WPS: Wait for response from an "
2995 "external Registrar");
2998 #endif /* CONFIG_WPS_UPNP */
3000 wpa_printf(MSG_DEBUG, "WPS: No more registrars available - "
3001 "terminate negotiation");
3008 static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
3009 const struct wpabuf *msg)
3011 struct wps_parse_attr attr;
3015 wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
3017 old_state = wps->state;
3018 wps->state = SEND_WSC_NACK;
3020 if (wps_parse_msg(msg, &attr) < 0)
3023 if (attr.msg_type == NULL) {
3024 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
3028 if (*attr.msg_type != WPS_WSC_NACK) {
3029 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
3034 #ifdef CONFIG_WPS_UPNP
3035 if (wps->wps->wps_upnp && wps->ext_reg) {
3036 wpa_printf(MSG_DEBUG, "WPS: Negotiation using external "
3037 "Registrar terminated by the Enrollee");
3040 #endif /* CONFIG_WPS_UPNP */
3042 if (attr.registrar_nonce == NULL ||
3043 os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
3045 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
3049 if (attr.enrollee_nonce == NULL ||
3050 os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
3051 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
3055 if (attr.config_error == NULL) {
3056 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
3061 config_error = WPA_GET_BE16(attr.config_error);
3062 wpa_printf(MSG_DEBUG, "WPS: Enrollee terminated negotiation with "
3063 "Configuration Error %d", config_error);
3065 switch (old_state) {
3067 wps_fail_event(wps->wps, WPS_M2, config_error,
3068 wps->error_indication, wps->mac_addr_e);
3071 wps_fail_event(wps->wps, WPS_M4, config_error,
3072 wps->error_indication, wps->mac_addr_e);
3075 wps_fail_event(wps->wps, WPS_M6, config_error,
3076 wps->error_indication, wps->mac_addr_e);
3079 wps_fail_event(wps->wps, WPS_M8, config_error,
3080 wps->error_indication, wps->mac_addr_e);
3090 static enum wps_process_res wps_process_wsc_done(struct wps_data *wps,
3091 const struct wpabuf *msg)
3093 struct wps_parse_attr attr;
3095 wpa_printf(MSG_DEBUG, "WPS: Received WSC_Done");
3097 if (wps->state != RECV_DONE &&
3098 (!wps->wps->wps_upnp || !wps->ext_reg)) {
3099 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
3100 "receiving WSC_Done", wps->state);
3104 if (wps_parse_msg(msg, &attr) < 0)
3107 if (attr.msg_type == NULL) {
3108 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
3112 if (*attr.msg_type != WPS_WSC_DONE) {
3113 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
3118 #ifdef CONFIG_WPS_UPNP
3119 if (wps->wps->wps_upnp && wps->ext_reg) {
3120 wpa_printf(MSG_DEBUG, "WPS: Negotiation using external "
3121 "Registrar completed successfully");
3122 wps_device_store(wps->wps->registrar, &wps->peer_dev,
3126 #endif /* CONFIG_WPS_UPNP */
3128 if (attr.registrar_nonce == NULL ||
3129 os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
3131 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
3135 if (attr.enrollee_nonce == NULL ||
3136 os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
3137 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
3141 wpa_printf(MSG_DEBUG, "WPS: Negotiation completed successfully");
3142 wps_device_store(wps->wps->registrar, &wps->peer_dev,
3145 if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->new_psk &&
3146 wps->wps->ap && !wps->wps->registrar->disable_auto_conf) {
3147 struct wps_credential cred;
3149 wpa_printf(MSG_DEBUG, "WPS: Moving to Configured state based "
3150 "on first Enrollee connection");
3152 os_memset(&cred, 0, sizeof(cred));
3153 os_memcpy(cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
3154 cred.ssid_len = wps->wps->ssid_len;
3155 cred.auth_type = WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK;
3156 cred.encr_type = WPS_ENCR_TKIP | WPS_ENCR_AES;
3157 os_memcpy(cred.key, wps->new_psk, wps->new_psk_len);
3158 cred.key_len = wps->new_psk_len;
3160 wps->wps->wps_state = WPS_STATE_CONFIGURED;
3161 wpa_hexdump_ascii_key(MSG_DEBUG,
3162 "WPS: Generated random passphrase",
3163 wps->new_psk, wps->new_psk_len);
3164 if (wps->wps->cred_cb)
3165 wps->wps->cred_cb(wps->wps->cb_ctx, &cred);
3167 os_free(wps->new_psk);
3168 wps->new_psk = NULL;
3171 if (!wps->wps->ap && !wps->er)
3172 wps_sta_cred_cb(wps);
3175 if (wps_cb_new_psk(wps->wps->registrar, wps->mac_addr_e,
3176 wps->p2p_dev_addr, wps->new_psk,
3177 wps->new_psk_len)) {
3178 wpa_printf(MSG_DEBUG, "WPS: Failed to configure the "
3181 os_free(wps->new_psk);
3182 wps->new_psk = NULL;
3185 wps_cb_reg_success(wps->wps->registrar, wps->mac_addr_e, wps->uuid_e,
3186 wps->dev_password, wps->dev_password_len);
3189 wps_registrar_remove_pbc_session(wps->wps->registrar,
3192 wps_registrar_pbc_completed(wps->wps->registrar);
3193 os_get_time(&wps->wps->registrar->pbc_ignore_start);
3194 os_memcpy(wps->wps->registrar->pbc_ignore_uuid, wps->uuid_e,
3197 wps_registrar_pin_completed(wps->wps->registrar);
3199 /* TODO: maintain AuthorizedMACs somewhere separately for each ER and
3200 * merge them into APs own list.. */
3202 wps_success_event(wps->wps, wps->mac_addr_e);
3208 enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
3209 enum wsc_op_code op_code,
3210 const struct wpabuf *msg)
3212 enum wps_process_res ret;
3214 wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
3216 (unsigned long) wpabuf_len(msg), op_code);
3218 #ifdef CONFIG_WPS_UPNP
3219 if (wps->wps->wps_upnp && op_code == WSC_MSG && wps->ext_reg == 1) {
3220 struct wps_parse_attr attr;
3221 if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type &&
3222 *attr.msg_type == WPS_M3)
3223 wps->ext_reg = 2; /* past M2/M2D phase */
3225 if (wps->ext_reg > 1)
3226 wps_registrar_free_pending_m2(wps->wps);
3227 if (wps->wps->wps_upnp && wps->ext_reg &&
3228 wps->wps->upnp_msgs == NULL &&
3229 (op_code == WSC_MSG || op_code == WSC_Done || op_code == WSC_NACK))
3231 struct wps_parse_attr attr;
3233 if (wps_parse_msg(msg, &attr) < 0 || attr.msg_type == NULL)
3236 type = *attr.msg_type;
3237 wpa_printf(MSG_DEBUG, "WPS: Sending received message (type %d)"
3238 " to external Registrar for processing", type);
3239 upnp_wps_device_send_wlan_event(wps->wps->wps_upnp,
3241 UPNP_WPS_WLANEVENT_TYPE_EAP,
3243 if (op_code == WSC_MSG)
3245 } else if (wps->wps->wps_upnp && wps->ext_reg && op_code == WSC_MSG) {
3246 wpa_printf(MSG_DEBUG, "WPS: Skip internal processing - using "
3247 "external Registrar");
3248 return WPS_CONTINUE;
3250 #endif /* CONFIG_WPS_UPNP */
3254 return wps_process_wsc_msg(wps, msg);
3256 if (wps_validate_wsc_ack(msg) < 0)
3258 return wps_process_wsc_ack(wps, msg);
3260 if (wps_validate_wsc_nack(msg) < 0)
3262 return wps_process_wsc_nack(wps, msg);
3264 if (wps_validate_wsc_done(msg) < 0)
3266 ret = wps_process_wsc_done(wps, msg);
3267 if (ret == WPS_FAILURE) {
3268 wps->state = SEND_WSC_NACK;
3269 wps_fail_event(wps->wps, WPS_WSC_DONE,
3271 wps->error_indication, wps->mac_addr_e);
3275 wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
3281 int wps_registrar_update_ie(struct wps_registrar *reg)
3283 return wps_set_ie(reg);
3287 static void wps_registrar_set_selected_timeout(void *eloop_ctx,
3290 struct wps_registrar *reg = eloop_ctx;
3292 wpa_printf(MSG_DEBUG, "WPS: Selected Registrar timeout - "
3293 "unselect internal Registrar");
3294 reg->selected_registrar = 0;
3296 wps_registrar_selected_registrar_changed(reg, 0);
3300 #ifdef CONFIG_WPS_UPNP
3301 static void wps_registrar_sel_reg_add(struct wps_registrar *reg,
3302 struct subscription *s)
3305 wpa_printf(MSG_DEBUG, "WPS: External Registrar selected (dev_pw_id=%d "
3306 "config_methods=0x%x)",
3307 s->dev_password_id, s->config_methods);
3308 reg->sel_reg_union = 1;
3309 if (reg->sel_reg_dev_password_id_override != DEV_PW_PUSHBUTTON)
3310 reg->sel_reg_dev_password_id_override = s->dev_password_id;
3311 if (reg->sel_reg_config_methods_override == -1)
3312 reg->sel_reg_config_methods_override = 0;
3313 reg->sel_reg_config_methods_override |= s->config_methods;
3314 for (i = 0; i < WPS_MAX_AUTHORIZED_MACS; i++)
3315 if (is_zero_ether_addr(reg->authorized_macs_union[i]))
3317 for (j = 0; i < WPS_MAX_AUTHORIZED_MACS && j < WPS_MAX_AUTHORIZED_MACS;
3319 if (is_zero_ether_addr(s->authorized_macs[j]))
3321 wpa_printf(MSG_DEBUG, "WPS: Add authorized MAC into union: "
3322 MACSTR, MAC2STR(s->authorized_macs[j]));
3323 os_memcpy(reg->authorized_macs_union[i],
3324 s->authorized_macs[j], ETH_ALEN);
3327 wpa_hexdump(MSG_DEBUG, "WPS: Authorized MACs union",
3328 (u8 *) reg->authorized_macs_union,
3329 sizeof(reg->authorized_macs_union));
3331 #endif /* CONFIG_WPS_UPNP */
3334 static void wps_registrar_sel_reg_union(struct wps_registrar *reg)
3336 #ifdef CONFIG_WPS_UPNP
3337 struct subscription *s;
3339 if (reg->wps->wps_upnp == NULL)
3342 dl_list_for_each(s, ®->wps->wps_upnp->subscriptions,
3343 struct subscription, list) {
3344 struct subscr_addr *sa;
3345 sa = dl_list_first(&s->addr_list, struct subscr_addr, list);
3347 wpa_printf(MSG_DEBUG, "WPS: External Registrar %s:%d",
3348 inet_ntoa(sa->saddr.sin_addr),
3349 ntohs(sa->saddr.sin_port));
3351 if (s->selected_registrar)
3352 wps_registrar_sel_reg_add(reg, s);
3354 wpa_printf(MSG_DEBUG, "WPS: External Registrar not "
3357 #endif /* CONFIG_WPS_UPNP */
3362 * wps_registrar_selected_registrar_changed - SetSelectedRegistrar change
3363 * @reg: Registrar data from wps_registrar_init()
3365 * This function is called when selected registrar state changes, e.g., when an
3366 * AP receives a SetSelectedRegistrar UPnP message.
3368 void wps_registrar_selected_registrar_changed(struct wps_registrar *reg,
3371 wpa_printf(MSG_DEBUG, "WPS: Selected registrar information changed");
3373 reg->sel_reg_union = reg->selected_registrar;
3374 reg->sel_reg_dev_password_id_override = -1;
3375 reg->sel_reg_config_methods_override = -1;
3376 os_memcpy(reg->authorized_macs_union, reg->authorized_macs,
3377 WPS_MAX_AUTHORIZED_MACS * ETH_ALEN);
3378 wpa_hexdump(MSG_DEBUG, "WPS: Authorized MACs union (start with own)",
3379 (u8 *) reg->authorized_macs_union,
3380 sizeof(reg->authorized_macs_union));
3381 if (reg->selected_registrar) {
3384 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
3386 methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |
3387 WPS_CONFIG_PHY_PUSHBUTTON);
3388 #endif /* CONFIG_WPS2 */
3390 reg->sel_reg_dev_password_id_override =
3392 wps_set_pushbutton(&methods, reg->wps->config_methods);
3393 } else if (dev_pw_id)
3394 reg->sel_reg_dev_password_id_override = dev_pw_id;
3395 wpa_printf(MSG_DEBUG, "WPS: Internal Registrar selected "
3396 "(pbc=%d)", reg->pbc);
3397 reg->sel_reg_config_methods_override = methods;
3399 wpa_printf(MSG_DEBUG, "WPS: Internal Registrar not selected");
3401 wps_registrar_sel_reg_union(reg);
3404 wps_cb_set_sel_reg(reg);
3408 int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr,
3409 char *buf, size_t buflen)
3411 struct wps_registrar_device *d;
3414 char devtype[WPS_DEV_TYPE_BUFSIZE];
3416 d = wps_device_get(reg, addr);
3419 if (uuid_bin2str(d->uuid, uuid, sizeof(uuid)))
3422 ret = os_snprintf(buf + len, buflen - len,
3424 "wpsPrimaryDeviceType=%s\n"
3425 "wpsDeviceName=%s\n"
3426 "wpsManufacturer=%s\n"
3428 "wpsModelNumber=%s\n"
3429 "wpsSerialNumber=%s\n",
3431 wps_dev_type_bin2str(d->dev.pri_dev_type, devtype,
3433 d->dev.device_name ? d->dev.device_name : "",
3434 d->dev.manufacturer ? d->dev.manufacturer : "",
3435 d->dev.model_name ? d->dev.model_name : "",
3436 d->dev.model_number ? d->dev.model_number : "",
3437 d->dev.serial_number ? d->dev.serial_number : "");
3438 if (ret < 0 || (size_t) ret >= buflen - len)
3446 int wps_registrar_config_ap(struct wps_registrar *reg,
3447 struct wps_credential *cred)
3450 printf("encr_type=0x%x\n", cred->encr_type);
3451 if (!(cred->encr_type & (WPS_ENCR_NONE | WPS_ENCR_TKIP |
3453 if (cred->encr_type & WPS_ENCR_WEP) {
3454 wpa_printf(MSG_INFO, "WPS: Reject new AP settings "
3455 "due to WEP configuration");
3459 wpa_printf(MSG_INFO, "WPS: Reject new AP settings due to "
3460 "invalid encr_type 0x%x", cred->encr_type);
3464 if ((cred->encr_type & (WPS_ENCR_TKIP | WPS_ENCR_AES)) ==
3466 wpa_printf(MSG_DEBUG, "WPS: Upgrade encr_type TKIP -> "
3468 cred->encr_type |= WPS_ENCR_AES;
3471 if ((cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) ==
3473 wpa_printf(MSG_DEBUG, "WPS: Upgrade auth_type WPAPSK -> "
3475 cred->auth_type |= WPS_AUTH_WPA2PSK;
3477 #endif /* CONFIG_WPS2 */
3479 if (reg->wps->cred_cb)
3480 return reg->wps->cred_cb(reg->wps->cb_ctx, cred);
3486 #ifdef CONFIG_WPS_NFC
3488 int wps_registrar_add_nfc_pw_token(struct wps_registrar *reg,
3489 const u8 *pubkey_hash, u16 pw_id,
3490 const u8 *dev_pw, size_t dev_pw_len)
3492 struct wps_nfc_pw_token *token;
3494 if (dev_pw_len > WPS_OOB_DEVICE_PASSWORD_LEN)
3497 wps_free_nfc_pw_tokens(®->nfc_pw_tokens, pw_id);
3499 token = os_zalloc(sizeof(*token));
3503 os_memcpy(token->pubkey_hash, pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN);
3504 token->pw_id = pw_id;
3505 wpa_snprintf_hex_uppercase((char *) token->dev_pw,
3506 sizeof(token->dev_pw),
3507 dev_pw, dev_pw_len);
3508 token->dev_pw_len = dev_pw_len * 2;
3510 dl_list_add(®->nfc_pw_tokens, &token->list);
3512 reg->selected_registrar = 1;
3514 wps_registrar_add_authorized_mac(reg,
3515 (u8 *) "\xff\xff\xff\xff\xff\xff");
3516 wps_registrar_selected_registrar_changed(reg, pw_id);
3517 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
3518 eloop_register_timeout(WPS_PBC_WALK_TIME, 0,
3519 wps_registrar_set_selected_timeout,
3522 wpa_printf(MSG_DEBUG, "WPS: Added NFC Device Password %u to Registrar",
3529 int wps_registrar_add_nfc_password_token(struct wps_registrar *reg,
3530 const u8 *oob_dev_pw,
3531 size_t oob_dev_pw_len)
3533 const u8 *pos, *hash, *dev_pw;
3537 if (oob_dev_pw_len < WPS_OOB_PUBKEY_HASH_LEN + 2 +
3538 WPS_OOB_DEVICE_PASSWORD_MIN_LEN ||
3539 oob_dev_pw_len > WPS_OOB_PUBKEY_HASH_LEN + 2 +
3540 WPS_OOB_DEVICE_PASSWORD_LEN)
3544 pos = oob_dev_pw + WPS_OOB_PUBKEY_HASH_LEN;
3545 id = WPA_GET_BE16(pos);
3547 dev_pw_len = oob_dev_pw + oob_dev_pw_len - dev_pw;
3549 wpa_printf(MSG_DEBUG, "WPS: Add NFC Password Token for Password ID %u",
3552 wpa_hexdump(MSG_DEBUG, "WPS: Public Key Hash",
3553 hash, WPS_OOB_PUBKEY_HASH_LEN);
3554 wpa_hexdump_key(MSG_DEBUG, "WPS: Device Password", dev_pw, dev_pw_len);
3556 return wps_registrar_add_nfc_pw_token(reg, hash, id, dev_pw,
3561 void wps_registrar_remove_nfc_pw_token(struct wps_registrar *reg,
3562 struct wps_nfc_pw_token *token)
3564 wps_registrar_remove_authorized_mac(reg,
3565 (u8 *) "\xff\xff\xff\xff\xff\xff");
3566 wps_registrar_selected_registrar_changed(reg, 0);
3569 #endif /* CONFIG_WPS_NFC */