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>
34 #define AES_BLOCK_LEN 16
35 #define CCMP_HDR_LEN 8
36 #define CCMP_MIC_LEN 8
37 #define CCMP_TK_LEN 16
62 const u8 pt[16],
u8 ct[16])
64 crypto_cipher_encrypt_one((
void *)tfm, ct, pt);
67 static void * ieee80211_ccmp_init(
int key_idx)
77 if (IS_ERR(priv->
tfm)) {
89 crypto_free_cipher((
void *)priv->
tfm);
97 static void ieee80211_ccmp_deinit(
void *priv)
101 if (_priv && _priv->
tfm)
102 crypto_free_cipher((
void *)_priv->
tfm);
107 static inline void xor_block(
u8 *
b,
u8 *
a,
size_t len)
110 for (i = 0; i < len; i++)
122 int a4_included, qc_included;
154 b0[14] = (dlen >> 8) & 0xff;
155 b0[15] = dlen & 0xff;
166 aad[1] = aad_len & 0xff;
167 aad[2] = pos[0] & 0x8f;
168 aad[3] = pos[1] & 0xc7;
171 aad[22] = pos[0] & 0x0f;
177 aad[a4_included ? 30 : 24] = qc;
198 int blocks,
last, len;
219 if (key->
tx_pn[i] != 0)
224 *pos++ = key->
tx_pn[5];
225 *pos++ = key->
tx_pn[4];
227 *pos++ = (key->
key_idx << 6) | (1 << 5) ;
228 *pos++ = key->
tx_pn[3];
229 *pos++ = key->
tx_pn[2];
230 *pos++ = key->
tx_pn[1];
231 *pos++ = key->
tx_pn[0];
237 ccmp_init_blocks(key->
tfm, hdr, key->
tx_pn, data_len, b0, b, s0);
242 for (i = 1; i <= blocks; i++) {
245 xor_block(b, pos, len);
248 b0[14] = (i >> 8) & 0xff;
251 xor_block(pos, e, len);
256 mic[i] = b[i] ^ s0[i];
262 static int ieee80211_ccmp_decrypt(
struct sk_buff *skb,
int hdr_len,
void *priv)
273 int i, blocks, last, len;
281 pos = skb->
data + hdr_len;
283 if (!(keyidx & (1 << 5))) {
286 " flag from %pM\n", hdr->
addr2);
294 "keyidx=%d priv=%p\n", key->
key_idx, keyidx, priv);
300 " with keyid=%d that does not have a configured"
301 " key\n", hdr->
addr2, keyidx);
317 " previous PN %pm received PN %pm\n",
324 ccmp_init_blocks(key->
tfm, hdr, pn, data_len, b0, a, b);
325 xor_block(mic, b, CCMP_MIC_LEN);
330 for (i = 1; i <= blocks; i++) {
333 b0[14] = (i >> 8) & 0xff;
336 xor_block(pos, b, len);
338 xor_block(a, pos, len);
343 if (
memcmp(mic, a, CCMP_MIC_LEN) != 0) {
346 "%pM\n", hdr->
addr2);
363 static int ieee80211_ccmp_set_key(
void *key,
int len,
u8 *seq,
void *priv)
370 memset(data, 0,
sizeof(*data));
377 data->
rx_pn[0] = seq[5];
378 data->
rx_pn[1] = seq[4];
379 data->
rx_pn[2] = seq[3];
380 data->
rx_pn[3] = seq[2];
381 data->
rx_pn[4] = seq[1];
382 data->
rx_pn[5] = seq[0];
394 static int ieee80211_ccmp_get_key(
void *key,
int len,
u8 *seq,
void *priv)
406 seq[0] = data->
tx_pn[5];
407 seq[1] = data->
tx_pn[4];
408 seq[2] = data->
tx_pn[3];
409 seq[3] = data->
tx_pn[2];
410 seq[4] = data->
tx_pn[1];
411 seq[5] = data->
tx_pn[0];
418 static char * ieee80211_ccmp_print_stats(
char *
p,
void *priv)
421 p +=
sprintf(p,
"key[%d] alg=CCMP key_set=%d "
422 "tx_pn=%pm rx_pn=%pm "
423 "format_errors=%d replays=%d decrypt_errors=%d\n",
440 .init = ieee80211_ccmp_init,
441 .deinit = ieee80211_ccmp_deinit,
442 .encrypt_mpdu = ieee80211_ccmp_encrypt,
443 .decrypt_mpdu = ieee80211_ccmp_decrypt,
444 .encrypt_msdu =
NULL,
445 .decrypt_msdu =
NULL,
446 .set_key = ieee80211_ccmp_set_key,
447 .get_key = ieee80211_ccmp_get_key,
448 .print_stats = ieee80211_ccmp_print_stats,