137 DBG (
"WPA: Can't make RSN IE for a non-associating device\n" );
147 DBG (
"WPA: Can't make RSN IE when we didn't get one\n" );
157 DBG (
"WPA: No support for (GC:%d, PC:%d)\n",
217 const void *pmk,
size_t pmk_len )
222 u8 *ap_rsn_ie =
NULL, *ap_rsn_ie_end;
236 &
ctx->ap_rsn_is_rsn, &ap_rsn_ie_end );
238 ctx->ap_rsn_ie =
malloc ( ap_rsn_ie_end - ap_rsn_ie );
239 if ( !
ctx->ap_rsn_ie )
241 memcpy (
ctx->ap_rsn_ie, ap_rsn_ie, ap_rsn_ie_end - ap_rsn_ie );
242 ctx->ap_rsn_ie_len = ap_rsn_ie_end - ap_rsn_ie;
290 if (
memcmp (
ctx->dev->netdev->ll_addr,
ctx->dev->bssid,
315 "Pairwise key expansion",
316 &ptk_data, sizeof ( ptk_data ),
317 &
ctx->ptk, sizeof (
ctx->ptk ) );
333 DBGC (
ctx,
"WPA %p: installing %d-byte pairwise transient key\n",
352 DBGC (
ctx,
"WPA %p: installing %d-byte group transient key\n",
389 if ( ie->
len - 6
u > sizeof (
ctx->gtk.tk ) ) {
390 DBGC (
ctx,
"WPA %p: GTK KDE is too long (%d bytes, max %zd)\n",
391 ctx, ie->
len - 4, sizeof (
ctx->gtk.tk ) );
458 kie->
mic ( &
ctx->ptk.kck, eapol, sizeof ( *eapol ) +
462 return net_tx ( iob,
ctx->dev->netdev, &eapol_protocol,
463 ctx->dev->bssid,
ctx->dev->netdev->ll_addr );
487 memcpy ( npkt, pkt,
sizeof ( *pkt ) );
521 if ( !
ctx->have_Snonce ) {
523 sizeof (
ctx->Snonce ) );
524 ctx->have_Snonce = 1;
527 DBGC (
ctx,
"WPA %p: received 1/4, looks OK\n",
ctx );
555 memcpy ( npkt, pkt,
sizeof ( *pkt ) );
588 u8 *this_rsn, *this_rsn_end;
589 u8 *new_rsn, *new_rsn_end;
590 int this_is_rsn, new_is_rsn;
599 DBGC (
ctx,
"WPA %p ALERT: nonce mismatch in 3/4\n",
ctx );
606 &this_is_rsn, &this_rsn_end );
611 &new_is_rsn, &new_rsn_end );
615 if ( !
ctx->ap_rsn_ie || ! this_rsn ||
616 ctx->ap_rsn_ie_len != ( this_rsn_end - this_rsn ) ||
617 ctx->ap_rsn_is_rsn != this_is_rsn ||
618 memcmp (
ctx->ap_rsn_ie, this_rsn,
ctx->ap_rsn_ie_len ) != 0 ) {
619 DBGC (
ctx,
"WPA %p ALERT: RSN mismatch in 3/4\n",
ctx );
620 DBGC2 (
ctx,
"WPA %p RSNs (in 3/4, in beacon):\n",
ctx );
621 DBGC2_HD (
ctx, this_rsn, this_rsn_end - this_rsn );
630 if ( new_rsn && this_is_rsn == new_is_rsn ) {
632 DBGC (
ctx,
"WPA %p: accommodating bait-and-switch tactics\n",
634 DBGC2 (
ctx,
"WPA %p RSNs (in 3/4+beacon, new in 3/4):\n",
636 DBGC2_HD (
ctx, this_rsn, this_rsn_end - this_rsn );
643 DBGC (
ctx,
"WPA %p: bait-and-switch invalid, staying " 644 "with original request\n",
ctx );
647 new_is_rsn = this_is_rsn;
648 new_rsn_end = this_rsn_end;
662 DBGC (
ctx,
"WPA %p did not install GTK in 3/4: %s\n",
669 DBGC (
ctx,
"WPA %p: received 3/4, looks OK\n",
ctx );
679 DBGC (
ctx,
"WPA %p failed to install PTK: %s\n",
ctx,
685 ctx->have_Snonce = 0;
733 DBGC (
ctx,
"WPA %p: failed to install GTK in 1/2: " 741 DBGC (
ctx,
"WPA %p: failed to decrypt GTK: %s\n",
745 if ( pkt->
datalen > sizeof (
ctx->gtk.tk ) ) {
746 DBGC (
ctx,
"WPA %p: too much GTK data (%d > %zd)\n",
755 DBGC (
ctx,
"WPA %p: received 1/2, looks OK\n",
ctx );
769 struct io_buffer *iob,
const void *ll_source )
775 int is_rsn, found_ctx;
779 u8 their_mic[16], our_mic[16];
782 pkt = ( ( (
void * ) eapol ) +
sizeof ( *eapol ) );
786 DBG (
"EAPOL-Key: packet not of 802.11 type\n" );
794 DBG (
"EAPOL-Key: packet not from 802.11\n" );
800 DBG (
"EAPOL-Key: packet not from associated AP\n" );
806 DBG (
"EAPOL-Key: packet sent in wrong direction\n" );
813 if (
ctx->dev == dev ) {
820 DBG (
"EAPOL-Key: no WPA context to handle packet for %p\n",
827 DBGC (
ctx,
"WPA %p: packet truncated (has %zd extra bytes, " 828 "states %d)\n",
ctx, iob->
tail - (
void * ) ( pkt + 1 ),
837 DBGC (
ctx,
"WPA %p: no support for packet version %d\n",
ctx,
847 kie->
mic ( &
ctx->ptk.kck, eapol,
848 sizeof ( *eapol ) +
sizeof ( *pkt ) +
850 DBGC2 (
ctx,
"WPA %p MIC comparison (theirs, ours):\n",
ctx );
853 if (
memcmp ( their_mic, our_mic,
sizeof ( pkt->
mic ) ) != 0 ) {
854 DBGC (
ctx,
"WPA %p: EAPOL MIC failure\n",
ctx );
866 if (
ctx->replay != ~0ULL &&
ctx->replay >= pkt->
replay ) {
867 DBGC (
ctx,
"WPA %p ALERT: Replay detected! " 868 "(%08x:%08x >= %08x:%08x)\n",
ctx,
881 DBGC (
ctx,
"WPA %p: failed to decrypt packet: %s\n",
903 DBGC (
ctx,
"WPA %p: Invalid combination of key flags %04x\n",
u32 akm_list[1]
List of authentication type IDs for supported types.
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.
#define EINVAL
Invalid argument.
u8 type
One of the EAPOL_KEY_TYPE_* defines.
struct arbelprm_rc_send_wqe rc
Performing 4-Way Handshake.
struct net80211_device * dev
802.11 device we are authenticating for
Structure representing a probed network.
static int wpa_send_eapol(struct io_buffer *iob, struct wpa_common_ctx *ctx, struct wpa_kie *kie)
Send EAPOL-Key packet.
enum net80211_crypto_alg crypto
Cryptographic algorithm used on the network.
#define iob_put(iobuf, len)
static union ieee80211_ie * ieee80211_next_ie(union ieee80211_ie *ie, void *end)
Advance to next 802.11 information element.
static struct net80211_crypto * wpa_find_cryptosystem(enum net80211_crypto_alg crypt)
Find a cryptosystem handler structure from a crypto ID.
u16 version
RSN information element version.
#define EAPOL_KEY_INFO_KEY_ENC
Key Encrypted bit; set when the Key Data field is encrypted.
Dummy value used when the cryptosystem can't be detected.
struct golan_inbox_hdr hdr
Message header.
u16 rsn_capab
Security capabilities field (RSN only)
#define iob_push(iobuf, len)
static int rbg_generate(const void *additional, size_t additional_len, int prediction_resist, void *data, size_t len)
Generate bits using RBG.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
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.
u32 oui
OUI and vendor-specific type byte.
enum net80211_security_proto handshaking
Security handshaking method used on the network.
WPA handshake key integrity and encryption handler.
An 802.11 data or management frame without QoS or WDS header fields.
static int wpa_install_ptk(struct wpa_common_ctx *ctx, int len)
Install pairwise transient key.
#define ENOENT
No such file or directory.
union ieee80211_ie * rsn_ie
RSN or WPA information element to include with association.
struct wpa_gtk gtk
Encapsulated group transient key.
#define EACCES
Permission denied.
struct golan_eq_context ctx
u16 keysize
Length of encryption key to be used, network byte order.
void net80211_deauthenticate(struct net80211_device *dev, int rc)
Deauthenticate from current network and try again.
struct list_head wpa_contexts
List of WPA contexts in active use.
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.
Ready for 4-Way Handshake.
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definitions for general secured-network routines.
#define ENOTSUP
Operation not supported.
A doubly-linked list entry (or list head)
#define EAPOL_KEY_TYPE_WPA
Old EAPOL-Key type field used by WPA1 hardware before 802.11i ratified.
u16 pmkid_count
Number of PMKIDs included (present only in association frames)
static int wpa_fail(struct wpa_common_ctx *ctx, int rc)
Return an error code and deauthenticate.
#define list_del(list)
Delete an entry from a list.
u8 mic[16]
Message integrity code over the entire EAPOL frame.
#define ENOMEM
Not enough space.
static size_t ieee80211_rsn_size(int npair, int nauth, int npmkid, int rsn_ie)
Calculate necessary size of RSN information element.
u32 group_cipher
Cipher ID for the cipher used in multicast/broadcast frames.
enum net80211_crypto_alg algorithm
The cryptographic algorithm implemented.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static void wpa_derive_ptk(struct wpa_common_ctx *ctx)
Derive pairwise transient key.
#define EAPOL_KEY_TYPE_GTK
Key type field value for a GTK (group) key handshake.
u32 version
Driver version.
Common definitions for all types of WPA-protected networks.
u8 id
Information element ID.
#define IEEE80211_WPA_OUI_VEN
Old vendor-type WPA IE OUI type + subtype.
#define EAPOL_KEY_INFO_VERSION
Key descriptor version, indicating WPA or WPA2.
u8 rsc[8]
Receive sequence counter for GTK.
Keyed-Hashing for Message Authentication.
#define EAPOL_KEY_INFO_KEY_ACK
Key ACK bit; set when a response is required, on all messages except #4.
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.
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
#define EAPOL_TYPE_KEY
EAPoL key.
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
struct wpa_kie * wpa_find_kie(int version)
Find WPA key integrity and encryption handler from key version field.
#define WPA_KDE_GTK
KDE type for an encapsulated Group Transient Key (requires encryption)
u8 rsc[8]
Receive sequence counter for GTK.
4-Way Handshake succeeded
struct eap_supplicant eap
EAP supplicant.
static struct net_device * netdev
REQUIRING_SYMBOL(eapol_key_handler)
#define MAX_LL_HEADER_LEN
Maximum length of a link-layer header.
int version
Value of version bits in EAPOL-Key info field for which to use.
Common context for WPA security handshaking.
Extensible Authentication Protocol over LAN (EAPoL)
int sec80211_install(struct net80211_crypto **which, enum net80211_crypto_alg crypt, const void *key, int len, const void *rsc)
Install 802.11 cryptosystem.
#define WPA_NONCE_LEN
Length of a nonce.
u16 info
Bitfield of key characteristics, network byte order.
int(* decrypt)(const void *kek, const void *iv, void *msg, u16 *len)
Decrypt key data.
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
#define EAPOL_KEY_TYPE_RSN
EAPOL-Key type field for modern 802.11i/RSN WPA packets.
u16 akm_count
Number of authentication types supported.
int wpa_make_rsn_ie(struct net80211_device *dev, union ieee80211_ie **ie_ret)
Construct RSN or WPA information element.
#define IEEE80211_IE_VENDOR
Information element ID for Vendor Specific information element.
char * strerror(int errno)
Retrieve string representation of error number.
#define be64_to_cpu(value)
static void(* free)(struct refcnt *refcnt))
The iPXE 802.11 MAC layer.
u32 pairwise_cipher[1]
List of cipher IDs for supported unicast frame ciphers.
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
Waiting for PMK to be set.
Structure encapsulating the complete state of an 802.11 device.
#define EAPOL_VERSION_2001
802.1X-2001
#define IEEE80211_IE_RSN
Information element ID for Robust Security Network information element.
void(* mic)(const void *kck, const void *msg, size_t len, void *mic)
Calculate MIC over message.
struct ieee80211_ie_vendor vendor
Vendor-specific.
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
void wpa_stop(struct net80211_device *dev)
Disable handling of received WPA handshake frames.
FILE_LICENCE(GPL2_OR_LATER)
static int ieee80211_ie_bound(union ieee80211_ie *ie, void *end)
Check that 802.11 information element is bounded by buffer.
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.
u16 datalen
Length of the data field in bytes, network byte order.
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.
u16 pairwise_count
Number of unicast ciphers supported.
struct wpa_kde_gtk_encap gtk_encap
For GTK-type KDEs, encapsulated GTK.
Any 802.11 information element.
void * malloc(size_t size)
Allocate memory.
struct net80211_device * net80211_get(struct net_device *netdev)
Get 802.11 device from wrapping network device.
u8 len
Information element data length.
struct net80211_wlan * associating
Network with which we are associating.
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.
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.
802.11 Robust Security Network ("WPA") information element
#define iob_reserve(iobuf, len)
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.
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.
struct eapol_handler eapol_key_handler __eapol_handler
net80211_crypto_alg
An 802.11 data encryption algorithm.
void * data
Start of data.
struct list_head list
List entry.
u8 iv[16]
Initialization vector.
u32 group_cipher
Cipher ID for the cipher used in multicast/broadcast frames.
u8 len
Length, not including ie_type and length fields.
#define cpu_to_be64(value)
#define IEEE80211_RSN_VERSION
802.11 RSN IE: expected version number
Any key descriptor element type.
enum net80211_crypto_alg sec80211_rsn_get_net80211_crypt(u32 desc)
Determine net80211 cryptosystem number from RSN descriptor.
#define EAPOL_KEY_INFO_KEY_MIC
Key MIC bit; set when the MIC field is valid, on messages 3 and 4.
struct net_device * netdev
Network device.
u8 bssid[ETH_ALEN]
MAC address of the access point most recently associated.
#define EAPOL_KEY_INFO_INSTALL
Key install bit; set on message 3 except when legacy hacks are used.
#define EAPOL_KEY_TYPE_PTK
Key type field value for a PTK (pairwise) key handshake.
#define DBG(...)
Print a debugging message.
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Interface to an 802.11 cryptosystem.
struct io_buffer * beacon
The complete beacon or probe-response frame received.
static struct io_buffer * wpa_alloc_frame(int kdlen)
Allocate I/O buffer for construction of outgoing EAPOL-Key frame.
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
u64 replay
Monotonically increasing value for EAPOL-Key conversations.
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.
#define NULL
NULL pointer (VOID *)
static int wpa_install_gtk(struct wpa_common_ctx *ctx, int len, const void *rsc)
Install group transient key.
void * memset(void *dest, int character, size_t len) __nonnull
#define EAPOL_KEY_INFO_TYPE
Key type bit, indicating pairwise or group.
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.