wpa.h File Reference

Common definitions for all types of WPA-protected networks. More...

#include <gpxe/ieee80211.h>
#include <gpxe/list.h>

Go to the source code of this file.

Data Structures

struct  eapol_key_pkt
 An EAPOL-Key packet. More...
struct  tkip_tk
 Structure of the Temporal Key for TKIP encryption. More...
union  wpa_tk
 Structure of a generic Temporal Key. More...
struct  wpa_ptk
 Structure of the Pairwise Transient Key. More...
struct  wpa_gtk
 Structure of the Group Transient Key. More...
struct  wpa_common_ctx
 Common context for WPA security handshaking. More...
struct  wpa_kie
 WPA handshake key integrity and encryption handler. More...
struct  wpa_kde_gtk_encap
 Payload structure of the GTK-encapsulating KDE. More...
struct  wpa_kde
 Any key descriptor element type. More...

Defines

#define EAPOL_KEY_TYPE_RSN   2
 EAPOL-Key type field for modern 802.11i/RSN WPA packets.
#define EAPOL_KEY_TYPE_WPA   254
 Old EAPOL-Key type field used by WPA1 hardware before 802.11i ratified.
#define EAPOL_KEY_INFO_VERSION   0x0007
 Key descriptor version, indicating WPA or WPA2.
#define EAPOL_KEY_INFO_TYPE   0x0008
 Key type bit, indicating pairwise or group.
#define EAPOL_KEY_INFO_INSTALL   0x0040
 Key install bit; set on message 3 except when legacy hacks are used.
#define EAPOL_KEY_INFO_KEY_ACK   0x0080
 Key ACK bit; set when a response is required, on all messages except #4.
#define EAPOL_KEY_INFO_KEY_MIC   0x0100
 Key MIC bit; set when the MIC field is valid, on messages 3 and 4.
#define EAPOL_KEY_INFO_SECURE   0x0200
 Secure bit; set when both sides have both keys, on messages 3 and 4.
#define EAPOL_KEY_INFO_ERROR   0x0400
 Error bit; set on a MIC failure for TKIP.
#define EAPOL_KEY_INFO_REQUEST   0x0800
 Request bit; set when authentication is initiated by the Peer (unusual).
#define EAPOL_KEY_INFO_KEY_ENC   0x1000
 Key Encrypted bit; set when the Key Data field is encrypted.
#define EAPOL_KEY_INFO_SMC_MESS   0x2000
 SMC Message bit; set when this frame is part of an IBSS SMK handshake.
#define EAPOL_KEY_VERSION_WPA   1
 Key descriptor version field value for WPA (TKIP).
#define EAPOL_KEY_VERSION_WPA2   2
 Key descriptor version field value for WPA2 (CCMP).
#define EAPOL_KEY_TYPE_PTK   0x0008
 Key type field value for a PTK (pairwise) key handshake.
#define EAPOL_KEY_TYPE_GTK   0x0000
 Key type field value for a GTK (group) key handshake.
#define WPA_NONCE_LEN   32
 Length of a nonce.
#define WPA_TKIP_KEY_LEN   16
 Length of a TKIP main key.
#define WPA_TKIP_MIC_KEY_LEN   8
 Length of a TKIP MIC key.
#define WPA_CCMP_KEY_LEN   16
 Length of a CCMP key.
#define WPA_KCK_LEN   16
 Length of an EAPOL Key Confirmation Key.
#define WPA_KEK_LEN   16
 Length of an EAPOL Key Encryption Key.
#define WPA_PMK_LEN   32
 Usual length of a Pairwise Master Key.
#define WPA_PMKID_LEN   16
 Length of a PMKID.
#define WPA_KIES   __table ( struct wpa_kie, "wpa_kies" )
#define __wpa_kie   __table_entry ( WPA_KIES, 01 )
#define WPA_GTK_KID   0x03
 Mask for Key ID in wpa_kde_gtk::id field.
#define WPA_GTK_TXBIT   0x04
 Mask for Tx bit in wpa_kde_gtk::id field.
#define WPA_KDE_GTK   _MKOUI ( 0x00, 0x0F, 0xAC, 0x01 )
 KDE type for an encapsulated Group Transient Key (requires encryption).
