iPXE
wpa_ccmp.c File Reference

Backend for WPA using the CCMP encryption method. More...

#include <string.h>
#include <ipxe/net80211.h>
#include <ipxe/crypto.h>
#include <ipxe/hmac.h>
#include <ipxe/sha1.h>
#include <ipxe/aes.h>
#include <ipxe/wpa.h>
#include <byteswap.h>
#include <errno.h>

Go to the source code of this file.

Data Structures

struct  ccmp_ctx
 Context for CCMP encryption and decryption. More...
struct  ccmp_head
 Header structure at the beginning of CCMP frame data. More...
struct  ccmp_nonce
 CCMP nonce structure. More...
struct  ccmp_aad
 CCMP additional authentication data structure. More...

Macros

#define CCMP_HEAD_LEN   8
 CCMP header overhead.
#define CCMP_MIC_LEN   8
 CCMP MIC trailer overhead.
#define CCMP_NONCE_LEN   13
 CCMP nonce length.
#define CCMP_AAD_LEN   22
 CCMP additional authentication data length (for non-QoS, non-WDS frames)
#define CCMP_AAD_FC_MASK   0xC38F
 Mask for Frame Control field in AAD.
#define CCMP_AAD_SEQ_MASK   0x000F
 Mask for Sequence Control field in AAD.
#define PN_MSB   1
 Value for msb argument of u64_to_pn() for MSB output.
#define PN_LSB   0
 Value for msb argument of u64_to_pn() for LSB output.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 FILE_SECBOOT (FORBIDDEN)
static u64 pn_to_u64 (const u8 *pn)
 Convert 6-byte LSB packet number to 64-bit integer.
static void u64_to_pn (u64 v, u8 *pn, int msb)
 Convert 64-bit integer to 6-byte packet number.
static int ccmp_init (struct net80211_crypto *crypto, const void *key, int keylen, const void *rsc)
 Initialise CCMP state and install key.
static void ccmp_ctr_xor (struct ccmp_ctx *ctx, const void *nonce, const void *srcv, void *destv, int len, const void *msrcv, void *mdestv)
 Encrypt or decrypt data stream using AES in Counter mode.
static void ccmp_feed_cbc_mac (void *aes_ctx, u8 *B, u8 *X)
 Advance one block in CBC-MAC calculation.
static void ccmp_cbc_mac (struct ccmp_ctx *ctx, const void *nonce, const void *data, u16 datalen, const void *aad, void *mic)
 Calculate MIC on plaintext data using CBC-MAC.
struct io_bufferccmp_encrypt (struct net80211_crypto *crypto, struct io_buffer *iob)
 Encapsulate and encrypt a packet using CCMP.
static struct io_bufferccmp_decrypt (struct net80211_crypto *crypto, struct io_buffer *eiob)
 Decrypt a packet using CCMP.
static void ccmp_kie_mic (const void *kck, const void *msg, size_t len, void *mic)
 Calculate HMAC-SHA1 MIC for EAPOL-Key frame.
static int ccmp_kie_decrypt (const void *kek, const void *iv __unused, void *msg, u16 *len)
 Decrypt key data in EAPOL-Key frame.

Variables

struct net80211_crypto ccmp_crypto __net80211_crypto
 CCMP cryptosystem.
struct wpa_kie ccmp_kie __wpa_kie
 CCMP-style key integrity and encryption handler.

Detailed Description

Backend for WPA using the CCMP encryption method.

Definition in file wpa_ccmp.c.

Macro Definition Documentation

◆ CCMP_HEAD_LEN

#define CCMP_HEAD_LEN   8

CCMP header overhead.

Definition at line 62 of file wpa_ccmp.c.

Referenced by ccmp_decrypt(), and ccmp_encrypt().

◆ CCMP_MIC_LEN

#define CCMP_MIC_LEN   8

CCMP MIC trailer overhead.

Definition at line 65 of file wpa_ccmp.c.

Referenced by ccmp_decrypt(), and ccmp_encrypt().

◆ CCMP_NONCE_LEN

#define CCMP_NONCE_LEN   13

CCMP nonce length.

Definition at line 68 of file wpa_ccmp.c.

Referenced by ccmp_cbc_mac(), and ccmp_ctr_xor().

◆ CCMP_AAD_LEN

#define CCMP_AAD_LEN   22

