|
@@ -18,21 +18,24 @@
|
|
|
#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)
|
|
|
+int 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)
|
|
|
{
|
|
|
struct scatterlist sg[3];
|
|
|
+ struct aead_request *aead_req;
|
|
|
+ int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
|
|
|
+ u8 *__aad;
|
|
|
|
|
|
- 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;
|
|
|
+ aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC);
|
|
|
+ if (!aead_req)
|
|
|
+ return -ENOMEM;
|
|
|
|
|
|
- memset(aead_req, 0, sizeof(aead_req_data));
|
|
|
+ __aad = (u8 *)aead_req + reqsize;
|
|
|
+ memcpy(__aad, aad, CCM_AAD_LEN);
|
|
|
|
|
|
sg_init_table(sg, 3);
|
|
|
- sg_set_buf(&sg[0], &aad[2], be16_to_cpup((__be16 *)aad));
|
|
|
+ sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
|
|
|
sg_set_buf(&sg[1], data, data_len);
|
|
|
sg_set_buf(&sg[2], mic, mic_len);
|
|
|
|
|
@@ -41,6 +44,9 @@ void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
|
|
|
aead_request_set_ad(aead_req, sg[0].length);
|
|
|
|
|
|
crypto_aead_encrypt(aead_req);
|
|
|
+ kzfree(aead_req);
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
|
|
@@ -48,18 +54,23 @@ int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
|
|
|
size_t mic_len)
|
|
|
{
|
|
|
struct scatterlist sg[3];
|
|
|
- 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;
|
|
|
+ struct aead_request *aead_req;
|
|
|
+ int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
|
|
|
+ u8 *__aad;
|
|
|
+ int err;
|
|
|
|
|
|
if (data_len == 0)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- memset(aead_req, 0, sizeof(aead_req_data));
|
|
|
+ aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC);
|
|
|
+ if (!aead_req)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ __aad = (u8 *)aead_req + reqsize;
|
|
|
+ memcpy(__aad, aad, CCM_AAD_LEN);
|
|
|
|
|
|
sg_init_table(sg, 3);
|
|
|
- sg_set_buf(&sg[0], &aad[2], be16_to_cpup((__be16 *)aad));
|
|
|
+ sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
|
|
|
sg_set_buf(&sg[1], data, data_len);
|
|
|
sg_set_buf(&sg[2], mic, mic_len);
|
|
|
|
|
@@ -67,7 +78,10 @@ int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
|
|
|
aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0);
|
|
|
aead_request_set_ad(aead_req, sg[0].length);
|
|
|
|
|
|
- return crypto_aead_decrypt(aead_req);
|
|
|
+ err = crypto_aead_decrypt(aead_req);
|
|
|
+ kzfree(aead_req);
|
|
|
+
|
|
|
+ return err;
|
|
|
}
|
|
|
|
|
|
struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
|