mac80211: update to wireless-testing 2014-03-31
[openwrt/openwrt.git] / package / kernel / mac80211 / patches / 100-revert_aes_ccm_port.patch
1 --- a/net/mac80211/wpa.c
2 +++ b/net/mac80211/wpa.c
3 @@ -301,15 +301,22 @@ ieee80211_crypto_tkip_decrypt(struct iee
4 }
5
6
7 -static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad)
8 +static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
9 + int encrypted)
10 {
11 __le16 mask_fc;
12 int a4_included, mgmt;
13 u8 qos_tid;
14 - u16 len_a;
15 + u8 *b_0, *aad;
16 + u16 data_len, len_a;
17 unsigned int hdrlen;
18 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
19
20 + memset(scratch, 0, 6 * AES_BLOCK_SIZE);
21 +
22 + b_0 = scratch + 3 * AES_BLOCK_SIZE;
23 + aad = scratch + 4 * AES_BLOCK_SIZE;
24 +
25 /*
26 * Mask FC: zero subtype b4 b5 b6 (if not mgmt)
27 * Retry, PwrMgt, MoreData; set Protected
28 @@ -331,21 +338,20 @@ static void ccmp_special_blocks(struct s
29 else
30 qos_tid = 0;
31
32 - /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
33 - * mode authentication are not allowed to collide, yet both are derived
34 - * from this vector b_0. We only set L := 1 here to indicate that the
35 - * data size can be represented in (L+1) bytes. The CCM layer will take
36 - * care of storing the data length in the top (L+1) bytes and setting
37 - * and clearing the other bits as is required to derive the two IVs.
38 - */
39 - b_0[0] = 0x1;
40 + data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN;
41 + if (encrypted)
42 + data_len -= IEEE80211_CCMP_MIC_LEN;
43
44 + /* First block, b_0 */
45 + b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
46 /* Nonce: Nonce Flags | A2 | PN
47 * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
48 */
49 b_0[1] = qos_tid | (mgmt << 4);
50 memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
51 memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
52 + /* l(m) */
53 + put_unaligned_be16(data_len, &b_0[14]);
54
55 /* AAD (extra authenticate-only data) / masked 802.11 header
56 * FC | A1 | A2 | A3 | SC | [A4] | [QC] */
57 @@ -401,8 +407,7 @@ static int ccmp_encrypt_skb(struct ieee8
58 u8 *pos;
59 u8 pn[6];
60 u64 pn64;
61 - u8 aad[2 * AES_BLOCK_SIZE];
62 - u8 b_0[AES_BLOCK_SIZE];
63 + u8 scratch[6 * AES_BLOCK_SIZE];
64
65 if (info->control.hw_key &&
66 !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
67 @@ -455,9 +460,9 @@ static int ccmp_encrypt_skb(struct ieee8
68 return 0;
69
70 pos += IEEE80211_CCMP_HDR_LEN;
71 - ccmp_special_blocks(skb, pn, b_0, aad);
72 - ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
73 - skb_put(skb, IEEE80211_CCMP_MIC_LEN));
74 + ccmp_special_blocks(skb, pn, scratch, 0);
75 + ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len,
76 + pos, skb_put(skb, IEEE80211_CCMP_MIC_LEN));
77
78 return 0;
79 }
80 @@ -520,16 +525,16 @@ ieee80211_crypto_ccmp_decrypt(struct iee
81 }
82
83 if (!(status->flag & RX_FLAG_DECRYPTED)) {
84 - u8 aad[2 * AES_BLOCK_SIZE];
85 - u8 b_0[AES_BLOCK_SIZE];
86 + u8 scratch[6 * AES_BLOCK_SIZE];
87 /* hardware didn't decrypt/verify MIC */
88 - ccmp_special_blocks(skb, pn, b_0, aad);
89 + ccmp_special_blocks(skb, pn, scratch, 1);
90
91 if (ieee80211_aes_ccm_decrypt(
92 - key->u.ccmp.tfm, b_0, aad,
93 + key->u.ccmp.tfm, scratch,
94 skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
95 data_len,
96 - skb->data + skb->len - IEEE80211_CCMP_MIC_LEN))
97 + skb->data + skb->len - IEEE80211_CCMP_MIC_LEN,
98 + skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN))
99 return RX_DROP_UNUSABLE;
100 }
101
102 --- a/net/mac80211/Kconfig
103 +++ b/net/mac80211/Kconfig
104 @@ -5,7 +5,6 @@ config MAC80211
105 depends on CRYPTO
106 depends on CRYPTO_ARC4
107 depends on CRYPTO_AES
108 - depends on CRYPTO_CCM
109 depends on CRC32
110 select BACKPORT_AVERAGE
111 ---help---
112 --- a/net/mac80211/aes_ccm.c
113 +++ b/net/mac80211/aes_ccm.c
114 @@ -2,8 +2,6 @@
115 * Copyright 2003-2004, Instant802 Networks, Inc.
116 * Copyright 2005-2006, Devicescape Software, Inc.
117 *
118 - * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
119 - *
120 * This program is free software; you can redistribute it and/or modify
121 * it under the terms of the GNU General Public License version 2 as
122 * published by the Free Software Foundation.
123 @@ -19,75 +17,134 @@
124 #include "key.h"
125 #include "aes_ccm.h"
126
127 -void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
128 - u8 *data, size_t data_len, u8 *mic)
129 +static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *scratch, u8 *a)
130 {
131 - struct scatterlist assoc, pt, ct[2];
132 - struct {
133 - struct aead_request req;
134 - u8 priv[crypto_aead_reqsize(tfm)];
135 - } aead_req;
136 -
137 - memset(&aead_req, 0, sizeof(aead_req));
138 -
139 - sg_init_one(&pt, data, data_len);
140 - sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad));
141 - sg_init_table(ct, 2);
142 - sg_set_buf(&ct[0], data, data_len);
143 - sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN);
144 -
145 - aead_request_set_tfm(&aead_req.req, tfm);
146 - aead_request_set_assoc(&aead_req.req, &assoc, assoc.length);
147 - aead_request_set_crypt(&aead_req.req, &pt, ct, data_len, b_0);
148 + int i;
149 + u8 *b_0, *aad, *b, *s_0;
150
151 - crypto_aead_encrypt(&aead_req.req);
152 + b_0 = scratch + 3 * AES_BLOCK_SIZE;
153 + aad = scratch + 4 * AES_BLOCK_SIZE;
154 + b = scratch;
155 + s_0 = scratch + AES_BLOCK_SIZE;
156 +
157 + crypto_cipher_encrypt_one(tfm, b, b_0);
158 +
159 + /* Extra Authenticate-only data (always two AES blocks) */
160 + for (i = 0; i < AES_BLOCK_SIZE; i++)
161 + aad[i] ^= b[i];
162 + crypto_cipher_encrypt_one(tfm, b, aad);
163 +
164 + aad += AES_BLOCK_SIZE;
165 +
166 + for (i = 0; i < AES_BLOCK_SIZE; i++)
167 + aad[i] ^= b[i];
168 + crypto_cipher_encrypt_one(tfm, a, aad);
169 +
170 + /* Mask out bits from auth-only-b_0 */
171 + b_0[0] &= 0x07;
172 +
173 + /* S_0 is used to encrypt T (= MIC) */
174 + b_0[14] = 0;
175 + b_0[15] = 0;
176 + crypto_cipher_encrypt_one(tfm, s_0, b_0);
177 }
178
179 -int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
180 - u8 *data, size_t data_len, u8 *mic)
181 +
182 +void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
183 + u8 *data, size_t data_len,
184 + u8 *cdata, u8 *mic)
185 {
186 - struct scatterlist assoc, pt, ct[2];
187 - struct {
188 - struct aead_request req;
189 - u8 priv[crypto_aead_reqsize(tfm)];
190 - } aead_req;
191 -
192 - memset(&aead_req, 0, sizeof(aead_req));
193 -
194 - sg_init_one(&pt, data, data_len);
195 - sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad));
196 - sg_init_table(ct, 2);
197 - sg_set_buf(&ct[0], data, data_len);
198 - sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN);
199 -
200 - aead_request_set_tfm(&aead_req.req, tfm);
201 - aead_request_set_assoc(&aead_req.req, &assoc, assoc.length);
202 - aead_request_set_crypt(&aead_req.req, ct, &pt,
203 - data_len + IEEE80211_CCMP_MIC_LEN, b_0);
204 + int i, j, last_len, num_blocks;
205 + u8 *pos, *cpos, *b, *s_0, *e, *b_0;
206 +
207 + b = scratch;
208 + s_0 = scratch + AES_BLOCK_SIZE;
209 + e = scratch + 2 * AES_BLOCK_SIZE;
210 + b_0 = scratch + 3 * AES_BLOCK_SIZE;
211 +
212 + num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
213 + last_len = data_len % AES_BLOCK_SIZE;
214 + aes_ccm_prepare(tfm, scratch, b);
215 +
216 + /* Process payload blocks */
217 + pos = data;
218 + cpos = cdata;
219 + for (j = 1; j <= num_blocks; j++) {
220 + int blen = (j == num_blocks && last_len) ?
221 + last_len : AES_BLOCK_SIZE;
222 +
223 + /* Authentication followed by encryption */
224 + for (i = 0; i < blen; i++)
225 + b[i] ^= pos[i];
226 + crypto_cipher_encrypt_one(tfm, b, b);
227 +
228 + b_0[14] = (j >> 8) & 0xff;
229 + b_0[15] = j & 0xff;
230 + crypto_cipher_encrypt_one(tfm, e, b_0);
231 + for (i = 0; i < blen; i++)
232 + *cpos++ = *pos++ ^ e[i];
233 + }
234
235 - return crypto_aead_decrypt(&aead_req.req);
236 + for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++)
237 + mic[i] = b[i] ^ s_0[i];
238 }
239
240 -struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[])
241 +
242 +int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
243 + u8 *cdata, size_t data_len, u8 *mic, u8 *data)
244 {
245 - struct crypto_aead *tfm;
246 - int err;
247 + int i, j, last_len, num_blocks;
248 + u8 *pos, *cpos, *b, *s_0, *a, *b_0;
249
250 - tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC);
251 - if (IS_ERR(tfm))
252 - return tfm;
253 -
254 - err = crypto_aead_setkey(tfm, key, WLAN_KEY_LEN_CCMP);
255 - if (!err)
256 - err = crypto_aead_setauthsize(tfm, IEEE80211_CCMP_MIC_LEN);
257 - if (!err)
258 - return tfm;
259 + b = scratch;
260 + s_0 = scratch + AES_BLOCK_SIZE;
261 + a = scratch + 2 * AES_BLOCK_SIZE;
262 + b_0 = scratch + 3 * AES_BLOCK_SIZE;
263 +
264 + num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
265 + last_len = data_len % AES_BLOCK_SIZE;
266 + aes_ccm_prepare(tfm, scratch, a);
267 +
268 + /* Process payload blocks */
269 + cpos = cdata;
270 + pos = data;
271 + for (j = 1; j <= num_blocks; j++) {
272 + int blen = (j == num_blocks && last_len) ?
273 + last_len : AES_BLOCK_SIZE;
274 +
275 + /* Decryption followed by authentication */
276 + b_0[14] = (j >> 8) & 0xff;
277 + b_0[15] = j & 0xff;
278 + crypto_cipher_encrypt_one(tfm, b, b_0);
279 + for (i = 0; i < blen; i++) {
280 + *pos = *cpos++ ^ b[i];
281 + a[i] ^= *pos++;
282 + }
283 + crypto_cipher_encrypt_one(tfm, a, a);
284 + }
285 +
286 + for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++) {
287 + if ((mic[i] ^ s_0[i]) != a[i])
288 + return -1;
289 + }
290
291 - crypto_free_aead(tfm);
292 - return ERR_PTR(err);
293 + return 0;
294 }
295
296 -void ieee80211_aes_key_free(struct crypto_aead *tfm)
297 +
298 +struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[])
299 +{
300 + struct crypto_cipher *tfm;
301 +
302 + tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
303 + if (!IS_ERR(tfm))
304 + crypto_cipher_setkey(tfm, key, WLAN_KEY_LEN_CCMP);
305 +
306 + return tfm;
307 +}
308 +
309 +
310 +void ieee80211_aes_key_free(struct crypto_cipher *tfm)
311 {
312 - crypto_free_aead(tfm);
313 + crypto_free_cipher(tfm);
314 }
315 --- a/net/mac80211/aes_ccm.h
316 +++ b/net/mac80211/aes_ccm.h
317 @@ -12,11 +12,13 @@
318
319 #include <linux/crypto.h>
320
321 -struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[]);
322 -void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
323 - u8 *data, size_t data_len, u8 *mic);
324 -int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
325 - u8 *data, size_t data_len, u8 *mic);
326 -void ieee80211_aes_key_free(struct crypto_aead *tfm);
327 +struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]);
328 +void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
329 + u8 *data, size_t data_len,
330 + u8 *cdata, u8 *mic);
331 +int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
332 + u8 *cdata, size_t data_len,
333 + u8 *mic, u8 *data);
334 +void ieee80211_aes_key_free(struct crypto_cipher *tfm);
335
336 #endif /* AES_CCM_H */
337 --- a/net/mac80211/key.h
338 +++ b/net/mac80211/key.h
339 @@ -84,7 +84,7 @@ struct ieee80211_key {
340 * Management frames.
341 */
342 u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN];
343 - struct crypto_aead *tfm;
344 + struct crypto_cipher *tfm;
345 u32 replays; /* dot11RSNAStatsCCMPReplays */
346 } ccmp;
347 struct {