2 * Wi-Fi Protected Setup
3 * Copyright (c) 2007-2008, 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.
19 #include "wps_dev_attr.h"
20 #include "ieee802_11_defs.h"
23 struct wps_data * wps_init(const struct wps_config *cfg)
25 struct wps_data *data = os_zalloc(sizeof(*data));
28 data->authenticator = cfg->authenticator;
30 data->registrar = cfg->registrar;
31 if (cfg->enrollee_mac_addr)
32 os_memcpy(data->mac_addr_e, cfg->enrollee_mac_addr, ETH_ALEN);
34 os_memcpy(cfg->registrar ? data->uuid_r : data->uuid_e,
35 cfg->uuid, WPS_UUID_LEN);
38 data->dev_pw_id = DEV_PW_DEFAULT;
39 data->dev_password = os_malloc(cfg->pin_len);
40 if (data->dev_password == NULL) {
44 os_memcpy(data->dev_password, cfg->pin, cfg->pin_len);
45 data->dev_password_len = cfg->pin_len;
50 /* Use special PIN '00000000' for PBC */
51 data->dev_pw_id = DEV_PW_PUSHBUTTON;
52 os_free(data->dev_password);
53 data->dev_password = os_malloc(8);
54 if (data->dev_password == NULL) {
58 os_memset(data->dev_password, '0', 8);
59 data->dev_password_len = 8;
62 data->state = data->registrar ? RECV_M1 : SEND_M1;
64 if (cfg->assoc_wps_ie) {
65 struct wps_parse_attr attr;
66 wpa_hexdump_buf(MSG_DEBUG, "WPS: WPS IE from (Re)AssocReq",
68 if (wps_parse_msg(cfg->assoc_wps_ie, &attr) < 0) {
69 wpa_printf(MSG_DEBUG, "WPS: Failed to parse WPS IE "
71 } else if (attr.request_type == NULL) {
72 wpa_printf(MSG_DEBUG, "WPS: No Request Type attribute "
73 "in (Re)AssocReq WPS IE");
75 wpa_printf(MSG_DEBUG, "WPS: Request Type (from WPS IE "
76 "in (Re)AssocReq WPS IE): %d",
78 data->request_type = *attr.request_type;
86 void wps_deinit(struct wps_data *data)
88 if (data->wps_pin_revealed) {
89 wpa_printf(MSG_DEBUG, "WPS: Full PIN information revealed and "
90 "negotiation failed");
92 wps_registrar_invalidate_pin(data->registrar,
94 } else if (data->registrar)
95 wps_registrar_unlock_pin(data->registrar, data->uuid_e);
97 wpabuf_free(data->dh_privkey);
98 wpabuf_free(data->dh_pubkey_e);
99 wpabuf_free(data->dh_pubkey_r);
100 wpabuf_free(data->last_msg);
101 os_free(data->dev_password);
102 os_free(data->new_psk);
103 wps_device_data_free(&data->peer_dev);
108 enum wps_process_res wps_process_msg(struct wps_data *wps, u8 op_code,
109 const struct wpabuf *msg)
112 return wps_registrar_process_msg(wps, op_code, msg);
114 return wps_enrollee_process_msg(wps, op_code, msg);
118 struct wpabuf * wps_get_msg(struct wps_data *wps, u8 *op_code)
121 return wps_registrar_get_msg(wps, op_code);
123 return wps_enrollee_get_msg(wps, op_code);
127 int wps_is_selected_pbc_registrar(const u8 *buf, size_t len)
129 struct wps_parse_attr attr;
132 wpabuf_set(&msg, buf, len);
133 if (wps_parse_msg(&msg, &attr) < 0 ||
134 !attr.selected_registrar || *attr.selected_registrar == 0 ||
135 !attr.sel_reg_config_methods ||
136 !(WPA_GET_BE16(attr.sel_reg_config_methods) &
137 WPS_CONFIG_PUSHBUTTON) ||
138 !attr.dev_password_id ||
139 WPA_GET_BE16(attr.dev_password_id) != DEV_PW_PUSHBUTTON)
146 int wps_is_selected_pin_registrar(const u8 *buf, size_t len)
148 struct wps_parse_attr attr;
151 wpabuf_set(&msg, buf, len);
152 if (wps_parse_msg(&msg, &attr) < 0 ||
153 !attr.selected_registrar || *attr.selected_registrar == 0 ||
154 !attr.sel_reg_config_methods ||
155 !(WPA_GET_BE16(attr.sel_reg_config_methods) &
156 (WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD)) ||
157 !attr.dev_password_id ||
158 WPA_GET_BE16(attr.dev_password_id) == DEV_PW_PUSHBUTTON)
165 const u8 * wps_get_uuid_e(const u8 *buf, size_t len)
167 struct wps_parse_attr attr;
170 wpabuf_set(&msg, buf, len);
171 if (wps_parse_msg(&msg, &attr) < 0)
177 struct wpabuf * wps_build_assoc_req_ie(u8 req_type)
182 wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for (Re)Association "
184 ie = wpabuf_alloc(100);
188 wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
189 len = wpabuf_put(ie, 1);
190 wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
192 if (wps_build_version(ie) ||
193 wps_build_req_type(ie, req_type)) {
198 *len = wpabuf_len(ie) - 2;
204 struct wpabuf * wps_build_probe_req_ie(int pbc, struct wps_device_data *dev,
205 const u8 *uuid, u8 req_type)
211 wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for Probe Request");
213 ie = wpabuf_alloc(200);
217 wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
218 len = wpabuf_put(ie, 1);
219 wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
222 methods = WPS_CONFIG_PUSHBUTTON;
224 methods = WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY |
227 if (wps_build_version(ie) ||
228 wps_build_req_type(ie, req_type) ||
229 wps_build_config_methods(ie, methods) ||
230 wps_build_uuid_e(ie, uuid) ||
231 wps_build_primary_dev_type(dev, ie) ||
232 wps_build_rf_bands(dev, ie) ||
233 wps_build_assoc_state(NULL, ie) ||
234 wps_build_config_error(ie, WPS_CFG_NO_ERROR) ||
235 wps_build_dev_password_id(ie, pbc ? DEV_PW_PUSHBUTTON :
241 *len = wpabuf_len(ie) - 2;