13 #include <linux/kernel.h>
15 #include <linux/module.h>
17 #include <linux/slab.h>
18 #include <linux/random.h>
20 #include <linux/netdevice.h>
21 #include <linux/if_ether.h>
22 #include <linux/if_arp.h>
23 #include <asm/string.h>
24 #include <linux/wireless.h>
36 #define AES_BLOCK_LEN 16
37 #define CCMP_HDR_LEN 8
38 #define CCMP_MIC_LEN 8
39 #define CCMP_TK_LEN 16
63 static inline void lib80211_ccmp_aes_encrypt(
struct crypto_cipher *tfm,
64 const u8 pt[16],
u8 ct[16])
66 crypto_cipher_encrypt_one(tfm, ct, pt);
69 static void *lib80211_ccmp_init(
int key_idx)
79 if (IS_ERR(priv->
tfm)) {
89 crypto_free_cipher(priv->
tfm);
96 static void lib80211_ccmp_deinit(
void *priv)
99 if (_priv && _priv->
tfm)
100 crypto_free_cipher(_priv->
tfm);
104 static inline void xor_block(
u8 *
b,
u8 *
a,
size_t len)
107 for (i = 0; i < len; i++)
117 int a4_included, qc_included;
143 b0[14] = (dlen >> 8) & 0xff;
144 b0[15] = dlen & 0xff;
155 aad[1] = aad_len & 0xff;
156 aad[2] = pos[0] & 0x8f;
157 aad[3] = pos[1] & 0xc7;
160 aad[22] = pos[0] & 0x0f;
166 aad[a4_included ? 30 : 24] = qc;
171 lib80211_ccmp_aes_encrypt(tfm, b0, auth);
173 lib80211_ccmp_aes_encrypt(tfm, auth, auth);
175 lib80211_ccmp_aes_encrypt(tfm, auth, auth);
178 lib80211_ccmp_aes_encrypt(tfm, b0, s0);
182 u8 *aeskey,
int keylen,
void *priv)
201 if (key->
tx_pn[i] != 0)
206 *pos++ = key->
tx_pn[5];
207 *pos++ = key->
tx_pn[4];
209 *pos++ = (key->
key_idx << 6) | (1 << 5) ;
210 *pos++ = key->
tx_pn[3];
211 *pos++ = key->
tx_pn[2];
212 *pos++ = key->
tx_pn[1];
213 *pos++ = key->
tx_pn[0];
218 static int lib80211_ccmp_encrypt(
struct sk_buff *skb,
int hdr_len,
void *priv)
233 len = lib80211_ccmp_hdr(skb, hdr_len,
NULL, 0, priv);
239 ccmp_init_blocks(key->
tfm, hdr, key->
tx_pn, data_len, b0, b, s0);
244 for (i = 1; i <= blocks; i++) {
247 xor_block(b, pos, len);
248 lib80211_ccmp_aes_encrypt(key->
tfm, b, b);
250 b0[14] = (i >> 8) & 0xff;
252 lib80211_ccmp_aes_encrypt(key->
tfm, b0, e);
253 xor_block(pos, e, len);
259 mic[i] = b[i] ^ s0[i];
268 static inline int ccmp_replay_check(
u8 *pn_n,
u8 *pn_o)
273 iv32_n = (pn_n[0] << 24) | (pn_n[1] << 16) | (pn_n[2] << 8) | pn_n[3];
274 iv16_n = (pn_n[4] << 8) | pn_n[5];
276 iv32_o = (pn_o[0] << 24) | (pn_o[1] << 16) | (pn_o[2] << 8) | pn_o[3];
277 iv16_o = (pn_o[4] << 8) | pn_o[5];
279 if ((
s32)iv32_n - (
s32)iv32_o < 0 ||
280 (iv32_n == iv32_o && iv16_n <= iv16_o))
285 static int lib80211_ccmp_decrypt(
struct sk_buff *skb,
int hdr_len,
void *priv)
294 int i, blocks, last, len;
298 if (skb->
len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
304 pos = skb->
data + hdr_len;
306 if (!(keyidx & (1 << 5))) {
315 "keyidx=%d priv=%p\n", key->
key_idx, keyidx, priv);
319 net_dbg_ratelimited(
"CCMP: received packet from %pM with keyid=%d that does not have a configured key\n",
332 if (ccmp_replay_check(pn, key->
rx_pn)) {
333 #ifdef CONFIG_LIB80211_DEBUG
334 net_dbg_ratelimited(
"CCMP: replay detected: STA=%pM previous PN %02x%02x%02x%02x%02x%02x received PN %02x%02x%02x%02x%02x%02x\n",
338 pn[0], pn[1], pn[2], pn[3], pn[4], pn[5]);
344 ccmp_init_blocks(key->
tfm, hdr, pn, data_len, b0, a, b);
345 xor_block(mic, b, CCMP_MIC_LEN);
350 for (i = 1; i <= blocks; i++) {
353 b0[14] = (i >> 8) & 0xff;
355 lib80211_ccmp_aes_encrypt(key->
tfm, b0, b);
356 xor_block(pos, b, len);
358 xor_block(a, pos, len);
359 lib80211_ccmp_aes_encrypt(key->
tfm, a, a);
363 if (
memcmp(mic, a, CCMP_MIC_LEN) != 0) {
380 static int lib80211_ccmp_set_key(
void *key,
int len,
u8 * seq,
void *priv)
387 memset(data, 0,
sizeof(*data));
394 data->
rx_pn[0] = seq[5];
395 data->
rx_pn[1] = seq[4];
396 data->
rx_pn[2] = seq[3];
397 data->
rx_pn[3] = seq[2];
398 data->
rx_pn[4] = seq[1];
399 data->
rx_pn[5] = seq[0];
410 static int lib80211_ccmp_get_key(
void *key,
int len,
u8 * seq,
void *priv)
422 seq[0] = data->
tx_pn[5];
423 seq[1] = data->
tx_pn[4];
424 seq[2] = data->
tx_pn[3];
425 seq[3] = data->
tx_pn[2];
426 seq[4] = data->
tx_pn[1];
427 seq[5] = data->
tx_pn[0];
433 static char *lib80211_ccmp_print_stats(
char *
p,
void *priv)
437 p +=
sprintf(p,
"key[%d] alg=CCMP key_set=%d "
438 "tx_pn=%02x%02x%02x%02x%02x%02x "
439 "rx_pn=%02x%02x%02x%02x%02x%02x "
440 "format_errors=%d replays=%d decrypt_errors=%d\n",
455 .init = lib80211_ccmp_init,
456 .deinit = lib80211_ccmp_deinit,
457 .encrypt_mpdu = lib80211_ccmp_encrypt,
458 .decrypt_mpdu = lib80211_ccmp_decrypt,
459 .encrypt_msdu =
NULL,
460 .decrypt_msdu =
NULL,
461 .set_key = lib80211_ccmp_set_key,
462 .get_key = lib80211_ccmp_get_key,
463 .print_stats = lib80211_ccmp_print_stats,
469 static int __init lib80211_crypto_ccmp_init(
void)
474 static void __exit lib80211_crypto_ccmp_exit(
void)