CCMP additional authentication data length (for non-QoS, non-WDS frames)

Definition at line 79 of file wpa_ccmp.c.

Referenced by ccmp_cbc_mac().

◆ CCMP_AAD_FC_MASK

#define CCMP_AAD_FC_MASK   0xC38F

Mask for Frame Control field in AAD.

Definition at line 93 of file wpa_ccmp.c.

Referenced by ccmp_decrypt(), and ccmp_encrypt().

◆ CCMP_AAD_SEQ_MASK

#define CCMP_AAD_SEQ_MASK   0x000F

Mask for Sequence Control field in AAD.

Definition at line 96 of file wpa_ccmp.c.

Referenced by ccmp_decrypt(), and ccmp_encrypt().

◆ PN_MSB

#define PN_MSB   1

Value for msb argument of u64_to_pn() for MSB output.

Definition at line 142 of file wpa_ccmp.c.

Referenced by ccmp_decrypt(), and ccmp_encrypt().

◆ PN_LSB

#define PN_LSB   0

Value for msb argument of u64_to_pn() for LSB output.

Definition at line 145 of file wpa_ccmp.c.

Referenced by ccmp_encrypt().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER )

◆ FILE_SECBOOT()

FILE_SECBOOT ( FORBIDDEN )

◆ pn_to_u64()

u64 pn_to_u64 ( const u8 * pn)
static

Convert 6-byte LSB packet number to 64-bit integer.

Parameters
pnPointer to 6-byte packet number
Return values
v64-bit integer value of pn

Definition at line 105 of file wpa_ccmp.c.

106{
107 int i;
108 u64 ret = 0;
109
110 for ( i = 5; i >= 0; i-- ) {
111 ret <<= 8;
112 ret |= pn[i];
113 }
114
115 return ret;
116}
uint64_t u64
Definition stdint.h:26

References u8.

Referenced by ccmp_decrypt(), and ccmp_init().

◆ u64_to_pn()

void u64_to_pn ( u64 v,
u8 * pn,
int msb )
static

Convert 64-bit integer to 6-byte packet number.

Parameters
v64-bit integer
msbIf TRUE, reverse the output PN to be in MSB order
Return values
pn6-byte packet number

The PN is stored in LSB order in the packet header and in MSB order in the nonce. WHYYYYY?

Definition at line 128 of file wpa_ccmp.c.

129{
130 int i;
131 u8 *pnp = pn + ( msb ? 5 : 0 );
132 int delta = ( msb ? -1 : +1 );
133
134 for ( i = 0; i < 6; i++ ) {
135 *pnp = v & 0xFF;
136 pnp += delta;
137 v >>= 8;
138 }
139}
#define u8
Definition igbvf_osdep.h:40

References u8.

Referenced by ccmp_decrypt(), and ccmp_encrypt().

◆ ccmp_init()

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

Initialise CCMP state and install key.

Parameters
cryptoCCMP cryptosystem structure
keyPointer to 16-byte temporal key to install
keylenLength of key (16 bytes)
rscInitial receive sequence counter

Definition at line 157 of file wpa_ccmp.c.

159{
160 struct ccmp_ctx *ctx = crypto->priv;
161
162 if ( keylen != 16 )
163 return -EINVAL;
164
165 if ( rsc )
166 ctx->rx_seq = pn_to_u64 ( rsc );
167
168 cipher_setkey ( &aes_algorithm, ctx->aes_ctx, key, keylen );
169
170 return 0;
171}
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
struct golan_eq_context ctx
Definition CIB_PRM.h:0
struct cipher_algorithm aes_algorithm
Basic AES algorithm.
Definition aes.c:784
#define EINVAL
Invalid argument.
Definition errno.h:429
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition crypto.h:235
Context for CCMP encryption and decryption.
Definition wpa_ccmp.c:40
void * priv
Private data for the algorithm to store key and state info.
Definition net80211.h:766
u8 rsc[8]
Receive sequence counter for GTK.
Definition wpa.h:42
static u64 pn_to_u64(const u8 *pn)
Convert 6-byte LSB packet number to 64-bit integer.
Definition wpa_ccmp.c:105

References aes_algorithm, cipher_setkey(), ctx, EINVAL, key, pn_to_u64(), net80211_crypto::priv, and rsc.

