Root/
1 | /* |
2 | * GCM: Galois/Counter Mode. |
3 | * |
4 | * Copyright (c) 2007 Nokia Siemens Networks - Mikko Herranen <mh1@iki.fi> |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License version 2 as published |
8 | * by the Free Software Foundation. |
9 | */ |
10 | |
11 | #include <crypto/gf128mul.h> |
12 | #include <crypto/internal/aead.h> |
13 | #include <crypto/internal/skcipher.h> |
14 | #include <crypto/internal/hash.h> |
15 | #include <crypto/scatterwalk.h> |
16 | #include <crypto/hash.h> |
17 | #include "internal.h" |
18 | #include <linux/completion.h> |
19 | #include <linux/err.h> |
20 | #include <linux/init.h> |
21 | #include <linux/kernel.h> |
22 | #include <linux/module.h> |
23 | #include <linux/slab.h> |
24 | |
25 | struct gcm_instance_ctx { |
26 | struct crypto_skcipher_spawn ctr; |
27 | struct crypto_ahash_spawn ghash; |
28 | }; |
29 | |
30 | struct crypto_gcm_ctx { |
31 | struct crypto_ablkcipher *ctr; |
32 | struct crypto_ahash *ghash; |
33 | }; |
34 | |
35 | struct crypto_rfc4106_ctx { |
36 | struct crypto_aead *child; |
37 | u8 nonce[4]; |
38 | }; |
39 | |
40 | struct crypto_rfc4543_ctx { |
41 | struct crypto_aead *child; |
42 | u8 nonce[4]; |
43 | }; |
44 | |
45 | struct crypto_rfc4543_req_ctx { |
46 | u8 auth_tag[16]; |
47 | struct scatterlist cipher[1]; |
48 | struct scatterlist payload[2]; |
49 | struct scatterlist assoc[2]; |
50 | struct aead_request subreq; |
51 | }; |
52 | |
53 | struct crypto_gcm_ghash_ctx { |
54 | unsigned int cryptlen; |
55 | struct scatterlist *src; |
56 | void (*complete)(struct aead_request *req, int err); |
57 | }; |
58 | |
59 | struct crypto_gcm_req_priv_ctx { |
60 | u8 auth_tag[16]; |
61 | u8 iauth_tag[16]; |
62 | struct scatterlist src[2]; |
63 | struct scatterlist dst[2]; |
64 | struct crypto_gcm_ghash_ctx ghash_ctx; |
65 | union { |
66 | struct ahash_request ahreq; |
67 | struct ablkcipher_request abreq; |
68 | } u; |
69 | }; |
70 | |
71 | struct crypto_gcm_setkey_result { |
72 | int err; |
73 | struct completion completion; |
74 | }; |
75 | |
76 | static void *gcm_zeroes; |
77 | |
78 | static inline struct crypto_gcm_req_priv_ctx *crypto_gcm_reqctx( |
79 | struct aead_request *req) |
80 | { |
81 | unsigned long align = crypto_aead_alignmask(crypto_aead_reqtfm(req)); |
82 | |
83 | return (void *)PTR_ALIGN((u8 *)aead_request_ctx(req), align + 1); |
84 | } |
85 | |
86 | static void crypto_gcm_setkey_done(struct crypto_async_request *req, int err) |
87 | { |
88 | struct crypto_gcm_setkey_result *result = req->data; |
89 | |
90 | if (err == -EINPROGRESS) |
91 | return; |
92 | |
93 | result->err = err; |
94 | complete(&result->completion); |
95 | } |
96 | |
97 | static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key, |
98 | unsigned int keylen) |
99 | { |
100 | struct crypto_gcm_ctx *ctx = crypto_aead_ctx(aead); |
101 | struct crypto_ahash *ghash = ctx->ghash; |
102 | struct crypto_ablkcipher *ctr = ctx->ctr; |
103 | struct { |
104 | be128 hash; |
105 | u8 iv[8]; |
106 | |
107 | struct crypto_gcm_setkey_result result; |
108 | |
109 | struct scatterlist sg[1]; |
110 | struct ablkcipher_request req; |
111 | } *data; |
112 | int err; |
113 | |
114 | crypto_ablkcipher_clear_flags(ctr, CRYPTO_TFM_REQ_MASK); |
115 | crypto_ablkcipher_set_flags(ctr, crypto_aead_get_flags(aead) & |
116 | CRYPTO_TFM_REQ_MASK); |
117 | |
118 | err = crypto_ablkcipher_setkey(ctr, key, keylen); |
119 | if (err) |
120 | return err; |
121 | |
122 | crypto_aead_set_flags(aead, crypto_ablkcipher_get_flags(ctr) & |
123 | CRYPTO_TFM_RES_MASK); |
124 | |
125 | data = kzalloc(sizeof(*data) + crypto_ablkcipher_reqsize(ctr), |
126 | GFP_KERNEL); |
127 | if (!data) |
128 | return -ENOMEM; |
129 | |
130 | init_completion(&data->result.completion); |
131 | sg_init_one(data->sg, &data->hash, sizeof(data->hash)); |
132 | ablkcipher_request_set_tfm(&data->req, ctr); |
133 | ablkcipher_request_set_callback(&data->req, CRYPTO_TFM_REQ_MAY_SLEEP | |
134 | CRYPTO_TFM_REQ_MAY_BACKLOG, |
135 | crypto_gcm_setkey_done, |
136 | &data->result); |
137 | ablkcipher_request_set_crypt(&data->req, data->sg, data->sg, |
138 | sizeof(data->hash), data->iv); |
139 | |
140 | err = crypto_ablkcipher_encrypt(&data->req); |
141 | if (err == -EINPROGRESS || err == -EBUSY) { |
142 | err = wait_for_completion_interruptible( |
143 | &data->result.completion); |
144 | if (!err) |
145 | err = data->result.err; |
146 | } |
147 | |
148 | if (err) |
149 | goto out; |
150 | |
151 | crypto_ahash_clear_flags(ghash, CRYPTO_TFM_REQ_MASK); |
152 | crypto_ahash_set_flags(ghash, crypto_aead_get_flags(aead) & |
153 | CRYPTO_TFM_REQ_MASK); |
154 | err = crypto_ahash_setkey(ghash, (u8 *)&data->hash, sizeof(be128)); |
155 | crypto_aead_set_flags(aead, crypto_ahash_get_flags(ghash) & |
156 | CRYPTO_TFM_RES_MASK); |
157 | |
158 | out: |
159 | kfree(data); |
160 | return err; |
161 | } |
162 | |
163 | static int crypto_gcm_setauthsize(struct crypto_aead *tfm, |
164 | unsigned int authsize) |
165 | { |
166 | switch (authsize) { |
167 | case 4: |
168 | case 8: |
169 | case 12: |
170 | case 13: |
171 | case 14: |
172 | case 15: |
173 | case 16: |
174 | break; |
175 | default: |
176 | return -EINVAL; |
177 | } |
178 | |
179 | return 0; |
180 | } |
181 | |
182 | static void crypto_gcm_init_crypt(struct ablkcipher_request *ablk_req, |
183 | struct aead_request *req, |
184 | unsigned int cryptlen) |
185 | { |
186 | struct crypto_aead *aead = crypto_aead_reqtfm(req); |
187 | struct crypto_gcm_ctx *ctx = crypto_aead_ctx(aead); |
188 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
189 | struct scatterlist *dst; |
190 | __be32 counter = cpu_to_be32(1); |
191 | |
192 | memset(pctx->auth_tag, 0, sizeof(pctx->auth_tag)); |
193 | memcpy(req->iv + 12, &counter, 4); |
194 | |
195 | sg_init_table(pctx->src, 2); |
196 | sg_set_buf(pctx->src, pctx->auth_tag, sizeof(pctx->auth_tag)); |
197 | scatterwalk_sg_chain(pctx->src, 2, req->src); |
198 | |
199 | dst = pctx->src; |
200 | if (req->src != req->dst) { |
201 | sg_init_table(pctx->dst, 2); |
202 | sg_set_buf(pctx->dst, pctx->auth_tag, sizeof(pctx->auth_tag)); |
203 | scatterwalk_sg_chain(pctx->dst, 2, req->dst); |
204 | dst = pctx->dst; |
205 | } |
206 | |
207 | ablkcipher_request_set_tfm(ablk_req, ctx->ctr); |
208 | ablkcipher_request_set_crypt(ablk_req, pctx->src, dst, |
209 | cryptlen + sizeof(pctx->auth_tag), |
210 | req->iv); |
211 | } |
212 | |
213 | static inline unsigned int gcm_remain(unsigned int len) |
214 | { |
215 | len &= 0xfU; |
216 | return len ? 16 - len : 0; |
217 | } |
218 | |
219 | static void gcm_hash_len_done(struct crypto_async_request *areq, int err); |
220 | static void gcm_hash_final_done(struct crypto_async_request *areq, int err); |
221 | |
222 | static int gcm_hash_update(struct aead_request *req, |
223 | struct crypto_gcm_req_priv_ctx *pctx, |
224 | crypto_completion_t complete, |
225 | struct scatterlist *src, |
226 | unsigned int len) |
227 | { |
228 | struct ahash_request *ahreq = &pctx->u.ahreq; |
229 | |
230 | ahash_request_set_callback(ahreq, aead_request_flags(req), |
231 | complete, req); |
232 | ahash_request_set_crypt(ahreq, src, NULL, len); |
233 | |
234 | return crypto_ahash_update(ahreq); |
235 | } |
236 | |
237 | static int gcm_hash_remain(struct aead_request *req, |
238 | struct crypto_gcm_req_priv_ctx *pctx, |
239 | unsigned int remain, |
240 | crypto_completion_t complete) |
241 | { |
242 | struct ahash_request *ahreq = &pctx->u.ahreq; |
243 | |
244 | ahash_request_set_callback(ahreq, aead_request_flags(req), |
245 | complete, req); |
246 | sg_init_one(pctx->src, gcm_zeroes, remain); |
247 | ahash_request_set_crypt(ahreq, pctx->src, NULL, remain); |
248 | |
249 | return crypto_ahash_update(ahreq); |
250 | } |
251 | |
252 | static int gcm_hash_len(struct aead_request *req, |
253 | struct crypto_gcm_req_priv_ctx *pctx) |
254 | { |
255 | struct ahash_request *ahreq = &pctx->u.ahreq; |
256 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
257 | u128 lengths; |
258 | |
259 | lengths.a = cpu_to_be64(req->assoclen * 8); |
260 | lengths.b = cpu_to_be64(gctx->cryptlen * 8); |
261 | memcpy(pctx->iauth_tag, &lengths, 16); |
262 | sg_init_one(pctx->src, pctx->iauth_tag, 16); |
263 | ahash_request_set_callback(ahreq, aead_request_flags(req), |
264 | gcm_hash_len_done, req); |
265 | ahash_request_set_crypt(ahreq, pctx->src, |
266 | NULL, sizeof(lengths)); |
267 | |
268 | return crypto_ahash_update(ahreq); |
269 | } |
270 | |
271 | static int gcm_hash_final(struct aead_request *req, |
272 | struct crypto_gcm_req_priv_ctx *pctx) |
273 | { |
274 | struct ahash_request *ahreq = &pctx->u.ahreq; |
275 | |
276 | ahash_request_set_callback(ahreq, aead_request_flags(req), |
277 | gcm_hash_final_done, req); |
278 | ahash_request_set_crypt(ahreq, NULL, pctx->iauth_tag, 0); |
279 | |
280 | return crypto_ahash_final(ahreq); |
281 | } |
282 | |
283 | static void __gcm_hash_final_done(struct aead_request *req, int err) |
284 | { |
285 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
286 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
287 | |
288 | if (!err) |
289 | crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16); |
290 | |
291 | gctx->complete(req, err); |
292 | } |
293 | |
294 | static void gcm_hash_final_done(struct crypto_async_request *areq, int err) |
295 | { |
296 | struct aead_request *req = areq->data; |
297 | |
298 | __gcm_hash_final_done(req, err); |
299 | } |
300 | |
301 | static void __gcm_hash_len_done(struct aead_request *req, int err) |
302 | { |
303 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
304 | |
305 | if (!err) { |
306 | err = gcm_hash_final(req, pctx); |
307 | if (err == -EINPROGRESS || err == -EBUSY) |
308 | return; |
309 | } |
310 | |
311 | __gcm_hash_final_done(req, err); |
312 | } |
313 | |
314 | static void gcm_hash_len_done(struct crypto_async_request *areq, int err) |
315 | { |
316 | struct aead_request *req = areq->data; |
317 | |
318 | __gcm_hash_len_done(req, err); |
319 | } |
320 | |
321 | static void __gcm_hash_crypt_remain_done(struct aead_request *req, int err) |
322 | { |
323 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
324 | |
325 | if (!err) { |
326 | err = gcm_hash_len(req, pctx); |
327 | if (err == -EINPROGRESS || err == -EBUSY) |
328 | return; |
329 | } |
330 | |
331 | __gcm_hash_len_done(req, err); |
332 | } |
333 | |
334 | static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq, |
335 | int err) |
336 | { |
337 | struct aead_request *req = areq->data; |
338 | |
339 | __gcm_hash_crypt_remain_done(req, err); |
340 | } |
341 | |
342 | static void __gcm_hash_crypt_done(struct aead_request *req, int err) |
343 | { |
344 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
345 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
346 | unsigned int remain; |
347 | |
348 | if (!err) { |
349 | remain = gcm_remain(gctx->cryptlen); |
350 | BUG_ON(!remain); |
351 | err = gcm_hash_remain(req, pctx, remain, |
352 | gcm_hash_crypt_remain_done); |
353 | if (err == -EINPROGRESS || err == -EBUSY) |
354 | return; |
355 | } |
356 | |
357 | __gcm_hash_crypt_remain_done(req, err); |
358 | } |
359 | |
360 | static void gcm_hash_crypt_done(struct crypto_async_request *areq, int err) |
361 | { |
362 | struct aead_request *req = areq->data; |
363 | |
364 | __gcm_hash_crypt_done(req, err); |
365 | } |
366 | |
367 | static void __gcm_hash_assoc_remain_done(struct aead_request *req, int err) |
368 | { |
369 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
370 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
371 | crypto_completion_t complete; |
372 | unsigned int remain = 0; |
373 | |
374 | if (!err && gctx->cryptlen) { |
375 | remain = gcm_remain(gctx->cryptlen); |
376 | complete = remain ? gcm_hash_crypt_done : |
377 | gcm_hash_crypt_remain_done; |
378 | err = gcm_hash_update(req, pctx, complete, |
379 | gctx->src, gctx->cryptlen); |
380 | if (err == -EINPROGRESS || err == -EBUSY) |
381 | return; |
382 | } |
383 | |
384 | if (remain) |
385 | __gcm_hash_crypt_done(req, err); |
386 | else |
387 | __gcm_hash_crypt_remain_done(req, err); |
388 | } |
389 | |
390 | static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq, |
391 | int err) |
392 | { |
393 | struct aead_request *req = areq->data; |
394 | |
395 | __gcm_hash_assoc_remain_done(req, err); |
396 | } |
397 | |
398 | static void __gcm_hash_assoc_done(struct aead_request *req, int err) |
399 | { |
400 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
401 | unsigned int remain; |
402 | |
403 | if (!err) { |
404 | remain = gcm_remain(req->assoclen); |
405 | BUG_ON(!remain); |
406 | err = gcm_hash_remain(req, pctx, remain, |
407 | gcm_hash_assoc_remain_done); |
408 | if (err == -EINPROGRESS || err == -EBUSY) |
409 | return; |
410 | } |
411 | |
412 | __gcm_hash_assoc_remain_done(req, err); |
413 | } |
414 | |
415 | static void gcm_hash_assoc_done(struct crypto_async_request *areq, int err) |
416 | { |
417 | struct aead_request *req = areq->data; |
418 | |
419 | __gcm_hash_assoc_done(req, err); |
420 | } |
421 | |
422 | static void __gcm_hash_init_done(struct aead_request *req, int err) |
423 | { |
424 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
425 | crypto_completion_t complete; |
426 | unsigned int remain = 0; |
427 | |
428 | if (!err && req->assoclen) { |
429 | remain = gcm_remain(req->assoclen); |
430 | complete = remain ? gcm_hash_assoc_done : |
431 | gcm_hash_assoc_remain_done; |
432 | err = gcm_hash_update(req, pctx, complete, |
433 | req->assoc, req->assoclen); |
434 | if (err == -EINPROGRESS || err == -EBUSY) |
435 | return; |
436 | } |
437 | |
438 | if (remain) |
439 | __gcm_hash_assoc_done(req, err); |
440 | else |
441 | __gcm_hash_assoc_remain_done(req, err); |
442 | } |
443 | |
444 | static void gcm_hash_init_done(struct crypto_async_request *areq, int err) |
445 | { |
446 | struct aead_request *req = areq->data; |
447 | |
448 | __gcm_hash_init_done(req, err); |
449 | } |
450 | |
451 | static int gcm_hash(struct aead_request *req, |
452 | struct crypto_gcm_req_priv_ctx *pctx) |
453 | { |
454 | struct ahash_request *ahreq = &pctx->u.ahreq; |
455 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
456 | struct crypto_gcm_ctx *ctx = crypto_tfm_ctx(req->base.tfm); |
457 | unsigned int remain; |
458 | crypto_completion_t complete; |
459 | int err; |
460 | |
461 | ahash_request_set_tfm(ahreq, ctx->ghash); |
462 | |
463 | ahash_request_set_callback(ahreq, aead_request_flags(req), |
464 | gcm_hash_init_done, req); |
465 | err = crypto_ahash_init(ahreq); |
466 | if (err) |
467 | return err; |
468 | remain = gcm_remain(req->assoclen); |
469 | complete = remain ? gcm_hash_assoc_done : gcm_hash_assoc_remain_done; |
470 | err = gcm_hash_update(req, pctx, complete, req->assoc, req->assoclen); |
471 | if (err) |
472 | return err; |
473 | if (remain) { |
474 | err = gcm_hash_remain(req, pctx, remain, |
475 | gcm_hash_assoc_remain_done); |
476 | if (err) |
477 | return err; |
478 | } |
479 | remain = gcm_remain(gctx->cryptlen); |
480 | complete = remain ? gcm_hash_crypt_done : gcm_hash_crypt_remain_done; |
481 | err = gcm_hash_update(req, pctx, complete, gctx->src, gctx->cryptlen); |
482 | if (err) |
483 | return err; |
484 | if (remain) { |
485 | err = gcm_hash_remain(req, pctx, remain, |
486 | gcm_hash_crypt_remain_done); |
487 | if (err) |
488 | return err; |
489 | } |
490 | err = gcm_hash_len(req, pctx); |
491 | if (err) |
492 | return err; |
493 | err = gcm_hash_final(req, pctx); |
494 | if (err) |
495 | return err; |
496 | |
497 | return 0; |
498 | } |
499 | |
500 | static void gcm_enc_copy_hash(struct aead_request *req, |
501 | struct crypto_gcm_req_priv_ctx *pctx) |
502 | { |
503 | struct crypto_aead *aead = crypto_aead_reqtfm(req); |
504 | u8 *auth_tag = pctx->auth_tag; |
505 | |
506 | scatterwalk_map_and_copy(auth_tag, req->dst, req->cryptlen, |
507 | crypto_aead_authsize(aead), 1); |
508 | } |
509 | |
510 | static void gcm_enc_hash_done(struct aead_request *req, int err) |
511 | { |
512 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
513 | |
514 | if (!err) |
515 | gcm_enc_copy_hash(req, pctx); |
516 | |
517 | aead_request_complete(req, err); |
518 | } |
519 | |
520 | static void gcm_encrypt_done(struct crypto_async_request *areq, int err) |
521 | { |
522 | struct aead_request *req = areq->data; |
523 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
524 | |
525 | if (!err) { |
526 | err = gcm_hash(req, pctx); |
527 | if (err == -EINPROGRESS || err == -EBUSY) |
528 | return; |
529 | else if (!err) { |
530 | crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16); |
531 | gcm_enc_copy_hash(req, pctx); |
532 | } |
533 | } |
534 | |
535 | aead_request_complete(req, err); |
536 | } |
537 | |
538 | static int crypto_gcm_encrypt(struct aead_request *req) |
539 | { |
540 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
541 | struct ablkcipher_request *abreq = &pctx->u.abreq; |
542 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
543 | int err; |
544 | |
545 | crypto_gcm_init_crypt(abreq, req, req->cryptlen); |
546 | ablkcipher_request_set_callback(abreq, aead_request_flags(req), |
547 | gcm_encrypt_done, req); |
548 | |
549 | gctx->src = req->dst; |
550 | gctx->cryptlen = req->cryptlen; |
551 | gctx->complete = gcm_enc_hash_done; |
552 | |
553 | err = crypto_ablkcipher_encrypt(abreq); |
554 | if (err) |
555 | return err; |
556 | |
557 | err = gcm_hash(req, pctx); |
558 | if (err) |
559 | return err; |
560 | |
561 | crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16); |
562 | gcm_enc_copy_hash(req, pctx); |
563 | |
564 | return 0; |
565 | } |
566 | |
567 | static int crypto_gcm_verify(struct aead_request *req, |
568 | struct crypto_gcm_req_priv_ctx *pctx) |
569 | { |
570 | struct crypto_aead *aead = crypto_aead_reqtfm(req); |
571 | u8 *auth_tag = pctx->auth_tag; |
572 | u8 *iauth_tag = pctx->iauth_tag; |
573 | unsigned int authsize = crypto_aead_authsize(aead); |
574 | unsigned int cryptlen = req->cryptlen - authsize; |
575 | |
576 | crypto_xor(auth_tag, iauth_tag, 16); |
577 | scatterwalk_map_and_copy(iauth_tag, req->src, cryptlen, authsize, 0); |
578 | return memcmp(iauth_tag, auth_tag, authsize) ? -EBADMSG : 0; |
579 | } |
580 | |
581 | static void gcm_decrypt_done(struct crypto_async_request *areq, int err) |
582 | { |
583 | struct aead_request *req = areq->data; |
584 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
585 | |
586 | if (!err) |
587 | err = crypto_gcm_verify(req, pctx); |
588 | |
589 | aead_request_complete(req, err); |
590 | } |
591 | |
592 | static void gcm_dec_hash_done(struct aead_request *req, int err) |
593 | { |
594 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
595 | struct ablkcipher_request *abreq = &pctx->u.abreq; |
596 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
597 | |
598 | if (!err) { |
599 | ablkcipher_request_set_callback(abreq, aead_request_flags(req), |
600 | gcm_decrypt_done, req); |
601 | crypto_gcm_init_crypt(abreq, req, gctx->cryptlen); |
602 | err = crypto_ablkcipher_decrypt(abreq); |
603 | if (err == -EINPROGRESS || err == -EBUSY) |
604 | return; |
605 | else if (!err) |
606 | err = crypto_gcm_verify(req, pctx); |
607 | } |
608 | |
609 | aead_request_complete(req, err); |
610 | } |
611 | |
612 | static int crypto_gcm_decrypt(struct aead_request *req) |
613 | { |
614 | struct crypto_aead *aead = crypto_aead_reqtfm(req); |
615 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
616 | struct ablkcipher_request *abreq = &pctx->u.abreq; |
617 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
618 | unsigned int authsize = crypto_aead_authsize(aead); |
619 | unsigned int cryptlen = req->cryptlen; |
620 | int err; |
621 | |
622 | if (cryptlen < authsize) |
623 | return -EINVAL; |
624 | cryptlen -= authsize; |
625 | |
626 | gctx->src = req->src; |
627 | gctx->cryptlen = cryptlen; |
628 | gctx->complete = gcm_dec_hash_done; |
629 | |
630 | err = gcm_hash(req, pctx); |
631 | if (err) |
632 | return err; |
633 | |
634 | ablkcipher_request_set_callback(abreq, aead_request_flags(req), |
635 | gcm_decrypt_done, req); |
636 | crypto_gcm_init_crypt(abreq, req, cryptlen); |
637 | err = crypto_ablkcipher_decrypt(abreq); |
638 | if (err) |
639 | return err; |
640 | |
641 | return crypto_gcm_verify(req, pctx); |
642 | } |
643 | |
644 | static int crypto_gcm_init_tfm(struct crypto_tfm *tfm) |
645 | { |
646 | struct crypto_instance *inst = (void *)tfm->__crt_alg; |
647 | struct gcm_instance_ctx *ictx = crypto_instance_ctx(inst); |
648 | struct crypto_gcm_ctx *ctx = crypto_tfm_ctx(tfm); |
649 | struct crypto_ablkcipher *ctr; |
650 | struct crypto_ahash *ghash; |
651 | unsigned long align; |
652 | int err; |
653 | |
654 | ghash = crypto_spawn_ahash(&ictx->ghash); |
655 | if (IS_ERR(ghash)) |
656 | return PTR_ERR(ghash); |
657 | |
658 | ctr = crypto_spawn_skcipher(&ictx->ctr); |
659 | err = PTR_ERR(ctr); |
660 | if (IS_ERR(ctr)) |
661 | goto err_free_hash; |
662 | |
663 | ctx->ctr = ctr; |
664 | ctx->ghash = ghash; |
665 | |
666 | align = crypto_tfm_alg_alignmask(tfm); |
667 | align &= ~(crypto_tfm_ctx_alignment() - 1); |
668 | tfm->crt_aead.reqsize = align + |
669 | offsetof(struct crypto_gcm_req_priv_ctx, u) + |
670 | max(sizeof(struct ablkcipher_request) + |
671 | crypto_ablkcipher_reqsize(ctr), |
672 | sizeof(struct ahash_request) + |
673 | crypto_ahash_reqsize(ghash)); |
674 | |
675 | return 0; |
676 | |
677 | err_free_hash: |
678 | crypto_free_ahash(ghash); |
679 | return err; |
680 | } |
681 | |
682 | static void crypto_gcm_exit_tfm(struct crypto_tfm *tfm) |
683 | { |
684 | struct crypto_gcm_ctx *ctx = crypto_tfm_ctx(tfm); |
685 | |
686 | crypto_free_ahash(ctx->ghash); |
687 | crypto_free_ablkcipher(ctx->ctr); |
688 | } |
689 | |
690 | static struct crypto_instance *crypto_gcm_alloc_common(struct rtattr **tb, |
691 | const char *full_name, |
692 | const char *ctr_name, |
693 | const char *ghash_name) |
694 | { |
695 | struct crypto_attr_type *algt; |
696 | struct crypto_instance *inst; |
697 | struct crypto_alg *ctr; |
698 | struct crypto_alg *ghash_alg; |
699 | struct ahash_alg *ghash_ahash_alg; |
700 | struct gcm_instance_ctx *ctx; |
701 | int err; |
702 | |
703 | algt = crypto_get_attr_type(tb); |
704 | err = PTR_ERR(algt); |
705 | if (IS_ERR(algt)) |
706 | return ERR_PTR(err); |
707 | |
708 | if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask) |
709 | return ERR_PTR(-EINVAL); |
710 | |
711 | ghash_alg = crypto_find_alg(ghash_name, &crypto_ahash_type, |
712 | CRYPTO_ALG_TYPE_HASH, |
713 | CRYPTO_ALG_TYPE_AHASH_MASK); |
714 | err = PTR_ERR(ghash_alg); |
715 | if (IS_ERR(ghash_alg)) |
716 | return ERR_PTR(err); |
717 | |
718 | err = -ENOMEM; |
719 | inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); |
720 | if (!inst) |
721 | goto out_put_ghash; |
722 | |
723 | ctx = crypto_instance_ctx(inst); |
724 | ghash_ahash_alg = container_of(ghash_alg, struct ahash_alg, halg.base); |
725 | err = crypto_init_ahash_spawn(&ctx->ghash, &ghash_ahash_alg->halg, |
726 | inst); |
727 | if (err) |
728 | goto err_free_inst; |
729 | |
730 | crypto_set_skcipher_spawn(&ctx->ctr, inst); |
731 | err = crypto_grab_skcipher(&ctx->ctr, ctr_name, 0, |
732 | crypto_requires_sync(algt->type, |
733 | algt->mask)); |
734 | if (err) |
735 | goto err_drop_ghash; |
736 | |
737 | ctr = crypto_skcipher_spawn_alg(&ctx->ctr); |
738 | |
739 | /* We only support 16-byte blocks. */ |
740 | if (ctr->cra_ablkcipher.ivsize != 16) |
741 | goto out_put_ctr; |
742 | |
743 | /* Not a stream cipher? */ |
744 | err = -EINVAL; |
745 | if (ctr->cra_blocksize != 1) |
746 | goto out_put_ctr; |
747 | |
748 | err = -ENAMETOOLONG; |
749 | if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, |
750 | "gcm_base(%s,%s)", ctr->cra_driver_name, |
751 | ghash_alg->cra_driver_name) >= |
752 | CRYPTO_MAX_ALG_NAME) |
753 | goto out_put_ctr; |
754 | |
755 | memcpy(inst->alg.cra_name, full_name, CRYPTO_MAX_ALG_NAME); |
756 | |
757 | inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD; |
758 | inst->alg.cra_flags |= ctr->cra_flags & CRYPTO_ALG_ASYNC; |
759 | inst->alg.cra_priority = ctr->cra_priority; |
760 | inst->alg.cra_blocksize = 1; |
761 | inst->alg.cra_alignmask = ctr->cra_alignmask | (__alignof__(u64) - 1); |
762 | inst->alg.cra_type = &crypto_aead_type; |
763 | inst->alg.cra_aead.ivsize = 16; |
764 | inst->alg.cra_aead.maxauthsize = 16; |
765 | inst->alg.cra_ctxsize = sizeof(struct crypto_gcm_ctx); |
766 | inst->alg.cra_init = crypto_gcm_init_tfm; |
767 | inst->alg.cra_exit = crypto_gcm_exit_tfm; |
768 | inst->alg.cra_aead.setkey = crypto_gcm_setkey; |
769 | inst->alg.cra_aead.setauthsize = crypto_gcm_setauthsize; |
770 | inst->alg.cra_aead.encrypt = crypto_gcm_encrypt; |
771 | inst->alg.cra_aead.decrypt = crypto_gcm_decrypt; |
772 | |
773 | out: |
774 | crypto_mod_put(ghash_alg); |
775 | return inst; |
776 | |
777 | out_put_ctr: |
778 | crypto_drop_skcipher(&ctx->ctr); |
779 | err_drop_ghash: |
780 | crypto_drop_ahash(&ctx->ghash); |
781 | err_free_inst: |
782 | kfree(inst); |
783 | out_put_ghash: |
784 | inst = ERR_PTR(err); |
785 | goto out; |
786 | } |
787 | |
788 | static struct crypto_instance *crypto_gcm_alloc(struct rtattr **tb) |
789 | { |
790 | int err; |
791 | const char *cipher_name; |
792 | char ctr_name[CRYPTO_MAX_ALG_NAME]; |
793 | char full_name[CRYPTO_MAX_ALG_NAME]; |
794 | |
795 | cipher_name = crypto_attr_alg_name(tb[1]); |
796 | err = PTR_ERR(cipher_name); |
797 | if (IS_ERR(cipher_name)) |
798 | return ERR_PTR(err); |
799 | |
800 | if (snprintf(ctr_name, CRYPTO_MAX_ALG_NAME, "ctr(%s)", cipher_name) >= |
801 | CRYPTO_MAX_ALG_NAME) |
802 | return ERR_PTR(-ENAMETOOLONG); |
803 | |
804 | if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "gcm(%s)", cipher_name) >= |
805 | CRYPTO_MAX_ALG_NAME) |
806 | return ERR_PTR(-ENAMETOOLONG); |
807 | |
808 | return crypto_gcm_alloc_common(tb, full_name, ctr_name, "ghash"); |
809 | } |
810 | |
811 | static void crypto_gcm_free(struct crypto_instance *inst) |
812 | { |
813 | struct gcm_instance_ctx *ctx = crypto_instance_ctx(inst); |
814 | |
815 | crypto_drop_skcipher(&ctx->ctr); |
816 | crypto_drop_ahash(&ctx->ghash); |
817 | kfree(inst); |
818 | } |
819 | |
820 | static struct crypto_template crypto_gcm_tmpl = { |
821 | .name = "gcm", |
822 | .alloc = crypto_gcm_alloc, |
823 | .free = crypto_gcm_free, |
824 | .module = THIS_MODULE, |
825 | }; |
826 | |
827 | static struct crypto_instance *crypto_gcm_base_alloc(struct rtattr **tb) |
828 | { |
829 | int err; |
830 | const char *ctr_name; |
831 | const char *ghash_name; |
832 | char full_name[CRYPTO_MAX_ALG_NAME]; |
833 | |
834 | ctr_name = crypto_attr_alg_name(tb[1]); |
835 | err = PTR_ERR(ctr_name); |
836 | if (IS_ERR(ctr_name)) |
837 | return ERR_PTR(err); |
838 | |
839 | ghash_name = crypto_attr_alg_name(tb[2]); |
840 | err = PTR_ERR(ghash_name); |
841 | if (IS_ERR(ghash_name)) |
842 | return ERR_PTR(err); |
843 | |
844 | if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "gcm_base(%s,%s)", |
845 | ctr_name, ghash_name) >= CRYPTO_MAX_ALG_NAME) |
846 | return ERR_PTR(-ENAMETOOLONG); |
847 | |
848 | return crypto_gcm_alloc_common(tb, full_name, ctr_name, ghash_name); |
849 | } |
850 | |
851 | static struct crypto_template crypto_gcm_base_tmpl = { |
852 | .name = "gcm_base", |
853 | .alloc = crypto_gcm_base_alloc, |
854 | .free = crypto_gcm_free, |
855 | .module = THIS_MODULE, |
856 | }; |
857 | |
858 | static int crypto_rfc4106_setkey(struct crypto_aead *parent, const u8 *key, |
859 | unsigned int keylen) |
860 | { |
861 | struct crypto_rfc4106_ctx *ctx = crypto_aead_ctx(parent); |
862 | struct crypto_aead *child = ctx->child; |
863 | int err; |
864 | |
865 | if (keylen < 4) |
866 | return -EINVAL; |
867 | |
868 | keylen -= 4; |
869 | memcpy(ctx->nonce, key + keylen, 4); |
870 | |
871 | crypto_aead_clear_flags(child, CRYPTO_TFM_REQ_MASK); |
872 | crypto_aead_set_flags(child, crypto_aead_get_flags(parent) & |
873 | CRYPTO_TFM_REQ_MASK); |
874 | err = crypto_aead_setkey(child, key, keylen); |
875 | crypto_aead_set_flags(parent, crypto_aead_get_flags(child) & |
876 | CRYPTO_TFM_RES_MASK); |
877 | |
878 | return err; |
879 | } |
880 | |
881 | static int crypto_rfc4106_setauthsize(struct crypto_aead *parent, |
882 | unsigned int authsize) |
883 | { |
884 | struct crypto_rfc4106_ctx *ctx = crypto_aead_ctx(parent); |
885 | |
886 | switch (authsize) { |
887 | case 8: |
888 | case 12: |
889 | case 16: |
890 | break; |
891 | default: |
892 | return -EINVAL; |
893 | } |
894 | |
895 | return crypto_aead_setauthsize(ctx->child, authsize); |
896 | } |
897 | |
898 | static struct aead_request *crypto_rfc4106_crypt(struct aead_request *req) |
899 | { |
900 | struct aead_request *subreq = aead_request_ctx(req); |
901 | struct crypto_aead *aead = crypto_aead_reqtfm(req); |
902 | struct crypto_rfc4106_ctx *ctx = crypto_aead_ctx(aead); |
903 | struct crypto_aead *child = ctx->child; |
904 | u8 *iv = PTR_ALIGN((u8 *)(subreq + 1) + crypto_aead_reqsize(child), |
905 | crypto_aead_alignmask(child) + 1); |
906 | |
907 | memcpy(iv, ctx->nonce, 4); |
908 | memcpy(iv + 4, req->iv, 8); |
909 | |
910 | aead_request_set_tfm(subreq, child); |
911 | aead_request_set_callback(subreq, req->base.flags, req->base.complete, |
912 | req->base.data); |
913 | aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, iv); |
914 | aead_request_set_assoc(subreq, req->assoc, req->assoclen); |
915 | |
916 | return subreq; |
917 | } |
918 | |
919 | static int crypto_rfc4106_encrypt(struct aead_request *req) |
920 | { |
921 | req = crypto_rfc4106_crypt(req); |
922 | |
923 | return crypto_aead_encrypt(req); |
924 | } |
925 | |
926 | static int crypto_rfc4106_decrypt(struct aead_request *req) |
927 | { |
928 | req = crypto_rfc4106_crypt(req); |
929 | |
930 | return crypto_aead_decrypt(req); |
931 | } |
932 | |
933 | static int crypto_rfc4106_init_tfm(struct crypto_tfm *tfm) |
934 | { |
935 | struct crypto_instance *inst = (void *)tfm->__crt_alg; |
936 | struct crypto_aead_spawn *spawn = crypto_instance_ctx(inst); |
937 | struct crypto_rfc4106_ctx *ctx = crypto_tfm_ctx(tfm); |
938 | struct crypto_aead *aead; |
939 | unsigned long align; |
940 | |
941 | aead = crypto_spawn_aead(spawn); |
942 | if (IS_ERR(aead)) |
943 | return PTR_ERR(aead); |
944 | |
945 | ctx->child = aead; |
946 | |
947 | align = crypto_aead_alignmask(aead); |
948 | align &= ~(crypto_tfm_ctx_alignment() - 1); |
949 | tfm->crt_aead.reqsize = sizeof(struct aead_request) + |
950 | ALIGN(crypto_aead_reqsize(aead), |
951 | crypto_tfm_ctx_alignment()) + |
952 | align + 16; |
953 | |
954 | return 0; |
955 | } |
956 | |
957 | static void crypto_rfc4106_exit_tfm(struct crypto_tfm *tfm) |
958 | { |
959 | struct crypto_rfc4106_ctx *ctx = crypto_tfm_ctx(tfm); |
960 | |
961 | crypto_free_aead(ctx->child); |
962 | } |
963 | |
964 | static struct crypto_instance *crypto_rfc4106_alloc(struct rtattr **tb) |
965 | { |
966 | struct crypto_attr_type *algt; |
967 | struct crypto_instance *inst; |
968 | struct crypto_aead_spawn *spawn; |
969 | struct crypto_alg *alg; |
970 | const char *ccm_name; |
971 | int err; |
972 | |
973 | algt = crypto_get_attr_type(tb); |
974 | err = PTR_ERR(algt); |
975 | if (IS_ERR(algt)) |
976 | return ERR_PTR(err); |
977 | |
978 | if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask) |
979 | return ERR_PTR(-EINVAL); |
980 | |
981 | ccm_name = crypto_attr_alg_name(tb[1]); |
982 | err = PTR_ERR(ccm_name); |
983 | if (IS_ERR(ccm_name)) |
984 | return ERR_PTR(err); |
985 | |
986 | inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); |
987 | if (!inst) |
988 | return ERR_PTR(-ENOMEM); |
989 | |
990 | spawn = crypto_instance_ctx(inst); |
991 | crypto_set_aead_spawn(spawn, inst); |
992 | err = crypto_grab_aead(spawn, ccm_name, 0, |
993 | crypto_requires_sync(algt->type, algt->mask)); |
994 | if (err) |
995 | goto out_free_inst; |
996 | |
997 | alg = crypto_aead_spawn_alg(spawn); |
998 | |
999 | err = -EINVAL; |
1000 | |
1001 | /* We only support 16-byte blocks. */ |
1002 | if (alg->cra_aead.ivsize != 16) |
1003 | goto out_drop_alg; |
1004 | |
1005 | /* Not a stream cipher? */ |
1006 | if (alg->cra_blocksize != 1) |
1007 | goto out_drop_alg; |
1008 | |
1009 | err = -ENAMETOOLONG; |
1010 | if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, |
1011 | "rfc4106(%s)", alg->cra_name) >= CRYPTO_MAX_ALG_NAME || |
1012 | snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, |
1013 | "rfc4106(%s)", alg->cra_driver_name) >= |
1014 | CRYPTO_MAX_ALG_NAME) |
1015 | goto out_drop_alg; |
1016 | |
1017 | inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD; |
1018 | inst->alg.cra_flags |= alg->cra_flags & CRYPTO_ALG_ASYNC; |
1019 | inst->alg.cra_priority = alg->cra_priority; |
1020 | inst->alg.cra_blocksize = 1; |
1021 | inst->alg.cra_alignmask = alg->cra_alignmask; |
1022 | inst->alg.cra_type = &crypto_nivaead_type; |
1023 | |
1024 | inst->alg.cra_aead.ivsize = 8; |
1025 | inst->alg.cra_aead.maxauthsize = 16; |
1026 | |
1027 | inst->alg.cra_ctxsize = sizeof(struct crypto_rfc4106_ctx); |
1028 | |
1029 | inst->alg.cra_init = crypto_rfc4106_init_tfm; |
1030 | inst->alg.cra_exit = crypto_rfc4106_exit_tfm; |
1031 | |
1032 | inst->alg.cra_aead.setkey = crypto_rfc4106_setkey; |
1033 | inst->alg.cra_aead.setauthsize = crypto_rfc4106_setauthsize; |
1034 | inst->alg.cra_aead.encrypt = crypto_rfc4106_encrypt; |
1035 | inst->alg.cra_aead.decrypt = crypto_rfc4106_decrypt; |
1036 | |
1037 | inst->alg.cra_aead.geniv = "seqiv"; |
1038 | |
1039 | out: |
1040 | return inst; |
1041 | |
1042 | out_drop_alg: |
1043 | crypto_drop_aead(spawn); |
1044 | out_free_inst: |
1045 | kfree(inst); |
1046 | inst = ERR_PTR(err); |
1047 | goto out; |
1048 | } |
1049 | |
1050 | static void crypto_rfc4106_free(struct crypto_instance *inst) |
1051 | { |
1052 | crypto_drop_spawn(crypto_instance_ctx(inst)); |
1053 | kfree(inst); |
1054 | } |
1055 | |
1056 | static struct crypto_template crypto_rfc4106_tmpl = { |
1057 | .name = "rfc4106", |
1058 | .alloc = crypto_rfc4106_alloc, |
1059 | .free = crypto_rfc4106_free, |
1060 | .module = THIS_MODULE, |
1061 | }; |
1062 | |
1063 | static inline struct crypto_rfc4543_req_ctx *crypto_rfc4543_reqctx( |
1064 | struct aead_request *req) |
1065 | { |
1066 | unsigned long align = crypto_aead_alignmask(crypto_aead_reqtfm(req)); |
1067 | |
1068 | return (void *)PTR_ALIGN((u8 *)aead_request_ctx(req), align + 1); |
1069 | } |
1070 | |
1071 | static int crypto_rfc4543_setkey(struct crypto_aead *parent, const u8 *key, |
1072 | unsigned int keylen) |
1073 | { |
1074 | struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(parent); |
1075 | struct crypto_aead *child = ctx->child; |
1076 | int err; |
1077 | |
1078 | if (keylen < 4) |
1079 | return -EINVAL; |
1080 | |
1081 | keylen -= 4; |
1082 | memcpy(ctx->nonce, key + keylen, 4); |
1083 | |
1084 | crypto_aead_clear_flags(child, CRYPTO_TFM_REQ_MASK); |
1085 | crypto_aead_set_flags(child, crypto_aead_get_flags(parent) & |
1086 | CRYPTO_TFM_REQ_MASK); |
1087 | err = crypto_aead_setkey(child, key, keylen); |
1088 | crypto_aead_set_flags(parent, crypto_aead_get_flags(child) & |
1089 | CRYPTO_TFM_RES_MASK); |
1090 | |
1091 | return err; |
1092 | } |
1093 | |
1094 | static int crypto_rfc4543_setauthsize(struct crypto_aead *parent, |
1095 | unsigned int authsize) |
1096 | { |
1097 | struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(parent); |
1098 | |
1099 | if (authsize != 16) |
1100 | return -EINVAL; |
1101 | |
1102 | return crypto_aead_setauthsize(ctx->child, authsize); |
1103 | } |
1104 | |
1105 | /* this is the same as crypto_authenc_chain */ |
1106 | static void crypto_rfc4543_chain(struct scatterlist *head, |
1107 | struct scatterlist *sg, int chain) |
1108 | { |
1109 | if (chain) { |
1110 | head->length += sg->length; |
1111 | sg = scatterwalk_sg_next(sg); |
1112 | } |
1113 | |
1114 | if (sg) |
1115 | scatterwalk_sg_chain(head, 2, sg); |
1116 | else |
1117 | sg_mark_end(head); |
1118 | } |
1119 | |
1120 | static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req, |
1121 | int enc) |
1122 | { |
1123 | struct crypto_aead *aead = crypto_aead_reqtfm(req); |
1124 | struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(aead); |
1125 | struct crypto_rfc4543_req_ctx *rctx = crypto_rfc4543_reqctx(req); |
1126 | struct aead_request *subreq = &rctx->subreq; |
1127 | struct scatterlist *dst = req->dst; |
1128 | struct scatterlist *cipher = rctx->cipher; |
1129 | struct scatterlist *payload = rctx->payload; |
1130 | struct scatterlist *assoc = rctx->assoc; |
1131 | unsigned int authsize = crypto_aead_authsize(aead); |
1132 | unsigned int assoclen = req->assoclen; |
1133 | struct page *dstp; |
1134 | u8 *vdst; |
1135 | u8 *iv = PTR_ALIGN((u8 *)(rctx + 1) + crypto_aead_reqsize(ctx->child), |
1136 | crypto_aead_alignmask(ctx->child) + 1); |
1137 | |
1138 | memcpy(iv, ctx->nonce, 4); |
1139 | memcpy(iv + 4, req->iv, 8); |
1140 | |
1141 | /* construct cipher/plaintext */ |
1142 | if (enc) |
1143 | memset(rctx->auth_tag, 0, authsize); |
1144 | else |
1145 | scatterwalk_map_and_copy(rctx->auth_tag, dst, |
1146 | req->cryptlen - authsize, |
1147 | authsize, 0); |
1148 | |
1149 | sg_init_one(cipher, rctx->auth_tag, authsize); |
1150 | |
1151 | /* construct the aad */ |
1152 | dstp = sg_page(dst); |
1153 | vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + dst->offset; |
1154 | |
1155 | sg_init_table(payload, 2); |
1156 | sg_set_buf(payload, req->iv, 8); |
1157 | crypto_rfc4543_chain(payload, dst, vdst == req->iv + 8); |
1158 | assoclen += 8 + req->cryptlen - (enc ? 0 : authsize); |
1159 | |
1160 | sg_init_table(assoc, 2); |
1161 | sg_set_page(assoc, sg_page(req->assoc), req->assoc->length, |
1162 | req->assoc->offset); |
1163 | crypto_rfc4543_chain(assoc, payload, 0); |
1164 | |
1165 | aead_request_set_tfm(subreq, ctx->child); |
1166 | aead_request_set_callback(subreq, req->base.flags, req->base.complete, |
1167 | req->base.data); |
1168 | aead_request_set_crypt(subreq, cipher, cipher, enc ? 0 : authsize, iv); |
1169 | aead_request_set_assoc(subreq, assoc, assoclen); |
1170 | |
1171 | return subreq; |
1172 | } |
1173 | |
1174 | static int crypto_rfc4543_encrypt(struct aead_request *req) |
1175 | { |
1176 | struct crypto_aead *aead = crypto_aead_reqtfm(req); |
1177 | struct crypto_rfc4543_req_ctx *rctx = crypto_rfc4543_reqctx(req); |
1178 | struct aead_request *subreq; |
1179 | int err; |
1180 | |
1181 | subreq = crypto_rfc4543_crypt(req, 1); |
1182 | err = crypto_aead_encrypt(subreq); |
1183 | if (err) |
1184 | return err; |
1185 | |
1186 | scatterwalk_map_and_copy(rctx->auth_tag, req->dst, req->cryptlen, |
1187 | crypto_aead_authsize(aead), 1); |
1188 | |
1189 | return 0; |
1190 | } |
1191 | |
1192 | static int crypto_rfc4543_decrypt(struct aead_request *req) |
1193 | { |
1194 | req = crypto_rfc4543_crypt(req, 0); |
1195 | |
1196 | return crypto_aead_decrypt(req); |
1197 | } |
1198 | |
1199 | static int crypto_rfc4543_init_tfm(struct crypto_tfm *tfm) |
1200 | { |
1201 | struct crypto_instance *inst = (void *)tfm->__crt_alg; |
1202 | struct crypto_aead_spawn *spawn = crypto_instance_ctx(inst); |
1203 | struct crypto_rfc4543_ctx *ctx = crypto_tfm_ctx(tfm); |
1204 | struct crypto_aead *aead; |
1205 | unsigned long align; |
1206 | |
1207 | aead = crypto_spawn_aead(spawn); |
1208 | if (IS_ERR(aead)) |
1209 | return PTR_ERR(aead); |
1210 | |
1211 | ctx->child = aead; |
1212 | |
1213 | align = crypto_aead_alignmask(aead); |
1214 | align &= ~(crypto_tfm_ctx_alignment() - 1); |
1215 | tfm->crt_aead.reqsize = sizeof(struct crypto_rfc4543_req_ctx) + |
1216 | ALIGN(crypto_aead_reqsize(aead), |
1217 | crypto_tfm_ctx_alignment()) + |
1218 | align + 16; |
1219 | |
1220 | return 0; |
1221 | } |
1222 | |
1223 | static void crypto_rfc4543_exit_tfm(struct crypto_tfm *tfm) |
1224 | { |
1225 | struct crypto_rfc4543_ctx *ctx = crypto_tfm_ctx(tfm); |
1226 | |
1227 | crypto_free_aead(ctx->child); |
1228 | } |
1229 | |
1230 | static struct crypto_instance *crypto_rfc4543_alloc(struct rtattr **tb) |
1231 | { |
1232 | struct crypto_attr_type *algt; |
1233 | struct crypto_instance *inst; |
1234 | struct crypto_aead_spawn *spawn; |
1235 | struct crypto_alg *alg; |
1236 | const char *ccm_name; |
1237 | int err; |
1238 | |
1239 | algt = crypto_get_attr_type(tb); |
1240 | err = PTR_ERR(algt); |
1241 | if (IS_ERR(algt)) |
1242 | return ERR_PTR(err); |
1243 | |
1244 | if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask) |
1245 | return ERR_PTR(-EINVAL); |
1246 | |
1247 | ccm_name = crypto_attr_alg_name(tb[1]); |
1248 | err = PTR_ERR(ccm_name); |
1249 | if (IS_ERR(ccm_name)) |
1250 | return ERR_PTR(err); |
1251 | |
1252 | inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); |
1253 | if (!inst) |
1254 | return ERR_PTR(-ENOMEM); |
1255 | |
1256 | spawn = crypto_instance_ctx(inst); |
1257 | crypto_set_aead_spawn(spawn, inst); |
1258 | err = crypto_grab_aead(spawn, ccm_name, 0, |
1259 | crypto_requires_sync(algt->type, algt->mask)); |
1260 | if (err) |
1261 | goto out_free_inst; |
1262 | |
1263 | alg = crypto_aead_spawn_alg(spawn); |
1264 | |
1265 | err = -EINVAL; |
1266 | |
1267 | /* We only support 16-byte blocks. */ |
1268 | if (alg->cra_aead.ivsize != 16) |
1269 | goto out_drop_alg; |
1270 | |
1271 | /* Not a stream cipher? */ |
1272 | if (alg->cra_blocksize != 1) |
1273 | goto out_drop_alg; |
1274 | |
1275 | err = -ENAMETOOLONG; |
1276 | if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, |
1277 | "rfc4543(%s)", alg->cra_name) >= CRYPTO_MAX_ALG_NAME || |
1278 | snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, |
1279 | "rfc4543(%s)", alg->cra_driver_name) >= |
1280 | CRYPTO_MAX_ALG_NAME) |
1281 | goto out_drop_alg; |
1282 | |
1283 | inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD; |
1284 | inst->alg.cra_flags |= alg->cra_flags & CRYPTO_ALG_ASYNC; |
1285 | inst->alg.cra_priority = alg->cra_priority; |
1286 | inst->alg.cra_blocksize = 1; |
1287 | inst->alg.cra_alignmask = alg->cra_alignmask; |
1288 | inst->alg.cra_type = &crypto_nivaead_type; |
1289 | |
1290 | inst->alg.cra_aead.ivsize = 8; |
1291 | inst->alg.cra_aead.maxauthsize = 16; |
1292 | |
1293 | inst->alg.cra_ctxsize = sizeof(struct crypto_rfc4543_ctx); |
1294 | |
1295 | inst->alg.cra_init = crypto_rfc4543_init_tfm; |
1296 | inst->alg.cra_exit = crypto_rfc4543_exit_tfm; |
1297 | |
1298 | inst->alg.cra_aead.setkey = crypto_rfc4543_setkey; |
1299 | inst->alg.cra_aead.setauthsize = crypto_rfc4543_setauthsize; |
1300 | inst->alg.cra_aead.encrypt = crypto_rfc4543_encrypt; |
1301 | inst->alg.cra_aead.decrypt = crypto_rfc4543_decrypt; |
1302 | |
1303 | inst->alg.cra_aead.geniv = "seqiv"; |
1304 | |
1305 | out: |
1306 | return inst; |
1307 | |
1308 | out_drop_alg: |
1309 | crypto_drop_aead(spawn); |
1310 | out_free_inst: |
1311 | kfree(inst); |
1312 | inst = ERR_PTR(err); |
1313 | goto out; |
1314 | } |
1315 | |
1316 | static void crypto_rfc4543_free(struct crypto_instance *inst) |
1317 | { |
1318 | crypto_drop_spawn(crypto_instance_ctx(inst)); |
1319 | kfree(inst); |
1320 | } |
1321 | |
1322 | static struct crypto_template crypto_rfc4543_tmpl = { |
1323 | .name = "rfc4543", |
1324 | .alloc = crypto_rfc4543_alloc, |
1325 | .free = crypto_rfc4543_free, |
1326 | .module = THIS_MODULE, |
1327 | }; |
1328 | |
1329 | static int __init crypto_gcm_module_init(void) |
1330 | { |
1331 | int err; |
1332 | |
1333 | gcm_zeroes = kzalloc(16, GFP_KERNEL); |
1334 | if (!gcm_zeroes) |
1335 | return -ENOMEM; |
1336 | |
1337 | err = crypto_register_template(&crypto_gcm_base_tmpl); |
1338 | if (err) |
1339 | goto out; |
1340 | |
1341 | err = crypto_register_template(&crypto_gcm_tmpl); |
1342 | if (err) |
1343 | goto out_undo_base; |
1344 | |
1345 | err = crypto_register_template(&crypto_rfc4106_tmpl); |
1346 | if (err) |
1347 | goto out_undo_gcm; |
1348 | |
1349 | err = crypto_register_template(&crypto_rfc4543_tmpl); |
1350 | if (err) |
1351 | goto out_undo_rfc4106; |
1352 | |
1353 | return 0; |
1354 | |
1355 | out_undo_rfc4106: |
1356 | crypto_unregister_template(&crypto_rfc4106_tmpl); |
1357 | out_undo_gcm: |
1358 | crypto_unregister_template(&crypto_gcm_tmpl); |
1359 | out_undo_base: |
1360 | crypto_unregister_template(&crypto_gcm_base_tmpl); |
1361 | out: |
1362 | kfree(gcm_zeroes); |
1363 | return err; |
1364 | } |
1365 | |
1366 | static void __exit crypto_gcm_module_exit(void) |
1367 | { |
1368 | kfree(gcm_zeroes); |
1369 | crypto_unregister_template(&crypto_rfc4543_tmpl); |
1370 | crypto_unregister_template(&crypto_rfc4106_tmpl); |
1371 | crypto_unregister_template(&crypto_gcm_tmpl); |
1372 | crypto_unregister_template(&crypto_gcm_base_tmpl); |
1373 | } |
1374 | |
1375 | module_init(crypto_gcm_module_init); |
1376 | module_exit(crypto_gcm_module_exit); |
1377 | |
1378 | MODULE_LICENSE("GPL"); |
1379 | MODULE_DESCRIPTION("Galois/Counter Mode"); |
1380 | MODULE_AUTHOR("Mikko Herranen <mh1@iki.fi>"); |
1381 | MODULE_ALIAS("gcm_base"); |
1382 | MODULE_ALIAS("rfc4106"); |
1383 | MODULE_ALIAS("rfc4543"); |
1384 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9