123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504 |
- /*
- * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
- #ifndef _IPXE_WPA_H
- #define _IPXE_WPA_H
-
- #include <ipxe/ieee80211.h>
- #include <ipxe/list.h>
-
- FILE_LICENCE ( GPL2_OR_LATER );
-
- /** @file
- *
- * Common definitions for all types of WPA-protected networks.
- */
-
-
- /** EAPOL-Key type field for modern 802.11i/RSN WPA packets */
- #define EAPOL_KEY_TYPE_RSN 2
-
- /** Old EAPOL-Key type field used by WPA1 hardware before 802.11i ratified */
- #define EAPOL_KEY_TYPE_WPA 254
-
-
- /**
- * @defgroup eapol_key_info EAPOL-Key Info field bits
- * @{
- */
-
- /** Key descriptor version, indicating WPA or WPA2 */
- #define EAPOL_KEY_INFO_VERSION 0x0007
-
- /** Key type bit, indicating pairwise or group */
- #define EAPOL_KEY_INFO_TYPE 0x0008
-
- /** Key install bit; set on message 3 except when legacy hacks are used */
- #define EAPOL_KEY_INFO_INSTALL 0x0040
-
- /** Key ACK bit; set when a response is required, on all messages except #4 */
- #define EAPOL_KEY_INFO_KEY_ACK 0x0080
-
- /** Key MIC bit; set when the MIC field is valid, on messages 3 and 4 */
- #define EAPOL_KEY_INFO_KEY_MIC 0x0100
-
- /** Secure bit; set when both sides have both keys, on messages 3 and 4 */
- #define EAPOL_KEY_INFO_SECURE 0x0200
-
- /** Error bit; set on a MIC failure for TKIP */
- #define EAPOL_KEY_INFO_ERROR 0x0400
-
- /** Request bit; set when authentication is initiated by the Peer (unusual) */
- #define EAPOL_KEY_INFO_REQUEST 0x0800
-
- /** Key Encrypted bit; set when the Key Data field is encrypted */
- #define EAPOL_KEY_INFO_KEY_ENC 0x1000
-
- /** SMC Message bit; set when this frame is part of an IBSS SMK handshake */
- #define EAPOL_KEY_INFO_SMC_MESS 0x2000
-
-
- /** Key descriptor version field value for WPA (TKIP) */
- #define EAPOL_KEY_VERSION_WPA 1
-
- /** Key descriptor version field value for WPA2 (CCMP) */
- #define EAPOL_KEY_VERSION_WPA2 2
-
- /** Key type field value for a PTK (pairwise) key handshake */
- #define EAPOL_KEY_TYPE_PTK 0x0008
-
- /** Key type field value for a GTK (group) key handshake */
- #define EAPOL_KEY_TYPE_GTK 0x0000
-
- /** @} */
-
-
-
- /** An EAPOL-Key packet.
- *
- * These are used for the WPA 4-Way Handshake, whether or not prior
- * authentication has been performed using EAP.
- *
- * On LANs, an eapol_key_pkt is always encapsulated in the data field
- * of an eapol_frame, with the frame's type code set to EAPOL_TYPE_KEY.
- *
- * Unlike 802.11 frame headers, the fields in this structure are
- * stored in big-endian!
- */
- struct eapol_key_pkt
- {
- /** One of the EAPOL_KEY_TYPE_* defines. */
- u8 type;
-
- /** Bitfield of key characteristics, network byte order */
- u16 info;
-
- /** Length of encryption key to be used, network byte order
- *
- * This is 16 for CCMP, 32 for TKIP, and 5 or 13 for WEP.
- */
- u16 keysize;
-
- /** Monotonically increasing value for EAPOL-Key conversations
- *
- * In another classic demonstration of overengineering, this
- * 8-byte value will rarely be anything above 1. It's stored
- * in network byte order.
- */
- u64 replay;
-
- /** Nonce value
- *
- * This is the authenticator's ANonce in frame 1, the peer's
- * SNonce in frame 2, and 0 in frames 3 and 4.
- */
- u8 nonce[32];
-
- /** Initialization vector
- *
- * This contains the IV used with the Key Encryption Key, or 0
- * if the key is unencrypted or encrypted using an algorithm
- * that does not require an IV.
- */
- u8 iv[16];
-
- /** Receive sequence counter for GTK
- *
- * This is used to synchronize the client's replay counter for
- * ordinary data packets. The first six bytes contain PN0
- * through PN5 for CCMP mode, or TSC0 through TSC5 for TKIP
- * mode. The last two bytes are zero.
- */
- u8 rsc[8];
-
- /** Reserved bytes */
- u8 _reserved[8];
-
- /** Message integrity code over the entire EAPOL frame
- *
- * This is calculated using HMAC-MD5 when the key descriptor
- * version field in @a info is 1, and HMAC-SHA1 ignoring the
- * last 4 bytes of the hash when the version field in @a info
- * is 2.
- */
- u8 mic[16];
-
- /** Length of the @a data field in bytes, network byte order */
- u16 datalen;
-
- /** Key data
- *
- * This is formatted as a series of 802.11 information
- * elements, with cryptographic data encapsulated using a
- * "vendor-specific IE" code and an IEEE-specified OUI.
- */
- u8 data[0];
- } __attribute__ (( packed ));
-
-
- /** WPA handshaking state */
- enum wpa_state {
- /** Waiting for PMK to be set */
- WPA_WAITING = 0,
-
- /** Ready for 4-Way Handshake */
- WPA_READY,
-
- /** Performing 4-Way Handshake */
- WPA_WORKING,
-
- /** 4-Way Handshake succeeded */
- WPA_SUCCESS,
-
- /** 4-Way Handshake failed */
- WPA_FAILURE,
- };
-
- /** Bitfield indicating a selection of WPA transient keys */
- enum wpa_keymask {
- /** Pairwise transient key */
- WPA_PTK = 1,
-
- /** Group transient key */
- WPA_GTK = 2,
- };
-
-
- /** Length of a nonce */
- #define WPA_NONCE_LEN 32
-
- /** Length of a TKIP main key */
- #define WPA_TKIP_KEY_LEN 16
-
- /** Length of a TKIP MIC key */
- #define WPA_TKIP_MIC_KEY_LEN 8
-
- /** Length of a CCMP key */
- #define WPA_CCMP_KEY_LEN 16
-
- /** Length of an EAPOL Key Confirmation Key */
- #define WPA_KCK_LEN 16
-
- /** Length of an EAPOL Key Encryption Key */
- #define WPA_KEK_LEN 16
-
- /** Usual length of a Pairwise Master Key */
- #define WPA_PMK_LEN 32
-
- /** Length of a PMKID */
- #define WPA_PMKID_LEN 16
-
-
- /** Structure of the Temporal Key for TKIP encryption */
- struct tkip_tk
- {
- /** Main key: input to TKIP Phase 1 and Phase 2 key mixing functions */
- u8 key[WPA_TKIP_KEY_LEN];
-
- /** Michael MIC keys */
- struct {
- /** MIC key for packets from the AP */
- u8 rx[WPA_TKIP_MIC_KEY_LEN];
-
- /** MIC key for packets to the AP */
- u8 tx[WPA_TKIP_MIC_KEY_LEN];
- } __attribute__ (( packed )) mic;
- } __attribute__ (( packed ));
-
- /** Structure of a generic Temporal Key */
- union wpa_tk
- {
- /** CCMP key */
- u8 ccmp[WPA_CCMP_KEY_LEN];
-
- /** TKIP keys */
- struct tkip_tk tkip;
- };
-
- /** Structure of the Pairwise Transient Key */
- struct wpa_ptk
- {
- /** EAPOL-Key Key Confirmation Key (KCK) */
- u8 kck[WPA_KCK_LEN];
-
- /** EAPOL-Key Key Encryption Key (KEK) */
- u8 kek[WPA_KEK_LEN];
-
- /** Temporal key */
- union wpa_tk tk;
- } __attribute__ (( packed ));
-
- /** Structure of the Group Transient Key */
- struct wpa_gtk
- {
- /** Temporal key */
- union wpa_tk tk;
- } __attribute__ (( packed ));
-
-
- /** Common context for WPA security handshaking
- *
- * Any implementor of a particular handshaking type (e.g. PSK or EAP)
- * must include this structure at the very beginning of their private
- * data context structure, to allow the EAPOL-Key handling code to
- * work. When the preliminary authentication is done, it is necessary
- * to call wpa_start(), passing the PMK (derived from PSK or EAP MSK)
- * as an argument. The handshaker can use its @a step function to
- * monitor @a state in this wpa_ctx structure for success or
- * failure. On success, the keys will be available in @a ptk and @a
- * gtk according to the state of the @a valid bitmask.
- *
- * After an initial success, the parent handshaker does not need to
- * concern itself with rekeying; the WPA common code takes care of
- * that.
- */
- struct wpa_common_ctx
- {
- /** 802.11 device we are authenticating for */
- struct net80211_device *dev;
-
- /** The Pairwise Master Key to use in handshaking
- *
- * This is set either by running the PBKDF2 algorithm on a
- * passphrase with the SSID as salt to generate a pre-shared
- * key, or by copying the first 32 bytes of the EAP Master
- * Session Key in 802.1X-served authentication.
- */
- u8 pmk[WPA_PMK_LEN];
-
- /** Length of the Pairwise Master Key
- *
- * This is always 32 except with one EAP method which only
- * gives 16 bytes.
- */
- int pmk_len;
-
- /** State of EAPOL-Key handshaking */
- enum wpa_state state;
-
- /** Replay counter for this association
- *
- * This stores the replay counter value for the most recent
- * packet we've accepted. It is initially initialised to ~0 to
- * show we'll accept anything.
- */
- u64 replay;
-
- /** Mask of valid keys after authentication success
- *
- * If the PTK is not valid, the GTK should be used for both
- * unicast and multicast decryption; if the GTK is not valid,
- * multicast packets cannot be decrypted.
- */
- enum wpa_keymask valid;
-
- /** The cipher to use for unicast RX and all TX */
- enum net80211_crypto_alg crypt;
-
- /** The cipher to use for broadcast and multicast RX */
- enum net80211_crypto_alg gcrypt;
-
- /** The Pairwise Transient Key derived from the handshake */
- struct wpa_ptk ptk;
-
- /** The Group Transient Key derived from the handshake */
- struct wpa_gtk gtk;
-
- /** Authenticator-provided nonce */
- u8 Anonce[WPA_NONCE_LEN];
-
- /** Supplicant-generated nonce (that's us) */
- u8 Snonce[WPA_NONCE_LEN];
-
- /** Whether we should refrain from generating another SNonce */
- int have_Snonce;
-
- /** Data in WPA or RSN IE from AP's beacon frame */
- void *ap_rsn_ie;
-
- /** Length of @a ap_rsn_ie */
- int ap_rsn_ie_len;
-
- /** Whether @a ap_rsn_ie is an RSN IE (as opposed to old WPA) */
- int ap_rsn_is_rsn;
-
- /** List entry */
- struct list_head list;
- };
-
-
- /** WPA handshake key integrity and encryption handler
- *
- * Note that due to the structure of the 4-Way Handshake we never
- * actually need to encrypt key data, only decrypt it.
- */
- struct wpa_kie {
- /** Value of version bits in EAPOL-Key info field for which to use
- *
- * This should be one of the @c EAPOL_KEY_VERSION_* constants.
- */
- int version;
-
- /** Calculate MIC over message
- *
- * @v kck Key Confirmation Key, 16 bytes
- * @v msg Message to calculate MIC over
- * @v len Number of bytes to calculate MIC over
- * @ret mic Calculated MIC, 16 bytes long
- *
- * The @a mic return may point within @a msg, so it must not
- * be filled until the calculation has been performed.
- */
- void ( * mic ) ( const void *kck, const void *msg, size_t len,
- void *mic );
-
- /** Decrypt key data
- *
- * @v kek Key Encryption Key, 16 bytes
- * @v iv Initialisation vector for encryption, 16 bytes
- * @v msg Message to decrypt (Key Data field)
- * @v len Length of message
- * @ret msg Decrypted message in place of original
- * @ret len Updated to reflect encrypted length
- * @ret rc Return status code
- *
- * The decrypted message is written over the encrypted one.
- */
- int ( * decrypt ) ( const void *kek, const void *iv, void *msg,
- u16 *len );
- };
-
- #define WPA_KIES __table ( struct wpa_kie, "wpa_kies" )
- #define __wpa_kie __table_entry ( WPA_KIES, 01 )
-
-
-
- /**
- * @defgroup wpa_kde Key descriptor element types
- * @{
- */
-
- /** Payload structure of the GTK-encapsulating KDE
- *
- * This does not include the IE type, length, or OUI bytes, which are
- * generic to all KDEs.
- */
- struct wpa_kde_gtk_encap
- {
- /** Key ID and TX bit */
- u8 id;
-
- /** Reserved byte */
- u8 _rsvd;
-
- /** Encapsulated group transient key */
- struct wpa_gtk gtk;
- } __attribute__ (( packed ));
-
- /** Mask for Key ID in wpa_kde_gtk::id field */
- #define WPA_GTK_KID 0x03
-
- /** Mask for Tx bit in wpa_kde_gtk::id field */
- #define WPA_GTK_TXBIT 0x04
-
-
- /** KDE type for an encapsulated Group Transient Key (requires encryption) */
- #define WPA_KDE_GTK _MKOUI ( 0x00, 0x0F, 0xAC, 0x01 )
-
- /** KDE type for a MAC address */
- #define WPA_KDE_MAC _MKOUI ( 0x00, 0x0F, 0xAC, 0x03 )
-
- /** KDE type for a PMKID */
- #define WPA_KDE_PMKID _MKOUI ( 0x00, 0x0F, 0xAC, 0x04 )
-
- /** KDE type for a nonce */
- #define WPA_KDE_NONCE _MKOUI ( 0x00, 0x0F, 0xAC, 0x06 )
-
- /** KDE type for a lifetime value */
- #define WPA_KDE_LIFETIME _MKOUI ( 0x00, 0x0F, 0xAC, 0x07 )
-
-
- /** Any key descriptor element type
- *
- * KDEs follow the 802.11 information element format of a type byte
- * (in this case "vendor-specific", with the requisite OUI+subtype
- * after length) and a length byte whose value does not include the
- * length of the type and length bytes.
- */
- struct wpa_kde
- {
- /** Information element type: always 0xDD (IEEE80211_IE_VENDOR) */
- u8 ie_type;
-
- /** Length, not including ie_type and length fields */
- u8 len;
-
- /** OUI + type byte */
- u32 oui_type;
-
- /** Payload data */
- union {
- /** For GTK-type KDEs, encapsulated GTK */
- struct wpa_kde_gtk_encap gtk_encap;
-
- /** For MAC-type KDEs, the MAC address */
- u8 mac[ETH_ALEN];
-
- /** For PMKID-type KDEs, the PMKID */
- u8 pmkid[WPA_PMKID_LEN];
-
- /** For Nonce-type KDEs, the nonce */
- u8 nonce[WPA_NONCE_LEN];
-
- /** For Lifetime-type KDEs, the lifetime in seconds
- *
- * This is in network byte order!
- */
- u32 lifetime;
- };
- } __attribute__ (( packed ));
-
- /** @} */
-
- int wpa_make_rsn_ie ( struct net80211_device *dev, union ieee80211_ie **ie );
- int wpa_start ( struct net80211_device *dev, struct wpa_common_ctx *ctx,
- const void *pmk, size_t pmk_len );
- void wpa_stop ( struct net80211_device *dev );
-
- #endif /* _IPXE_WPA_H */
|