◆ ccmp_ctr_xor()

void ccmp_ctr_xor ( struct ccmp_ctx * ctx,
const void * nonce,
const void * srcv,
void * destv,
int len,
const void * msrcv,
void * mdestv )
static

Encrypt or decrypt data stream using AES in Counter mode.

Parameters
ctxCCMP cryptosystem context
nonceNonce value, 13 bytes
srcvData to encrypt or decrypt
lenNumber of bytes pointed to by src
msrcvMIC value to encrypt or decrypt (may be NULL)
Return values
destvEncrypted or decrypted data
mdestvEncrypted or decrypted MIC value

This assumes CCMP parameters of L=2 and M=8. The algorithm is defined in RFC 3610.

Definition at line 188 of file wpa_ccmp.c.

191{
192 u8 A[16], S[16];
193 u16 ctr;
194 int i;
195 const u8 *src = srcv, *msrc = msrcv;
196 u8 *dest = destv, *mdest = mdestv;
197
198 A[0] = 0x01; /* flags, L' = L - 1 = 1, other bits rsvd */
199 memcpy ( A + 1, nonce, CCMP_NONCE_LEN );
200
201 if ( msrcv ) {
202 A[14] = A[15] = 0;
203
204 cipher_encrypt ( &aes_algorithm, ctx->aes_ctx, A, S, 16 );
205
206 for ( i = 0; i < 8; i++ ) {
207 *mdest++ = *msrc++ ^ S[i];
208 }
209 }
210
211 for ( ctr = 1 ;; ctr++ ) {
212 A[14] = ctr >> 8;
213 A[15] = ctr & 0xFF;
214
215 cipher_encrypt ( &aes_algorithm, ctx->aes_ctx, A, S, 16 );
216
217 for ( i = 0; i < len && i < 16; i++ )
218 *dest++ = *src++ ^ S[i];
219
220 if ( len <= 16 )
221 break; /* we're done */
222
223 len -= 16;
224 }
225}
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" retur dest)
Definition string.h:151
static const void * src
Definition string.h:48
ring len
Length.
Definition dwmac.h:226
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition crypto.h:251
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define u16
Definition vga.h:20
u8 nonce[32]
Nonce value.
Definition wpa.h:25
#define CCMP_NONCE_LEN
CCMP nonce length.
Definition wpa_ccmp.c:68
static u16 S(u16 v)
Perform S-box mapping on a 16-bit value.
Definition wpa_tkip.c:138

References aes_algorithm, CCMP_NONCE_LEN, cipher_encrypt, ctx, dest, len, memcpy(), nonce, S(), src, u16, and u8.

Referenced by ccmp_decrypt(), and ccmp_encrypt().

◆ ccmp_feed_cbc_mac()

void ccmp_feed_cbc_mac ( void * aes_ctx,
u8 * B,
u8 * X )
static

Advance one block in CBC-MAC calculation.

Parameters
aes_ctxAES encryption context with key set
BCleartext block to incorporate (16 bytes)
XPrevious ciphertext block (16 bytes)
Return values
BClobbered
XNew ciphertext block (16 bytes)

This function does X := E[key] ( X ^ B ).

Definition at line 239 of file wpa_ccmp.c.

240{
241 int i;
242 for ( i = 0; i < 16; i++ )
243 B[i] ^= X[i];
244 cipher_encrypt ( &aes_algorithm, aes_ctx, B, X, 16 );
245}

References aes_algorithm, ccmp_ctx::aes_ctx, cipher_encrypt, and u8.

Referenced by ccmp_cbc_mac().

◆ ccmp_cbc_mac()

void ccmp_cbc_mac ( struct ccmp_ctx * ctx,
const void * nonce,
const void * data,
u16 datalen,
const void * aad,
void * mic )
static

Calculate MIC on plaintext data using CBC-MAC.

Parameters
ctxCCMP cryptosystem context
nonceNonce value, 13 bytes
dataData to calculate MIC over
datalenLength of data
aadAdditional authentication data, for MIC but not encryption
Return values
micMIC value (unencrypted), 8 bytes

aadlen is assumed to be 22 bytes long, as it always is for 802.11 use when transmitting non-QoS, not-between-APs frames (the only type we deal with).

Definition at line 262 of file wpa_ccmp.c.

