2 * Wi-Fi Protected Setup - Registrar
3 * Copyright (c) 2008-2009, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
20 #include "ieee802_11_defs.h"
23 #include "wps_dev_attr.h"
28 #define WPS_WORKAROUNDS
31 struct wps_uuid_pin *next;
32 u8 uuid[WPS_UUID_LEN];
36 #define PIN_LOCKED BIT(0)
37 #define PIN_EXPIRES BIT(1)
39 struct os_time expiration;
43 static void wps_free_pin(struct wps_uuid_pin *pin)
50 static void wps_free_pins(struct wps_uuid_pin *pins)
52 struct wps_uuid_pin *pin, *prev;
63 struct wps_pbc_session {
64 struct wps_pbc_session *next;
66 u8 uuid_e[WPS_UUID_LEN];
67 struct os_time timestamp;
71 static void wps_free_pbc_sessions(struct wps_pbc_session *pbc)
73 struct wps_pbc_session *prev;
83 struct wps_registrar_device {
84 struct wps_registrar_device *next;
85 struct wps_device_data dev;
86 u8 uuid[WPS_UUID_LEN];
90 struct wps_registrar {
91 struct wps_context *wps;
94 int selected_registrar;
96 int (*new_psk_cb)(void *ctx, const u8 *mac_addr, const u8 *psk,
98 int (*set_ie_cb)(void *ctx, const u8 *beacon_ie, size_t beacon_ie_len,
99 const u8 *probe_resp_ie, size_t probe_resp_ie_len);
100 void (*pin_needed_cb)(void *ctx, const u8 *uuid_e,
101 const struct wps_device_data *dev);
102 void (*reg_success_cb)(void *ctx, const u8 *mac_addr,
106 struct wps_uuid_pin *pins;
107 struct wps_pbc_session *pbc_sessions;
110 struct wpabuf *extra_cred;
111 int disable_auto_conf;
112 int sel_reg_dev_password_id_override;
113 int sel_reg_config_methods_override;
116 struct wps_registrar_device *devices;
118 int force_pbc_overlap;
122 static int wps_set_ie(struct wps_registrar *reg);
123 static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx);
124 static void wps_registrar_set_selected_timeout(void *eloop_ctx,
128 static void wps_free_devices(struct wps_registrar_device *dev)
130 struct wps_registrar_device *prev;
135 wps_device_data_free(&prev->dev);
141 static struct wps_registrar_device * wps_device_get(struct wps_registrar *reg,
144 struct wps_registrar_device *dev;
146 for (dev = reg->devices; dev; dev = dev->next) {
147 if (os_memcmp(dev->dev.mac_addr, addr, ETH_ALEN) == 0)
154 static void wps_device_clone_data(struct wps_device_data *dst,
155 struct wps_device_data *src)
157 os_memcpy(dst->mac_addr, src->mac_addr, ETH_ALEN);
158 dst->categ = src->categ;
160 dst->sub_categ = src->sub_categ;
162 #define WPS_STRDUP(n) \
164 dst->n = src->n ? os_strdup(src->n) : NULL
166 WPS_STRDUP(device_name);
167 WPS_STRDUP(manufacturer);
168 WPS_STRDUP(model_name);
169 WPS_STRDUP(model_number);
170 WPS_STRDUP(serial_number);
175 int wps_device_store(struct wps_registrar *reg,
176 struct wps_device_data *dev, const u8 *uuid)
178 struct wps_registrar_device *d;
180 d = wps_device_get(reg, dev->mac_addr);
182 d = os_zalloc(sizeof(*d));
185 d->next = reg->devices;
189 wps_device_clone_data(&d->dev, dev);
190 os_memcpy(d->uuid, uuid, WPS_UUID_LEN);
196 static void wps_registrar_add_pbc_session(struct wps_registrar *reg,
197 const u8 *addr, const u8 *uuid_e)
199 struct wps_pbc_session *pbc, *prev = NULL;
204 pbc = reg->pbc_sessions;
206 if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&
207 os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {
209 prev->next = pbc->next;
211 reg->pbc_sessions = pbc->next;
219 pbc = os_zalloc(sizeof(*pbc));
222 os_memcpy(pbc->addr, addr, ETH_ALEN);
224 os_memcpy(pbc->uuid_e, uuid_e, WPS_UUID_LEN);
227 pbc->next = reg->pbc_sessions;
228 reg->pbc_sessions = pbc;
229 pbc->timestamp = now;
231 /* remove entries that have timed out */
236 if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME) {
238 wps_free_pbc_sessions(pbc);
247 static void wps_registrar_remove_pbc_session(struct wps_registrar *reg,
248 const u8 *addr, const u8 *uuid_e)
250 struct wps_pbc_session *pbc, *prev = NULL;
252 pbc = reg->pbc_sessions;
254 if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&
255 os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {
257 prev->next = pbc->next;
259 reg->pbc_sessions = pbc->next;
269 static int wps_registrar_pbc_overlap(struct wps_registrar *reg,
270 const u8 *addr, const u8 *uuid_e)
273 struct wps_pbc_session *pbc;
278 for (pbc = reg->pbc_sessions; pbc; pbc = pbc->next) {
279 if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME)
281 if (addr == NULL || os_memcmp(addr, pbc->addr, ETH_ALEN) ||
283 os_memcmp(uuid_e, pbc->uuid_e, WPS_UUID_LEN))
290 return count > 1 ? 1 : 0;
294 static int wps_build_wps_state(struct wps_context *wps, struct wpabuf *msg)
296 wpa_printf(MSG_DEBUG, "WPS: * Wi-Fi Protected Setup State (%d)",
298 wpabuf_put_be16(msg, ATTR_WPS_STATE);
299 wpabuf_put_be16(msg, 1);
300 wpabuf_put_u8(msg, wps->wps_state);
305 #ifdef CONFIG_WPS_UPNP
306 static void wps_registrar_free_pending_m2(struct wps_context *wps)
308 struct upnp_pending_message *p, *p2, *prev = NULL;
311 if (p->type == WPS_M2 || p->type == WPS_M2D) {
313 wps->upnp_msgs = p->next;
315 prev->next = p->next;
316 wpa_printf(MSG_DEBUG, "WPS UPnP: Drop pending M2/M2D");
319 wpabuf_free(p2->msg);
327 #endif /* CONFIG_WPS_UPNP */
330 static int wps_build_ap_setup_locked(struct wps_context *wps,
333 if (wps->ap_setup_locked) {
334 wpa_printf(MSG_DEBUG, "WPS: * AP Setup Locked");
335 wpabuf_put_be16(msg, ATTR_AP_SETUP_LOCKED);
336 wpabuf_put_be16(msg, 1);
337 wpabuf_put_u8(msg, 1);
343 static int wps_build_selected_registrar(struct wps_registrar *reg,
346 if (!reg->selected_registrar)
348 wpa_printf(MSG_DEBUG, "WPS: * Selected Registrar");
349 wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR);
350 wpabuf_put_be16(msg, 1);
351 wpabuf_put_u8(msg, 1);
356 static int wps_build_sel_reg_dev_password_id(struct wps_registrar *reg,
359 u16 id = reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT;
360 if (!reg->selected_registrar)
362 if (reg->sel_reg_dev_password_id_override >= 0)
363 id = reg->sel_reg_dev_password_id_override;
364 wpa_printf(MSG_DEBUG, "WPS: * Device Password ID (%d)", id);
365 wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
366 wpabuf_put_be16(msg, 2);
367 wpabuf_put_be16(msg, id);
372 static int wps_build_sel_reg_config_methods(struct wps_registrar *reg,
376 if (!reg->selected_registrar)
378 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
380 methods |= WPS_CONFIG_PUSHBUTTON;
381 if (reg->sel_reg_config_methods_override >= 0)
382 methods = reg->sel_reg_config_methods_override;
383 wpa_printf(MSG_DEBUG, "WPS: * Selected Registrar Config Methods (%x)",
385 wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS);
386 wpabuf_put_be16(msg, 2);
387 wpabuf_put_be16(msg, methods);
392 static int wps_build_probe_config_methods(struct wps_registrar *reg,
397 wpa_printf(MSG_DEBUG, "WPS: * Config Methods (%x)", methods);
398 wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
399 wpabuf_put_be16(msg, 2);
400 wpabuf_put_be16(msg, methods);
405 static int wps_build_config_methods_r(struct wps_registrar *reg,
409 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
411 methods |= WPS_CONFIG_PUSHBUTTON;
412 return wps_build_config_methods(msg, methods);
416 static int wps_build_resp_type(struct wps_registrar *reg, struct wpabuf *msg)
418 u8 resp = reg->wps->ap ? WPS_RESP_AP : WPS_RESP_REGISTRAR;
419 wpa_printf(MSG_DEBUG, "WPS: * Response Type (%d)", resp);
420 wpabuf_put_be16(msg, ATTR_RESPONSE_TYPE);
421 wpabuf_put_be16(msg, 1);
422 wpabuf_put_u8(msg, resp);
428 * wps_registrar_init - Initialize WPS Registrar data
429 * @wps: Pointer to longterm WPS context
430 * @cfg: Registrar configuration
431 * Returns: Pointer to allocated Registrar data or %NULL on failure
433 * This function is used to initialize WPS Registrar functionality. It can be
434 * used for a single Registrar run (e.g., when run in a supplicant) or multiple
435 * runs (e.g., when run as an internal Registrar in an AP). Caller is
436 * responsible for freeing the returned data with wps_registrar_deinit() when
437 * Registrar functionality is not needed anymore.
439 struct wps_registrar *
440 wps_registrar_init(struct wps_context *wps,
441 const struct wps_registrar_config *cfg)
443 struct wps_registrar *reg = os_zalloc(sizeof(*reg));
448 reg->new_psk_cb = cfg->new_psk_cb;
449 reg->set_ie_cb = cfg->set_ie_cb;
450 reg->pin_needed_cb = cfg->pin_needed_cb;
451 reg->reg_success_cb = cfg->reg_success_cb;
452 reg->cb_ctx = cfg->cb_ctx;
453 reg->skip_cred_build = cfg->skip_cred_build;
454 if (cfg->extra_cred) {
455 reg->extra_cred = wpabuf_alloc_copy(cfg->extra_cred,
456 cfg->extra_cred_len);
457 if (reg->extra_cred == NULL) {
462 reg->disable_auto_conf = cfg->disable_auto_conf;
463 reg->sel_reg_dev_password_id_override = -1;
464 reg->sel_reg_config_methods_override = -1;
465 reg->static_wep_only = cfg->static_wep_only;
467 if (wps_set_ie(reg)) {
468 wps_registrar_deinit(reg);
477 * wps_registrar_deinit - Deinitialize WPS Registrar data
478 * @reg: Registrar data from wps_registrar_init()
480 void wps_registrar_deinit(struct wps_registrar *reg)
484 eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
485 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
486 wps_free_pins(reg->pins);
487 wps_free_pbc_sessions(reg->pbc_sessions);
488 wpabuf_free(reg->extra_cred);
489 wps_free_devices(reg->devices);
495 * wps_registrar_add_pin - Configure a new PIN for Registrar
496 * @reg: Registrar data from wps_registrar_init()
497 * @uuid: UUID-E or %NULL for wildcard (any UUID)
498 * @pin: PIN (Device Password)
499 * @pin_len: Length of pin in octets
500 * @timeout: Time (in seconds) when the PIN will be invalidated; 0 = no timeout
501 * Returns: 0 on success, -1 on failure
503 int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *uuid,
504 const u8 *pin, size_t pin_len, int timeout)
506 struct wps_uuid_pin *p;
508 p = os_zalloc(sizeof(*p));
512 p->wildcard_uuid = 1;
514 os_memcpy(p->uuid, uuid, WPS_UUID_LEN);
515 p->pin = os_malloc(pin_len);
516 if (p->pin == NULL) {
520 os_memcpy(p->pin, pin, pin_len);
521 p->pin_len = pin_len;
524 p->flags |= PIN_EXPIRES;
525 os_get_time(&p->expiration);
526 p->expiration.sec += timeout;
532 wpa_printf(MSG_DEBUG, "WPS: A new PIN configured (timeout=%d)",
534 wpa_hexdump(MSG_DEBUG, "WPS: UUID", uuid, WPS_UUID_LEN);
535 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: PIN", pin, pin_len);
536 reg->selected_registrar = 1;
539 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
540 eloop_register_timeout(WPS_PBC_WALK_TIME, 0,
541 wps_registrar_set_selected_timeout,
548 static void wps_registrar_expire_pins(struct wps_registrar *reg)
550 struct wps_uuid_pin *pin, *prev, *del;
557 if ((pin->flags & PIN_EXPIRES) &&
558 os_time_before(&pin->expiration, &now)) {
560 reg->pins = pin->next;
562 prev->next = pin->next;
565 wpa_hexdump(MSG_DEBUG, "WPS: Expired PIN for UUID",
566 del->uuid, WPS_UUID_LEN);
577 * wps_registrar_invalidate_pin - Invalidate a PIN for a specific UUID-E
578 * @reg: Registrar data from wps_registrar_init()
580 * Returns: 0 on success, -1 on failure (e.g., PIN not found)
582 int wps_registrar_invalidate_pin(struct wps_registrar *reg, const u8 *uuid)
584 struct wps_uuid_pin *pin, *prev;
589 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
591 reg->pins = pin->next;
593 prev->next = pin->next;
594 wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID",
595 pin->uuid, WPS_UUID_LEN);
607 static const u8 * wps_registrar_get_pin(struct wps_registrar *reg,
608 const u8 *uuid, size_t *pin_len)
610 struct wps_uuid_pin *pin;
612 wps_registrar_expire_pins(reg);
616 if (!pin->wildcard_uuid &&
617 os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0)
623 /* Check for wildcard UUIDs since none of the UUID-specific
627 if (pin->wildcard_uuid == 1) {
628 wpa_printf(MSG_DEBUG, "WPS: Found a wildcard "
629 "PIN. Assigned it for this UUID-E");
630 pin->wildcard_uuid = 2;
631 os_memcpy(pin->uuid, uuid, WPS_UUID_LEN);
642 * Lock the PIN to avoid attacks based on concurrent re-use of the PIN
643 * that could otherwise avoid PIN invalidations.
645 if (pin->flags & PIN_LOCKED) {
646 wpa_printf(MSG_DEBUG, "WPS: Selected PIN locked - do not "
647 "allow concurrent re-use");
650 *pin_len = pin->pin_len;
651 pin->flags |= PIN_LOCKED;
657 * wps_registrar_unlock_pin - Unlock a PIN for a specific UUID-E
658 * @reg: Registrar data from wps_registrar_init()
660 * Returns: 0 on success, -1 on failure
662 * PINs are locked to enforce only one concurrent use. This function unlocks a
663 * PIN to allow it to be used again. If the specified PIN was configured using
664 * a wildcard UUID, it will be removed instead of allowing multiple uses.
666 int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid)
668 struct wps_uuid_pin *pin;
672 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
673 if (pin->wildcard_uuid == 2) {
674 wpa_printf(MSG_DEBUG, "WPS: Invalidating used "
676 return wps_registrar_invalidate_pin(reg, uuid);
678 pin->flags &= ~PIN_LOCKED;
688 static void wps_registrar_stop_pbc(struct wps_registrar *reg)
690 reg->selected_registrar = 0;
696 static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx)
698 struct wps_registrar *reg = eloop_ctx;
700 wpa_printf(MSG_DEBUG, "WPS: PBC timed out - disable PBC mode");
701 wps_pbc_timeout_event(reg->wps);
702 wps_registrar_stop_pbc(reg);
707 * wps_registrar_button_pushed - Notify Registrar that AP button was pushed
708 * @reg: Registrar data from wps_registrar_init()
709 * Returns: 0 on success, -1 on failure
711 * This function is called on an AP when a push button is pushed to activate
712 * PBC mode. The PBC mode will be stopped after walk time (2 minutes) timeout
713 * or when a PBC registration is completed.
715 int wps_registrar_button_pushed(struct wps_registrar *reg)
717 if (wps_registrar_pbc_overlap(reg, NULL, NULL)) {
718 wpa_printf(MSG_DEBUG, "WPS: PBC overlap - do not start PBC "
720 wps_pbc_overlap_event(reg->wps);
723 wpa_printf(MSG_DEBUG, "WPS: Button pushed - PBC mode started");
724 reg->force_pbc_overlap = 0;
725 reg->selected_registrar = 1;
729 eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
730 eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wps_registrar_pbc_timeout,
736 static void wps_registrar_pbc_completed(struct wps_registrar *reg)
738 wpa_printf(MSG_DEBUG, "WPS: PBC completed - stopping PBC mode");
739 eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
740 wps_registrar_stop_pbc(reg);
743 static void wps_registrar_pin_completed(struct wps_registrar *reg)
745 wpa_printf(MSG_DEBUG, "WPS: PIN completed using internal Registrar");
746 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
747 reg->selected_registrar = 0;
753 * wps_registrar_probe_req_rx - Notify Registrar of Probe Request
754 * @reg: Registrar data from wps_registrar_init()
755 * @addr: MAC address of the Probe Request sender
756 * @wps_data: WPS IE contents
758 * This function is called on an AP when a Probe Request with WPS IE is
759 * received. This is used to track PBC mode use and to detect possible overlap
760 * situation with other WPS APs.
762 void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
763 const struct wpabuf *wps_data)
765 struct wps_parse_attr attr;
768 wpa_hexdump_buf(MSG_MSGDUMP,
769 "WPS: Probe Request with WPS data received",
772 if (wps_parse_msg(wps_data, &attr) < 0)
774 if (!wps_version_supported(attr.version)) {
775 wpa_printf(MSG_DEBUG, "WPS: Unsupported ProbeReq WPS IE "
776 "version 0x%x", attr.version ? *attr.version : 0);
780 if (attr.config_methods == NULL) {
781 wpa_printf(MSG_DEBUG, "WPS: No Config Methods attribute in "
786 methods = WPA_GET_BE16(attr.config_methods);
787 if (!(methods & WPS_CONFIG_PUSHBUTTON))
788 return; /* Not PBC */
790 wpa_printf(MSG_DEBUG, "WPS: Probe Request for PBC received from "
791 MACSTR, MAC2STR(addr));
793 wps_registrar_add_pbc_session(reg, addr, attr.uuid_e);
794 if (wps_registrar_pbc_overlap(reg, addr, attr.uuid_e)) {
795 wpa_printf(MSG_DEBUG, "WPS: PBC session overlap detected");
796 reg->force_pbc_overlap = 1;
797 wps_pbc_overlap_event(reg->wps);
802 static int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr,
803 const u8 *psk, size_t psk_len)
805 if (reg->new_psk_cb == NULL)
808 return reg->new_psk_cb(reg->cb_ctx, mac_addr, psk, psk_len);
812 static void wps_cb_pin_needed(struct wps_registrar *reg, const u8 *uuid_e,
813 const struct wps_device_data *dev)
815 if (reg->pin_needed_cb == NULL)
818 reg->pin_needed_cb(reg->cb_ctx, uuid_e, dev);
822 static void wps_cb_reg_success(struct wps_registrar *reg, const u8 *mac_addr,
825 if (reg->reg_success_cb == NULL)
828 reg->reg_success_cb(reg->cb_ctx, mac_addr, uuid_e);
832 static int wps_cb_set_ie(struct wps_registrar *reg,
833 const struct wpabuf *beacon_ie,
834 const struct wpabuf *probe_resp_ie)
836 if (reg->set_ie_cb == NULL)
839 return reg->set_ie_cb(reg->cb_ctx, wpabuf_head(beacon_ie),
840 wpabuf_len(beacon_ie),
841 wpabuf_head(probe_resp_ie),
842 wpabuf_len(probe_resp_ie));
846 /* Encapsulate WPS IE data with one (or more, if needed) IE headers */
847 static struct wpabuf * wps_ie_encapsulate(struct wpabuf *data)
852 ie = wpabuf_alloc(wpabuf_len(data) + 100);
858 pos = wpabuf_head(data);
859 end = pos + wpabuf_len(data);
862 size_t frag_len = end - pos;
865 wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
866 wpabuf_put_u8(ie, 4 + frag_len);
867 wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
868 wpabuf_put_data(ie, pos, frag_len);
878 static int wps_set_ie(struct wps_registrar *reg)
880 struct wpabuf *beacon;
881 struct wpabuf *probe;
884 wpa_printf(MSG_DEBUG, "WPS: Build Beacon and Probe Response IEs");
886 beacon = wpabuf_alloc(300);
889 probe = wpabuf_alloc(400);
895 if (wps_build_version(beacon) ||
896 wps_build_wps_state(reg->wps, beacon) ||
897 wps_build_ap_setup_locked(reg->wps, beacon) ||
898 wps_build_selected_registrar(reg, beacon) ||
899 wps_build_sel_reg_dev_password_id(reg, beacon) ||
900 wps_build_sel_reg_config_methods(reg, beacon) ||
901 wps_build_version(probe) ||
902 wps_build_wps_state(reg->wps, probe) ||
903 wps_build_ap_setup_locked(reg->wps, probe) ||
904 wps_build_selected_registrar(reg, probe) ||
905 wps_build_sel_reg_dev_password_id(reg, probe) ||
906 wps_build_sel_reg_config_methods(reg, probe) ||
907 wps_build_resp_type(reg, probe) ||
908 wps_build_uuid_e(probe, reg->wps->uuid) ||
909 wps_build_device_attrs(®->wps->dev, probe) ||
910 wps_build_probe_config_methods(reg, probe) ||
911 wps_build_rf_bands(®->wps->dev, probe)) {
917 beacon = wps_ie_encapsulate(beacon);
918 probe = wps_ie_encapsulate(probe);
920 if (!beacon || !probe) {
926 if (reg->static_wep_only) {
928 * Windows XP and Vista clients can get confused about
929 * EAP-Identity/Request when they probe the network with
930 * EAPOL-Start. In such a case, they may assume the network is
931 * using IEEE 802.1X and prompt user for a certificate while
932 * the correct (non-WPS) behavior would be to ask for the
933 * static WEP key. As a workaround, use Microsoft Provisioning
934 * IE to advertise that legacy 802.1X is not supported.
936 const u8 ms_wps[7] = {
937 WLAN_EID_VENDOR_SPECIFIC, 5,
938 /* Microsoft Provisioning IE (00:50:f2:5) */
940 0x00 /* no legacy 802.1X or MS WPS */
942 wpa_printf(MSG_DEBUG, "WPS: Add Microsoft Provisioning IE "
943 "into Beacon/Probe Response frames");
944 wpabuf_put_data(beacon, ms_wps, sizeof(ms_wps));
945 wpabuf_put_data(probe, ms_wps, sizeof(ms_wps));
948 ret = wps_cb_set_ie(reg, beacon, probe);
956 static int wps_get_dev_password(struct wps_data *wps)
961 os_free(wps->dev_password);
962 wps->dev_password = NULL;
965 wpa_printf(MSG_DEBUG, "WPS: Use default PIN for PBC");
966 pin = (const u8 *) "00000000";
969 pin = wps_registrar_get_pin(wps->wps->registrar, wps->uuid_e,
973 wpa_printf(MSG_DEBUG, "WPS: No Device Password available for "
975 wps_cb_pin_needed(wps->wps->registrar, wps->uuid_e,
980 wps->dev_password = os_malloc(pin_len);
981 if (wps->dev_password == NULL)
983 os_memcpy(wps->dev_password, pin, pin_len);
984 wps->dev_password_len = pin_len;
990 static int wps_build_uuid_r(struct wps_data *wps, struct wpabuf *msg)
992 wpa_printf(MSG_DEBUG, "WPS: * UUID-R");
993 wpabuf_put_be16(msg, ATTR_UUID_R);
994 wpabuf_put_be16(msg, WPS_UUID_LEN);
995 wpabuf_put_data(msg, wps->uuid_r, WPS_UUID_LEN);
1000 static int wps_build_r_hash(struct wps_data *wps, struct wpabuf *msg)
1006 if (os_get_random(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
1008 wpa_hexdump(MSG_DEBUG, "WPS: R-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
1009 wpa_hexdump(MSG_DEBUG, "WPS: R-S2",
1010 wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
1012 if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
1013 wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
1014 "R-Hash derivation");
1018 wpa_printf(MSG_DEBUG, "WPS: * R-Hash1");
1019 wpabuf_put_be16(msg, ATTR_R_HASH1);
1020 wpabuf_put_be16(msg, SHA256_MAC_LEN);
1021 hash = wpabuf_put(msg, SHA256_MAC_LEN);
1022 /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
1023 addr[0] = wps->snonce;
1024 len[0] = WPS_SECRET_NONCE_LEN;
1025 addr[1] = wps->psk1;
1026 len[1] = WPS_PSK_LEN;
1027 addr[2] = wpabuf_head(wps->dh_pubkey_e);
1028 len[2] = wpabuf_len(wps->dh_pubkey_e);
1029 addr[3] = wpabuf_head(wps->dh_pubkey_r);
1030 len[3] = wpabuf_len(wps->dh_pubkey_r);
1031 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
1032 wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", hash, SHA256_MAC_LEN);
1034 wpa_printf(MSG_DEBUG, "WPS: * R-Hash2");
1035 wpabuf_put_be16(msg, ATTR_R_HASH2);
1036 wpabuf_put_be16(msg, SHA256_MAC_LEN);
1037 hash = wpabuf_put(msg, SHA256_MAC_LEN);
1038 /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
1039 addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
1040 addr[1] = wps->psk2;
1041 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
1042 wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", hash, SHA256_MAC_LEN);
1048 static int wps_build_r_snonce1(struct wps_data *wps, struct wpabuf *msg)
1050 wpa_printf(MSG_DEBUG, "WPS: * R-SNonce1");
1051 wpabuf_put_be16(msg, ATTR_R_SNONCE1);
1052 wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
1053 wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
1058 static int wps_build_r_snonce2(struct wps_data *wps, struct wpabuf *msg)
1060 wpa_printf(MSG_DEBUG, "WPS: * R-SNonce2");
1061 wpabuf_put_be16(msg, ATTR_R_SNONCE2);
1062 wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
1063 wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
1064 WPS_SECRET_NONCE_LEN);
1069 static int wps_build_cred_network_idx(struct wpabuf *msg,
1070 struct wps_credential *cred)
1072 wpa_printf(MSG_DEBUG, "WPS: * Network Index");
1073 wpabuf_put_be16(msg, ATTR_NETWORK_INDEX);
1074 wpabuf_put_be16(msg, 1);
1075 wpabuf_put_u8(msg, 1);
1080 static int wps_build_cred_ssid(struct wpabuf *msg,
1081 struct wps_credential *cred)
1083 wpa_printf(MSG_DEBUG, "WPS: * SSID");
1084 wpabuf_put_be16(msg, ATTR_SSID);
1085 wpabuf_put_be16(msg, cred->ssid_len);
1086 wpabuf_put_data(msg, cred->ssid, cred->ssid_len);
1091 static int wps_build_cred_auth_type(struct wpabuf *msg,
1092 struct wps_credential *cred)
1094 wpa_printf(MSG_DEBUG, "WPS: * Authentication Type (0x%x)",
1096 wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
1097 wpabuf_put_be16(msg, 2);
1098 wpabuf_put_be16(msg, cred->auth_type);
1103 static int wps_build_cred_encr_type(struct wpabuf *msg,
1104 struct wps_credential *cred)
1106 wpa_printf(MSG_DEBUG, "WPS: * Encryption Type (0x%x)",
1108 wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
1109 wpabuf_put_be16(msg, 2);
1110 wpabuf_put_be16(msg, cred->encr_type);
1115 static int wps_build_cred_network_key(struct wpabuf *msg,
1116 struct wps_credential *cred)
1118 wpa_printf(MSG_DEBUG, "WPS: * Network Key");
1119 wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
1120 wpabuf_put_be16(msg, cred->key_len);
1121 wpabuf_put_data(msg, cred->key, cred->key_len);
1126 static int wps_build_cred_mac_addr(struct wpabuf *msg,
1127 struct wps_credential *cred)
1129 wpa_printf(MSG_DEBUG, "WPS: * MAC Address (" MACSTR ")",
1130 MAC2STR(cred->mac_addr));
1131 wpabuf_put_be16(msg, ATTR_MAC_ADDR);
1132 wpabuf_put_be16(msg, ETH_ALEN);
1133 wpabuf_put_data(msg, cred->mac_addr, ETH_ALEN);
1138 static int wps_build_credential(struct wpabuf *msg,
1139 struct wps_credential *cred)
1141 if (wps_build_cred_network_idx(msg, cred) ||
1142 wps_build_cred_ssid(msg, cred) ||
1143 wps_build_cred_auth_type(msg, cred) ||
1144 wps_build_cred_encr_type(msg, cred) ||
1145 wps_build_cred_network_key(msg, cred) ||
1146 wps_build_cred_mac_addr(msg, cred))
1152 int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
1154 struct wpabuf *cred;
1156 if (wps->wps->registrar->skip_cred_build)
1157 goto skip_cred_build;
1159 wpa_printf(MSG_DEBUG, "WPS: * Credential");
1160 os_memset(&wps->cred, 0, sizeof(wps->cred));
1162 os_memcpy(wps->cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
1163 wps->cred.ssid_len = wps->wps->ssid_len;
1165 /* Select the best authentication and encryption type */
1166 if (wps->auth_type & WPS_AUTH_WPA2PSK)
1167 wps->auth_type = WPS_AUTH_WPA2PSK;
1168 else if (wps->auth_type & WPS_AUTH_WPAPSK)
1169 wps->auth_type = WPS_AUTH_WPAPSK;
1170 else if (wps->auth_type & WPS_AUTH_OPEN)
1171 wps->auth_type = WPS_AUTH_OPEN;
1172 else if (wps->auth_type & WPS_AUTH_SHARED)
1173 wps->auth_type = WPS_AUTH_SHARED;
1175 wpa_printf(MSG_DEBUG, "WPS: Unsupported auth_type 0x%x",
1179 wps->cred.auth_type = wps->auth_type;
1181 if (wps->auth_type == WPS_AUTH_WPA2PSK ||
1182 wps->auth_type == WPS_AUTH_WPAPSK) {
1183 if (wps->encr_type & WPS_ENCR_AES)
1184 wps->encr_type = WPS_ENCR_AES;
1185 else if (wps->encr_type & WPS_ENCR_TKIP)
1186 wps->encr_type = WPS_ENCR_TKIP;
1188 wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
1189 "type for WPA/WPA2");
1193 if (wps->encr_type & WPS_ENCR_WEP)
1194 wps->encr_type = WPS_ENCR_WEP;
1195 else if (wps->encr_type & WPS_ENCR_NONE)
1196 wps->encr_type = WPS_ENCR_NONE;
1198 wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
1199 "type for non-WPA/WPA2 mode");
1203 wps->cred.encr_type = wps->encr_type;
1204 /* Set MAC address in the Credential to be the AP's address (BSSID) */
1205 os_memcpy(wps->cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN);
1207 if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap &&
1208 !wps->wps->registrar->disable_auto_conf) {
1210 /* Generate a random passphrase */
1211 if (os_get_random(r, sizeof(r)) < 0)
1213 os_free(wps->new_psk);
1214 wps->new_psk = base64_encode(r, sizeof(r), &wps->new_psk_len);
1215 if (wps->new_psk == NULL)
1217 wps->new_psk_len--; /* remove newline */
1218 while (wps->new_psk_len &&
1219 wps->new_psk[wps->new_psk_len - 1] == '=')
1221 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Generated passphrase",
1222 wps->new_psk, wps->new_psk_len);
1223 os_memcpy(wps->cred.key, wps->new_psk, wps->new_psk_len);
1224 wps->cred.key_len = wps->new_psk_len;
1225 } else if (wps->wps->network_key) {
1226 os_memcpy(wps->cred.key, wps->wps->network_key,
1227 wps->wps->network_key_len);
1228 wps->cred.key_len = wps->wps->network_key_len;
1229 } else if (wps->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
1231 /* Generate a random per-device PSK */
1232 os_free(wps->new_psk);
1233 wps->new_psk_len = 32;
1234 wps->new_psk = os_malloc(wps->new_psk_len);
1235 if (wps->new_psk == NULL)
1237 if (os_get_random(wps->new_psk, wps->new_psk_len) < 0) {
1238 os_free(wps->new_psk);
1239 wps->new_psk = NULL;
1242 wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
1243 wps->new_psk, wps->new_psk_len);
1244 wpa_snprintf_hex(hex, sizeof(hex), wps->new_psk,
1246 os_memcpy(wps->cred.key, hex, wps->new_psk_len * 2);
1247 wps->cred.key_len = wps->new_psk_len * 2;
1250 cred = wpabuf_alloc(200);
1254 if (wps_build_credential(cred, &wps->cred)) {
1259 wpabuf_put_be16(msg, ATTR_CRED);
1260 wpabuf_put_be16(msg, wpabuf_len(cred));
1261 wpabuf_put_buf(msg, cred);
1265 if (wps->wps->registrar->extra_cred) {
1266 wpa_printf(MSG_DEBUG, "WPS: * Credential (pre-configured)");
1267 wpabuf_put_buf(msg, wps->wps->registrar->extra_cred);
1274 static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *msg)
1276 wpa_printf(MSG_DEBUG, "WPS: * AP Settings");
1278 if (wps_build_credential(msg, &wps->cred))
1285 static struct wpabuf * wps_build_m2(struct wps_data *wps)
1289 if (os_get_random(wps->nonce_r, WPS_NONCE_LEN) < 0)
1291 wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
1292 wps->nonce_r, WPS_NONCE_LEN);
1293 wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
1295 wpa_printf(MSG_DEBUG, "WPS: Building Message M2");
1296 msg = wpabuf_alloc(1000);
1300 if (wps_build_version(msg) ||
1301 wps_build_msg_type(msg, WPS_M2) ||
1302 wps_build_enrollee_nonce(wps, msg) ||
1303 wps_build_registrar_nonce(wps, msg) ||
1304 wps_build_uuid_r(wps, msg) ||
1305 wps_build_public_key(wps, msg) ||
1306 wps_derive_keys(wps) ||
1307 wps_build_auth_type_flags(wps, msg) ||
1308 wps_build_encr_type_flags(wps, msg) ||
1309 wps_build_conn_type_flags(wps, msg) ||
1310 wps_build_config_methods_r(wps->wps->registrar, msg) ||
1311 wps_build_device_attrs(&wps->wps->dev, msg) ||
1312 wps_build_rf_bands(&wps->wps->dev, msg) ||
1313 wps_build_assoc_state(wps, msg) ||
1314 wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
1315 wps_build_dev_password_id(msg, wps->dev_pw_id) ||
1316 wps_build_os_version(&wps->wps->dev, msg) ||
1317 wps_build_authenticator(wps, msg)) {
1322 wps->state = RECV_M3;
1327 static struct wpabuf * wps_build_m2d(struct wps_data *wps)
1330 u16 err = wps->config_error;
1332 wpa_printf(MSG_DEBUG, "WPS: Building Message M2D");
1333 msg = wpabuf_alloc(1000);
1337 if (wps->wps->ap && wps->wps->ap_setup_locked &&
1338 err == WPS_CFG_NO_ERROR)
1339 err = WPS_CFG_SETUP_LOCKED;
1341 if (wps_build_version(msg) ||
1342 wps_build_msg_type(msg, WPS_M2D) ||
1343 wps_build_enrollee_nonce(wps, msg) ||
1344 wps_build_registrar_nonce(wps, msg) ||
1345 wps_build_uuid_r(wps, msg) ||
1346 wps_build_auth_type_flags(wps, msg) ||
1347 wps_build_encr_type_flags(wps, msg) ||
1348 wps_build_conn_type_flags(wps, msg) ||
1349 wps_build_config_methods_r(wps->wps->registrar, msg) ||
1350 wps_build_device_attrs(&wps->wps->dev, msg) ||
1351 wps_build_rf_bands(&wps->wps->dev, msg) ||
1352 wps_build_assoc_state(wps, msg) ||
1353 wps_build_config_error(msg, err) ||
1354 wps_build_os_version(&wps->wps->dev, msg)) {
1359 wps->state = RECV_M2D_ACK;
1364 static struct wpabuf * wps_build_m4(struct wps_data *wps)
1366 struct wpabuf *msg, *plain;
1368 wpa_printf(MSG_DEBUG, "WPS: Building Message M4");
1370 wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);
1372 plain = wpabuf_alloc(200);
1376 msg = wpabuf_alloc(1000);
1382 if (wps_build_version(msg) ||
1383 wps_build_msg_type(msg, WPS_M4) ||
1384 wps_build_enrollee_nonce(wps, msg) ||
1385 wps_build_r_hash(wps, msg) ||
1386 wps_build_r_snonce1(wps, plain) ||
1387 wps_build_key_wrap_auth(wps, plain) ||
1388 wps_build_encr_settings(wps, msg, plain) ||
1389 wps_build_authenticator(wps, msg)) {
1396 wps->state = RECV_M5;
1401 static struct wpabuf * wps_build_m6(struct wps_data *wps)
1403 struct wpabuf *msg, *plain;
1405 wpa_printf(MSG_DEBUG, "WPS: Building Message M6");
1407 plain = wpabuf_alloc(200);
1411 msg = wpabuf_alloc(1000);
1417 if (wps_build_version(msg) ||
1418 wps_build_msg_type(msg, WPS_M6) ||
1419 wps_build_enrollee_nonce(wps, msg) ||
1420 wps_build_r_snonce2(wps, plain) ||
1421 wps_build_key_wrap_auth(wps, plain) ||
1422 wps_build_encr_settings(wps, msg, plain) ||
1423 wps_build_authenticator(wps, msg)) {
1430 wps->wps_pin_revealed = 1;
1431 wps->state = RECV_M7;
1436 static struct wpabuf * wps_build_m8(struct wps_data *wps)
1438 struct wpabuf *msg, *plain;
1440 wpa_printf(MSG_DEBUG, "WPS: Building Message M8");
1442 plain = wpabuf_alloc(500);
1446 msg = wpabuf_alloc(1000);
1452 if (wps_build_version(msg) ||
1453 wps_build_msg_type(msg, WPS_M8) ||
1454 wps_build_enrollee_nonce(wps, msg) ||
1455 (wps->wps->ap && wps_build_cred(wps, plain)) ||
1456 (!wps->wps->ap && wps_build_ap_settings(wps, plain)) ||
1457 wps_build_key_wrap_auth(wps, plain) ||
1458 wps_build_encr_settings(wps, msg, plain) ||
1459 wps_build_authenticator(wps, msg)) {
1466 wps->state = RECV_DONE;
1471 static struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
1475 wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_ACK");
1477 msg = wpabuf_alloc(1000);
1481 if (wps_build_version(msg) ||
1482 wps_build_msg_type(msg, WPS_WSC_ACK) ||
1483 wps_build_enrollee_nonce(wps, msg) ||
1484 wps_build_registrar_nonce(wps, msg)) {
1493 static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
1497 wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK");
1499 msg = wpabuf_alloc(1000);
1503 if (wps_build_version(msg) ||
1504 wps_build_msg_type(msg, WPS_WSC_NACK) ||
1505 wps_build_enrollee_nonce(wps, msg) ||
1506 wps_build_registrar_nonce(wps, msg) ||
1507 wps_build_config_error(msg, wps->config_error)) {
1516 struct wpabuf * wps_registrar_get_msg(struct wps_data *wps,
1517 enum wsc_op_code *op_code)
1521 #ifdef CONFIG_WPS_UPNP
1522 if (wps->wps->wps_upnp) {
1523 struct upnp_pending_message *p, *prev = NULL;
1524 if (wps->ext_reg > 1)
1525 wps_registrar_free_pending_m2(wps->wps);
1526 p = wps->wps->upnp_msgs;
1527 /* TODO: check pending message MAC address */
1528 while (p && p->next) {
1533 wpa_printf(MSG_DEBUG, "WPS: Use pending message from "
1538 wps->wps->upnp_msgs = NULL;
1542 if (wps->ext_reg == 0)
1548 wpa_printf(MSG_DEBUG, "WPS: Using external Registrar, but no "
1549 "pending message available");
1552 #endif /* CONFIG_WPS_UPNP */
1554 switch (wps->state) {
1556 if (wps_get_dev_password(wps) < 0)
1557 msg = wps_build_m2d(wps);
1559 msg = wps_build_m2(wps);
1563 msg = wps_build_m2d(wps);
1567 msg = wps_build_m4(wps);
1571 msg = wps_build_m6(wps);
1575 msg = wps_build_m8(wps);
1579 msg = wps_build_wsc_ack(wps);
1583 msg = wps_build_wsc_nack(wps);
1584 *op_code = WSC_NACK;
1587 wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
1588 "a message", wps->state);
1593 if (*op_code == WSC_MSG && msg) {
1594 /* Save a copy of the last message for Authenticator derivation
1596 wpabuf_free(wps->last_msg);
1597 wps->last_msg = wpabuf_dup(msg);
1604 static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
1606 if (e_nonce == NULL) {
1607 wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
1611 os_memcpy(wps->nonce_e, e_nonce, WPS_NONCE_LEN);
1612 wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
1613 wps->nonce_e, WPS_NONCE_LEN);
1619 static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
1621 if (r_nonce == NULL) {
1622 wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
1626 if (os_memcmp(wps->nonce_r, r_nonce, WPS_NONCE_LEN) != 0) {
1627 wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce received");
1635 static int wps_process_uuid_e(struct wps_data *wps, const u8 *uuid_e)
1637 if (uuid_e == NULL) {
1638 wpa_printf(MSG_DEBUG, "WPS: No UUID-E received");
1642 os_memcpy(wps->uuid_e, uuid_e, WPS_UUID_LEN);
1643 wpa_hexdump(MSG_DEBUG, "WPS: UUID-E", wps->uuid_e, WPS_UUID_LEN);
1649 static int wps_process_dev_password_id(struct wps_data *wps, const u8 *pw_id)
1651 if (pw_id == NULL) {
1652 wpa_printf(MSG_DEBUG, "WPS: No Device Password ID received");
1656 wps->dev_pw_id = WPA_GET_BE16(pw_id);
1657 wpa_printf(MSG_DEBUG, "WPS: Device Password ID %d", wps->dev_pw_id);
1663 static int wps_process_e_hash1(struct wps_data *wps, const u8 *e_hash1)
1665 if (e_hash1 == NULL) {
1666 wpa_printf(MSG_DEBUG, "WPS: No E-Hash1 received");
1670 os_memcpy(wps->peer_hash1, e_hash1, WPS_HASH_LEN);
1671 wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", wps->peer_hash1, WPS_HASH_LEN);
1677 static int wps_process_e_hash2(struct wps_data *wps, const u8 *e_hash2)
1679 if (e_hash2 == NULL) {
1680 wpa_printf(MSG_DEBUG, "WPS: No E-Hash2 received");
1684 os_memcpy(wps->peer_hash2, e_hash2, WPS_HASH_LEN);
1685 wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", wps->peer_hash2, WPS_HASH_LEN);
1691 static int wps_process_e_snonce1(struct wps_data *wps, const u8 *e_snonce1)
1693 u8 hash[SHA256_MAC_LEN];
1697 if (e_snonce1 == NULL) {
1698 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce1 received");
1702 wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce1", e_snonce1,
1703 WPS_SECRET_NONCE_LEN);
1705 /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
1706 addr[0] = e_snonce1;
1707 len[0] = WPS_SECRET_NONCE_LEN;
1708 addr[1] = wps->psk1;
1709 len[1] = WPS_PSK_LEN;
1710 addr[2] = wpabuf_head(wps->dh_pubkey_e);
1711 len[2] = wpabuf_len(wps->dh_pubkey_e);
1712 addr[3] = wpabuf_head(wps->dh_pubkey_r);
1713 len[3] = wpabuf_len(wps->dh_pubkey_r);
1714 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
1716 if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
1717 wpa_printf(MSG_DEBUG, "WPS: E-Hash1 derived from E-S1 does "
1718 "not match with the pre-committed value");
1719 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
1720 wps_pwd_auth_fail_event(wps->wps, 0, 1);
1724 wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the first "
1725 "half of the device password");
1731 static int wps_process_e_snonce2(struct wps_data *wps, const u8 *e_snonce2)
1733 u8 hash[SHA256_MAC_LEN];
1737 if (e_snonce2 == NULL) {
1738 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce2 received");
1742 wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce2", e_snonce2,
1743 WPS_SECRET_NONCE_LEN);
1745 /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
1746 addr[0] = e_snonce2;
1747 len[0] = WPS_SECRET_NONCE_LEN;
1748 addr[1] = wps->psk2;
1749 len[1] = WPS_PSK_LEN;
1750 addr[2] = wpabuf_head(wps->dh_pubkey_e);
1751 len[2] = wpabuf_len(wps->dh_pubkey_e);
1752 addr[3] = wpabuf_head(wps->dh_pubkey_r);
1753 len[3] = wpabuf_len(wps->dh_pubkey_r);
1754 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
1756 if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
1757 wpa_printf(MSG_DEBUG, "WPS: E-Hash2 derived from E-S2 does "
1758 "not match with the pre-committed value");
1759 wps_registrar_invalidate_pin(wps->wps->registrar, wps->uuid_e);
1760 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
1761 wps_pwd_auth_fail_event(wps->wps, 0, 2);
1765 wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the second "
1766 "half of the device password");
1767 wps->wps_pin_revealed = 0;
1768 wps_registrar_unlock_pin(wps->wps->registrar, wps->uuid_e);
1774 static int wps_process_mac_addr(struct wps_data *wps, const u8 *mac_addr)
1776 if (mac_addr == NULL) {
1777 wpa_printf(MSG_DEBUG, "WPS: No MAC Address received");
1781 wpa_printf(MSG_DEBUG, "WPS: Enrollee MAC Address " MACSTR,
1783 os_memcpy(wps->mac_addr_e, mac_addr, ETH_ALEN);
1784 os_memcpy(wps->peer_dev.mac_addr, mac_addr, ETH_ALEN);
1790 static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
1793 if (pk == NULL || pk_len == 0) {
1794 wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
1798 #ifdef CONFIG_WPS_OOB
1799 if (wps->wps->oob_conf.pubkey_hash != NULL) {
1801 u8 hash[WPS_HASH_LEN];
1804 sha256_vector(1, addr, &pk_len, hash);
1806 wpabuf_head(wps->wps->oob_conf.pubkey_hash),
1807 WPS_OOB_PUBKEY_HASH_LEN) != 0) {
1808 wpa_printf(MSG_ERROR, "WPS: Public Key hash error");
1812 #endif /* CONFIG_WPS_OOB */
1814 wpabuf_free(wps->dh_pubkey_e);
1815 wps->dh_pubkey_e = wpabuf_alloc_copy(pk, pk_len);
1816 if (wps->dh_pubkey_e == NULL)
1823 static int wps_process_auth_type_flags(struct wps_data *wps, const u8 *auth)
1828 wpa_printf(MSG_DEBUG, "WPS: No Authentication Type flags "
1833 auth_types = WPA_GET_BE16(auth);
1835 wpa_printf(MSG_DEBUG, "WPS: Enrollee Authentication Type flags 0x%x",
1837 wps->auth_type = wps->wps->auth_types & auth_types;
1838 if (wps->auth_type == 0) {
1839 wpa_printf(MSG_DEBUG, "WPS: No match in supported "
1840 "authentication types (own 0x%x Enrollee 0x%x)",
1841 wps->wps->auth_types, auth_types);
1842 #ifdef WPS_WORKAROUNDS
1844 * Some deployed implementations seem to advertise incorrect
1845 * information in this attribute. For example, Linksys WRT350N
1846 * seems to have a byteorder bug that breaks this negotiation.
1847 * In order to interoperate with existing implementations,
1848 * assume that the Enrollee supports everything we do.
1850 wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
1851 "does not advertise supported authentication types "
1853 wps->auth_type = wps->wps->auth_types;
1854 #else /* WPS_WORKAROUNDS */
1856 #endif /* WPS_WORKAROUNDS */
1863 static int wps_process_encr_type_flags(struct wps_data *wps, const u8 *encr)
1868 wpa_printf(MSG_DEBUG, "WPS: No Encryption Type flags "
1873 encr_types = WPA_GET_BE16(encr);
1875 wpa_printf(MSG_DEBUG, "WPS: Enrollee Encryption Type flags 0x%x",
1877 wps->encr_type = wps->wps->encr_types & encr_types;
1878 if (wps->encr_type == 0) {
1879 wpa_printf(MSG_DEBUG, "WPS: No match in supported "
1880 "encryption types (own 0x%x Enrollee 0x%x)",
1881 wps->wps->encr_types, encr_types);
1882 #ifdef WPS_WORKAROUNDS
1884 * Some deployed implementations seem to advertise incorrect
1885 * information in this attribute. For example, Linksys WRT350N
1886 * seems to have a byteorder bug that breaks this negotiation.
1887 * In order to interoperate with existing implementations,
1888 * assume that the Enrollee supports everything we do.
1890 wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
1891 "does not advertise supported encryption types "
1893 wps->encr_type = wps->wps->encr_types;
1894 #else /* WPS_WORKAROUNDS */
1896 #endif /* WPS_WORKAROUNDS */
1903 static int wps_process_conn_type_flags(struct wps_data *wps, const u8 *conn)
1906 wpa_printf(MSG_DEBUG, "WPS: No Connection Type flags "
1911 wpa_printf(MSG_DEBUG, "WPS: Enrollee Connection Type flags 0x%x",
1918 static int wps_process_config_methods(struct wps_data *wps, const u8 *methods)
1922 if (methods == NULL) {
1923 wpa_printf(MSG_DEBUG, "WPS: No Config Methods received");
1927 m = WPA_GET_BE16(methods);
1929 wpa_printf(MSG_DEBUG, "WPS: Enrollee Config Methods 0x%x", m);
1935 static int wps_process_wps_state(struct wps_data *wps, const u8 *state)
1937 if (state == NULL) {
1938 wpa_printf(MSG_DEBUG, "WPS: No Wi-Fi Protected Setup State "
1943 wpa_printf(MSG_DEBUG, "WPS: Enrollee Wi-Fi Protected Setup State %d",
1950 static int wps_process_assoc_state(struct wps_data *wps, const u8 *assoc)
1954 if (assoc == NULL) {
1955 wpa_printf(MSG_DEBUG, "WPS: No Association State received");
1959 a = WPA_GET_BE16(assoc);
1960 wpa_printf(MSG_DEBUG, "WPS: Enrollee Association State %d", a);
1966 static int wps_process_config_error(struct wps_data *wps, const u8 *err)
1971 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error received");
1975 e = WPA_GET_BE16(err);
1976 wpa_printf(MSG_DEBUG, "WPS: Enrollee Configuration Error %d", e);
1982 static enum wps_process_res wps_process_m1(struct wps_data *wps,
1983 struct wps_parse_attr *attr)
1985 wpa_printf(MSG_DEBUG, "WPS: Received M1");
1987 if (wps->state != RECV_M1) {
1988 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1989 "receiving M1", wps->state);
1993 if (wps_process_uuid_e(wps, attr->uuid_e) ||
1994 wps_process_mac_addr(wps, attr->mac_addr) ||
1995 wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
1996 wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
1997 wps_process_auth_type_flags(wps, attr->auth_type_flags) ||
1998 wps_process_encr_type_flags(wps, attr->encr_type_flags) ||
1999 wps_process_conn_type_flags(wps, attr->conn_type_flags) ||
2000 wps_process_config_methods(wps, attr->config_methods) ||
2001 wps_process_wps_state(wps, attr->wps_state) ||
2002 wps_process_device_attrs(&wps->peer_dev, attr) ||
2003 wps_process_rf_bands(&wps->peer_dev, attr->rf_bands) ||
2004 wps_process_assoc_state(wps, attr->assoc_state) ||
2005 wps_process_dev_password_id(wps, attr->dev_password_id) ||
2006 wps_process_config_error(wps, attr->config_error) ||
2007 wps_process_os_version(&wps->peer_dev, attr->os_version))
2010 if (wps->dev_pw_id < 0x10 &&
2011 wps->dev_pw_id != DEV_PW_DEFAULT &&
2012 wps->dev_pw_id != DEV_PW_USER_SPECIFIED &&
2013 wps->dev_pw_id != DEV_PW_MACHINE_SPECIFIED &&
2014 wps->dev_pw_id != DEV_PW_REGISTRAR_SPECIFIED &&
2015 (wps->dev_pw_id != DEV_PW_PUSHBUTTON ||
2016 !wps->wps->registrar->pbc)) {
2017 wpa_printf(MSG_DEBUG, "WPS: Unsupported Device Password ID %d",
2019 wps->state = SEND_M2D;
2020 return WPS_CONTINUE;
2023 #ifdef CONFIG_WPS_OOB
2024 if (wps->dev_pw_id >= 0x10 &&
2025 wps->dev_pw_id != wps->wps->oob_dev_pw_id) {
2026 wpa_printf(MSG_DEBUG, "WPS: OOB Device Password ID "
2027 "%d mismatch", wps->dev_pw_id);
2028 wps->state = SEND_M2D;
2029 return WPS_CONTINUE;
2031 #endif /* CONFIG_WPS_OOB */
2033 if (wps->dev_pw_id == DEV_PW_PUSHBUTTON) {
2034 if (wps->wps->registrar->force_pbc_overlap ||
2035 wps_registrar_pbc_overlap(wps->wps->registrar,
2036 wps->mac_addr_e, wps->uuid_e)) {
2037 wpa_printf(MSG_DEBUG, "WPS: PBC overlap - deny PBC "
2039 wps->state = SEND_M2D;
2040 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2041 wps_pbc_overlap_event(wps->wps);
2042 wps->wps->registrar->force_pbc_overlap = 1;
2043 return WPS_CONTINUE;
2045 wps_registrar_add_pbc_session(wps->wps->registrar,
2046 wps->mac_addr_e, wps->uuid_e);
2050 wps->state = SEND_M2;
2051 return WPS_CONTINUE;
2055 static enum wps_process_res wps_process_m3(struct wps_data *wps,
2056 const struct wpabuf *msg,
2057 struct wps_parse_attr *attr)
2059 wpa_printf(MSG_DEBUG, "WPS: Received M3");
2061 if (wps->state != RECV_M3) {
2062 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2063 "receiving M3", wps->state);
2064 wps->state = SEND_WSC_NACK;
2065 return WPS_CONTINUE;
2068 if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
2069 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
2071 wps->state = SEND_WSC_NACK;
2072 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2073 return WPS_CONTINUE;
2076 if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
2077 wps_process_authenticator(wps, attr->authenticator, msg) ||
2078 wps_process_e_hash1(wps, attr->e_hash1) ||
2079 wps_process_e_hash2(wps, attr->e_hash2)) {
2080 wps->state = SEND_WSC_NACK;
2081 return WPS_CONTINUE;
2084 wps->state = SEND_M4;
2085 return WPS_CONTINUE;
2089 static enum wps_process_res wps_process_m5(struct wps_data *wps,
2090 const struct wpabuf *msg,
2091 struct wps_parse_attr *attr)
2093 struct wpabuf *decrypted;
2094 struct wps_parse_attr eattr;
2096 wpa_printf(MSG_DEBUG, "WPS: Received M5");
2098 if (wps->state != RECV_M5) {
2099 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2100 "receiving M5", wps->state);
2101 wps->state = SEND_WSC_NACK;
2102 return WPS_CONTINUE;
2105 if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
2106 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
2108 wps->state = SEND_WSC_NACK;
2109 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2110 return WPS_CONTINUE;
2113 if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
2114 wps_process_authenticator(wps, attr->authenticator, msg)) {
2115 wps->state = SEND_WSC_NACK;
2116 return WPS_CONTINUE;
2119 decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
2120 attr->encr_settings_len);
2121 if (decrypted == NULL) {
2122 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
2123 "Settings attribute");
2124 wps->state = SEND_WSC_NACK;
2125 return WPS_CONTINUE;
2128 wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
2130 if (wps_parse_msg(decrypted, &eattr) < 0 ||
2131 wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
2132 wps_process_e_snonce1(wps, eattr.e_snonce1)) {
2133 wpabuf_free(decrypted);
2134 wps->state = SEND_WSC_NACK;
2135 return WPS_CONTINUE;
2137 wpabuf_free(decrypted);
2139 wps->state = SEND_M6;
2140 return WPS_CONTINUE;
2144 static void wps_sta_cred_cb(struct wps_data *wps)
2147 * Update credential to only include a single authentication and
2148 * encryption type in case the AP configuration includes more than one
2151 if (wps->cred.auth_type & WPS_AUTH_WPA2PSK)
2152 wps->cred.auth_type = WPS_AUTH_WPA2PSK;
2153 else if (wps->cred.auth_type & WPS_AUTH_WPAPSK)
2154 wps->cred.auth_type = WPS_AUTH_WPAPSK;
2155 if (wps->cred.encr_type & WPS_ENCR_AES)
2156 wps->cred.encr_type = WPS_ENCR_AES;
2157 else if (wps->cred.encr_type & WPS_ENCR_TKIP)
2158 wps->cred.encr_type = WPS_ENCR_TKIP;
2159 wpa_printf(MSG_DEBUG, "WPS: Update local configuration based on the "
2160 "AP configuration");
2161 if (wps->wps->cred_cb)
2162 wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
2166 static void wps_cred_update(struct wps_credential *dst,
2167 struct wps_credential *src)
2169 os_memcpy(dst->ssid, src->ssid, sizeof(dst->ssid));
2170 dst->ssid_len = src->ssid_len;
2171 dst->auth_type = src->auth_type;
2172 dst->encr_type = src->encr_type;
2173 dst->key_idx = src->key_idx;
2174 os_memcpy(dst->key, src->key, sizeof(dst->key));
2175 dst->key_len = src->key_len;
2179 static int wps_process_ap_settings_r(struct wps_data *wps,
2180 struct wps_parse_attr *attr)
2185 /* AP Settings Attributes in M7 when Enrollee is an AP */
2186 if (wps_process_ap_settings(attr, &wps->cred) < 0)
2189 wpa_printf(MSG_INFO, "WPS: Received old AP configuration from AP");
2191 if (wps->new_ap_settings) {
2192 wpa_printf(MSG_INFO, "WPS: Update AP configuration based on "
2194 wps_cred_update(&wps->cred, wps->new_ap_settings);
2198 * Use the AP PIN only to receive the current AP settings, not
2199 * to reconfigure the AP.
2201 wps_sta_cred_cb(wps);
2207 static enum wps_process_res wps_process_m7(struct wps_data *wps,
2208 const struct wpabuf *msg,
2209 struct wps_parse_attr *attr)
2211 struct wpabuf *decrypted;
2212 struct wps_parse_attr eattr;
2214 wpa_printf(MSG_DEBUG, "WPS: Received M7");
2216 if (wps->state != RECV_M7) {
2217 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2218 "receiving M7", wps->state);
2219 wps->state = SEND_WSC_NACK;
2220 return WPS_CONTINUE;
2223 if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
2224 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
2226 wps->state = SEND_WSC_NACK;
2227 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2228 return WPS_CONTINUE;
2231 if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
2232 wps_process_authenticator(wps, attr->authenticator, msg)) {
2233 wps->state = SEND_WSC_NACK;
2234 return WPS_CONTINUE;
2237 decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
2238 attr->encr_settings_len);
2239 if (decrypted == NULL) {
2240 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
2241 "Settings attribute");
2242 wps->state = SEND_WSC_NACK;
2243 return WPS_CONTINUE;
2246 wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
2248 if (wps_parse_msg(decrypted, &eattr) < 0 ||
2249 wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
2250 wps_process_e_snonce2(wps, eattr.e_snonce2) ||
2251 wps_process_ap_settings_r(wps, &eattr)) {
2252 wpabuf_free(decrypted);
2253 wps->state = SEND_WSC_NACK;
2254 return WPS_CONTINUE;
2257 wpabuf_free(decrypted);
2259 wps->state = SEND_M8;
2260 return WPS_CONTINUE;
2264 static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
2265 const struct wpabuf *msg)
2267 struct wps_parse_attr attr;
2268 enum wps_process_res ret = WPS_CONTINUE;
2270 wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
2272 if (wps_parse_msg(msg, &attr) < 0)
2275 if (!wps_version_supported(attr.version)) {
2276 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
2277 attr.version ? *attr.version : 0);
2281 if (attr.msg_type == NULL) {
2282 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2286 if (*attr.msg_type != WPS_M1 &&
2287 (attr.registrar_nonce == NULL ||
2288 os_memcmp(wps->nonce_r, attr.registrar_nonce,
2289 WPS_NONCE_LEN != 0))) {
2290 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2294 switch (*attr.msg_type) {
2296 #ifdef CONFIG_WPS_UPNP
2297 if (wps->wps->wps_upnp && attr.mac_addr) {
2298 /* Remove old pending messages when starting new run */
2299 wps_free_pending_msgs(wps->wps->upnp_msgs);
2300 wps->wps->upnp_msgs = NULL;
2302 upnp_wps_device_send_wlan_event(
2303 wps->wps->wps_upnp, attr.mac_addr,
2304 UPNP_WPS_WLANEVENT_TYPE_EAP, msg);
2306 #endif /* CONFIG_WPS_UPNP */
2307 ret = wps_process_m1(wps, &attr);
2310 ret = wps_process_m3(wps, msg, &attr);
2311 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
2312 wps_fail_event(wps->wps, WPS_M3);
2315 ret = wps_process_m5(wps, msg, &attr);
2316 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
2317 wps_fail_event(wps->wps, WPS_M5);
2320 ret = wps_process_m7(wps, msg, &attr);
2321 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
2322 wps_fail_event(wps->wps, WPS_M7);
2325 wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
2330 if (ret == WPS_CONTINUE) {
2331 /* Save a copy of the last message for Authenticator derivation
2333 wpabuf_free(wps->last_msg);
2334 wps->last_msg = wpabuf_dup(msg);
2341 static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
2342 const struct wpabuf *msg)
2344 struct wps_parse_attr attr;
2346 wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
2348 if (wps_parse_msg(msg, &attr) < 0)
2351 if (!wps_version_supported(attr.version)) {
2352 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
2353 attr.version ? *attr.version : 0);
2357 if (attr.msg_type == NULL) {
2358 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2362 if (*attr.msg_type != WPS_WSC_ACK) {
2363 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
2368 #ifdef CONFIG_WPS_UPNP
2369 if (wps->wps->wps_upnp && wps->ext_reg && wps->state == RECV_M2D_ACK &&
2370 upnp_wps_subscribers(wps->wps->wps_upnp)) {
2371 if (wps->wps->upnp_msgs)
2372 return WPS_CONTINUE;
2373 wpa_printf(MSG_DEBUG, "WPS: Wait for response from an "
2374 "external Registrar");
2377 #endif /* CONFIG_WPS_UPNP */
2379 if (attr.registrar_nonce == NULL ||
2380 os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
2382 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2386 if (attr.enrollee_nonce == NULL ||
2387 os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
2388 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
2392 if (wps->state == RECV_M2D_ACK) {
2393 #ifdef CONFIG_WPS_UPNP
2394 if (wps->wps->wps_upnp &&
2395 upnp_wps_subscribers(wps->wps->wps_upnp)) {
2396 if (wps->wps->upnp_msgs)
2397 return WPS_CONTINUE;
2398 if (wps->ext_reg == 0)
2400 wpa_printf(MSG_DEBUG, "WPS: Wait for response from an "
2401 "external Registrar");
2404 #endif /* CONFIG_WPS_UPNP */
2406 wpa_printf(MSG_DEBUG, "WPS: No more registrars available - "
2407 "terminate negotiation");
2414 static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
2415 const struct wpabuf *msg)
2417 struct wps_parse_attr attr;
2420 wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
2422 old_state = wps->state;
2423 wps->state = SEND_WSC_NACK;
2425 if (wps_parse_msg(msg, &attr) < 0)
2428 if (!wps_version_supported(attr.version)) {
2429 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
2430 attr.version ? *attr.version : 0);
2434 if (attr.msg_type == NULL) {
2435 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2439 if (*attr.msg_type != WPS_WSC_NACK) {
2440 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
2445 #ifdef CONFIG_WPS_UPNP
2446 if (wps->wps->wps_upnp && wps->ext_reg) {
2447 wpa_printf(MSG_DEBUG, "WPS: Negotiation using external "
2448 "Registrar terminated by the Enrollee");
2451 #endif /* CONFIG_WPS_UPNP */
2453 if (attr.registrar_nonce == NULL ||
2454 os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
2456 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2460 if (attr.enrollee_nonce == NULL ||
2461 os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
2462 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
2466 if (attr.config_error == NULL) {
2467 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
2472 wpa_printf(MSG_DEBUG, "WPS: Enrollee terminated negotiation with "
2473 "Configuration Error %d", WPA_GET_BE16(attr.config_error));
2475 switch (old_state) {
2477 wps_fail_event(wps->wps, WPS_M2);
2480 wps_fail_event(wps->wps, WPS_M4);
2483 wps_fail_event(wps->wps, WPS_M6);
2486 wps_fail_event(wps->wps, WPS_M8);
2496 static enum wps_process_res wps_process_wsc_done(struct wps_data *wps,
2497 const struct wpabuf *msg)
2499 struct wps_parse_attr attr;
2501 wpa_printf(MSG_DEBUG, "WPS: Received WSC_Done");
2503 if (wps->state != RECV_DONE &&
2504 (!wps->wps->wps_upnp || !wps->ext_reg)) {
2505 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2506 "receiving WSC_Done", wps->state);
2510 if (wps_parse_msg(msg, &attr) < 0)
2513 if (!wps_version_supported(attr.version)) {
2514 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
2515 attr.version ? *attr.version : 0);
2519 if (attr.msg_type == NULL) {
2520 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2524 if (*attr.msg_type != WPS_WSC_DONE) {
2525 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
2530 #ifdef CONFIG_WPS_UPNP
2531 if (wps->wps->wps_upnp && wps->ext_reg) {
2532 wpa_printf(MSG_DEBUG, "WPS: Negotiation using external "
2533 "Registrar completed successfully");
2534 wps_device_store(wps->wps->registrar, &wps->peer_dev,
2538 #endif /* CONFIG_WPS_UPNP */
2540 if (attr.registrar_nonce == NULL ||
2541 os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
2543 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2547 if (attr.enrollee_nonce == NULL ||
2548 os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
2549 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
2553 wpa_printf(MSG_DEBUG, "WPS: Negotiation completed successfully");
2554 wps_device_store(wps->wps->registrar, &wps->peer_dev,
2557 if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->new_psk &&
2558 wps->wps->ap && !wps->wps->registrar->disable_auto_conf) {
2559 struct wps_credential cred;
2561 wpa_printf(MSG_DEBUG, "WPS: Moving to Configured state based "
2562 "on first Enrollee connection");
2564 os_memset(&cred, 0, sizeof(cred));
2565 os_memcpy(cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
2566 cred.ssid_len = wps->wps->ssid_len;
2567 cred.auth_type = WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK;
2568 cred.encr_type = WPS_ENCR_TKIP | WPS_ENCR_AES;
2569 os_memcpy(cred.key, wps->new_psk, wps->new_psk_len);
2570 cred.key_len = wps->new_psk_len;
2572 wps->wps->wps_state = WPS_STATE_CONFIGURED;
2573 wpa_hexdump_ascii_key(MSG_DEBUG,
2574 "WPS: Generated random passphrase",
2575 wps->new_psk, wps->new_psk_len);
2576 if (wps->wps->cred_cb)
2577 wps->wps->cred_cb(wps->wps->cb_ctx, &cred);
2579 os_free(wps->new_psk);
2580 wps->new_psk = NULL;
2584 wps_sta_cred_cb(wps);
2587 if (wps_cb_new_psk(wps->wps->registrar, wps->mac_addr_e,
2588 wps->new_psk, wps->new_psk_len)) {
2589 wpa_printf(MSG_DEBUG, "WPS: Failed to configure the "
2592 os_free(wps->new_psk);
2593 wps->new_psk = NULL;
2596 wps_cb_reg_success(wps->wps->registrar, wps->mac_addr_e, wps->uuid_e);
2599 wps_registrar_remove_pbc_session(wps->wps->registrar,
2600 wps->mac_addr_e, wps->uuid_e);
2601 wps_registrar_pbc_completed(wps->wps->registrar);
2603 wps_registrar_pin_completed(wps->wps->registrar);
2606 wps_success_event(wps->wps);
2612 enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
2613 enum wsc_op_code op_code,
2614 const struct wpabuf *msg)
2616 enum wps_process_res ret;
2618 wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
2620 (unsigned long) wpabuf_len(msg), op_code);
2622 #ifdef CONFIG_WPS_UPNP
2623 if (wps->wps->wps_upnp && op_code == WSC_MSG && wps->ext_reg == 1) {
2624 struct wps_parse_attr attr;
2625 if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type &&
2626 *attr.msg_type == WPS_M3)
2627 wps->ext_reg = 2; /* past M2/M2D phase */
2629 if (wps->ext_reg > 1)
2630 wps_registrar_free_pending_m2(wps->wps);
2631 if (wps->wps->wps_upnp && wps->ext_reg &&
2632 wps->wps->upnp_msgs == NULL &&
2633 (op_code == WSC_MSG || op_code == WSC_Done)) {
2634 struct wps_parse_attr attr;
2636 if (wps_parse_msg(msg, &attr) < 0 || attr.msg_type == NULL)
2639 type = *attr.msg_type;
2640 wpa_printf(MSG_DEBUG, "WPS: Sending received message (type %d)"
2641 " to external Registrar for processing", type);
2642 upnp_wps_device_send_wlan_event(wps->wps->wps_upnp,
2644 UPNP_WPS_WLANEVENT_TYPE_EAP,
2646 if (op_code == WSC_MSG)
2648 } else if (wps->wps->wps_upnp && wps->ext_reg && op_code == WSC_MSG) {
2649 wpa_printf(MSG_DEBUG, "WPS: Skip internal processing - using "
2650 "external Registrar");
2651 return WPS_CONTINUE;
2653 #endif /* CONFIG_WPS_UPNP */
2657 return wps_process_wsc_msg(wps, msg);
2659 return wps_process_wsc_ack(wps, msg);
2661 return wps_process_wsc_nack(wps, msg);
2663 ret = wps_process_wsc_done(wps, msg);
2664 if (ret == WPS_FAILURE) {
2665 wps->state = SEND_WSC_NACK;
2666 wps_fail_event(wps->wps, WPS_WSC_DONE);
2670 wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
2676 int wps_registrar_update_ie(struct wps_registrar *reg)
2678 return wps_set_ie(reg);
2682 static void wps_registrar_set_selected_timeout(void *eloop_ctx,
2685 struct wps_registrar *reg = eloop_ctx;
2687 wpa_printf(MSG_DEBUG, "WPS: SetSelectedRegistrar timed out - "
2688 "unselect Registrar");
2689 reg->selected_registrar = 0;
2691 reg->sel_reg_dev_password_id_override = -1;
2692 reg->sel_reg_config_methods_override = -1;
2698 * wps_registrar_set_selected_registrar - Notification of SetSelectedRegistrar
2699 * @reg: Registrar data from wps_registrar_init()
2700 * @msg: Received message from SetSelectedRegistrar
2701 * Returns: 0 on success, -1 on failure
2703 * This function is called when an AP receives a SetSelectedRegistrar UPnP
2706 int wps_registrar_set_selected_registrar(struct wps_registrar *reg,
2707 const struct wpabuf *msg)
2709 struct wps_parse_attr attr;
2711 wpa_hexdump_buf(MSG_MSGDUMP, "WPS: SetSelectedRegistrar attributes",
2714 if (wps_parse_msg(msg, &attr) < 0)
2716 if (!wps_version_supported(attr.version)) {
2717 wpa_printf(MSG_DEBUG, "WPS: Unsupported SetSelectedRegistrar "
2718 "version 0x%x", attr.version ? *attr.version : 0);
2722 if (attr.selected_registrar == NULL ||
2723 *attr.selected_registrar == 0) {
2724 wpa_printf(MSG_DEBUG, "WPS: SetSelectedRegistrar: Disable "
2725 "Selected Registrar");
2726 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg,
2728 wps_registrar_set_selected_timeout(reg, NULL);
2732 reg->selected_registrar = 1;
2733 reg->sel_reg_dev_password_id_override = attr.dev_password_id ?
2734 WPA_GET_BE16(attr.dev_password_id) : DEV_PW_DEFAULT;
2735 reg->sel_reg_config_methods_override = attr.sel_reg_config_methods ?
2736 WPA_GET_BE16(attr.sel_reg_config_methods) : -1;
2739 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
2740 eloop_register_timeout(WPS_PBC_WALK_TIME, 0,
2741 wps_registrar_set_selected_timeout,
2747 int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr,
2748 char *buf, size_t buflen)
2750 struct wps_registrar_device *d;
2754 d = wps_device_get(reg, addr);
2757 if (uuid_bin2str(d->uuid, uuid, sizeof(uuid)))
2760 ret = os_snprintf(buf + len, buflen - len,
2762 "wpsPrimaryDeviceType=%u-%08X-%u\n"
2763 "wpsDeviceName=%s\n"
2764 "wpsManufacturer=%s\n"
2766 "wpsModelNumber=%s\n"
2767 "wpsSerialNumber=%s\n",
2769 d->dev.categ, d->dev.oui, d->dev.sub_categ,
2770 d->dev.device_name ? d->dev.device_name : "",
2771 d->dev.manufacturer ? d->dev.manufacturer : "",
2772 d->dev.model_name ? d->dev.model_name : "",
2773 d->dev.model_number ? d->dev.model_number : "",
2774 d->dev.serial_number ? d->dev.serial_number : "");
2775 if (ret < 0 || (size_t) ret >= buflen - len)