wpa_tkip.c File Reference

Backend for WPA using the TKIP encryption standard. More...

#include <gpxe/net80211.h>
#include <gpxe/crypto.h>
#include <gpxe/hmac.h>
#include <gpxe/sha1.h>
#include <gpxe/md5.h>
#include <gpxe/crc32.h>
#include <gpxe/arc4.h>
#include <gpxe/wpa.h>
#include <byteswap.h>
#include <errno.h>

Go to the source code of this file.

Data Structures

struct  tkip_dir_ctx
 Context for one direction of TKIP, either encryption or decryption. More...
struct  tkip_ctx
 Context for TKIP encryption and decryption. More...
struct  tkip_head
 Header structure at the beginning of TKIP frame data. More...

Defines

#define TKIP_HEAD_LEN   8
 TKIP header overhead (IV + KID + ExtIV).
#define TKIP_FOOT_LEN   12
 TKIP trailer overhead (MIC + ICV) [assumes unfragmented].
#define TKIP_MIC_LEN   8
 TKIP MIC length.
#define TKIP_ICV_LEN   4
 TKIP ICV length.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
static u16 S (u16 v)
 Perform S-box mapping on a 16-bit value.
static u16 ror16 (u16 v, int bits)
 Rotate 16-bit value right.
static u32 ror32 (u32 v, int bits)
 Rotate 32-bit value right.
static u32 rol32 (u32 v, int bits)
 Rotate 32-bit value left.
static int tkip_init (struct net80211_crypto *crypto, const void *key, int keylen, const void *rsc)
 Initialise TKIP state and install key.
static void tkip_mix_1 (struct tkip_dir_ctx *dctx, struct tkip_tk *tk, u8 *mac)
 Perform TKIP key mixing, phase 1.
static void tkip_mix_2 (struct tkip_dir_ctx *dctx, struct tkip_tk *tk, void *key)
 Perform TKIP key mixing, phase 2.
static void tkip_feed_michael (u32 *V, u32 word)
 Update Michael message integrity code based on next 32-bit word of data.
static void tkip_michael (const void *key, const void *da, const void *sa, const void *data, size_t len, void *mic)
 Calculate Michael message integrity code.
static struct io_buffertkip_encrypt (struct net80211_crypto *crypto, struct io_buffer *iob)
 Encrypt a packet using TKIP.
static struct io_buffertkip_decrypt (struct net80211_crypto *crypto, struct io_buffer *eiob)
 Decrypt a packet using TKIP.
static void tkip_kie_mic (const void *kck, const void *msg, size_t len, void *mic)
 Calculate HMAC-MD5 MIC for EAPOL-Key frame.
static int tkip_kie_decrypt (const void *kek, const void *iv, void *msg, u16 *len)
 Decrypt key data in EAPOL-Key frame.

Variables

static const u16 Sbox [256]
 TKIP S-box.
struct net80211_crypto tkip_crypto __net80211_crypto
 TKIP cryptosystem.
struct wpa_kie tkip_kie __wpa_kie
 TKIP-style key integrity and encryption handler.


Detailed Description

Backend for WPA using the TKIP encryption standard.

Definition in file wpa_tkip.c.


Define Documentation

#define TKIP_HEAD_LEN   8

TKIP header overhead (IV + KID + ExtIV).

Definition at line 81 of file wpa_tkip.c.

Referenced by tkip_decrypt(), and tkip_encrypt().

#define TKIP_FOOT_LEN   12

TKIP trailer overhead (MIC + ICV) [assumes unfragmented].

Definition at line 84 of file wpa_tkip.c.

Referenced by tkip_decrypt(), and tkip_encrypt().

#define TKIP_MIC_LEN   8

TKIP MIC length.

Definition at line 87 of file wpa_tkip.c.

Referenced by tkip_decrypt().

#define TKIP_ICV_LEN   4

TKIP ICV length.

Definition at line 90 of file wpa_tkip.c.

Referenced by tkip_encrypt().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

static u16 S ( u16  v  )  [inline, static]

Perform S-box mapping on a 16-bit value.

