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