#define WPA_KDE_MAC   _MKOUI ( 0x00, 0x0F, 0xAC, 0x03 )
 KDE type for a MAC address.
#define WPA_KDE_PMKID   _MKOUI ( 0x00, 0x0F, 0xAC, 0x04 )
 KDE type for a PMKID.
#define WPA_KDE_NONCE   _MKOUI ( 0x00, 0x0F, 0xAC, 0x06 )
 KDE type for a nonce.
#define WPA_KDE_LIFETIME   _MKOUI ( 0x00, 0x0F, 0xAC, 0x07 )
 KDE type for a lifetime value.

Enumerations

enum  wpa_state {
  WPA_WAITING = 0, WPA_READY, WPA_WORKING, WPA_SUCCESS,
  WPA_FAILURE
}
 WPA handshaking state. More...
enum  wpa_keymask { WPA_PTK = 1, WPA_GTK = 2 }
 Bitfield indicating a selection of WPA transient keys. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER)
int wpa_make_rsn_ie (struct net80211_device *dev, union ieee80211_ie **ie)
 Construct RSN or WPA information element.
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.
void wpa_stop (struct net80211_device *dev)
 Disable handling of received WPA handshake frames.

Variables

struct eapol_key_pkt packed
 An EAPOL-Key packet.


Detailed Description

Common definitions for all types of WPA-protected networks.

Definition in file wpa.h.


Define Documentation

#define EAPOL_KEY_TYPE_RSN   2

EAPOL-Key type field for modern 802.11i/RSN WPA packets.

Definition at line 34 of file wpa.h.

Referenced by eapol_key_rx().

#define EAPOL_KEY_TYPE_WPA   254

Old EAPOL-Key type field used by WPA1 hardware before 802.11i ratified.

Definition at line 37 of file wpa.h.

Referenced by eapol_key_rx().

#define WPA_NONCE_LEN   32

Length of a nonce.

Definition at line 203 of file wpa.h.

Referenced by wpa_derive_ptk(), and wpa_handle_3_of_4().

#define WPA_TKIP_KEY_LEN   16

Length of a TKIP main key.

Definition at line 206 of file wpa.h.

#define WPA_TKIP_MIC_KEY_LEN   8

Length of a TKIP MIC key.

Definition at line 209 of file wpa.h.

#define WPA_CCMP_KEY_LEN   16

Length of a CCMP key.

Definition at line 212 of file wpa.h.

#define WPA_KCK_LEN   16

Length of an EAPOL Key Confirmation Key.

Definition at line 215 of file wpa.h.

#define WPA_KEK_LEN   16

Length of an EAPOL Key Encryption Key.

Definition at line 218 of file wpa.h.

#define WPA_PMK_LEN   32

Usual length of a Pairwise Master Key.

Definition at line 221 of file wpa.h.

Referenced by wpa_psk_start().

#define WPA_PMKID_LEN   16

Length of a PMKID.

Definition at line 224 of file wpa.h.

Referenced by wpa_check_pmkid().

#define WPA_KIES   __table ( struct wpa_kie, "wpa_kies" )

Definition at line 406 of file wpa.h.

Referenced by wpa_find_kie().

#define __wpa_kie   __table_entry ( WPA_KIES, 01 )

Definition at line 407 of file wpa.h.


Enumeration Type Documentation

enum wpa_state

WPA handshaking state.

Enumerator:
WPA_WAITING  Waiting for PMK to be set.
WPA_READY  Ready for 4-Way Handshake.
WPA_WORKING  Performing 4-Way Handshake.
WPA_SUCCESS  4-Way Handshake succeeded
WPA_FAILURE  4-Way Handshake failed

Definition at line 175 of file wpa.h.

00175                {
00176         /** Waiting for PMK to be set */
00177         WPA_WAITING = 0,
00178 
00179         /** Ready for 4-Way Handshake */
00180         WPA_READY,
00181 
00182         /** Performing 4-Way Handshake */
00183         WPA_WORKING,
00184 
00185         /** 4-Way Handshake succeeded */
00186         WPA_SUCCESS,
00187 
00188         /** 4-Way Handshake failed */
00189         WPA_FAILURE,
00190 };

Bitfield indicating a selection of WPA transient keys.