Parameters:
v Value to perform S-box mapping on
Return values:
Sv S-box mapped value

Definition at line 135 of file wpa_tkip.c.

References swap16.

Referenced by arc4_setkey(), arc4_xor(), ccmp_ctr_xor(), tkip_mix_1(), and tkip_mix_2().

00136 {
00137         return Sbox[v & 0xFF] ^ swap16 ( Sbox[v >> 8] );
00138 }

static u16 ror16 ( u16  v,
int  bits 
) [inline, static]

Rotate 16-bit value right.

Parameters:
v Value to rotate
bits Number of bits to rotate by
Return values:
rotv Rotated value

Definition at line 147 of file wpa_tkip.c.

Referenced by tkip_mix_2().

00148 {
00149         return ( v >> bits ) | ( v << ( 16 - bits ) );
00150 }

static u32 ror32 ( u32  v,
int  bits 
) [inline, static]

Rotate 32-bit value right.

Parameters:
v Value to rotate
bits Number of bits to rotate by
Return values:
rotv Rotated value

Definition at line 159 of file wpa_tkip.c.

Referenced by tkip_feed_michael().

00160 {
00161         return ( v >> bits ) | ( v << ( 32 - bits ) );
00162 }

static u32 rol32 ( u32  v,
int  bits 
) [inline, static]

Rotate 32-bit value left.

Parameters:
v Value to rotate
bits Number of bits to rotate by
Return values:
rotv Rotated value

Definition at line 171 of file wpa_tkip.c.

Referenced by tkip_feed_michael().

00172 {
00173         return ( v << bits ) | ( v >> ( 32 - bits ) );
00174 }

static int tkip_init ( struct net80211_crypto crypto,
const void *  key,
int  keylen,
const void *  rsc 
) [static]

Initialise TKIP state and install key.

Parameters:
crypto TKIP cryptosystem structure
key Pointer to tkip_tk to install
keylen Length of key (32 bytes)
rsc Initial receive sequence counter

Definition at line 185 of file wpa_tkip.c.

References tkip_ctx::dec, EINVAL, memcpy, net80211_crypto::priv, tkip_ctx::tk, tkip_dir_ctx::tsc_hi, tkip_dir_ctx::tsc_lo, and u8.

00187 {
00188         struct tkip_ctx *ctx = crypto->priv;
00189         const u8 *rscb = rsc;
00190 
00191         if ( keylen != sizeof ( ctx->tk ) )
00192                 return -EINVAL;
00193 
00194         if ( rscb ) {
00195                 ctx->dec.tsc_lo =   ( rscb[1] <<  8 ) |   rscb[0];
00196                 ctx->dec.tsc_hi = ( ( rscb[5] << 24 ) | ( rscb[4] << 16 ) |
00197                                     ( rscb[3] <<  8 ) |   rscb[2] );
00198         }
00199 
00200         memcpy ( &ctx->tk, key, sizeof ( ctx->tk ) );
00201 
00202         return 0;
00203 }

static void tkip_mix_1 ( struct tkip_dir_ctx dctx,
struct tkip_tk tk,
u8 mac 
) [static]

Perform TKIP key mixing, phase 1.

Parameters:
dctx TKIP directional context
tk TKIP temporal key
mac MAC address of transmitter
This recomputes the TTAK in dctx if necessary, and sets dctx->ttak_ok.

Definition at line 215 of file wpa_tkip.c.

References ETH_ALEN, tkip_tk::key, tkip_dir_ctx::mac, memcmp(), memcpy, S(), tkip_dir_ctx::tsc_hi, tkip_dir_ctx::ttak, and tkip_dir_ctx::ttak_ok.

Referenced by tkip_decrypt(), and tkip_encrypt().

