12 #include <linux/module.h>
14 #include <linux/slab.h>
15 #include <linux/random.h>
17 #include <linux/netdevice.h>
18 #include <linux/if_ether.h>
19 #include <linux/if_arp.h>
20 #include <linux/string.h>
21 #include <linux/wireless.h>
28 #define AES_BLOCK_LEN 16
29 #define CCMP_HDR_LEN 8
30 #define CCMP_MIC_LEN 8
31 #define CCMP_TK_LEN 16
55 static void rtllib_ccmp_aes_encrypt(
struct crypto_tfm *tfm,
56 const u8 pt[16],
u8 ct[16])
58 crypto_cipher_encrypt_one((
void *)tfm, ct, pt);
61 static void *rtllib_ccmp_init(
int key_idx)
71 if (IS_ERR(priv->
tfm)) {
82 crypto_free_cipher((
void *)priv->
tfm);
90 static void rtllib_ccmp_deinit(
void *priv)
93 if (_priv && _priv->
tfm)
94 crypto_free_cipher((
void *)_priv->
tfm);
99 static inline void xor_block(
u8 *
b,
u8 *
a,
size_t len)
102 for (i = 0; i < len; i++)
116 int a4_included, qc_included;
147 b0[14] = (dlen >> 8) & 0xff;
148 b0[15] = dlen & 0xff;
159 aad[1] = aad_len & 0xff;
160 aad[2] = pos[0] & 0x8f;
161 aad[3] = pos[1] & 0xc7;
164 aad[22] = pos[0] & 0x0f;
170 aad[a4_included ? 30 : 24] = qc;
175 rtllib_ccmp_aes_encrypt(tfm, b0, auth);
177 rtllib_ccmp_aes_encrypt(tfm, auth, auth);
179 rtllib_ccmp_aes_encrypt(tfm, auth, auth);
182 rtllib_ccmp_aes_encrypt(tfm, b0, s0);
208 if (key->
tx_pn[i] != 0)
213 *pos++ = key->
tx_pn[5];
214 *pos++ = key->
tx_pn[4];
216 *pos++ = (key->
key_idx << 6) | (1 << 5) ;
217 *pos++ = key->
tx_pn[3];
218 *pos++ = key->
tx_pn[2];
219 *pos++ = key->
tx_pn[1];
220 *pos++ = key->
tx_pn[0];
225 int blocks,
last, len;
234 ccmp_init_blocks(key->
tfm, hdr, key->
tx_pn, data_len,
240 for (i = 1; i <= blocks; i++) {
243 xor_block(b, pos, len);
244 rtllib_ccmp_aes_encrypt(key->
tfm, b, b);
246 b0[14] = (i >> 8) & 0xff;
248 rtllib_ccmp_aes_encrypt(key->
tfm, b0, e);
249 xor_block(pos, e, len);
254 mic[i] = b[i] ^ s0[i];
260 static int rtllib_ccmp_decrypt(
struct sk_buff *skb,
int hdr_len,
void *priv)
275 pos = skb->
data + hdr_len;
277 if (!(keyidx & (1 << 5))) {
280 " flag from %pM\n", hdr->
addr2);
288 "keyidx=%d priv=%p\n", key->
key_idx, keyidx, priv);
294 " with keyid=%d that does not have a configured"
295 " key\n", hdr->
addr2, keyidx);
318 int i, blocks, last, len;
321 ccmp_init_blocks(key->
tfm, hdr, pn, data_len, b0, a, b);
322 xor_block(mic, b, CCMP_MIC_LEN);
327 for (i = 1; i <= blocks; i++) {
330 b0[14] = (i >> 8) & 0xff;
332 rtllib_ccmp_aes_encrypt(key->
tfm, b0, b);
333 xor_block(pos, b, len);
335 xor_block(a, pos, len);
336 rtllib_ccmp_aes_encrypt(key->
tfm, a, a);
340 if (
memcmp(mic, a, CCMP_MIC_LEN) != 0) {
343 " %pM\n", hdr->
addr2);
360 static int rtllib_ccmp_set_key(
void *key,
int len,
u8 *seq,
void *priv)
367 memset(data, 0,
sizeof(*data));
374 data->
rx_pn[0] = seq[5];
375 data->
rx_pn[1] = seq[4];
376 data->
rx_pn[2] = seq[3];
377 data->
rx_pn[3] = seq[2];
378 data->
rx_pn[4] = seq[1];
379 data->
rx_pn[5] = seq[0];
391 static int rtllib_ccmp_get_key(
void *key,
int len,
u8 *seq,
void *priv)
403 seq[0] = data->
tx_pn[5];
404 seq[1] = data->
tx_pn[4];
405 seq[2] = data->
tx_pn[3];
406 seq[3] = data->
tx_pn[2];
407 seq[4] = data->
tx_pn[1];
408 seq[5] = data->
tx_pn[0];
415 static char *rtllib_ccmp_print_stats(
char *
p,
void *priv)
418 p +=
sprintf(p,
"key[%d] alg=CCMP key_set=%d "
419 "tx_pn=%pM rx_pn=%pM "
420 "format_errors=%d replays=%d decrypt_errors=%d\n",
432 .init = rtllib_ccmp_init,
433 .deinit = rtllib_ccmp_deinit,
434 .encrypt_mpdu = rtllib_ccmp_encrypt,
435 .decrypt_mpdu = rtllib_ccmp_decrypt,
436 .encrypt_msdu =
NULL,
437 .decrypt_msdu =
NULL,
438 .set_key = rtllib_ccmp_set_key,
439 .get_key = rtllib_ccmp_get_key,
440 .print_stats = rtllib_ccmp_print_stats,