Lines Matching +full:mic +full:- +full:pos

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>
66 priv->key_idx = key_idx; in lib80211_ccmp_init()
68 priv->tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC); in lib80211_ccmp_init()
69 if (IS_ERR(priv->tfm)) { in lib80211_ccmp_init()
70 priv->tfm = NULL; in lib80211_ccmp_init()
78 if (priv->tfm) in lib80211_ccmp_init()
79 crypto_free_aead(priv->tfm); in lib80211_ccmp_init()
89 if (_priv && _priv->tfm) in lib80211_ccmp_deinit()
90 crypto_free_aead(_priv->tfm); in lib80211_ccmp_deinit()
97 u8 *pos, qc = 0; in ccmp_init_iv_and_aad() local
101 a4_included = ieee80211_has_a4(hdr->frame_control); in ccmp_init_iv_and_aad()
102 qc_included = ieee80211_is_data_qos(hdr->frame_control); in ccmp_init_iv_and_aad()
108 pos = (u8 *) & hdr->addr4; in ccmp_init_iv_and_aad()
110 pos += 6; in ccmp_init_iv_and_aad()
111 qc = *pos & 0x0f; in ccmp_init_iv_and_aad()
126 memcpy(iv + 2, hdr->addr2, ETH_ALEN); in ccmp_init_iv_and_aad()
136 pos = (u8 *) hdr; in ccmp_init_iv_and_aad()
137 aad[0] = pos[0] & 0x8f; in ccmp_init_iv_and_aad()
138 aad[1] = pos[1] & 0xc7; in ccmp_init_iv_and_aad()
139 memcpy(aad + 2, &hdr->addrs, 3 * ETH_ALEN); in ccmp_init_iv_and_aad()
140 pos = (u8 *) & hdr->seq_ctrl; in ccmp_init_iv_and_aad()
141 aad[20] = pos[0] & 0x0f; in ccmp_init_iv_and_aad()
145 memcpy(aad + 22, hdr->addr4, ETH_ALEN); in ccmp_init_iv_and_aad()
158 u8 *pos; in lib80211_ccmp_hdr() local
160 if (skb_headroom(skb) < CCMP_HDR_LEN || skb->len < hdr_len) in lib80211_ccmp_hdr()
161 return -1; in lib80211_ccmp_hdr()
164 memcpy(aeskey, key->key, CCMP_TK_LEN); in lib80211_ccmp_hdr()
166 pos = skb_push(skb, CCMP_HDR_LEN); in lib80211_ccmp_hdr()
167 memmove(pos, pos + CCMP_HDR_LEN, hdr_len); in lib80211_ccmp_hdr()
168 pos += hdr_len; in lib80211_ccmp_hdr()
170 i = CCMP_PN_LEN - 1; in lib80211_ccmp_hdr()
172 key->tx_pn[i]++; in lib80211_ccmp_hdr()
173 if (key->tx_pn[i] != 0) in lib80211_ccmp_hdr()
175 i--; in lib80211_ccmp_hdr()
178 *pos++ = key->tx_pn[5]; in lib80211_ccmp_hdr()
179 *pos++ = key->tx_pn[4]; in lib80211_ccmp_hdr()
180 *pos++ = 0; in lib80211_ccmp_hdr()
181 *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */ ; in lib80211_ccmp_hdr()
182 *pos++ = key->tx_pn[3]; in lib80211_ccmp_hdr()
183 *pos++ = key->tx_pn[2]; in lib80211_ccmp_hdr()
184 *pos++ = key->tx_pn[1]; in lib80211_ccmp_hdr()
185 *pos++ = key->tx_pn[0]; in lib80211_ccmp_hdr()
196 u8 *aad = key->tx_aad; in lib80211_ccmp_encrypt()
201 if (skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len) in lib80211_ccmp_encrypt()
202 return -1; in lib80211_ccmp_encrypt()
204 data_len = skb->len - hdr_len; in lib80211_ccmp_encrypt()
207 return -1; in lib80211_ccmp_encrypt()
209 req = aead_request_alloc(key->tfm, GFP_ATOMIC); in lib80211_ccmp_encrypt()
211 return -ENOMEM; in lib80211_ccmp_encrypt()
213 hdr = (struct ieee80211_hdr *)skb->data; in lib80211_ccmp_encrypt()
214 aad_len = ccmp_init_iv_and_aad(hdr, key->tx_pn, iv, aad); in lib80211_ccmp_encrypt()
220 sg_set_buf(&sg[1], skb->data + hdr_len + CCMP_HDR_LEN, in lib80211_ccmp_encrypt()
248 if ((s32)iv32_n - (s32)iv32_o < 0 || in ccmp_replay_check()
257 u8 keyidx, *pos; in lib80211_ccmp_decrypt() local
261 u8 *aad = key->rx_aad; in lib80211_ccmp_decrypt()
265 size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN; in lib80211_ccmp_decrypt()
267 if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) { in lib80211_ccmp_decrypt()
268 key->dot11RSNAStatsCCMPFormatErrors++; in lib80211_ccmp_decrypt()
269 return -1; in lib80211_ccmp_decrypt()
272 hdr = (struct ieee80211_hdr *)skb->data; in lib80211_ccmp_decrypt()
273 pos = skb->data + hdr_len; in lib80211_ccmp_decrypt()
274 keyidx = pos[3]; in lib80211_ccmp_decrypt()
277 hdr->addr2); in lib80211_ccmp_decrypt()
278 key->dot11RSNAStatsCCMPFormatErrors++; in lib80211_ccmp_decrypt()
279 return -2; in lib80211_ccmp_decrypt()
282 if (key->key_idx != keyidx) { in lib80211_ccmp_decrypt()
283 net_dbg_ratelimited("CCMP: RX tkey->key_idx=%d frame keyidx=%d\n", in lib80211_ccmp_decrypt()
284 key->key_idx, keyidx); in lib80211_ccmp_decrypt()
285 return -6; in lib80211_ccmp_decrypt()
287 if (!key->key_set) { in lib80211_ccmp_decrypt()
289 hdr->addr2, keyidx); in lib80211_ccmp_decrypt()
290 return -3; in lib80211_ccmp_decrypt()
293 pn[0] = pos[7]; in lib80211_ccmp_decrypt()
294 pn[1] = pos[6]; in lib80211_ccmp_decrypt()
295 pn[2] = pos[5]; in lib80211_ccmp_decrypt()
296 pn[3] = pos[4]; in lib80211_ccmp_decrypt()
297 pn[4] = pos[1]; in lib80211_ccmp_decrypt()
298 pn[5] = pos[0]; in lib80211_ccmp_decrypt()
299 pos += 8; in lib80211_ccmp_decrypt()
301 if (ccmp_replay_check(pn, key->rx_pn)) { in lib80211_ccmp_decrypt()
304 hdr->addr2, in lib80211_ccmp_decrypt()
305 key->rx_pn[0], key->rx_pn[1], key->rx_pn[2], in lib80211_ccmp_decrypt()
306 key->rx_pn[3], key->rx_pn[4], key->rx_pn[5], in lib80211_ccmp_decrypt()
309 key->dot11RSNAStatsCCMPReplays++; in lib80211_ccmp_decrypt()
310 return -4; in lib80211_ccmp_decrypt()
313 req = aead_request_alloc(key->tfm, GFP_ATOMIC); in lib80211_ccmp_decrypt()
315 return -ENOMEM; in lib80211_ccmp_decrypt()
321 sg_set_buf(&sg[1], pos, data_len); in lib80211_ccmp_decrypt()
332 hdr->addr2, ret); in lib80211_ccmp_decrypt()
333 key->dot11RSNAStatsCCMPDecryptErrors++; in lib80211_ccmp_decrypt()
334 return -5; in lib80211_ccmp_decrypt()
337 memcpy(key->rx_pn, pn, CCMP_PN_LEN); in lib80211_ccmp_decrypt()
339 /* Remove hdr and MIC */ in lib80211_ccmp_decrypt()
340 memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len); in lib80211_ccmp_decrypt()
342 skb_trim(skb, skb->len - CCMP_MIC_LEN); in lib80211_ccmp_decrypt()
351 struct crypto_aead *tfm = data->tfm; in lib80211_ccmp_set_key()
353 keyidx = data->key_idx; in lib80211_ccmp_set_key()
355 data->key_idx = keyidx; in lib80211_ccmp_set_key()
356 data->tfm = tfm; in lib80211_ccmp_set_key()
358 memcpy(data->key, key, CCMP_TK_LEN); in lib80211_ccmp_set_key()
359 data->key_set = 1; in lib80211_ccmp_set_key()
361 data->rx_pn[0] = seq[5]; in lib80211_ccmp_set_key()
362 data->rx_pn[1] = seq[4]; in lib80211_ccmp_set_key()
363 data->rx_pn[2] = seq[3]; in lib80211_ccmp_set_key()
364 data->rx_pn[3] = seq[2]; in lib80211_ccmp_set_key()
365 data->rx_pn[4] = seq[1]; in lib80211_ccmp_set_key()
366 data->rx_pn[5] = seq[0]; in lib80211_ccmp_set_key()
368 if (crypto_aead_setauthsize(data->tfm, CCMP_MIC_LEN) || in lib80211_ccmp_set_key()
369 crypto_aead_setkey(data->tfm, data->key, CCMP_TK_LEN)) in lib80211_ccmp_set_key()
370 return -1; in lib80211_ccmp_set_key()
372 data->key_set = 0; in lib80211_ccmp_set_key()
374 return -1; in lib80211_ccmp_set_key()
384 return -1; in lib80211_ccmp_get_key()
386 if (!data->key_set) in lib80211_ccmp_get_key()
388 memcpy(key, data->key, CCMP_TK_LEN); in lib80211_ccmp_get_key()
391 seq[0] = data->tx_pn[5]; in lib80211_ccmp_get_key()
392 seq[1] = data->tx_pn[4]; in lib80211_ccmp_get_key()
393 seq[2] = data->tx_pn[3]; in lib80211_ccmp_get_key()
394 seq[3] = data->tx_pn[2]; in lib80211_ccmp_get_key()
395 seq[4] = data->tx_pn[1]; in lib80211_ccmp_get_key()
396 seq[5] = data->tx_pn[0]; in lib80211_ccmp_get_key()
411 ccmp->key_idx, ccmp->key_set, in lib80211_ccmp_print_stats()
412 ccmp->tx_pn[0], ccmp->tx_pn[1], ccmp->tx_pn[2], in lib80211_ccmp_print_stats()
413 ccmp->tx_pn[3], ccmp->tx_pn[4], ccmp->tx_pn[5], in lib80211_ccmp_print_stats()
414 ccmp->rx_pn[0], ccmp->rx_pn[1], ccmp->rx_pn[2], in lib80211_ccmp_print_stats()
415 ccmp->rx_pn[3], ccmp->rx_pn[4], ccmp->rx_pn[5], in lib80211_ccmp_print_stats()
416 ccmp->dot11RSNAStatsCCMPFormatErrors, in lib80211_ccmp_print_stats()
417 ccmp->dot11RSNAStatsCCMPReplays, in lib80211_ccmp_print_stats()
418 ccmp->dot11RSNAStatsCCMPDecryptErrors); in lib80211_ccmp_print_stats()