iPXE
|
Handler for the aspects of WPA handshaking that are independent of 802.1X/PSK or TKIP/CCMP; this mostly involves the 4-Way Handshake. More...
#include <ipxe/net80211.h>
#include <ipxe/sec80211.h>
#include <ipxe/wpa.h>
#include <ipxe/eapol.h>
#include <ipxe/crypto.h>
#include <ipxe/arc4.h>
#include <ipxe/crc32.h>
#include <ipxe/sha1.h>
#include <ipxe/hmac.h>
#include <ipxe/list.h>
#include <ipxe/ethernet.h>
#include <ipxe/rbg.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>
Go to the source code of this file.
Functions | |
FILE_LICENCE (GPL2_OR_LATER) | |
static int | wpa_fail (struct wpa_common_ctx *ctx, int rc) |
Return an error code and deauthenticate. More... | |
static struct net80211_crypto * | wpa_find_cryptosystem (enum net80211_crypto_alg crypt) |
Find a cryptosystem handler structure from a crypto ID. More... | |
struct wpa_kie * | wpa_find_kie (int version) |
Find WPA key integrity and encryption handler from key version field. More... | |
int | wpa_make_rsn_ie (struct net80211_device *dev, union ieee80211_ie **ie_ret) |
Construct RSN or WPA information element. More... | |
int | wpa_start (struct net80211_device *dev, struct wpa_common_ctx *ctx, const void *pmk, size_t pmk_len) |
Set up generic WPA support to handle 4-Way Handshake. More... | |
void | wpa_stop (struct net80211_device *dev) |
Disable handling of received WPA handshake frames. More... | |
static void | wpa_derive_ptk (struct wpa_common_ctx *ctx) |
Derive pairwise transient key. More... | |
static int | wpa_install_ptk (struct wpa_common_ctx *ctx, int len) |
Install pairwise transient key. More... | |
static int | wpa_install_gtk (struct wpa_common_ctx *ctx, int len, const void *rsc) |
Install group transient key. More... | |
static int | wpa_maybe_install_gtk (struct wpa_common_ctx *ctx, union ieee80211_ie *ie, void *ie_end, const void *rsc) |
Search for group transient key, and install it if found. More... | |
static struct io_buffer * | wpa_alloc_frame (int kdlen) |
Allocate I/O buffer for construction of outgoing EAPOL-Key frame. More... | |
static int | wpa_send_eapol (struct io_buffer *iob, struct wpa_common_ctx *ctx, struct wpa_kie *kie) |
Send EAPOL-Key packet. More... | |
static int | wpa_send_2_of_4 (struct wpa_common_ctx *ctx, struct eapol_key_pkt *pkt, int is_rsn, struct wpa_kie *kie) |
Send second frame in 4-Way Handshake. More... | |
static int | wpa_handle_1_of_4 (struct wpa_common_ctx *ctx, struct eapol_key_pkt *pkt, int is_rsn, struct wpa_kie *kie) |
Handle receipt of first frame in 4-Way Handshake. More... | |
static int | wpa_send_final (struct wpa_common_ctx *ctx, struct eapol_key_pkt *pkt, int is_rsn, struct wpa_kie *kie) |
Send fourth frame in 4-Way Handshake, or second in Group Key Handshake. More... | |
static int | wpa_handle_3_of_4 (struct wpa_common_ctx *ctx, struct eapol_key_pkt *pkt, int is_rsn, struct wpa_kie *kie) |
Handle receipt of third frame in 4-Way Handshake. More... | |
static int | wpa_handle_1_of_2 (struct wpa_common_ctx *ctx, struct eapol_key_pkt *pkt, int is_rsn, struct wpa_kie *kie) |
Handle receipt of first frame in Group Key Handshake. More... | |
static int | eapol_key_rx (struct eapol_supplicant *supplicant, struct io_buffer *iob, const void *ll_source) |
Handle receipt of EAPOL-Key frame for WPA. More... | |
REQUIRING_SYMBOL (eapol_key_handler) | |
REQUIRE_OBJECT (eapol) | |
Variables | |
struct list_head | wpa_contexts = LIST_HEAD_INIT ( wpa_contexts ) |
List of WPA contexts in active use. More... | |
struct eapol_handler eapol_key_handler | __eapol_handler |
Handler for the aspects of WPA handshaking that are independent of 802.1X/PSK or TKIP/CCMP; this mostly involves the 4-Way Handshake.
Definition in file wpa.c.
FILE_LICENCE | ( | GPL2_OR_LATER | ) |
|
static |
Return an error code and deauthenticate.
ctx | WPA common context |
rc | Return status code |
rc | The passed return status code |
Definition at line 56 of file wpa.c.
References ctx, net80211_deauthenticate(), and rc.
Referenced by eapol_key_rx(), wpa_handle_1_of_2(), and wpa_handle_3_of_4().
|
static |
Find a cryptosystem handler structure from a crypto ID.
crypt | Cryptosystem ID |
crypto | Cryptosystem handler structure |
If support for crypt is not compiled in to iPXE, or if crypt is NET80211_CRYPT_UNKNOWN, returns NULL
.
Definition at line 73 of file wpa.c.
References net80211_crypto::algorithm, for_each_table_entry, NET80211_CRYPTOS, and NULL.
Referenced by wpa_make_rsn_ie().
struct wpa_kie* wpa_find_kie | ( | int | version | ) |
Find WPA key integrity and encryption handler from key version field.
ver | Version bits of EAPOL-Key info field |
kie | Key integrity and encryption handler |
Definition at line 92 of file wpa.c.
References for_each_table_entry, NULL, wpa_kie::version, version, and WPA_KIES.
Referenced by eapol_key_rx().
int wpa_make_rsn_ie | ( | struct net80211_device * | dev, |
union ieee80211_ie ** | ie_ret | ||
) |
Construct RSN or WPA information element.
dev | 802.11 device |
ie_ret | RSN or WPA information element |
rc | Return status code |
This function allocates, fills, and returns a RSN or WPA information element suitable for including in an association request frame to the network identified by dev->associating
. If it is impossible to construct an information element consistent with iPXE's capabilities that is compatible with that network, or if none should be sent because that network's beacon included no security information, returns an error indication and leaves ie_ret unchanged.
The returned IE will be of the same type (RSN or WPA) as was included in the beacon for the network it is destined for.
Definition at line 124 of file wpa.c.
References ieee80211_ie_rsn::akm_count, ieee80211_ie_rsn::akm_list, net80211_device::associating, net80211_wlan::beacon, net80211_wlan::crypto, io_buffer::data, DBG, EINVAL, ENOMEM, ENOTSUP, group_cipher, ieee80211_ie_rsn::group_cipher, net80211_wlan::handshaking, hdr, ieee80211_beacon, IEEE80211_IE_RSN, IEEE80211_IE_VENDOR, ieee80211_rsn_size(), IEEE80211_RSN_VERSION, IEEE80211_WPA_OUI_VEN, malloc(), ieee80211_ie_rsn::pairwise_cipher, ieee80211_ie_rsn::pairwise_count, ieee80211_ie_rsn::pmkid_count, ieee80211_ie_rsn::rsn_capab, sec80211_find_rsn(), sec80211_rsn_get_akm_desc(), sec80211_rsn_get_crypto_desc(), sec80211_rsn_get_net80211_crypt(), io_buffer::tail, ieee80211_ie_rsn::version, and wpa_find_cryptosystem().
Referenced by wpa_psk_init().
int wpa_start | ( | struct net80211_device * | dev, |
struct wpa_common_ctx * | ctx, | ||
const void * | pmk, | ||
size_t | pmk_len | ||
) |
Set up generic WPA support to handle 4-Way Handshake.
dev | 802.11 device |
ctx | WPA common context |
pmk | Pairwise Master Key to use for session |
pmk_len | Length of PMK, almost always 32 |
rc | Return status code |
Definition at line 216 of file wpa.c.
References net80211_device::associating, net80211_wlan::beacon, net80211_wlan::crypto, ctx, io_buffer::data, EINVAL, ENOENT, ENOMEM, hdr, ieee80211_beacon, list_add_tail, malloc(), memcpy(), NET80211_CRYPT_UNKNOWN, NULL, net80211_device::rsn_ie, sec80211_find_rsn(), io_buffer::tail, wpa_contexts, and WPA_READY.
Referenced by wpa_psk_start().
void wpa_stop | ( | struct net80211_device * | dev | ) |
Disable handling of received WPA handshake frames.
dev | 802.11 device |
Definition at line 260 of file wpa.c.
References ctx, wpa_common_ctx::dev, free, wpa_common_ctx::list, list_del, list_for_each_entry_safe, NULL, tmp, and wpa_contexts.
Referenced by wpa_psk_stop().
|
static |
Derive pairwise transient key.
ctx | WPA common context |
Definition at line 279 of file wpa.c.
References __attribute__, ctx, DBGC2, DBGC2_HD, ETH_ALEN, eth_ntoa(), memcmp(), memcpy(), prf_sha1(), and WPA_NONCE_LEN.
Referenced by wpa_handle_1_of_4().
|
inlinestatic |
Install pairwise transient key.
ctx | WPA common context |
len | Key length (16 for CCMP, 32 for TKIP) |
rc | Return status code |
Definition at line 331 of file wpa.c.
References ctx, DBGC, DBGC2_HD, len, NULL, and sec80211_install().
Referenced by wpa_handle_3_of_4().
|
inlinestatic |
Install group transient key.
ctx | WPA common context |
len | Key length (16 for CCMP, 32 for TKIP) |
rsc | Receive sequence counter field in EAPOL-Key packet |
rc | Return status code |
Definition at line 349 of file wpa.c.
References ctx, DBGC, DBGC2_HD, len, rsc, and sec80211_install().
Referenced by wpa_handle_1_of_2(), and wpa_maybe_install_gtk().
|
static |
Search for group transient key, and install it if found.
ctx | WPA common context |
ie | Pointer to first IE in key data field |
ie_end | Pointer to first byte not in key data field |
rsc | Receive sequence counter field in EAPOL-Key packet |
rc | Return status code |
Definition at line 369 of file wpa.c.
References ctx, DBGC, EINVAL, ENOENT, wpa_kde_gtk_encap::gtk, wpa_kde::gtk_encap, ieee80211_ie::id, ieee80211_ie_bound(), IEEE80211_IE_VENDOR, ieee80211_next_ie(), wpa_kde::len, ieee80211_ie::len, memcpy(), ieee80211_ie_vendor::oui, rsc, u, ieee80211_ie::vendor, wpa_install_gtk(), and WPA_KDE_GTK.
Referenced by wpa_handle_1_of_2(), and wpa_handle_3_of_4().
|
static |
Allocate I/O buffer for construction of outgoing EAPOL-Key frame.
kdlen | Maximum number of bytes in the Key Data field |
iob | Newly allocated I/O buffer |
The returned buffer will have space reserved for the link-layer and EAPOL headers, and will have iob->tail
pointing to the start of the Key Data field. Thus, it is necessary to use iob_put() in filling the Key Data.
Definition at line 414 of file wpa.c.
References alloc_iob(), iob_put, iob_reserve, MAX_LL_HEADER_LEN, memset(), and NULL.
Referenced by wpa_send_2_of_4(), and wpa_send_final().
|
static |
Send EAPOL-Key packet.
iob | I/O buffer, with sufficient headroom for headers |
dev | 802.11 device |
kie | Key integrity and encryption handler |
is_rsn | If TRUE, handshake uses new RSN format |
rc | Return status code |
If a KIE is specified, the MIC will be filled in before transmission.
Definition at line 442 of file wpa.c.
References cpu_to_be64, ctx, io_buffer::data, eapol_key_pkt::datalen, EAPOL_TYPE_KEY, EAPOL_VERSION_2001, htons, eapol_key_pkt::info, iob_push, eapol_key_pkt::keysize, eapol_header::len, memset(), eapol_key_pkt::mic, wpa_kie::mic, net_tx(), ntohs, eapol_key_pkt::replay, io_buffer::tail, eapol_header::type, and eapol_header::version.
Referenced by wpa_send_2_of_4(), and wpa_send_final().
|
static |
Send second frame in 4-Way Handshake.
ctx | WPA common context |
pkt | First frame, to which this is a reply |
is_rsn | If TRUE, handshake uses new RSN format |
kie | Key integrity and encryption handler |
rc | Return status code |
Definition at line 476 of file wpa.c.
References ctx, io_buffer::data, eapol_key_pkt::datalen, DBGC, EAPOL_KEY_INFO_KEY_ACK, EAPOL_KEY_INFO_KEY_MIC, ENOMEM, eapol_key_pkt::info, iob_put, eapol_key_pkt::keysize, memcpy(), eapol_key_pkt::nonce, wpa_alloc_frame(), and wpa_send_eapol().
Referenced by wpa_handle_1_of_4().
|
static |
Handle receipt of first frame in 4-Way Handshake.
ctx | WPA common context |
pkt | EAPOL-Key packet |
is_rsn | If TRUE, frame uses new RSN format |
kie | Key integrity and encryption handler |
rc | Return status code |
Definition at line 512 of file wpa.c.
References ctx, DBGC, EINVAL, memcpy(), eapol_key_pkt::nonce, NULL, rbg_generate(), wpa_derive_ptk(), wpa_send_2_of_4(), WPA_WAITING, and WPA_WORKING.
Referenced by eapol_key_rx().
|
static |
Send fourth frame in 4-Way Handshake, or second in Group Key Handshake.
ctx | WPA common context |
pkt | EAPOL-Key packet for frame to which we're replying |
is_rsn | If TRUE, frame uses new RSN format |
kie | Key integrity and encryption handler |
rc | Return status code |
Definition at line 544 of file wpa.c.
References ctx, io_buffer::data, eapol_key_pkt::datalen, DBGC, EAPOL_KEY_INFO_INSTALL, EAPOL_KEY_INFO_KEY_ACK, EAPOL_KEY_INFO_KEY_ENC, EAPOL_KEY_INFO_TYPE, ENOMEM, eapol_key_pkt::info, eapol_key_pkt::iv, eapol_key_pkt::keysize, memcpy(), memset(), eapol_key_pkt::nonce, wpa_alloc_frame(), and wpa_send_eapol().
Referenced by wpa_handle_1_of_2(), and wpa_handle_3_of_4().
|
static |
Handle receipt of third frame in 4-Way Handshake.
ctx | WPA common context |
pkt | EAPOL-Key packet |
is_rsn | If TRUE, frame uses new RSN format |
kie | Key integrity and encryption handler |
rc | Return status code |
Definition at line 583 of file wpa.c.
References net80211_wlan::crypto, ctx, eapol_key_pkt::data, eapol_key_pkt::datalen, DBGC, DBGC2, DBGC2_HD, EACCES, EAPOL_KEY_INFO_KEY_ENC, EINVAL, ENOENT, net80211_wlan::handshaking, eapol_key_pkt::info, eapol_key_pkt::keysize, memcmp(), eapol_key_pkt::nonce, NULL, rc, eapol_key_pkt::rsc, sec80211_detect_ie(), sec80211_find_rsn(), sec80211_rsn_get_net80211_crypt(), strerror(), wpa_fail(), wpa_install_ptk(), wpa_maybe_install_gtk(), WPA_NONCE_LEN, wpa_send_final(), WPA_SUCCESS, WPA_WAITING, and WPA_WORKING.
Referenced by eapol_key_rx().
|
static |
Handle receipt of first frame in Group Key Handshake.
ctx | WPA common context |
pkt | EAPOL-Key packet |
is_rsn | If TRUE, frame uses new RSN format |
kie | Key integrity and encryption handler |
rc | Return status code |
Definition at line 702 of file wpa.c.
References ctx, eapol_key_pkt::data, eapol_key_pkt::datalen, DBGC, wpa_kie::decrypt, EAPOL_KEY_INFO_KEY_ENC, EINVAL, eapol_key_pkt::info, eapol_key_pkt::iv, memcpy(), rc, eapol_key_pkt::rsc, strerror(), wpa_fail(), wpa_install_gtk(), wpa_maybe_install_gtk(), and wpa_send_final().
Referenced by eapol_key_rx().
|
static |
Handle receipt of EAPOL-Key frame for WPA.
supplicant | EAPoL supplicant |
iob | I/O buffer |
ll_source | Source link-layer address |
Definition at line 768 of file wpa.c.
References be64_to_cpu, net80211_device::bssid, ctx, io_buffer::data, eapol_key_pkt::data, eapol_key_pkt::datalen, DBG, DBGC, DBGC2, DBGC2_HD, wpa_kie::decrypt, eapol_supplicant::eap, EAPOL_KEY_INFO_KEY_ACK, EAPOL_KEY_INFO_KEY_ENC, EAPOL_KEY_INFO_KEY_MIC, EAPOL_KEY_INFO_TYPE, EAPOL_KEY_INFO_VERSION, EAPOL_KEY_TYPE_GTK, EAPOL_KEY_TYPE_PTK, EAPOL_KEY_TYPE_RSN, EAPOL_KEY_TYPE_WPA, EINVAL, ENOENT, ENOTSUP, ETH_ALEN, free_iob(), eapol_key_pkt::info, eapol_key_pkt::iv, eapol_key_pkt::keysize, list_for_each_entry, memcmp(), memcpy(), memset(), eapol_key_pkt::mic, wpa_kie::mic, net80211_get(), netdev, eap_supplicant::netdev, ntohs, rc, eapol_key_pkt::replay, strerror(), io_buffer::tail, eapol_key_pkt::type, wpa_contexts, wpa_fail(), wpa_find_kie(), wpa_handle_1_of_2(), wpa_handle_1_of_4(), and wpa_handle_3_of_4().
REQUIRING_SYMBOL | ( | eapol_key_handler | ) |
REQUIRE_OBJECT | ( | eapol | ) |
struct list_head wpa_contexts = LIST_HEAD_INIT ( wpa_contexts ) |
List of WPA contexts in active use.
Definition at line 46 of file wpa.c.
Referenced by eapol_key_rx(), wpa_start(), and wpa_stop().
struct eapol_handler eapol_key_handler __eapol_handler |