00216 {
00217         int i, j;
00218 
00219         if ( dctx->ttak_ok && ! memcmp ( mac, dctx->mac, ETH_ALEN ) )
00220                 return;
00221 
00222         memcpy ( dctx->mac, mac, ETH_ALEN );
00223 
00224         dctx->ttak[0] = dctx->tsc_hi & 0xFFFF;
00225         dctx->ttak[1] = dctx->tsc_hi >> 16;
00226         dctx->ttak[2] = ( mac[1] << 8 ) | mac[0];
00227         dctx->ttak[3] = ( mac[3] << 8 ) | mac[2];
00228         dctx->ttak[4] = ( mac[5] << 8 ) | mac[4];
00229 
00230         for ( i = 0; i < 8; i++ ) {
00231                 j = 2 * ( i & 1 );
00232 
00233                 dctx->ttak[0] += S ( dctx->ttak[4] ^ ( ( tk->key[1 + j] << 8 ) |
00234                                                          tk->key[0 + j] ) );
00235                 dctx->ttak[1] += S ( dctx->ttak[0] ^ ( ( tk->key[5 + j] << 8 ) |
00236                                                          tk->key[4 + j] ) );
00237                 dctx->ttak[2] += S ( dctx->ttak[1] ^ ( ( tk->key[9 + j] << 8 ) |
00238                                                          tk->key[8 + j] ) );
00239                 dctx->ttak[3] += S ( dctx->ttak[2] ^ ( ( tk->key[13+ j] << 8 ) |
00240                                                          tk->key[12+ j] ) );
00241                 dctx->ttak[4] += S ( dctx->ttak[3] ^ ( ( tk->key[1 + j] << 8 ) |
00242                                                          tk->key[0 + j] ) ) + i;
00243         }
00244 
00245         dctx->ttak_ok = 1;
00246 }

static void tkip_mix_2 ( struct tkip_dir_ctx dctx,
struct tkip_tk tk,
void *  key 
) [static]

Perform TKIP key mixing, phase 2.

Parameters:
dctx TKIP directional context
tk TKIP temporal key
Return values:
key ARC4 key, 16 bytes long

Definition at line 255 of file wpa_tkip.c.

References tkip_tk::key, memcpy, ror16(), S(), tkip_dir_ctx::tsc_lo, tkip_dir_ctx::ttak, u16, and u8.

Referenced by tkip_decrypt(), and tkip_encrypt().

00257 {
00258         u8 *kb = key;
00259         u16 ppk[6];
00260         int i;
00261 
00262         memcpy ( ppk, dctx->ttak, sizeof ( dctx->ttak ) );
00263         ppk[5] = dctx->ttak[4] + dctx->tsc_lo;
00264 
00265         ppk[0] += S ( ppk[5] ^ ( ( tk->key[1] << 8 ) | tk->key[0] ) );
00266         ppk[1] += S ( ppk[0] ^ ( ( tk->key[3] << 8 ) | tk->key[2] ) );
00267         ppk[2] += S ( ppk[1] ^ ( ( tk->key[5] << 8 ) | tk->key[4] ) );
00268         ppk[3] += S ( ppk[2] ^ ( ( tk->key[7] << 8 ) | tk->key[6] ) );
00269         ppk[4] += S ( ppk[3] ^ ( ( tk->key[9] << 8 ) | tk->key[8] ) );
00270         ppk[5] += S ( ppk[4] ^ ( ( tk->key[11] << 8 ) | tk->key[10] ) );
00271 
00272         ppk[0] += ror16 ( ppk[5] ^ ( ( tk->key[13] << 8 ) | tk->key[12] ), 1 );
00273         ppk[1] += ror16 ( ppk[0] ^ ( ( tk->key[15] << 8 ) | tk->key[14] ), 1 );
00274         ppk[2] += ror16 ( ppk[1], 1 );
00275         ppk[3] += ror16 ( ppk[2], 1 );
00276         ppk[4] += ror16 ( ppk[3], 1 );
00277         ppk[5] += ror16 ( ppk[4], 1 );
00278 
00279         kb[0] = dctx->tsc_lo >> 8;
00280         kb[1] = ( ( dctx->tsc_lo >> 8 ) | 0x20 ) & 0x7F;
00281         kb[2] = dctx->tsc_lo & 0xFF;
00282         kb[3] = ( ( ppk[5] ^ ( ( tk->key[1] << 8 ) | tk->key[0] ) ) >> 1 )
00283                 & 0xFF;
00284 
00285         for ( i = 0; i < 6; i++ ) {
00286                 kb[4 + 2*i] = ppk[i] & 0xFF;
00287                 kb[5 + 2*i] = ppk[i] >> 8;
00288         }
00289 }

