138 DBG (
"WPA: Can't make RSN IE for a non-associating device\n" );
148 DBG (
"WPA: Can't make RSN IE when we didn't get one\n" );
158 DBG (
"WPA: No support for (GC:%d, PC:%d)\n",
218 const void *pmk,
size_t pmk_len )
223 u8 *ap_rsn_ie =
NULL, *ap_rsn_ie_end;
237 &
ctx->ap_rsn_is_rsn, &ap_rsn_ie_end );
239 ctx->ap_rsn_ie =
malloc ( ap_rsn_ie_end - ap_rsn_ie );
240 if ( !
ctx->ap_rsn_ie )
242 memcpy (
ctx->ap_rsn_ie, ap_rsn_ie, ap_rsn_ie_end - ap_rsn_ie );
243 ctx->ap_rsn_ie_len = ap_rsn_ie_end - ap_rsn_ie;
291 if (
memcmp (
ctx->dev->netdev->ll_addr,
ctx->dev->bssid,
316 "Pairwise key expansion",
317 &ptk_data, sizeof ( ptk_data ),
318 &
ctx->ptk, sizeof (
ctx->ptk ) );
334 DBGC (
ctx,
"WPA %p: installing %d-byte pairwise transient key\n",
353 DBGC (
ctx,
"WPA %p: installing %d-byte group transient key\n",
390 if ( ie->
len - 6u > sizeof (
ctx->gtk.tk ) ) {
391 DBGC (
ctx,
"WPA %p: GTK KDE is too long (%d bytes, max %zd)\n",
392 ctx, ie->
len - 4, sizeof (
ctx->gtk.tk ) );
459 kie->
mic ( &
ctx->ptk.kck, eapol, sizeof ( *eapol ) +
463 return net_tx ( iob,
ctx->dev->netdev, &eapol_protocol,
464 ctx->dev->bssid,
ctx->dev->netdev->ll_addr );
488 memcpy ( npkt, pkt,
sizeof ( *pkt ) );
522 if ( !
ctx->have_Snonce ) {
524 sizeof (
ctx->Snonce ) );
525 ctx->have_Snonce = 1;
528 DBGC (
ctx,
"WPA %p: received 1/4, looks OK\n",
ctx );
556 memcpy ( npkt, pkt,
sizeof ( *pkt ) );
589 u8 *this_rsn, *this_rsn_end;
590 u8 *new_rsn, *new_rsn_end;
591 int this_is_rsn, new_is_rsn;
600 DBGC (
ctx,
"WPA %p ALERT: nonce mismatch in 3/4\n",
ctx );
607 &this_is_rsn, &this_rsn_end );
612 &new_is_rsn, &new_rsn_end );
616 if ( !
ctx->ap_rsn_ie || ! this_rsn ||
617 ctx->ap_rsn_ie_len != ( this_rsn_end - this_rsn ) ||
618 ctx->ap_rsn_is_rsn != this_is_rsn ||
619 memcmp (
ctx->ap_rsn_ie, this_rsn,
ctx->ap_rsn_ie_len ) != 0 ) {
620 DBGC (
ctx,
"WPA %p ALERT: RSN mismatch in 3/4\n",
ctx );
621 DBGC2 (
ctx,
"WPA %p RSNs (in 3/4, in beacon):\n",
ctx );
622 DBGC2_HD (
ctx, this_rsn, this_rsn_end - this_rsn );
631 if ( new_rsn && this_is_rsn == new_is_rsn ) {
633 DBGC (
ctx,
"WPA %p: accommodating bait-and-switch tactics\n",
635 DBGC2 (
ctx,
"WPA %p RSNs (in 3/4+beacon, new in 3/4):\n",
637 DBGC2_HD (
ctx, this_rsn, this_rsn_end - this_rsn );
644 DBGC (
ctx,
"WPA %p: bait-and-switch invalid, staying "
645 "with original request\n",
ctx );
648 new_is_rsn = this_is_rsn;
649 new_rsn_end = this_rsn_end;
663 DBGC (
ctx,
"WPA %p did not install GTK in 3/4: %s\n",
670 DBGC (
ctx,
"WPA %p: received 3/4, looks OK\n",
ctx );
680 DBGC (
ctx,
"WPA %p failed to install PTK: %s\n",
ctx,
686 ctx->have_Snonce = 0;
734 DBGC (
ctx,
"WPA %p: failed to install GTK in 1/2: "
742 DBGC (
ctx,
"WPA %p: failed to decrypt GTK: %s\n",
746 if ( pkt->
datalen > sizeof (
ctx->gtk.tk ) ) {
747 DBGC (
ctx,
"WPA %p: too much GTK data (%d > %zd)\n",
756 DBGC (
ctx,
"WPA %p: received 1/2, looks OK\n",
ctx );
770 struct io_buffer *iob,
const void *ll_source )
776 int is_rsn, found_ctx;
780 u8 their_mic[16], our_mic[16];
783 pkt = ( ( (
void * ) eapol ) +
sizeof ( *eapol ) );
787 DBG (
"EAPOL-Key: packet not of 802.11 type\n" );
795 DBG (
"EAPOL-Key: packet not from 802.11\n" );
801 DBG (
"EAPOL-Key: packet not from associated AP\n" );
807 DBG (
"EAPOL-Key: packet sent in wrong direction\n" );
814 if (
ctx->dev == dev ) {
821 DBG (
"EAPOL-Key: no WPA context to handle packet for %p\n",
828 DBGC (
ctx,
"WPA %p: packet truncated (has %zd extra bytes, "
829 "states %d)\n",
ctx, iob->
tail - (
void * ) ( pkt + 1 ),
838 DBGC (
ctx,
"WPA %p: no support for packet version %d\n",
ctx,
848 kie->
mic ( &
ctx->ptk.kck, eapol,
849 sizeof ( *eapol ) +
sizeof ( *pkt ) +
851 DBGC2 (
ctx,
"WPA %p MIC comparison (theirs, ours):\n",
ctx );
854 if (
memcmp ( their_mic, our_mic,
sizeof ( pkt->
mic ) ) != 0 ) {
855 DBGC (
ctx,
"WPA %p: EAPOL MIC failure\n",
ctx );
867 if (
ctx->replay != ~0ULL &&
ctx->replay >= pkt->
replay ) {
868 DBGC (
ctx,
"WPA %p ALERT: Replay detected! "
869 "(%08x:%08x >= %08x:%08x)\n",
ctx,
882 DBGC (
ctx,
"WPA %p: failed to decrypt packet: %s\n",
904 DBGC (
ctx,
"WPA %p: Invalid combination of key flags %04x\n",
#define NULL
NULL pointer (VOID *)
struct golan_eq_context ctx
struct golan_inbox_hdr hdr
Message header.
struct arbelprm_rc_send_wqe rc
u32 version
Driver version.
Extensible Authentication Protocol over LAN (EAPoL)
#define __eapol_handler
Declare an EAPoL handler.
#define EAPOL_VERSION_2001
802.1X-2001
#define EAPOL_TYPE_KEY
EAPoL key.
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
static struct net_device * netdev
#define DBG(...)
Print a debugging message.
#define EAPOL_KEY_INFO_KEY_ENC
Key Encrypted bit; set when the Key Data field is encrypted.
#define EAPOL_KEY_INFO_KEY_MIC
Key MIC bit; set when the MIC field is valid, on messages 3 and 4.
#define EAPOL_KEY_TYPE_PTK
Key type field value for a PTK (pairwise) key handshake.
#define EAPOL_KEY_INFO_INSTALL
Key install bit; set on message 3 except when legacy hacks are used.
#define EAPOL_KEY_INFO_TYPE
Key type bit, indicating pairwise or group.
#define EAPOL_KEY_INFO_VERSION
Key descriptor version, indicating WPA or WPA2.
#define EAPOL_KEY_INFO_KEY_ACK
Key ACK bit; set when a response is required, on all messages except #4.
#define EAPOL_KEY_TYPE_GTK
Key type field value for a GTK (group) key handshake.
static size_t ieee80211_rsn_size(int npair, int nauth, int npmkid, int rsn_ie)
Calculate necessary size of RSN information element.
static int ieee80211_ie_bound(union ieee80211_ie *ie, void *end)
Check that 802.11 information element is bounded by buffer.
#define IEEE80211_WPA_OUI_VEN
Old vendor-type WPA IE OUI type + subtype.
#define IEEE80211_IE_VENDOR
Information element ID for Vendor Specific information element.
#define IEEE80211_RSN_VERSION
802.11 RSN IE: expected version number
static union ieee80211_ie * ieee80211_next_ie(union ieee80211_ie *ie, void *end)
Advance to next 802.11 information element.
#define IEEE80211_IE_RSN
Information element ID for Robust Security Network information element.
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
void net80211_deauthenticate(struct net80211_device *dev, int rc)
Deauthenticate from current network and try again.
struct net80211_device * net80211_get(struct net_device *netdev)
Get 802.11 device from wrapping network device.
#define REQUIRE_OBJECT(object)
Require an object.
#define ENOENT
No such file or directory.
#define EINVAL
Invalid argument.
#define ENOMEM
Not enough space.
#define ENOTSUP
Operation not supported.
#define EACCES
Permission denied.
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
#define REQUIRING_SYMBOL(symbol)
Specify the file's requiring symbol.
#define WPA_KDE_GTK
KDE type for an encapsulated Group Transient Key (requires encryption)
Keyed-Hashing for Message Authentication.
u32 group_cipher
Cipher ID for the cipher used in multicast/broadcast frames.
#define cpu_to_be64(value)
#define be64_to_cpu(value)
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
#define iob_push(iobuf, len)
#define iob_put(iobuf, len)
#define iob_reserve(iobuf, len)
#define LIST_HEAD_INIT(list)
Initialise a static list head.
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
#define list_del(list)
Delete an entry from a list.
void * malloc(size_t size)
Allocate memory.
The iPXE 802.11 MAC layer.
net80211_crypto_alg
An 802.11 data encryption algorithm.
@ NET80211_CRYPT_UNKNOWN
Dummy value used when the cryptosystem can't be detected.
int net_tx(struct io_buffer *iobuf, struct net_device *netdev, struct net_protocol *net_protocol, const void *ll_dest, const void *ll_source)
Transmit network-layer packet.
#define MAX_LL_HEADER_LEN
Maximum length of a link-layer header.
int rbg_generate(const void *additional, size_t additional_len, int prediction_resist, void *data, size_t len)
Generate bits using RBG.
static void(* free)(struct refcnt *refcnt))
u8 * sec80211_find_rsn(union ieee80211_ie *ie, void *ie_end, int *is_rsn, u8 **end)
Find the RSN or WPA information element in the provided beacon frame.
enum net80211_crypto_alg sec80211_rsn_get_net80211_crypt(u32 desc)
Determine net80211 cryptosystem number from RSN descriptor.
int sec80211_install(struct net80211_crypto **which, enum net80211_crypto_alg crypt, const void *key, int len, const void *rsc)
Install 802.11 cryptosystem.
int sec80211_detect_ie(int is_rsn, u8 *start, u8 *end, enum net80211_security_proto *secprot, enum net80211_crypto_alg *crypt)
Detect crypto and AKM types from RSN information element.
u32 sec80211_rsn_get_crypto_desc(enum net80211_crypto_alg crypt, int rsnie)
Determine RSN descriptor for specified net80211 cryptosystem number.
u32 sec80211_rsn_get_akm_desc(enum net80211_security_proto secprot, int rsnie)
Determine RSN descriptor for specified net80211 handshaker number.
Definitions for general secured-network routines.
char * strerror(int errno)
Retrieve string representation of error number.
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
struct net_device * netdev
Network device.
u8 iv[16]
Initialization vector.
u16 keysize
Length of encryption key to be used, network byte order.
u8 rsc[8]
Receive sequence counter for GTK.
u8 mic[16]
Message integrity code over the entire EAPOL frame.
u16 info
Bitfield of key characteristics, network byte order.
u8 type
One of the EAPOL_KEY_TYPE_* defines.
u16 datalen
Length of the data field in bytes, network byte order.
u64 replay
Monotonically increasing value for EAPOL-Key conversations.
struct eap_supplicant eap
EAP supplicant.
An 802.11 data or management frame without QoS or WDS header fields.
802.11 Robust Security Network ("WPA") information element
u16 akm_count
Number of authentication types supported.
u16 pairwise_count
Number of unicast ciphers supported.
u32 akm_list[1]
List of authentication type IDs for supported types.
u32 pairwise_cipher[1]
List of cipher IDs for supported unicast frame ciphers.
u16 rsn_capab
Security capabilities field (RSN only)
u32 group_cipher
Cipher ID for the cipher used in multicast/broadcast frames.
u16 pmkid_count
Number of PMKIDs included (present only in association frames)
u16 version
RSN information element version.
u32 oui
OUI and vendor-specific type byte.
void * data
Start of data.
A doubly-linked list entry (or list head)
Interface to an 802.11 cryptosystem.
enum net80211_crypto_alg algorithm
The cryptographic algorithm implemented.
Structure encapsulating the complete state of an 802.11 device.
union ieee80211_ie * rsn_ie
RSN or WPA information element to include with association.
struct net80211_wlan * associating
Network with which we are associating.
u8 bssid[ETH_ALEN]
MAC address of the access point most recently associated.
Structure representing a probed network.
struct io_buffer * beacon
The complete beacon or probe-response frame received.
enum net80211_crypto_alg crypto
Cryptographic algorithm used on the network.
enum net80211_security_proto handshaking
Security handshaking method used on the network.
Common context for WPA security handshaking.
struct list_head list
List entry.
struct net80211_device * dev
802.11 device we are authenticating for
struct wpa_gtk gtk
Encapsulated group transient key.
Any key descriptor element type.
u8 len
Length, not including ie_type and length fields.
struct wpa_kde_gtk_encap gtk_encap
For GTK-type KDEs, encapsulated GTK.
WPA handshake key integrity and encryption handler.
int version
Value of version bits in EAPOL-Key info field for which to use.
int(* decrypt)(const void *kek, const void *iv, void *msg, u16 *len)
Decrypt key data.
void(* mic)(const void *kck, const void *msg, size_t len, void *mic)
Calculate MIC over message.
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Any 802.11 information element.
u8 len
Information element data length.
struct ieee80211_ie_vendor vendor
Vendor-specific.
u8 id
Information element ID.
static int wpa_install_ptk(struct wpa_common_ctx *ctx, int len)
Install pairwise transient key.
int wpa_make_rsn_ie(struct net80211_device *dev, union ieee80211_ie **ie_ret)
Construct RSN or WPA information element.
static int wpa_fail(struct wpa_common_ctx *ctx, int rc)
Return an error code and deauthenticate.
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.
void wpa_stop(struct net80211_device *dev)
Disable handling of received WPA handshake frames.
struct wpa_kie * wpa_find_kie(int version)
Find WPA key integrity and encryption handler from key version field.
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.
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.
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.
struct list_head wpa_contexts
List of WPA contexts in active use.
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.
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.
static int wpa_install_gtk(struct wpa_common_ctx *ctx, int len, const void *rsc)
Install group transient key.
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.
static void wpa_derive_ptk(struct wpa_common_ctx *ctx)
Derive pairwise transient key.
static struct net80211_crypto * wpa_find_cryptosystem(enum net80211_crypto_alg crypt)
Find a cryptosystem handler structure from a crypto ID.
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.
static int wpa_send_eapol(struct io_buffer *iob, struct wpa_common_ctx *ctx, struct wpa_kie *kie)
Send EAPOL-Key packet.
static struct io_buffer * wpa_alloc_frame(int kdlen)
Allocate I/O buffer for construction of outgoing EAPOL-Key frame.
Common definitions for all types of WPA-protected networks.
#define EAPOL_KEY_TYPE_WPA
Old EAPOL-Key type field used by WPA1 hardware before 802.11i ratified.
u8 rsc[8]
Receive sequence counter for GTK.
#define WPA_NONCE_LEN
Length of a nonce.
#define EAPOL_KEY_TYPE_RSN
EAPOL-Key type field for modern 802.11i/RSN WPA packets.
@ WPA_WAITING
Waiting for PMK to be set.
@ WPA_WORKING
Performing 4-Way Handshake.
@ WPA_SUCCESS
4-Way Handshake succeeded
@ WPA_READY
Ready for 4-Way Handshake.