iPXE
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)
#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)
 FILE_SECBOOT (FORBIDDEN)
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.

Macro Definition Documentation

◆ TKIP_HEAD_LEN

#define TKIP_HEAD_LEN   8

TKIP header overhead (IV + KID + ExtIV)

Definition at line 84 of file wpa_tkip.c.

Referenced by tkip_decrypt(), and tkip_encrypt().

◆ TKIP_FOOT_LEN

#define TKIP_FOOT_LEN   12

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

Definition at line 87 of file wpa_tkip.c.

Referenced by tkip_decrypt(), and tkip_encrypt().

◆ TKIP_MIC_LEN

#define TKIP_MIC_LEN   8

TKIP MIC length.

Definition at line 90 of file wpa_tkip.c.

Referenced by tkip_decrypt().

◆ TKIP_ICV_LEN

#define TKIP_ICV_LEN   4

TKIP ICV length.

Definition at line 93 of file wpa_tkip.c.

Referenced by tkip_encrypt().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER )

◆ FILE_SECBOOT()

FILE_SECBOOT ( FORBIDDEN )

◆ S()

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 138 of file wpa_tkip.c.

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

References bswap_16, Sbox, and u16.

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

◆ ror16()

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 150 of file wpa_tkip.c.

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

References bits, and u16.

Referenced by tkip_mix_2().

◆ ror32()

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 162 of file wpa_tkip.c.

163{
164 return ( v >> bits ) | ( v << ( 32 - bits ) );
165}

References bits, and u32.

Referenced by aes_key_rotate(), des_generate(), sha256_digest(), and tkip_feed_michael().

◆ rol32()

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 174 of file wpa_tkip.c.

175{
176 return ( v << bits ) | ( v >> ( 32 - bits ) );
177}

References bits, and u32.

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

◆ tkip_init()

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 188 of file wpa_tkip.c.

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

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

◆ tkip_mix_1()

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 218 of file wpa_tkip.c.

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

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

Referenced by tkip_decrypt(), and tkip_encrypt().

◆ tkip_mix_2()

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 258 of file wpa_tkip.c.

260{
261 u8 *kb = key;
262 u16 ppk[6];
263 int i;
264
265 memcpy ( ppk, dctx->ttak, sizeof ( dctx->ttak ) );
266 ppk[5] = dctx->ttak[4] + dctx->tsc_lo;
267
268 ppk[0] += S ( ppk[5] ^ ( ( tk->key[1] << 8 ) | tk->key[0] ) );
269 ppk[1] += S ( ppk[0] ^ ( ( tk->key[3] << 8 ) | tk->key[2] ) );
270 ppk[2] += S ( ppk[1] ^ ( ( tk->key[5] << 8 ) | tk->key[4] ) );
271 ppk[3] += S ( ppk[2] ^ ( ( tk->key[7] << 8 ) | tk->key[6] ) );
272 ppk[4] += S ( ppk[3] ^ ( ( tk->key[9] << 8 ) | tk->key[8] ) );
273 ppk[5] += S ( ppk[4] ^ ( ( tk->key[11] << 8 ) | tk->key[10] ) );
274
275 ppk[0] += ror16 ( ppk[5] ^ ( ( tk->key[13] << 8 ) | tk->key[12] ), 1 );
276 ppk[1] += ror16 ( ppk[0] ^ ( ( tk->key[15] << 8 ) | tk->key[14] ), 1 );
277 ppk[2] += ror16 ( ppk[1], 1 );
278 ppk[3] += ror16 ( ppk[2], 1 );
279 ppk[4] += ror16 ( ppk[3], 1 );
280 ppk[5] += ror16 ( ppk[4], 1 );
281
282 kb[0] = dctx->tsc_lo >> 8;
283 kb[1] = ( ( dctx->tsc_lo >> 8 ) | 0x20 ) & 0x7F;
284 kb[2] = dctx->tsc_lo & 0xFF;
285 kb[3] = ( ( ppk[5] ^ ( ( tk->key[1] << 8 ) | tk->key[0] ) ) >> 1 )
286 & 0xFF;
287
288 for ( i = 0; i < 6; i++ ) {
289 kb[4 + 2*i] = ppk[i] & 0xFF;
290 kb[5 + 2*i] = ppk[i] >> 8;
291 }
292}
u16 tsc_lo
Low 32 bits of last sequence counter value used.
Definition wpa_tkip.c:47
#define u16
Definition vga.h:20
static u16 ror16(u16 v, int bits)
Rotate 16-bit value right.
Definition wpa_tkip.c:150

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

Referenced by tkip_decrypt(), and tkip_encrypt().

◆ tkip_feed_michael()

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 300 of file wpa_tkip.c.

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

