summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/aes_cmac.c126
-rw-r--r--net/mac80211/aes_cmac.h11
-rw-r--r--net/mac80211/key.h2
3 files changed, 32 insertions, 107 deletions
diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c
index d0bd5fff5f0a..2fb65588490c 100644
--- a/net/mac80211/aes_cmac.c
+++ b/net/mac80211/aes_cmac.c
@@ -22,126 +22,50 @@
22#define CMAC_TLEN_256 16 /* CMAC TLen = 128 bits (16 octets) */ 22#define CMAC_TLEN_256 16 /* CMAC TLen = 128 bits (16 octets) */
23#define AAD_LEN 20 23#define AAD_LEN 20
24 24
25static const u8 zero[CMAC_TLEN_256];
25 26
26void gf_mulx(u8 *pad) 27void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad,
27{
28 int i, carry;
29
30 carry = pad[0] & 0x80;
31 for (i = 0; i < AES_BLOCK_SIZE - 1; i++)
32 pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);
33 pad[AES_BLOCK_SIZE - 1] <<= 1;
34 if (carry)
35 pad[AES_BLOCK_SIZE - 1] ^= 0x87;
36}
37
38void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem,
39 const u8 *addr[], const size_t *len, u8 *mac,
40 size_t mac_len)
41{
42 u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];
43 const u8 *pos, *end;
44 size_t i, e, left, total_len;
45
46 memset(cbc, 0, AES_BLOCK_SIZE);
47
48 total_len = 0;
49 for (e = 0; e < num_elem; e++)
50 total_len += len[e];
51 left = total_len;
52
53 e = 0;
54 pos = addr[0];
55 end = pos + len[0];
56
57 while (left >= AES_BLOCK_SIZE) {
58 for (i = 0; i < AES_BLOCK_SIZE; i++) {
59 cbc[i] ^= *pos++;
60 if (pos >= end) {
61 e++;
62 pos = addr[e];
63 end = pos + len[e];
64 }
65 }
66 if (left > AES_BLOCK_SIZE)
67 crypto_cipher_encrypt_one(tfm, cbc, cbc);
68 left -= AES_BLOCK_SIZE;
69 }
70
71 memset(pad, 0, AES_BLOCK_SIZE);
72 crypto_cipher_encrypt_one(tfm, pad, pad);
73 gf_mulx(pad);
74
75 if (left || total_len == 0) {
76 for (i = 0; i < left; i++) {
77 cbc[i] ^= *pos++;
78 if (pos >= end) {
79 e++;
80 pos = addr[e];
81 end = pos + len[e];
82 }
83 }
84 cbc[left] ^= 0x80;
85 gf_mulx(pad);
86 }
87
88 for (i = 0; i < AES_BLOCK_SIZE; i++)
89 pad[i] ^= cbc[i];
90 crypto_cipher_encrypt_one(tfm, pad, pad);
91 memcpy(mac, pad, mac_len);
92}
93
94
95void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad,
96 const u8 *data, size_t data_len, u8 *mic) 28 const u8 *data, size_t data_len, u8 *mic)
97{ 29{
98 const u8 *addr[3]; 30 SHASH_DESC_ON_STACK(desc, tfm);
99 size_t len[3]; 31 u8 out[AES_BLOCK_SIZE];
100 u8 zero[CMAC_TLEN];
101 32
102 memset(zero, 0, CMAC_TLEN); 33 desc->tfm = tfm;
103 addr[0] = aad;
104 len[0] = AAD_LEN;
105 addr[1] = data;
106 len[1] = data_len - CMAC_TLEN;
107 addr[2] = zero;
108 len[2] = CMAC_TLEN;
109 34
110 aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN); 35 crypto_shash_init(desc);
36 crypto_shash_update(desc, aad, AAD_LEN);
37 crypto_shash_update(desc, data, data_len - CMAC_TLEN);
38 crypto_shash_finup(desc, zero, CMAC_TLEN, out);
39
40 memcpy(mic, out, CMAC_TLEN);
111} 41}
112 42
113void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad, 43void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad,
114 const u8 *data, size_t data_len, u8 *mic) 44 const u8 *data, size_t data_len, u8 *mic)
115{ 45{
116 const u8 *addr[3]; 46 SHASH_DESC_ON_STACK(desc, tfm);
117 size_t len[3];
118 u8 zero[CMAC_TLEN_256];
119 47
120 memset(zero, 0, CMAC_TLEN_256); 48 desc->tfm = tfm;
121 addr[0] = aad;
122 len[0] = AAD_LEN;
123 addr[1] = data;
124 len[1] = data_len - CMAC_TLEN_256;
125 addr[2] = zero;
126 len[2] = CMAC_TLEN_256;
127 49
128 aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN_256); 50 crypto_shash_init(desc);
51 crypto_shash_update(desc, aad, AAD_LEN);
52 crypto_shash_update(desc, data, data_len - CMAC_TLEN_256);
53 crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic);
129} 54}
130 55
131struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[], 56struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[],
132 size_t key_len) 57 size_t key_len)
133{ 58{
134 struct crypto_cipher *tfm; 59 struct crypto_shash *tfm;
135 60
136 tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); 61 tfm = crypto_alloc_shash("cmac(aes)", 0, 0);
137 if (!IS_ERR(tfm)) 62 if (!IS_ERR(tfm))
138 crypto_cipher_setkey(tfm, key, key_len); 63 crypto_shash_setkey(tfm, key, key_len);
139 64
140 return tfm; 65 return tfm;
141} 66}
142 67
143 68void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm)
144void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm)
145{ 69{
146 crypto_free_cipher(tfm); 70 crypto_free_shash(tfm);
147} 71}
diff --git a/net/mac80211/aes_cmac.h b/net/mac80211/aes_cmac.h
index 3702041f44fd..fef531f42003 100644
--- a/net/mac80211/aes_cmac.h
+++ b/net/mac80211/aes_cmac.h
@@ -10,13 +10,14 @@
10#define AES_CMAC_H 10#define AES_CMAC_H
11 11
12#include <linux/crypto.h> 12#include <linux/crypto.h>
13#include <crypto/hash.h>
13 14
14struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[], 15struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[],
15 size_t key_len); 16 size_t key_len);
16void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad, 17void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad,
17 const u8 *data, size_t data_len, u8 *mic); 18 const u8 *data, size_t data_len, u8 *mic);
18void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad, 19void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad,
19 const u8 *data, size_t data_len, u8 *mic); 20 const u8 *data, size_t data_len, u8 *mic);
20void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm); 21void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm);
21 22
22#endif /* AES_CMAC_H */ 23#endif /* AES_CMAC_H */
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 4aa20cef0859..ebdb80b85dc3 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -93,7 +93,7 @@ struct ieee80211_key {
93 } ccmp; 93 } ccmp;
94 struct { 94 struct {
95 u8 rx_pn[IEEE80211_CMAC_PN_LEN]; 95 u8 rx_pn[IEEE80211_CMAC_PN_LEN];
96 struct crypto_cipher *tfm; 96 struct crypto_shash *tfm;
97 u32 replays; /* dot11RSNAStatsCMACReplays */ 97 u32 replays; /* dot11RSNAStatsCMACReplays */
98 u32 icverrors; /* dot11RSNAStatsCMACICVErrors */ 98 u32 icverrors; /* dot11RSNAStatsCMACICVErrors */
99 } aes_cmac; 99 } aes_cmac;