iPXE
Data Structures | Macros | Functions | Variables
wpa_tkip.c File Reference

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

#include <string.h>
#include <ipxe/net80211.h>
#include <ipxe/crypto.h>
#include <ipxe/hmac.h>
#include <ipxe/sha1.h>
#include <ipxe/md5.h>
#include <ipxe/crc32.h>
#include <ipxe/arc4.h>
#include <ipxe/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...
 

Macros

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

Functions

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

Variables

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

Detailed Description

Backend for WPA using the TKIP encryption standard.

Definition in file wpa_tkip.c.

Macro Definition Documentation

◆ TKIP_HEAD_LEN

#define TKIP_HEAD_LEN   8

TKIP header overhead (IV + KID + ExtIV)

Definition at line 83 of file wpa_tkip.c.

◆ TKIP_FOOT_LEN

#define TKIP_FOOT_LEN   12

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

Definition at line 86 of file wpa_tkip.c.

◆ TKIP_MIC_LEN

#define TKIP_MIC_LEN   8

TKIP MIC length.

Definition at line 89 of file wpa_tkip.c.

◆ TKIP_ICV_LEN

#define TKIP_ICV_LEN   4

TKIP ICV length.

Definition at line 92 of file wpa_tkip.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ S()

static u16 S ( u16  v)
inlinestatic

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

Parameters
vValue to perform S-box mapping on
Return values
SvS-box mapped value

Definition at line 137 of file wpa_tkip.c.

138 {
139  return Sbox[v & 0xFF] ^ bswap_16 ( Sbox[v >> 8] );
140 }
static const u16 Sbox[256]
TKIP S-box.
Definition: wpa_tkip.c:96
#define bswap_16(value)
Definition: byteswap.h:58

References bswap_16, and Sbox.

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

◆ ror16()

static u16 ror16 ( u16  v,
int  bits 
)
inlinestatic

Rotate 16-bit value right.

Parameters
vValue to rotate
bitsNumber of bits to rotate by
Return values
rotvRotated value

Definition at line 149 of file wpa_tkip.c.

150 {
151  return ( v >> bits ) | ( v << ( 16 - bits ) );
152 }
static volatile void * bits
Definition: bitops.h:27

References bits.

Referenced by tkip_mix_2().

◆ ror32()

static u32 ror32 ( u32  v,
int  bits 
)
inlinestatic

Rotate 32-bit value right.

Parameters
vValue to rotate
bitsNumber of bits to rotate by
Return values
rotvRotated value

Definition at line 161 of file wpa_tkip.c.

162 {
163  return ( v >> bits ) | ( v << ( 32 - bits ) );
164 }
static volatile void * bits
Definition: bitops.h:27

References bits.

Referenced by sha256_digest(), and tkip_feed_michael().

◆ rol32()

static u32 rol32 ( u32  v,
int  bits 
)
inlinestatic

Rotate 32-bit value left.

Parameters
vValue to rotate
bitsNumber of bits to rotate by
Return values
rotvRotated value

Definition at line 173 of file wpa_tkip.c.

174 {
175  return ( v << bits ) | ( v >> ( 32 - bits ) );
176 }
static volatile void * bits
Definition: bitops.h:27

References bits.

Referenced by aes_key_sbox(), md4_digest(), md5_digest(), sha1_digest(), and tkip_feed_michael().

◆ tkip_init()

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

Initialise TKIP state and install key.

Parameters
cryptoTKIP cryptosystem structure
keyPointer to tkip_tk to install
keylenLength of key (32 bytes)
rscInitial receive sequence counter

Definition at line 187 of file wpa_tkip.c.