265{
266 u8 X[16], B[16];
267
268 /* Zeroth block: flags, nonce, length */
269
270 /* Rsv AAD - M'- - L'-
271 * 0 1 0 1 1 0 0 1 for an 8-byte MAC and 2-byte message length
272 */
273 B[0] = 0x59;
274 memcpy ( B + 1, nonce, CCMP_NONCE_LEN );
275 B[14] = datalen >> 8;
276 B[15] = datalen & 0xFF;
277
278 cipher_encrypt ( &aes_algorithm, ctx->aes_ctx, B, X, 16 );
279
280 /* First block: AAD length field and 14 bytes of AAD */
281 B[0] = 0;
282 B[1] = CCMP_AAD_LEN;
283 memcpy ( B + 2, aad, 14 );
284
285 ccmp_feed_cbc_mac ( ctx->aes_ctx, B, X );
286
287 /* Second block: Remaining 8 bytes of AAD, 8 bytes zero pad */
288 memcpy ( B, aad + 14, 8 );
289 memset ( B + 8, 0, 8 );
290
291 ccmp_feed_cbc_mac ( ctx->aes_ctx, B, X );
292
293 /* Message blocks */
294 while ( datalen ) {
295 if ( datalen >= 16 ) {
296 memcpy ( B, data, 16 );
297 datalen -= 16;
298 } else {
299 memcpy ( B, data, datalen );
300 memset ( B + datalen, 0, 16 - datalen );
301 datalen = 0;
302 }
303
304 ccmp_feed_cbc_mac ( ctx->aes_ctx, B, X );
305
306 data += 16;
307 }
308
309 /* Get MIC from final value of X */
310 memcpy ( mic, X, 8 );
311}
uint8_t data[48]
Additional event data.
Definition ena.h:11
void * memset(void *dest, int character, size_t len) __nonnull
u16 datalen
Length of the data field in bytes, network byte order.
Definition wpa.h:57
u8 mic[16]
Message integrity code over the entire EAPOL frame.
Definition wpa.h:54
#define CCMP_AAD_LEN
CCMP additional authentication data length (for non-QoS, non-WDS frames)
Definition wpa_ccmp.c:79
static void ccmp_feed_cbc_mac(void *aes_ctx, u8 *B, u8 *X)
Advance one block in CBC-MAC calculation.
Definition wpa_ccmp.c:239

References aes_algorithm, CCMP_AAD_LEN, ccmp_feed_cbc_mac(), CCMP_NONCE_LEN, cipher_encrypt, ctx, data, datalen, memcpy(), memset(), mic, nonce, u16, and u8.

Referenced by ccmp_decrypt(), and ccmp_encrypt().

◆ ccmp_encrypt()

struct io_buffer * ccmp_encrypt ( struct net80211_crypto * crypto,
struct io_buffer * iob )

Encapsulate and encrypt a packet using CCMP.

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

Definition at line 321 of file wpa_ccmp.c.

