1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Host AP crypt: host-based CCMP encryption implementation for Host AP driver 4 * 5 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi> 6 */ 7 8 #include <linux/module.h> 9 #include <linux/init.h> 10 #include <linux/slab.h> 11 #include <linux/random.h> 12 #include <linux/skbuff.h> 13 #include <linux/netdevice.h> 14 #include <linux/if_ether.h> 15 #include <linux/if_arp.h> 16 #include <linux/string.h> 17 #include <linux/wireless.h> 18 19 #include "ieee80211.h" 20 21 #include <linux/crypto.h> 22 #include <crypto/aead.h> 23 #include <linux/scatterlist.h> 24 25 MODULE_AUTHOR("Jouni Malinen"); 26 MODULE_DESCRIPTION("Host AP crypt: CCMP"); 27 MODULE_LICENSE("GPL"); 28 29 #define AES_BLOCK_LEN 16 30 #define CCMP_HDR_LEN 8 31 #define CCMP_MIC_LEN 8 32 #define CCMP_TK_LEN 16 33 #define CCMP_PN_LEN 6 34 35 struct ieee80211_ccmp_data { 36 u8 key[CCMP_TK_LEN]; 37 int key_set; 38 39 u8 tx_pn[CCMP_PN_LEN]; 40 u8 rx_pn[CCMP_PN_LEN]; 41 42 u32 dot11RSNAStatsCCMPFormatErrors; 43 u32 dot11RSNAStatsCCMPReplays; 44 u32 dot11RSNAStatsCCMPDecryptErrors; 45 46 int key_idx; 47 48 struct crypto_aead *tfm; 49 50 /* scratch buffers for virt_to_page() (crypto API) */ 51 u8 tx_aad[2 * AES_BLOCK_LEN]; 52 u8 rx_aad[2 * AES_BLOCK_LEN]; 53 }; 54 55 static void *ieee80211_ccmp_init(int key_idx) 56 { 57 struct ieee80211_ccmp_data *priv; 58 59 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 60 if (!priv) 61 goto fail; 62 priv->key_idx = key_idx; 63 64 priv->tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC); 65 if (IS_ERR(priv->tfm)) { 66 pr_debug("ieee80211_crypt_ccmp: could not allocate crypto API aes\n"); 67 priv->tfm = NULL; 68 goto fail; 69 } 70 71 return priv; 72 73 fail: 74 if (priv) { 75 if (priv->tfm) 76 crypto_free_aead(priv->tfm); 77 kfree(priv); 78 } 79 80 return NULL; 81 } 82 83 static void ieee80211_ccmp_deinit(void *priv) 84 { 85 struct ieee80211_ccmp_data *_priv = priv; 86 87 if (_priv && _priv->tfm) 88 crypto_free_aead(_priv->tfm); 89 kfree(priv); 90 } 91 92 static int ccmp_init_iv_and_aad(struct rtl_80211_hdr_4addr *hdr, 93 u8 *pn, u8 *iv, u8 *aad) 94 { 95 u8 *pos, qc = 0; 96 size_t aad_len; 97 u16 fc; 98 int a4_included, qc_included; 99 100 fc = le16_to_cpu(hdr->frame_ctl); 101 a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == 102 (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)); 103 /* qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) && 104 * (WLAN_FC_GET_STYPE(fc) & 0x08)); 105 */ 106 /* fixed by David :2006.9.6 */ 107 qc_included = (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) && 108 (WLAN_FC_GET_STYPE(fc) & 0x80); 109 aad_len = 22; 110 if (a4_included) 111 aad_len += 6; 112 if (qc_included) { 113 pos = (u8 *)&hdr->addr4; 114 if (a4_included) 115 pos += 6; 116 qc = *pos & 0x0f; 117 aad_len += 2; 118 } 119 120 /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC 121 * mode authentication are not allowed to collide, yet both are derived 122 * from the same vector. We only set L := 1 here to indicate that the 123 * data size can be represented in (L+1) bytes. The CCM layer will take 124 * care of storing the data length in the top (L+1) bytes and setting 125 * and clearing the other bits as is required to derive the two IVs. 126 */ 127 iv[0] = 0x1; 128 129 /* Nonce: QC | A2 | PN */ 130 iv[1] = qc; 131 memcpy(iv + 2, hdr->addr2, ETH_ALEN); 132 memcpy(iv + 8, pn, CCMP_PN_LEN); 133 134 /* AAD: 135 * FC with bits 4..6 and 11..13 masked to zero; 14 is always one 136 * A1 | A2 | A3 137 * SC with bits 4..15 (seq#) masked to zero 138 * A4 (if present) 139 * QC (if present) 140 */ 141 pos = (u8 *)hdr; 142 aad[0] = pos[0] & 0x8f; 143 aad[1] = pos[1] & 0xc7; 144 memcpy(&aad[2], &hdr->addr1, ETH_ALEN); 145 memcpy(&aad[8], &hdr->addr2, ETH_ALEN); 146 memcpy(&aad[14], &hdr->addr3, ETH_ALEN); 147 pos = (u8 *)&hdr->seq_ctl; 148 aad[20] = pos[0] & 0x0f; 149 aad[21] = 0; /* all bits masked */ 150 memset(aad + 22, 0, 8); 151 if (a4_included) 152 memcpy(aad + 22, hdr->addr4, ETH_ALEN); 153 if (qc_included) { 154 aad[a4_included ? 28 : 22] = qc; 155 /* rest of QC masked */ 156 } 157 158 return aad_len; 159 } 160 161 static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) 162 { 163 struct ieee80211_ccmp_data *key = priv; 164 int i; 165 u8 *pos; 166 struct rtl_80211_hdr_4addr *hdr; 167 struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); 168 169 if (skb_headroom(skb) < CCMP_HDR_LEN || 170 skb_tailroom(skb) < CCMP_MIC_LEN || 171 skb->len < hdr_len) 172 return -1; 173 174 pos = skb_push(skb, CCMP_HDR_LEN); 175 memmove(pos, pos + CCMP_HDR_LEN, hdr_len); 176 pos += hdr_len; 177 /* mic = skb_put(skb, CCMP_MIC_LEN); */ 178 179 i = CCMP_PN_LEN - 1; 180 while (i >= 0) { 181 key->tx_pn[i]++; 182 if (key->tx_pn[i] != 0) 183 break; 184 i--; 185 } 186 187 *pos++ = key->tx_pn[5]; 188 *pos++ = key->tx_pn[4]; 189 *pos++ = 0; 190 *pos++ = (key->key_idx << 6) | BIT(5) /* Ext IV included */; 191 *pos++ = key->tx_pn[3]; 192 *pos++ = key->tx_pn[2]; 193 *pos++ = key->tx_pn[1]; 194 *pos++ = key->tx_pn[0]; 195 196 hdr = (struct rtl_80211_hdr_4addr *)skb->data; 197 if (!tcb_desc->bHwSec) { 198 struct aead_request *req; 199 struct scatterlist sg[2]; 200 u8 *aad = key->tx_aad; 201 u8 iv[AES_BLOCK_LEN]; 202 int aad_len, ret; 203 size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN; 204 205 req = aead_request_alloc(key->tfm, GFP_ATOMIC); 206 if (!req) 207 return -ENOMEM; 208 209 aad_len = ccmp_init_iv_and_aad(hdr, key->tx_pn, iv, aad); 210 211 skb_put(skb, CCMP_MIC_LEN); 212 213 sg_init_table(sg, 2); 214 sg_set_buf(&sg[0], aad, aad_len); 215 sg_set_buf(&sg[1], skb->data + hdr_len + CCMP_HDR_LEN, 216 data_len + CCMP_MIC_LEN); 217 218 aead_request_set_callback(req, 0, NULL, NULL); 219 aead_request_set_ad(req, aad_len); 220 aead_request_set_crypt(req, sg, sg, data_len, iv); 221 222 ret = crypto_aead_encrypt(req); 223 aead_request_free(req); 224 225 return ret; 226 } 227 return 0; 228 } 229 230 static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) 231 { 232 struct ieee80211_ccmp_data *key = priv; 233 u8 keyidx, *pos; 234 struct rtl_80211_hdr_4addr *hdr; 235 struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); 236 u8 pn[6]; 237 238 if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) { 239 key->dot11RSNAStatsCCMPFormatErrors++; 240 return -1; 241 } 242 243 hdr = (struct rtl_80211_hdr_4addr *)skb->data; 244 pos = skb->data + hdr_len; 245 keyidx = pos[3]; 246 if (!(keyidx & BIT(5))) { 247 if (net_ratelimit()) { 248 netdev_dbg(skb->dev, "CCMP: received packet without ExtIV flag from %pM\n", 249 hdr->addr2); 250 } 251 key->dot11RSNAStatsCCMPFormatErrors++; 252 return -2; 253 } 254 keyidx >>= 6; 255 if (key->key_idx != keyidx) { 256 netdev_dbg(skb->dev, "CCMP: RX tkey->key_idx=%d frame keyidx=%d priv=%p\n", 257 key->key_idx, keyidx, priv); 258 return -6; 259 } 260 if (!key->key_set) { 261 if (net_ratelimit()) { 262 netdev_dbg(skb->dev, "CCMP: received packet from %pM with keyid=%d that does not have a configured key\n", 263 hdr->addr2, keyidx); 264 } 265 return -3; 266 } 267 268 pn[0] = pos[7]; 269 pn[1] = pos[6]; 270 pn[2] = pos[5]; 271 pn[3] = pos[4]; 272 pn[4] = pos[1]; 273 pn[5] = pos[0]; 274 pos += 8; 275 276 if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { 277 if (net_ratelimit()) { 278 netdev_dbg(skb->dev, "CCMP: replay detected: STA=%pM previous PN %pm received PN %pm\n", 279 hdr->addr2, key->rx_pn, pn); 280 } 281 key->dot11RSNAStatsCCMPReplays++; 282 return -4; 283 } 284 if (!tcb_desc->bHwSec) { 285 struct aead_request *req; 286 struct scatterlist sg[2]; 287 u8 *aad = key->rx_aad; 288 u8 iv[AES_BLOCK_LEN]; 289 int aad_len, ret; 290 size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN; 291 292 req = aead_request_alloc(key->tfm, GFP_ATOMIC); 293 if (!req) 294 return -ENOMEM; 295 296 aad_len = ccmp_init_iv_and_aad(hdr, pn, iv, aad); 297 298 sg_init_table(sg, 2); 299 sg_set_buf(&sg[0], aad, aad_len); 300 sg_set_buf(&sg[1], pos, data_len); 301 302 aead_request_set_callback(req, 0, NULL, NULL); 303 aead_request_set_ad(req, aad_len); 304 aead_request_set_crypt(req, sg, sg, data_len, iv); 305 306 ret = crypto_aead_decrypt(req); 307 aead_request_free(req); 308 309 if (ret) { 310 if (net_ratelimit()) { 311 netdev_dbg(skb->dev, "CCMP: decrypt failed: STA=%pM\n", 312 hdr->addr2); 313 } 314 key->dot11RSNAStatsCCMPDecryptErrors++; 315 return -5; 316 } 317 318 memcpy(key->rx_pn, pn, CCMP_PN_LEN); 319 } 320 /* Remove hdr and MIC */ 321 memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len); 322 skb_pull(skb, CCMP_HDR_LEN); 323 skb_trim(skb, skb->len - CCMP_MIC_LEN); 324 325 return keyidx; 326 } 327 328 static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv) 329 { 330 struct ieee80211_ccmp_data *data = priv; 331 int keyidx; 332 struct crypto_aead *tfm = data->tfm; 333 334 keyidx = data->key_idx; 335 memset(data, 0, sizeof(*data)); 336 data->key_idx = keyidx; 337 if (len == CCMP_TK_LEN) { 338 memcpy(data->key, key, CCMP_TK_LEN); 339 data->key_set = 1; 340 if (seq) { 341 data->rx_pn[0] = seq[5]; 342 data->rx_pn[1] = seq[4]; 343 data->rx_pn[2] = seq[3]; 344 data->rx_pn[3] = seq[2]; 345 data->rx_pn[4] = seq[1]; 346 data->rx_pn[5] = seq[0]; 347 } 348 if (crypto_aead_setauthsize(tfm, CCMP_MIC_LEN) || 349 crypto_aead_setkey(tfm, data->key, CCMP_TK_LEN)) 350 return -1; 351 } else if (len == 0) { 352 data->key_set = 0; 353 } else { 354 return -1; 355 } 356 357 return 0; 358 } 359 360 static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv) 361 { 362 struct ieee80211_ccmp_data *data = priv; 363 364 if (len < CCMP_TK_LEN) 365 return 0; 366 367 if (!data->key_set) 368 return 0; 369 memcpy(key, data->key, CCMP_TK_LEN); 370 371 if (seq) { 372 seq[0] = data->tx_pn[5]; 373 seq[1] = data->tx_pn[4]; 374 seq[2] = data->tx_pn[3]; 375 seq[3] = data->tx_pn[2]; 376 seq[4] = data->tx_pn[1]; 377 seq[5] = data->tx_pn[0]; 378 } 379 380 return CCMP_TK_LEN; 381 } 382 383 static char *ieee80211_ccmp_print_stats(char *p, void *priv) 384 { 385 struct ieee80211_ccmp_data *ccmp = priv; 386 387 p += sprintf(p, "key[%d] alg=CCMP key_set=%d tx_pn=%pm rx_pn=%pm format_errors=%d replays=%d decrypt_errors=%d\n", 388 ccmp->key_idx, ccmp->key_set, 389 ccmp->tx_pn, ccmp->rx_pn, 390 ccmp->dot11RSNAStatsCCMPFormatErrors, 391 ccmp->dot11RSNAStatsCCMPReplays, 392 ccmp->dot11RSNAStatsCCMPDecryptErrors); 393 394 return p; 395 } 396 397 static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = { 398 .name = "CCMP", 399 .init = ieee80211_ccmp_init, 400 .deinit = ieee80211_ccmp_deinit, 401 .encrypt_mpdu = ieee80211_ccmp_encrypt, 402 .decrypt_mpdu = ieee80211_ccmp_decrypt, 403 .encrypt_msdu = NULL, 404 .decrypt_msdu = NULL, 405 .set_key = ieee80211_ccmp_set_key, 406 .get_key = ieee80211_ccmp_get_key, 407 .print_stats = ieee80211_ccmp_print_stats, 408 .extra_prefix_len = CCMP_HDR_LEN, 409 .extra_postfix_len = CCMP_MIC_LEN, 410 .owner = THIS_MODULE, 411 }; 412 413 int __init ieee80211_crypto_ccmp_init(void) 414 { 415 return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp); 416 } 417 418 void ieee80211_crypto_ccmp_exit(void) 419 { 420 ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp); 421 } 422