OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | --- a/net/mac80211/Makefile |
2 | +++ b/net/mac80211/Makefile |
||
3 | @@ -7,7 +7,6 @@ mac80211-y := \ |
||
4 | driver-ops.o \ |
||
5 | sta_info.o \ |
||
6 | wep.o \ |
||
7 | - aead_api.o \ |
||
8 | wpa.o \ |
||
9 | scan.o offchannel.o \ |
||
10 | ht.o agg-tx.o agg-rx.o \ |
||
11 | @@ -18,8 +17,8 @@ mac80211-y := \ |
||
12 | rate.o \ |
||
13 | michael.o \ |
||
14 | tkip.o \ |
||
15 | + aes_ccm.o \ |
||
16 | aes_cmac.o \ |
||
17 | - aes_gmac.o \ |
||
18 | fils_aead.o \ |
||
19 | cfg.o \ |
||
20 | ethtool.o \ |
||
21 | --- a/net/mac80211/aead_api.c |
||
22 | +++ /dev/null |
||
23 | @@ -1,115 +0,0 @@ |
||
24 | -/* |
||
25 | - * Copyright 2003-2004, Instant802 Networks, Inc. |
||
26 | - * Copyright 2005-2006, Devicescape Software, Inc. |
||
27 | - * Copyright 2014-2015, Qualcomm Atheros, Inc. |
||
28 | - * |
||
29 | - * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org> |
||
30 | - * |
||
31 | - * This program is free software; you can redistribute it and/or modify |
||
32 | - * it under the terms of the GNU General Public License version 2 as |
||
33 | - * published by the Free Software Foundation. |
||
34 | - */ |
||
35 | - |
||
36 | -#include <linux/kernel.h> |
||
37 | -#include <linux/types.h> |
||
38 | -#include <linux/err.h> |
||
39 | -#include <linux/scatterlist.h> |
||
40 | -#include <crypto/aead.h> |
||
41 | - |
||
42 | -#include "aead_api.h" |
||
43 | - |
||
44 | -int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len, |
||
45 | - u8 *data, size_t data_len, u8 *mic) |
||
46 | -{ |
||
47 | - size_t mic_len = crypto_aead_authsize(tfm); |
||
48 | - struct scatterlist sg[3]; |
||
49 | - struct aead_request *aead_req; |
||
50 | - int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); |
||
51 | - u8 *__aad; |
||
52 | - |
||
53 | - aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC); |
||
54 | - if (!aead_req) |
||
55 | - return -ENOMEM; |
||
56 | - |
||
57 | - __aad = (u8 *)aead_req + reqsize; |
||
58 | - memcpy(__aad, aad, aad_len); |
||
59 | - |
||
60 | - sg_init_table(sg, 3); |
||
61 | - sg_set_buf(&sg[0], __aad, aad_len); |
||
62 | - sg_set_buf(&sg[1], data, data_len); |
||
63 | - sg_set_buf(&sg[2], mic, mic_len); |
||
64 | - |
||
65 | - aead_request_set_tfm(aead_req, tfm); |
||
66 | - aead_request_set_crypt(aead_req, sg, sg, data_len, b_0); |
||
67 | - aead_request_set_ad(aead_req, sg[0].length); |
||
68 | - |
||
69 | - crypto_aead_encrypt(aead_req); |
||
70 | - kzfree(aead_req); |
||
71 | - |
||
72 | - return 0; |
||
73 | -} |
||
74 | - |
||
75 | -int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len, |
||
76 | - u8 *data, size_t data_len, u8 *mic) |
||
77 | -{ |
||
78 | - size_t mic_len = crypto_aead_authsize(tfm); |
||
79 | - struct scatterlist sg[3]; |
||
80 | - struct aead_request *aead_req; |
||
81 | - int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); |
||
82 | - u8 *__aad; |
||
83 | - int err; |
||
84 | - |
||
85 | - if (data_len == 0) |
||
86 | - return -EINVAL; |
||
87 | - |
||
88 | - aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC); |
||
89 | - if (!aead_req) |
||
90 | - return -ENOMEM; |
||
91 | - |
||
92 | - __aad = (u8 *)aead_req + reqsize; |
||
93 | - memcpy(__aad, aad, aad_len); |
||
94 | - |
||
95 | - sg_init_table(sg, 3); |
||
96 | - sg_set_buf(&sg[0], __aad, aad_len); |
||
97 | - sg_set_buf(&sg[1], data, data_len); |
||
98 | - sg_set_buf(&sg[2], mic, mic_len); |
||
99 | - |
||
100 | - aead_request_set_tfm(aead_req, tfm); |
||
101 | - aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0); |
||
102 | - aead_request_set_ad(aead_req, sg[0].length); |
||
103 | - |
||
104 | - err = crypto_aead_decrypt(aead_req); |
||
105 | - kzfree(aead_req); |
||
106 | - |
||
107 | - return err; |
||
108 | -} |
||
109 | - |
||
110 | -struct crypto_aead * |
||
111 | -aead_key_setup_encrypt(const char *alg, const u8 key[], |
||
112 | - size_t key_len, size_t mic_len) |
||
113 | -{ |
||
114 | - struct crypto_aead *tfm; |
||
115 | - int err; |
||
116 | - |
||
117 | - tfm = crypto_alloc_aead(alg, 0, CRYPTO_ALG_ASYNC); |
||
118 | - if (IS_ERR(tfm)) |
||
119 | - return tfm; |
||
120 | - |
||
121 | - err = crypto_aead_setkey(tfm, key, key_len); |
||
122 | - if (err) |
||
123 | - goto free_aead; |
||
124 | - err = crypto_aead_setauthsize(tfm, mic_len); |
||
125 | - if (err) |
||
126 | - goto free_aead; |
||
127 | - |
||
128 | - return tfm; |
||
129 | - |
||
130 | -free_aead: |
||
131 | - crypto_free_aead(tfm); |
||
132 | - return ERR_PTR(err); |
||
133 | -} |
||
134 | - |
||
135 | -void aead_key_free(struct crypto_aead *tfm) |
||
136 | -{ |
||
137 | - crypto_free_aead(tfm); |
||
138 | -} |
||
139 | --- a/net/mac80211/aead_api.h |
||
140 | +++ /dev/null |
||
141 | @@ -1,27 +0,0 @@ |
||
142 | -/* |
||
143 | - * This program is free software; you can redistribute it and/or modify |
||
144 | - * it under the terms of the GNU General Public License version 2 as |
||
145 | - * published by the Free Software Foundation. |
||
146 | - */ |
||
147 | - |
||
148 | -#ifndef _AEAD_API_H |
||
149 | -#define _AEAD_API_H |
||
150 | - |
||
151 | -#include <crypto/aead.h> |
||
152 | -#include <linux/crypto.h> |
||
153 | - |
||
154 | -struct crypto_aead * |
||
155 | -aead_key_setup_encrypt(const char *alg, const u8 key[], |
||
156 | - size_t key_len, size_t mic_len); |
||
157 | - |
||
158 | -int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, |
||
159 | - size_t aad_len, u8 *data, |
||
160 | - size_t data_len, u8 *mic); |
||
161 | - |
||
162 | -int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, |
||
163 | - size_t aad_len, u8 *data, |
||
164 | - size_t data_len, u8 *mic); |
||
165 | - |
||
166 | -void aead_key_free(struct crypto_aead *tfm); |
||
167 | - |
||
168 | -#endif /* _AEAD_API_H */ |
||
169 | --- a/net/mac80211/aes_ccm.h |
||
170 | +++ b/net/mac80211/aes_ccm.h |
||
171 | @@ -10,39 +10,17 @@ |
||
172 | #ifndef AES_CCM_H |
||
173 | #define AES_CCM_H |
||
174 | |||
175 | -#include "aead_api.h" |
||
176 | +#include <linux/crypto.h> |
||
177 | |||
178 | -#define CCM_AAD_LEN 32 |
||
179 | - |
||
180 | -static inline struct crypto_aead * |
||
181 | -ieee80211_aes_key_setup_encrypt(const u8 key[], size_t key_len, size_t mic_len) |
||
182 | -{ |
||
183 | - return aead_key_setup_encrypt("ccm(aes)", key, key_len, mic_len); |
||
184 | -} |
||
185 | - |
||
186 | -static inline int |
||
187 | -ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, |
||
188 | - u8 *b_0, u8 *aad, u8 *data, |
||
189 | - size_t data_len, u8 *mic) |
||
190 | -{ |
||
191 | - return aead_encrypt(tfm, b_0, aad + 2, |
||
192 | - be16_to_cpup((__be16 *)aad), |
||
193 | - data, data_len, mic); |
||
194 | -} |
||
195 | - |
||
196 | -static inline int |
||
197 | -ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, |
||
198 | - u8 *b_0, u8 *aad, u8 *data, |
||
199 | - size_t data_len, u8 *mic) |
||
200 | -{ |
||
201 | - return aead_decrypt(tfm, b_0, aad + 2, |
||
202 | - be16_to_cpup((__be16 *)aad), |
||
203 | - data, data_len, mic); |
||
204 | -} |
||
205 | - |
||
206 | -static inline void ieee80211_aes_key_free(struct crypto_aead *tfm) |
||
207 | -{ |
||
208 | - return aead_key_free(tfm); |
||
209 | -} |
||
210 | +struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[], |
||
211 | + size_t key_len, |
||
212 | + size_t mic_len); |
||
213 | +void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, |
||
214 | + u8 *data, size_t data_len, u8 *mic, |
||
215 | + size_t mic_len); |
||
216 | +int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, |
||
217 | + u8 *data, size_t data_len, u8 *mic, |
||
218 | + size_t mic_len); |
||
219 | +void ieee80211_aes_key_free(struct crypto_cipher *tfm); |
||
220 | |||
221 | #endif /* AES_CCM_H */ |
||
222 | --- /dev/null |
||
223 | +++ b/net/mac80211/aes_gcm.c |
||
224 | @@ -0,0 +1,109 @@ |
||
225 | +/* |
||
226 | + * Copyright 2014-2015, Qualcomm Atheros, Inc. |
||
227 | + * |
||
228 | + * This program is free software; you can redistribute it and/or modify |
||
229 | + * it under the terms of the GNU General Public License version 2 as |
||
230 | + * published by the Free Software Foundation. |
||
231 | + */ |
||
232 | + |
||
233 | +#include <linux/kernel.h> |
||
234 | +#include <linux/types.h> |
||
235 | +#include <linux/err.h> |
||
236 | +#include <crypto/aead.h> |
||
237 | + |
||
238 | +#include <net/mac80211.h> |
||
239 | +#include "key.h" |
||
240 | +#include "aes_gcm.h" |
||
241 | + |
||
242 | +int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, |
||
243 | + u8 *data, size_t data_len, u8 *mic) |
||
244 | +{ |
||
245 | + struct scatterlist sg[3]; |
||
246 | + struct aead_request *aead_req; |
||
247 | + int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); |
||
248 | + u8 *__aad; |
||
249 | + |
||
250 | + aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC); |
||
251 | + if (!aead_req) |
||
252 | + return -ENOMEM; |
||
253 | + |
||
254 | + __aad = (u8 *)aead_req + reqsize; |
||
255 | + memcpy(__aad, aad, GCM_AAD_LEN); |
||
256 | + |
||
257 | + sg_init_table(sg, 3); |
||
258 | + sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad)); |
||
259 | + sg_set_buf(&sg[1], data, data_len); |
||
260 | + sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN); |
||
261 | + |
||
262 | + aead_request_set_tfm(aead_req, tfm); |
||
263 | + aead_request_set_crypt(aead_req, sg, sg, data_len, j_0); |
||
264 | + aead_request_set_ad(aead_req, sg[0].length); |
||
265 | + |
||
266 | + crypto_aead_encrypt(aead_req); |
||
267 | + kzfree(aead_req); |
||
268 | + return 0; |
||
269 | +} |
||
270 | + |
||
271 | +int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, |
||
272 | + u8 *data, size_t data_len, u8 *mic) |
||
273 | +{ |
||
274 | + struct scatterlist sg[3]; |
||
275 | + struct aead_request *aead_req; |
||
276 | + int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); |
||
277 | + u8 *__aad; |
||
278 | + int err; |
||
279 | + |
||
280 | + if (data_len == 0) |
||
281 | + return -EINVAL; |
||
282 | + |
||
283 | + aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC); |
||
284 | + if (!aead_req) |
||
285 | + return -ENOMEM; |
||
286 | + |
||
287 | + __aad = (u8 *)aead_req + reqsize; |
||
288 | + memcpy(__aad, aad, GCM_AAD_LEN); |
||
289 | + |
||
290 | + sg_init_table(sg, 3); |
||
291 | + sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad)); |
||
292 | + sg_set_buf(&sg[1], data, data_len); |
||
293 | + sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN); |
||
294 | + |
||
295 | + aead_request_set_tfm(aead_req, tfm); |
||
296 | + aead_request_set_crypt(aead_req, sg, sg, |
||
297 | + data_len + IEEE80211_GCMP_MIC_LEN, j_0); |
||
298 | + aead_request_set_ad(aead_req, sg[0].length); |
||
299 | + |
||
300 | + err = crypto_aead_decrypt(aead_req); |
||
301 | + kzfree(aead_req); |
||
302 | + |
||
303 | + return err; |
||
304 | +} |
||
305 | + |
||
306 | +struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], |
||
307 | + size_t key_len) |
||
308 | +{ |
||
309 | + struct crypto_aead *tfm; |
||
310 | + int err; |
||
311 | + |
||
312 | + tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC); |
||
313 | + if (IS_ERR(tfm)) |
||
314 | + return tfm; |
||
315 | + |
||
316 | + err = crypto_aead_setkey(tfm, key, key_len); |
||
317 | + if (err) |
||
318 | + goto free_aead; |
||
319 | + err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN); |
||
320 | + if (err) |
||
321 | + goto free_aead; |
||
322 | + |
||
323 | + return tfm; |
||
324 | + |
||
325 | +free_aead: |
||
326 | + crypto_free_aead(tfm); |
||
327 | + return ERR_PTR(err); |
||
328 | +} |
||
329 | + |
||
330 | +void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) |
||
331 | +{ |
||
332 | + crypto_free_aead(tfm); |
||
333 | +} |
||
334 | --- a/net/mac80211/aes_gcm.h |
||
335 | +++ b/net/mac80211/aes_gcm.h |
||
336 | @@ -9,38 +9,30 @@ |
||
337 | #ifndef AES_GCM_H |
||
338 | #define AES_GCM_H |
||
339 | |||
340 | -#include "aead_api.h" |
||
341 | +#include <linux/crypto.h> |
||
342 | |||
343 | -#define GCM_AAD_LEN 32 |
||
344 | - |
||
345 | -static inline int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, |
||
346 | - u8 *j_0, u8 *aad, u8 *data, |
||
347 | - size_t data_len, u8 *mic) |
||
348 | +static inline void |
||
349 | +ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, |
||
350 | + u8 *data, size_t data_len, u8 *mic) |
||
351 | { |
||
352 | - return aead_encrypt(tfm, j_0, aad + 2, |
||
353 | - be16_to_cpup((__be16 *)aad), |
||
354 | - data, data_len, mic); |
||
355 | } |
||
356 | |||
357 | -static inline int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, |
||
358 | - u8 *j_0, u8 *aad, u8 *data, |
||
359 | - size_t data_len, u8 *mic) |
||
360 | +static inline int |
||
361 | +ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, |
||
362 | + u8 *data, size_t data_len, u8 *mic) |
||
363 | { |
||
364 | - return aead_decrypt(tfm, j_0, aad + 2, |
||
365 | - be16_to_cpup((__be16 *)aad), |
||
366 | - data, data_len, mic); |
||
367 | + return -EOPNOTSUPP; |
||
368 | } |
||
369 | |||
370 | static inline struct crypto_aead * |
||
371 | ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len) |
||
372 | { |
||
373 | - return aead_key_setup_encrypt("gcm(aes)", key, |
||
374 | - key_len, IEEE80211_GCMP_MIC_LEN); |
||
375 | + return NULL; |
||
376 | } |
||
377 | |||
378 | -static inline void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) |
||
379 | +static inline void |
||
380 | +ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) |
||
381 | { |
||
382 | - return aead_key_free(tfm); |
||
383 | } |
||
384 | |||
385 | #endif /* AES_GCM_H */ |
||
386 | --- a/net/mac80211/wpa.c |
||
387 | +++ b/net/mac80211/wpa.c |
||
388 | @@ -314,7 +314,8 @@ ieee80211_crypto_tkip_decrypt(struct iee |
||
389 | } |
||
390 | |||
391 | |||
392 | -static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad) |
||
393 | +static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad, |
||
394 | + u16 data_len) |
||
395 | { |
||
396 | __le16 mask_fc; |
||
397 | int a4_included, mgmt; |
||
398 | @@ -344,14 +345,8 @@ static void ccmp_special_blocks(struct s |
||
399 | else |
||
400 | qos_tid = 0; |
||
401 | |||
402 | - /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC |
||
403 | - * mode authentication are not allowed to collide, yet both are derived |
||
404 | - * from this vector b_0. We only set L := 1 here to indicate that the |
||
405 | - * data size can be represented in (L+1) bytes. The CCM layer will take |
||
406 | - * care of storing the data length in the top (L+1) bytes and setting |
||
407 | - * and clearing the other bits as is required to derive the two IVs. |
||
408 | - */ |
||
409 | - b_0[0] = 0x1; |
||
410 | + /* First block, b_0 */ |
||
411 | + b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ |
||
412 | |||
413 | /* Nonce: Nonce Flags | A2 | PN |
||
414 | * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7) |
||
415 | @@ -359,6 +354,8 @@ static void ccmp_special_blocks(struct s |
||
416 | b_0[1] = qos_tid | (mgmt << 4); |
||
417 | memcpy(&b_0[2], hdr->addr2, ETH_ALEN); |
||
418 | memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN); |
||
419 | + /* l(m) */ |
||
420 | + put_unaligned_be16(data_len, &b_0[14]); |
||
421 | |||
422 | /* AAD (extra authenticate-only data) / masked 802.11 header |
||
423 | * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ |
||
424 | @@ -415,7 +412,7 @@ static int ccmp_encrypt_skb(struct ieee8 |
||
425 | u8 *pos; |
||
426 | u8 pn[6]; |
||
427 | u64 pn64; |
||
428 | - u8 aad[CCM_AAD_LEN]; |
||
429 | + u8 aad[2 * AES_BLOCK_SIZE]; |
||
430 | u8 b_0[AES_BLOCK_SIZE]; |
||
431 | |||
432 | if (info->control.hw_key && |
||
433 | @@ -470,9 +467,11 @@ static int ccmp_encrypt_skb(struct ieee8 |
||
434 | return 0; |
||
435 | |||
436 | pos += IEEE80211_CCMP_HDR_LEN; |
||
437 | - ccmp_special_blocks(skb, pn, b_0, aad); |
||
438 | - return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, |
||
439 | - skb_put(skb, mic_len)); |
||
440 | + ccmp_special_blocks(skb, pn, b_0, aad, len); |
||
441 | + ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, |
||
442 | + skb_put(skb, mic_len), mic_len); |
||
443 | + |
||
444 | + return 0; |
||
445 | } |
||
446 | |||
447 | |||
448 | @@ -545,13 +544,13 @@ ieee80211_crypto_ccmp_decrypt(struct iee |
||
449 | u8 aad[2 * AES_BLOCK_SIZE]; |
||
450 | u8 b_0[AES_BLOCK_SIZE]; |
||
451 | /* hardware didn't decrypt/verify MIC */ |
||
452 | - ccmp_special_blocks(skb, pn, b_0, aad); |
||
453 | + ccmp_special_blocks(skb, pn, b_0, aad, data_len); |
||
454 | |||
455 | if (ieee80211_aes_ccm_decrypt( |
||
456 | key->u.ccmp.tfm, b_0, aad, |
||
457 | skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN, |
||
458 | data_len, |
||
459 | - skb->data + skb->len - mic_len)) |
||
460 | + skb->data + skb->len - mic_len, mic_len)) |
||
461 | return RX_DROP_UNUSABLE; |
||
462 | } |
||
463 | |||
464 | @@ -646,7 +645,7 @@ static int gcmp_encrypt_skb(struct ieee8 |
||
465 | u8 *pos; |
||
466 | u8 pn[6]; |
||
467 | u64 pn64; |
||
468 | - u8 aad[GCM_AAD_LEN]; |
||
469 | + u8 aad[2 * AES_BLOCK_SIZE]; |
||
470 | u8 j_0[AES_BLOCK_SIZE]; |
||
471 | |||
472 | if (info->control.hw_key && |
||
473 | @@ -703,8 +702,10 @@ static int gcmp_encrypt_skb(struct ieee8 |
||
474 | |||
475 | pos += IEEE80211_GCMP_HDR_LEN; |
||
476 | gcmp_special_blocks(skb, pn, j_0, aad); |
||
477 | - return ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len, |
||
478 | - skb_put(skb, IEEE80211_GCMP_MIC_LEN)); |
||
479 | + ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len, |
||
480 | + skb_put(skb, IEEE80211_GCMP_MIC_LEN)); |
||
481 | + |
||
482 | + return 0; |
||
483 | } |
||
484 | |||
485 | ieee80211_tx_result |
||
486 | @@ -1127,9 +1128,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct |
||
487 | struct ieee80211_key *key = tx->key; |
||
488 | struct ieee80211_mmie_16 *mmie; |
||
489 | struct ieee80211_hdr *hdr; |
||
490 | - u8 aad[GMAC_AAD_LEN]; |
||
491 | + u8 aad[20]; |
||
492 | u64 pn64; |
||
493 | - u8 nonce[GMAC_NONCE_LEN]; |
||
494 | + u8 nonce[12]; |
||
495 | |||
496 | if (WARN_ON(skb_queue_len(&tx->skbs) != 1)) |
||
497 | return TX_DROP; |
||
498 | @@ -1175,7 +1176,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct |
||
499 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
||
500 | struct ieee80211_key *key = rx->key; |
||
501 | struct ieee80211_mmie_16 *mmie; |
||
502 | - u8 aad[GMAC_AAD_LEN], mic[GMAC_MIC_LEN], ipn[6], nonce[GMAC_NONCE_LEN]; |
||
503 | + u8 aad[20], mic[16], ipn[6], nonce[12]; |
||
504 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
||
505 | |||
506 | if (!ieee80211_is_mgmt(hdr->frame_control)) |
||
507 | --- /dev/null |
||
508 | +++ b/net/mac80211/aes_ccm.c |
||
509 | @@ -0,0 +1,144 @@ |
||
510 | +/* |
||
511 | + * Copyright 2003-2004, Instant802 Networks, Inc. |
||
512 | + * Copyright 2005-2006, Devicescape Software, Inc. |
||
513 | + * |
||
514 | + * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org> |
||
515 | + * |
||
516 | + * This program is free software; you can redistribute it and/or modify |
||
517 | + * it under the terms of the GNU General Public License version 2 as |
||
518 | + * published by the Free Software Foundation. |
||
519 | + */ |
||
520 | + |
||
521 | +#include <linux/kernel.h> |
||
522 | +#include <linux/types.h> |
||
523 | +#include <linux/err.h> |
||
524 | +#include <crypto/aead.h> |
||
525 | +#include <crypto/aes.h> |
||
526 | + |
||
527 | +#include <net/mac80211.h> |
||
528 | +#include "key.h" |
||
529 | +#include "aes_ccm.h" |
||
530 | + |
||
531 | +static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, u8 *s_0, |
||
532 | + u8 *a, u8 *b) |
||
533 | +{ |
||
534 | + int i; |
||
535 | + |
||
536 | + crypto_cipher_encrypt_one(tfm, b, b_0); |
||
537 | + |
||
538 | + /* Extra Authenticate-only data (always two AES blocks) */ |
||
539 | + for (i = 0; i < AES_BLOCK_SIZE; i++) |
||
540 | + aad[i] ^= b[i]; |
||
541 | + crypto_cipher_encrypt_one(tfm, b, aad); |
||
542 | + |
||
543 | + aad += AES_BLOCK_SIZE; |
||
544 | + |
||
545 | + for (i = 0; i < AES_BLOCK_SIZE; i++) |
||
546 | + aad[i] ^= b[i]; |
||
547 | + crypto_cipher_encrypt_one(tfm, a, aad); |
||
548 | + |
||
549 | + /* Mask out bits from auth-only-b_0 */ |
||
550 | + b_0[0] &= 0x07; |
||
551 | + |
||
552 | + /* S_0 is used to encrypt T (= MIC) */ |
||
553 | + b_0[14] = 0; |
||
554 | + b_0[15] = 0; |
||
555 | + crypto_cipher_encrypt_one(tfm, s_0, b_0); |
||
556 | +} |
||
557 | + |
||
558 | + |
||
559 | +void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, |
||
560 | + u8 *data, size_t data_len, u8 *mic, |
||
561 | + size_t mic_len) |
||
562 | +{ |
||
563 | + int i, j, last_len, num_blocks; |
||
564 | + u8 b[AES_BLOCK_SIZE]; |
||
565 | + u8 s_0[AES_BLOCK_SIZE]; |
||
566 | + u8 e[AES_BLOCK_SIZE]; |
||
567 | + u8 *pos, *cpos; |
||
568 | + |
||
569 | + num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE); |
||
570 | + last_len = data_len % AES_BLOCK_SIZE; |
||
571 | + aes_ccm_prepare(tfm, b_0, aad, s_0, b, b); |
||
572 | + |
||
573 | + /* Process payload blocks */ |
||
574 | + pos = data; |
||
575 | + cpos = data; |
||
576 | + for (j = 1; j <= num_blocks; j++) { |
||
577 | + int blen = (j == num_blocks && last_len) ? |
||
578 | + last_len : AES_BLOCK_SIZE; |
||
579 | + |
||
580 | + /* Authentication followed by encryption */ |
||
581 | + for (i = 0; i < blen; i++) |
||
582 | + b[i] ^= pos[i]; |
||
583 | + crypto_cipher_encrypt_one(tfm, b, b); |
||
584 | + |
||
585 | + b_0[14] = (j >> 8) & 0xff; |
||
586 | + b_0[15] = j & 0xff; |
||
587 | + crypto_cipher_encrypt_one(tfm, e, b_0); |
||
588 | + for (i = 0; i < blen; i++) |
||
589 | + *cpos++ = *pos++ ^ e[i]; |
||
590 | + } |
||
591 | + |
||
592 | + for (i = 0; i < mic_len; i++) |
||
593 | + mic[i] = b[i] ^ s_0[i]; |
||
594 | +} |
||
595 | + |
||
596 | +int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, |
||
597 | + u8 *data, size_t data_len, u8 *mic, |
||
598 | + size_t mic_len) |
||
599 | +{ |
||
600 | + int i, j, last_len, num_blocks; |
||
601 | + u8 *pos, *cpos; |
||
602 | + u8 a[AES_BLOCK_SIZE]; |
||
603 | + u8 b[AES_BLOCK_SIZE]; |
||
604 | + u8 s_0[AES_BLOCK_SIZE]; |
||
605 | + |
||
606 | + num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE); |
||
607 | + last_len = data_len % AES_BLOCK_SIZE; |
||
608 | + aes_ccm_prepare(tfm, b_0, aad, s_0, a, b); |
||
609 | + |
||
610 | + /* Process payload blocks */ |
||
611 | + cpos = data; |
||
612 | + pos = data; |
||
613 | + for (j = 1; j <= num_blocks; j++) { |
||
614 | + int blen = (j == num_blocks && last_len) ? |
||
615 | + last_len : AES_BLOCK_SIZE; |
||
616 | + |
||
617 | + /* Decryption followed by authentication */ |
||
618 | + b_0[14] = (j >> 8) & 0xff; |
||
619 | + b_0[15] = j & 0xff; |
||
620 | + crypto_cipher_encrypt_one(tfm, b, b_0); |
||
621 | + for (i = 0; i < blen; i++) { |
||
622 | + *pos = *cpos++ ^ b[i]; |
||
623 | + a[i] ^= *pos++; |
||
624 | + } |
||
625 | + crypto_cipher_encrypt_one(tfm, a, a); |
||
626 | + } |
||
627 | + |
||
628 | + for (i = 0; i < mic_len; i++) { |
||
629 | + if ((mic[i] ^ s_0[i]) != a[i]) |
||
630 | + return -1; |
||
631 | + } |
||
632 | + |
||
633 | + return 0; |
||
634 | +} |
||
635 | + |
||
636 | +struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[], |
||
637 | + size_t key_len, |
||
638 | + size_t mic_len) |
||
639 | +{ |
||
640 | + struct crypto_cipher *tfm; |
||
641 | + |
||
642 | + tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); |
||
643 | + if (!IS_ERR(tfm)) |
||
644 | + crypto_cipher_setkey(tfm, key, key_len); |
||
645 | + |
||
646 | + return tfm; |
||
647 | +} |
||
648 | + |
||
649 | + |
||
650 | +void ieee80211_aes_key_free(struct crypto_cipher *tfm) |
||
651 | +{ |
||
652 | + crypto_free_cipher(tfm); |
||
653 | +} |
||
654 | --- a/net/mac80211/Kconfig |
||
655 | +++ b/net/mac80211/Kconfig |
||
656 | @@ -5,8 +5,6 @@ config MAC80211 |
||
657 | depends on CRYPTO |
||
658 | depends on CRYPTO_ARC4 |
||
659 | depends on CRYPTO_AES |
||
660 | - depends on CRYPTO_CCM |
||
661 | - depends on CRYPTO_GCM |
||
662 | depends on CRYPTO_CMAC |
||
663 | depends on CRC32 |
||
664 | ---help--- |
||
665 | --- a/net/mac80211/aes_gmac.h |
||
666 | +++ b/net/mac80211/aes_gmac.h |
||
667 | @@ -15,10 +15,22 @@ |
||
668 | #define GMAC_MIC_LEN 16 |
||
669 | #define GMAC_NONCE_LEN 12 |
||
670 | |||
671 | -struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[], |
||
672 | - size_t key_len); |
||
673 | -int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce, |
||
674 | - const u8 *data, size_t data_len, u8 *mic); |
||
675 | -void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm); |
||
676 | +static inline struct crypto_aead * |
||
677 | +ieee80211_aes_gmac_key_setup(const u8 key[], size_t key_len) |
||
678 | +{ |
||
679 | + return NULL; |
||
680 | +} |
||
681 | + |
||
682 | +static inline int |
||
683 | +ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce, |
||
684 | + const u8 *data, size_t data_len, u8 *mic) |
||
685 | +{ |
||
686 | + return -EOPNOTSUPP; |
||
687 | +} |
||
688 | + |
||
689 | +static inline void |
||
690 | +ieee80211_aes_gmac_key_free(struct crypto_aead *tfm) |
||
691 | +{ |
||
692 | +} |
||
693 | |||
694 | #endif /* AES_GMAC_H */ |
||
695 | --- a/net/mac80211/key.h |
||
696 | +++ b/net/mac80211/key.h |
||
697 | @@ -88,7 +88,7 @@ struct ieee80211_key { |
||
698 | * Management frames. |
||
699 | */ |
||
700 | u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN]; |
||
701 | - struct crypto_aead *tfm; |
||
702 | + struct crypto_cipher *tfm; |
||
703 | u32 replays; /* dot11RSNAStatsCCMPReplays */ |
||
704 | } ccmp; |
||
705 | struct { |