1 /*
2 * Copyright 2008-2024 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 /** @file wifi_nxp_wps.h
9 *
10 * @brief WPS - WiFi Protected Setup
11 *
12 * Wi-Fi Protected Setup (WPS) is a standard for easy and secure wireless
13 * network set up and connections. Using this standard, wireless clients
14 * can associate with the WPS enabled access point by entering the same
15 * PIN at client and AP end or by pushing a pushbutton on both. This eliminates
16 * the need for manually entering the security configuration on the client side.
17 *
18 * Two methods that are supported by SDK are:
19 *
20 * \li PIN Method: In this method the same PIN (Personal Identification Number)
21 * is entered on the wireless client and access point. The PIN can be static
22 * or dynamically generated on any of the AP or wireless client.
23 * \li PBC Method: in which the user simply has to push a button, either
24 * an actual or virtual one, on both the AP and wireless client.
25 *
26 * \section wps_usage Usage
27 * In a typical implementation WPS thread is started by calling \ref wps_start.
28 * A valid initialized \ref wps_config structure needs to be passed to this
29 * function. This structure contains a callback handler which is invoked by the
30 * WPS thread on occurrence of various events. Once the WPS thread is started,
31 * commands can be sent to it using \ref wps_connect function. Typically
32 * these commands can be start PIN session, or start a pushbutton session. This
33 * requires passing \ref wps_session_command structure that contains a valid
34 * \ref wlan_scan_result that contains network information for a WPS enabled
35 * wireless network. On successful WPS session, callback handler is invoked with
36 * \ref WPS_SESSION_SUCCESSFUL event with \ref wlan_network structure that
37 * contains all the security information for the network with which WPS
38 * session was attempted. After this \ref wps_stop should be called to
39 * terminate the WPS thread.
40 *
41 * \note WPS implementation lets application decide PIN policy. PIN could either
42 * be generated by the application, or by the access point or can be statically
43 * generated at device manufacturing time. \ref wps_generate_pin and \ref
44 * wps_validate_pin utility functions can be used by the application to generate
45 * and validate PIN.
46 *
47 * \note WPS thread internally uses multiple dynamic allocations. Please do not
48 * reduce the heap size below 64KB if the application wishes to use WPS.
49 *
50 */
51
52 #ifndef WPS_H
53 #define WPS_H
54
55 #include <wlan.h>
56 #include <wmlog.h>
57
58 #if (CONFIG_WPA2_ENTP) && !(CONFIG_WPS2)
59 #error "CONFIG_WPA2_ENTP is enabled, but CONFIG_WPS2 is not, enable it from wifi_config.h"
60 #endif
61
62 #if CONFIG_WPS_DEBUG
63 #define wps_d(...) wmlog("wps", ##__VA_ARGS__)
64 #else
65 #define wps_d(...)
66 #endif
67
68 /** MAC to string */
69 #ifndef MAC2STR
70 #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
71 #endif
72 /** MAC string */
73 #ifndef MACSTR
74 #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
75 #endif
76
77 #if CONFIG_WPS_DEBUG
78 /** ENTER */
79 #ifndef ENTER
80 #define ENTER() PRINTF("Enter: %s : %i\r\n", __FUNCTION__, __LINE__)
81 // #define ENTER() PRINTF("Enter: %s, %s:%i\r\n", __FUNCTION__, __FILE__, __LINE__)
82 #endif
83
84 /** LEAVE */
85 #ifndef LEAVE
86 #define LEAVE() PRINTF("Leave: %s : %i\r\n", __FUNCTION__, __LINE__)
87 // #define LEAVE() PRINTF("Leave: %s, %s:%i\r\n", __FUNCTION__, __FILE__, __LINE__)
88 #endif
89 #else
90 #ifndef ENTER
91 #define ENTER()
92 #endif
93 #ifndef LEAVE
94 #define LEAVE()
95 #endif
96 #endif
97
98 #ifndef BIT
99 #define BIT(x) (1 << (x))
100 #endif
101
102 #define PROV_NON_SESSION_ATTEMPT 0
103 #define PROV_WPS_SESSION_ATTEMPT 1
104 #define PROV_ENTP_SESSION_ATTEMPT 2
105
106 #if CONFIG_WPS_DEBUG
wps_hexdump(const char * title,const unsigned char * data,size_t len)107 static inline void wps_hexdump(const char *title, const unsigned char *data, size_t len)
108 {
109 int i, j;
110 unsigned char *offset;
111 // #ifndef ENTER
112 offset = (unsigned char *)data;
113 PRINTF("[wps] %s - hexdump(len=%lu):\r\n", title, (unsigned long)len);
114 // #define ENTER() PRINTF("Enter: %s : %i\r\n", __FUNCTION__, __LINE__)
115 for (i = 0; i < len / 16; i++)
116 {
117 for (j = 0; j < 16; j++)
118 PRINTF("%02x ", offset[j]);
119 PRINTF("\r\n");
120 offset += 16;
121 }
122 i = len % 16;
123 for (j = 0; j < i; j++)
124 PRINTF("%02x ", offset[j]);
125 PRINTF("\r\n");
126 }
127 #else
wps_hexdump(const char * title,const unsigned char * data,size_t len)128 static inline void wps_hexdump(const char *title, const unsigned char *data, size_t len)
129 {
130 }
131 #endif
132 #define PM3_BSS
133
134 #if defined(__arm__)
135 #if defined(__ARMCC_VERSION)
136 #define LWIP_TIMEVAL_PRIVATE 1
137 #else
138 #define LWIP_TIMEVAL_PRIVATE 0
139 #endif
140 #ifndef LWIP_SOCKET_SELECT
141 #define LWIP_SOCKET_SELECT 0
142 #endif
143 #endif
144
145 /** enum : WPS session commands */
146 enum wps_session_command
147 {
148 /** Command to start WPS PIN session */
149 CMD_WPS_PIN = 0,
150 /** Command to start WPS PBC session */
151 CMD_WPS_PBC
152 };
153
154 /** enum : WPS events */
155 enum wps_event
156 {
157 /** WPS thread started */
158 WPS_STARTED = 0,
159 /** WPS PBC/PIN Session started */
160 WPS_SESSION_STARTED,
161 /** WPS PIN checksum failed */
162 WPS_SESSION_PIN_CHKSUM_FAILED,
163 /** WPS Session aborted */
164 WPS_SESSION_ABORTED,
165 /** WPS Session registration timeout */
166 WPS_SESSION_TIMEOUT,
167 /** WPS Session attempt successful */
168 WPS_SESSION_SUCCESSFUL,
169 /** WPS Session failed */
170 WPS_SESSION_FAILED,
171 /** WPS thread stopped */
172 WPS_FINISHED
173 };
174
175 /** Enum that indicates type of WPS session
176 * either a push button or a PIN based session is
177 * determined by value fo this enum
178 */
179 enum wps_session_types
180 {
181 /** WPS session is not active */
182 WPS_SESSION_INACTIVE = 0xffff,
183 /** WPS Push Button session active */
184 WPS_SESSION_PBC = 0x0004,
185 /** WPS PIN session active */
186 WPS_SESSION_PIN = 0x0000,
187 };
188
189 /**
190 * This struct is passed to wps_start(). The user must initialize it
191 * with parameters as described inline.
192 */
193 struct wps_config
194 {
195 /** Enrollee: 1, Registrar: 2, WiFi Direct mode:4 */
196 uint8_t role;
197 /** PIN Generator - Enrollee or Registrar */
198 uint8_t pin_generator;
199 /** version */
200 uint8_t version;
201 /** version */
202 uint8_t version2;
203 /** Device name */
204 uint8_t device_name[32];
205 /** Manufacture */
206 uint8_t manufacture[64];
207 /** Model name */
208 uint8_t model_name[32];
209 /** Model number */
210 uint8_t model_number[32];
211 /** Serial number */
212 uint8_t serial_number[32];
213 /** Config methods */
214 uint16_t config_methods;
215 /** Primary Device category*/
216 uint16_t primary_dev_category;
217 /** Primary Device subcategory*/
218 uint16_t primary_dev_subcategory;
219 /** RF bands */
220 uint8_t rf_bands;
221 /** OS Version */
222 uint32_t os_version;
223 /** WPS message max retry */
224 uint8_t wps_msg_max_retry;
225 /** WPS message timeout */
226 uint32_t wps_msg_timeout;
227 /** PIN length */
228 uint16_t pin_len;
229 /** WPS callback */
230 int (*wps_callback)(enum wps_event event, void *data, uint16_t len);
231 /** session attempt PROV_NON_SESSION_ATTEMPT/PROV_WPS_SESSION_ATTEMPT/PROV_ENTP_SESSION_ATTEMPT */
232 uint8_t prov_session;
233 };
234
235 /** Starts WPS thread and enables commands delivery
236 *
237 * \param wps_conf A pointer to WPS custom configuration
238 *
239 * \returns WM_SUCCESS if successful, -WM_FAIL otherwise
240 */
241 int wps_start(struct wps_config *wps_conf);
242
243 /** Connect to WPS enabled AP
244 *
245 * Connect to a WPS enabled AP. This function is typically called whenever
246 * the users pushes the wps button or enters wps pin.
247 *
248 * \param pbc Set to 1 if Push-button session is desired
249 * \param pin Ignore if pbc is 1. If pbc is 0, this indicates the pin that
250 * should be used. The pin can be 4 or 8 digits.
251 * \param res The WPS enabled AP to connect to.
252 *
253 * \returns WM_SUCCESS if successful, -WM_FAIL otherwise
254 */
255 int wps_connect(enum wps_session_command pbc, uint32_t pin, struct wlan_scan_result *res);
256
257 /** Generate 8 digit WPS PIN value with random number generator
258 *
259 * \param wps_pin Generated 8 digit WPS PIN value
260 *
261 * \returns WM_SUCCESS if successful, -WM_FAIL otherwise
262 */
263 int wps_generate_pin(uint32_t *wps_pin);
264
265 /**Validate checksum of PIN
266 *
267 * \param wps_pin WPS PIN value
268 *
269 * \returns WM_SUCCESS if successful, -WM_FAIL otherwise
270 **/
271 int wps_validate_pin(uint32_t wps_pin);
272
273 /** Deletes WPS thread and message queue
274 *
275 * \returns WM_SUCCESS if successful, -WM_FAIL otherwise
276 */
277 int wps_stop();
278 #endif
279