This patch reverts the following commits from wireless-testing: 8ade538bf39b1ee53418528fdacd36b8e65621b9 56c52da2d554f081e8fce58ecbcf6a40c605b95b 2b2ba0db1c820d04d5143452d70012cd44d7b578 00b9cfa3ff38401bd70c34b250ca13e5ea347b4a 4f031fa9f188b2b0641ac20087d9e16bcfb4e49d 6e1ee5d2e9e411892b5d84e3ea93e3fc88ac786c 30ef7ef9672d92ab2cac37f60a31955c118321e7 f359d3fe832e49eeec2232b2af5a9e3aee6b4862 (only the changes in aes_cmac.{c,h}) 7ec7c4a9a686c608315739ab6a2b0527a240883c --- --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1017,15 +1017,6 @@ struct ieee80211_mmie { u8 mic[8]; } __packed; -/* Management MIC information element (IEEE 802.11w) for GMAC and CMAC-256 */ -struct ieee80211_mmie_16 { - u8 element_id; - u8 length; - __le16 key_id; - u8 sequence_number[6]; - u8 mic[16]; -} __packed; - struct ieee80211_vendor_ie { u8 element_id; u8 len; --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1306,8 +1306,8 @@ struct ieee80211_vif *wdev_to_ieee80211_ * @IEEE80211_KEY_FLAG_PAIRWISE: Set by mac80211, this flag indicates * that the key is pairwise rather then a shared key. * @IEEE80211_KEY_FLAG_SW_MGMT_TX: This flag should be set by the driver for a - * CCMP/GCMP key if it requires CCMP/GCMP encryption of management frames - * (MFP) to be done in software. + * CCMP key if it requires CCMP encryption of management frames (MFP) to + * be done in software. * @IEEE80211_KEY_FLAG_PUT_IV_SPACE: This flag should be set by the driver * if space should be prepared for the IV, but the IV * itself should not be generated. Do not set together with @@ -1322,7 +1322,7 @@ struct ieee80211_vif *wdev_to_ieee80211_ * RX, if your crypto engine can't deal with TX you can also set the * %IEEE80211_KEY_FLAG_SW_MGMT_TX flag to encrypt such frames in SW. * @IEEE80211_KEY_FLAG_GENERATE_IV_MGMT: This flag should be set by the - * driver for a CCMP/GCMP key to indicate that is requires IV generation + * driver for a CCMP key to indicate that is requires IV generation * only for managment frames (MFP). * @IEEE80211_KEY_FLAG_RESERVE_TAILROOM: This flag should be set by the * driver for a key to indicate that sufficient tailroom must always @@ -4112,10 +4112,6 @@ void ieee80211_aes_cmac_calculate_k1_k2( * reverse order than in packet) * @aes_cmac: PN data, most significant byte first (big endian, * reverse order than in packet) - * @aes_gmac: PN data, most significant byte first (big endian, - * reverse order than in packet) - * @gcmp: PN data, most significant byte first (big endian, - * reverse order than in packet) */ struct ieee80211_key_seq { union { @@ -4129,12 +4125,6 @@ struct ieee80211_key_seq { struct { u8 pn[6]; } aes_cmac; - struct { - u8 pn[6]; - } aes_gmac; - struct { - u8 pn[6]; - } gcmp; }; }; @@ -4159,7 +4149,7 @@ void ieee80211_get_key_tx_seq(struct iee * ieee80211_get_key_rx_seq - get key RX sequence counter * * @keyconf: the parameter passed with the set key - * @tid: The TID, or -1 for the management frame value (CCMP/GCMP only); + * @tid: The TID, or -1 for the management frame value (CCMP only); * the value on TID 0 is also used for non-QoS frames. For * CMAC, only TID 0 is valid. * @seq: buffer to receive the sequence data @@ -4195,7 +4185,7 @@ void ieee80211_set_key_tx_seq(struct iee * ieee80211_set_key_rx_seq - set key RX sequence counter * * @keyconf: the parameter passed with the set key - * @tid: The TID, or -1 for the management frame value (CCMP/GCMP only); + * @tid: The TID, or -1 for the management frame value (CCMP only); * the value on TID 0 is also used for non-QoS frames. For * CMAC, only TID 0 is valid. * @seq: new sequence data --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -5,8 +5,6 @@ config MAC80211 depends on CRYPTO depends on CRYPTO_ARC4 depends on CRYPTO_AES - select BPAUTO_CRYPTO_CCM - depends on CRYPTO_GCM depends on CRC32 select BPAUTO_AVERAGE ---help--- --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile @@ -15,9 +15,7 @@ mac80211-y := \ michael.o \ tkip.o \ aes_ccm.o \ - aes_gcm.o \ aes_cmac.o \ - aes_gmac.o \ cfg.o \ ethtool.o \ rx.o \ --- a/net/mac80211/aes_ccm.c +++ b/net/mac80211/aes_ccm.c @@ -2,8 +2,6 @@ * Copyright 2003-2004, Instant802 Networks, Inc. * Copyright 2005-2006, Devicescape Software, Inc. * - * Rewrite: Copyright (C) 2013 Linaro Ltd - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. @@ -19,82 +17,134 @@ #include "key.h" #include "aes_ccm.h" -void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, - u8 *data, size_t data_len, u8 *mic, - size_t mic_len) +static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *scratch, u8 *a) +{ + int i; + u8 *b_0, *aad, *b, *s_0; + + b_0 = scratch + 3 * AES_BLOCK_SIZE; + aad = scratch + 4 * AES_BLOCK_SIZE; + b = scratch; + s_0 = scratch + AES_BLOCK_SIZE; + + crypto_cipher_encrypt_one(tfm, b, b_0); + + /* Extra Authenticate-only data (always two AES blocks) */ + for (i = 0; i < AES_BLOCK_SIZE; i++) + aad[i] ^= b[i]; + crypto_cipher_encrypt_one(tfm, b, aad); + + aad += AES_BLOCK_SIZE; + + for (i = 0; i < AES_BLOCK_SIZE; i++) + aad[i] ^= b[i]; + crypto_cipher_encrypt_one(tfm, a, aad); + + /* Mask out bits from auth-only-b_0 */ + b_0[0] &= 0x07; + + /* S_0 is used to encrypt T (= MIC) */ + b_0[14] = 0; + b_0[15] = 0; + crypto_cipher_encrypt_one(tfm, s_0, b_0); +} + + +void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, + u8 *data, size_t data_len, + u8 *cdata, u8 *mic) { - struct scatterlist assoc, pt, ct[2]; + int i, j, last_len, num_blocks; + u8 *pos, *cpos, *b, *s_0, *e, *b_0; - char aead_req_data[sizeof(struct aead_request) + - crypto_aead_reqsize(tfm)] - __aligned(__alignof__(struct aead_request)); - struct aead_request *aead_req = (void *) aead_req_data; - - memset(aead_req, 0, sizeof(aead_req_data)); - - sg_init_one(&pt, data, data_len); - sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad)); - sg_init_table(ct, 2); - sg_set_buf(&ct[0], data, data_len); - sg_set_buf(&ct[1], mic, mic_len); - - aead_request_set_tfm(aead_req, tfm); - aead_request_set_assoc(aead_req, &assoc, assoc.length); - aead_request_set_crypt(aead_req, &pt, ct, data_len, b_0); + b = scratch; + s_0 = scratch + AES_BLOCK_SIZE; + e = scratch + 2 * AES_BLOCK_SIZE; + b_0 = scratch + 3 * AES_BLOCK_SIZE; + + num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE); + last_len = data_len % AES_BLOCK_SIZE; + aes_ccm_prepare(tfm, scratch, b); + + /* Process payload blocks */ + pos = data; + cpos = cdata; + for (j = 1; j <= num_blocks; j++) { + int blen = (j == num_blocks && last_len) ? + last_len : AES_BLOCK_SIZE; + + /* Authentication followed by encryption */ + for (i = 0; i < blen; i++) + b[i] ^= pos[i]; + crypto_cipher_encrypt_one(tfm, b, b); + + b_0[14] = (j >> 8) & 0xff; + b_0[15] = j & 0xff; + crypto_cipher_encrypt_one(tfm, e, b_0); + for (i = 0; i < blen; i++) + *cpos++ = *pos++ ^ e[i]; + } - crypto_aead_encrypt(aead_req); + for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++) + mic[i] = b[i] ^ s_0[i]; } -int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, - u8 *data, size_t data_len, u8 *mic, - size_t mic_len) + +int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, + u8 *cdata, size_t data_len, u8 *mic, u8 *data) { - struct scatterlist assoc, pt, ct[2]; - char aead_req_data[sizeof(struct aead_request) + - crypto_aead_reqsize(tfm)] - __aligned(__alignof__(struct aead_request)); - struct aead_request *aead_req = (void *) aead_req_data; - - if (data_len == 0) - return -EINVAL; - - memset(aead_req, 0, sizeof(aead_req_data)); - - sg_init_one(&pt, data, data_len); - sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad)); - sg_init_table(ct, 2); - sg_set_buf(&ct[0], data, data_len); - sg_set_buf(&ct[1], mic, mic_len); - - aead_request_set_tfm(aead_req, tfm); - aead_request_set_assoc(aead_req, &assoc, assoc.length); - aead_request_set_crypt(aead_req, ct, &pt, data_len + mic_len, b_0); + int i, j, last_len, num_blocks; + u8 *pos, *cpos, *b, *s_0, *a, *b_0; + + b = scratch; + s_0 = scratch + AES_BLOCK_SIZE; + a = scratch + 2 * AES_BLOCK_SIZE; + b_0 = scratch + 3 * AES_BLOCK_SIZE; + + num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE); + last_len = data_len % AES_BLOCK_SIZE; + aes_ccm_prepare(tfm, scratch, a); + + /* Process payload blocks */ + cpos = cdata; + pos = data; + for (j = 1; j <= num_blocks; j++) { + int blen = (j == num_blocks && last_len) ? + last_len : AES_BLOCK_SIZE; + + /* Decryption followed by authentication */ + b_0[14] = (j >> 8) & 0xff; + b_0[15] = j & 0xff; + crypto_cipher_encrypt_one(tfm, b, b_0); + for (i = 0; i < blen; i++) { + *pos = *cpos++ ^ b[i]; + a[i] ^= *pos++; + } + crypto_cipher_encrypt_one(tfm, a, a); + } + + for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++) { + if ((mic[i] ^ s_0[i]) != a[i]) + return -1; + } - return crypto_aead_decrypt(aead_req); + return 0; } -struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[], - size_t key_len, - size_t mic_len) + +struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]) { - struct crypto_aead *tfm; - int err; + struct crypto_cipher *tfm; - tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(tfm)) - return tfm; - - err = crypto_aead_setkey(tfm, key, key_len); - if (!err) - err = crypto_aead_setauthsize(tfm, mic_len); - if (!err) - return tfm; + tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); + if (!IS_ERR(tfm)) + crypto_cipher_setkey(tfm, key, WLAN_KEY_LEN_CCMP); - crypto_free_aead(tfm); - return ERR_PTR(err); + return tfm; } -void ieee80211_aes_key_free(struct crypto_aead *tfm) + +void ieee80211_aes_key_free(struct crypto_cipher *tfm) { - crypto_free_aead(tfm); + crypto_free_cipher(tfm); } --- a/net/mac80211/aes_ccm.h +++ b/net/mac80211/aes_ccm.h @@ -12,15 +12,13 @@ #include -struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[], - size_t key_len, - size_t mic_len); -void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, - u8 *data, size_t data_len, u8 *mic, - size_t mic_len); -int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, - u8 *data, size_t data_len, u8 *mic, - size_t mic_len); -void ieee80211_aes_key_free(struct crypto_aead *tfm); +struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]); +void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, + u8 *data, size_t data_len, + u8 *cdata, u8 *mic); +int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, + u8 *cdata, size_t data_len, + u8 *mic, u8 *data); +void ieee80211_aes_key_free(struct crypto_cipher *tfm); #endif /* AES_CCM_H */ --- a/net/mac80211/aes_cmac.c +++ b/net/mac80211/aes_cmac.c @@ -18,8 +18,8 @@ #include "key.h" #include "aes_cmac.h" +#define AES_CMAC_KEY_LEN 16 #define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */ -#define CMAC_TLEN_256 16 /* CMAC TLen = 128 bits (16 octets) */ #define AAD_LEN 20 @@ -35,9 +35,9 @@ static void gf_mulx(u8 *pad) pad[AES_BLOCK_SIZE - 1] ^= 0x87; } -static void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem, - const u8 *addr[], const size_t *len, u8 *mac, - size_t mac_len) + +static void aes_128_cmac_vector(struct crypto_cipher *tfm, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac) { u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE]; const u8 *pos, *end; @@ -88,7 +88,7 @@ static void aes_cmac_vector(struct crypt for (i = 0; i < AES_BLOCK_SIZE; i++) pad[i] ^= cbc[i]; crypto_cipher_encrypt_one(tfm, pad, pad); - memcpy(mac, pad, mac_len); + memcpy(mac, pad, CMAC_TLEN); } @@ -107,35 +107,17 @@ void ieee80211_aes_cmac(struct crypto_ci addr[2] = zero; len[2] = CMAC_TLEN; - aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN); + aes_128_cmac_vector(tfm, 3, addr, len, mic); } -void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad, - const u8 *data, size_t data_len, u8 *mic) -{ - const u8 *addr[3]; - size_t len[3]; - u8 zero[CMAC_TLEN_256]; - - memset(zero, 0, CMAC_TLEN_256); - addr[0] = aad; - len[0] = AAD_LEN; - addr[1] = data; - len[1] = data_len - CMAC_TLEN_256; - addr[2] = zero; - len[2] = CMAC_TLEN_256; - - aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN_256); -} -struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[], - size_t key_len) +struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]) { struct crypto_cipher *tfm; tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); if (!IS_ERR(tfm)) - crypto_cipher_setkey(tfm, key, key_len); + crypto_cipher_setkey(tfm, key, AES_CMAC_KEY_LEN); return tfm; } --- a/net/mac80211/aes_cmac.h +++ b/net/mac80211/aes_cmac.h @@ -11,12 +11,9 @@ #include -struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[], - size_t key_len); +struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]); void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad, const u8 *data, size_t data_len, u8 *mic); -void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad, - const u8 *data, size_t data_len, u8 *mic); void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm); #endif /* AES_CMAC_H */ --- a/net/mac80211/aes_gcm.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2014-2015, Qualcomm Atheros, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include - -#include -#include "key.h" -#include "aes_gcm.h" - -void ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, - u8 *data, size_t data_len, u8 *mic) -{ - struct scatterlist assoc, pt, ct[2]; - - char aead_req_data[sizeof(struct aead_request) + - crypto_aead_reqsize(tfm)] - __aligned(__alignof__(struct aead_request)); - struct aead_request *aead_req = (void *)aead_req_data; - - memset(aead_req, 0, sizeof(aead_req_data)); - - sg_init_one(&pt, data, data_len); - sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad)); - sg_init_table(ct, 2); - sg_set_buf(&ct[0], data, data_len); - sg_set_buf(&ct[1], mic, IEEE80211_GCMP_MIC_LEN); - - aead_request_set_tfm(aead_req, tfm); - aead_request_set_assoc(aead_req, &assoc, assoc.length); - aead_request_set_crypt(aead_req, &pt, ct, data_len, j_0); - - crypto_aead_encrypt(aead_req); -} - -int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, - u8 *data, size_t data_len, u8 *mic) -{ - struct scatterlist assoc, pt, ct[2]; - char aead_req_data[sizeof(struct aead_request) + - crypto_aead_reqsize(tfm)] - __aligned(__alignof__(struct aead_request)); - struct aead_request *aead_req = (void *)aead_req_data; - - if (data_len == 0) - return -EINVAL; - - memset(aead_req, 0, sizeof(aead_req_data)); - - sg_init_one(&pt, data, data_len); - sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad)); - sg_init_table(ct, 2); - sg_set_buf(&ct[0], data, data_len); - sg_set_buf(&ct[1], mic, IEEE80211_GCMP_MIC_LEN); - - aead_request_set_tfm(aead_req, tfm); - aead_request_set_assoc(aead_req, &assoc, assoc.length); - aead_request_set_crypt(aead_req, ct, &pt, - data_len + IEEE80211_GCMP_MIC_LEN, j_0); - - return crypto_aead_decrypt(aead_req); -} - -struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], - size_t key_len) -{ - struct crypto_aead *tfm; - int err; - - tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(tfm)) - return tfm; - - err = crypto_aead_setkey(tfm, key, key_len); - if (!err) - err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN); - if (!err) - return tfm; - - crypto_free_aead(tfm); - return ERR_PTR(err); -} - -void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) -{ - crypto_free_aead(tfm); -} --- a/net/mac80211/aes_gcm.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2014-2015, Qualcomm Atheros, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef AES_GCM_H -#define AES_GCM_H - -#include - -void ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, - u8 *data, size_t data_len, u8 *mic); -int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, - u8 *data, size_t data_len, u8 *mic); -struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], - size_t key_len); -void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm); - -#endif /* AES_GCM_H */ --- a/net/mac80211/aes_gmac.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * AES-GMAC for IEEE 802.11 BIP-GMAC-128 and BIP-GMAC-256 - * Copyright 2015, Qualcomm Atheros, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include - -#include -#include "key.h" -#include "aes_gmac.h" - -#define GMAC_MIC_LEN 16 -#define GMAC_NONCE_LEN 12 -#define AAD_LEN 20 - -int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce, - const u8 *data, size_t data_len, u8 *mic) -{ - struct scatterlist sg[3], ct[1]; - char aead_req_data[sizeof(struct aead_request) + - crypto_aead_reqsize(tfm)] - __aligned(__alignof__(struct aead_request)); - struct aead_request *aead_req = (void *)aead_req_data; - u8 zero[GMAC_MIC_LEN], iv[AES_BLOCK_SIZE]; - - if (data_len < GMAC_MIC_LEN) - return -EINVAL; - - memset(aead_req, 0, sizeof(aead_req_data)); - - memset(zero, 0, GMAC_MIC_LEN); - sg_init_table(sg, 3); - sg_set_buf(&sg[0], aad, AAD_LEN); - sg_set_buf(&sg[1], data, data_len - GMAC_MIC_LEN); - sg_set_buf(&sg[2], zero, GMAC_MIC_LEN); - - memcpy(iv, nonce, GMAC_NONCE_LEN); - memset(iv + GMAC_NONCE_LEN, 0, sizeof(iv) - GMAC_NONCE_LEN); - iv[AES_BLOCK_SIZE - 1] = 0x01; - - sg_init_table(ct, 1); - sg_set_buf(&ct[0], mic, GMAC_MIC_LEN); - - aead_request_set_tfm(aead_req, tfm); - aead_request_set_assoc(aead_req, sg, AAD_LEN + data_len); - aead_request_set_crypt(aead_req, NULL, ct, 0, iv); - - crypto_aead_encrypt(aead_req); - - return 0; -} - -struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[], - size_t key_len) -{ - struct crypto_aead *tfm; - int err; - - tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(tfm)) - return tfm; - - err = crypto_aead_setkey(tfm, key, key_len); - if (!err) - return tfm; - if (!err) - err = crypto_aead_setauthsize(tfm, GMAC_MIC_LEN); - - crypto_free_aead(tfm); - return ERR_PTR(err); -} - -void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm) -{ - crypto_free_aead(tfm); -} --- a/net/mac80211/aes_gmac.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2015, Qualcomm Atheros, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef AES_GMAC_H -#define AES_GMAC_H - -#include - -struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[], - size_t key_len); -int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce, - const u8 *data, size_t data_len, u8 *mic); -void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm); - -#endif /* AES_GMAC_H */ --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -162,13 +162,8 @@ static int ieee80211_add_key(struct wiph return -EINVAL; break; case WLAN_CIPHER_SUITE_CCMP: - case WLAN_CIPHER_SUITE_CCMP_256: case WLAN_CIPHER_SUITE_AES_CMAC: - case WLAN_CIPHER_SUITE_BIP_CMAC_256: - case WLAN_CIPHER_SUITE_BIP_GMAC_128: - case WLAN_CIPHER_SUITE_BIP_GMAC_256: case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: break; default: cs = ieee80211_cs_get(local, params->cipher, sdata->vif.type); @@ -353,7 +348,6 @@ static int ieee80211_get_key(struct wiph params.seq_len = 6; break; case WLAN_CIPHER_SUITE_CCMP: - case WLAN_CIPHER_SUITE_CCMP_256: pn64 = atomic64_read(&key->u.ccmp.tx_pn); seq[0] = pn64; seq[1] = pn64 >> 8; @@ -365,35 +359,10 @@ static int ieee80211_get_key(struct wiph params.seq_len = 6; break; case WLAN_CIPHER_SUITE_AES_CMAC: - case WLAN_CIPHER_SUITE_BIP_CMAC_256: pn64 = atomic64_read(&key->u.aes_cmac.tx_pn); seq[0] = pn64; seq[1] = pn64 >> 8; seq[2] = pn64 >> 16; - seq[3] = pn64 >> 24; - seq[4] = pn64 >> 32; - seq[5] = pn64 >> 40; - params.seq = seq; - params.seq_len = 6; - break; - case WLAN_CIPHER_SUITE_BIP_GMAC_128: - case WLAN_CIPHER_SUITE_BIP_GMAC_256: - pn64 = atomic64_read(&key->u.aes_gmac.tx_pn); - seq[0] = pn64; - seq[1] = pn64 >> 8; - seq[2] = pn64 >> 16; - seq[3] = pn64 >> 24; - seq[4] = pn64 >> 32; - seq[5] = pn64 >> 40; - params.seq = seq; - params.seq_len = 6; - break; - case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: - pn64 = atomic64_read(&key->u.gcmp.tx_pn); - seq[0] = pn64; - seq[1] = pn64 >> 8; - seq[2] = pn64 >> 16; seq[3] = pn64 >> 24; seq[4] = pn64 >> 32; seq[5] = pn64 >> 40; --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c @@ -94,33 +94,17 @@ static ssize_t key_tx_spec_read(struct f key->u.tkip.tx.iv16); break; case WLAN_CIPHER_SUITE_CCMP: - case WLAN_CIPHER_SUITE_CCMP_256: pn = atomic64_read(&key->u.ccmp.tx_pn); len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", (u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24), (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn); break; case WLAN_CIPHER_SUITE_AES_CMAC: - case WLAN_CIPHER_SUITE_BIP_CMAC_256: pn = atomic64_read(&key->u.aes_cmac.tx_pn); len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", (u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24), (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn); break; - case WLAN_CIPHER_SUITE_BIP_GMAC_128: - case WLAN_CIPHER_SUITE_BIP_GMAC_256: - pn = atomic64_read(&key->u.aes_gmac.tx_pn); - len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", - (u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24), - (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn); - break; - case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: - pn = atomic64_read(&key->u.gcmp.tx_pn); - len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", - (u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24), - (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn); - break; default: return 0; } @@ -150,7 +134,6 @@ static ssize_t key_rx_spec_read(struct f len = p - buf; break; case WLAN_CIPHER_SUITE_CCMP: - case WLAN_CIPHER_SUITE_CCMP_256: for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) { rpn = key->u.ccmp.rx_pn[i]; p += scnprintf(p, sizeof(buf)+buf-p, @@ -161,7 +144,6 @@ static ssize_t key_rx_spec_read(struct f len = p - buf; break; case WLAN_CIPHER_SUITE_AES_CMAC: - case WLAN_CIPHER_SUITE_BIP_CMAC_256: rpn = key->u.aes_cmac.rx_pn; p += scnprintf(p, sizeof(buf)+buf-p, "%02x%02x%02x%02x%02x%02x\n", @@ -169,26 +151,6 @@ static ssize_t key_rx_spec_read(struct f rpn[3], rpn[4], rpn[5]); len = p - buf; break; - case WLAN_CIPHER_SUITE_BIP_GMAC_128: - case WLAN_CIPHER_SUITE_BIP_GMAC_256: - rpn = key->u.aes_gmac.rx_pn; - p += scnprintf(p, sizeof(buf)+buf-p, - "%02x%02x%02x%02x%02x%02x\n", - rpn[0], rpn[1], rpn[2], - rpn[3], rpn[4], rpn[5]); - len = p - buf; - break; - case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: - for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) { - rpn = key->u.gcmp.rx_pn[i]; - p += scnprintf(p, sizeof(buf)+buf-p, - "%02x%02x%02x%02x%02x%02x\n", - rpn[0], rpn[1], rpn[2], - rpn[3], rpn[4], rpn[5]); - } - len = p - buf; - break; default: return 0; } @@ -205,23 +167,12 @@ static ssize_t key_replays_read(struct f switch (key->conf.cipher) { case WLAN_CIPHER_SUITE_CCMP: - case WLAN_CIPHER_SUITE_CCMP_256: len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays); break; case WLAN_CIPHER_SUITE_AES_CMAC: - case WLAN_CIPHER_SUITE_BIP_CMAC_256: len = scnprintf(buf, sizeof(buf), "%u\n", key->u.aes_cmac.replays); break; - case WLAN_CIPHER_SUITE_BIP_GMAC_128: - case WLAN_CIPHER_SUITE_BIP_GMAC_256: - len = scnprintf(buf, sizeof(buf), "%u\n", - key->u.aes_gmac.replays); - break; - case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: - len = scnprintf(buf, sizeof(buf), "%u\n", key->u.gcmp.replays); - break; default: return 0; } @@ -238,15 +189,9 @@ static ssize_t key_icverrors_read(struct switch (key->conf.cipher) { case WLAN_CIPHER_SUITE_AES_CMAC: - case WLAN_CIPHER_SUITE_BIP_CMAC_256: len = scnprintf(buf, sizeof(buf), "%u\n", key->u.aes_cmac.icverrors); break; - case WLAN_CIPHER_SUITE_BIP_GMAC_128: - case WLAN_CIPHER_SUITE_BIP_GMAC_256: - len = scnprintf(buf, sizeof(buf), "%u\n", - key->u.aes_gmac.icverrors); - break; default: return 0; } --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -24,8 +24,6 @@ #include "debugfs_key.h" #include "aes_ccm.h" #include "aes_cmac.h" -#include "aes_gmac.h" -#include "aes_gcm.h" /** @@ -164,13 +162,7 @@ static int ieee80211_key_enable_hw_accel case WLAN_CIPHER_SUITE_WEP104: case WLAN_CIPHER_SUITE_TKIP: case WLAN_CIPHER_SUITE_CCMP: - case WLAN_CIPHER_SUITE_CCMP_256: case WLAN_CIPHER_SUITE_AES_CMAC: - case WLAN_CIPHER_SUITE_BIP_CMAC_256: - case WLAN_CIPHER_SUITE_BIP_GMAC_128: - case WLAN_CIPHER_SUITE_BIP_GMAC_256: - case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: /* all of these we can do in software - if driver can */ if (ret == 1) return 0; @@ -394,26 +386,7 @@ ieee80211_key_alloc(u32 cipher, int idx, * Initialize AES key state here as an optimization so that * it does not need to be initialized for every packet. */ - key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt( - key_data, key_len, IEEE80211_CCMP_MIC_LEN); - if (IS_ERR(key->u.ccmp.tfm)) { - err = PTR_ERR(key->u.ccmp.tfm); - kfree(key); - return ERR_PTR(err); - } - break; - case WLAN_CIPHER_SUITE_CCMP_256: - key->conf.iv_len = IEEE80211_CCMP_256_HDR_LEN; - key->conf.icv_len = IEEE80211_CCMP_256_MIC_LEN; - for (i = 0; seq && i < IEEE80211_NUM_TIDS + 1; i++) - for (j = 0; j < IEEE80211_CCMP_256_PN_LEN; j++) - key->u.ccmp.rx_pn[i][j] = - seq[IEEE80211_CCMP_256_PN_LEN - j - 1]; - /* Initialize AES key state here as an optimization so that - * it does not need to be initialized for every packet. - */ - key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt( - key_data, key_len, IEEE80211_CCMP_256_MIC_LEN); + key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(key_data); if (IS_ERR(key->u.ccmp.tfm)) { err = PTR_ERR(key->u.ccmp.tfm); kfree(key); @@ -421,12 +394,8 @@ ieee80211_key_alloc(u32 cipher, int idx, } break; case WLAN_CIPHER_SUITE_AES_CMAC: - case WLAN_CIPHER_SUITE_BIP_CMAC_256: key->conf.iv_len = 0; - if (cipher == WLAN_CIPHER_SUITE_AES_CMAC) - key->conf.icv_len = sizeof(struct ieee80211_mmie); - else - key->conf.icv_len = sizeof(struct ieee80211_mmie_16); + key->conf.icv_len = sizeof(struct ieee80211_mmie); if (seq) for (j = 0; j < IEEE80211_CMAC_PN_LEN; j++) key->u.aes_cmac.rx_pn[j] = @@ -436,51 +405,13 @@ ieee80211_key_alloc(u32 cipher, int idx, * it does not need to be initialized for every packet. */ key->u.aes_cmac.tfm = - ieee80211_aes_cmac_key_setup(key_data, key_len); + ieee80211_aes_cmac_key_setup(key_data); if (IS_ERR(key->u.aes_cmac.tfm)) { err = PTR_ERR(key->u.aes_cmac.tfm); kfree(key); return ERR_PTR(err); } break; - case WLAN_CIPHER_SUITE_BIP_GMAC_128: - case WLAN_CIPHER_SUITE_BIP_GMAC_256: - key->conf.iv_len = 0; - key->conf.icv_len = sizeof(struct ieee80211_mmie_16); - if (seq) - for (j = 0; j < IEEE80211_GMAC_PN_LEN; j++) - key->u.aes_gmac.rx_pn[j] = - seq[IEEE80211_GMAC_PN_LEN - j - 1]; - /* Initialize AES key state here as an optimization so that - * it does not need to be initialized for every packet. - */ - key->u.aes_gmac.tfm = - ieee80211_aes_gmac_key_setup(key_data, key_len); - if (IS_ERR(key->u.aes_gmac.tfm)) { - err = PTR_ERR(key->u.aes_gmac.tfm); - kfree(key); - return ERR_PTR(err); - } - break; - case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: - key->conf.iv_len = IEEE80211_GCMP_HDR_LEN; - key->conf.icv_len = IEEE80211_GCMP_MIC_LEN; - for (i = 0; seq && i < IEEE80211_NUM_TIDS + 1; i++) - for (j = 0; j < IEEE80211_GCMP_PN_LEN; j++) - key->u.gcmp.rx_pn[i][j] = - seq[IEEE80211_GCMP_PN_LEN - j - 1]; - /* Initialize AES key state here as an optimization so that - * it does not need to be initialized for every packet. - */ - key->u.gcmp.tfm = ieee80211_aes_gcm_key_setup_encrypt(key_data, - key_len); - if (IS_ERR(key->u.gcmp.tfm)) { - err = PTR_ERR(key->u.gcmp.tfm); - kfree(key); - return ERR_PTR(err); - } - break; default: if (cs) { size_t len = (seq_len > MAX_PN_LEN) ? @@ -502,24 +433,10 @@ ieee80211_key_alloc(u32 cipher, int idx, static void ieee80211_key_free_common(struct ieee80211_key *key) { - switch (key->conf.cipher) { - case WLAN_CIPHER_SUITE_CCMP: - case WLAN_CIPHER_SUITE_CCMP_256: + if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP) ieee80211_aes_key_free(key->u.ccmp.tfm); - break; - case WLAN_CIPHER_SUITE_AES_CMAC: - case WLAN_CIPHER_SUITE_BIP_CMAC_256: + if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC) ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); - break; - case WLAN_CIPHER_SUITE_BIP_GMAC_128: - case WLAN_CIPHER_SUITE_BIP_GMAC_256: - ieee80211_aes_gmac_key_free(key->u.aes_gmac.tfm); - break; - case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: - ieee80211_aes_gcm_key_free(key->u.gcmp.tfm); - break; - } kzfree(key); } @@ -826,7 +743,6 @@ void ieee80211_get_key_tx_seq(struct iee seq->tkip.iv16 = key->u.tkip.tx.iv16; break; case WLAN_CIPHER_SUITE_CCMP: - case WLAN_CIPHER_SUITE_CCMP_256: pn64 = atomic64_read(&key->u.ccmp.tx_pn); seq->ccmp.pn[5] = pn64; seq->ccmp.pn[4] = pn64 >> 8; @@ -836,7 +752,6 @@ void ieee80211_get_key_tx_seq(struct iee seq->ccmp.pn[0] = pn64 >> 40; break; case WLAN_CIPHER_SUITE_AES_CMAC: - case WLAN_CIPHER_SUITE_BIP_CMAC_256: pn64 = atomic64_read(&key->u.aes_cmac.tx_pn); seq->ccmp.pn[5] = pn64; seq->ccmp.pn[4] = pn64 >> 8; @@ -845,26 +760,6 @@ void ieee80211_get_key_tx_seq(struct iee seq->ccmp.pn[1] = pn64 >> 32; seq->ccmp.pn[0] = pn64 >> 40; break; - case WLAN_CIPHER_SUITE_BIP_GMAC_128: - case WLAN_CIPHER_SUITE_BIP_GMAC_256: - pn64 = atomic64_read(&key->u.aes_gmac.tx_pn); - seq->ccmp.pn[5] = pn64; - seq->ccmp.pn[4] = pn64 >> 8; - seq->ccmp.pn[3] = pn64 >> 16; - seq->ccmp.pn[2] = pn64 >> 24; - seq->ccmp.pn[1] = pn64 >> 32; - seq->ccmp.pn[0] = pn64 >> 40; - break; - case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: - pn64 = atomic64_read(&key->u.gcmp.tx_pn); - seq->gcmp.pn[5] = pn64; - seq->gcmp.pn[4] = pn64 >> 8; - seq->gcmp.pn[3] = pn64 >> 16; - seq->gcmp.pn[2] = pn64 >> 24; - seq->gcmp.pn[1] = pn64 >> 32; - seq->gcmp.pn[0] = pn64 >> 40; - break; default: WARN_ON(1); } @@ -887,7 +782,6 @@ void ieee80211_get_key_rx_seq(struct iee seq->tkip.iv16 = key->u.tkip.rx[tid].iv16; break; case WLAN_CIPHER_SUITE_CCMP: - case WLAN_CIPHER_SUITE_CCMP_256: if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS)) return; if (tid < 0) @@ -897,29 +791,11 @@ void ieee80211_get_key_rx_seq(struct iee memcpy(seq->ccmp.pn, pn, IEEE80211_CCMP_PN_LEN); break; case WLAN_CIPHER_SUITE_AES_CMAC: - case WLAN_CIPHER_SUITE_BIP_CMAC_256: if (WARN_ON(tid != 0)) return; pn = key->u.aes_cmac.rx_pn; memcpy(seq->aes_cmac.pn, pn, IEEE80211_CMAC_PN_LEN); break; - case WLAN_CIPHER_SUITE_BIP_GMAC_128: - case WLAN_CIPHER_SUITE_BIP_GMAC_256: - if (WARN_ON(tid != 0)) - return; - pn = key->u.aes_gmac.rx_pn; - memcpy(seq->aes_gmac.pn, pn, IEEE80211_GMAC_PN_LEN); - break; - case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: - if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS)) - return; - if (tid < 0) - pn = key->u.gcmp.rx_pn[IEEE80211_NUM_TIDS]; - else - pn = key->u.gcmp.rx_pn[tid]; - memcpy(seq->gcmp.pn, pn, IEEE80211_GCMP_PN_LEN); - break; } } EXPORT_SYMBOL(ieee80211_get_key_rx_seq); @@ -938,7 +814,6 @@ void ieee80211_set_key_tx_seq(struct iee key->u.tkip.tx.iv16 = seq->tkip.iv16; break; case WLAN_CIPHER_SUITE_CCMP: - case WLAN_CIPHER_SUITE_CCMP_256: pn64 = (u64)seq->ccmp.pn[5] | ((u64)seq->ccmp.pn[4] << 8) | ((u64)seq->ccmp.pn[3] << 16) | @@ -948,7 +823,6 @@ void ieee80211_set_key_tx_seq(struct iee atomic64_set(&key->u.ccmp.tx_pn, pn64); break; case WLAN_CIPHER_SUITE_AES_CMAC: - case WLAN_CIPHER_SUITE_BIP_CMAC_256: pn64 = (u64)seq->aes_cmac.pn[5] | ((u64)seq->aes_cmac.pn[4] << 8) | ((u64)seq->aes_cmac.pn[3] << 16) | @@ -957,26 +831,6 @@ void ieee80211_set_key_tx_seq(struct iee ((u64)seq->aes_cmac.pn[0] << 40); atomic64_set(&key->u.aes_cmac.tx_pn, pn64); break; - case WLAN_CIPHER_SUITE_BIP_GMAC_128: - case WLAN_CIPHER_SUITE_BIP_GMAC_256: - pn64 = (u64)seq->aes_gmac.pn[5] | - ((u64)seq->aes_gmac.pn[4] << 8) | - ((u64)seq->aes_gmac.pn[3] << 16) | - ((u64)seq->aes_gmac.pn[2] << 24) | - ((u64)seq->aes_gmac.pn[1] << 32) | - ((u64)seq->aes_gmac.pn[0] << 40); - atomic64_set(&key->u.aes_gmac.tx_pn, pn64); - break; - case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: - pn64 = (u64)seq->gcmp.pn[5] | - ((u64)seq->gcmp.pn[4] << 8) | - ((u64)seq->gcmp.pn[3] << 16) | - ((u64)seq->gcmp.pn[2] << 24) | - ((u64)seq->gcmp.pn[1] << 32) | - ((u64)seq->gcmp.pn[0] << 40); - atomic64_set(&key->u.gcmp.tx_pn, pn64); - break; default: WARN_ON(1); break; @@ -1000,7 +854,6 @@ void ieee80211_set_key_rx_seq(struct iee key->u.tkip.rx[tid].iv16 = seq->tkip.iv16; break; case WLAN_CIPHER_SUITE_CCMP: - case WLAN_CIPHER_SUITE_CCMP_256: if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS)) return; if (tid < 0) @@ -1010,29 +863,11 @@ void ieee80211_set_key_rx_seq(struct iee memcpy(pn, seq->ccmp.pn, IEEE80211_CCMP_PN_LEN); break; case WLAN_CIPHER_SUITE_AES_CMAC: - case WLAN_CIPHER_SUITE_BIP_CMAC_256: if (WARN_ON(tid != 0)) return; pn = key->u.aes_cmac.rx_pn; memcpy(pn, seq->aes_cmac.pn, IEEE80211_CMAC_PN_LEN); break; - case WLAN_CIPHER_SUITE_BIP_GMAC_128: - case WLAN_CIPHER_SUITE_BIP_GMAC_256: - if (WARN_ON(tid != 0)) - return; - pn = key->u.aes_gmac.rx_pn; - memcpy(pn, seq->aes_gmac.pn, IEEE80211_GMAC_PN_LEN); - break; - case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: - if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS)) - return; - if (tid < 0) - pn = key->u.gcmp.rx_pn[IEEE80211_NUM_TIDS]; - else - pn = key->u.gcmp.rx_pn[tid]; - memcpy(pn, seq->gcmp.pn, IEEE80211_GCMP_PN_LEN); - break; default: WARN_ON(1); break; --- a/net/mac80211/key.h +++ b/net/mac80211/key.h @@ -84,7 +84,7 @@ struct ieee80211_key { * Management frames. */ u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN]; - struct crypto_aead *tfm; + struct crypto_cipher *tfm; u32 replays; /* dot11RSNAStatsCCMPReplays */ } ccmp; struct { @@ -95,24 +95,6 @@ struct ieee80211_key { u32 icverrors; /* dot11RSNAStatsCMACICVErrors */ } aes_cmac; struct { - atomic64_t tx_pn; - u8 rx_pn[IEEE80211_GMAC_PN_LEN]; - struct crypto_aead *tfm; - u32 replays; /* dot11RSNAStatsCMACReplays */ - u32 icverrors; /* dot11RSNAStatsCMACICVErrors */ - } aes_gmac; - struct { - atomic64_t tx_pn; - /* Last received packet number. The first - * IEEE80211_NUM_TIDS counters are used with Data - * frames and the last counter is used with Robust - * Management frames. - */ - u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_GCMP_PN_LEN]; - struct crypto_aead *tfm; - u32 replays; /* dot11RSNAStatsGCMPReplays */ - } gcmp; - struct { /* generic cipher scheme */ u8 rx_pn[IEEE80211_NUM_TIDS + 1][MAX_PN_LEN]; } gen; --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -666,15 +666,9 @@ static int ieee80211_init_cipher_suites( WLAN_CIPHER_SUITE_WEP104, WLAN_CIPHER_SUITE_TKIP, WLAN_CIPHER_SUITE_CCMP, - WLAN_CIPHER_SUITE_CCMP_256, - WLAN_CIPHER_SUITE_GCMP, - WLAN_CIPHER_SUITE_GCMP_256, /* keep last -- depends on hw flags! */ - WLAN_CIPHER_SUITE_AES_CMAC, - WLAN_CIPHER_SUITE_BIP_CMAC_256, - WLAN_CIPHER_SUITE_BIP_GMAC_128, - WLAN_CIPHER_SUITE_BIP_GMAC_256, + WLAN_CIPHER_SUITE_AES_CMAC }; if (local->hw.flags & IEEE80211_HW_SW_CRYPTO_CONTROL || @@ -713,7 +707,7 @@ static int ieee80211_init_cipher_suites( local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); if (!have_mfp) - local->hw.wiphy->n_cipher_suites -= 4; + local->hw.wiphy->n_cipher_suites--; if (!have_wep) { local->hw.wiphy->cipher_suites += 2; @@ -730,42 +724,32 @@ static int ieee80211_init_cipher_suites( /* Driver specifies cipher schemes only (but not cipher suites * including the schemes) * - * We start counting ciphers defined by schemes, TKIP, CCMP, - * CCMP-256, GCMP, and GCMP-256 + * We start counting ciphers defined by schemes, TKIP and CCMP */ - n_suites = local->hw.n_cipher_schemes + 5; + n_suites = local->hw.n_cipher_schemes + 2; /* check if we have WEP40 and WEP104 */ if (have_wep) n_suites += 2; - /* check if we have AES_CMAC, BIP-CMAC-256, BIP-GMAC-128, - * BIP-GMAC-256 - */ + /* check if we have AES_CMAC */ if (have_mfp) - n_suites += 4; + n_suites++; suites = kmalloc(sizeof(u32) * n_suites, GFP_KERNEL); if (!suites) return -ENOMEM; suites[w++] = WLAN_CIPHER_SUITE_CCMP; - suites[w++] = WLAN_CIPHER_SUITE_CCMP_256; suites[w++] = WLAN_CIPHER_SUITE_TKIP; - suites[w++] = WLAN_CIPHER_SUITE_GCMP; - suites[w++] = WLAN_CIPHER_SUITE_GCMP_256; if (have_wep) { suites[w++] = WLAN_CIPHER_SUITE_WEP40; suites[w++] = WLAN_CIPHER_SUITE_WEP104; } - if (have_mfp) { + if (have_mfp) suites[w++] = WLAN_CIPHER_SUITE_AES_CMAC; - suites[w++] = WLAN_CIPHER_SUITE_BIP_CMAC_256; - suites[w++] = WLAN_CIPHER_SUITE_BIP_GMAC_128; - suites[w++] = WLAN_CIPHER_SUITE_BIP_GMAC_256; - } for (r = 0; r < local->hw.n_cipher_schemes; r++) suites[w++] = cs[r].cipher; --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -647,7 +647,6 @@ static int ieee80211_get_mmie_keyidx(str { struct ieee80211_mgmt *hdr = (struct ieee80211_mgmt *) skb->data; struct ieee80211_mmie *mmie; - struct ieee80211_mmie_16 *mmie16; if (skb->len < 24 + sizeof(*mmie) || !is_multicast_ether_addr(hdr->da)) return -1; @@ -657,18 +656,11 @@ static int ieee80211_get_mmie_keyidx(str mmie = (struct ieee80211_mmie *) (skb->data + skb->len - sizeof(*mmie)); - if (mmie->element_id == WLAN_EID_MMIE && - mmie->length == sizeof(*mmie) - 2) - return le16_to_cpu(mmie->key_id); - - mmie16 = (struct ieee80211_mmie_16 *) - (skb->data + skb->len - sizeof(*mmie16)); - if (skb->len >= 24 + sizeof(*mmie16) && - mmie16->element_id == WLAN_EID_MMIE && - mmie16->length == sizeof(*mmie16) - 2) - return le16_to_cpu(mmie16->key_id); + if (mmie->element_id != WLAN_EID_MMIE || + mmie->length != sizeof(*mmie) - 2) + return -1; - return -1; + return le16_to_cpu(mmie->key_id); } static int iwl80211_get_cs_keyid(const struct ieee80211_cipher_scheme *cs, @@ -1658,27 +1650,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_ result = ieee80211_crypto_tkip_decrypt(rx); break; case WLAN_CIPHER_SUITE_CCMP: - result = ieee80211_crypto_ccmp_decrypt( - rx, IEEE80211_CCMP_MIC_LEN); - break; - case WLAN_CIPHER_SUITE_CCMP_256: - result = ieee80211_crypto_ccmp_decrypt( - rx, IEEE80211_CCMP_256_MIC_LEN); + result = ieee80211_crypto_ccmp_decrypt(rx); break; case WLAN_CIPHER_SUITE_AES_CMAC: result = ieee80211_crypto_aes_cmac_decrypt(rx); break; - case WLAN_CIPHER_SUITE_BIP_CMAC_256: - result = ieee80211_crypto_aes_cmac_256_decrypt(rx); - break; - case WLAN_CIPHER_SUITE_BIP_GMAC_128: - case WLAN_CIPHER_SUITE_BIP_GMAC_256: - result = ieee80211_crypto_aes_gmac_decrypt(rx); - break; - case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: - result = ieee80211_crypto_gcmp_decrypt(rx); - break; default: result = ieee80211_crypto_hw_decrypt(rx); } @@ -1805,9 +1781,7 @@ ieee80211_rx_h_defragment(struct ieee802 /* This is the first fragment of a new frame. */ entry = ieee80211_reassemble_add(rx->sdata, frag, seq, rx->seqno_idx, &(rx->skb)); - if (rx->key && - (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP || - rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256) && + if (rx->key && rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP && ieee80211_has_protected(fc)) { int queue = rx->security_idx; /* Store CCMP PN so that we can verify that the next @@ -1836,9 +1810,7 @@ ieee80211_rx_h_defragment(struct ieee802 int i; u8 pn[IEEE80211_CCMP_PN_LEN], *rpn; int queue; - if (!rx->key || - (rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP && - rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256)) + if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP) return RX_DROP_UNUSABLE; memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN); for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) { --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -626,9 +626,6 @@ ieee80211_tx_h_select_key(struct ieee802 tx->key = NULL; break; case WLAN_CIPHER_SUITE_CCMP: - case WLAN_CIPHER_SUITE_CCMP_256: - case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: if (!ieee80211_is_data_present(hdr->frame_control) && !ieee80211_use_mfp(hdr->frame_control, tx->sta, tx->skb)) @@ -639,9 +636,6 @@ ieee80211_tx_h_select_key(struct ieee802 ieee80211_is_mgmt(hdr->frame_control); break; case WLAN_CIPHER_SUITE_AES_CMAC: - case WLAN_CIPHER_SUITE_BIP_CMAC_256: - case WLAN_CIPHER_SUITE_BIP_GMAC_128: - case WLAN_CIPHER_SUITE_BIP_GMAC_256: if (!ieee80211_is_mgmt(hdr->frame_control)) tx->key = NULL; break; @@ -1017,21 +1011,9 @@ ieee80211_tx_h_encrypt(struct ieee80211_ case WLAN_CIPHER_SUITE_TKIP: return ieee80211_crypto_tkip_encrypt(tx); case WLAN_CIPHER_SUITE_CCMP: - return ieee80211_crypto_ccmp_encrypt( - tx, IEEE80211_CCMP_MIC_LEN); - case WLAN_CIPHER_SUITE_CCMP_256: - return ieee80211_crypto_ccmp_encrypt( - tx, IEEE80211_CCMP_256_MIC_LEN); + return ieee80211_crypto_ccmp_encrypt(tx); case WLAN_CIPHER_SUITE_AES_CMAC: return ieee80211_crypto_aes_cmac_encrypt(tx); - case WLAN_CIPHER_SUITE_BIP_CMAC_256: - return ieee80211_crypto_aes_cmac_256_encrypt(tx); - case WLAN_CIPHER_SUITE_BIP_GMAC_128: - case WLAN_CIPHER_SUITE_BIP_GMAC_256: - return ieee80211_crypto_aes_gmac_encrypt(tx); - case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: - return ieee80211_crypto_gcmp_encrypt(tx); default: return ieee80211_crypto_hw_encrypt(tx); } --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -22,8 +22,6 @@ #include "tkip.h" #include "aes_ccm.h" #include "aes_cmac.h" -#include "aes_gmac.h" -#include "aes_gcm.h" #include "wpa.h" ieee80211_tx_result @@ -304,15 +302,22 @@ ieee80211_crypto_tkip_decrypt(struct iee } -static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad) +static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch, + int encrypted) { __le16 mask_fc; int a4_included, mgmt; u8 qos_tid; - u16 len_a; + u8 *b_0, *aad; + u16 data_len, len_a; unsigned int hdrlen; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + memset(scratch, 0, 6 * AES_BLOCK_SIZE); + + b_0 = scratch + 3 * AES_BLOCK_SIZE; + aad = scratch + 4 * AES_BLOCK_SIZE; + /* * Mask FC: zero subtype b4 b5 b6 (if not mgmt) * Retry, PwrMgt, MoreData; set Protected @@ -334,21 +339,20 @@ static void ccmp_special_blocks(struct s else qos_tid = 0; - /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC - * mode authentication are not allowed to collide, yet both are derived - * from this vector b_0. We only set L := 1 here to indicate that the - * data size can be represented in (L+1) bytes. The CCM layer will take - * care of storing the data length in the top (L+1) bytes and setting - * and clearing the other bits as is required to derive the two IVs. - */ - b_0[0] = 0x1; + data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN; + if (encrypted) + data_len -= IEEE80211_CCMP_MIC_LEN; + /* First block, b_0 */ + b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ /* Nonce: Nonce Flags | A2 | PN * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7) */ b_0[1] = qos_tid | (mgmt << 4); memcpy(&b_0[2], hdr->addr2, ETH_ALEN); memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN); + /* l(m) */ + put_unaligned_be16(data_len, &b_0[14]); /* AAD (extra authenticate-only data) / masked 802.11 header * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ @@ -395,8 +399,7 @@ static inline void ccmp_hdr2pn(u8 *pn, u } -static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb, - unsigned int mic_len) +static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_key *key = tx->key; @@ -405,8 +408,7 @@ static int ccmp_encrypt_skb(struct ieee8 u8 *pos; u8 pn[6]; u64 pn64; - u8 aad[2 * AES_BLOCK_SIZE]; - u8 b_0[AES_BLOCK_SIZE]; + u8 scratch[6 * AES_BLOCK_SIZE]; if (info->control.hw_key && !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) && @@ -427,7 +429,7 @@ static int ccmp_encrypt_skb(struct ieee8 if (info->control.hw_key) tail = 0; else - tail = mic_len; + tail = IEEE80211_CCMP_MIC_LEN; if (WARN_ON(skb_tailroom(skb) < tail || skb_headroom(skb) < IEEE80211_CCMP_HDR_LEN)) @@ -460,24 +462,23 @@ static int ccmp_encrypt_skb(struct ieee8 return 0; pos += IEEE80211_CCMP_HDR_LEN; - ccmp_special_blocks(skb, pn, b_0, aad); - ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, - skb_put(skb, mic_len), mic_len); + ccmp_special_blocks(skb, pn, scratch, 0); + ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len, + pos, skb_put(skb, IEEE80211_CCMP_MIC_LEN)); return 0; } ieee80211_tx_result -ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx, - unsigned int mic_len) +ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx) { struct sk_buff *skb; ieee80211_tx_set_protected(tx); skb_queue_walk(&tx->skbs, skb) { - if (ccmp_encrypt_skb(tx, skb, mic_len) < 0) + if (ccmp_encrypt_skb(tx, skb) < 0) return TX_DROP; } @@ -486,8 +487,7 @@ ieee80211_crypto_ccmp_encrypt(struct iee ieee80211_rx_result -ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx, - unsigned int mic_len) +ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; int hdrlen; @@ -504,7 +504,8 @@ ieee80211_crypto_ccmp_decrypt(struct iee !ieee80211_is_robust_mgmt_frame(skb)) return RX_CONTINUE; - data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - mic_len; + data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - + IEEE80211_CCMP_MIC_LEN; if (!rx->sta || data_len < 0) return RX_DROP_UNUSABLE; @@ -526,23 +527,23 @@ ieee80211_crypto_ccmp_decrypt(struct iee } if (!(status->flag & RX_FLAG_DECRYPTED)) { - u8 aad[2 * AES_BLOCK_SIZE]; - u8 b_0[AES_BLOCK_SIZE]; + u8 scratch[6 * AES_BLOCK_SIZE]; /* hardware didn't decrypt/verify MIC */ - ccmp_special_blocks(skb, pn, b_0, aad); + ccmp_special_blocks(skb, pn, scratch, 1); if (ieee80211_aes_ccm_decrypt( - key->u.ccmp.tfm, b_0, aad, + key->u.ccmp.tfm, scratch, skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN, data_len, - skb->data + skb->len - mic_len, mic_len)) + skb->data + skb->len - IEEE80211_CCMP_MIC_LEN, + skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN)) return RX_DROP_UNUSABLE; } memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN); /* Remove CCMP header and MIC */ - if (pskb_trim(skb, skb->len - mic_len)) + if (pskb_trim(skb, skb->len - IEEE80211_CCMP_MIC_LEN)) return RX_DROP_UNUSABLE; memmove(skb->data + IEEE80211_CCMP_HDR_LEN, skb->data, hdrlen); skb_pull(skb, IEEE80211_CCMP_HDR_LEN); @@ -550,229 +551,6 @@ ieee80211_crypto_ccmp_decrypt(struct iee return RX_CONTINUE; } -static void gcmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *j_0, u8 *aad) -{ - __le16 mask_fc; - u8 qos_tid; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - - memcpy(j_0, hdr->addr2, ETH_ALEN); - memcpy(&j_0[ETH_ALEN], pn, IEEE80211_GCMP_PN_LEN); - j_0[13] = 0; - j_0[14] = 0; - j_0[AES_BLOCK_SIZE - 1] = 0x01; - - /* AAD (extra authenticate-only data) / masked 802.11 header - * FC | A1 | A2 | A3 | SC | [A4] | [QC] - */ - put_unaligned_be16(ieee80211_hdrlen(hdr->frame_control) - 2, &aad[0]); - /* Mask FC: zero subtype b4 b5 b6 (if not mgmt) - * Retry, PwrMgt, MoreData; set Protected - */ - mask_fc = hdr->frame_control; - mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY | - IEEE80211_FCTL_PM | IEEE80211_FCTL_MOREDATA); - if (!ieee80211_is_mgmt(hdr->frame_control)) - mask_fc &= ~cpu_to_le16(0x0070); - mask_fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); - - put_unaligned(mask_fc, (__le16 *)&aad[2]); - memcpy(&aad[4], &hdr->addr1, 3 * ETH_ALEN); - - /* Mask Seq#, leave Frag# */ - aad[22] = *((u8 *)&hdr->seq_ctrl) & 0x0f; - aad[23] = 0; - - if (ieee80211_is_data_qos(hdr->frame_control)) - qos_tid = *ieee80211_get_qos_ctl(hdr) & - IEEE80211_QOS_CTL_TID_MASK; - else - qos_tid = 0; - - if (ieee80211_has_a4(hdr->frame_control)) { - memcpy(&aad[24], hdr->addr4, ETH_ALEN); - aad[30] = qos_tid; - aad[31] = 0; - } else { - memset(&aad[24], 0, ETH_ALEN + IEEE80211_QOS_CTL_LEN); - aad[24] = qos_tid; - } -} - -static inline void gcmp_pn2hdr(u8 *hdr, const u8 *pn, int key_id) -{ - hdr[0] = pn[5]; - hdr[1] = pn[4]; - hdr[2] = 0; - hdr[3] = 0x20 | (key_id << 6); - hdr[4] = pn[3]; - hdr[5] = pn[2]; - hdr[6] = pn[1]; - hdr[7] = pn[0]; -} - -static inline void gcmp_hdr2pn(u8 *pn, const u8 *hdr) -{ - pn[0] = hdr[7]; - pn[1] = hdr[6]; - pn[2] = hdr[5]; - pn[3] = hdr[4]; - pn[4] = hdr[1]; - pn[5] = hdr[0]; -} - -static int gcmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_key *key = tx->key; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - int hdrlen, len, tail; - u8 *pos; - u8 pn[6]; - u64 pn64; - u8 aad[2 * AES_BLOCK_SIZE]; - u8 j_0[AES_BLOCK_SIZE]; - - if (info->control.hw_key && - !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) && - !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) && - !((info->control.hw_key->flags & - IEEE80211_KEY_FLAG_GENERATE_IV_MGMT) && - ieee80211_is_mgmt(hdr->frame_control))) { - /* hwaccel has no need for preallocated room for GCMP - * header or MIC fields - */ - return 0; - } - - hdrlen = ieee80211_hdrlen(hdr->frame_control); - len = skb->len - hdrlen; - - if (info->control.hw_key) - tail = 0; - else - tail = IEEE80211_GCMP_MIC_LEN; - - if (WARN_ON(skb_tailroom(skb) < tail || - skb_headroom(skb) < IEEE80211_GCMP_HDR_LEN)) - return -1; - - pos = skb_push(skb, IEEE80211_GCMP_HDR_LEN); - memmove(pos, pos + IEEE80211_GCMP_HDR_LEN, hdrlen); - skb_set_network_header(skb, skb_network_offset(skb) + - IEEE80211_GCMP_HDR_LEN); - - /* the HW only needs room for the IV, but not the actual IV */ - if (info->control.hw_key && - (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) - return 0; - - hdr = (struct ieee80211_hdr *)pos; - pos += hdrlen; - - pn64 = atomic64_inc_return(&key->u.gcmp.tx_pn); - - pn[5] = pn64; - pn[4] = pn64 >> 8; - pn[3] = pn64 >> 16; - pn[2] = pn64 >> 24; - pn[1] = pn64 >> 32; - pn[0] = pn64 >> 40; - - gcmp_pn2hdr(pos, pn, key->conf.keyidx); - - /* hwaccel - with software GCMP header */ - if (info->control.hw_key) - return 0; - - pos += IEEE80211_GCMP_HDR_LEN; - gcmp_special_blocks(skb, pn, j_0, aad); - ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len, - skb_put(skb, IEEE80211_GCMP_MIC_LEN)); - - return 0; -} - -ieee80211_tx_result -ieee80211_crypto_gcmp_encrypt(struct ieee80211_tx_data *tx) -{ - struct sk_buff *skb; - - ieee80211_tx_set_protected(tx); - - skb_queue_walk(&tx->skbs, skb) { - if (gcmp_encrypt_skb(tx, skb) < 0) - return TX_DROP; - } - - return TX_CONTINUE; -} - -ieee80211_rx_result -ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; - int hdrlen; - struct ieee80211_key *key = rx->key; - struct sk_buff *skb = rx->skb; - struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); - u8 pn[IEEE80211_GCMP_PN_LEN]; - int data_len; - int queue; - - hdrlen = ieee80211_hdrlen(hdr->frame_control); - - if (!ieee80211_is_data(hdr->frame_control) && - !ieee80211_is_robust_mgmt_frame(skb)) - return RX_CONTINUE; - - data_len = skb->len - hdrlen - IEEE80211_GCMP_HDR_LEN - - IEEE80211_GCMP_MIC_LEN; - if (!rx->sta || data_len < 0) - return RX_DROP_UNUSABLE; - - if (status->flag & RX_FLAG_DECRYPTED) { - if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_GCMP_HDR_LEN)) - return RX_DROP_UNUSABLE; - } else { - if (skb_linearize(rx->skb)) - return RX_DROP_UNUSABLE; - } - - gcmp_hdr2pn(pn, skb->data + hdrlen); - - queue = rx->security_idx; - - if (memcmp(pn, key->u.gcmp.rx_pn[queue], IEEE80211_GCMP_PN_LEN) <= 0) { - key->u.gcmp.replays++; - return RX_DROP_UNUSABLE; - } - - if (!(status->flag & RX_FLAG_DECRYPTED)) { - u8 aad[2 * AES_BLOCK_SIZE]; - u8 j_0[AES_BLOCK_SIZE]; - /* hardware didn't decrypt/verify MIC */ - gcmp_special_blocks(skb, pn, j_0, aad); - - if (ieee80211_aes_gcm_decrypt( - key->u.gcmp.tfm, j_0, aad, - skb->data + hdrlen + IEEE80211_GCMP_HDR_LEN, - data_len, - skb->data + skb->len - IEEE80211_GCMP_MIC_LEN)) - return RX_DROP_UNUSABLE; - } - - memcpy(key->u.gcmp.rx_pn[queue], pn, IEEE80211_GCMP_PN_LEN); - - /* Remove GCMP header and MIC */ - if (pskb_trim(skb, skb->len - IEEE80211_GCMP_MIC_LEN)) - return RX_DROP_UNUSABLE; - memmove(skb->data + IEEE80211_GCMP_HDR_LEN, skb->data, hdrlen); - skb_pull(skb, IEEE80211_GCMP_HDR_LEN); - - return RX_CONTINUE; -} - static ieee80211_tx_result ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx, struct sk_buff *skb) @@ -956,48 +734,6 @@ ieee80211_crypto_aes_cmac_encrypt(struct return TX_CONTINUE; } -ieee80211_tx_result -ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx) -{ - struct sk_buff *skb; - struct ieee80211_tx_info *info; - struct ieee80211_key *key = tx->key; - struct ieee80211_mmie_16 *mmie; - u8 aad[20]; - u64 pn64; - - if (WARN_ON(skb_queue_len(&tx->skbs) != 1)) - return TX_DROP; - - skb = skb_peek(&tx->skbs); - - info = IEEE80211_SKB_CB(skb); - - if (info->control.hw_key) - return TX_CONTINUE; - - if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie))) - return TX_DROP; - - mmie = (struct ieee80211_mmie_16 *)skb_put(skb, sizeof(*mmie)); - mmie->element_id = WLAN_EID_MMIE; - mmie->length = sizeof(*mmie) - 2; - mmie->key_id = cpu_to_le16(key->conf.keyidx); - - /* PN = PN + 1 */ - pn64 = atomic64_inc_return(&key->u.aes_cmac.tx_pn); - - bip_ipn_set64(mmie->sequence_number, pn64); - - bip_aad(skb, aad); - - /* MIC = AES-256-CMAC(IGTK, AAD || Management Frame Body || MMIE, 128) - */ - ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, - skb->data + 24, skb->len - 24, mmie->mic); - - return TX_CONTINUE; -} ieee80211_rx_result ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) @@ -1045,160 +781,6 @@ ieee80211_crypto_aes_cmac_decrypt(struct /* Remove MMIE */ skb_trim(skb, skb->len - sizeof(*mmie)); - - return RX_CONTINUE; -} - -ieee80211_rx_result -ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx) -{ - struct sk_buff *skb = rx->skb; - struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); - struct ieee80211_key *key = rx->key; - struct ieee80211_mmie_16 *mmie; - u8 aad[20], mic[16], ipn[6]; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - - if (!ieee80211_is_mgmt(hdr->frame_control)) - return RX_CONTINUE; - - /* management frames are already linear */ - - if (skb->len < 24 + sizeof(*mmie)) - return RX_DROP_UNUSABLE; - - mmie = (struct ieee80211_mmie_16 *) - (skb->data + skb->len - sizeof(*mmie)); - if (mmie->element_id != WLAN_EID_MMIE || - mmie->length != sizeof(*mmie) - 2) - return RX_DROP_UNUSABLE; /* Invalid MMIE */ - - bip_ipn_swap(ipn, mmie->sequence_number); - - if (memcmp(ipn, key->u.aes_cmac.rx_pn, 6) <= 0) { - key->u.aes_cmac.replays++; - return RX_DROP_UNUSABLE; - } - - if (!(status->flag & RX_FLAG_DECRYPTED)) { - /* hardware didn't decrypt/verify MIC */ - bip_aad(skb, aad); - ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, - skb->data + 24, skb->len - 24, mic); - if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) { - key->u.aes_cmac.icverrors++; - return RX_DROP_UNUSABLE; - } - } - - memcpy(key->u.aes_cmac.rx_pn, ipn, 6); - - /* Remove MMIE */ - skb_trim(skb, skb->len - sizeof(*mmie)); - - return RX_CONTINUE; -} - -ieee80211_tx_result -ieee80211_crypto_aes_gmac_encrypt(struct ieee80211_tx_data *tx) -{ - struct sk_buff *skb; - struct ieee80211_tx_info *info; - struct ieee80211_key *key = tx->key; - struct ieee80211_mmie_16 *mmie; - struct ieee80211_hdr *hdr; - u8 aad[20]; - u64 pn64; - u8 nonce[12]; - - if (WARN_ON(skb_queue_len(&tx->skbs) != 1)) - return TX_DROP; - - skb = skb_peek(&tx->skbs); - - info = IEEE80211_SKB_CB(skb); - - if (info->control.hw_key) - return TX_CONTINUE; - - if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie))) - return TX_DROP; - - mmie = (struct ieee80211_mmie_16 *)skb_put(skb, sizeof(*mmie)); - mmie->element_id = WLAN_EID_MMIE; - mmie->length = sizeof(*mmie) - 2; - mmie->key_id = cpu_to_le16(key->conf.keyidx); - - /* PN = PN + 1 */ - pn64 = atomic64_inc_return(&key->u.aes_gmac.tx_pn); - - bip_ipn_set64(mmie->sequence_number, pn64); - - bip_aad(skb, aad); - - hdr = (struct ieee80211_hdr *)skb->data; - memcpy(nonce, hdr->addr2, ETH_ALEN); - bip_ipn_swap(nonce + ETH_ALEN, mmie->sequence_number); - - /* MIC = AES-GMAC(IGTK, AAD || Management Frame Body || MMIE, 128) */ - if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce, - skb->data + 24, skb->len - 24, mmie->mic) < 0) - return TX_DROP; - - return TX_CONTINUE; -} - -ieee80211_rx_result -ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx) -{ - struct sk_buff *skb = rx->skb; - struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); - struct ieee80211_key *key = rx->key; - struct ieee80211_mmie_16 *mmie; - u8 aad[20], mic[16], ipn[6], nonce[12]; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - - if (!ieee80211_is_mgmt(hdr->frame_control)) - return RX_CONTINUE; - - /* management frames are already linear */ - - if (skb->len < 24 + sizeof(*mmie)) - return RX_DROP_UNUSABLE; - - mmie = (struct ieee80211_mmie_16 *) - (skb->data + skb->len - sizeof(*mmie)); - if (mmie->element_id != WLAN_EID_MMIE || - mmie->length != sizeof(*mmie) - 2) - return RX_DROP_UNUSABLE; /* Invalid MMIE */ - - bip_ipn_swap(ipn, mmie->sequence_number); - - if (memcmp(ipn, key->u.aes_gmac.rx_pn, 6) <= 0) { - key->u.aes_gmac.replays++; - return RX_DROP_UNUSABLE; - } - - if (!(status->flag & RX_FLAG_DECRYPTED)) { - /* hardware didn't decrypt/verify MIC */ - bip_aad(skb, aad); - - memcpy(nonce, hdr->addr2, ETH_ALEN); - memcpy(nonce + ETH_ALEN, ipn, 6); - - if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce, - skb->data + 24, skb->len - 24, - mic) < 0 || - memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) { - key->u.aes_gmac.icverrors++; - return RX_DROP_UNUSABLE; - } - } - - memcpy(key->u.aes_gmac.rx_pn, ipn, 6); - - /* Remove MMIE */ - skb_trim(skb, skb->len - sizeof(*mmie)); return RX_CONTINUE; } --- a/net/mac80211/wpa.h +++ b/net/mac80211/wpa.h @@ -24,32 +24,17 @@ ieee80211_rx_result ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx); ieee80211_tx_result -ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx, - unsigned int mic_len); +ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx); ieee80211_rx_result -ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx, - unsigned int mic_len); +ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx); ieee80211_tx_result ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx); -ieee80211_tx_result -ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx); ieee80211_rx_result ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx); -ieee80211_rx_result -ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx); -ieee80211_tx_result -ieee80211_crypto_aes_gmac_encrypt(struct ieee80211_tx_data *tx); -ieee80211_rx_result -ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx); ieee80211_tx_result ieee80211_crypto_hw_encrypt(struct ieee80211_tx_data *tx); ieee80211_rx_result ieee80211_crypto_hw_decrypt(struct ieee80211_rx_data *rx); -ieee80211_tx_result -ieee80211_crypto_gcmp_encrypt(struct ieee80211_tx_data *tx); -ieee80211_rx_result -ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx); - #endif /* WPA_H */