1 /* 2 * Wi-Fi Protected Setup 3 * Copyright (c) 2007-2008, Jouni Malinen <j@w1.fi> 4 * 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. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15 #ifndef WPS_H 16 #define WPS_H 17 18 #include "wps_defs.h" 19 20 /** 21 * enum wsc_op_code - EAP-WSC OP-Code values 22 */ 23 enum wsc_op_code { 24 WSC_UPnP = 0 /* No OP Code in UPnP transport */, 25 WSC_Start = 0x01, 26 WSC_ACK = 0x02, 27 WSC_NACK = 0x03, 28 WSC_MSG = 0x04, 29 WSC_Done = 0x05, 30 WSC_FRAG_ACK = 0x06 31 }; 32 33 struct wps_registrar; 34 struct upnp_wps_device_sm; 35 36 /** 37 * struct wps_credential - WPS Credential 38 * @ssid: SSID 39 * @ssid_len: Length of SSID 40 * @auth_type: Authentication Type (WPS_AUTH_OPEN, .. flags) 41 * @encr_type: Encryption Type (WPS_ENCR_NONE, .. flags) 42 * @key_idx: Key index 43 * @key: Key 44 * @key_len: Key length in octets 45 * @mac_addr: MAC address of the Credential receiver 46 * @cred_attr: Unparsed Credential attribute data (used only in cred_cb()); 47 * this may be %NULL, if not used 48 * @cred_attr_len: Length of cred_attr in octets 49 */ 50 struct wps_credential { 51 u8 ssid[32]; 52 size_t ssid_len; 53 u16 auth_type; 54 u16 encr_type; 55 u8 key_idx; 56 u8 key[64]; 57 size_t key_len; 58 u8 mac_addr[ETH_ALEN]; 59 const u8 *cred_attr; 60 size_t cred_attr_len; 61 }; 62 63 /** 64 * struct wps_device_data - WPS Device Data 65 * @mac_addr: Device MAC address 66 * @device_name: Device Name (0..32 octets encoded in UTF-8) 67 * @manufacturer: Manufacturer (0..64 octets encoded in UTF-8) 68 * @model_name: Model Name (0..32 octets encoded in UTF-8) 69 * @model_number: Model Number (0..32 octets encoded in UTF-8) 70 * @serial_number: Serial Number (0..32 octets encoded in UTF-8) 71 * @categ: Primary Device Category 72 * @oui: Primary Device OUI 73 * @sub_categ: Primary Device Sub-Category 74 * @os_version: OS Version 75 * @rf_bands: RF bands (WPS_RF_24GHZ, WPS_RF_50GHZ flags) 76 */ 77 struct wps_device_data { 78 u8 mac_addr[ETH_ALEN]; 79 char *device_name; 80 char *manufacturer; 81 char *model_name; 82 char *model_number; 83 char *serial_number; 84 u16 categ; 85 u32 oui; 86 u16 sub_categ; 87 u32 os_version; 88 u8 rf_bands; 89 }; 90 91 /** 92 * struct wps_config - WPS configuration for a single registration protocol run 93 */ 94 struct wps_config { 95 /** 96 * wps - Pointer to long term WPS context 97 */ 98 struct wps_context *wps; 99 100 /** 101 * registrar - Whether this end is a Registrar 102 */ 103 int registrar; 104 105 /** 106 * pin - Enrollee Device Password (%NULL for Registrar or PBC) 107 */ 108 const u8 *pin; 109 110 /** 111 * pin_len - Length on pin in octets 112 */ 113 size_t pin_len; 114 115 /** 116 * pbc - Whether this is protocol run uses PBC 117 */ 118 int pbc; 119 120 /** 121 * assoc_wps_ie: (Re)AssocReq WPS IE (in AP; %NULL if not AP) 122 */ 123 const struct wpabuf *assoc_wps_ie; 124 }; 125 126 struct wps_data * wps_init(const struct wps_config *cfg); 127 128 void wps_deinit(struct wps_data *data); 129 130 /** 131 * enum wps_process_res - WPS message processing result 132 */ 133 enum wps_process_res { 134 /** 135 * WPS_DONE - Processing done 136 */ 137 WPS_DONE, 138 139 /** 140 * WPS_CONTINUE - Processing continues 141 */ 142 WPS_CONTINUE, 143 144 /** 145 * WPS_FAILURE - Processing failed 146 */ 147 WPS_FAILURE, 148 149 /** 150 * WPS_PENDING - Processing continues, but waiting for an external 151 * event (e.g., UPnP message from an external Registrar) 152 */ 153 WPS_PENDING 154 }; 155 enum wps_process_res wps_process_msg(struct wps_data *wps, 156 enum wsc_op_code op_code, 157 const struct wpabuf *msg); 158 159 struct wpabuf * wps_get_msg(struct wps_data *wps, enum wsc_op_code *op_code); 160 161 int wps_is_selected_pbc_registrar(const struct wpabuf *msg); 162 int wps_is_selected_pin_registrar(const struct wpabuf *msg); 163 const u8 * wps_get_uuid_e(const struct wpabuf *msg); 164 165 struct wpabuf * wps_build_assoc_req_ie(enum wps_request_type req_type); 166 struct wpabuf * wps_build_probe_req_ie(int pbc, struct wps_device_data *dev, 167 const u8 *uuid, 168 enum wps_request_type req_type); 169 170 171 /** 172 * struct wps_registrar_config - WPS Registrar configuration 173 */ 174 struct wps_registrar_config { 175 /** 176 * new_psk_cb - Callback for new PSK 177 * @ctx: Higher layer context data (cb_ctx) 178 * @mac_addr: MAC address of the Enrollee 179 * @psk: The new PSK 180 * @psk_len: The length of psk in octets 181 * Returns: 0 on success, -1 on failure 182 * 183 * This callback is called when a new per-device PSK is provisioned. 184 */ 185 int (*new_psk_cb)(void *ctx, const u8 *mac_addr, const u8 *psk, 186 size_t psk_len); 187 188 /** 189 * set_ie_cb - Callback for WPS IE changes 190 * @ctx: Higher layer context data (cb_ctx) 191 * @beacon_ie: WPS IE for Beacon 192 * @beacon_ie_len: WPS IE length for Beacon 193 * @probe_resp_ie: WPS IE for Probe Response 194 * @probe_resp_ie_len: WPS IE length for Probe Response 195 * Returns: 0 on success, -1 on failure 196 * 197 * This callback is called whenever the WPS IE in Beacon or Probe 198 * Response frames needs to be changed (AP only). 199 */ 200 int (*set_ie_cb)(void *ctx, const u8 *beacon_ie, size_t beacon_ie_len, 201 const u8 *probe_resp_ie, size_t probe_resp_ie_len); 202 203 /** 204 * pin_needed_cb - Callback for requesting a PIN 205 * @ctx: Higher layer context data (cb_ctx) 206 * @uuid_e: UUID-E of the unknown Enrollee 207 * @dev: Device Data from the unknown Enrollee 208 * 209 * This callback is called whenever an unknown Enrollee requests to use 210 * PIN method and a matching PIN (Device Password) is not found in 211 * Registrar data. 212 */ 213 void (*pin_needed_cb)(void *ctx, const u8 *uuid_e, 214 const struct wps_device_data *dev); 215 216 /** 217 * reg_success_cb - Callback for reporting successful registration 218 * @ctx: Higher layer context data (cb_ctx) 219 * @mac_addr: MAC address of the Enrollee 220 * @uuid_e: UUID-E of the Enrollee 221 * 222 * This callback is called whenever an Enrollee completes registration 223 * successfully. 224 */ 225 void (*reg_success_cb)(void *ctx, const u8 *mac_addr, 226 const u8 *uuid_e); 227 228 /** 229 * cb_ctx: Higher layer context data for Registrar callbacks 230 */ 231 void *cb_ctx; 232 233 /** 234 * skip_cred_build: Do not build credential 235 * 236 * This option can be used to disable internal code that builds 237 * Credential attribute into M8 based on the current network 238 * configuration and Enrollee capabilities. The extra_cred data will 239 * then be used as the Credential(s). 240 */ 241 int skip_cred_build; 242 243 /** 244 * extra_cred: Additional Credential attribute(s) 245 * 246 * This optional data (set to %NULL to disable) can be used to add 247 * Credential attribute(s) for other networks into M8. If 248 * skip_cred_build is set, this will also override the automatically 249 * generated Credential attribute. 250 */ 251 const u8 *extra_cred; 252 253 /** 254 * extra_cred_len: Length of extra_cred in octets 255 */ 256 size_t extra_cred_len; 257 258 /** 259 * disable_auto_conf - Disable auto-configuration on first registration 260 * 261 * By default, the AP that is started in not configured state will 262 * generate a random PSK and move to configured state when the first 263 * registration protocol run is completed successfully. This option can 264 * be used to disable this functionality and leave it up to an external 265 * program to take care of configuration. This requires the extra_cred 266 * to be set with a suitable Credential and skip_cred_build being used. 267 */ 268 int disable_auto_conf; 269 270 /** 271 * static_wep_only - Whether the BSS supports only static WEP 272 */ 273 int static_wep_only; 274 }; 275 276 277 /** 278 * enum wps_event - WPS event types 279 */ 280 enum wps_event { 281 /** 282 * WPS_EV_M2D - M2D received (Registrar did not know us) 283 */ 284 WPS_EV_M2D, 285 286 /** 287 * WPS_EV_FAIL - Registration failed 288 */ 289 WPS_EV_FAIL, 290 291 /** 292 * WPS_EV_SUCCESS - Registration succeeded 293 */ 294 WPS_EV_SUCCESS, 295 296 /** 297 * WPS_EV_PWD_AUTH_FAIL - Password authentication failed 298 */ 299 WPS_EV_PWD_AUTH_FAIL, 300 301 /** 302 * WPS_EV_PBC_OVERLAP - PBC session overlap detected 303 */ 304 WPS_EV_PBC_OVERLAP, 305 306 /** 307 * WPS_EV_PBC_TIMEOUT - PBC walktime expired before protocol run start 308 */ 309 WPS_EV_PBC_TIMEOUT 310 }; 311 312 /** 313 * union wps_event_data - WPS event data 314 */ 315 union wps_event_data { 316 /** 317 * struct wps_event_m2d - M2D event data 318 */ 319 struct wps_event_m2d { 320 u16 config_methods; 321 const u8 *manufacturer; 322 size_t manufacturer_len; 323 const u8 *model_name; 324 size_t model_name_len; 325 const u8 *model_number; 326 size_t model_number_len; 327 const u8 *serial_number; 328 size_t serial_number_len; 329 const u8 *dev_name; 330 size_t dev_name_len; 331 const u8 *primary_dev_type; /* 8 octets */ 332 u16 config_error; 333 u16 dev_password_id; 334 } m2d; 335 336 /** 337 * struct wps_event_fail - Registration failure information 338 * @msg: enum wps_msg_type 339 */ 340 struct wps_event_fail { 341 int msg; 342 } fail; 343 344 struct wps_event_pwd_auth_fail { 345 int enrollee; 346 int part; 347 } pwd_auth_fail; 348 }; 349 350 /** 351 * struct upnp_pending_message - Pending PutWLANResponse messages 352 * @next: Pointer to next pending message or %NULL 353 * @addr: NewWLANEventMAC 354 * @msg: NewMessage 355 * @type: Message Type 356 */ 357 struct upnp_pending_message { 358 struct upnp_pending_message *next; 359 u8 addr[ETH_ALEN]; 360 struct wpabuf *msg; 361 enum wps_msg_type type; 362 }; 363 364 /** 365 * struct wps_context - Long term WPS context data 366 * 367 * This data is stored at the higher layer Authenticator or Supplicant data 368 * structures and it is maintained over multiple registration protocol runs. 369 */ 370 struct wps_context { 371 /** 372 * ap - Whether the local end is an access point 373 */ 374 int ap; 375 376 /** 377 * registrar - Pointer to WPS registrar data from wps_registrar_init() 378 */ 379 struct wps_registrar *registrar; 380 381 /** 382 * wps_state - Current WPS state 383 */ 384 enum wps_state wps_state; 385 386 /** 387 * ap_setup_locked - Whether AP setup is locked (only used at AP) 388 */ 389 int ap_setup_locked; 390 391 /** 392 * uuid - Own UUID 393 */ 394 u8 uuid[16]; 395 396 /** 397 * ssid - SSID 398 * 399 * This SSID is used by the Registrar to fill in information for 400 * Credentials. In addition, AP uses it when acting as an Enrollee to 401 * notify Registrar of the current configuration. 402 */ 403 u8 ssid[32]; 404 405 /** 406 * ssid_len - Length of ssid in octets 407 */ 408 size_t ssid_len; 409 410 /** 411 * dev - Own WPS device data 412 */ 413 struct wps_device_data dev; 414 415 /** 416 * config_methods - Enabled configuration methods 417 * 418 * Bit field of WPS_CONFIG_* 419 */ 420 u16 config_methods; 421 422 /** 423 * encr_types - Enabled encryption types (bit field of WPS_ENCR_*) 424 */ 425 u16 encr_types; 426 427 /** 428 * auth_types - Authentication types (bit field of WPS_AUTH_*) 429 */ 430 u16 auth_types; 431 432 /** 433 * network_key - The current Network Key (PSK) or %NULL to generate new 434 * 435 * If %NULL, Registrar will generate per-device PSK. In addition, AP 436 * uses this when acting as an Enrollee to notify Registrar of the 437 * current configuration. 438 */ 439 u8 *network_key; 440 441 /** 442 * network_key_len - Length of network_key in octets 443 */ 444 size_t network_key_len; 445 446 /** 447 * ap_settings - AP Settings override for M7 (only used at AP) 448 * 449 * If %NULL, AP Settings attributes will be generated based on the 450 * current network configuration. 451 */ 452 u8 *ap_settings; 453 454 /** 455 * ap_settings_len - Length of ap_settings in octets 456 */ 457 size_t ap_settings_len; 458 459 /** 460 * friendly_name - Friendly Name (required for UPnP) 461 */ 462 char *friendly_name; 463 464 /** 465 * manufacturer_url - Manufacturer URL (optional for UPnP) 466 */ 467 char *manufacturer_url; 468 469 /** 470 * model_description - Model Description (recommended for UPnP) 471 */ 472 char *model_description; 473 474 /** 475 * model_url - Model URL (optional for UPnP) 476 */ 477 char *model_url; 478 479 /** 480 * upc - Universal Product Code (optional for UPnP) 481 */ 482 char *upc; 483 484 /** 485 * cred_cb - Callback to notify that new Credentials were received 486 * @ctx: Higher layer context data (cb_ctx) 487 * @cred: The received Credential 488 * Return: 0 on success, -1 on failure 489 */ 490 int (*cred_cb)(void *ctx, const struct wps_credential *cred); 491 492 /** 493 * event_cb - Event callback (state information about progress) 494 * @ctx: Higher layer context data (cb_ctx) 495 * @event: Event type 496 * @data: Event data 497 */ 498 void (*event_cb)(void *ctx, enum wps_event event, 499 union wps_event_data *data); 500 501 /** 502 * cb_ctx: Higher layer context data for callbacks 503 */ 504 void *cb_ctx; 505 506 struct upnp_wps_device_sm *wps_upnp; 507 508 /* Pending messages from UPnP PutWLANResponse */ 509 struct upnp_pending_message *upnp_msgs; 510 }; 511 512 513 struct wps_registrar * 514 wps_registrar_init(struct wps_context *wps, 515 const struct wps_registrar_config *cfg); 516 void wps_registrar_deinit(struct wps_registrar *reg); 517 int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *uuid, 518 const u8 *pin, size_t pin_len, int timeout); 519 int wps_registrar_invalidate_pin(struct wps_registrar *reg, const u8 *uuid); 520 int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid); 521 int wps_registrar_button_pushed(struct wps_registrar *reg); 522 void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr, 523 const struct wpabuf *wps_data); 524 int wps_registrar_update_ie(struct wps_registrar *reg); 525 int wps_registrar_set_selected_registrar(struct wps_registrar *reg, 526 const struct wpabuf *msg); 527 528 unsigned int wps_pin_checksum(unsigned int pin); 529 unsigned int wps_pin_valid(unsigned int pin); 530 unsigned int wps_generate_pin(void); 531 void wps_free_pending_msgs(struct upnp_pending_message *msgs); 532 533 #endif /* WPS_H */ 534