189 {
190  struct tkip_ctx *ctx = crypto->priv;
191  const u8 *rscb = rsc;
192 
193  if ( keylen != sizeof ( ctx->tk ) )
194  return -EINVAL;
195 
196  if ( rscb ) {
197  ctx->dec.tsc_lo = ( rscb[1] << 8 ) | rscb[0];
198  ctx->dec.tsc_hi = ( ( rscb[5] << 24 ) | ( rscb[4] << 16 ) |
199  ( rscb[3] << 8 ) | rscb[2] );
200  }
201 
202  memcpy ( &ctx->tk, key, sizeof ( ctx->tk ) );
203 
204  return 0;
205 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u8 rsc[8]
Receive sequence counter for GTK.
Definition: wpa.h:69
Context for TKIP encryption and decryption.
Definition: wpa_tkip.c:59
void * priv
Private data for the algorithm to store key and state info.
Definition: net80211.h:766
uint8_t u8
Definition: stdint.h:19
union @375 key
Sense key.
Definition: scsi.h:18

References ctx, EINVAL, key, memcpy(), net80211_crypto::priv, and rsc.

◆ tkip_mix_1()

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

Perform TKIP key mixing, phase 1.

Parameters
dctxTKIP directional context
tkTKIP temporal key
macMAC address of transmitter

This recomputes the TTAK in dctx if necessary, and sets dctx->ttak_ok.

Definition at line 217 of file wpa_tkip.c.

218 {
219  int i, j;
220 
221  if ( dctx->ttak_ok && ! memcmp ( mac, dctx->mac, ETH_ALEN ) )
222  return;
223 
224  memcpy ( dctx->mac, mac, ETH_ALEN );
225 
226  dctx->ttak[0] = dctx->tsc_hi & 0xFFFF;
227  dctx->ttak[1] = dctx->tsc_hi >> 16;
228  dctx->ttak[2] = ( mac[1] << 8 ) | mac[0];
229  dctx->ttak[3] = ( mac[3] << 8 ) | mac[2];
230  dctx->ttak[4] = ( mac[5] << 8 ) | mac[4];
231 
232  for ( i = 0; i < 8; i++ ) {
233  j = 2 * ( i & 1 );
234 
235  dctx->ttak[0] += S ( dctx->ttak[4] ^ ( ( tk->key[1 + j] << 8 ) |
236  tk->key[0 + j] ) );
237  dctx->ttak[1] += S ( dctx->ttak[0] ^ ( ( tk->key[5 + j] << 8 ) |
238  tk->key[4 + j] ) );
239  dctx->ttak[2] += S ( dctx->ttak[1] ^ ( ( tk->key[9 + j] << 8 ) |
240  tk->key[8 + j] ) );
241  dctx->ttak[3] += S ( dctx->ttak[2] ^ ( ( tk->key[13+ j] << 8 ) |
242  tk->key[12+ j] ) );
243  dctx->ttak[4] += S ( dctx->ttak[3] ^ ( ( tk->key[1 + j] << 8 ) |
244  tk->key[0 + j] ) ) + i;
245  }
246 
247  dctx->ttak_ok = 1;
248 }
u8 mac[ETH_ALEN]
MAC address used to derive TTAK.
Definition: wpa_tkip.c:49
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
static u16 S(u16 v)
Perform S-box mapping on a 16-bit value.
Definition: wpa_tkip.c:137
void * memcpy(void *dest, const void *src, size_t len) __nonnull
union wpa_tk tk
Temporal key.
Definition: wpa.h:34
#define ETH_ALEN
Definition: if_ether.h:8
u16 ttak_ok
If TRUE, TTAK is valid.
Definition: wpa_tkip.c:52
u16 ttak[5]
TKIP-mixed transmit address and key, depends on tsc_hi and MAC.
Definition: wpa_tkip.c:55
u32 tsc_hi
High 32 bits of last sequence counter value used.
Definition: wpa_tkip.c:43
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98

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

Referenced by tkip_decrypt(), and tkip_encrypt().

◆ tkip_mix_2()

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

Perform TKIP key mixing, phase 2.

Parameters
dctxTKIP directional context
tkTKIP temporal key
Return values
keyARC4 key, 16 bytes long

Definition at line 257 of file wpa_tkip.c.

259 {
260  u8 *kb = key;
261  u16 ppk[6];
262  int i;
263 
264  memcpy ( ppk, dctx->ttak, sizeof ( dctx->ttak ) );
265  ppk[5] = dctx->ttak[4] + dctx->tsc_lo;
266 
267  ppk[0] += S ( ppk[5] ^ ( ( tk->key[1] << 8 ) | tk->key[0] ) );
268  ppk[1] += S ( ppk[0] ^ ( ( tk->key[3] << 8 ) | tk->key[2] ) );
269  ppk[2] += S ( ppk[1] ^ ( ( tk->key[5] << 8 ) | tk->key[4] ) );
270  ppk[3] += S ( ppk[2] ^ ( ( tk->key[7] << 8 ) | tk->key[6] ) );
271  ppk[4] += S ( ppk[3] ^ ( ( tk->key[9] << 8 ) | tk->key[8] ) );
272  ppk[5] += S ( ppk[4] ^ ( ( tk->key[11] << 8 ) | tk->key[10] ) );
273 
274  ppk[0] += ror16 ( ppk[5] ^ ( ( tk->key[13] << 8 ) | tk->key[12] ), 1 );
275  ppk[1] += ror16 ( ppk[0] ^ ( ( tk->key[15] << 8 ) | tk->key[14] ), 1 );
276  ppk[2] += ror16 ( ppk[1], 1 );
277  ppk[3] += ror16 ( ppk[2], 1 );
278  ppk[4] += ror16 ( ppk[3], 1 );
279  ppk[5] += ror16 ( ppk[4], 1 );
280 
281  kb[0] = dctx->tsc_lo >> 8;
282  kb[1] = ( ( dctx->tsc_lo >> 8 ) | 0x20 ) & 0x7F;
283  kb[2] = dctx->tsc_lo & 0xFF;
284  kb[3] = ( ( ppk[5] ^ ( ( tk->key[1] << 8 ) | tk->key[0] ) ) >> 1 )
285  & 0xFF;
286 
287  for ( i = 0; i < 6; i++ ) {
288  kb[4 + 2*i] = ppk[i] & 0xFF;
289  kb[5 + 2*i] = ppk[i] >> 8;
290  }
291 }
uint16_t u16
Definition: stdint.h:21
static u16 S(u16 v)
Perform S-box mapping on a 16-bit value.
Definition: wpa_tkip.c:137
void * memcpy(void *dest, const void *src, size_t len) __nonnull
union wpa_tk tk
Temporal key.
Definition: wpa.h:34
u16 tsc_lo
Low 32 bits of last sequence counter value used.
Definition: wpa_tkip.c:46
u16 ttak[5]
TKIP-mixed transmit address and key, depends on tsc_hi and MAC.
Definition: wpa_tkip.c:55
static u16 ror16(u16 v, int bits)
Rotate 16-bit value right.
Definition: wpa_tkip.c:149
uint8_t u8
Definition: stdint.h:19
union @375 key
Sense key.
Definition: scsi.h:18

References key, memcpy(), ror16(), S(), tk, tkip_dir_ctx::tsc_lo, and tkip_dir_ctx::ttak.

Referenced by tkip_decrypt(), and tkip_encrypt().

◆ tkip_feed_michael()

static void tkip_feed_michael ( u32 V,
u32  word 
)
static

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

Parameters
VMichael code state (two 32-bit words)
wordNext 32-bit word of data

Definition at line 299 of file wpa_tkip.c.

300 {
301  V[0] ^= word;
302  V[1] ^= rol32 ( V[0], 17 );
303  V[0] += V[1];
304  V[1] ^= ( ( V[0] & 0xFF00FF00 ) >> 8 ) | ( ( V[0] & 0x00FF00FF ) << 8 );
305  V[0] += V[1];
306  V[1] ^= rol32 ( V[0], 3 );
307  V[0] += V[1];
308  V[1] ^= ror32 ( V[0], 2 );
309  V[0] += V[1];
310 }
static u32 rol32(u32 v, int bits)
Rotate 32-bit value left.
Definition: wpa_tkip.c:173
static u32 ror32(u32 v, int bits)
Rotate 32-bit value right.
Definition: wpa_tkip.c:161
unsigned short word
Definition: smc9000.h:39

References rol32(), and ror32().

Referenced by tkip_michael().

◆ tkip_michael()

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
keyMIC key to use (8 bytes)
daDestination link-layer address
saSource link-layer address
dataStart of data to calculate over
lenLength of header + data
Return values
micCalculated Michael MIC (8 bytes)

Definition at line 322 of file wpa_tkip.c.

324 {
325  u32 V[2]; /* V[0] = "l", V[1] = "r" in 802.11 */
326  union {
327  u8 byte[12];
328  u32 word[3];
329  } cap;
330  const u8 *ptr = data;
331  const u8 *end = ptr + len;
332  int i;
333 
334  memcpy ( V, key, sizeof ( V ) );
335  V[0] = le32_to_cpu ( V[0] );
336  V[1] = le32_to_cpu ( V[1] );
337 
338  /* Feed in header (we assume non-QoS, so Priority = 0) */
339  memcpy ( &cap.byte[0], da, ETH_ALEN );
340  memcpy ( &cap.byte[6], sa, ETH_ALEN );
341  tkip_feed_michael ( V, le32_to_cpu ( cap.word[0] ) );
342  tkip_feed_michael ( V, le32_to_cpu ( cap.word[1] ) );
343  tkip_feed_michael ( V, le32_to_cpu ( cap.word[2] ) );
344  tkip_feed_michael ( V, 0 );
345 
346  /* Feed in data */
347  while ( ptr + 4 <= end ) {
348  tkip_feed_michael ( V, le32_to_cpu ( *( u32 * ) ptr ) );
349  ptr += 4;
350  }
351 
352  /* Add unaligned part and padding */
353  for ( i = 0; ptr < end; i++ )
354  cap.byte[i] = *ptr++;
355  cap.byte[i++] = 0x5a;
356  for ( ; i < 8; i++ )
357  cap.byte[i] = 0;
358 
359  /* Feed in padding */
360  tkip_feed_michael ( V, le32_to_cpu ( cap.word[0] ) );
361  tkip_feed_michael ( V, le32_to_cpu ( cap.word[1] ) );
362 
363  /* Output MIC */
364  V[0] = cpu_to_le32 ( V[0] );
365  V[1] = cpu_to_le32 ( V[1] );
366  memcpy ( mic, V, sizeof ( V ) );
367 }
static void tkip_feed_michael(u32 *V, u32 word)
Update Michael message integrity code based on next 32-bit word of data.
Definition: wpa_tkip.c:299
struct sockaddr sa
Definition: dns.c:68
#define le32_to_cpu(value)
Definition: byteswap.h:113
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define cpu_to_le32(value)
Definition: byteswap.h:107
#define ETH_ALEN
Definition: if_ether.h:8
uint32_t len
Length.
Definition: ena.h:14
unsigned short word
Definition: smc9000.h:39
uint32_t end
Ending offset.
Definition: netvsc.h:18
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
u8 mic[16]
Message integrity code over the entire EAPOL frame.
Definition: wpa.h:81
uint8_t u8
Definition: stdint.h:19
union @375 key
Sense key.
Definition: scsi.h:18
uint32_t u32
Definition: stdint.h:23

References cpu_to_le32, data, end, ETH_ALEN, key, le32_to_cpu, len, memcpy(), mic, sa, and tkip_feed_michael().

Referenced by tkip_decrypt(), and tkip_encrypt().

◆ tkip_encrypt()

static struct io_buffer* tkip_encrypt ( struct net80211_crypto crypto,
struct io_buffer iob 
)
static

Encrypt a packet using TKIP.

Parameters
cryptoTKIP cryptosystem
iobI/O buffer containing cleartext packet
Return values
eiobI/O buffer containing encrypted packet

Definition at line 376 of file wpa_tkip.c.

378 {
379  struct tkip_ctx *ctx = crypto->priv;
380  struct ieee80211_frame *hdr = iob->data;
381  struct io_buffer *eiob;
382  struct arc4_ctx arc4;
383  u8 key[16];
384  struct tkip_head head;
385  u8 mic[8];
386  u32 icv;
387  const int hdrlen = IEEE80211_TYP_FRAME_HEADER_LEN;
388  int datalen = iob_len ( iob ) - hdrlen;
389 
390  ctx->enc.tsc_lo++;
391  if ( ctx->enc.tsc_lo == 0 ) {
392  ctx->enc.tsc_hi++;
393  ctx->enc.ttak_ok = 0;
394  }
395 
396  tkip_mix_1 ( &ctx->enc, &ctx->tk, hdr->addr2 );
397  tkip_mix_2 ( &ctx->enc, &ctx->tk, key );
398 
399  eiob = alloc_iob ( iob_len ( iob ) + TKIP_HEAD_LEN + TKIP_FOOT_LEN );
400  if ( ! eiob )
401  return NULL;
402 
403  /* Copy frame header */
404  memcpy ( iob_put ( eiob, hdrlen ), iob->data, hdrlen );
405  hdr = eiob->data;
407 
408  /* Fill in IV and key ID byte, and extended IV */
409  memcpy ( &head, key, 3 );
410  head.kid = 0x20; /* have Extended IV, key ID 0 */
411  head.tsc_hi = cpu_to_le32 ( ctx->enc.tsc_hi );
412  memcpy ( iob_put ( eiob, sizeof ( head ) ), &head, sizeof ( head ) );
413 
414  /* Copy and encrypt the data */
415  cipher_setkey ( &arc4_algorithm, &arc4, key, 16 );
416  cipher_encrypt ( &arc4_algorithm, &arc4, iob->data + hdrlen,
417  iob_put ( eiob, datalen ), datalen );
418 
419  /* Add MIC */
420  hdr = iob->data;
421  tkip_michael ( &ctx->tk.mic.tx, hdr->addr3, hdr->addr2,
422  iob->data + hdrlen, datalen, mic );
423  cipher_encrypt ( &arc4_algorithm, &arc4, mic,
424  iob_put ( eiob, sizeof ( mic ) ), sizeof ( mic ) );
425 
426  /* Add ICV */
427  icv = crc32_le ( ~0, iob->data + hdrlen, datalen );
428  icv = crc32_le ( icv, mic, sizeof ( mic ) );
429  icv = cpu_to_le32 ( ~icv );
430  cipher_encrypt ( &arc4_algorithm, &arc4, &icv,
431  iob_put ( eiob, TKIP_ICV_LEN ), TKIP_ICV_LEN );
432 
433  DBGC2 ( ctx, "WPA-TKIP %p: encrypted packet %p -> %p\n", ctx,
434  iob, eiob );
435 
436  return eiob;
437 }
#define iob_put(iobuf, len)
Definition: iobuf.h:116
Definition: arc4.h:10
An 802.11 data or management frame without QoS or WDS header fields.
Definition: ieee80211.h:300
uint8_t head
Head number.
Definition: int13.h:34
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
Header structure at the beginning of TKIP frame data.
Definition: wpa_tkip.c:72
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:128
u32 crc32_le(u32 seed, const void *data, size_t len)
Calculate 32-bit little-endian CRC checksum.
Definition: crc32.c:39
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:202
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define IEEE80211_TYP_FRAME_HEADER_LEN
Frame header length for frames we might work with.
Definition: ieee80211.h:60
u16 datalen
Length of the data field in bytes, network byte order.
Definition: wpa.h:84
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.
Definition: wpa_tkip.c:322
#define cpu_to_le32(value)
Definition: byteswap.h:107
#define TKIP_HEAD_LEN
TKIP header overhead (IV + KID + ExtIV)
Definition: wpa_tkip.c:83
#define IEEE80211_FC_PROTECTED
802.11 Frame Control field: Protected flag
Definition: ieee80211.h:264
Context for TKIP encryption and decryption.
Definition: wpa_tkip.c:59
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
static void tkip_mix_1(struct tkip_dir_ctx *dctx, struct tkip_tk *tk, u8 *mac)
Perform TKIP key mixing, phase 1.
Definition: wpa_tkip.c:217
void * priv
Private data for the algorithm to store key and state info.
Definition: net80211.h:766
static void tkip_mix_2(struct tkip_dir_ctx *dctx, struct tkip_tk *tk, void *key)
Perform TKIP key mixing, phase 2.
Definition: wpa_tkip.c:257
uint32_t hdr
Message header.
Definition: intelvf.h:12
struct cipher_algorithm arc4_algorithm
Definition: arc4.c:124
#define DBGC2(...)
Definition: compiler.h:522
#define TKIP_ICV_LEN
TKIP ICV length.
Definition: wpa_tkip.c:92
void * data
Start of data.
Definition: iobuf.h:44
u8 mic[16]
Message integrity code over the entire EAPOL frame.
Definition: wpa.h:81
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define TKIP_FOOT_LEN
TKIP trailer overhead (MIC + ICV) [assumes unfragmented].
Definition: wpa_tkip.c:86
uint8_t u8
Definition: stdint.h:19
union @375 key
Sense key.
Definition: scsi.h:18
uint32_t u32
Definition: stdint.h:23
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition: crypto.h:187
A persistent I/O buffer.
Definition: iobuf.h:32

References alloc_iob(), arc4_algorithm, cipher_encrypt, cipher_setkey(), cpu_to_le32, crc32_le(), ctx, io_buffer::data, datalen, DBGC2, hdr, head, IEEE80211_FC_PROTECTED, IEEE80211_TYP_FRAME_HEADER_LEN, iob_len(), iob_put, key, memcpy(), mic, NULL, net80211_crypto::priv, TKIP_FOOT_LEN, TKIP_HEAD_LEN, TKIP_ICV_LEN, tkip_michael(), tkip_mix_1(), and tkip_mix_2().

◆ tkip_decrypt()

static struct io_buffer* tkip_decrypt ( struct net80211_crypto crypto,
struct io_buffer eiob 
)
static

Decrypt a packet using TKIP.

Parameters
cryptoTKIP cryptosystem
eiobI/O buffer containing encrypted packet
Return values
iobI/O buffer containing cleartext packet

Definition at line 446 of file wpa_tkip.c.

448 {
449  struct tkip_ctx *ctx = crypto->priv;
450  struct ieee80211_frame *hdr;
451  struct io_buffer *iob;
452  const int hdrlen = IEEE80211_TYP_FRAME_HEADER_LEN;
453  int datalen = iob_len ( eiob ) - hdrlen - TKIP_HEAD_LEN - TKIP_FOOT_LEN;
454  struct tkip_head *head;
455  struct arc4_ctx arc4;
456  u16 rx_tsc_lo;
457  u8 key[16];
458  u8 mic[8];
459  u32 icv, crc;
460 
461  iob = alloc_iob ( hdrlen + datalen + TKIP_FOOT_LEN );
462  if ( ! iob )
463  return NULL;
464 
465  /* Copy frame header */
466  memcpy ( iob_put ( iob, hdrlen ), eiob->data, hdrlen );
467  hdr = iob->data;
468  hdr->fc &= ~IEEE80211_FC_PROTECTED;
469 
470  /* Check and update TSC */
471  head = eiob->data + hdrlen;
472  rx_tsc_lo = ( head->tsc1 << 8 ) | head->tsc0;
473 
474  if ( head->tsc_hi < ctx->dec.tsc_hi ||
475  ( head->tsc_hi == ctx->dec.tsc_hi &&
476  rx_tsc_lo <= ctx->dec.tsc_lo ) ) {
477  DBGC ( ctx, "WPA-TKIP %p: packet received out of order "
478  "(%08x:%04x <= %08x:%04x)\n", ctx, head->tsc_hi,
479  rx_tsc_lo, ctx->dec.tsc_hi, ctx->dec.tsc_lo );
480  free_iob ( iob );
481  return NULL;
482  }
483  ctx->dec.tsc_lo = rx_tsc_lo;
484  if ( ctx->dec.tsc_hi != head->tsc_hi ) {
485  ctx->dec.ttak_ok = 0;
486  ctx->dec.tsc_hi = head->tsc_hi;
487  }
488 
489  /* Calculate key */
490  tkip_mix_1 ( &ctx->dec, &ctx->tk, hdr->addr2 );
491  tkip_mix_2 ( &ctx->dec, &ctx->tk, key );
492 
493  /* Copy-decrypt data, MIC, ICV */
494  cipher_setkey ( &arc4_algorithm, &arc4, key, 16 );
495  cipher_decrypt ( &arc4_algorithm, &arc4,
496  eiob->data + hdrlen + TKIP_HEAD_LEN,
497  iob_put ( iob, datalen ), datalen + TKIP_FOOT_LEN );
498 
499  /* Check ICV */
500  icv = le32_to_cpu ( *( u32 * ) ( iob->tail + TKIP_MIC_LEN ) );
501  crc = ~crc32_le ( ~0, iob->data + hdrlen, datalen + TKIP_MIC_LEN );
502  if ( crc != icv ) {
503  DBGC ( ctx, "WPA-TKIP %p CRC mismatch: expect %08x, get %08x\n",
504  ctx, icv, crc );
505  free_iob ( iob );
506  return NULL;
507  }
508 
509  /* Check MIC */
510  tkip_michael ( &ctx->tk.mic.rx, hdr->addr1, hdr->addr3,
511  iob->data + hdrlen, datalen, mic );
512  if ( memcmp ( mic, iob->tail, TKIP_MIC_LEN ) != 0 ) {
513  DBGC ( ctx, "WPA-TKIP %p ALERT! MIC failure\n", ctx );
514  /* XXX we should do the countermeasures here */
515  free_iob ( iob );
516  return NULL;
517  }
518 
519  DBGC2 ( ctx, "WPA-TKIP %p: decrypted packet %p -> %p\n", ctx,
520  eiob, iob );
521 
522  return iob;
523 }
uint16_t u16
Definition: stdint.h:21
#define iob_put(iobuf, len)
Definition: iobuf.h:116
#define le32_to_cpu(value)
Definition: byteswap.h:113
Definition: arc4.h:10
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
#define DBGC(...)
Definition: compiler.h:505
An 802.11 data or management frame without QoS or WDS header fields.
Definition: ieee80211.h:300
uint8_t head
Head number.
Definition: int13.h:34
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
Header structure at the beginning of TKIP frame data.
Definition: wpa_tkip.c:72
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:128
#define TKIP_MIC_LEN
TKIP MIC length.
Definition: wpa_tkip.c:89
u32 crc32_le(u32 seed, const void *data, size_t len)
Calculate 32-bit little-endian CRC checksum.
Definition: crc32.c:39
void * tail
End of data.
Definition: iobuf.h:46
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define IEEE80211_TYP_FRAME_HEADER_LEN
Frame header length for frames we might work with.
Definition: ieee80211.h:60
u16 datalen
Length of the data field in bytes, network byte order.
Definition: wpa.h:84
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.
Definition: wpa_tkip.c:322
#define TKIP_HEAD_LEN
TKIP header overhead (IV + KID + ExtIV)
Definition: wpa_tkip.c:83
#define IEEE80211_FC_PROTECTED
802.11 Frame Control field: Protected flag
Definition: ieee80211.h:264
Context for TKIP encryption and decryption.
Definition: wpa_tkip.c:59
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
#define cipher_decrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:212
static void tkip_mix_1(struct tkip_dir_ctx *dctx, struct tkip_tk *tk, u8 *mac)
Perform TKIP key mixing, phase 1.
Definition: wpa_tkip.c:217
void * priv
Private data for the algorithm to store key and state info.
Definition: net80211.h:766
static void tkip_mix_2(struct tkip_dir_ctx *dctx, struct tkip_tk *tk, void *key)
Perform TKIP key mixing, phase 2.
Definition: wpa_tkip.c:257
uint32_t hdr
Message header.
Definition: intelvf.h:12
struct cipher_algorithm arc4_algorithm
Definition: arc4.c:124
#define DBGC2(...)
Definition: compiler.h:522
void * data
Start of data.
Definition: iobuf.h:44
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98
u8 mic[16]
Message integrity code over the entire EAPOL frame.
Definition: wpa.h:81
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define TKIP_FOOT_LEN
TKIP trailer overhead (MIC + ICV) [assumes unfragmented].
Definition: wpa_tkip.c:86
uint8_t u8
Definition: stdint.h:19
union @375 key
Sense key.
Definition: scsi.h:18
uint32_t u32
Definition: stdint.h:23
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition: crypto.h:187
if(natsemi->flags &NATSEMI_64BIT) return 1
A persistent I/O buffer.
Definition: iobuf.h:32

References alloc_iob(), arc4_algorithm, cipher_decrypt, cipher_setkey(), crc32_le(), ctx, io_buffer::data, datalen, DBGC, DBGC2, free_iob(), hdr, head, IEEE80211_FC_PROTECTED, IEEE80211_TYP_FRAME_HEADER_LEN, if(), iob_len(), iob_put, key, le32_to_cpu, memcmp(), memcpy(), mic, NULL, net80211_crypto::priv, io_buffer::tail, TKIP_FOOT_LEN, TKIP_HEAD_LEN, TKIP_MIC_LEN, tkip_michael(), tkip_mix_1(), and tkip_mix_2().

◆ tkip_kie_mic()

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
kckKey Confirmation Key, 16 bytes
msgMessage to calculate MIC over
lenNumber of bytes to calculate MIC over
Return values
micCalculated MIC, 16 bytes long

Definition at line 545 of file wpa_tkip.c.

547 {
549  u8 kckb[16];
550  size_t kck_len = 16;
551 
552  memcpy ( kckb, kck, kck_len );
553 
554  hmac_init ( &md5_algorithm, ctx, kckb, &kck_len );
556  hmac_final ( &md5_algorithm, ctx, kckb, &kck_len, mic );
557 }
void hmac_final(struct digest_algorithm *digest, void *digest_ctx, void *key, size_t *key_len, void *hmac)
Finalise HMAC.
Definition: hmac.c:115
u8 kck[WPA_KCK_LEN]
EAPOL-Key Key Confirmation Key (KCK)
Definition: wpa.h:28
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define MD5_CTX_SIZE
MD5 context size.
Definition: md5.h:66
unsigned char uint8_t
Definition: stdint.h:10
uint32_t len
Length.
Definition: ena.h:14
void hmac_init(struct digest_algorithm *digest, void *digest_ctx, void *key, size_t *key_len)
Initialise HMAC.
Definition: hmac.c:80
static void hmac_update(struct digest_algorithm *digest, void *digest_ctx, const void *data, size_t len)
Update HMAC.
Definition: hmac.h:21
u8 mic[16]
Message integrity code over the entire EAPOL frame.
Definition: wpa.h:81
uint8_t u8
Definition: stdint.h:19
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:287
static void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: settings_ui.c:285

References ctx, hmac_final(), hmac_init(), hmac_update(), kck, len, md5_algorithm, MD5_CTX_SIZE, memcpy(), mic, and msg().

◆ tkip_kie_decrypt()

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

Decrypt key data in EAPOL-Key frame.

Parameters
kekKey Encryption Key, 16 bytes
ivInitialisation vector, 16 bytes
msgMessage to decrypt
lenLength of message
Return values
msgDecrypted message in place of original
lenUnchanged
rcAlways 0 for success

Definition at line 570 of file wpa_tkip.c.

572 {
573  u8 key[32];
574  memcpy ( key, iv, 16 );
575  memcpy ( key + 16, kek, 16 );
576 
577  arc4_skip ( key, 32, 256, msg, msg, *len );
578 
579  return 0;
580 }
u8 iv[16]
Initialization vector.
Definition: wpa.h:60
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void arc4_skip(const void *key, size_t keylen, size_t skip, const void *src, void *dst, size_t msglen)
Perform ARC4 encryption or decryption, skipping initial keystream bytes.
Definition: arc4.c:115
u8 kek[WPA_KEK_LEN]
EAPOL-Key Key Encryption Key (KEK)
Definition: wpa.h:31
uint32_t len
Length.
Definition: ena.h:14
uint8_t u8
Definition: stdint.h:19
union @375 key
Sense key.
Definition: scsi.h:18
static void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: settings_ui.c:285

References arc4_skip(), iv, kek, key, len, memcpy(), and msg().

Variable Documentation

◆ Sbox

const u16 Sbox[256]
static

TKIP S-box.

Definition at line 96 of file wpa_tkip.c.

Referenced by S().

◆ __net80211_crypto

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 ),
}
Context for TKIP encryption and decryption.
Definition: wpa_tkip.c:59
static int tkip_init(struct net80211_crypto *crypto, const void *key, int keylen, const void *rsc)
Initialise TKIP state and install key.
Definition: wpa_tkip.c:187
static struct io_buffer * tkip_encrypt(struct net80211_crypto *crypto, struct io_buffer *iob)
Encrypt a packet using TKIP.
Definition: wpa_tkip.c:376
static struct io_buffer * tkip_decrypt(struct net80211_crypto *crypto, struct io_buffer *eiob)
Decrypt a packet using TKIP.
Definition: wpa_tkip.c:446
Network protected with TKIP (better RC4-based system)
Definition: net80211.h:163

TKIP cryptosystem.

Definition at line 526 of file wpa_tkip.c.

◆ __wpa_kie

struct wpa_kie tkip_kie __wpa_kie
Initial value:
= {
.mic = tkip_kie_mic,
.decrypt = tkip_kie_decrypt,
}
#define EAPOL_KEY_VERSION_WPA
Key descriptor version field value for WPA (TKIP)
Definition: wpa.h:78
static int tkip_kie_decrypt(const void *kek, const void *iv, void *msg, u16 *len)
Decrypt key data in EAPOL-Key frame.
Definition: wpa_tkip.c:570
static void tkip_kie_mic(const void *kck, const void *msg, size_t len, void *mic)
Calculate HMAC-MD5 MIC for EAPOL-Key frame.
Definition: wpa_tkip.c:545

TKIP-style key integrity and encryption handler.

Definition at line 584 of file wpa_tkip.c.