static void tkip_feed_michael ( u32 V,
u32  word 
) [static]

Update Michael message integrity code based on next 32-bit word of data.

Parameters:
V Michael code state (two 32-bit words)
word Next 32-bit word of data

Definition at line 297 of file wpa_tkip.c.

References rol32(), and ror32().

Referenced by tkip_michael().

00298 {
00299         V[0] ^= word;
00300         V[1] ^= rol32 ( V[0], 17 );
00301         V[0] += V[1];
00302         V[1] ^= ( ( V[0] & 0xFF00FF00 ) >> 8 ) | ( ( V[0] & 0x00FF00FF ) << 8 );
00303         V[0] += V[1];
00304         V[1] ^= rol32 ( V[0], 3 );
00305         V[0] += V[1];
00306         V[1] ^= ror32 ( V[0], 2 );
00307         V[0] += V[1];
00308 }

static void tkip_michael ( const void *  key,
const void *  da,
const void *  sa,
const void *  data,
size_t  len,
void *  mic 
) [static]

Calculate Michael message integrity code.

Parameters:
key MIC key to use (8 bytes)
da Destination link-layer address
sa Source link-layer address
data Start of data to calculate over
len Length of header + data
Return values:
mic Calculated Michael MIC (8 bytes)

Definition at line 320 of file wpa_tkip.c.

References cpu_to_le32, ETH_ALEN, le32_to_cpu, memcpy, tkip_feed_michael(), u32, and u8.

Referenced by tkip_decrypt(), and tkip_encrypt().

00322 {
00323         u32 V[2];               /* V[0] = "l", V[1] = "r" in 802.11 */
00324         union {
00325                 u8 byte[12];
00326                 u32 word[3];
00327         } cap;
00328         const u8 *ptr = data;
00329         const u8 *end = ptr + len;
00330         int i;
00331 
00332         memcpy ( V, key, sizeof ( V ) );
00333         V[0] = le32_to_cpu ( V[0] );
00334         V[1] = le32_to_cpu ( V[1] );
00335 
00336         /* Feed in header (we assume non-QoS, so Priority = 0) */
00337         memcpy ( &cap.byte[0], da, ETH_ALEN );
00338         memcpy ( &cap.byte[6], sa, ETH_ALEN );
00339         tkip_feed_michael ( V, le32_to_cpu ( cap.word[0] ) );
00340         tkip_feed_michael ( V, le32_to_cpu ( cap.word[1] ) );
00341         tkip_feed_michael ( V, le32_to_cpu ( cap.word[2] ) );
00342         tkip_feed_michael ( V, 0 );
00343 
00344         /* Feed in data */
00345         while ( ptr + 4 <= end ) {
00346                 tkip_feed_michael ( V, le32_to_cpu ( *( u32 * ) ptr ) );
00347                 ptr += 4;
00348         }
00349 
00350         /* Add unaligned part and padding */
00351         for ( i = 0; ptr < end; i++ )
00352                 cap.byte[i] = *ptr++;
00353         cap.byte[i++] = 0x5a;
00354         for ( ; i < 8; i++ )
00355                 cap.byte[i] = 0;
00356 
00357         /* Feed in padding */
00358         tkip_feed_michael ( V, le32_to_cpu ( cap.word[0] ) );
00359         tkip_feed_michael ( V, le32_to_cpu ( cap.word[1] ) );
00360 
00361         /* Output MIC */
00362         V[0] = cpu_to_le32 ( V[0] );
00363         V[1] = cpu_to_le32 ( V[1] );
00364         memcpy ( mic, V, sizeof ( V ) );
00365 }

static struct io_buffer* tkip_encrypt ( struct net80211_crypto crypto,
struct io_buffer iob 
) [static, read]

Encrypt a packet using TKIP.

Parameters:
crypto TKIP cryptosystem
iob I/O buffer containing cleartext packet
Return values:
eiob I/O buffer containing encrypted packet

