|
Developer notes for wpa_supplicantThe design goal for wpa_supplicant was to use hardware, driver, and OS independent, portable C code for all WPA functionality. All hardware/driver specific functionality is in separate files that implement a well-defined driver API. The goal of this file and the comments in the header files is to give enough information for other developers to be able to port the example code. If any information is missing, feel free to contact Jouni Malinen <jkmaline@cc.hut.fi> for more information. Contributions as patch files are also very welcome at the same address. Structure of the source codeProgram initialization, main control loop and event handling is implemented in wpa_supplicant.c. WPA state machines and 4-Way/Group Key Handshake processing in in wpa.c. IEEE 802.1X/EAPOL processing and state machines are in eapol_sm.c. EAP state machine is in eap.c. EAP methods for the internal EAP peer are in eap_*.c. Parser for the configuration file is implemented in config.c. Driver interface API is defined in driver.h and all hardware/driver dependent functionality is implemented in driver_*.c (see below). Generic helper functionswpa_supplicant uses generic helper functions some of which are shared with with hostapd. The following C files are currently used: eloop.[ch] event loop (select() loop with registerable timeouts, socket read callbacks, and signal callbacks) common.[ch] common helper functions defs.h definitions shared by multiple files l2_packet.[ch] Layer 2 (link) access wrapper (includes native Linux implementation and wrappers for libdnet/libpcap) pcsc_funcs.[ch] Wrapper for PC/SC lite SIM and smart card readers Cryptographic functionsmd5.c MD5 (replaced with openssl/crypto if TLS support is included) HMAC-MD5 (keyed checksum for message authenticity validation) rc4.c RC4 (broadcast/default key encryption) sha1.c SHA-1 (replaced with openssl/crypto if TLS support is included) HMAC-SHA-1 (keyed checksum for message authenticity validation) PRF-SHA-1 (pseudorandom (key/nonce generation) function) PBKDF2-SHA-1 (ASCII passphrase to shared secret) T-PRF (for EAP-FAST) TLS-PRF (RFC 2246) aes_wrap.[ch], aes.c AES AES Key Wrap Algorithm with 128-bit KEK, RFC3394 (broadcast/default key encryption) One-Key CBC MAC (OMAC1) hash with AES-128 AES-128 CTR mode encryption AES-128 EAX mode encryption/decryption AES-128 CBC crypto.[ch] Wrapper functions for libcrypto (MD4 and DES) ms_funcs.[ch] Helper functions for MSCHAPV2 and LEAP tls.h Definition of TLS library wrapper tls_none.c Dummy implementation of TLS library wrapper for cases where TLS functionality is not included. tls_openssl.c TLS library wrapper for openssl Configurationconfig_ssid.h Definition of per network configuration items config.h Definition of the wpa_supplicant configuration config.c Configuration file parser Control interfacewpa_supplicant has a control interface that can be used to get status information and manage operations from external programs. An example, command line interface, wpa_cli, for this interface is included in the wpa_supplicant distribution. ctrl_iface.[ch] wpa_supplicant-side of the control interface wpa_ctrl.[ch] Library functions for external programs to provide access to the wpa_supplicant control interface wpa_cli.c Example program for using wpa_supplicant control interface EAP peereap.[ch] EAP state machine eap_defs.h Common EAP definitions eap_i.h Internal definitions for EAP state machine and EAP methods eap_sim_common.[ch] Common code for EAP-SIM and EAP-AKA eap_tls_common.[ch] Common code for EAP-PEAP, EAP-TTLS, and EAP-FAST eap_tlv.[ch] EAP-TLV code for EAP-PEAP and EAP-FAST eap_{aka,fast,gtc,leap,md5,mschapv2,otp,peap,psk,sim,tls,ttls}.c EAP method implementations EAPOL supplicanteapol_sm.[ch] EAPOL supplicant state machine and IEEE 802.1X processing Windows portndis_events.cpp External program for receiving NdisMIndicateStatus() events and delivering them to wpa_supplicant in more easier to use form win_if_list.c External program for listing current network interface Test programsradius_client.[ch] RADIUS authentication client implementation for eapol_test eapol_test.c Standalone EAP testing tool with integrated RADIUS authentication client preauth_test.c Standalone RSN pre-authentication tool wpa_supplicant.cmain() wpa_supplicant_dot1x_receive() wpa_supplicant_get_beacon_ie() wpa_supplicant_deauthenticate() wpa_supplicant_disassociate() wpa_supplicant_scan() wpa_supplicant_reconfig() wpa_supplicant_terminate() wpa_supplicant_reload_configuration() wpa_supplicant_event()
wpa_supplicant_associate() wpa_supplicant_req_auth_timeout() wpa_supplicant_cancel_auth_timeout() wpa_supplicant_req_scan() wpa_supplicant_cancel_scan() wpa_supplicant_notify_eapol_done() wpa_eapol_send() wpa_eapol_send_preauth() wpa_msg() wpa_supplicant.h
wpa_supplicant_i.h
wpa.[ch]
pmksa_cache_free() pmksa_cache_get() pmksa_cache_list() pmksa_candidate_free() wpa_parse_wpa_ie() wpa_gen_wpa_ei() wpa_supplicant_get_ssid() wpa_supplicant_key_request() wpa_sm_rx_eapol()
wpa_supplicant_rx_eapol() wpa_get_mib() rsn_preauth_receive() rsn_preauth_eapol_cb() rsn_preauth_init() pmksa_candidate_add() rsn_preauth_scan_results() Driver wrapper implementation (driver.h, drivers.c)All hardware and driver dependent functionality is implemented in as a separate C file(s) implementing defined wrapper functions. Other parts of the wpa_supplicant are designed to be hardware, driver, and operating system independent. Driver wrappers need to implement whatever calls are used in the target operating system/driver for controlling wireless LAN devices. As an example, in case of Linux, these are mostly some glue code and ioctl() calls and netlink message parsing for Linux Wireless Extensions. Since all features required for WPA are not yet included in Wireless Extensions, some driver specific code is used in the example implementation for Host AP driver. These driver dependent parts are to be replaced with generic code once the needed changes are included in the Wireless Extensions. After that, all Linux drivers, at least in theory, could use the same driver wrapper code. A driver wrapper needs to implement some or all of the functions defined in driver.h (see that file for detailed documentation of the functions). Hardware independent parts of wpa_supplicant will call these functions to control the driver/wlan card. In addition, support for driver events is required. The event callback function, wpa_supplicant_event(), and its parameters are documented in wpa_supplicant.h. In addition, pointer to the 'struct wpa_driver_ops' needs to be registered in drivers.c file. When porting to other operating systems, driver wrapper should be modified to use the native interface of the target OS. It is possible that some extra requirements for the interface between the driver wrapper and generic wpa_supplicant code are discovered during porting to a new operating system. These will be addresses on case by case basic by modifying the interface and updating the other driver wrappers for this. The goal is to avoid changing this interface without very good reasons in order to limit the number of changes needed to other wrappers and hardware independent parts of wpa_supplicant. Generic Linux Wireless Extensions functions are implemented in driver_wext.c. All Linux driver wrappers can use these when the kernel driver supports the generic ioctl()s and wireless events. Driver specific functions are implemented in separate C files, e.g., driver_hostap.c. These files need to define struct wpa_driver_ops entry that will be used in wpa_supplicant.c when calling driver functions. These entries need to be added to the lists in wpa_supplicant_set_driver() and usage() functions in wpa_supplicant.c. In general, it is likely to be useful to first take a look at couple of the driver interfaces before starting on implementing a new one. driver_hostap.c and driver_wext.c include a complete implementation for Linux drivers that use wpa_supplicant-based control of WPA IE and roaming. driver_ndis.c (with help from driver_ndis_.c) is an example of a complete interface for Windows NDIS interface for drivers that generate WPA IE themselves and decide when to roam. These example implementations include full support for all security modes. Driver requirements for WPAWPA introduces new requirements for the device driver. At least some of these need to be implemented in order to provide enough support for wpa_supplicant. TKIP/CCMP WPA requires that the pairwise cipher suite (encryption algorithm for unicast data packets) is TKIP or CCMP. These are new encryption protocols and thus, the driver will need to be modified to support them. Depending on the used wlan hardware, some parts of these may be implemented by the hardware/firmware. Specification for both TKIP and CCMP is available from IEEE (IEEE 802.11i draft version 3.0). Fully functional, hardware independent implementation of both encryption protocols is also available in Host AP driver (driver/modules/hostap_{tkip,ccmp}.c). The driver will also need to provide configuration mechanism to allow user space programs to configure TKIP and CCMP. Current Linux Wireless Extensions (v16) does not yet support these algorithms or individual/non-default keys. Host AP driver has an example of private ioctl()s for this. Eventually, this should be replaced with modified Linux Wireless Extensions. Roaming control and scanning support wpa_supplicant controls AP selections based on the information received from Beacon and/or Probe Response frames. This means that the driver should support external control for scan process. In case of Linux, use of new Wireless Extensions scan support (i.e., 'iwlist wlan0 scan') is recommended. The current driver wrapper (driver_wext.c) uses this for scan results. Scan results must also include WPA information element. This is not yet defined in Linux Wireless Extensions and Host AP driver uses a custom event to provide the full WPA IE (including element id and length) as a hex string that is included in the scan results. Eventually, this should be defined as a Wireless Extensions ioctl that can be used both with scan results and with configuration of WPA IE for association request (and Beacon/Probe Response in case of an AP/IBSS). wpa_supplicant needs to also be able to request the driver to associate with a specific BSS. Current Host AP driver and matching driver_hostap.c wrapper uses following sequence for this request. Similar/identical mechanism should be usable also with other drivers.
WPA IE generation wpa_supplicant selects which cipher suites and key management suites are used. Based on this information, it generates a WPA IE. This is provided to the driver interface in the associate call. This does not match with Windows NDIS drivers which generate the WPA IE themselves. wpa_supplicant allows Windows NDIS-like behavior by providing the selected cipher and key management suites in the associate call. If the driver generates its own WPA IE and that differs from the one generated by wpa_supplicant, the driver has to inform wpa_supplicant about the used WPA IE (i.e., the one it used in (Re)Associate Request). This notification is done using EVENT_ASSOCINFO event (see wpa_supplicant.h). Driver events wpa_supplicant needs to receive event callbacks when certain events occur (association, disassociation, Michael MIC failure, scan results available, PMKSA caching candidate). These events and the callback details are defined in wpa_supplicant.h. On Linux, association and disassociation can use existing Wireless Extensions event that is reporting new AP with SIOCGIWAP event. Similarly, completion of scan can be reported with SIOCGIWSCAN event. Michael MIC failure event is not yet included in Wireless Extensions, so this needs a custom event. Host AP driver uses custom event with following contents: MLME-MICHAELMICFAILURE.indication(keyid=# broadcast/unicast addr=addr2). This is the recommended format until the event is added to Linux Wireless Extensions. |