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
,
104 void (*set_sel_reg_cb
)(void *ctx
, int sel_reg
, u16 dev_passwd_id
,
105 u16 sel_reg_config_methods
);
108 struct wps_uuid_pin
*pins
;
109 struct wps_pbc_session
*pbc_sessions
;
112 struct wpabuf
*extra_cred
;
113 int disable_auto_conf
;
114 int sel_reg_dev_password_id_override
;
115 int sel_reg_config_methods_override
;
118 struct wps_registrar_device
*devices
;
120 int force_pbc_overlap
;
124 static int wps_set_ie(struct wps_registrar
*reg
);
125 static void wps_cb_set_sel_reg(struct wps_registrar
*reg
);
126 static void wps_registrar_pbc_timeout(void *eloop_ctx
, void *timeout_ctx
);
127 static void wps_registrar_set_selected_timeout(void *eloop_ctx
,
131 static void wps_free_devices(struct wps_registrar_device
*dev
)
133 struct wps_registrar_device
*prev
;
138 wps_device_data_free(&prev
->dev
);
144 static struct wps_registrar_device
* wps_device_get(struct wps_registrar
*reg
,
147 struct wps_registrar_device
*dev
;
149 for (dev
= reg
->devices
; dev
; dev
= dev
->next
) {
150 if (os_memcmp(dev
->dev
.mac_addr
, addr
, ETH_ALEN
) == 0)
157 static void wps_device_clone_data(struct wps_device_data
*dst
,
158 struct wps_device_data
*src
)
160 os_memcpy(dst
->mac_addr
, src
->mac_addr
, ETH_ALEN
);
161 dst
->categ
= src
->categ
;
163 dst
->sub_categ
= src
->sub_categ
;
165 #define WPS_STRDUP(n) \
167 dst->n = src->n ? os_strdup(src->n) : NULL
169 WPS_STRDUP(device_name
);
170 WPS_STRDUP(manufacturer
);
171 WPS_STRDUP(model_name
);
172 WPS_STRDUP(model_number
);
173 WPS_STRDUP(serial_number
);
178 int wps_device_store(struct wps_registrar
*reg
,
179 struct wps_device_data
*dev
, const u8
*uuid
)
181 struct wps_registrar_device
*d
;
183 d
= wps_device_get(reg
, dev
->mac_addr
);
185 d
= os_zalloc(sizeof(*d
));
188 d
->next
= reg
->devices
;
192 wps_device_clone_data(&d
->dev
, dev
);
193 os_memcpy(d
->uuid
, uuid
, WPS_UUID_LEN
);
199 static void wps_registrar_add_pbc_session(struct wps_registrar
*reg
,
200 const u8
*addr
, const u8
*uuid_e
)
202 struct wps_pbc_session
*pbc
, *prev
= NULL
;
207 pbc
= reg
->pbc_sessions
;
209 if (os_memcmp(pbc
->addr
, addr
, ETH_ALEN
) == 0 &&
210 os_memcmp(pbc
->uuid_e
, uuid_e
, WPS_UUID_LEN
) == 0) {
212 prev
->next
= pbc
->next
;
214 reg
->pbc_sessions
= pbc
->next
;
222 pbc
= os_zalloc(sizeof(*pbc
));
225 os_memcpy(pbc
->addr
, addr
, ETH_ALEN
);
227 os_memcpy(pbc
->uuid_e
, uuid_e
, WPS_UUID_LEN
);
230 pbc
->next
= reg
->pbc_sessions
;
231 reg
->pbc_sessions
= pbc
;
232 pbc
->timestamp
= now
;
234 /* remove entries that have timed out */
239 if (now
.sec
> pbc
->timestamp
.sec
+ WPS_PBC_WALK_TIME
) {
241 wps_free_pbc_sessions(pbc
);
250 static void wps_registrar_remove_pbc_session(struct wps_registrar
*reg
,
251 const u8
*addr
, const u8
*uuid_e
)
253 struct wps_pbc_session
*pbc
, *prev
= NULL
;
255 pbc
= reg
->pbc_sessions
;
257 if (os_memcmp(pbc
->addr
, addr
, ETH_ALEN
) == 0 &&
258 os_memcmp(pbc
->uuid_e
, uuid_e
, WPS_UUID_LEN
) == 0) {
260 prev
->next
= pbc
->next
;
262 reg
->pbc_sessions
= pbc
->next
;
272 static int wps_registrar_pbc_overlap(struct wps_registrar
*reg
,
273 const u8
*addr
, const u8
*uuid_e
)
276 struct wps_pbc_session
*pbc
;
281 for (pbc
= reg
->pbc_sessions
; pbc
; pbc
= pbc
->next
) {
282 if (now
.sec
> pbc
->timestamp
.sec
+ WPS_PBC_WALK_TIME
)
284 if (addr
== NULL
|| os_memcmp(addr
, pbc
->addr
, ETH_ALEN
) ||
286 os_memcmp(uuid_e
, pbc
->uuid_e
, WPS_UUID_LEN
))
293 return count
> 1 ? 1 : 0;
297 static int wps_build_wps_state(struct wps_context
*wps
, struct wpabuf
*msg
)
299 wpa_printf(MSG_DEBUG
, "WPS: * Wi-Fi Protected Setup State (%d)",
301 wpabuf_put_be16(msg
, ATTR_WPS_STATE
);
302 wpabuf_put_be16(msg
, 1);
303 wpabuf_put_u8(msg
, wps
->wps_state
);
308 #ifdef CONFIG_WPS_UPNP
309 static void wps_registrar_free_pending_m2(struct wps_context
*wps
)
311 struct upnp_pending_message
*p
, *p2
, *prev
= NULL
;
314 if (p
->type
== WPS_M2
|| p
->type
== WPS_M2D
) {
316 wps
->upnp_msgs
= p
->next
;
318 prev
->next
= p
->next
;
319 wpa_printf(MSG_DEBUG
, "WPS UPnP: Drop pending M2/M2D");
322 wpabuf_free(p2
->msg
);
330 #endif /* CONFIG_WPS_UPNP */
333 static int wps_build_ap_setup_locked(struct wps_context
*wps
,
336 if (wps
->ap_setup_locked
) {
337 wpa_printf(MSG_DEBUG
, "WPS: * AP Setup Locked");
338 wpabuf_put_be16(msg
, ATTR_AP_SETUP_LOCKED
);
339 wpabuf_put_be16(msg
, 1);
340 wpabuf_put_u8(msg
, 1);
346 static int wps_build_selected_registrar(struct wps_registrar
*reg
,
349 if (!reg
->selected_registrar
)
351 wpa_printf(MSG_DEBUG
, "WPS: * Selected Registrar");
352 wpabuf_put_be16(msg
, ATTR_SELECTED_REGISTRAR
);
353 wpabuf_put_be16(msg
, 1);
354 wpabuf_put_u8(msg
, 1);
359 static int wps_build_sel_reg_dev_password_id(struct wps_registrar
*reg
,
362 u16 id
= reg
->pbc
? DEV_PW_PUSHBUTTON
: DEV_PW_DEFAULT
;
363 if (!reg
->selected_registrar
)
365 if (reg
->sel_reg_dev_password_id_override
>= 0)
366 id
= reg
->sel_reg_dev_password_id_override
;
367 wpa_printf(MSG_DEBUG
, "WPS: * Device Password ID (%d)", id
);
368 wpabuf_put_be16(msg
, ATTR_DEV_PASSWORD_ID
);
369 wpabuf_put_be16(msg
, 2);
370 wpabuf_put_be16(msg
, id
);
375 static int wps_build_sel_reg_config_methods(struct wps_registrar
*reg
,
379 if (!reg
->selected_registrar
)
381 methods
= reg
->wps
->config_methods
& ~WPS_CONFIG_PUSHBUTTON
;
383 methods
|= WPS_CONFIG_PUSHBUTTON
;
384 if (reg
->sel_reg_config_methods_override
>= 0)
385 methods
= reg
->sel_reg_config_methods_override
;
386 wpa_printf(MSG_DEBUG
, "WPS: * Selected Registrar Config Methods (%x)",
388 wpabuf_put_be16(msg
, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS
);
389 wpabuf_put_be16(msg
, 2);
390 wpabuf_put_be16(msg
, methods
);
395 static int wps_build_probe_config_methods(struct wps_registrar
*reg
,
400 wpa_printf(MSG_DEBUG
, "WPS: * Config Methods (%x)", methods
);
401 wpabuf_put_be16(msg
, ATTR_CONFIG_METHODS
);
402 wpabuf_put_be16(msg
, 2);
403 wpabuf_put_be16(msg
, methods
);
408 static int wps_build_config_methods_r(struct wps_registrar
*reg
,
412 methods
= reg
->wps
->config_methods
& ~WPS_CONFIG_PUSHBUTTON
;
414 methods
|= WPS_CONFIG_PUSHBUTTON
;
415 return wps_build_config_methods(msg
, methods
);
419 static int wps_build_resp_type(struct wps_registrar
*reg
, struct wpabuf
*msg
)
421 u8 resp
= reg
->wps
->ap
? WPS_RESP_AP
: WPS_RESP_REGISTRAR
;
422 wpa_printf(MSG_DEBUG
, "WPS: * Response Type (%d)", resp
);
423 wpabuf_put_be16(msg
, ATTR_RESPONSE_TYPE
);
424 wpabuf_put_be16(msg
, 1);
425 wpabuf_put_u8(msg
, resp
);
431 * wps_registrar_init - Initialize WPS Registrar data
432 * @wps: Pointer to longterm WPS context
433 * @cfg: Registrar configuration
434 * Returns: Pointer to allocated Registrar data or %NULL on failure
436 * This function is used to initialize WPS Registrar functionality. It can be
437 * used for a single Registrar run (e.g., when run in a supplicant) or multiple
438 * runs (e.g., when run as an internal Registrar in an AP). Caller is
439 * responsible for freeing the returned data with wps_registrar_deinit() when
440 * Registrar functionality is not needed anymore.
442 struct wps_registrar
*
443 wps_registrar_init(struct wps_context
*wps
,
444 const struct wps_registrar_config
*cfg
)
446 struct wps_registrar
*reg
= os_zalloc(sizeof(*reg
));
451 reg
->new_psk_cb
= cfg
->new_psk_cb
;
452 reg
->set_ie_cb
= cfg
->set_ie_cb
;
453 reg
->pin_needed_cb
= cfg
->pin_needed_cb
;
454 reg
->reg_success_cb
= cfg
->reg_success_cb
;
455 reg
->set_sel_reg_cb
= cfg
->set_sel_reg_cb
;
456 reg
->cb_ctx
= cfg
->cb_ctx
;
457 reg
->skip_cred_build
= cfg
->skip_cred_build
;
458 if (cfg
->extra_cred
) {
459 reg
->extra_cred
= wpabuf_alloc_copy(cfg
->extra_cred
,
460 cfg
->extra_cred_len
);
461 if (reg
->extra_cred
== NULL
) {
466 reg
->disable_auto_conf
= cfg
->disable_auto_conf
;
467 reg
->sel_reg_dev_password_id_override
= -1;
468 reg
->sel_reg_config_methods_override
= -1;
469 reg
->static_wep_only
= cfg
->static_wep_only
;
471 if (wps_set_ie(reg
)) {
472 wps_registrar_deinit(reg
);
481 * wps_registrar_deinit - Deinitialize WPS Registrar data
482 * @reg: Registrar data from wps_registrar_init()
484 void wps_registrar_deinit(struct wps_registrar
*reg
)
488 eloop_cancel_timeout(wps_registrar_pbc_timeout
, reg
, NULL
);
489 eloop_cancel_timeout(wps_registrar_set_selected_timeout
, reg
, NULL
);
490 wps_free_pins(reg
->pins
);
491 wps_free_pbc_sessions(reg
->pbc_sessions
);
492 wpabuf_free(reg
->extra_cred
);
493 wps_free_devices(reg
->devices
);
499 * wps_registrar_add_pin - Configure a new PIN for Registrar
500 * @reg: Registrar data from wps_registrar_init()
501 * @uuid: UUID-E or %NULL for wildcard (any UUID)
502 * @pin: PIN (Device Password)
503 * @pin_len: Length of pin in octets
504 * @timeout: Time (in seconds) when the PIN will be invalidated; 0 = no timeout
505 * Returns: 0 on success, -1 on failure
507 int wps_registrar_add_pin(struct wps_registrar
*reg
, const u8
*uuid
,
508 const u8
*pin
, size_t pin_len
, int timeout
)
510 struct wps_uuid_pin
*p
;
512 p
= os_zalloc(sizeof(*p
));
516 p
->wildcard_uuid
= 1;
518 os_memcpy(p
->uuid
, uuid
, WPS_UUID_LEN
);
519 p
->pin
= os_malloc(pin_len
);
520 if (p
->pin
== NULL
) {
524 os_memcpy(p
->pin
, pin
, pin_len
);
525 p
->pin_len
= pin_len
;
528 p
->flags
|= PIN_EXPIRES
;
529 os_get_time(&p
->expiration
);
530 p
->expiration
.sec
+= timeout
;
536 wpa_printf(MSG_DEBUG
, "WPS: A new PIN configured (timeout=%d)",
538 wpa_hexdump(MSG_DEBUG
, "WPS: UUID", uuid
, WPS_UUID_LEN
);
539 wpa_hexdump_ascii_key(MSG_DEBUG
, "WPS: PIN", pin
, pin_len
);
540 reg
->selected_registrar
= 1;
543 wps_cb_set_sel_reg(reg
);
544 eloop_cancel_timeout(wps_registrar_set_selected_timeout
, reg
, NULL
);
545 eloop_register_timeout(WPS_PBC_WALK_TIME
, 0,
546 wps_registrar_set_selected_timeout
,
553 static void wps_registrar_expire_pins(struct wps_registrar
*reg
)
555 struct wps_uuid_pin
*pin
, *prev
, *del
;
562 if ((pin
->flags
& PIN_EXPIRES
) &&
563 os_time_before(&pin
->expiration
, &now
)) {
565 reg
->pins
= pin
->next
;
567 prev
->next
= pin
->next
;
570 wpa_hexdump(MSG_DEBUG
, "WPS: Expired PIN for UUID",
571 del
->uuid
, WPS_UUID_LEN
);
582 * wps_registrar_invalidate_pin - Invalidate a PIN for a specific UUID-E
583 * @reg: Registrar data from wps_registrar_init()
585 * Returns: 0 on success, -1 on failure (e.g., PIN not found)
587 int wps_registrar_invalidate_pin(struct wps_registrar
*reg
, const u8
*uuid
)
589 struct wps_uuid_pin
*pin
, *prev
;
594 if (os_memcmp(pin
->uuid
, uuid
, WPS_UUID_LEN
) == 0) {
596 reg
->pins
= pin
->next
;
598 prev
->next
= pin
->next
;
599 wpa_hexdump(MSG_DEBUG
, "WPS: Invalidated PIN for UUID",
600 pin
->uuid
, WPS_UUID_LEN
);
612 static const u8
* wps_registrar_get_pin(struct wps_registrar
*reg
,
613 const u8
*uuid
, size_t *pin_len
)
615 struct wps_uuid_pin
*pin
;
617 wps_registrar_expire_pins(reg
);
621 if (!pin
->wildcard_uuid
&&
622 os_memcmp(pin
->uuid
, uuid
, WPS_UUID_LEN
) == 0)
628 /* Check for wildcard UUIDs since none of the UUID-specific
632 if (pin
->wildcard_uuid
== 1) {
633 wpa_printf(MSG_DEBUG
, "WPS: Found a wildcard "
634 "PIN. Assigned it for this UUID-E");
635 pin
->wildcard_uuid
= 2;
636 os_memcpy(pin
->uuid
, uuid
, WPS_UUID_LEN
);
647 * Lock the PIN to avoid attacks based on concurrent re-use of the PIN
648 * that could otherwise avoid PIN invalidations.
650 if (pin
->flags
& PIN_LOCKED
) {
651 wpa_printf(MSG_DEBUG
, "WPS: Selected PIN locked - do not "
652 "allow concurrent re-use");
655 *pin_len
= pin
->pin_len
;
656 pin
->flags
|= PIN_LOCKED
;
662 * wps_registrar_unlock_pin - Unlock a PIN for a specific UUID-E
663 * @reg: Registrar data from wps_registrar_init()
665 * Returns: 0 on success, -1 on failure
667 * PINs are locked to enforce only one concurrent use. This function unlocks a
668 * PIN to allow it to be used again. If the specified PIN was configured using
669 * a wildcard UUID, it will be removed instead of allowing multiple uses.
671 int wps_registrar_unlock_pin(struct wps_registrar
*reg
, const u8
*uuid
)
673 struct wps_uuid_pin
*pin
;
677 if (os_memcmp(pin
->uuid
, uuid
, WPS_UUID_LEN
) == 0) {
678 if (pin
->wildcard_uuid
== 2) {
679 wpa_printf(MSG_DEBUG
, "WPS: Invalidating used "
681 return wps_registrar_invalidate_pin(reg
, uuid
);
683 pin
->flags
&= ~PIN_LOCKED
;
693 static void wps_registrar_stop_pbc(struct wps_registrar
*reg
)
695 reg
->selected_registrar
= 0;
698 wps_cb_set_sel_reg(reg
);
702 static void wps_registrar_pbc_timeout(void *eloop_ctx
, void *timeout_ctx
)
704 struct wps_registrar
*reg
= eloop_ctx
;
706 wpa_printf(MSG_DEBUG
, "WPS: PBC timed out - disable PBC mode");
707 wps_pbc_timeout_event(reg
->wps
);
708 wps_registrar_stop_pbc(reg
);
713 * wps_registrar_button_pushed - Notify Registrar that AP button was pushed
714 * @reg: Registrar data from wps_registrar_init()
715 * Returns: 0 on success, -1 on failure
717 * This function is called on an AP when a push button is pushed to activate
718 * PBC mode. The PBC mode will be stopped after walk time (2 minutes) timeout
719 * or when a PBC registration is completed.
721 int wps_registrar_button_pushed(struct wps_registrar
*reg
)
723 if (wps_registrar_pbc_overlap(reg
, NULL
, NULL
)) {
724 wpa_printf(MSG_DEBUG
, "WPS: PBC overlap - do not start PBC "
726 wps_pbc_overlap_event(reg
->wps
);
729 wpa_printf(MSG_DEBUG
, "WPS: Button pushed - PBC mode started");
730 reg
->force_pbc_overlap
= 0;
731 reg
->selected_registrar
= 1;
734 wps_cb_set_sel_reg(reg
);
736 eloop_cancel_timeout(wps_registrar_pbc_timeout
, reg
, NULL
);
737 eloop_register_timeout(WPS_PBC_WALK_TIME
, 0, wps_registrar_pbc_timeout
,
743 static void wps_registrar_pbc_completed(struct wps_registrar
*reg
)
745 wpa_printf(MSG_DEBUG
, "WPS: PBC completed - stopping PBC mode");
746 eloop_cancel_timeout(wps_registrar_pbc_timeout
, reg
, NULL
);
747 wps_registrar_stop_pbc(reg
);
750 static void wps_registrar_pin_completed(struct wps_registrar
*reg
)
752 wpa_printf(MSG_DEBUG
, "WPS: PIN completed using internal Registrar");
753 eloop_cancel_timeout(wps_registrar_set_selected_timeout
, reg
, NULL
);
754 reg
->selected_registrar
= 0;
756 wps_cb_set_sel_reg(reg
);
761 * wps_registrar_probe_req_rx - Notify Registrar of Probe Request
762 * @reg: Registrar data from wps_registrar_init()
763 * @addr: MAC address of the Probe Request sender
764 * @wps_data: WPS IE contents
766 * This function is called on an AP when a Probe Request with WPS IE is
767 * received. This is used to track PBC mode use and to detect possible overlap
768 * situation with other WPS APs.
770 void wps_registrar_probe_req_rx(struct wps_registrar
*reg
, const u8
*addr
,
771 const struct wpabuf
*wps_data
)
773 struct wps_parse_attr attr
;
776 wpa_hexdump_buf(MSG_MSGDUMP
,
777 "WPS: Probe Request with WPS data received",
780 if (wps_parse_msg(wps_data
, &attr
) < 0)
782 if (!wps_version_supported(attr
.version
)) {
783 wpa_printf(MSG_DEBUG
, "WPS: Unsupported ProbeReq WPS IE "
784 "version 0x%x", attr
.version
? *attr
.version
: 0);
788 if (attr
.config_methods
== NULL
) {
789 wpa_printf(MSG_DEBUG
, "WPS: No Config Methods attribute in "
794 methods
= WPA_GET_BE16(attr
.config_methods
);
795 if (!(methods
& WPS_CONFIG_PUSHBUTTON
))
796 return; /* Not PBC */
798 wpa_printf(MSG_DEBUG
, "WPS: Probe Request for PBC received from "
799 MACSTR
, MAC2STR(addr
));
801 wps_registrar_add_pbc_session(reg
, addr
, attr
.uuid_e
);
802 if (wps_registrar_pbc_overlap(reg
, addr
, attr
.uuid_e
)) {
803 wpa_printf(MSG_DEBUG
, "WPS: PBC session overlap detected");
804 reg
->force_pbc_overlap
= 1;
805 wps_pbc_overlap_event(reg
->wps
);
810 static int wps_cb_new_psk(struct wps_registrar
*reg
, const u8
*mac_addr
,
811 const u8
*psk
, size_t psk_len
)
813 if (reg
->new_psk_cb
== NULL
)
816 return reg
->new_psk_cb(reg
->cb_ctx
, mac_addr
, psk
, psk_len
);
820 static void wps_cb_pin_needed(struct wps_registrar
*reg
, const u8
*uuid_e
,
821 const struct wps_device_data
*dev
)
823 if (reg
->pin_needed_cb
== NULL
)
826 reg
->pin_needed_cb(reg
->cb_ctx
, uuid_e
, dev
);
830 static void wps_cb_reg_success(struct wps_registrar
*reg
, const u8
*mac_addr
,
833 if (reg
->reg_success_cb
== NULL
)
836 reg
->reg_success_cb(reg
->cb_ctx
, mac_addr
, uuid_e
);
840 static int wps_cb_set_ie(struct wps_registrar
*reg
,
841 const struct wpabuf
*beacon_ie
,
842 const struct wpabuf
*probe_resp_ie
)
844 if (reg
->set_ie_cb
== NULL
)
847 return reg
->set_ie_cb(reg
->cb_ctx
, wpabuf_head(beacon_ie
),
848 wpabuf_len(beacon_ie
),
849 wpabuf_head(probe_resp_ie
),
850 wpabuf_len(probe_resp_ie
));
854 static void wps_cb_set_sel_reg(struct wps_registrar
*reg
)
857 if (reg
->set_sel_reg_cb
== NULL
)
860 if (reg
->selected_registrar
) {
861 methods
= reg
->wps
->config_methods
& ~WPS_CONFIG_PUSHBUTTON
;
863 methods
|= WPS_CONFIG_PUSHBUTTON
;
866 reg
->set_sel_reg_cb(reg
->cb_ctx
, reg
->selected_registrar
,
867 reg
->pbc
? DEV_PW_PUSHBUTTON
: DEV_PW_DEFAULT
,
872 /* Encapsulate WPS IE data with one (or more, if needed) IE headers */
873 static struct wpabuf
* wps_ie_encapsulate(struct wpabuf
*data
)
878 ie
= wpabuf_alloc(wpabuf_len(data
) + 100);
884 pos
= wpabuf_head(data
);
885 end
= pos
+ wpabuf_len(data
);
888 size_t frag_len
= end
- pos
;
891 wpabuf_put_u8(ie
, WLAN_EID_VENDOR_SPECIFIC
);
892 wpabuf_put_u8(ie
, 4 + frag_len
);
893 wpabuf_put_be32(ie
, WPS_DEV_OUI_WFA
);
894 wpabuf_put_data(ie
, pos
, frag_len
);
904 static int wps_set_ie(struct wps_registrar
*reg
)
906 struct wpabuf
*beacon
;
907 struct wpabuf
*probe
;
910 wpa_printf(MSG_DEBUG
, "WPS: Build Beacon and Probe Response IEs");
912 beacon
= wpabuf_alloc(300);
915 probe
= wpabuf_alloc(400);
921 if (wps_build_version(beacon
) ||
922 wps_build_wps_state(reg
->wps
, beacon
) ||
923 wps_build_ap_setup_locked(reg
->wps
, beacon
) ||
924 wps_build_selected_registrar(reg
, beacon
) ||
925 wps_build_sel_reg_dev_password_id(reg
, beacon
) ||
926 wps_build_sel_reg_config_methods(reg
, beacon
) ||
927 wps_build_version(probe
) ||
928 wps_build_wps_state(reg
->wps
, probe
) ||
929 wps_build_ap_setup_locked(reg
->wps
, probe
) ||
930 wps_build_selected_registrar(reg
, probe
) ||
931 wps_build_sel_reg_dev_password_id(reg
, probe
) ||
932 wps_build_sel_reg_config_methods(reg
, probe
) ||
933 wps_build_resp_type(reg
, probe
) ||
934 wps_build_uuid_e(probe
, reg
->wps
->uuid
) ||
935 wps_build_device_attrs(®
->wps
->dev
, probe
) ||
936 wps_build_probe_config_methods(reg
, probe
) ||
937 wps_build_rf_bands(®
->wps
->dev
, probe
)) {
943 beacon
= wps_ie_encapsulate(beacon
);
944 probe
= wps_ie_encapsulate(probe
);
946 if (!beacon
|| !probe
) {
952 if (reg
->static_wep_only
) {
954 * Windows XP and Vista clients can get confused about
955 * EAP-Identity/Request when they probe the network with
956 * EAPOL-Start. In such a case, they may assume the network is
957 * using IEEE 802.1X and prompt user for a certificate while
958 * the correct (non-WPS) behavior would be to ask for the
959 * static WEP key. As a workaround, use Microsoft Provisioning
960 * IE to advertise that legacy 802.1X is not supported.
962 const u8 ms_wps
[7] = {
963 WLAN_EID_VENDOR_SPECIFIC
, 5,
964 /* Microsoft Provisioning IE (00:50:f2:5) */
966 0x00 /* no legacy 802.1X or MS WPS */
968 wpa_printf(MSG_DEBUG
, "WPS: Add Microsoft Provisioning IE "
969 "into Beacon/Probe Response frames");
970 wpabuf_put_data(beacon
, ms_wps
, sizeof(ms_wps
));
971 wpabuf_put_data(probe
, ms_wps
, sizeof(ms_wps
));
974 ret
= wps_cb_set_ie(reg
, beacon
, probe
);
982 static int wps_get_dev_password(struct wps_data
*wps
)
987 os_free(wps
->dev_password
);
988 wps
->dev_password
= NULL
;
991 wpa_printf(MSG_DEBUG
, "WPS: Use default PIN for PBC");
992 pin
= (const u8
*) "00000000";
995 pin
= wps_registrar_get_pin(wps
->wps
->registrar
, wps
->uuid_e
,
999 wpa_printf(MSG_DEBUG
, "WPS: No Device Password available for "
1001 wps_cb_pin_needed(wps
->wps
->registrar
, wps
->uuid_e
,
1006 wps
->dev_password
= os_malloc(pin_len
);
1007 if (wps
->dev_password
== NULL
)
1009 os_memcpy(wps
->dev_password
, pin
, pin_len
);
1010 wps
->dev_password_len
= pin_len
;
1016 static int wps_build_uuid_r(struct wps_data
*wps
, struct wpabuf
*msg
)
1018 wpa_printf(MSG_DEBUG
, "WPS: * UUID-R");
1019 wpabuf_put_be16(msg
, ATTR_UUID_R
);
1020 wpabuf_put_be16(msg
, WPS_UUID_LEN
);
1021 wpabuf_put_data(msg
, wps
->uuid_r
, WPS_UUID_LEN
);
1026 static int wps_build_r_hash(struct wps_data
*wps
, struct wpabuf
*msg
)
1032 if (os_get_random(wps
->snonce
, 2 * WPS_SECRET_NONCE_LEN
) < 0)
1034 wpa_hexdump(MSG_DEBUG
, "WPS: R-S1", wps
->snonce
, WPS_SECRET_NONCE_LEN
);
1035 wpa_hexdump(MSG_DEBUG
, "WPS: R-S2",
1036 wps
->snonce
+ WPS_SECRET_NONCE_LEN
, WPS_SECRET_NONCE_LEN
);
1038 if (wps
->dh_pubkey_e
== NULL
|| wps
->dh_pubkey_r
== NULL
) {
1039 wpa_printf(MSG_DEBUG
, "WPS: DH public keys not available for "
1040 "R-Hash derivation");
1044 wpa_printf(MSG_DEBUG
, "WPS: * R-Hash1");
1045 wpabuf_put_be16(msg
, ATTR_R_HASH1
);
1046 wpabuf_put_be16(msg
, SHA256_MAC_LEN
);
1047 hash
= wpabuf_put(msg
, SHA256_MAC_LEN
);
1048 /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
1049 addr
[0] = wps
->snonce
;
1050 len
[0] = WPS_SECRET_NONCE_LEN
;
1051 addr
[1] = wps
->psk1
;
1052 len
[1] = WPS_PSK_LEN
;
1053 addr
[2] = wpabuf_head(wps
->dh_pubkey_e
);
1054 len
[2] = wpabuf_len(wps
->dh_pubkey_e
);
1055 addr
[3] = wpabuf_head(wps
->dh_pubkey_r
);
1056 len
[3] = wpabuf_len(wps
->dh_pubkey_r
);
1057 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
1058 wpa_hexdump(MSG_DEBUG
, "WPS: R-Hash1", hash
, SHA256_MAC_LEN
);
1060 wpa_printf(MSG_DEBUG
, "WPS: * R-Hash2");
1061 wpabuf_put_be16(msg
, ATTR_R_HASH2
);
1062 wpabuf_put_be16(msg
, SHA256_MAC_LEN
);
1063 hash
= wpabuf_put(msg
, SHA256_MAC_LEN
);
1064 /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
1065 addr
[0] = wps
->snonce
+ WPS_SECRET_NONCE_LEN
;
1066 addr
[1] = wps
->psk2
;
1067 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
1068 wpa_hexdump(MSG_DEBUG
, "WPS: R-Hash2", hash
, SHA256_MAC_LEN
);
1074 static int wps_build_r_snonce1(struct wps_data
*wps
, struct wpabuf
*msg
)
1076 wpa_printf(MSG_DEBUG
, "WPS: * R-SNonce1");
1077 wpabuf_put_be16(msg
, ATTR_R_SNONCE1
);
1078 wpabuf_put_be16(msg
, WPS_SECRET_NONCE_LEN
);
1079 wpabuf_put_data(msg
, wps
->snonce
, WPS_SECRET_NONCE_LEN
);
1084 static int wps_build_r_snonce2(struct wps_data
*wps
, struct wpabuf
*msg
)
1086 wpa_printf(MSG_DEBUG
, "WPS: * R-SNonce2");
1087 wpabuf_put_be16(msg
, ATTR_R_SNONCE2
);
1088 wpabuf_put_be16(msg
, WPS_SECRET_NONCE_LEN
);
1089 wpabuf_put_data(msg
, wps
->snonce
+ WPS_SECRET_NONCE_LEN
,
1090 WPS_SECRET_NONCE_LEN
);
1095 static int wps_build_cred_network_idx(struct wpabuf
*msg
,
1096 const struct wps_credential
*cred
)
1098 wpa_printf(MSG_DEBUG
, "WPS: * Network Index");
1099 wpabuf_put_be16(msg
, ATTR_NETWORK_INDEX
);
1100 wpabuf_put_be16(msg
, 1);
1101 wpabuf_put_u8(msg
, 1);
1106 static int wps_build_cred_ssid(struct wpabuf
*msg
,
1107 const struct wps_credential
*cred
)
1109 wpa_printf(MSG_DEBUG
, "WPS: * SSID");
1110 wpabuf_put_be16(msg
, ATTR_SSID
);
1111 wpabuf_put_be16(msg
, cred
->ssid_len
);
1112 wpabuf_put_data(msg
, cred
->ssid
, cred
->ssid_len
);
1117 static int wps_build_cred_auth_type(struct wpabuf
*msg
,
1118 const struct wps_credential
*cred
)
1120 wpa_printf(MSG_DEBUG
, "WPS: * Authentication Type (0x%x)",
1122 wpabuf_put_be16(msg
, ATTR_AUTH_TYPE
);
1123 wpabuf_put_be16(msg
, 2);
1124 wpabuf_put_be16(msg
, cred
->auth_type
);
1129 static int wps_build_cred_encr_type(struct wpabuf
*msg
,
1130 const struct wps_credential
*cred
)
1132 wpa_printf(MSG_DEBUG
, "WPS: * Encryption Type (0x%x)",
1134 wpabuf_put_be16(msg
, ATTR_ENCR_TYPE
);
1135 wpabuf_put_be16(msg
, 2);
1136 wpabuf_put_be16(msg
, cred
->encr_type
);
1141 static int wps_build_cred_network_key(struct wpabuf
*msg
,
1142 const struct wps_credential
*cred
)
1144 wpa_printf(MSG_DEBUG
, "WPS: * Network Key");
1145 wpabuf_put_be16(msg
, ATTR_NETWORK_KEY
);
1146 wpabuf_put_be16(msg
, cred
->key_len
);
1147 wpabuf_put_data(msg
, cred
->key
, cred
->key_len
);
1152 static int wps_build_cred_mac_addr(struct wpabuf
*msg
,
1153 const struct wps_credential
*cred
)
1155 wpa_printf(MSG_DEBUG
, "WPS: * MAC Address (" MACSTR
")",
1156 MAC2STR(cred
->mac_addr
));
1157 wpabuf_put_be16(msg
, ATTR_MAC_ADDR
);
1158 wpabuf_put_be16(msg
, ETH_ALEN
);
1159 wpabuf_put_data(msg
, cred
->mac_addr
, ETH_ALEN
);
1164 static int wps_build_credential(struct wpabuf
*msg
,
1165 const struct wps_credential
*cred
)
1167 if (wps_build_cred_network_idx(msg
, cred
) ||
1168 wps_build_cred_ssid(msg
, cred
) ||
1169 wps_build_cred_auth_type(msg
, cred
) ||
1170 wps_build_cred_encr_type(msg
, cred
) ||
1171 wps_build_cred_network_key(msg
, cred
) ||
1172 wps_build_cred_mac_addr(msg
, cred
))
1178 int wps_build_cred(struct wps_data
*wps
, struct wpabuf
*msg
)
1180 struct wpabuf
*cred
;
1182 if (wps
->wps
->registrar
->skip_cred_build
)
1183 goto skip_cred_build
;
1185 wpa_printf(MSG_DEBUG
, "WPS: * Credential");
1186 if (wps
->use_cred
) {
1187 os_memcpy(&wps
->cred
, wps
->use_cred
, sizeof(wps
->cred
));
1190 os_memset(&wps
->cred
, 0, sizeof(wps
->cred
));
1192 os_memcpy(wps
->cred
.ssid
, wps
->wps
->ssid
, wps
->wps
->ssid_len
);
1193 wps
->cred
.ssid_len
= wps
->wps
->ssid_len
;
1195 /* Select the best authentication and encryption type */
1196 if (wps
->auth_type
& WPS_AUTH_WPA2PSK
)
1197 wps
->auth_type
= WPS_AUTH_WPA2PSK
;
1198 else if (wps
->auth_type
& WPS_AUTH_WPAPSK
)
1199 wps
->auth_type
= WPS_AUTH_WPAPSK
;
1200 else if (wps
->auth_type
& WPS_AUTH_OPEN
)
1201 wps
->auth_type
= WPS_AUTH_OPEN
;
1202 else if (wps
->auth_type
& WPS_AUTH_SHARED
)
1203 wps
->auth_type
= WPS_AUTH_SHARED
;
1205 wpa_printf(MSG_DEBUG
, "WPS: Unsupported auth_type 0x%x",
1209 wps
->cred
.auth_type
= wps
->auth_type
;
1211 if (wps
->auth_type
== WPS_AUTH_WPA2PSK
||
1212 wps
->auth_type
== WPS_AUTH_WPAPSK
) {
1213 if (wps
->encr_type
& WPS_ENCR_AES
)
1214 wps
->encr_type
= WPS_ENCR_AES
;
1215 else if (wps
->encr_type
& WPS_ENCR_TKIP
)
1216 wps
->encr_type
= WPS_ENCR_TKIP
;
1218 wpa_printf(MSG_DEBUG
, "WPS: No suitable encryption "
1219 "type for WPA/WPA2");
1223 if (wps
->encr_type
& WPS_ENCR_WEP
)
1224 wps
->encr_type
= WPS_ENCR_WEP
;
1225 else if (wps
->encr_type
& WPS_ENCR_NONE
)
1226 wps
->encr_type
= WPS_ENCR_NONE
;
1228 wpa_printf(MSG_DEBUG
, "WPS: No suitable encryption "
1229 "type for non-WPA/WPA2 mode");
1233 wps
->cred
.encr_type
= wps
->encr_type
;
1235 * Set MAC address in the Credential to be the Enrollee's MAC address
1237 os_memcpy(wps
->cred
.mac_addr
, wps
->mac_addr_e
, ETH_ALEN
);
1239 if (wps
->wps
->wps_state
== WPS_STATE_NOT_CONFIGURED
&& wps
->wps
->ap
&&
1240 !wps
->wps
->registrar
->disable_auto_conf
) {
1242 /* Generate a random passphrase */
1243 if (os_get_random(r
, sizeof(r
)) < 0)
1245 os_free(wps
->new_psk
);
1246 wps
->new_psk
= base64_encode(r
, sizeof(r
), &wps
->new_psk_len
);
1247 if (wps
->new_psk
== NULL
)
1249 wps
->new_psk_len
--; /* remove newline */
1250 while (wps
->new_psk_len
&&
1251 wps
->new_psk
[wps
->new_psk_len
- 1] == '=')
1253 wpa_hexdump_ascii_key(MSG_DEBUG
, "WPS: Generated passphrase",
1254 wps
->new_psk
, wps
->new_psk_len
);
1255 os_memcpy(wps
->cred
.key
, wps
->new_psk
, wps
->new_psk_len
);
1256 wps
->cred
.key_len
= wps
->new_psk_len
;
1257 } else if (wps
->wps
->network_key
) {
1258 os_memcpy(wps
->cred
.key
, wps
->wps
->network_key
,
1259 wps
->wps
->network_key_len
);
1260 wps
->cred
.key_len
= wps
->wps
->network_key_len
;
1261 } else if (wps
->auth_type
& (WPS_AUTH_WPAPSK
| WPS_AUTH_WPA2PSK
)) {
1263 /* Generate a random per-device PSK */
1264 os_free(wps
->new_psk
);
1265 wps
->new_psk_len
= 32;
1266 wps
->new_psk
= os_malloc(wps
->new_psk_len
);
1267 if (wps
->new_psk
== NULL
)
1269 if (os_get_random(wps
->new_psk
, wps
->new_psk_len
) < 0) {
1270 os_free(wps
->new_psk
);
1271 wps
->new_psk
= NULL
;
1274 wpa_hexdump_key(MSG_DEBUG
, "WPS: Generated per-device PSK",
1275 wps
->new_psk
, wps
->new_psk_len
);
1276 wpa_snprintf_hex(hex
, sizeof(hex
), wps
->new_psk
,
1278 os_memcpy(wps
->cred
.key
, hex
, wps
->new_psk_len
* 2);
1279 wps
->cred
.key_len
= wps
->new_psk_len
* 2;
1283 cred
= wpabuf_alloc(200);
1287 if (wps_build_credential(cred
, &wps
->cred
)) {
1292 wpabuf_put_be16(msg
, ATTR_CRED
);
1293 wpabuf_put_be16(msg
, wpabuf_len(cred
));
1294 wpabuf_put_buf(msg
, cred
);
1298 if (wps
->wps
->registrar
->extra_cred
) {
1299 wpa_printf(MSG_DEBUG
, "WPS: * Credential (pre-configured)");
1300 wpabuf_put_buf(msg
, wps
->wps
->registrar
->extra_cred
);
1307 static int wps_build_ap_settings(struct wps_data
*wps
, struct wpabuf
*msg
)
1309 wpa_printf(MSG_DEBUG
, "WPS: * AP Settings");
1311 if (wps_build_credential(msg
, &wps
->cred
))
1318 static struct wpabuf
* wps_build_m2(struct wps_data
*wps
)
1322 if (os_get_random(wps
->nonce_r
, WPS_NONCE_LEN
) < 0)
1324 wpa_hexdump(MSG_DEBUG
, "WPS: Registrar Nonce",
1325 wps
->nonce_r
, WPS_NONCE_LEN
);
1326 wpa_hexdump(MSG_DEBUG
, "WPS: UUID-R", wps
->uuid_r
, WPS_UUID_LEN
);
1328 wpa_printf(MSG_DEBUG
, "WPS: Building Message M2");
1329 msg
= wpabuf_alloc(1000);
1333 if (wps_build_version(msg
) ||
1334 wps_build_msg_type(msg
, WPS_M2
) ||
1335 wps_build_enrollee_nonce(wps
, msg
) ||
1336 wps_build_registrar_nonce(wps
, msg
) ||
1337 wps_build_uuid_r(wps
, msg
) ||
1338 wps_build_public_key(wps
, msg
) ||
1339 wps_derive_keys(wps
) ||
1340 wps_build_auth_type_flags(wps
, msg
) ||
1341 wps_build_encr_type_flags(wps
, msg
) ||
1342 wps_build_conn_type_flags(wps
, msg
) ||
1343 wps_build_config_methods_r(wps
->wps
->registrar
, msg
) ||
1344 wps_build_device_attrs(&wps
->wps
->dev
, msg
) ||
1345 wps_build_rf_bands(&wps
->wps
->dev
, msg
) ||
1346 wps_build_assoc_state(wps
, msg
) ||
1347 wps_build_config_error(msg
, WPS_CFG_NO_ERROR
) ||
1348 wps_build_dev_password_id(msg
, wps
->dev_pw_id
) ||
1349 wps_build_os_version(&wps
->wps
->dev
, msg
) ||
1350 wps_build_authenticator(wps
, msg
)) {
1355 wps
->state
= RECV_M3
;
1360 static struct wpabuf
* wps_build_m2d(struct wps_data
*wps
)
1363 u16 err
= wps
->config_error
;
1365 wpa_printf(MSG_DEBUG
, "WPS: Building Message M2D");
1366 msg
= wpabuf_alloc(1000);
1370 if (wps
->wps
->ap
&& wps
->wps
->ap_setup_locked
&&
1371 err
== WPS_CFG_NO_ERROR
)
1372 err
= WPS_CFG_SETUP_LOCKED
;
1374 if (wps_build_version(msg
) ||
1375 wps_build_msg_type(msg
, WPS_M2D
) ||
1376 wps_build_enrollee_nonce(wps
, msg
) ||
1377 wps_build_registrar_nonce(wps
, msg
) ||
1378 wps_build_uuid_r(wps
, msg
) ||
1379 wps_build_auth_type_flags(wps
, msg
) ||
1380 wps_build_encr_type_flags(wps
, msg
) ||
1381 wps_build_conn_type_flags(wps
, msg
) ||
1382 wps_build_config_methods_r(wps
->wps
->registrar
, msg
) ||
1383 wps_build_device_attrs(&wps
->wps
->dev
, msg
) ||
1384 wps_build_rf_bands(&wps
->wps
->dev
, msg
) ||
1385 wps_build_assoc_state(wps
, msg
) ||
1386 wps_build_config_error(msg
, err
) ||
1387 wps_build_os_version(&wps
->wps
->dev
, msg
)) {
1392 wps
->state
= RECV_M2D_ACK
;
1397 static struct wpabuf
* wps_build_m4(struct wps_data
*wps
)
1399 struct wpabuf
*msg
, *plain
;
1401 wpa_printf(MSG_DEBUG
, "WPS: Building Message M4");
1403 wps_derive_psk(wps
, wps
->dev_password
, wps
->dev_password_len
);
1405 plain
= wpabuf_alloc(200);
1409 msg
= wpabuf_alloc(1000);
1415 if (wps_build_version(msg
) ||
1416 wps_build_msg_type(msg
, WPS_M4
) ||
1417 wps_build_enrollee_nonce(wps
, msg
) ||
1418 wps_build_r_hash(wps
, msg
) ||
1419 wps_build_r_snonce1(wps
, plain
) ||
1420 wps_build_key_wrap_auth(wps
, plain
) ||
1421 wps_build_encr_settings(wps
, msg
, plain
) ||
1422 wps_build_authenticator(wps
, msg
)) {
1429 wps
->state
= RECV_M5
;
1434 static struct wpabuf
* wps_build_m6(struct wps_data
*wps
)
1436 struct wpabuf
*msg
, *plain
;
1438 wpa_printf(MSG_DEBUG
, "WPS: Building Message M6");
1440 plain
= wpabuf_alloc(200);
1444 msg
= wpabuf_alloc(1000);
1450 if (wps_build_version(msg
) ||
1451 wps_build_msg_type(msg
, WPS_M6
) ||
1452 wps_build_enrollee_nonce(wps
, msg
) ||
1453 wps_build_r_snonce2(wps
, plain
) ||
1454 wps_build_key_wrap_auth(wps
, plain
) ||
1455 wps_build_encr_settings(wps
, msg
, plain
) ||
1456 wps_build_authenticator(wps
, msg
)) {
1463 wps
->wps_pin_revealed
= 1;
1464 wps
->state
= RECV_M7
;
1469 static struct wpabuf
* wps_build_m8(struct wps_data
*wps
)
1471 struct wpabuf
*msg
, *plain
;
1473 wpa_printf(MSG_DEBUG
, "WPS: Building Message M8");
1475 plain
= wpabuf_alloc(500);
1479 msg
= wpabuf_alloc(1000);
1485 if (wps_build_version(msg
) ||
1486 wps_build_msg_type(msg
, WPS_M8
) ||
1487 wps_build_enrollee_nonce(wps
, msg
) ||
1488 ((wps
->wps
->ap
|| wps
->er
) && wps_build_cred(wps
, plain
)) ||
1489 (!wps
->wps
->ap
&& !wps
->er
&& wps_build_ap_settings(wps
, plain
)) ||
1490 wps_build_key_wrap_auth(wps
, plain
) ||
1491 wps_build_encr_settings(wps
, msg
, plain
) ||
1492 wps_build_authenticator(wps
, msg
)) {
1499 wps
->state
= RECV_DONE
;
1504 static struct wpabuf
* wps_build_wsc_ack(struct wps_data
*wps
)
1508 wpa_printf(MSG_DEBUG
, "WPS: Building Message WSC_ACK");
1510 msg
= wpabuf_alloc(1000);
1514 if (wps_build_version(msg
) ||
1515 wps_build_msg_type(msg
, WPS_WSC_ACK
) ||
1516 wps_build_enrollee_nonce(wps
, msg
) ||
1517 wps_build_registrar_nonce(wps
, msg
)) {
1526 static struct wpabuf
* wps_build_wsc_nack(struct wps_data
*wps
)
1530 wpa_printf(MSG_DEBUG
, "WPS: Building Message WSC_NACK");
1532 msg
= wpabuf_alloc(1000);
1536 if (wps_build_version(msg
) ||
1537 wps_build_msg_type(msg
, WPS_WSC_NACK
) ||
1538 wps_build_enrollee_nonce(wps
, msg
) ||
1539 wps_build_registrar_nonce(wps
, msg
) ||
1540 wps_build_config_error(msg
, wps
->config_error
)) {
1549 struct wpabuf
* wps_registrar_get_msg(struct wps_data
*wps
,
1550 enum wsc_op_code
*op_code
)
1554 #ifdef CONFIG_WPS_UPNP
1555 if (wps
->wps
->wps_upnp
) {
1556 struct upnp_pending_message
*p
, *prev
= NULL
;
1557 if (wps
->ext_reg
> 1)
1558 wps_registrar_free_pending_m2(wps
->wps
);
1559 p
= wps
->wps
->upnp_msgs
;
1560 /* TODO: check pending message MAC address */
1561 while (p
&& p
->next
) {
1566 wpa_printf(MSG_DEBUG
, "WPS: Use pending message from "
1571 wps
->wps
->upnp_msgs
= NULL
;
1578 *op_code
= WSC_NACK
;
1585 if (wps
->ext_reg
== 0)
1591 wpa_printf(MSG_DEBUG
, "WPS: Using external Registrar, but no "
1592 "pending message available");
1595 #endif /* CONFIG_WPS_UPNP */
1597 switch (wps
->state
) {
1599 if (wps_get_dev_password(wps
) < 0)
1600 msg
= wps_build_m2d(wps
);
1602 msg
= wps_build_m2(wps
);
1606 msg
= wps_build_m2d(wps
);
1610 msg
= wps_build_m4(wps
);
1614 msg
= wps_build_m6(wps
);
1618 msg
= wps_build_m8(wps
);
1622 msg
= wps_build_wsc_ack(wps
);
1626 msg
= wps_build_wsc_nack(wps
);
1627 *op_code
= WSC_NACK
;
1630 wpa_printf(MSG_DEBUG
, "WPS: Unsupported state %d for building "
1631 "a message", wps
->state
);
1636 if (*op_code
== WSC_MSG
&& msg
) {
1637 /* Save a copy of the last message for Authenticator derivation
1639 wpabuf_free(wps
->last_msg
);
1640 wps
->last_msg
= wpabuf_dup(msg
);
1647 static int wps_process_enrollee_nonce(struct wps_data
*wps
, const u8
*e_nonce
)
1649 if (e_nonce
== NULL
) {
1650 wpa_printf(MSG_DEBUG
, "WPS: No Enrollee Nonce received");
1654 os_memcpy(wps
->nonce_e
, e_nonce
, WPS_NONCE_LEN
);
1655 wpa_hexdump(MSG_DEBUG
, "WPS: Enrollee Nonce",
1656 wps
->nonce_e
, WPS_NONCE_LEN
);
1662 static int wps_process_registrar_nonce(struct wps_data
*wps
, const u8
*r_nonce
)
1664 if (r_nonce
== NULL
) {
1665 wpa_printf(MSG_DEBUG
, "WPS: No Registrar Nonce received");
1669 if (os_memcmp(wps
->nonce_r
, r_nonce
, WPS_NONCE_LEN
) != 0) {
1670 wpa_printf(MSG_DEBUG
, "WPS: Invalid Registrar Nonce received");
1678 static int wps_process_uuid_e(struct wps_data
*wps
, const u8
*uuid_e
)
1680 if (uuid_e
== NULL
) {
1681 wpa_printf(MSG_DEBUG
, "WPS: No UUID-E received");
1685 os_memcpy(wps
->uuid_e
, uuid_e
, WPS_UUID_LEN
);
1686 wpa_hexdump(MSG_DEBUG
, "WPS: UUID-E", wps
->uuid_e
, WPS_UUID_LEN
);
1692 static int wps_process_dev_password_id(struct wps_data
*wps
, const u8
*pw_id
)
1694 if (pw_id
== NULL
) {
1695 wpa_printf(MSG_DEBUG
, "WPS: No Device Password ID received");
1699 wps
->dev_pw_id
= WPA_GET_BE16(pw_id
);
1700 wpa_printf(MSG_DEBUG
, "WPS: Device Password ID %d", wps
->dev_pw_id
);
1706 static int wps_process_e_hash1(struct wps_data
*wps
, const u8
*e_hash1
)
1708 if (e_hash1
== NULL
) {
1709 wpa_printf(MSG_DEBUG
, "WPS: No E-Hash1 received");
1713 os_memcpy(wps
->peer_hash1
, e_hash1
, WPS_HASH_LEN
);
1714 wpa_hexdump(MSG_DEBUG
, "WPS: E-Hash1", wps
->peer_hash1
, WPS_HASH_LEN
);
1720 static int wps_process_e_hash2(struct wps_data
*wps
, const u8
*e_hash2
)
1722 if (e_hash2
== NULL
) {
1723 wpa_printf(MSG_DEBUG
, "WPS: No E-Hash2 received");
1727 os_memcpy(wps
->peer_hash2
, e_hash2
, WPS_HASH_LEN
);
1728 wpa_hexdump(MSG_DEBUG
, "WPS: E-Hash2", wps
->peer_hash2
, WPS_HASH_LEN
);
1734 static int wps_process_e_snonce1(struct wps_data
*wps
, const u8
*e_snonce1
)
1736 u8 hash
[SHA256_MAC_LEN
];
1740 if (e_snonce1
== NULL
) {
1741 wpa_printf(MSG_DEBUG
, "WPS: No E-SNonce1 received");
1745 wpa_hexdump_key(MSG_DEBUG
, "WPS: E-SNonce1", e_snonce1
,
1746 WPS_SECRET_NONCE_LEN
);
1748 /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
1749 addr
[0] = e_snonce1
;
1750 len
[0] = WPS_SECRET_NONCE_LEN
;
1751 addr
[1] = wps
->psk1
;
1752 len
[1] = WPS_PSK_LEN
;
1753 addr
[2] = wpabuf_head(wps
->dh_pubkey_e
);
1754 len
[2] = wpabuf_len(wps
->dh_pubkey_e
);
1755 addr
[3] = wpabuf_head(wps
->dh_pubkey_r
);
1756 len
[3] = wpabuf_len(wps
->dh_pubkey_r
);
1757 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
1759 if (os_memcmp(wps
->peer_hash1
, hash
, WPS_HASH_LEN
) != 0) {
1760 wpa_printf(MSG_DEBUG
, "WPS: E-Hash1 derived from E-S1 does "
1761 "not match with the pre-committed value");
1762 wps
->config_error
= WPS_CFG_DEV_PASSWORD_AUTH_FAILURE
;
1763 wps_pwd_auth_fail_event(wps
->wps
, 0, 1);
1767 wpa_printf(MSG_DEBUG
, "WPS: Enrollee proved knowledge of the first "
1768 "half of the device password");
1774 static int wps_process_e_snonce2(struct wps_data
*wps
, const u8
*e_snonce2
)
1776 u8 hash
[SHA256_MAC_LEN
];
1780 if (e_snonce2
== NULL
) {
1781 wpa_printf(MSG_DEBUG
, "WPS: No E-SNonce2 received");
1785 wpa_hexdump_key(MSG_DEBUG
, "WPS: E-SNonce2", e_snonce2
,
1786 WPS_SECRET_NONCE_LEN
);
1788 /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
1789 addr
[0] = e_snonce2
;
1790 len
[0] = WPS_SECRET_NONCE_LEN
;
1791 addr
[1] = wps
->psk2
;
1792 len
[1] = WPS_PSK_LEN
;
1793 addr
[2] = wpabuf_head(wps
->dh_pubkey_e
);
1794 len
[2] = wpabuf_len(wps
->dh_pubkey_e
);
1795 addr
[3] = wpabuf_head(wps
->dh_pubkey_r
);
1796 len
[3] = wpabuf_len(wps
->dh_pubkey_r
);
1797 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
1799 if (os_memcmp(wps
->peer_hash2
, hash
, WPS_HASH_LEN
) != 0) {
1800 wpa_printf(MSG_DEBUG
, "WPS: E-Hash2 derived from E-S2 does "
1801 "not match with the pre-committed value");
1802 wps_registrar_invalidate_pin(wps
->wps
->registrar
, wps
->uuid_e
);
1803 wps
->config_error
= WPS_CFG_DEV_PASSWORD_AUTH_FAILURE
;
1804 wps_pwd_auth_fail_event(wps
->wps
, 0, 2);
1808 wpa_printf(MSG_DEBUG
, "WPS: Enrollee proved knowledge of the second "
1809 "half of the device password");
1810 wps
->wps_pin_revealed
= 0;
1811 wps_registrar_unlock_pin(wps
->wps
->registrar
, wps
->uuid_e
);
1817 static int wps_process_mac_addr(struct wps_data
*wps
, const u8
*mac_addr
)
1819 if (mac_addr
== NULL
) {
1820 wpa_printf(MSG_DEBUG
, "WPS: No MAC Address received");
1824 wpa_printf(MSG_DEBUG
, "WPS: Enrollee MAC Address " MACSTR
,
1826 os_memcpy(wps
->mac_addr_e
, mac_addr
, ETH_ALEN
);
1827 os_memcpy(wps
->peer_dev
.mac_addr
, mac_addr
, ETH_ALEN
);
1833 static int wps_process_pubkey(struct wps_data
*wps
, const u8
*pk
,
1836 if (pk
== NULL
|| pk_len
== 0) {
1837 wpa_printf(MSG_DEBUG
, "WPS: No Public Key received");
1841 #ifdef CONFIG_WPS_OOB
1842 if (wps
->wps
->oob_conf
.pubkey_hash
!= NULL
) {
1844 u8 hash
[WPS_HASH_LEN
];
1847 sha256_vector(1, addr
, &pk_len
, hash
);
1849 wpabuf_head(wps
->wps
->oob_conf
.pubkey_hash
),
1850 WPS_OOB_PUBKEY_HASH_LEN
) != 0) {
1851 wpa_printf(MSG_ERROR
, "WPS: Public Key hash error");
1855 #endif /* CONFIG_WPS_OOB */
1857 wpabuf_free(wps
->dh_pubkey_e
);
1858 wps
->dh_pubkey_e
= wpabuf_alloc_copy(pk
, pk_len
);
1859 if (wps
->dh_pubkey_e
== NULL
)
1866 static int wps_process_auth_type_flags(struct wps_data
*wps
, const u8
*auth
)
1871 wpa_printf(MSG_DEBUG
, "WPS: No Authentication Type flags "
1876 auth_types
= WPA_GET_BE16(auth
);
1878 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Authentication Type flags 0x%x",
1880 wps
->auth_type
= wps
->wps
->auth_types
& auth_types
;
1881 if (wps
->auth_type
== 0) {
1882 wpa_printf(MSG_DEBUG
, "WPS: No match in supported "
1883 "authentication types (own 0x%x Enrollee 0x%x)",
1884 wps
->wps
->auth_types
, auth_types
);
1885 #ifdef WPS_WORKAROUNDS
1887 * Some deployed implementations seem to advertise incorrect
1888 * information in this attribute. For example, Linksys WRT350N
1889 * seems to have a byteorder bug that breaks this negotiation.
1890 * In order to interoperate with existing implementations,
1891 * assume that the Enrollee supports everything we do.
1893 wpa_printf(MSG_DEBUG
, "WPS: Workaround - assume Enrollee "
1894 "does not advertise supported authentication types "
1896 wps
->auth_type
= wps
->wps
->auth_types
;
1897 #else /* WPS_WORKAROUNDS */
1899 #endif /* WPS_WORKAROUNDS */
1906 static int wps_process_encr_type_flags(struct wps_data
*wps
, const u8
*encr
)
1911 wpa_printf(MSG_DEBUG
, "WPS: No Encryption Type flags "
1916 encr_types
= WPA_GET_BE16(encr
);
1918 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Encryption Type flags 0x%x",
1920 wps
->encr_type
= wps
->wps
->encr_types
& encr_types
;
1921 if (wps
->encr_type
== 0) {
1922 wpa_printf(MSG_DEBUG
, "WPS: No match in supported "
1923 "encryption types (own 0x%x Enrollee 0x%x)",
1924 wps
->wps
->encr_types
, encr_types
);
1925 #ifdef WPS_WORKAROUNDS
1927 * Some deployed implementations seem to advertise incorrect
1928 * information in this attribute. For example, Linksys WRT350N
1929 * seems to have a byteorder bug that breaks this negotiation.
1930 * In order to interoperate with existing implementations,
1931 * assume that the Enrollee supports everything we do.
1933 wpa_printf(MSG_DEBUG
, "WPS: Workaround - assume Enrollee "
1934 "does not advertise supported encryption types "
1936 wps
->encr_type
= wps
->wps
->encr_types
;
1937 #else /* WPS_WORKAROUNDS */
1939 #endif /* WPS_WORKAROUNDS */
1946 static int wps_process_conn_type_flags(struct wps_data
*wps
, const u8
*conn
)
1949 wpa_printf(MSG_DEBUG
, "WPS: No Connection Type flags "
1954 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Connection Type flags 0x%x",
1961 static int wps_process_config_methods(struct wps_data
*wps
, const u8
*methods
)
1965 if (methods
== NULL
) {
1966 wpa_printf(MSG_DEBUG
, "WPS: No Config Methods received");
1970 m
= WPA_GET_BE16(methods
);
1972 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Config Methods 0x%x", m
);
1978 static int wps_process_wps_state(struct wps_data
*wps
, const u8
*state
)
1980 if (state
== NULL
) {
1981 wpa_printf(MSG_DEBUG
, "WPS: No Wi-Fi Protected Setup State "
1986 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Wi-Fi Protected Setup State %d",
1993 static int wps_process_assoc_state(struct wps_data
*wps
, const u8
*assoc
)
1997 if (assoc
== NULL
) {
1998 wpa_printf(MSG_DEBUG
, "WPS: No Association State received");
2002 a
= WPA_GET_BE16(assoc
);
2003 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Association State %d", a
);
2009 static int wps_process_config_error(struct wps_data
*wps
, const u8
*err
)
2014 wpa_printf(MSG_DEBUG
, "WPS: No Configuration Error received");
2018 e
= WPA_GET_BE16(err
);
2019 wpa_printf(MSG_DEBUG
, "WPS: Enrollee Configuration Error %d", e
);
2025 static enum wps_process_res
wps_process_m1(struct wps_data
*wps
,
2026 struct wps_parse_attr
*attr
)
2028 wpa_printf(MSG_DEBUG
, "WPS: Received M1");
2030 if (wps
->state
!= RECV_M1
) {
2031 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
2032 "receiving M1", wps
->state
);
2036 if (wps_process_uuid_e(wps
, attr
->uuid_e
) ||
2037 wps_process_mac_addr(wps
, attr
->mac_addr
) ||
2038 wps_process_enrollee_nonce(wps
, attr
->enrollee_nonce
) ||
2039 wps_process_pubkey(wps
, attr
->public_key
, attr
->public_key_len
) ||
2040 wps_process_auth_type_flags(wps
, attr
->auth_type_flags
) ||
2041 wps_process_encr_type_flags(wps
, attr
->encr_type_flags
) ||
2042 wps_process_conn_type_flags(wps
, attr
->conn_type_flags
) ||
2043 wps_process_config_methods(wps
, attr
->config_methods
) ||
2044 wps_process_wps_state(wps
, attr
->wps_state
) ||
2045 wps_process_device_attrs(&wps
->peer_dev
, attr
) ||
2046 wps_process_rf_bands(&wps
->peer_dev
, attr
->rf_bands
) ||
2047 wps_process_assoc_state(wps
, attr
->assoc_state
) ||
2048 wps_process_dev_password_id(wps
, attr
->dev_password_id
) ||
2049 wps_process_config_error(wps
, attr
->config_error
) ||
2050 wps_process_os_version(&wps
->peer_dev
, attr
->os_version
))
2053 if (wps
->dev_pw_id
< 0x10 &&
2054 wps
->dev_pw_id
!= DEV_PW_DEFAULT
&&
2055 wps
->dev_pw_id
!= DEV_PW_USER_SPECIFIED
&&
2056 wps
->dev_pw_id
!= DEV_PW_MACHINE_SPECIFIED
&&
2057 wps
->dev_pw_id
!= DEV_PW_REGISTRAR_SPECIFIED
&&
2058 (wps
->dev_pw_id
!= DEV_PW_PUSHBUTTON
||
2059 !wps
->wps
->registrar
->pbc
)) {
2060 wpa_printf(MSG_DEBUG
, "WPS: Unsupported Device Password ID %d",
2062 wps
->state
= SEND_M2D
;
2063 return WPS_CONTINUE
;
2066 #ifdef CONFIG_WPS_OOB
2067 if (wps
->dev_pw_id
>= 0x10 &&
2068 wps
->dev_pw_id
!= wps
->wps
->oob_dev_pw_id
) {
2069 wpa_printf(MSG_DEBUG
, "WPS: OOB Device Password ID "
2070 "%d mismatch", wps
->dev_pw_id
);
2071 wps
->state
= SEND_M2D
;
2072 return WPS_CONTINUE
;
2074 #endif /* CONFIG_WPS_OOB */
2076 if (wps
->dev_pw_id
== DEV_PW_PUSHBUTTON
) {
2077 if (wps
->wps
->registrar
->force_pbc_overlap
||
2078 wps_registrar_pbc_overlap(wps
->wps
->registrar
,
2079 wps
->mac_addr_e
, wps
->uuid_e
)) {
2080 wpa_printf(MSG_DEBUG
, "WPS: PBC overlap - deny PBC "
2082 wps
->state
= SEND_M2D
;
2083 wps
->config_error
= WPS_CFG_MULTIPLE_PBC_DETECTED
;
2084 wps_pbc_overlap_event(wps
->wps
);
2085 wps
->wps
->registrar
->force_pbc_overlap
= 1;
2086 return WPS_CONTINUE
;
2088 wps_registrar_add_pbc_session(wps
->wps
->registrar
,
2089 wps
->mac_addr_e
, wps
->uuid_e
);
2093 wps
->state
= SEND_M2
;
2094 return WPS_CONTINUE
;
2098 static enum wps_process_res
wps_process_m3(struct wps_data
*wps
,
2099 const struct wpabuf
*msg
,
2100 struct wps_parse_attr
*attr
)
2102 wpa_printf(MSG_DEBUG
, "WPS: Received M3");
2104 if (wps
->state
!= RECV_M3
) {
2105 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
2106 "receiving M3", wps
->state
);
2107 wps
->state
= SEND_WSC_NACK
;
2108 return WPS_CONTINUE
;
2111 if (wps
->pbc
&& wps
->wps
->registrar
->force_pbc_overlap
) {
2112 wpa_printf(MSG_DEBUG
, "WPS: Reject negotiation due to PBC "
2114 wps
->state
= SEND_WSC_NACK
;
2115 wps
->config_error
= WPS_CFG_MULTIPLE_PBC_DETECTED
;
2116 return WPS_CONTINUE
;
2119 if (wps_process_registrar_nonce(wps
, attr
->registrar_nonce
) ||
2120 wps_process_authenticator(wps
, attr
->authenticator
, msg
) ||
2121 wps_process_e_hash1(wps
, attr
->e_hash1
) ||
2122 wps_process_e_hash2(wps
, attr
->e_hash2
)) {
2123 wps
->state
= SEND_WSC_NACK
;
2124 return WPS_CONTINUE
;
2127 wps
->state
= SEND_M4
;
2128 return WPS_CONTINUE
;
2132 static enum wps_process_res
wps_process_m5(struct wps_data
*wps
,
2133 const struct wpabuf
*msg
,
2134 struct wps_parse_attr
*attr
)
2136 struct wpabuf
*decrypted
;
2137 struct wps_parse_attr eattr
;
2139 wpa_printf(MSG_DEBUG
, "WPS: Received M5");
2141 if (wps
->state
!= RECV_M5
) {
2142 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
2143 "receiving M5", wps
->state
);
2144 wps
->state
= SEND_WSC_NACK
;
2145 return WPS_CONTINUE
;
2148 if (wps
->pbc
&& wps
->wps
->registrar
->force_pbc_overlap
) {
2149 wpa_printf(MSG_DEBUG
, "WPS: Reject negotiation due to PBC "
2151 wps
->state
= SEND_WSC_NACK
;
2152 wps
->config_error
= WPS_CFG_MULTIPLE_PBC_DETECTED
;
2153 return WPS_CONTINUE
;
2156 if (wps_process_registrar_nonce(wps
, attr
->registrar_nonce
) ||
2157 wps_process_authenticator(wps
, attr
->authenticator
, msg
)) {
2158 wps
->state
= SEND_WSC_NACK
;
2159 return WPS_CONTINUE
;
2162 decrypted
= wps_decrypt_encr_settings(wps
, attr
->encr_settings
,
2163 attr
->encr_settings_len
);
2164 if (decrypted
== NULL
) {
2165 wpa_printf(MSG_DEBUG
, "WPS: Failed to decrypted Encrypted "
2166 "Settings attribute");
2167 wps
->state
= SEND_WSC_NACK
;
2168 return WPS_CONTINUE
;
2171 wpa_printf(MSG_DEBUG
, "WPS: Processing decrypted Encrypted Settings "
2173 if (wps_parse_msg(decrypted
, &eattr
) < 0 ||
2174 wps_process_key_wrap_auth(wps
, decrypted
, eattr
.key_wrap_auth
) ||
2175 wps_process_e_snonce1(wps
, eattr
.e_snonce1
)) {
2176 wpabuf_free(decrypted
);
2177 wps
->state
= SEND_WSC_NACK
;
2178 return WPS_CONTINUE
;
2180 wpabuf_free(decrypted
);
2182 wps
->state
= SEND_M6
;
2183 return WPS_CONTINUE
;
2187 static void wps_sta_cred_cb(struct wps_data
*wps
)
2190 * Update credential to only include a single authentication and
2191 * encryption type in case the AP configuration includes more than one
2194 if (wps
->cred
.auth_type
& WPS_AUTH_WPA2PSK
)
2195 wps
->cred
.auth_type
= WPS_AUTH_WPA2PSK
;
2196 else if (wps
->cred
.auth_type
& WPS_AUTH_WPAPSK
)
2197 wps
->cred
.auth_type
= WPS_AUTH_WPAPSK
;
2198 if (wps
->cred
.encr_type
& WPS_ENCR_AES
)
2199 wps
->cred
.encr_type
= WPS_ENCR_AES
;
2200 else if (wps
->cred
.encr_type
& WPS_ENCR_TKIP
)
2201 wps
->cred
.encr_type
= WPS_ENCR_TKIP
;
2202 wpa_printf(MSG_DEBUG
, "WPS: Update local configuration based on the "
2203 "AP configuration");
2204 if (wps
->wps
->cred_cb
)
2205 wps
->wps
->cred_cb(wps
->wps
->cb_ctx
, &wps
->cred
);
2209 static void wps_cred_update(struct wps_credential
*dst
,
2210 struct wps_credential
*src
)
2212 os_memcpy(dst
->ssid
, src
->ssid
, sizeof(dst
->ssid
));
2213 dst
->ssid_len
= src
->ssid_len
;
2214 dst
->auth_type
= src
->auth_type
;
2215 dst
->encr_type
= src
->encr_type
;
2216 dst
->key_idx
= src
->key_idx
;
2217 os_memcpy(dst
->key
, src
->key
, sizeof(dst
->key
));
2218 dst
->key_len
= src
->key_len
;
2222 static int wps_process_ap_settings_r(struct wps_data
*wps
,
2223 struct wps_parse_attr
*attr
)
2225 if (wps
->wps
->ap
|| wps
->er
)
2228 /* AP Settings Attributes in M7 when Enrollee is an AP */
2229 if (wps_process_ap_settings(attr
, &wps
->cred
) < 0)
2232 wpa_printf(MSG_INFO
, "WPS: Received old AP configuration from AP");
2234 if (wps
->new_ap_settings
) {
2235 wpa_printf(MSG_INFO
, "WPS: Update AP configuration based on "
2237 wps_cred_update(&wps
->cred
, wps
->new_ap_settings
);
2241 * Use the AP PIN only to receive the current AP settings, not
2242 * to reconfigure the AP.
2244 if (wps
->ap_settings_cb
) {
2245 wps
->ap_settings_cb(wps
->ap_settings_cb_ctx
,
2249 wps_sta_cred_cb(wps
);
2255 static enum wps_process_res
wps_process_m7(struct wps_data
*wps
,
2256 const struct wpabuf
*msg
,
2257 struct wps_parse_attr
*attr
)
2259 struct wpabuf
*decrypted
;
2260 struct wps_parse_attr eattr
;
2262 wpa_printf(MSG_DEBUG
, "WPS: Received M7");
2264 if (wps
->state
!= RECV_M7
) {
2265 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
2266 "receiving M7", wps
->state
);
2267 wps
->state
= SEND_WSC_NACK
;
2268 return WPS_CONTINUE
;
2271 if (wps
->pbc
&& wps
->wps
->registrar
->force_pbc_overlap
) {
2272 wpa_printf(MSG_DEBUG
, "WPS: Reject negotiation due to PBC "
2274 wps
->state
= SEND_WSC_NACK
;
2275 wps
->config_error
= WPS_CFG_MULTIPLE_PBC_DETECTED
;
2276 return WPS_CONTINUE
;
2279 if (wps_process_registrar_nonce(wps
, attr
->registrar_nonce
) ||
2280 wps_process_authenticator(wps
, attr
->authenticator
, msg
)) {
2281 wps
->state
= SEND_WSC_NACK
;
2282 return WPS_CONTINUE
;
2285 decrypted
= wps_decrypt_encr_settings(wps
, attr
->encr_settings
,
2286 attr
->encr_settings_len
);
2287 if (decrypted
== NULL
) {
2288 wpa_printf(MSG_DEBUG
, "WPS: Failed to decrypt Encrypted "
2289 "Settings attribute");
2290 wps
->state
= SEND_WSC_NACK
;
2291 return WPS_CONTINUE
;
2294 wpa_printf(MSG_DEBUG
, "WPS: Processing decrypted Encrypted Settings "
2296 if (wps_parse_msg(decrypted
, &eattr
) < 0 ||
2297 wps_process_key_wrap_auth(wps
, decrypted
, eattr
.key_wrap_auth
) ||
2298 wps_process_e_snonce2(wps
, eattr
.e_snonce2
) ||
2299 wps_process_ap_settings_r(wps
, &eattr
)) {
2300 wpabuf_free(decrypted
);
2301 wps
->state
= SEND_WSC_NACK
;
2302 return WPS_CONTINUE
;
2305 wpabuf_free(decrypted
);
2307 wps
->state
= SEND_M8
;
2308 return WPS_CONTINUE
;
2312 static enum wps_process_res
wps_process_wsc_msg(struct wps_data
*wps
,
2313 const struct wpabuf
*msg
)
2315 struct wps_parse_attr attr
;
2316 enum wps_process_res ret
= WPS_CONTINUE
;
2318 wpa_printf(MSG_DEBUG
, "WPS: Received WSC_MSG");
2320 if (wps_parse_msg(msg
, &attr
) < 0)
2323 if (!wps_version_supported(attr
.version
)) {
2324 wpa_printf(MSG_DEBUG
, "WPS: Unsupported message version 0x%x",
2325 attr
.version
? *attr
.version
: 0);
2329 if (attr
.msg_type
== NULL
) {
2330 wpa_printf(MSG_DEBUG
, "WPS: No Message Type attribute");
2334 if (*attr
.msg_type
!= WPS_M1
&&
2335 (attr
.registrar_nonce
== NULL
||
2336 os_memcmp(wps
->nonce_r
, attr
.registrar_nonce
,
2337 WPS_NONCE_LEN
!= 0))) {
2338 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in registrar nonce");
2342 switch (*attr
.msg_type
) {
2344 #ifdef CONFIG_WPS_UPNP
2345 if (wps
->wps
->wps_upnp
&& attr
.mac_addr
) {
2346 /* Remove old pending messages when starting new run */
2347 wps_free_pending_msgs(wps
->wps
->upnp_msgs
);
2348 wps
->wps
->upnp_msgs
= NULL
;
2350 upnp_wps_device_send_wlan_event(
2351 wps
->wps
->wps_upnp
, attr
.mac_addr
,
2352 UPNP_WPS_WLANEVENT_TYPE_EAP
, msg
);
2354 #endif /* CONFIG_WPS_UPNP */
2355 ret
= wps_process_m1(wps
, &attr
);
2358 ret
= wps_process_m3(wps
, msg
, &attr
);
2359 if (ret
== WPS_FAILURE
|| wps
->state
== SEND_WSC_NACK
)
2360 wps_fail_event(wps
->wps
, WPS_M3
);
2363 ret
= wps_process_m5(wps
, msg
, &attr
);
2364 if (ret
== WPS_FAILURE
|| wps
->state
== SEND_WSC_NACK
)
2365 wps_fail_event(wps
->wps
, WPS_M5
);
2368 ret
= wps_process_m7(wps
, msg
, &attr
);
2369 if (ret
== WPS_FAILURE
|| wps
->state
== SEND_WSC_NACK
)
2370 wps_fail_event(wps
->wps
, WPS_M7
);
2373 wpa_printf(MSG_DEBUG
, "WPS: Unsupported Message Type %d",
2378 if (ret
== WPS_CONTINUE
) {
2379 /* Save a copy of the last message for Authenticator derivation
2381 wpabuf_free(wps
->last_msg
);
2382 wps
->last_msg
= wpabuf_dup(msg
);
2389 static enum wps_process_res
wps_process_wsc_ack(struct wps_data
*wps
,
2390 const struct wpabuf
*msg
)
2392 struct wps_parse_attr attr
;
2394 wpa_printf(MSG_DEBUG
, "WPS: Received WSC_ACK");
2396 if (wps_parse_msg(msg
, &attr
) < 0)
2399 if (!wps_version_supported(attr
.version
)) {
2400 wpa_printf(MSG_DEBUG
, "WPS: Unsupported message version 0x%x",
2401 attr
.version
? *attr
.version
: 0);
2405 if (attr
.msg_type
== NULL
) {
2406 wpa_printf(MSG_DEBUG
, "WPS: No Message Type attribute");
2410 if (*attr
.msg_type
!= WPS_WSC_ACK
) {
2411 wpa_printf(MSG_DEBUG
, "WPS: Invalid Message Type %d",
2416 #ifdef CONFIG_WPS_UPNP
2417 if (wps
->wps
->wps_upnp
&& wps
->ext_reg
&& wps
->state
== RECV_M2D_ACK
&&
2418 upnp_wps_subscribers(wps
->wps
->wps_upnp
)) {
2419 if (wps
->wps
->upnp_msgs
)
2420 return WPS_CONTINUE
;
2421 wpa_printf(MSG_DEBUG
, "WPS: Wait for response from an "
2422 "external Registrar");
2425 #endif /* CONFIG_WPS_UPNP */
2427 if (attr
.registrar_nonce
== NULL
||
2428 os_memcmp(wps
->nonce_r
, attr
.registrar_nonce
, WPS_NONCE_LEN
!= 0))
2430 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in registrar nonce");
2434 if (attr
.enrollee_nonce
== NULL
||
2435 os_memcmp(wps
->nonce_e
, attr
.enrollee_nonce
, WPS_NONCE_LEN
!= 0)) {
2436 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in enrollee nonce");
2440 if (wps
->state
== RECV_M2D_ACK
) {
2441 #ifdef CONFIG_WPS_UPNP
2442 if (wps
->wps
->wps_upnp
&&
2443 upnp_wps_subscribers(wps
->wps
->wps_upnp
)) {
2444 if (wps
->wps
->upnp_msgs
)
2445 return WPS_CONTINUE
;
2446 if (wps
->ext_reg
== 0)
2448 wpa_printf(MSG_DEBUG
, "WPS: Wait for response from an "
2449 "external Registrar");
2452 #endif /* CONFIG_WPS_UPNP */
2454 wpa_printf(MSG_DEBUG
, "WPS: No more registrars available - "
2455 "terminate negotiation");
2462 static enum wps_process_res
wps_process_wsc_nack(struct wps_data
*wps
,
2463 const struct wpabuf
*msg
)
2465 struct wps_parse_attr attr
;
2468 wpa_printf(MSG_DEBUG
, "WPS: Received WSC_NACK");
2470 old_state
= wps
->state
;
2471 wps
->state
= SEND_WSC_NACK
;
2473 if (wps_parse_msg(msg
, &attr
) < 0)
2476 if (!wps_version_supported(attr
.version
)) {
2477 wpa_printf(MSG_DEBUG
, "WPS: Unsupported message version 0x%x",
2478 attr
.version
? *attr
.version
: 0);
2482 if (attr
.msg_type
== NULL
) {
2483 wpa_printf(MSG_DEBUG
, "WPS: No Message Type attribute");
2487 if (*attr
.msg_type
!= WPS_WSC_NACK
) {
2488 wpa_printf(MSG_DEBUG
, "WPS: Invalid Message Type %d",
2493 #ifdef CONFIG_WPS_UPNP
2494 if (wps
->wps
->wps_upnp
&& wps
->ext_reg
) {
2495 wpa_printf(MSG_DEBUG
, "WPS: Negotiation using external "
2496 "Registrar terminated by the Enrollee");
2499 #endif /* CONFIG_WPS_UPNP */
2501 if (attr
.registrar_nonce
== NULL
||
2502 os_memcmp(wps
->nonce_r
, attr
.registrar_nonce
, WPS_NONCE_LEN
!= 0))
2504 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in registrar nonce");
2508 if (attr
.enrollee_nonce
== NULL
||
2509 os_memcmp(wps
->nonce_e
, attr
.enrollee_nonce
, WPS_NONCE_LEN
!= 0)) {
2510 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in enrollee nonce");
2514 if (attr
.config_error
== NULL
) {
2515 wpa_printf(MSG_DEBUG
, "WPS: No Configuration Error attribute "
2520 wpa_printf(MSG_DEBUG
, "WPS: Enrollee terminated negotiation with "
2521 "Configuration Error %d", WPA_GET_BE16(attr
.config_error
));
2523 switch (old_state
) {
2525 wps_fail_event(wps
->wps
, WPS_M2
);
2528 wps_fail_event(wps
->wps
, WPS_M4
);
2531 wps_fail_event(wps
->wps
, WPS_M6
);
2534 wps_fail_event(wps
->wps
, WPS_M8
);
2544 static enum wps_process_res
wps_process_wsc_done(struct wps_data
*wps
,
2545 const struct wpabuf
*msg
)
2547 struct wps_parse_attr attr
;
2549 wpa_printf(MSG_DEBUG
, "WPS: Received WSC_Done");
2551 if (wps
->state
!= RECV_DONE
&&
2552 (!wps
->wps
->wps_upnp
|| !wps
->ext_reg
)) {
2553 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
2554 "receiving WSC_Done", wps
->state
);
2558 if (wps_parse_msg(msg
, &attr
) < 0)
2561 if (!wps_version_supported(attr
.version
)) {
2562 wpa_printf(MSG_DEBUG
, "WPS: Unsupported message version 0x%x",
2563 attr
.version
? *attr
.version
: 0);
2567 if (attr
.msg_type
== NULL
) {
2568 wpa_printf(MSG_DEBUG
, "WPS: No Message Type attribute");
2572 if (*attr
.msg_type
!= WPS_WSC_DONE
) {
2573 wpa_printf(MSG_DEBUG
, "WPS: Invalid Message Type %d",
2578 #ifdef CONFIG_WPS_UPNP
2579 if (wps
->wps
->wps_upnp
&& wps
->ext_reg
) {
2580 wpa_printf(MSG_DEBUG
, "WPS: Negotiation using external "
2581 "Registrar completed successfully");
2582 wps_device_store(wps
->wps
->registrar
, &wps
->peer_dev
,
2586 #endif /* CONFIG_WPS_UPNP */
2588 if (attr
.registrar_nonce
== NULL
||
2589 os_memcmp(wps
->nonce_r
, attr
.registrar_nonce
, WPS_NONCE_LEN
!= 0))
2591 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in registrar nonce");
2595 if (attr
.enrollee_nonce
== NULL
||
2596 os_memcmp(wps
->nonce_e
, attr
.enrollee_nonce
, WPS_NONCE_LEN
!= 0)) {
2597 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in enrollee nonce");
2601 wpa_printf(MSG_DEBUG
, "WPS: Negotiation completed successfully");
2602 wps_device_store(wps
->wps
->registrar
, &wps
->peer_dev
,
2605 if (wps
->wps
->wps_state
== WPS_STATE_NOT_CONFIGURED
&& wps
->new_psk
&&
2606 wps
->wps
->ap
&& !wps
->wps
->registrar
->disable_auto_conf
) {
2607 struct wps_credential cred
;
2609 wpa_printf(MSG_DEBUG
, "WPS: Moving to Configured state based "
2610 "on first Enrollee connection");
2612 os_memset(&cred
, 0, sizeof(cred
));
2613 os_memcpy(cred
.ssid
, wps
->wps
->ssid
, wps
->wps
->ssid_len
);
2614 cred
.ssid_len
= wps
->wps
->ssid_len
;
2615 cred
.auth_type
= WPS_AUTH_WPAPSK
| WPS_AUTH_WPA2PSK
;
2616 cred
.encr_type
= WPS_ENCR_TKIP
| WPS_ENCR_AES
;
2617 os_memcpy(cred
.key
, wps
->new_psk
, wps
->new_psk_len
);
2618 cred
.key_len
= wps
->new_psk_len
;
2620 wps
->wps
->wps_state
= WPS_STATE_CONFIGURED
;
2621 wpa_hexdump_ascii_key(MSG_DEBUG
,
2622 "WPS: Generated random passphrase",
2623 wps
->new_psk
, wps
->new_psk_len
);
2624 if (wps
->wps
->cred_cb
)
2625 wps
->wps
->cred_cb(wps
->wps
->cb_ctx
, &cred
);
2627 os_free(wps
->new_psk
);
2628 wps
->new_psk
= NULL
;
2631 if (!wps
->wps
->ap
&& !wps
->er
)
2632 wps_sta_cred_cb(wps
);
2635 if (wps_cb_new_psk(wps
->wps
->registrar
, wps
->mac_addr_e
,
2636 wps
->new_psk
, wps
->new_psk_len
)) {
2637 wpa_printf(MSG_DEBUG
, "WPS: Failed to configure the "
2640 os_free(wps
->new_psk
);
2641 wps
->new_psk
= NULL
;
2644 wps_cb_reg_success(wps
->wps
->registrar
, wps
->mac_addr_e
, wps
->uuid_e
);
2647 wps_registrar_remove_pbc_session(wps
->wps
->registrar
,
2648 wps
->mac_addr_e
, wps
->uuid_e
);
2649 wps_registrar_pbc_completed(wps
->wps
->registrar
);
2651 wps_registrar_pin_completed(wps
->wps
->registrar
);
2654 wps_success_event(wps
->wps
);
2660 enum wps_process_res
wps_registrar_process_msg(struct wps_data
*wps
,
2661 enum wsc_op_code op_code
,
2662 const struct wpabuf
*msg
)
2664 enum wps_process_res ret
;
2666 wpa_printf(MSG_DEBUG
, "WPS: Processing received message (len=%lu "
2668 (unsigned long) wpabuf_len(msg
), op_code
);
2670 #ifdef CONFIG_WPS_UPNP
2671 if (wps
->wps
->wps_upnp
&& op_code
== WSC_MSG
&& wps
->ext_reg
== 1) {
2672 struct wps_parse_attr attr
;
2673 if (wps_parse_msg(msg
, &attr
) == 0 && attr
.msg_type
&&
2674 *attr
.msg_type
== WPS_M3
)
2675 wps
->ext_reg
= 2; /* past M2/M2D phase */
2677 if (wps
->ext_reg
> 1)
2678 wps_registrar_free_pending_m2(wps
->wps
);
2679 if (wps
->wps
->wps_upnp
&& wps
->ext_reg
&&
2680 wps
->wps
->upnp_msgs
== NULL
&&
2681 (op_code
== WSC_MSG
|| op_code
== WSC_Done
|| op_code
== WSC_NACK
))
2683 struct wps_parse_attr attr
;
2685 if (wps_parse_msg(msg
, &attr
) < 0 || attr
.msg_type
== NULL
)
2688 type
= *attr
.msg_type
;
2689 wpa_printf(MSG_DEBUG
, "WPS: Sending received message (type %d)"
2690 " to external Registrar for processing", type
);
2691 upnp_wps_device_send_wlan_event(wps
->wps
->wps_upnp
,
2693 UPNP_WPS_WLANEVENT_TYPE_EAP
,
2695 if (op_code
== WSC_MSG
)
2697 } else if (wps
->wps
->wps_upnp
&& wps
->ext_reg
&& op_code
== WSC_MSG
) {
2698 wpa_printf(MSG_DEBUG
, "WPS: Skip internal processing - using "
2699 "external Registrar");
2700 return WPS_CONTINUE
;
2702 #endif /* CONFIG_WPS_UPNP */
2706 return wps_process_wsc_msg(wps
, msg
);
2708 return wps_process_wsc_ack(wps
, msg
);
2710 return wps_process_wsc_nack(wps
, msg
);
2712 ret
= wps_process_wsc_done(wps
, msg
);
2713 if (ret
== WPS_FAILURE
) {
2714 wps
->state
= SEND_WSC_NACK
;
2715 wps_fail_event(wps
->wps
, WPS_WSC_DONE
);
2719 wpa_printf(MSG_DEBUG
, "WPS: Unsupported op_code %d", op_code
);
2725 int wps_registrar_update_ie(struct wps_registrar
*reg
)
2727 return wps_set_ie(reg
);
2731 static void wps_registrar_set_selected_timeout(void *eloop_ctx
,
2734 struct wps_registrar
*reg
= eloop_ctx
;
2736 wpa_printf(MSG_DEBUG
, "WPS: SetSelectedRegistrar timed out - "
2737 "unselect Registrar");
2738 reg
->selected_registrar
= 0;
2740 reg
->sel_reg_dev_password_id_override
= -1;
2741 reg
->sel_reg_config_methods_override
= -1;
2743 wps_cb_set_sel_reg(reg
);
2748 * wps_registrar_set_selected_registrar - Notification of SetSelectedRegistrar
2749 * @reg: Registrar data from wps_registrar_init()
2750 * @msg: Received message from SetSelectedRegistrar
2751 * Returns: 0 on success, -1 on failure
2753 * This function is called when an AP receives a SetSelectedRegistrar UPnP
2756 int wps_registrar_set_selected_registrar(struct wps_registrar
*reg
,
2757 const struct wpabuf
*msg
)
2759 struct wps_parse_attr attr
;
2761 wpa_hexdump_buf(MSG_MSGDUMP
, "WPS: SetSelectedRegistrar attributes",
2764 if (wps_parse_msg(msg
, &attr
) < 0)
2766 if (!wps_version_supported(attr
.version
)) {
2767 wpa_printf(MSG_DEBUG
, "WPS: Unsupported SetSelectedRegistrar "
2768 "version 0x%x", attr
.version
? *attr
.version
: 0);
2772 if (attr
.selected_registrar
== NULL
||
2773 *attr
.selected_registrar
== 0) {
2774 wpa_printf(MSG_DEBUG
, "WPS: SetSelectedRegistrar: Disable "
2775 "Selected Registrar");
2776 eloop_cancel_timeout(wps_registrar_set_selected_timeout
, reg
,
2778 wps_registrar_set_selected_timeout(reg
, NULL
);
2782 reg
->selected_registrar
= 1;
2783 reg
->sel_reg_dev_password_id_override
= attr
.dev_password_id
?
2784 WPA_GET_BE16(attr
.dev_password_id
) : DEV_PW_DEFAULT
;
2785 reg
->sel_reg_config_methods_override
= attr
.sel_reg_config_methods
?
2786 WPA_GET_BE16(attr
.sel_reg_config_methods
) : -1;
2789 eloop_cancel_timeout(wps_registrar_set_selected_timeout
, reg
, NULL
);
2790 eloop_register_timeout(WPS_PBC_WALK_TIME
, 0,
2791 wps_registrar_set_selected_timeout
,
2797 int wps_registrar_get_info(struct wps_registrar
*reg
, const u8
*addr
,
2798 char *buf
, size_t buflen
)
2800 struct wps_registrar_device
*d
;
2804 d
= wps_device_get(reg
, addr
);
2807 if (uuid_bin2str(d
->uuid
, uuid
, sizeof(uuid
)))
2810 ret
= os_snprintf(buf
+ len
, buflen
- len
,
2812 "wpsPrimaryDeviceType=%u-%08X-%u\n"
2813 "wpsDeviceName=%s\n"
2814 "wpsManufacturer=%s\n"
2816 "wpsModelNumber=%s\n"
2817 "wpsSerialNumber=%s\n",
2819 d
->dev
.categ
, d
->dev
.oui
, d
->dev
.sub_categ
,
2820 d
->dev
.device_name
? d
->dev
.device_name
: "",
2821 d
->dev
.manufacturer
? d
->dev
.manufacturer
: "",
2822 d
->dev
.model_name
? d
->dev
.model_name
: "",
2823 d
->dev
.model_number
? d
->dev
.model_number
: "",
2824 d
->dev
.serial_number
? d
->dev
.serial_number
: "");
2825 if (ret
< 0 || (size_t) ret
>= buflen
- len
)