Definition at line 374 of file wpa_tkip.c.

References ieee80211_frame::addr2, ieee80211_frame::addr3, alloc_iob(), arc4_algorithm, cipher_encrypt, cipher_setkey(), cpu_to_le32, crc32_le(), io_buffer::data, DBGC2, tkip_ctx::enc, ieee80211_frame::fc, IEEE80211_FC_PROTECTED, IEEE80211_TYP_FRAME_HEADER_LEN, iob_len(), iob_put, tkip_head::kid, memcpy, tkip_tk::mic, NULL, net80211_crypto::priv, tkip_ctx::tk, TKIP_FOOT_LEN, TKIP_HEAD_LEN, TKIP_ICV_LEN, tkip_michael(), tkip_mix_1(), tkip_mix_2(), tkip_head::tsc_hi, tkip_dir_ctx::tsc_hi, tkip_dir_ctx::tsc_lo, tkip_dir_ctx::ttak_ok, tkip_tk::tx, u32, and u8.

00376 {
00377         struct tkip_ctx *ctx = crypto->priv;
00378         struct ieee80211_frame *hdr = iob->data;
00379         struct io_buffer *eiob;
00380         struct arc4_ctx arc4;
00381         u8 key[16];
00382         struct tkip_head head;
00383         u8 mic[8];
00384         u32 icv;
00385         const int hdrlen = IEEE80211_TYP_FRAME_HEADER_LEN;
00386         int datalen = iob_len ( iob ) - hdrlen;
00387 
00388         ctx->enc.tsc_lo++;
00389         if ( ctx->enc.tsc_lo == 0 ) {
00390                 ctx->enc.tsc_hi++;
00391                 ctx->enc.ttak_ok = 0;
00392         }
00393 
00394         tkip_mix_1 ( &ctx->enc, &ctx->tk, hdr->addr2 );
00395         tkip_mix_2 ( &ctx->enc, &ctx->tk, key );
00396 
00397         eiob = alloc_iob ( iob_len ( iob ) + TKIP_HEAD_LEN + TKIP_FOOT_LEN );
00398         if ( ! eiob )
00399                 return NULL;
00400 
00401         /* Copy frame header */
00402         memcpy ( iob_put ( eiob, hdrlen ), iob->data, hdrlen );
00403         hdr = eiob->data;
00404         hdr->fc |= IEEE80211_FC_PROTECTED;
00405 
00406         /* Fill in IV and key ID byte, and extended IV */
00407         memcpy ( &head, key, 3 );
00408         head.kid = 0x20;                /* have Extended IV, key ID 0 */
00409         head.tsc_hi = cpu_to_le32 ( ctx->enc.tsc_hi );
00410         memcpy ( iob_put ( eiob, sizeof ( head ) ), &head, sizeof ( head ) );
00411 
00412         /* Copy and encrypt the data */
00413         cipher_setkey ( &arc4_algorithm, &arc4, key, 16 );
00414         cipher_encrypt ( &arc4_algorithm, &arc4, iob->data + hdrlen,
00415                          iob_put ( eiob, datalen ), datalen );
00416 
00417         /* Add MIC */
00418         hdr = iob->data;
00419         tkip_michael ( &ctx->tk.mic.tx, hdr->addr3, hdr->addr2,
00420                        iob->data + hdrlen, datalen, mic );
00421         cipher_encrypt ( &arc4_algorithm, &arc4, mic,
00422                          iob_put ( eiob, sizeof ( mic ) ), sizeof ( mic ) );
00423 
00424         /* Add ICV */
00425         icv = crc32_le ( ~0, iob->data + hdrlen, datalen );
00426         icv = crc32_le ( icv, mic, sizeof ( mic ) );
00427         icv = cpu_to_le32 ( ~icv );
00428         cipher_encrypt ( &arc4_algorithm, &arc4, &icv,
00429                          iob_put ( eiob, TKIP_ICV_LEN ), TKIP_ICV_LEN );
00430 
00431         DBGC2 ( ctx, "WPA-TKIP %p: encrypted packet %p -> %p\n", ctx,
00432                 iob, eiob );
00433 
00434         return eiob;
00435 }

