1 // SPDX-License-Identifier: GPL-2.0-only
3 * lib80211 crypt: host-based CCMP encryption implementation for lib80211
5 * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
6 * Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
9 #include <linux/kernel.h>
10 #include <linux/err.h>
11 #include <linux/module.h>
12 #include <linux/init.h>
13 #include <linux/slab.h>
14 #include <linux/random.h>
15 #include <linux/skbuff.h>
16 #include <linux/netdevice.h>
17 #include <linux/if_ether.h>
18 #include <linux/if_arp.h>
19 #include <asm/string.h>
20 #include <linux/wireless.h>
22 #include <linux/ieee80211.h>
24 #include <linux/crypto.h>
25 #include <crypto/aead.h>
27 #include <net/lib80211.h>
29 MODULE_AUTHOR("Jouni Malinen");
30 MODULE_DESCRIPTION("Host AP crypt: CCMP");
31 MODULE_LICENSE("GPL");
33 #define AES_BLOCK_LEN 16
34 #define CCMP_HDR_LEN 8
35 #define CCMP_MIC_LEN 8
36 #define CCMP_TK_LEN 16
39 struct lib80211_ccmp_data
{
43 u8 tx_pn
[CCMP_PN_LEN
];
44 u8 rx_pn
[CCMP_PN_LEN
];
46 u32 dot11RSNAStatsCCMPFormatErrors
;
47 u32 dot11RSNAStatsCCMPReplays
;
48 u32 dot11RSNAStatsCCMPDecryptErrors
;
52 struct crypto_aead
*tfm
;
54 /* scratch buffers for virt_to_page() (crypto API) */
55 u8 tx_aad
[2 * AES_BLOCK_LEN
];
56 u8 rx_aad
[2 * AES_BLOCK_LEN
];
59 static void *lib80211_ccmp_init(int key_idx
)
61 struct lib80211_ccmp_data
*priv
;
63 priv
= kzalloc(sizeof(*priv
), GFP_ATOMIC
);
66 priv
->key_idx
= key_idx
;
68 priv
->tfm
= crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC
);
69 if (IS_ERR(priv
->tfm
)) {
79 crypto_free_aead(priv
->tfm
);
86 static void lib80211_ccmp_deinit(void *priv
)
88 struct lib80211_ccmp_data
*_priv
= priv
;
89 if (_priv
&& _priv
->tfm
)
90 crypto_free_aead(_priv
->tfm
);
94 static int ccmp_init_iv_and_aad(const struct ieee80211_hdr
*hdr
,
95 const u8
*pn
, u8
*iv
, u8
*aad
)
99 int a4_included
, qc_included
;
101 a4_included
= ieee80211_has_a4(hdr
->frame_control
);
102 qc_included
= ieee80211_is_data_qos(hdr
->frame_control
);
108 pos
= (u8
*) & hdr
->addr4
;
115 /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
116 * mode authentication are not allowed to collide, yet both are derived
117 * from the same vector. We only set L := 1 here to indicate that the
118 * data size can be represented in (L+1) bytes. The CCM layer will take
119 * care of storing the data length in the top (L+1) bytes and setting
120 * and clearing the other bits as is required to derive the two IVs.
124 /* Nonce: QC | A2 | PN */
126 memcpy(iv
+ 2, hdr
->addr2
, ETH_ALEN
);
127 memcpy(iv
+ 8, pn
, CCMP_PN_LEN
);
130 * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
132 * SC with bits 4..15 (seq#) masked to zero
137 aad
[0] = pos
[0] & 0x8f;
138 aad
[1] = pos
[1] & 0xc7;
139 memcpy(aad
+ 2, hdr
->addr1
, 3 * ETH_ALEN
);
140 pos
= (u8
*) & hdr
->seq_ctrl
;
141 aad
[20] = pos
[0] & 0x0f;
142 aad
[21] = 0; /* all bits masked */
143 memset(aad
+ 22, 0, 8);
145 memcpy(aad
+ 22, hdr
->addr4
, ETH_ALEN
);
147 aad
[a4_included
? 28 : 22] = qc
;
148 /* rest of QC masked */
153 static int lib80211_ccmp_hdr(struct sk_buff
*skb
, int hdr_len
,
154 u8
*aeskey
, int keylen
, void *priv
)
156 struct lib80211_ccmp_data
*key
= priv
;
160 if (skb_headroom(skb
) < CCMP_HDR_LEN
|| skb
->len
< hdr_len
)
163 if (aeskey
!= NULL
&& keylen
>= CCMP_TK_LEN
)
164 memcpy(aeskey
, key
->key
, CCMP_TK_LEN
);
166 pos
= skb_push(skb
, CCMP_HDR_LEN
);
167 memmove(pos
, pos
+ CCMP_HDR_LEN
, hdr_len
);
173 if (key
->tx_pn
[i
] != 0)
178 *pos
++ = key
->tx_pn
[5];
179 *pos
++ = key
->tx_pn
[4];
181 *pos
++ = (key
->key_idx
<< 6) | (1 << 5) /* Ext IV included */ ;
182 *pos
++ = key
->tx_pn
[3];
183 *pos
++ = key
->tx_pn
[2];
184 *pos
++ = key
->tx_pn
[1];
185 *pos
++ = key
->tx_pn
[0];
190 static int lib80211_ccmp_encrypt(struct sk_buff
*skb
, int hdr_len
, void *priv
)
192 struct lib80211_ccmp_data
*key
= priv
;
193 struct ieee80211_hdr
*hdr
;
194 struct aead_request
*req
;
195 struct scatterlist sg
[2];
196 u8
*aad
= key
->tx_aad
;
197 u8 iv
[AES_BLOCK_LEN
];
198 int len
, data_len
, aad_len
;
201 if (skb_tailroom(skb
) < CCMP_MIC_LEN
|| skb
->len
< hdr_len
)
204 data_len
= skb
->len
- hdr_len
;
205 len
= lib80211_ccmp_hdr(skb
, hdr_len
, NULL
, 0, priv
);
209 req
= aead_request_alloc(key
->tfm
, GFP_ATOMIC
);
213 hdr
= (struct ieee80211_hdr
*)skb
->data
;
214 aad_len
= ccmp_init_iv_and_aad(hdr
, key
->tx_pn
, iv
, aad
);
216 skb_put(skb
, CCMP_MIC_LEN
);
218 sg_init_table(sg
, 2);
219 sg_set_buf(&sg
[0], aad
, aad_len
);
220 sg_set_buf(&sg
[1], skb
->data
+ hdr_len
+ CCMP_HDR_LEN
,
221 data_len
+ CCMP_MIC_LEN
);
223 aead_request_set_callback(req
, 0, NULL
, NULL
);
224 aead_request_set_ad(req
, aad_len
);
225 aead_request_set_crypt(req
, sg
, sg
, data_len
, iv
);
227 ret
= crypto_aead_encrypt(req
);
228 aead_request_free(req
);
234 * deal with seq counter wrapping correctly.
235 * refer to timer_after() for jiffies wrapping handling
237 static inline int ccmp_replay_check(u8
*pn_n
, u8
*pn_o
)
242 iv32_n
= (pn_n
[0] << 24) | (pn_n
[1] << 16) | (pn_n
[2] << 8) | pn_n
[3];
243 iv16_n
= (pn_n
[4] << 8) | pn_n
[5];
245 iv32_o
= (pn_o
[0] << 24) | (pn_o
[1] << 16) | (pn_o
[2] << 8) | pn_o
[3];
246 iv16_o
= (pn_o
[4] << 8) | pn_o
[5];
248 if ((s32
)iv32_n
- (s32
)iv32_o
< 0 ||
249 (iv32_n
== iv32_o
&& iv16_n
<= iv16_o
))
254 static int lib80211_ccmp_decrypt(struct sk_buff
*skb
, int hdr_len
, void *priv
)
256 struct lib80211_ccmp_data
*key
= priv
;
258 struct ieee80211_hdr
*hdr
;
259 struct aead_request
*req
;
260 struct scatterlist sg
[2];
261 u8
*aad
= key
->rx_aad
;
262 u8 iv
[AES_BLOCK_LEN
];
265 size_t data_len
= skb
->len
- hdr_len
- CCMP_HDR_LEN
;
267 if (skb
->len
< hdr_len
+ CCMP_HDR_LEN
+ CCMP_MIC_LEN
) {
268 key
->dot11RSNAStatsCCMPFormatErrors
++;
272 hdr
= (struct ieee80211_hdr
*)skb
->data
;
273 pos
= skb
->data
+ hdr_len
;
275 if (!(keyidx
& (1 << 5))) {
276 net_dbg_ratelimited("CCMP: received packet without ExtIV flag from %pM\n",
278 key
->dot11RSNAStatsCCMPFormatErrors
++;
282 if (key
->key_idx
!= keyidx
) {
283 net_dbg_ratelimited("CCMP: RX tkey->key_idx=%d frame keyidx=%d\n",
284 key
->key_idx
, keyidx
);
288 net_dbg_ratelimited("CCMP: received packet from %pM with keyid=%d that does not have a configured key\n",
301 if (ccmp_replay_check(pn
, key
->rx_pn
)) {
302 #ifdef CONFIG_LIB80211_DEBUG
303 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",
305 key
->rx_pn
[0], key
->rx_pn
[1], key
->rx_pn
[2],
306 key
->rx_pn
[3], key
->rx_pn
[4], key
->rx_pn
[5],
307 pn
[0], pn
[1], pn
[2], pn
[3], pn
[4], pn
[5]);
309 key
->dot11RSNAStatsCCMPReplays
++;
313 req
= aead_request_alloc(key
->tfm
, GFP_ATOMIC
);
317 aad_len
= ccmp_init_iv_and_aad(hdr
, pn
, iv
, aad
);
319 sg_init_table(sg
, 2);
320 sg_set_buf(&sg
[0], aad
, aad_len
);
321 sg_set_buf(&sg
[1], pos
, data_len
);
323 aead_request_set_callback(req
, 0, NULL
, NULL
);
324 aead_request_set_ad(req
, aad_len
);
325 aead_request_set_crypt(req
, sg
, sg
, data_len
, iv
);
327 ret
= crypto_aead_decrypt(req
);
328 aead_request_free(req
);
331 net_dbg_ratelimited("CCMP: decrypt failed: STA=%pM (%d)\n",
333 key
->dot11RSNAStatsCCMPDecryptErrors
++;
337 memcpy(key
->rx_pn
, pn
, CCMP_PN_LEN
);
339 /* Remove hdr and MIC */
340 memmove(skb
->data
+ CCMP_HDR_LEN
, skb
->data
, hdr_len
);
341 skb_pull(skb
, CCMP_HDR_LEN
);
342 skb_trim(skb
, skb
->len
- CCMP_MIC_LEN
);
347 static int lib80211_ccmp_set_key(void *key
, int len
, u8
* seq
, void *priv
)
349 struct lib80211_ccmp_data
*data
= priv
;
351 struct crypto_aead
*tfm
= data
->tfm
;
353 keyidx
= data
->key_idx
;
354 memset(data
, 0, sizeof(*data
));
355 data
->key_idx
= keyidx
;
357 if (len
== CCMP_TK_LEN
) {
358 memcpy(data
->key
, key
, CCMP_TK_LEN
);
361 data
->rx_pn
[0] = seq
[5];
362 data
->rx_pn
[1] = seq
[4];
363 data
->rx_pn
[2] = seq
[3];
364 data
->rx_pn
[3] = seq
[2];
365 data
->rx_pn
[4] = seq
[1];
366 data
->rx_pn
[5] = seq
[0];
368 if (crypto_aead_setauthsize(data
->tfm
, CCMP_MIC_LEN
) ||
369 crypto_aead_setkey(data
->tfm
, data
->key
, CCMP_TK_LEN
))
379 static int lib80211_ccmp_get_key(void *key
, int len
, u8
* seq
, void *priv
)
381 struct lib80211_ccmp_data
*data
= priv
;
383 if (len
< CCMP_TK_LEN
)
388 memcpy(key
, data
->key
, CCMP_TK_LEN
);
391 seq
[0] = data
->tx_pn
[5];
392 seq
[1] = data
->tx_pn
[4];
393 seq
[2] = data
->tx_pn
[3];
394 seq
[3] = data
->tx_pn
[2];
395 seq
[4] = data
->tx_pn
[1];
396 seq
[5] = data
->tx_pn
[0];
402 static void lib80211_ccmp_print_stats(struct seq_file
*m
, void *priv
)
404 struct lib80211_ccmp_data
*ccmp
= priv
;
407 "key[%d] alg=CCMP key_set=%d "
408 "tx_pn=%02x%02x%02x%02x%02x%02x "
409 "rx_pn=%02x%02x%02x%02x%02x%02x "
410 "format_errors=%d replays=%d decrypt_errors=%d\n",
411 ccmp
->key_idx
, ccmp
->key_set
,
412 ccmp
->tx_pn
[0], ccmp
->tx_pn
[1], ccmp
->tx_pn
[2],
413 ccmp
->tx_pn
[3], ccmp
->tx_pn
[4], ccmp
->tx_pn
[5],
414 ccmp
->rx_pn
[0], ccmp
->rx_pn
[1], ccmp
->rx_pn
[2],
415 ccmp
->rx_pn
[3], ccmp
->rx_pn
[4], ccmp
->rx_pn
[5],
416 ccmp
->dot11RSNAStatsCCMPFormatErrors
,
417 ccmp
->dot11RSNAStatsCCMPReplays
,
418 ccmp
->dot11RSNAStatsCCMPDecryptErrors
);
421 static struct lib80211_crypto_ops lib80211_crypt_ccmp
= {
423 .init
= lib80211_ccmp_init
,
424 .deinit
= lib80211_ccmp_deinit
,
425 .encrypt_mpdu
= lib80211_ccmp_encrypt
,
426 .decrypt_mpdu
= lib80211_ccmp_decrypt
,
427 .encrypt_msdu
= NULL
,
428 .decrypt_msdu
= NULL
,
429 .set_key
= lib80211_ccmp_set_key
,
430 .get_key
= lib80211_ccmp_get_key
,
431 .print_stats
= lib80211_ccmp_print_stats
,
432 .extra_mpdu_prefix_len
= CCMP_HDR_LEN
,
433 .extra_mpdu_postfix_len
= CCMP_MIC_LEN
,
434 .owner
= THIS_MODULE
,
437 static int __init
lib80211_crypto_ccmp_init(void)
439 return lib80211_register_crypto_ops(&lib80211_crypt_ccmp
);
442 static void __exit
lib80211_crypto_ccmp_exit(void)
444 lib80211_unregister_crypto_ops(&lib80211_crypt_ccmp
);
447 module_init(lib80211_crypto_ccmp_init
);
448 module_exit(lib80211_crypto_ccmp_exit
);