References rol32(), ror32(), and u32.

Referenced by tkip_michael().

◆ tkip_michael()

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 323 of file wpa_tkip.c.

325{
326 u32 V[2]; /* V[0] = "l", V[1] = "r" in 802.11 */
327 union {
328 u8 byte[12];
329 u32 word[3];
330 } cap;
331 const u8 *ptr = data;
332 const u8 *end = ptr + len;
333 int i;
334
335 memcpy ( V, key, sizeof ( V ) );
336 V[0] = le32_to_cpu ( V[0] );
337 V[1] = le32_to_cpu ( V[1] );
338
339 /* Feed in header (we assume non-QoS, so Priority = 0) */
340 memcpy ( &cap.byte[0], da, ETH_ALEN );
341 memcpy ( &cap.byte[6], sa, ETH_ALEN );
342 tkip_feed_michael ( V, le32_to_cpu ( cap.word[0] ) );
343 tkip_feed_michael ( V, le32_to_cpu ( cap.word[1] ) );
344 tkip_feed_michael ( V, le32_to_cpu ( cap.word[2] ) );
345 tkip_feed_michael ( V, 0 );
346
347 /* Feed in data */
348 while ( ptr + 4 <= end ) {
349 tkip_feed_michael ( V, le32_to_cpu ( *( u32 * ) ptr ) );
350 ptr += 4;
351 }
352
353 /* Add unaligned part and padding */
354 for ( i = 0; ptr < end; i++ )
355 cap.byte[i] = *ptr++;
356 cap.byte[i++] = 0x5a;
357 for ( ; i < 8; i++ )
358 cap.byte[i] = 0;
359
360 /* Feed in padding */
361 tkip_feed_michael ( V, le32_to_cpu ( cap.word[0] ) );
362 tkip_feed_michael ( V, le32_to_cpu ( cap.word[1] ) );
363
364 /* Output MIC */
365 V[0] = cpu_to_le32 ( V[0] );
366 V[1] = cpu_to_le32 ( V[1] );
367 memcpy ( mic, V, sizeof ( V ) );
368}
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define le32_to_cpu(value)
Definition byteswap.h:114
#define cpu_to_le32(value)
Definition byteswap.h:108
uint32_t end
Ending offset.
Definition netvsc.h:7
struct sockaddr sa
Definition syslog.c:57
#define u32
Definition vga.h:21
u8 mic[16]
Message integrity code over the entire EAPOL frame.
Definition wpa.h:54
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:300

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

Referenced by tkip_decrypt(), and tkip_encrypt().

◆ tkip_encrypt()

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 377 of file wpa_tkip.c.