323{
324 struct ccmp_ctx *ctx = crypto->priv;
325 struct ieee80211_frame *hdr = iob->data;
326 struct io_buffer *eiob;
327 const int hdrlen = IEEE80211_TYP_FRAME_HEADER_LEN;
328 int datalen = iob_len ( iob ) - hdrlen;
329 struct ccmp_head head;
330 struct ccmp_nonce nonce;
331 struct ccmp_aad aad;
332 u8 mic[8], tx_pn[6];
333 void *edata, *emic;
334
335 ctx->tx_seq++;
336 u64_to_pn ( ctx->tx_seq, tx_pn, PN_LSB );
337
338 /* Allocate memory */
339 eiob = alloc_iob ( iob_len ( iob ) + CCMP_HEAD_LEN + CCMP_MIC_LEN );
340 if ( ! eiob )
341 return NULL;
342
343 /* Copy frame header */
344 memcpy ( iob_put ( eiob, hdrlen ), iob->data, hdrlen );
345 hdr = eiob->data;
347
348 /* Fill in packet number and extended IV */
349 memcpy ( head.pn_lo, tx_pn, 2 );
350 memcpy ( head.pn_hi, tx_pn + 2, 4 );
351 head.kid = 0x20; /* have Extended IV, key ID 0 */
352 head._rsvd = 0;
353 memcpy ( iob_put ( eiob, sizeof ( head ) ), &head, sizeof ( head ) );
354
355 /* Form nonce */
356 nonce.prio = 0;
357 memcpy ( nonce.a2, hdr->addr2, ETH_ALEN );
358 u64_to_pn ( ctx->tx_seq, nonce.pn, PN_MSB );
359
360 /* Form additional authentication data */
361 aad.fc = hdr->fc & CCMP_AAD_FC_MASK;
362 memcpy ( aad.a1, hdr->addr1, 3 * ETH_ALEN ); /* all 3 at once */
363 aad.seq = hdr->seq & CCMP_AAD_SEQ_MASK;
364
365 /* Calculate MIC over the data */
366 ccmp_cbc_mac ( ctx, &nonce, iob->data + hdrlen, datalen, &aad, mic );
367
368 /* Copy and encrypt data and MIC */
369 edata = iob_put ( eiob, datalen );
370 emic = iob_put ( eiob, CCMP_MIC_LEN );
372 iob->data + hdrlen, edata, datalen,
373 mic, emic );
374
375 /* Done! */
376 DBGC2 ( ctx, "WPA-CCMP %p: encrypted packet %p -> %p\n", ctx,
377 iob, eiob );
378
379 return eiob;
380}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct golan_inbox_hdr hdr
Message header.
Definition CIB_PRM.h:0
#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
#define ETH_ALEN
Definition if_ether.h:9
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
CCMP additional authentication data structure.
Definition wpa_ccmp.c:83
Header structure at the beginning of CCMP frame data.
Definition wpa_ccmp.c:53
CCMP nonce structure.
Definition wpa_ccmp.c:72
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
#define CCMP_AAD_SEQ_MASK
Mask for Sequence Control field in AAD.
Definition wpa_ccmp.c:96
#define CCMP_AAD_FC_MASK
Mask for Frame Control field in AAD.
Definition wpa_ccmp.c:93
#define CCMP_HEAD_LEN
CCMP header overhead.
Definition wpa_ccmp.c:62
static void ccmp_ctr_xor(struct ccmp_ctx *ctx, const void *nonce, const void *srcv, void *destv, int len, const void *msrcv, void *mdestv)
Encrypt or decrypt data stream using AES in Counter mode.
Definition wpa_ccmp.c:188
static void u64_to_pn(u64 v, u8 *pn, int msb)
Convert 64-bit integer to 6-byte packet number.
Definition wpa_ccmp.c:128
static void ccmp_cbc_mac(struct ccmp_ctx *ctx, const void *nonce, const void *data, u16 datalen, const void *aad, void *mic)
Calculate MIC on plaintext data using CBC-MAC.
Definition wpa_ccmp.c:262
#define PN_MSB
Value for msb argument of u64_to_pn() for MSB output.
Definition wpa_ccmp.c:142
#define CCMP_MIC_LEN
CCMP MIC trailer overhead.
Definition wpa_ccmp.c:65
#define PN_LSB
Value for msb argument of u64_to_pn() for LSB output.
Definition wpa_ccmp.c:145

References ccmp_aad::a1, alloc_iob(), CCMP_AAD_FC_MASK, CCMP_AAD_SEQ_MASK, ccmp_cbc_mac(), ccmp_ctr_xor(), CCMP_HEAD_LEN, CCMP_MIC_LEN, ctx, io_buffer::data, datalen, DBGC2, ETH_ALEN, ccmp_aad::fc, hdr, head, IEEE80211_FC_PROTECTED, IEEE80211_TYP_FRAME_HEADER_LEN, iob_len(), iob_put, memcpy(), mic, nonce, NULL, PN_LSB, PN_MSB, net80211_crypto::priv, ccmp_aad::seq, u64_to_pn(), and u8.

◆ ccmp_decrypt()

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

Decrypt a packet using CCMP.

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

Definition at line 389 of file wpa_ccmp.c.