static struct io_buffer* tkip_decrypt ( struct net80211_crypto crypto,
struct io_buffer eiob 
) [static, read]

Decrypt a packet using TKIP.

Parameters:
crypto TKIP cryptosystem
eiob I/O buffer containing encrypted packet
Return values:
iob I/O buffer containing cleartext packet

Definition at line 444 of file wpa_tkip.c.

References ieee80211_frame::addr1, ieee80211_frame::addr2, ieee80211_frame::addr3, alloc_iob(), arc4_algorithm, cipher_decrypt, cipher_setkey(), crc32_le(), io_buffer::data, DBGC, DBGC2, tkip_ctx::dec, ieee80211_frame::fc, free_iob(), IEEE80211_FC_PROTECTED, IEEE80211_TYP_FRAME_HEADER_LEN, iob_len(), iob_put, le32_to_cpu, memcmp(), memcpy, tkip_tk::mic, NULL, net80211_crypto::priv, tkip_tk::rx, io_buffer::tail, tkip_ctx::tk, TKIP_FOOT_LEN, TKIP_HEAD_LEN, TKIP_MIC_LEN, tkip_michael(), tkip_mix_1(), tkip_mix_2(), tkip_head::tsc0, tkip_head::tsc1, tkip_dir_ctx::tsc_hi, tkip_head::tsc_hi, tkip_dir_ctx::tsc_lo, tkip_dir_ctx::ttak_ok, u16, u32, and u8.

00446 {
00447         struct tkip_ctx *ctx = crypto->priv;
00448         struct ieee80211_frame *hdr;
00449         struct io_buffer *iob;
00450         const int hdrlen = IEEE80211_TYP_FRAME_HEADER_LEN;
00451         int datalen = iob_len ( eiob ) - hdrlen - TKIP_HEAD_LEN - TKIP_FOOT_LEN;
00452         struct tkip_head *head;
00453         struct arc4_ctx arc4;
00454         u16 rx_tsc_lo;
00455         u8 key[16];
00456         u8 mic[8];
00457         u32 icv, crc;
00458 
00459         iob = alloc_iob ( hdrlen + datalen + TKIP_FOOT_LEN );
00460         if ( ! iob )
00461                 return NULL;
00462 
00463         /* Copy frame header */
00464         memcpy ( iob_put ( iob, hdrlen ), eiob->data, hdrlen );
00465         hdr = iob->data;
00466         hdr->fc &= ~IEEE80211_FC_PROTECTED;
00467 
00468         /* Check and update TSC */
00469         head = eiob->data + hdrlen;
00470         rx_tsc_lo = ( head->tsc1 << 8 ) | head->tsc0;
00471 
00472         if ( head->tsc_hi < ctx->dec.tsc_hi ||
00473              ( head->tsc_hi == ctx->dec.tsc_hi &&
00474                rx_tsc_lo <= ctx->dec.tsc_lo ) ) {
00475                 DBGC ( ctx, "WPA-TKIP %p: packet received out of order "
00476                        "(%08x:%04x <= %08x:%04x)\n", ctx, head->tsc_hi,
00477                        rx_tsc_lo, ctx->dec.tsc_hi, ctx->dec.tsc_lo );
00478                 free_iob ( iob );
00479                 return NULL;
00480         }
00481         ctx->dec.tsc_lo = rx_tsc_lo;
00482         if ( ctx->dec.tsc_hi != head->tsc_hi ) {
00483                 ctx->dec.ttak_ok = 0;
00484                 ctx->dec.tsc_hi = head->tsc_hi;
00485         }
00486 
00487         /* Calculate key */
00488         tkip_mix_1 ( &ctx->dec, &ctx->tk, hdr->addr2 );
00489         tkip_mix_2 ( &ctx->dec, &ctx->tk, key );
00490 
00491         /* Copy-decrypt data, MIC, ICV */
00492         cipher_setkey ( &arc4_algorithm, &arc4, key, 16 );
00493         cipher_decrypt ( &arc4_algorithm, &arc4,
00494                          eiob->data + hdrlen + TKIP_HEAD_LEN,
00495                          iob_put ( iob, datalen ), datalen + TKIP_FOOT_LEN );
00496 
00497         /* Check ICV */
00498         icv = le32_to_cpu ( *( u32 * ) ( iob->tail + TKIP_MIC_LEN ) );
00499         crc = ~crc32_le ( ~0, iob->data + hdrlen, datalen + TKIP_MIC_LEN );
00500         if ( crc != icv ) {
00501                 DBGC ( ctx, "WPA-TKIP %p CRC mismatch: expect %08x, get %08x\n",
00502                        ctx, icv, crc );
00503                 free_iob ( iob );
00504                 return NULL;
00505         }
00506 
00507         /* Check MIC */
00508         tkip_michael ( &ctx->tk.mic.rx, hdr->addr1, hdr->addr3,
00509                        iob->data + hdrlen, datalen, mic );
00510         if ( memcmp ( mic, iob->tail, TKIP_MIC_LEN ) != 0 ) {
00511                 DBGC ( ctx, "WPA-TKIP %p ALERT! MIC failure\n", ctx );
00512                 /* XXX we should do the countermeasures here */
00513                 free_iob ( iob );
00514                 return NULL;
00515         }
00516 
00517         DBGC2 ( ctx, "WPA-TKIP %p: decrypted packet %p -> %p\n", ctx,
00518                 eiob, iob );
00519 
00520         return iob;
00521 }

