summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorXiang Gao <qasdfgtyuiop@gmail.com>2017-10-10 22:31:49 -0400
committerJohannes Berg <johannes.berg@intel.com>2017-10-11 03:37:35 -0400
commit4133da73067af0417c623eb4ad5e85081ccbf4b4 (patch)
tree86ca2fa1fd06c84662778f34b8de6d01e3c9ede4 /net
parent8c03145a2e2d98d44dba4bf16ab34636eb60b834 (diff)
mac80211: aead api to reduce redundancy
Currently, the aes_ccm.c and aes_gcm.c are almost line by line copy of each other. This patch reduce code redundancy by moving the code in these two files to crypto/aead_api.c to make it a higher level aead api. The file aes_ccm.c and aes_gcm.c are removed and all the functions there are now implemented in their headers using the newly added aead api. Signed-off-by: Xiang Gao <qasdfgtyuiop@gmail.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/Makefile3
-rw-r--r--net/mac80211/aead_api.c (renamed from net/mac80211/aes_ccm.c)40
-rw-r--r--net/mac80211/aead_api.h27
-rw-r--r--net/mac80211/aes_ccm.h42
-rw-r--r--net/mac80211/aes_gcm.c109
-rw-r--r--net/mac80211/aes_gcm.h38
-rw-r--r--net/mac80211/wpa.c4
7 files changed, 111 insertions, 152 deletions
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 282912245938..80f25ff2f24b 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -6,6 +6,7 @@ mac80211-y := \
6 driver-ops.o \ 6 driver-ops.o \
7 sta_info.o \ 7 sta_info.o \
8 wep.o \ 8 wep.o \
9 aead_api.o \
9 wpa.o \ 10 wpa.o \
10 scan.o offchannel.o \ 11 scan.o offchannel.o \
11 ht.o agg-tx.o agg-rx.o \ 12 ht.o agg-tx.o agg-rx.o \
@@ -15,8 +16,6 @@ mac80211-y := \
15 rate.o \ 16 rate.o \
16 michael.o \ 17 michael.o \
17 tkip.o \ 18 tkip.o \
18 aes_ccm.o \
19 aes_gcm.o \
20 aes_cmac.o \ 19 aes_cmac.o \
21 aes_gmac.o \ 20 aes_gmac.o \
22 fils_aead.o \ 21 fils_aead.o \
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aead_api.c
index a4e0d59a40dd..347f13953b2c 100644
--- a/net/mac80211/aes_ccm.c
+++ b/net/mac80211/aead_api.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright 2003-2004, Instant802 Networks, Inc. 2 * Copyright 2003-2004, Instant802 Networks, Inc.
3 * Copyright 2005-2006, Devicescape Software, Inc. 3 * Copyright 2005-2006, Devicescape Software, Inc.
4 * Copyright 2014-2015, Qualcomm Atheros, Inc.
4 * 5 *
5 * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org> 6 * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
6 * 7 *
@@ -12,30 +13,29 @@
12#include <linux/kernel.h> 13#include <linux/kernel.h>
13#include <linux/types.h> 14#include <linux/types.h>
14#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/scatterlist.h>
15#include <crypto/aead.h> 17#include <crypto/aead.h>
16 18
17#include <net/mac80211.h> 19#include "aead_api.h"
18#include "key.h"
19#include "aes_ccm.h"
20 20
21int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, 21int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len,
22 u8 *data, size_t data_len, u8 *mic, 22 u8 *data, size_t data_len, u8 *mic)
23 size_t mic_len)
24{ 23{
24 size_t mic_len = tfm->authsize;
25 struct scatterlist sg[3]; 25 struct scatterlist sg[3];
26 struct aead_request *aead_req; 26 struct aead_request *aead_req;
27 int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); 27 int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
28 u8 *__aad; 28 u8 *__aad;
29 29
30 aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC); 30 aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
31 if (!aead_req) 31 if (!aead_req)
32 return -ENOMEM; 32 return -ENOMEM;
33 33
34 __aad = (u8 *)aead_req + reqsize; 34 __aad = (u8 *)aead_req + reqsize;
35 memcpy(__aad, aad, CCM_AAD_LEN); 35 memcpy(__aad, aad, aad_len);
36 36
37 sg_init_table(sg, 3); 37 sg_init_table(sg, 3);
38 sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad)); 38 sg_set_buf(&sg[0], __aad, aad_len);
39 sg_set_buf(&sg[1], data, data_len); 39 sg_set_buf(&sg[1], data, data_len);
40 sg_set_buf(&sg[2], mic, mic_len); 40 sg_set_buf(&sg[2], mic, mic_len);
41 41
@@ -49,10 +49,10 @@ int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
49 return 0; 49 return 0;
50} 50}
51 51
52int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, 52int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len,
53 u8 *data, size_t data_len, u8 *mic, 53 u8 *data, size_t data_len, u8 *mic)
54 size_t mic_len)
55{ 54{
55 size_t mic_len = tfm->authsize;
56 struct scatterlist sg[3]; 56 struct scatterlist sg[3];
57 struct aead_request *aead_req; 57 struct aead_request *aead_req;
58 int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); 58 int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
@@ -62,15 +62,15 @@ int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
62 if (data_len == 0) 62 if (data_len == 0)
63 return -EINVAL; 63 return -EINVAL;
64 64
65 aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC); 65 aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
66 if (!aead_req) 66 if (!aead_req)
67 return -ENOMEM; 67 return -ENOMEM;
68 68
69 __aad = (u8 *)aead_req + reqsize; 69 __aad = (u8 *)aead_req + reqsize;
70 memcpy(__aad, aad, CCM_AAD_LEN); 70 memcpy(__aad, aad, aad_len);
71 71
72 sg_init_table(sg, 3); 72 sg_init_table(sg, 3);
73 sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad)); 73 sg_set_buf(&sg[0], __aad, aad_len);
74 sg_set_buf(&sg[1], data, data_len); 74 sg_set_buf(&sg[1], data, data_len);
75 sg_set_buf(&sg[2], mic, mic_len); 75 sg_set_buf(&sg[2], mic, mic_len);
76 76
@@ -84,14 +84,14 @@ int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
84 return err; 84 return err;
85} 85}
86 86
87struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[], 87struct crypto_aead *
88 size_t key_len, 88aead_key_setup_encrypt(const char *alg, const u8 key[],
89 size_t mic_len) 89 size_t key_len, size_t mic_len)
90{ 90{
91 struct crypto_aead *tfm; 91 struct crypto_aead *tfm;
92 int err; 92 int err;
93 93
94 tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC); 94 tfm = crypto_alloc_aead(alg, 0, CRYPTO_ALG_ASYNC);
95 if (IS_ERR(tfm)) 95 if (IS_ERR(tfm))
96 return tfm; 96 return tfm;
97 97
@@ -109,7 +109,7 @@ free_aead:
109 return ERR_PTR(err); 109 return ERR_PTR(err);
110} 110}
111 111
112void ieee80211_aes_key_free(struct crypto_aead *tfm) 112void aead_key_free(struct crypto_aead *tfm)
113{ 113{
114 crypto_free_aead(tfm); 114 crypto_free_aead(tfm);
115} 115}
diff --git a/net/mac80211/aead_api.h b/net/mac80211/aead_api.h
new file mode 100644
index 000000000000..5e39ea843bbf
--- /dev/null
+++ b/net/mac80211/aead_api.h
@@ -0,0 +1,27 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 */
6
7#ifndef _AEAD_API_H
8#define _AEAD_API_H
9
10#include <crypto/aead.h>
11#include <linux/crypto.h>
12
13struct crypto_aead *
14aead_key_setup_encrypt(const char *alg, const u8 key[],
15 size_t key_len, size_t mic_len);
16
17int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
18 size_t aad_len, u8 *data,
19 size_t data_len, u8 *mic);
20
21int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
22 size_t aad_len, u8 *data,
23 size_t data_len, u8 *mic);
24
25void aead_key_free(struct crypto_aead *tfm);
26
27#endif /* _AEAD_API_H */
diff --git a/net/mac80211/aes_ccm.h b/net/mac80211/aes_ccm.h
index fcd3254c5cf0..e9b7ca0bde5b 100644
--- a/net/mac80211/aes_ccm.h
+++ b/net/mac80211/aes_ccm.h
@@ -10,19 +10,39 @@
10#ifndef AES_CCM_H 10#ifndef AES_CCM_H
11#define AES_CCM_H 11#define AES_CCM_H
12 12
13#include <linux/crypto.h> 13#include "aead_api.h"
14 14
15#define CCM_AAD_LEN 32 15#define CCM_AAD_LEN 32
16 16
17struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[], 17static inline struct crypto_aead *
18 size_t key_len, 18ieee80211_aes_key_setup_encrypt(const u8 key[], size_t key_len, size_t mic_len)
19 size_t mic_len); 19{
20int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, 20 return aead_key_setup_encrypt("ccm(aes)", key, key_len, mic_len);
21 u8 *data, size_t data_len, u8 *mic, 21}
22 size_t mic_len); 22
23int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, 23static inline int
24 u8 *data, size_t data_len, u8 *mic, 24ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm,
25 size_t mic_len); 25 u8 *b_0, u8 *aad, u8 *data,
26void ieee80211_aes_key_free(struct crypto_aead *tfm); 26 size_t data_len, u8 *mic)
27{
28 return aead_encrypt(tfm, b_0, aad + 2,
29 be16_to_cpup((__be16 *)aad),
30 data, data_len, mic);
31}
32
33static inline int
34ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm,
35 u8 *b_0, u8 *aad, u8 *data,
36 size_t data_len, u8 *mic)
37{
38 return aead_decrypt(tfm, b_0, aad + 2,
39 be16_to_cpup((__be16 *)aad),
40 data, data_len, mic);
41}
42
43static inline void ieee80211_aes_key_free(struct crypto_aead *tfm)
44{
45 return aead_key_free(tfm);
46}
27 47
28#endif /* AES_CCM_H */ 48#endif /* AES_CCM_H */
diff --git a/net/mac80211/aes_gcm.c b/net/mac80211/aes_gcm.c
deleted file mode 100644
index 8a4397cc1b08..000000000000
--- a/net/mac80211/aes_gcm.c
+++ /dev/null
@@ -1,109 +0,0 @@
1/*
2 * Copyright 2014-2015, Qualcomm Atheros, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/kernel.h>
10#include <linux/types.h>
11#include <linux/err.h>
12#include <crypto/aead.h>
13
14#include <net/mac80211.h>
15#include "key.h"
16#include "aes_gcm.h"
17
18int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
19 u8 *data, size_t data_len, u8 *mic)
20{
21 struct scatterlist sg[3];
22 struct aead_request *aead_req;
23 int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
24 u8 *__aad;
25
26 aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC);
27 if (!aead_req)
28 return -ENOMEM;
29
30 __aad = (u8 *)aead_req + reqsize;
31 memcpy(__aad, aad, GCM_AAD_LEN);
32
33 sg_init_table(sg, 3);
34 sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
35 sg_set_buf(&sg[1], data, data_len);
36 sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN);
37
38 aead_request_set_tfm(aead_req, tfm);
39 aead_request_set_crypt(aead_req, sg, sg, data_len, j_0);
40 aead_request_set_ad(aead_req, sg[0].length);
41
42 crypto_aead_encrypt(aead_req);
43 kzfree(aead_req);
44 return 0;
45}
46
47int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
48 u8 *data, size_t data_len, u8 *mic)
49{
50 struct scatterlist sg[3];
51 struct aead_request *aead_req;
52 int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
53 u8 *__aad;
54 int err;
55
56 if (data_len == 0)
57 return -EINVAL;
58
59 aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC);
60 if (!aead_req)
61 return -ENOMEM;
62
63 __aad = (u8 *)aead_req + reqsize;
64 memcpy(__aad, aad, GCM_AAD_LEN);
65
66 sg_init_table(sg, 3);
67 sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
68 sg_set_buf(&sg[1], data, data_len);
69 sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN);
70
71 aead_request_set_tfm(aead_req, tfm);
72 aead_request_set_crypt(aead_req, sg, sg,
73 data_len + IEEE80211_GCMP_MIC_LEN, j_0);
74 aead_request_set_ad(aead_req, sg[0].length);
75
76 err = crypto_aead_decrypt(aead_req);
77 kzfree(aead_req);
78
79 return err;
80}
81
82struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
83 size_t key_len)
84{
85 struct crypto_aead *tfm;
86 int err;
87
88 tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
89 if (IS_ERR(tfm))
90 return tfm;
91
92 err = crypto_aead_setkey(tfm, key, key_len);
93 if (err)
94 goto free_aead;
95 err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN);
96 if (err)
97 goto free_aead;
98
99 return tfm;
100
101free_aead:
102 crypto_free_aead(tfm);
103 return ERR_PTR(err);
104}
105
106void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
107{
108 crypto_free_aead(tfm);
109}
diff --git a/net/mac80211/aes_gcm.h b/net/mac80211/aes_gcm.h
index 55aed5352494..d2b096033009 100644
--- a/net/mac80211/aes_gcm.h
+++ b/net/mac80211/aes_gcm.h
@@ -9,16 +9,38 @@
9#ifndef AES_GCM_H 9#ifndef AES_GCM_H
10#define AES_GCM_H 10#define AES_GCM_H
11 11
12#include <linux/crypto.h> 12#include "aead_api.h"
13 13
14#define GCM_AAD_LEN 32 14#define GCM_AAD_LEN 32
15 15
16int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, 16static inline int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm,
17 u8 *data, size_t data_len, u8 *mic); 17 u8 *j_0, u8 *aad, u8 *data,
18int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, 18 size_t data_len, u8 *mic)
19 u8 *data, size_t data_len, u8 *mic); 19{
20struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], 20 return aead_encrypt(tfm, j_0, aad + 2,
21 size_t key_len); 21 be16_to_cpup((__be16 *)aad),
22void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm); 22 data, data_len, mic);
23}
24
25static inline int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm,
26 u8 *j_0, u8 *aad, u8 *data,
27 size_t data_len, u8 *mic)
28{
29 return aead_decrypt(tfm, j_0, aad + 2,
30 be16_to_cpup((__be16 *)aad),
31 data, data_len, mic);
32}
33
34static inline struct crypto_aead *
35ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len)
36{
37 return aead_key_setup_encrypt("gcm(aes)", key,
38 key_len, IEEE80211_GCMP_MIC_LEN);
39}
40
41static inline void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
42{
43 return aead_key_free(tfm);
44}
23 45
24#endif /* AES_GCM_H */ 46#endif /* AES_GCM_H */
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 0d722ea98a1b..b58722d9de37 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -464,7 +464,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb,
464 pos += IEEE80211_CCMP_HDR_LEN; 464 pos += IEEE80211_CCMP_HDR_LEN;
465 ccmp_special_blocks(skb, pn, b_0, aad); 465 ccmp_special_blocks(skb, pn, b_0, aad);
466 return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, 466 return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
467 skb_put(skb, mic_len), mic_len); 467 skb_put(skb, mic_len));
468} 468}
469 469
470 470
@@ -543,7 +543,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
543 key->u.ccmp.tfm, b_0, aad, 543 key->u.ccmp.tfm, b_0, aad,
544 skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN, 544 skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
545 data_len, 545 data_len,
546 skb->data + skb->len - mic_len, mic_len)) 546 skb->data + skb->len - mic_len))
547 return RX_DROP_UNUSABLE; 547 return RX_DROP_UNUSABLE;
548 } 548 }
549 549