391{
392 struct ccmp_ctx *ctx = crypto->priv;
393 struct ieee80211_frame *hdr;
394 struct io_buffer *iob;
395 const int hdrlen = IEEE80211_TYP_FRAME_HEADER_LEN;
396 int datalen = iob_len ( eiob ) - hdrlen - CCMP_HEAD_LEN - CCMP_MIC_LEN;
397 struct ccmp_head *head;
398 struct ccmp_nonce nonce;
399 struct ccmp_aad aad;
400 u8 rx_pn[6], their_mic[8], our_mic[8];
401
402 iob = alloc_iob ( hdrlen + datalen );
403 if ( ! iob )
404 return NULL;
405
406 /* Copy frame header */
407 memcpy ( iob_put ( iob, hdrlen ), eiob->data, hdrlen );
408 hdr = iob->data;
410
411 /* Check and update RX packet number */
412 head = eiob->data + hdrlen;
413 memcpy ( rx_pn, head->pn_lo, 2 );
414 memcpy ( rx_pn + 2, head->pn_hi, 4 );
415
416 if ( pn_to_u64 ( rx_pn ) <= ctx->rx_seq ) {
417 DBGC ( ctx, "WPA-CCMP %p: packet received out of order "
418 "(%012llx <= %012llx)\n", ctx, pn_to_u64 ( rx_pn ),
419 ctx->rx_seq );
420 free_iob ( iob );
421 return NULL;
422 }
423
424 ctx->rx_seq = pn_to_u64 ( rx_pn );
425 DBGC2 ( ctx, "WPA-CCMP %p: RX packet number %012llx\n", ctx, ctx->rx_seq );
426
427 /* Form nonce */
428 nonce.prio = 0;
429 memcpy ( nonce.a2, hdr->addr2, ETH_ALEN );
430 u64_to_pn ( ctx->rx_seq, nonce.pn, PN_MSB );
431
432 /* Form additional authentication data */
433 aad.fc = ( hdr->fc & CCMP_AAD_FC_MASK ) | IEEE80211_FC_PROTECTED;
434 memcpy ( aad.a1, hdr->addr1, 3 * ETH_ALEN ); /* all 3 at once */
435 aad.seq = hdr->seq & CCMP_AAD_SEQ_MASK;
436
437 /* Copy-decrypt data and MIC */
438 ccmp_ctr_xor ( ctx, &nonce, eiob->data + hdrlen + sizeof ( *head ),
439 iob_put ( iob, datalen ), datalen,
440 eiob->tail - CCMP_MIC_LEN, their_mic );
441
442 /* Check MIC */
443 ccmp_cbc_mac ( ctx, &nonce, iob->data + hdrlen, datalen, &aad,
444 our_mic );
445
446 if ( memcmp ( their_mic, our_mic, CCMP_MIC_LEN ) != 0 ) {
447 DBGC2 ( ctx, "WPA-CCMP %p: MIC failure\n", ctx );
448 free_iob ( iob );
449 return NULL;
450 }
451
452 DBGC2 ( ctx, "WPA-CCMP %p: decrypted packet %p -> %p\n", ctx,
453 eiob, iob );
454
455 return iob;
456}
#define DBGC(...)
Definition compiler.h:505
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
void * tail
End of data.
Definition iobuf.h:55

References ccmp_aad::a1, alloc_iob(), CCMP_AAD_FC_MASK, CCMP_AAD_SEQ_MASK, ccmp_cbc_mac(), ccmp_ctr_xor(), CCMP_HEAD_LEN, CCMP_MIC_LEN, ctx, io_buffer::data, datalen, DBGC, DBGC2, ETH_ALEN, ccmp_aad::fc, free_iob(), hdr, head, IEEE80211_FC_PROTECTED, IEEE80211_TYP_FRAME_HEADER_LEN, iob_len(), iob_put, memcmp(), memcpy(), nonce, NULL, PN_MSB, pn_to_u64(), net80211_crypto::priv, ccmp_aad::seq, io_buffer::tail, u64_to_pn(), and u8.

◆ ccmp_kie_mic()

void ccmp_kie_mic ( const void * kck,
const void * msg,
size_t len,
void * mic )
static

Calculate HMAC-SHA1 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 479 of file wpa_ccmp.c.

481{
483 u8 kckb[16];
485
486 memcpy ( kckb, kck, sizeof ( kckb ) );
487
488 hmac_init ( &sha1_algorithm, ctx, kckb, sizeof ( kckb ) );
491
492 memcpy ( mic, hash, 16 );
493}
#define SHA1_DIGEST_SIZE
Definition Tpm20.h:26
#define SHA1_BLOCK_SIZE
Definition Tpm20.h:27
pseudo_bit_t hash[0x00010]
Definition arbel.h:2
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
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition message.c:62
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition sha1.c:258
#define SHA1_CTX_SIZE
SHA-1 context size.
Definition sha1.h:67
u8 kck[WPA_KCK_LEN]
EAPOL-Key Key Confirmation Key (KCK)
Definition wpa.h:1

