13 #include <linux/module.h>
15 #include <linux/slab.h>
16 #include <linux/random.h>
18 #include <linux/netdevice.h>
19 #include <linux/if_ether.h>
20 #include <linux/if_arp.h>
21 #include <asm/string.h>
22 #include <linux/wireless.h>
33 #define AES_BLOCK_LEN 16
34 #define CCMP_HDR_LEN 8
35 #define CCMP_MIC_LEN 8
36 #define CCMP_TK_LEN 16
61 const u8 pt[16],
u8 ct[16])
63 crypto_cipher_encrypt_one((
void*)tfm, ct, pt);
66 static void * ieee80211_ccmp_init(
int key_idx)
76 if (IS_ERR(priv->
tfm)) {
88 crypto_free_cipher((
void*)priv->
tfm);
96 static void ieee80211_ccmp_deinit(
void *priv)
100 if (_priv && _priv->
tfm)
101 crypto_free_cipher((
void*)_priv->
tfm);
106 static inline void xor_block(
u8 *
b,
u8 *
a,
size_t len)
109 for (i = 0; i < len; i++)
123 int a4_included, qc_included;
155 b0[14] = (dlen >> 8) & 0xff;
156 b0[15] = dlen & 0xff;
167 aad[1] = aad_len & 0xff;
168 aad[2] = pos[0] & 0x8f;
169 aad[3] = pos[1] & 0xc7;
172 aad[22] = pos[0] & 0x0f;
178 aad[a4_included ? 30 : 24] = qc;
217 if (key->
tx_pn[i] != 0)
222 *pos++ = key->
tx_pn[5];
223 *pos++ = key->
tx_pn[4];
225 *pos++ = (key->
key_idx << 6) | (1 << 5) ;
226 *pos++ = key->
tx_pn[3];
227 *pos++ = key->
tx_pn[2];
228 *pos++ = key->
tx_pn[1];
229 *pos++ = key->
tx_pn[0];
235 int blocks,
last, len;
245 ccmp_init_blocks(key->
tfm, hdr, key->
tx_pn, data_len, b0, b, s0);
250 for (i = 1; i <= blocks; i++) {
253 xor_block(b, pos, len);
256 b0[14] = (i >> 8) & 0xff;
259 xor_block(pos, e, len);
264 mic[i] = b[i] ^ s0[i];
270 static int ieee80211_ccmp_decrypt(
struct sk_buff *skb,
int hdr_len,
void *priv)
284 pos = skb->
data + hdr_len;
286 if (!(keyidx & (1 << 5))) {
289 " flag from %pM\n", hdr->
addr2);
297 "keyidx=%d priv=%p\n", key->
key_idx, keyidx, priv);
303 " with keyid=%d that does not have a configured"
304 " key\n", hdr->
addr2, keyidx);
320 " previous PN %pm received PN %pm\n",
333 int i, blocks, last, len;
336 ccmp_init_blocks(key->
tfm, hdr, pn, data_len, b0, a, b);
337 xor_block(mic, b, CCMP_MIC_LEN);
342 for (i = 1; i <= blocks; i++) {
345 b0[14] = (i >> 8) & 0xff;
348 xor_block(pos, b, len);
350 xor_block(a, pos, len);
355 if (
memcmp(mic, a, CCMP_MIC_LEN) != 0) {
358 "%pM\n", hdr->
addr2);
375 static int ieee80211_ccmp_set_key(
void *key,
int len,
u8 *seq,
void *priv)
382 memset(data, 0,
sizeof(*data));
389 data->
rx_pn[0] = seq[5];
390 data->
rx_pn[1] = seq[4];
391 data->
rx_pn[2] = seq[3];
392 data->
rx_pn[3] = seq[2];
393 data->
rx_pn[4] = seq[1];
394 data->
rx_pn[5] = seq[0];
406 static int ieee80211_ccmp_get_key(
void *key,
int len,
u8 *seq,
void *priv)
418 seq[0] = data->
tx_pn[5];
419 seq[1] = data->
tx_pn[4];
420 seq[2] = data->
tx_pn[3];
421 seq[3] = data->
tx_pn[2];
422 seq[4] = data->
tx_pn[1];
423 seq[5] = data->
tx_pn[0];
430 static char * ieee80211_ccmp_print_stats(
char *
p,
void *priv)
433 p +=
sprintf(p,
"key[%d] alg=CCMP key_set=%d "
434 "tx_pn=%pm rx_pn=%pm "
435 "format_errors=%d replays=%d decrypt_errors=%d\n",
453 .init = ieee80211_ccmp_init,
454 .deinit = ieee80211_ccmp_deinit,
455 .encrypt_mpdu = ieee80211_ccmp_encrypt,
456 .decrypt_mpdu = ieee80211_ccmp_decrypt,
457 .encrypt_msdu =
NULL,
458 .decrypt_msdu =
NULL,
459 .set_key = ieee80211_ccmp_set_key,
460 .get_key = ieee80211_ccmp_get_key,
461 .print_stats = ieee80211_ccmp_print_stats,