Enumerator:
WPA_PTK  Pairwise transient key.
WPA_GTK  Group transient key.

Definition at line 193 of file wpa.h.

00193                  {
00194         /** Pairwise transient key */
00195         WPA_PTK = 1,
00196 
00197         /** Group transient key */
00198         WPA_GTK = 2,
00199 };


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

int wpa_make_rsn_ie ( struct net80211_device dev,
union ieee80211_ie **  ie_ret 
)

Construct RSN or WPA information element.

Parameters:
dev 802.11 device
Return values:
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 gPXE'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 121 of file wpa.c.

References ieee80211_ie_rsn::akm_count, ieee80211_ie_rsn::akm_list, net80211_device::associating, net80211_wlan::beacon, net80211_wlan::crypto, ieee80211_frame::data, io_buffer::data, DBG, EINVAL, ENOMEM, ENOTSUP, ieee80211_ie_rsn::group_cipher, net80211_wlan::handshaking, 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, u32, u8, ieee80211_ie_rsn::version, and wpa_find_cryptosystem().

Referenced by wpa_psk_init().

00122 {
00123         u8 *rsn, *rsn_end;
00124         int is_rsn;
00125         u32 group_cipher;
00126         enum net80211_crypto_alg gcrypt;
00127         int ie_len;
00128         u8 *iep;
00129         struct ieee80211_ie_rsn *ie;
00130         struct ieee80211_frame *hdr;
00131         struct ieee80211_beacon *beacon;
00132 
00133         if ( ! dev->associating ) {
00134                 DBG ( "WPA: Can't make RSN IE for a non-associating device\n" );
00135                 return -EINVAL;
00136         }
00137 
00138         hdr = dev->associating->beacon->data;
00139         beacon = ( struct ieee80211_beacon * ) hdr->data;
00140         rsn = sec80211_find_rsn ( beacon->info_element,
00141                                   dev->associating->beacon->tail, &is_rsn,
00142                                   &rsn_end );
00143         if ( ! rsn ) {
00144                 DBG ( "WPA: Can't make RSN IE when we didn't get one\n" );
00145                 return -EINVAL;
00146         }
00147 
00148         rsn += 2;               /* skip version */
00149         group_cipher = *( u32 * ) rsn;
00150         gcrypt = sec80211_rsn_get_net80211_crypt ( group_cipher );
00151 
00152         if ( ! wpa_find_cryptosystem ( gcrypt ) ||
00153              ! wpa_find_cryptosystem ( dev->associating->crypto ) ) {
00154                 DBG ( "WPA: No support for (GC:%d, PC:%d)\n",
00155                       gcrypt, dev->associating->crypto );
00156                 return -ENOTSUP;
00157         }
00158 
00159         /* Everything looks good - make our IE. */
00160 
00161         /* WPA IEs need 4 more bytes for the OUI+type */
00162         ie_len = ieee80211_rsn_size ( 1, 1, 0, is_rsn ) + ( 4 * ! is_rsn );
00163         iep = malloc ( ie_len );
00164         if ( ! iep )
00165                 return -ENOMEM;
00166 
00167         *ie_ret = ( union ieee80211_ie * ) iep;
00168 
00169         /* Store ID and length bytes. */
00170         *iep++ = ( is_rsn ? IEEE80211_IE_RSN : IEEE80211_IE_VENDOR );
00171         *iep++ = ie_len - 2;
00172 
00173         /* Store OUI+type for WPA IEs. */
00174         if ( ! is_rsn ) {
00175                 *( u32 * ) iep = IEEE80211_WPA_OUI_VEN;
00176                 iep += 4;
00177         }
00178 
00179         /* If this is a WPA IE, the id and len bytes in the
00180            ieee80211_ie_rsn structure will not be valid, but by doing
00181            the cast we can fill all the other fields much more
00182            readily. */
00183 
00184         ie = ( struct ieee80211_ie_rsn * ) ( iep - 2 );
00185         ie->version = IEEE80211_RSN_VERSION;
00186         ie->group_cipher = group_cipher;
00187         ie->pairwise_count = 1;
00188         ie->pairwise_cipher[0] =
00189                 sec80211_rsn_get_crypto_desc ( dev->associating->crypto,
00190                                                is_rsn );
00191         ie->akm_count = 1;
00192         ie->akm_list[0] =
00193                 sec80211_rsn_get_akm_desc ( dev->associating->handshaking,
00194                                             is_rsn );
00195         if ( is_rsn ) {
00196                 ie->rsn_capab = 0;
00197                 ie->pmkid_count = 0;
00198         }
00199 
00200         return 0;
00201 }

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.