static void tkip_kie_mic ( const void *  kck,
const void *  msg,
size_t  len,
void *  mic 
) [static]

Calculate HMAC-MD5 MIC for EAPOL-Key frame.

Parameters:
kck Key Confirmation Key, 16 bytes
msg Message to calculate MIC over
len Number of bytes to calculate MIC over
Return values:
mic Calculated MIC, 16 bytes long

Definition at line 543 of file wpa_tkip.c.

References hmac_final(), hmac_init(), hmac_update(), md5_algorithm, memcpy, and u8.

00545 {
00546         struct md5_ctx md5;
00547         u8 kckb[16];
00548         size_t kck_len = 16;
00549 
00550         memcpy ( kckb, kck, kck_len );
00551 
00552         hmac_init ( &md5_algorithm, &md5, kckb, &kck_len );
00553         hmac_update ( &md5_algorithm, &md5, msg, len );
00554         hmac_final ( &md5_algorithm, &md5, kckb, &kck_len, mic );
00555 }

static int tkip_kie_decrypt ( const void *  kek,
const void *  iv,
void *  msg,
u16 len 
) [static]

Decrypt key data in EAPOL-Key frame.

Parameters:
kek Key Encryption Key, 16 bytes
iv Initialisation vector, 16 bytes
msg Message to decrypt
len Length of message
Return values:
msg Decrypted message in place of original
len Unchanged
rc Always 0 for success

Definition at line 568 of file wpa_tkip.c.

References arc4_skip(), memcpy, and u8.

00570 {
00571         u8 key[32];
00572         memcpy ( key, iv, 16 );
00573         memcpy ( key + 16, kek, 16 );
00574 
00575         arc4_skip ( key, 32, 256, msg, msg, *len );
00576 
00577         return 0;
00578 }


Variable Documentation

const u16 Sbox[256] [static]

TKIP S-box.

Definition at line 94 of file wpa_tkip.c.

struct net80211_crypto tkip_crypto __net80211_crypto

Initial value:

 {
        .algorithm = NET80211_CRYPT_TKIP,
        .init = tkip_init,
        .encrypt = tkip_encrypt,
        .decrypt = tkip_decrypt,
        .priv_len = sizeof ( struct tkip_ctx ),
}
TKIP cryptosystem.

Definition at line 524 of file wpa_tkip.c.

struct wpa_kie tkip_kie __wpa_kie

Initial value:

 {
        .version = EAPOL_KEY_VERSION_WPA,
        .mic = tkip_kie_mic,
        .decrypt = tkip_kie_decrypt,
}
TKIP-style key integrity and encryption handler.

Definition at line 582 of file wpa_tkip.c.


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