]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - crypto/authencesn.c
module: Fix locking in symbol_put_addr()
[karo-tx-linux.git] / crypto / authencesn.c
1 /*
2  * authencesn.c - AEAD wrapper for IPsec with extended sequence numbers,
3  *                 derived from authenc.c
4  *
5  * Copyright (C) 2010 secunet Security Networks AG
6  * Copyright (C) 2010 Steffen Klassert <steffen.klassert@secunet.com>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the Free
10  * Software Foundation; either version 2 of the License, or (at your option)
11  * any later version.
12  *
13  */
14
15 #include <crypto/internal/aead.h>
16 #include <crypto/internal/hash.h>
17 #include <crypto/internal/skcipher.h>
18 #include <crypto/authenc.h>
19 #include <crypto/scatterwalk.h>
20 #include <linux/err.h>
21 #include <linux/init.h>
22 #include <linux/kernel.h>
23 #include <linux/module.h>
24 #include <linux/rtnetlink.h>
25 #include <linux/slab.h>
26 #include <linux/spinlock.h>
27
28 struct authenc_esn_instance_ctx {
29         struct crypto_ahash_spawn auth;
30         struct crypto_skcipher_spawn enc;
31 };
32
33 struct crypto_authenc_esn_ctx {
34         unsigned int reqoff;
35         struct crypto_ahash *auth;
36         struct crypto_ablkcipher *enc;
37 };
38
39 struct authenc_esn_request_ctx {
40         unsigned int cryptlen;
41         unsigned int headlen;
42         unsigned int trailen;
43         struct scatterlist *sg;
44         struct scatterlist hsg[2];
45         struct scatterlist tsg[1];
46         struct scatterlist cipher[2];
47         crypto_completion_t complete;
48         crypto_completion_t update_complete;
49         crypto_completion_t update_complete2;
50         char tail[];
51 };
52
53 static void authenc_esn_request_complete(struct aead_request *req, int err)
54 {
55         if (err != -EINPROGRESS)
56                 aead_request_complete(req, err);
57 }
58
59 static int crypto_authenc_esn_setkey(struct crypto_aead *authenc_esn, const u8 *key,
60                                      unsigned int keylen)
61 {
62         struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
63         struct crypto_ahash *auth = ctx->auth;
64         struct crypto_ablkcipher *enc = ctx->enc;
65         struct crypto_authenc_keys keys;
66         int err = -EINVAL;
67
68         if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
69                 goto badkey;
70
71         crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
72         crypto_ahash_set_flags(auth, crypto_aead_get_flags(authenc_esn) &
73                                      CRYPTO_TFM_REQ_MASK);
74         err = crypto_ahash_setkey(auth, keys.authkey, keys.authkeylen);
75         crypto_aead_set_flags(authenc_esn, crypto_ahash_get_flags(auth) &
76                                            CRYPTO_TFM_RES_MASK);
77
78         if (err)
79                 goto out;
80
81         crypto_ablkcipher_clear_flags(enc, CRYPTO_TFM_REQ_MASK);
82         crypto_ablkcipher_set_flags(enc, crypto_aead_get_flags(authenc_esn) &
83                                          CRYPTO_TFM_REQ_MASK);
84         err = crypto_ablkcipher_setkey(enc, keys.enckey, keys.enckeylen);
85         crypto_aead_set_flags(authenc_esn, crypto_ablkcipher_get_flags(enc) &
86                                            CRYPTO_TFM_RES_MASK);
87
88 out:
89         return err;
90
91 badkey:
92         crypto_aead_set_flags(authenc_esn, CRYPTO_TFM_RES_BAD_KEY_LEN);
93         goto out;
94 }
95
96 static void authenc_esn_geniv_ahash_update_done(struct crypto_async_request *areq,
97                                                 int err)
98 {
99         struct aead_request *req = areq->data;
100         struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
101         struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
102         struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
103         struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
104
105         if (err)
106                 goto out;
107
108         ahash_request_set_crypt(ahreq, areq_ctx->sg, ahreq->result,
109                                 areq_ctx->cryptlen);
110         ahash_request_set_callback(ahreq, aead_request_flags(req) &
111                                           CRYPTO_TFM_REQ_MAY_SLEEP,
112                                    areq_ctx->update_complete2, req);
113
114         err = crypto_ahash_update(ahreq);
115         if (err)
116                 goto out;
117
118         ahash_request_set_crypt(ahreq, areq_ctx->tsg, ahreq->result,
119                                 areq_ctx->trailen);
120         ahash_request_set_callback(ahreq, aead_request_flags(req) &
121                                           CRYPTO_TFM_REQ_MAY_SLEEP,
122                                    areq_ctx->complete, req);
123
124         err = crypto_ahash_finup(ahreq);
125         if (err)
126                 goto out;
127
128         scatterwalk_map_and_copy(ahreq->result, areq_ctx->sg,
129                                  areq_ctx->cryptlen,
130                                  crypto_aead_authsize(authenc_esn), 1);
131
132 out:
133         authenc_esn_request_complete(req, err);
134 }
135
136 static void authenc_esn_geniv_ahash_update_done2(struct crypto_async_request *areq,
137                                                  int err)
138 {
139         struct aead_request *req = areq->data;
140         struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
141         struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
142         struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
143         struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
144
145         if (err)
146                 goto out;
147
148         ahash_request_set_crypt(ahreq, areq_ctx->tsg, ahreq->result,
149                                 areq_ctx->trailen);
150         ahash_request_set_callback(ahreq, aead_request_flags(req) &
151                                           CRYPTO_TFM_REQ_MAY_SLEEP,
152                                    areq_ctx->complete, req);
153
154         err = crypto_ahash_finup(ahreq);
155         if (err)
156                 goto out;
157
158         scatterwalk_map_and_copy(ahreq->result, areq_ctx->sg,
159                                  areq_ctx->cryptlen,
160                                  crypto_aead_authsize(authenc_esn), 1);
161
162 out:
163         authenc_esn_request_complete(req, err);
164 }
165
166
167 static void authenc_esn_geniv_ahash_done(struct crypto_async_request *areq,
168                                          int err)
169 {
170         struct aead_request *req = areq->data;
171         struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
172         struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
173         struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
174         struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
175
176         if (err)
177                 goto out;
178
179         scatterwalk_map_and_copy(ahreq->result, areq_ctx->sg,
180                                  areq_ctx->cryptlen,
181                                  crypto_aead_authsize(authenc_esn), 1);
182
183 out:
184         aead_request_complete(req, err);
185 }
186
187
188 static void authenc_esn_verify_ahash_update_done(struct crypto_async_request *areq,
189                                                  int err)
190 {
191         u8 *ihash;
192         unsigned int authsize;
193         struct ablkcipher_request *abreq;
194         struct aead_request *req = areq->data;
195         struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
196         struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
197         struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
198         struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
199         unsigned int cryptlen = req->cryptlen;
200
201         if (err)
202                 goto out;
203
204         ahash_request_set_crypt(ahreq, areq_ctx->sg, ahreq->result,
205                                 areq_ctx->cryptlen);
206
207         ahash_request_set_callback(ahreq,
208                                    aead_request_flags(req) &
209                                    CRYPTO_TFM_REQ_MAY_SLEEP,
210                                    areq_ctx->update_complete2, req);
211
212         err = crypto_ahash_update(ahreq);
213         if (err)
214                 goto out;
215
216         ahash_request_set_crypt(ahreq, areq_ctx->tsg, ahreq->result,
217                                 areq_ctx->trailen);
218         ahash_request_set_callback(ahreq, aead_request_flags(req) &
219                                           CRYPTO_TFM_REQ_MAY_SLEEP,
220                                    areq_ctx->complete, req);
221
222         err = crypto_ahash_finup(ahreq);
223         if (err)
224                 goto out;
225
226         authsize = crypto_aead_authsize(authenc_esn);
227         cryptlen -= authsize;
228         ihash = ahreq->result + authsize;
229         scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
230                                  authsize, 0);
231
232         err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
233         if (err)
234                 goto out;
235
236         abreq = aead_request_ctx(req);
237         ablkcipher_request_set_tfm(abreq, ctx->enc);
238         ablkcipher_request_set_callback(abreq, aead_request_flags(req),
239                                         req->base.complete, req->base.data);
240         ablkcipher_request_set_crypt(abreq, req->src, req->dst,
241                                      cryptlen, req->iv);
242
243         err = crypto_ablkcipher_decrypt(abreq);
244
245 out:
246         authenc_esn_request_complete(req, err);
247 }
248
249 static void authenc_esn_verify_ahash_update_done2(struct crypto_async_request *areq,
250                                                   int err)
251 {
252         u8 *ihash;
253         unsigned int authsize;
254         struct ablkcipher_request *abreq;
255         struct aead_request *req = areq->data;
256         struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
257         struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
258         struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
259         struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
260         unsigned int cryptlen = req->cryptlen;
261
262         if (err)
263                 goto out;
264
265         ahash_request_set_crypt(ahreq, areq_ctx->tsg, ahreq->result,
266                                 areq_ctx->trailen);
267         ahash_request_set_callback(ahreq, aead_request_flags(req) &
268                                           CRYPTO_TFM_REQ_MAY_SLEEP,
269                                    areq_ctx->complete, req);
270
271         err = crypto_ahash_finup(ahreq);
272         if (err)
273                 goto out;
274
275         authsize = crypto_aead_authsize(authenc_esn);
276         cryptlen -= authsize;
277         ihash = ahreq->result + authsize;
278         scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
279                                  authsize, 0);
280
281         err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
282         if (err)
283                 goto out;
284
285         abreq = aead_request_ctx(req);
286         ablkcipher_request_set_tfm(abreq, ctx->enc);
287         ablkcipher_request_set_callback(abreq, aead_request_flags(req),
288                                         req->base.complete, req->base.data);
289         ablkcipher_request_set_crypt(abreq, req->src, req->dst,
290                                      cryptlen, req->iv);
291
292         err = crypto_ablkcipher_decrypt(abreq);
293
294 out:
295         authenc_esn_request_complete(req, err);
296 }
297
298
299 static void authenc_esn_verify_ahash_done(struct crypto_async_request *areq,
300                                           int err)
301 {
302         u8 *ihash;
303         unsigned int authsize;
304         struct ablkcipher_request *abreq;
305         struct aead_request *req = areq->data;
306         struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
307         struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
308         struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
309         struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
310         unsigned int cryptlen = req->cryptlen;
311
312         if (err)
313                 goto out;
314
315         authsize = crypto_aead_authsize(authenc_esn);
316         cryptlen -= authsize;
317         ihash = ahreq->result + authsize;
318         scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
319                                  authsize, 0);
320
321         err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
322         if (err)
323                 goto out;
324
325         abreq = aead_request_ctx(req);
326         ablkcipher_request_set_tfm(abreq, ctx->enc);
327         ablkcipher_request_set_callback(abreq, aead_request_flags(req),
328                                         req->base.complete, req->base.data);
329         ablkcipher_request_set_crypt(abreq, req->src, req->dst,
330                                      cryptlen, req->iv);
331
332         err = crypto_ablkcipher_decrypt(abreq);
333
334 out:
335         authenc_esn_request_complete(req, err);
336 }
337
338 static u8 *crypto_authenc_esn_ahash(struct aead_request *req,
339                                     unsigned int flags)
340 {
341         struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
342         struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
343         struct crypto_ahash *auth = ctx->auth;
344         struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
345         struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
346         u8 *hash = areq_ctx->tail;
347         int err;
348
349         hash = (u8 *)ALIGN((unsigned long)hash + crypto_ahash_alignmask(auth),
350                             crypto_ahash_alignmask(auth) + 1);
351
352         ahash_request_set_tfm(ahreq, auth);
353
354         err = crypto_ahash_init(ahreq);
355         if (err)
356                 return ERR_PTR(err);
357
358         ahash_request_set_crypt(ahreq, areq_ctx->hsg, hash, areq_ctx->headlen);
359         ahash_request_set_callback(ahreq, aead_request_flags(req) & flags,
360                                    areq_ctx->update_complete, req);
361
362         err = crypto_ahash_update(ahreq);
363         if (err)
364                 return ERR_PTR(err);
365
366         ahash_request_set_crypt(ahreq, areq_ctx->sg, hash, areq_ctx->cryptlen);
367         ahash_request_set_callback(ahreq, aead_request_flags(req) & flags,
368                                    areq_ctx->update_complete2, req);
369
370         err = crypto_ahash_update(ahreq);
371         if (err)
372                 return ERR_PTR(err);
373
374         ahash_request_set_crypt(ahreq, areq_ctx->tsg, hash,
375                                 areq_ctx->trailen);
376         ahash_request_set_callback(ahreq, aead_request_flags(req) & flags,
377                                    areq_ctx->complete, req);
378
379         err = crypto_ahash_finup(ahreq);
380         if (err)
381                 return ERR_PTR(err);
382
383         return hash;
384 }
385
386 static int crypto_authenc_esn_genicv(struct aead_request *req, u8 *iv,
387                                      unsigned int flags)
388 {
389         struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
390         struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
391         struct scatterlist *dst = req->dst;
392         struct scatterlist *assoc = req->assoc;
393         struct scatterlist *cipher = areq_ctx->cipher;
394         struct scatterlist *hsg = areq_ctx->hsg;
395         struct scatterlist *tsg = areq_ctx->tsg;
396         unsigned int ivsize = crypto_aead_ivsize(authenc_esn);
397         unsigned int cryptlen = req->cryptlen;
398         struct page *dstp;
399         u8 *vdst;
400         u8 *hash;
401
402         dstp = sg_page(dst);
403         vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + dst->offset;
404
405         if (ivsize) {
406                 sg_init_table(cipher, 2);
407                 sg_set_buf(cipher, iv, ivsize);
408                 scatterwalk_crypto_chain(cipher, dst, vdst == iv + ivsize, 2);
409                 dst = cipher;
410                 cryptlen += ivsize;
411         }
412
413         if (assoc->length < 12)
414                 return -EINVAL;
415
416         sg_init_table(hsg, 2);
417         sg_set_page(hsg, sg_page(assoc), 4, assoc->offset);
418         sg_set_page(hsg + 1, sg_page(assoc), 4, assoc->offset + 8);
419
420         sg_init_table(tsg, 1);
421         sg_set_page(tsg, sg_page(assoc), 4, assoc->offset + 4);
422
423         areq_ctx->cryptlen = cryptlen;
424         areq_ctx->headlen = 8;
425         areq_ctx->trailen = 4;
426         areq_ctx->sg = dst;
427
428         areq_ctx->complete = authenc_esn_geniv_ahash_done;
429         areq_ctx->update_complete = authenc_esn_geniv_ahash_update_done;
430         areq_ctx->update_complete2 = authenc_esn_geniv_ahash_update_done2;
431
432         hash = crypto_authenc_esn_ahash(req, flags);
433         if (IS_ERR(hash))
434                 return PTR_ERR(hash);
435
436         scatterwalk_map_and_copy(hash, dst, cryptlen,
437                                  crypto_aead_authsize(authenc_esn), 1);
438         return 0;
439 }
440
441
442 static void crypto_authenc_esn_encrypt_done(struct crypto_async_request *req,
443                                             int err)
444 {
445         struct aead_request *areq = req->data;
446
447         if (!err) {
448                 struct crypto_aead *authenc_esn = crypto_aead_reqtfm(areq);
449                 struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
450                 struct ablkcipher_request *abreq = aead_request_ctx(areq);
451                 u8 *iv = (u8 *)(abreq + 1) +
452                          crypto_ablkcipher_reqsize(ctx->enc);
453
454                 err = crypto_authenc_esn_genicv(areq, iv, 0);
455         }
456
457         authenc_esn_request_complete(areq, err);
458 }
459
460 static int crypto_authenc_esn_encrypt(struct aead_request *req)
461 {
462         struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
463         struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
464         struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
465         struct crypto_ablkcipher *enc = ctx->enc;
466         struct scatterlist *dst = req->dst;
467         unsigned int cryptlen = req->cryptlen;
468         struct ablkcipher_request *abreq = (void *)(areq_ctx->tail
469                                                     + ctx->reqoff);
470         u8 *iv = (u8 *)abreq - crypto_ablkcipher_ivsize(enc);
471         int err;
472
473         ablkcipher_request_set_tfm(abreq, enc);
474         ablkcipher_request_set_callback(abreq, aead_request_flags(req),
475                                         crypto_authenc_esn_encrypt_done, req);
476         ablkcipher_request_set_crypt(abreq, req->src, dst, cryptlen, req->iv);
477
478         memcpy(iv, req->iv, crypto_aead_ivsize(authenc_esn));
479
480         err = crypto_ablkcipher_encrypt(abreq);
481         if (err)
482                 return err;
483
484         return crypto_authenc_esn_genicv(req, iv, CRYPTO_TFM_REQ_MAY_SLEEP);
485 }
486
487 static void crypto_authenc_esn_givencrypt_done(struct crypto_async_request *req,
488                                                int err)
489 {
490         struct aead_request *areq = req->data;
491
492         if (!err) {
493                 struct skcipher_givcrypt_request *greq = aead_request_ctx(areq);
494
495                 err = crypto_authenc_esn_genicv(areq, greq->giv, 0);
496         }
497
498         authenc_esn_request_complete(areq, err);
499 }
500
501 static int crypto_authenc_esn_givencrypt(struct aead_givcrypt_request *req)
502 {
503         struct crypto_aead *authenc_esn = aead_givcrypt_reqtfm(req);
504         struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
505         struct aead_request *areq = &req->areq;
506         struct skcipher_givcrypt_request *greq = aead_request_ctx(areq);
507         u8 *iv = req->giv;
508         int err;
509
510         skcipher_givcrypt_set_tfm(greq, ctx->enc);
511         skcipher_givcrypt_set_callback(greq, aead_request_flags(areq),
512                                        crypto_authenc_esn_givencrypt_done, areq);
513         skcipher_givcrypt_set_crypt(greq, areq->src, areq->dst, areq->cryptlen,
514                                     areq->iv);
515         skcipher_givcrypt_set_giv(greq, iv, req->seq);
516
517         err = crypto_skcipher_givencrypt(greq);
518         if (err)
519                 return err;
520
521         return crypto_authenc_esn_genicv(areq, iv, CRYPTO_TFM_REQ_MAY_SLEEP);
522 }
523
524 static int crypto_authenc_esn_verify(struct aead_request *req)
525 {
526         struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
527         struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
528         u8 *ohash;
529         u8 *ihash;
530         unsigned int authsize;
531
532         areq_ctx->complete = authenc_esn_verify_ahash_done;
533         areq_ctx->update_complete = authenc_esn_verify_ahash_update_done;
534
535         ohash = crypto_authenc_esn_ahash(req, CRYPTO_TFM_REQ_MAY_SLEEP);
536         if (IS_ERR(ohash))
537                 return PTR_ERR(ohash);
538
539         authsize = crypto_aead_authsize(authenc_esn);
540         ihash = ohash + authsize;
541         scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
542                                  authsize, 0);
543         return crypto_memneq(ihash, ohash, authsize) ? -EBADMSG : 0;
544 }
545
546 static int crypto_authenc_esn_iverify(struct aead_request *req, u8 *iv,
547                                       unsigned int cryptlen)
548 {
549         struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
550         struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
551         struct scatterlist *src = req->src;
552         struct scatterlist *assoc = req->assoc;
553         struct scatterlist *cipher = areq_ctx->cipher;
554         struct scatterlist *hsg = areq_ctx->hsg;
555         struct scatterlist *tsg = areq_ctx->tsg;
556         unsigned int ivsize = crypto_aead_ivsize(authenc_esn);
557         struct page *srcp;
558         u8 *vsrc;
559
560         srcp = sg_page(src);
561         vsrc = PageHighMem(srcp) ? NULL : page_address(srcp) + src->offset;
562
563         if (ivsize) {
564                 sg_init_table(cipher, 2);
565                 sg_set_buf(cipher, iv, ivsize);
566                 scatterwalk_crypto_chain(cipher, src, vsrc == iv + ivsize, 2);
567                 src = cipher;
568                 cryptlen += ivsize;
569         }
570
571         if (assoc->length < 12)
572                 return -EINVAL;
573
574         sg_init_table(hsg, 2);
575         sg_set_page(hsg, sg_page(assoc), 4, assoc->offset);
576         sg_set_page(hsg + 1, sg_page(assoc), 4, assoc->offset + 8);
577
578         sg_init_table(tsg, 1);
579         sg_set_page(tsg, sg_page(assoc), 4, assoc->offset + 4);
580
581         areq_ctx->cryptlen = cryptlen;
582         areq_ctx->headlen = 8;
583         areq_ctx->trailen = 4;
584         areq_ctx->sg = src;
585
586         areq_ctx->complete = authenc_esn_verify_ahash_done;
587         areq_ctx->update_complete = authenc_esn_verify_ahash_update_done;
588         areq_ctx->update_complete2 = authenc_esn_verify_ahash_update_done2;
589
590         return crypto_authenc_esn_verify(req);
591 }
592
593 static int crypto_authenc_esn_decrypt(struct aead_request *req)
594 {
595         struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
596         struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
597         struct ablkcipher_request *abreq = aead_request_ctx(req);
598         unsigned int cryptlen = req->cryptlen;
599         unsigned int authsize = crypto_aead_authsize(authenc_esn);
600         u8 *iv = req->iv;
601         int err;
602
603         if (cryptlen < authsize)
604                 return -EINVAL;
605         cryptlen -= authsize;
606
607         err = crypto_authenc_esn_iverify(req, iv, cryptlen);
608         if (err)
609                 return err;
610
611         ablkcipher_request_set_tfm(abreq, ctx->enc);
612         ablkcipher_request_set_callback(abreq, aead_request_flags(req),
613                                         req->base.complete, req->base.data);
614         ablkcipher_request_set_crypt(abreq, req->src, req->dst, cryptlen, iv);
615
616         return crypto_ablkcipher_decrypt(abreq);
617 }
618
619 static int crypto_authenc_esn_init_tfm(struct crypto_tfm *tfm)
620 {
621         struct crypto_instance *inst = crypto_tfm_alg_instance(tfm);
622         struct authenc_esn_instance_ctx *ictx = crypto_instance_ctx(inst);
623         struct crypto_authenc_esn_ctx *ctx = crypto_tfm_ctx(tfm);
624         struct crypto_ahash *auth;
625         struct crypto_ablkcipher *enc;
626         int err;
627
628         auth = crypto_spawn_ahash(&ictx->auth);
629         if (IS_ERR(auth))
630                 return PTR_ERR(auth);
631
632         enc = crypto_spawn_skcipher(&ictx->enc);
633         err = PTR_ERR(enc);
634         if (IS_ERR(enc))
635                 goto err_free_ahash;
636
637         ctx->auth = auth;
638         ctx->enc = enc;
639
640         ctx->reqoff = ALIGN(2 * crypto_ahash_digestsize(auth) +
641                             crypto_ahash_alignmask(auth),
642                             crypto_ahash_alignmask(auth) + 1) +
643                       crypto_ablkcipher_ivsize(enc);
644
645         crypto_aead_set_reqsize(__crypto_aead_cast(tfm),
646                 sizeof(struct authenc_esn_request_ctx) +
647                 ctx->reqoff +
648                 max_t(unsigned int,
649                         crypto_ahash_reqsize(auth) +
650                         sizeof(struct ahash_request),
651                         sizeof(struct skcipher_givcrypt_request) +
652                         crypto_ablkcipher_reqsize(enc)));
653
654         return 0;
655
656 err_free_ahash:
657         crypto_free_ahash(auth);
658         return err;
659 }
660
661 static void crypto_authenc_esn_exit_tfm(struct crypto_tfm *tfm)
662 {
663         struct crypto_authenc_esn_ctx *ctx = crypto_tfm_ctx(tfm);
664
665         crypto_free_ahash(ctx->auth);
666         crypto_free_ablkcipher(ctx->enc);
667 }
668
669 static struct crypto_instance *crypto_authenc_esn_alloc(struct rtattr **tb)
670 {
671         struct crypto_attr_type *algt;
672         struct crypto_instance *inst;
673         struct hash_alg_common *auth;
674         struct crypto_alg *auth_base;
675         struct crypto_alg *enc;
676         struct authenc_esn_instance_ctx *ctx;
677         const char *enc_name;
678         int err;
679
680         algt = crypto_get_attr_type(tb);
681         if (IS_ERR(algt))
682                 return ERR_CAST(algt);
683
684         if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
685                 return ERR_PTR(-EINVAL);
686
687         auth = ahash_attr_alg(tb[1], CRYPTO_ALG_TYPE_HASH,
688                                CRYPTO_ALG_TYPE_AHASH_MASK);
689         if (IS_ERR(auth))
690                 return ERR_CAST(auth);
691
692         auth_base = &auth->base;
693
694         enc_name = crypto_attr_alg_name(tb[2]);
695         err = PTR_ERR(enc_name);
696         if (IS_ERR(enc_name))
697                 goto out_put_auth;
698
699         inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
700         err = -ENOMEM;
701         if (!inst)
702                 goto out_put_auth;
703
704         ctx = crypto_instance_ctx(inst);
705
706         err = crypto_init_ahash_spawn(&ctx->auth, auth, inst);
707         if (err)
708                 goto err_free_inst;
709
710         crypto_set_skcipher_spawn(&ctx->enc, inst);
711         err = crypto_grab_skcipher(&ctx->enc, enc_name, 0,
712                                    crypto_requires_sync(algt->type,
713                                                         algt->mask));
714         if (err)
715                 goto err_drop_auth;
716
717         enc = crypto_skcipher_spawn_alg(&ctx->enc);
718
719         err = -ENAMETOOLONG;
720         if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME,
721                      "authencesn(%s,%s)", auth_base->cra_name, enc->cra_name) >=
722             CRYPTO_MAX_ALG_NAME)
723                 goto err_drop_enc;
724
725         if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
726                      "authencesn(%s,%s)", auth_base->cra_driver_name,
727                      enc->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
728                 goto err_drop_enc;
729
730         inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD;
731         inst->alg.cra_flags |= enc->cra_flags & CRYPTO_ALG_ASYNC;
732         inst->alg.cra_priority = enc->cra_priority *
733                                  10 + auth_base->cra_priority;
734         inst->alg.cra_blocksize = enc->cra_blocksize;
735         inst->alg.cra_alignmask = auth_base->cra_alignmask | enc->cra_alignmask;
736         inst->alg.cra_type = &crypto_aead_type;
737
738         inst->alg.cra_aead.ivsize = enc->cra_ablkcipher.ivsize;
739         inst->alg.cra_aead.maxauthsize = auth->digestsize;
740
741         inst->alg.cra_ctxsize = sizeof(struct crypto_authenc_esn_ctx);
742
743         inst->alg.cra_init = crypto_authenc_esn_init_tfm;
744         inst->alg.cra_exit = crypto_authenc_esn_exit_tfm;
745
746         inst->alg.cra_aead.setkey = crypto_authenc_esn_setkey;
747         inst->alg.cra_aead.encrypt = crypto_authenc_esn_encrypt;
748         inst->alg.cra_aead.decrypt = crypto_authenc_esn_decrypt;
749         inst->alg.cra_aead.givencrypt = crypto_authenc_esn_givencrypt;
750
751 out:
752         crypto_mod_put(auth_base);
753         return inst;
754
755 err_drop_enc:
756         crypto_drop_skcipher(&ctx->enc);
757 err_drop_auth:
758         crypto_drop_ahash(&ctx->auth);
759 err_free_inst:
760         kfree(inst);
761 out_put_auth:
762         inst = ERR_PTR(err);
763         goto out;
764 }
765
766 static void crypto_authenc_esn_free(struct crypto_instance *inst)
767 {
768         struct authenc_esn_instance_ctx *ctx = crypto_instance_ctx(inst);
769
770         crypto_drop_skcipher(&ctx->enc);
771         crypto_drop_ahash(&ctx->auth);
772         kfree(inst);
773 }
774
775 static struct crypto_template crypto_authenc_esn_tmpl = {
776         .name = "authencesn",
777         .alloc = crypto_authenc_esn_alloc,
778         .free = crypto_authenc_esn_free,
779         .module = THIS_MODULE,
780 };
781
782 static int __init crypto_authenc_esn_module_init(void)
783 {
784         return crypto_register_template(&crypto_authenc_esn_tmpl);
785 }
786
787 static void __exit crypto_authenc_esn_module_exit(void)
788 {
789         crypto_unregister_template(&crypto_authenc_esn_tmpl);
790 }
791
792 module_init(crypto_authenc_esn_module_init);
793 module_exit(crypto_authenc_esn_module_exit);
794
795 MODULE_LICENSE("GPL");
796 MODULE_AUTHOR("Steffen Klassert <steffen.klassert@secunet.com>");
797 MODULE_DESCRIPTION("AEAD wrapper for IPsec with extended sequence numbers");
798 MODULE_ALIAS_CRYPTO("authencesn");