379{
380 struct tkip_ctx *ctx = crypto->priv;
381 struct ieee80211_frame *hdr = iob->data;
382 struct io_buffer *eiob;
383 struct arc4_ctx arc4;
384 u8 key[16];
385 struct tkip_head head;
386 u8 mic[8];
387 u32 icv;
388 const int hdrlen = IEEE80211_TYP_FRAME_HEADER_LEN;
389 int datalen = iob_len ( iob ) - hdrlen;
390
391 ctx->enc.tsc_lo++;
392 if ( ctx->enc.tsc_lo == 0 ) {
393 ctx->enc.tsc_hi++;
394 ctx->enc.ttak_ok = 0;
395 }
396
397 tkip_mix_1 ( &ctx->enc, &ctx->tk, hdr->addr2 );
398 tkip_mix_2 ( &ctx->enc, &ctx->tk, key );
399
400 eiob = alloc_iob ( iob_len ( iob ) + TKIP_HEAD_LEN + TKIP_FOOT_LEN );
401 if ( ! eiob )
402 return NULL;
403
404 /* Copy frame header */
405 memcpy ( iob_put ( eiob, hdrlen ), iob->data, hdrlen );
406 hdr = eiob->data;
408
409 /* Fill in IV and key ID byte, and extended IV */
410 memcpy ( &head, key, 3 );
411 head.kid = 0x20; /* have Extended IV, key ID 0 */
412 head.tsc_hi = cpu_to_le32 ( ctx->enc.tsc_hi );
413 memcpy ( iob_put ( eiob, sizeof ( head ) ), &head, sizeof ( head ) );
414
415 /* Copy and encrypt the data */
416 cipher_setkey ( &arc4_algorithm, &arc4, key, 16 );
417 cipher_encrypt ( &arc4_algorithm, &arc4, iob->data + hdrlen,
418 iob_put ( eiob, datalen ), datalen );
419
420 /* Add MIC */
421 hdr = iob->data;
422 tkip_michael ( &ctx->tk.mic.tx, hdr->addr3, hdr->addr2,
423 iob->data + hdrlen, datalen, mic );
425 iob_put ( eiob, sizeof ( mic ) ), sizeof ( mic ) );
426
427 /* Add ICV */
428 icv = crc32_le ( ~0, iob->data + hdrlen, datalen );
429 icv = crc32_le ( icv, mic, sizeof ( mic ) );
430 icv = cpu_to_le32 ( ~icv );
431 cipher_encrypt ( &arc4_algorithm, &arc4, &icv,
432 iob_put ( eiob, TKIP_ICV_LEN ), TKIP_ICV_LEN );
433
434 DBGC2 ( ctx, "WPA-TKIP %p: encrypted packet %p -> %p\n", ctx,
435 iob, eiob );
436
437 return eiob;
438}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct golan_inbox_hdr hdr
Message header.
Definition CIB_PRM.h:0
struct cipher_algorithm arc4_algorithm
Definition arc4.c:118
u32 crc32_le(u32 seed, const void *data, size_t len)
Calculate 32-bit little-endian CRC checksum.
Definition crc32.c:40
#define DBGC2(...)
Definition compiler.h:522
#define IEEE80211_FC_PROTECTED
802.11 Frame Control field: Protected flag
Definition ieee80211.h:264
#define IEEE80211_TYP_FRAME_HEADER_LEN
Frame header length for frames we might work with.
Definition ieee80211.h:60
uint8_t head
Head number.
Definition int13.h:23
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition crypto.h:235
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition crypto.h:251
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
#define iob_put(iobuf, len)
Definition iobuf.h:125
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
An 802.11 data or management frame without QoS or WDS header fields.
Definition ieee80211.h:301
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
Header structure at the beginning of TKIP frame data.
Definition wpa_tkip.c:74
u16 datalen
Length of the data field in bytes, network byte order.
Definition wpa.h:57
#define TKIP_ICV_LEN
TKIP ICV length.
Definition wpa_tkip.c:93
#define TKIP_FOOT_LEN
TKIP trailer overhead (MIC + ICV) [assumes unfragmented].
Definition wpa_tkip.c:87
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:218
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:323
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:258
#define TKIP_HEAD_LEN
TKIP header overhead (IV + KID + ExtIV)
Definition wpa_tkip.c:84

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(), tkip_mix_2(), u32, and u8.

◆ tkip_decrypt()

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 447 of file wpa_tkip.c.

449{
450 struct tkip_ctx *ctx = crypto->priv;
451 struct ieee80211_frame *hdr;
452 struct io_buffer *iob;
453 const int hdrlen = IEEE80211_TYP_FRAME_HEADER_LEN;
454 int datalen = iob_len ( eiob ) - hdrlen - TKIP_HEAD_LEN - TKIP_FOOT_LEN;
455 struct tkip_head *head;
456 struct arc4_ctx arc4;
457 u16 rx_tsc_lo;
458 u8 key[16];
459 u8 mic[8];
460 u32 icv, crc;
461
462 iob = alloc_iob ( hdrlen + datalen + TKIP_FOOT_LEN );
463 if ( ! iob )
464 return NULL;
465
466 /* Copy frame header */
467 memcpy ( iob_put ( iob, hdrlen ), eiob->data, hdrlen );
468 hdr = iob->data;
470
471 /* Check and update TSC */
472 head = eiob->data + hdrlen;
473 rx_tsc_lo = ( head->tsc1 << 8 ) | head->tsc0;
474
475 if ( head->tsc_hi < ctx->dec.tsc_hi ||
476 ( head->tsc_hi == ctx->dec.tsc_hi &&
477 rx_tsc_lo <= ctx->dec.tsc_lo ) ) {
478 DBGC ( ctx, "WPA-TKIP %p: packet received out of order "
479 "(%08x:%04x <= %08x:%04x)\n", ctx, head->tsc_hi,
480 rx_tsc_lo, ctx->dec.tsc_hi, ctx->dec.tsc_lo );
481 free_iob ( iob );
482 return NULL;
483 }
484 ctx->dec.tsc_lo = rx_tsc_lo;
485 if ( ctx->dec.tsc_hi != head->tsc_hi ) {
486 ctx->dec.ttak_ok = 0;
487 ctx->dec.tsc_hi = head->tsc_hi;
488 }
489
490 /* Calculate key */
491 tkip_mix_1 ( &ctx->dec, &ctx->tk, hdr->addr2 );
492 tkip_mix_2 ( &ctx->dec, &ctx->tk, key );
493
494 /* Copy-decrypt data, MIC, ICV */
495 cipher_setkey ( &arc4_algorithm, &arc4, key, 16 );
497 eiob->data + hdrlen + TKIP_HEAD_LEN,
498 iob_put ( iob, datalen ), datalen + TKIP_FOOT_LEN );
499
500 /* Check ICV */
501 icv = le32_to_cpu ( *( u32 * ) ( iob->tail + TKIP_MIC_LEN ) );
502 crc = ~crc32_le ( ~0, iob->data + hdrlen, datalen + TKIP_MIC_LEN );
503 if ( crc != icv ) {
504 DBGC ( ctx, "WPA-TKIP %p CRC mismatch: expect %08x, get %08x\n",
505 ctx, icv, crc );
506 free_iob ( iob );
507 return NULL;
508 }
509
510 /* Check MIC */
511 tkip_michael ( &ctx->tk.mic.rx, hdr->addr1, hdr->addr3,
512 iob->data + hdrlen, datalen, mic );
513 if ( memcmp ( mic, iob->tail, TKIP_MIC_LEN ) != 0 ) {
514 DBGC ( ctx, "WPA-TKIP %p ALERT! MIC failure\n", ctx );
515 /* XXX we should do the countermeasures here */
516 free_iob ( iob );
517 return NULL;
518 }
519
520 DBGC2 ( ctx, "WPA-TKIP %p: decrypted packet %p -> %p\n", ctx,
521 eiob, iob );
522
523 return iob;
524}
#define DBGC(...)
Definition compiler.h:505
#define cipher_decrypt(cipher, ctx, src, dst, len)
Definition crypto.h:261
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
void * tail
End of data.
Definition iobuf.h:55
#define TKIP_MIC_LEN
TKIP MIC length.
Definition wpa_tkip.c:90

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, 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(), tkip_mix_2(), u16, u32, and u8.