Parameters:
dev 802.11 device
ctx WPA common context
pmk Pairwise Master Key to use for session
pmk_len Length of PMK, almost always 32
Return values:
rc Return status code

Definition at line 213 of file wpa.c.

References wpa_common_ctx::ap_rsn_ie, wpa_common_ctx::ap_rsn_ie_len, wpa_common_ctx::ap_rsn_is_rsn, net80211_device::associating, net80211_wlan::beacon, wpa_common_ctx::crypt, net80211_wlan::crypto, ieee80211_frame::data, io_buffer::data, wpa_common_ctx::dev, EINVAL, ENOENT, ENOMEM, wpa_common_ctx::gcrypt, ieee80211_beacon, wpa_common_ctx::list, list_add_tail, malloc(), memcpy, NET80211_CRYPT_UNKNOWN, NULL, wpa_common_ctx::pmk, wpa_common_ctx::pmk_len, wpa_common_ctx::replay, net80211_device::rsn_ie, sec80211_find_rsn(), wpa_common_ctx::state, io_buffer::tail, u8, and WPA_READY.

Referenced by wpa_psk_start().

00215 {
00216         struct io_buffer *iob;
00217         struct ieee80211_frame *hdr;
00218         struct ieee80211_beacon *beacon;
00219         u8 *ap_rsn_ie = NULL, *ap_rsn_ie_end;
00220 
00221         if ( ! dev->rsn_ie || ! dev->associating )
00222                 return -EINVAL;
00223 
00224         ctx->dev = dev;
00225         memcpy ( ctx->pmk, pmk, ctx->pmk_len = pmk_len );
00226         ctx->state = WPA_READY;
00227         ctx->replay = ~0ULL;
00228 
00229         iob = dev->associating->beacon;
00230         hdr = iob->data;
00231         beacon = ( struct ieee80211_beacon * ) hdr->data;
00232         ap_rsn_ie = sec80211_find_rsn ( beacon->info_element, iob->tail,
00233                                         &ctx->ap_rsn_is_rsn, &ap_rsn_ie_end );
00234         if ( ap_rsn_ie ) {
00235                 ctx->ap_rsn_ie = malloc ( ap_rsn_ie_end - ap_rsn_ie );
00236                 if ( ! ctx->ap_rsn_ie )
00237                         return -ENOMEM;
00238                 memcpy ( ctx->ap_rsn_ie, ap_rsn_ie, ap_rsn_ie_end - ap_rsn_ie );
00239                 ctx->ap_rsn_ie_len = ap_rsn_ie_end - ap_rsn_ie;
00240         } else {
00241                 return -ENOENT;
00242         }
00243 
00244         ctx->crypt = dev->associating->crypto;
00245         ctx->gcrypt = NET80211_CRYPT_UNKNOWN;
00246 
00247         list_add_tail ( &ctx->list, &wpa_contexts );
00248         return 0;
00249 }

void wpa_stop ( struct net80211_device dev  ) 

Disable handling of received WPA handshake frames.

Parameters:
dev 802.11 device

Definition at line 257 of file wpa.c.

References wpa_common_ctx::ap_rsn_ie, wpa_common_ctx::dev, free(), wpa_common_ctx::list, list_del, list_for_each_entry_safe, and NULL.

Referenced by wpa_psk_stop().

00258 {
00259         struct wpa_common_ctx *ctx, *tmp;
00260 
00261         list_for_each_entry_safe ( ctx, tmp, &wpa_contexts, list ) {
00262                 if ( ctx->dev == dev ) {
00263                         free ( ctx->ap_rsn_ie );
00264                         ctx->ap_rsn_ie = NULL;
00265                         list_del ( &ctx->list );
00266                 }
00267         }
00268 }


Generated on Tue Apr 6 20:01:53 2010 for gPXE by  doxygen 1.5.7.1