References ctx, hash, hmac_final(), hmac_init(), hmac_update(), kck, len, memcpy(), mic, msg(), sha1_algorithm, SHA1_BLOCK_SIZE, SHA1_CTX_SIZE, SHA1_DIGEST_SIZE, and u8.

◆ ccmp_kie_decrypt()

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

Decrypt key data in EAPOL-Key frame.

Parameters
kekKey Encryption Key, 16 bytes
ivInitialisation vector, 16 bytes (unused)
msgMessage to decrypt
lenLength of message
Return values
msgDecrypted message in place of original
lenAdjusted downward for 8 bytes of overhead
rcReturn status code

The returned message may still contain padding of 0xDD followed by zero or more 0x00 octets. It is impossible to remove the padding without parsing the IEs in the packet (another design decision that tends to make one question the 802.11i committee's intelligence...)

Definition at line 511 of file wpa_ccmp.c.

513{
514 if ( *len % 8 != 0 )
515 return -EINVAL;
516
517 if ( aes_unwrap ( kek, msg, msg, *len / 8 - 1 ) != 0 )
518 return -EINVAL;
519
520 *len -= 8;
521
522 return 0;
523}
int aes_unwrap(const void *kek, const void *src, void *dest, int nblk)
Unwrap a key or other data using AES Key Wrap (RFC 3394)
Definition aes_wrap.c:85
u8 kek[WPA_KEK_LEN]
EAPOL-Key Key Encryption Key (KEK)
Definition wpa.h:4

References __unused, aes_unwrap(), EINVAL, iv, kek, len, msg(), and u16.

Variable Documentation

◆ __net80211_crypto

struct net80211_crypto ccmp_crypto __net80211_crypto
Initial value:
= {
.algorithm = NET80211_CRYPT_CCMP,
.init = ccmp_init,
.encrypt = ccmp_encrypt,
.decrypt = ccmp_decrypt,
.priv_len = sizeof ( struct ccmp_ctx ),
}
@ NET80211_CRYPT_CCMP
Network protected with CCMP (AES-based system)
Definition net80211.h:174
static struct io_buffer * ccmp_decrypt(struct net80211_crypto *crypto, struct io_buffer *eiob)
Decrypt a packet using CCMP.
Definition wpa_ccmp.c:389
static int ccmp_init(struct net80211_crypto *crypto, const void *key, int keylen, const void *rsc)
Initialise CCMP state and install key.
Definition wpa_ccmp.c:157
struct io_buffer * ccmp_encrypt(struct net80211_crypto *crypto, struct io_buffer *iob)
Encapsulate and encrypt a packet using CCMP.
Definition wpa_ccmp.c:321

CCMP cryptosystem.

Definition at line 460 of file wpa_ccmp.c.

460 {
461 .algorithm = NET80211_CRYPT_CCMP,
462 .init = ccmp_init,
463 .encrypt = ccmp_encrypt,
464 .decrypt = ccmp_decrypt,
465 .priv_len = sizeof ( struct ccmp_ctx ),
466};

◆ __wpa_kie

struct wpa_kie ccmp_kie __wpa_kie
Initial value:
= {
.mic = ccmp_kie_mic,
.decrypt = ccmp_kie_decrypt,
}
#define EAPOL_KEY_VERSION_WPA2
Key descriptor version field value for WPA2 (CCMP)
Definition wpa.h:81
static int ccmp_kie_decrypt(const void *kek, const void *iv __unused, void *msg, u16 *len)
Decrypt key data in EAPOL-Key frame.
Definition wpa_ccmp.c:511
static void ccmp_kie_mic(const void *kck, const void *msg, size_t len, void *mic)
Calculate HMAC-SHA1 MIC for EAPOL-Key frame.
Definition wpa_ccmp.c:479

CCMP-style key integrity and encryption handler.

Definition at line 526 of file wpa_ccmp.c.

526 {
527 .version = EAPOL_KEY_VERSION_WPA2,
528 .mic = ccmp_kie_mic,
529 .decrypt = ccmp_kie_decrypt,
530};