◆ tkip_kie_mic()

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 546 of file wpa_tkip.c.

548{
550 u8 kckb[16];
551
552 memcpy ( kckb, kck, sizeof ( kckb ) );
553
554 hmac_init ( &md5_algorithm, ctx, kckb, sizeof ( kckb ) );
557}
unsigned char uint8_t
Definition stdint.h:10
void hmac_init(struct digest_algorithm *digest, void *ctx, const void *key, size_t key_len)
Initialise HMAC.
Definition hmac.c:58
void hmac_final(struct digest_algorithm *digest, void *ctx, void *hmac)
Finalise HMAC.
Definition hmac.c:88
static void hmac_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Update HMAC.
Definition hmac.h:43
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition md5.c:287
#define MD5_CTX_SIZE
MD5 context size.
Definition md5.h:67
#define MD5_BLOCK_SIZE
MD5 block size.
Definition md5.h:70
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition message.c:62
u8 kck[WPA_KCK_LEN]
EAPOL-Key Key Confirmation Key (KCK)
Definition wpa.h:1

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

◆ tkip_kie_decrypt()

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}
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:109
u8 iv[16]
Initialization vector.
Definition wpa.h:33
u8 kek[WPA_KEK_LEN]
EAPOL-Key Key Encryption Key (KEK)
Definition wpa.h:4

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

Variable Documentation

◆ Sbox

const u16 Sbox[256]
static

TKIP S-box.

Definition at line 97 of file wpa_tkip.c.

97 {
98 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
99 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
100 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
101 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
102 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
103 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
104 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
105 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
106 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
107 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
108 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
109 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
110 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
111 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
112 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
113 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
114 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
115 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
116 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
117 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
118 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
119 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
120 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
121 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
122 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
123 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
124 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
125 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
126 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
127 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
128 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
129 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
130};

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 ),
}
@ NET80211_CRYPT_TKIP
Network protected with TKIP (better RC4-based system)
Definition net80211.h:163
static struct io_buffer * tkip_decrypt(struct net80211_crypto *crypto, struct io_buffer *eiob)
Decrypt a packet using TKIP.
Definition wpa_tkip.c:447
static struct io_buffer * tkip_encrypt(struct net80211_crypto *crypto, struct io_buffer *iob)
Encrypt a packet using TKIP.
Definition wpa_tkip.c:377
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:188

TKIP cryptosystem.

Definition at line 527 of file wpa_tkip.c.

527 {
528 .algorithm = NET80211_CRYPT_TKIP,
529 .init = tkip_init,
530 .encrypt = tkip_encrypt,
531 .decrypt = tkip_decrypt,
532 .priv_len = sizeof ( struct tkip_ctx ),
533};

◆ __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 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:546
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

TKIP-style key integrity and encryption handler.

Definition at line 584 of file wpa_tkip.c.

584 {
585 .version = EAPOL_KEY_VERSION_WPA,
586 .mic = tkip_kie_mic,
587 .decrypt = tkip_kie_decrypt,
588};