Merge remote-tracking branches 'asoc/fix/atmel', 'asoc/fix/fsl', 'asoc/fix/tegra...
[linux-drm-fsl-dcu.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/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         struct scatterlist *assoc1;
397         struct scatterlist *assoc2;
398         unsigned int ivsize = crypto_aead_ivsize(authenc_esn);
399         unsigned int cryptlen = req->cryptlen;
400         struct page *dstp;
401         u8 *vdst;
402         u8 *hash;
403
404         dstp = sg_page(dst);
405         vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + dst->offset;
406
407         if (ivsize) {
408                 sg_init_table(cipher, 2);
409                 sg_set_buf(cipher, iv, ivsize);
410                 scatterwalk_crypto_chain(cipher, dst, vdst == iv + ivsize, 2);
411                 dst = cipher;
412                 cryptlen += ivsize;
413         }
414
415         if (sg_is_last(assoc))
416                 return -EINVAL;
417
418         assoc1 = assoc + 1;
419         if (sg_is_last(assoc1))
420                 return -EINVAL;
421
422         assoc2 = assoc + 2;
423         if (!sg_is_last(assoc2))
424                 return -EINVAL;
425
426         sg_init_table(hsg, 2);
427         sg_set_page(hsg, sg_page(assoc), assoc->length, assoc->offset);
428         sg_set_page(hsg + 1, sg_page(assoc2), assoc2->length, assoc2->offset);
429
430         sg_init_table(tsg, 1);
431         sg_set_page(tsg, sg_page(assoc1), assoc1->length, assoc1->offset);
432
433         areq_ctx->cryptlen = cryptlen;
434         areq_ctx->headlen = assoc->length + assoc2->length;
435         areq_ctx->trailen = assoc1->length;
436         areq_ctx->sg = dst;
437
438         areq_ctx->complete = authenc_esn_geniv_ahash_done;
439         areq_ctx->update_complete = authenc_esn_geniv_ahash_update_done;
440         areq_ctx->update_complete2 = authenc_esn_geniv_ahash_update_done2;
441
442         hash = crypto_authenc_esn_ahash(req, flags);
443         if (IS_ERR(hash))
444                 return PTR_ERR(hash);
445
446         scatterwalk_map_and_copy(hash, dst, cryptlen,
447                                  crypto_aead_authsize(authenc_esn), 1);
448         return 0;
449 }
450
451
452 static void crypto_authenc_esn_encrypt_done(struct crypto_async_request *req,
453                                             int err)
454 {
455         struct aead_request *areq = req->data;
456
457         if (!err) {
458                 struct crypto_aead *authenc_esn = crypto_aead_reqtfm(areq);
459                 struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
460                 struct ablkcipher_request *abreq = aead_request_ctx(areq);
461                 u8 *iv = (u8 *)(abreq + 1) +
462                          crypto_ablkcipher_reqsize(ctx->enc);
463
464                 err = crypto_authenc_esn_genicv(areq, iv, 0);
465         }
466
467         authenc_esn_request_complete(areq, err);
468 }
469
470 static int crypto_authenc_esn_encrypt(struct aead_request *req)
471 {
472         struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
473         struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
474         struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
475         struct crypto_ablkcipher *enc = ctx->enc;
476         struct scatterlist *dst = req->dst;
477         unsigned int cryptlen = req->cryptlen;
478         struct ablkcipher_request *abreq = (void *)(areq_ctx->tail
479                                                     + ctx->reqoff);
480         u8 *iv = (u8 *)abreq - crypto_ablkcipher_ivsize(enc);
481         int err;
482
483         ablkcipher_request_set_tfm(abreq, enc);
484         ablkcipher_request_set_callback(abreq, aead_request_flags(req),
485                                         crypto_authenc_esn_encrypt_done, req);
486         ablkcipher_request_set_crypt(abreq, req->src, dst, cryptlen, req->iv);
487
488         memcpy(iv, req->iv, crypto_aead_ivsize(authenc_esn));
489
490         err = crypto_ablkcipher_encrypt(abreq);
491         if (err)
492                 return err;
493
494         return crypto_authenc_esn_genicv(req, iv, CRYPTO_TFM_REQ_MAY_SLEEP);
495 }
496
497 static void crypto_authenc_esn_givencrypt_done(struct crypto_async_request *req,
498                                                int err)
499 {
500         struct aead_request *areq = req->data;
501
502         if (!err) {
503                 struct skcipher_givcrypt_request *greq = aead_request_ctx(areq);
504
505                 err = crypto_authenc_esn_genicv(areq, greq->giv, 0);
506         }
507
508         authenc_esn_request_complete(areq, err);
509 }
510
511 static int crypto_authenc_esn_givencrypt(struct aead_givcrypt_request *req)
512 {
513         struct crypto_aead *authenc_esn = aead_givcrypt_reqtfm(req);
514         struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
515         struct aead_request *areq = &req->areq;
516         struct skcipher_givcrypt_request *greq = aead_request_ctx(areq);
517         u8 *iv = req->giv;
518         int err;
519
520         skcipher_givcrypt_set_tfm(greq, ctx->enc);
521         skcipher_givcrypt_set_callback(greq, aead_request_flags(areq),
522                                        crypto_authenc_esn_givencrypt_done, areq);
523         skcipher_givcrypt_set_crypt(greq, areq->src, areq->dst, areq->cryptlen,
524                                     areq->iv);
525         skcipher_givcrypt_set_giv(greq, iv, req->seq);
526
527         err = crypto_skcipher_givencrypt(greq);
528         if (err)
529                 return err;
530
531         return crypto_authenc_esn_genicv(areq, iv, CRYPTO_TFM_REQ_MAY_SLEEP);
532 }
533
534 static int crypto_authenc_esn_verify(struct aead_request *req)
535 {
536         struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
537         struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
538         u8 *ohash;
539         u8 *ihash;
540         unsigned int authsize;
541
542         areq_ctx->complete = authenc_esn_verify_ahash_done;
543         areq_ctx->update_complete = authenc_esn_verify_ahash_update_done;
544
545         ohash = crypto_authenc_esn_ahash(req, CRYPTO_TFM_REQ_MAY_SLEEP);
546         if (IS_ERR(ohash))
547                 return PTR_ERR(ohash);
548
549         authsize = crypto_aead_authsize(authenc_esn);
550         ihash = ohash + authsize;
551         scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
552                                  authsize, 0);
553         return crypto_memneq(ihash, ohash, authsize) ? -EBADMSG : 0;
554 }
555
556 static int crypto_authenc_esn_iverify(struct aead_request *req, u8 *iv,
557                                       unsigned int cryptlen)
558 {
559         struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
560         struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
561         struct scatterlist *src = req->src;
562         struct scatterlist *assoc = req->assoc;
563         struct scatterlist *cipher = areq_ctx->cipher;
564         struct scatterlist *hsg = areq_ctx->hsg;
565         struct scatterlist *tsg = areq_ctx->tsg;
566         struct scatterlist *assoc1;
567         struct scatterlist *assoc2;
568         unsigned int ivsize = crypto_aead_ivsize(authenc_esn);
569         struct page *srcp;
570         u8 *vsrc;
571
572         srcp = sg_page(src);
573         vsrc = PageHighMem(srcp) ? NULL : page_address(srcp) + src->offset;
574
575         if (ivsize) {
576                 sg_init_table(cipher, 2);
577                 sg_set_buf(cipher, iv, ivsize);
578                 scatterwalk_crypto_chain(cipher, src, vsrc == iv + ivsize, 2);
579                 src = cipher;
580                 cryptlen += ivsize;
581         }
582
583         if (sg_is_last(assoc))
584                 return -EINVAL;
585
586         assoc1 = assoc + 1;
587         if (sg_is_last(assoc1))
588                 return -EINVAL;
589
590         assoc2 = assoc + 2;
591         if (!sg_is_last(assoc2))
592                 return -EINVAL;
593
594         sg_init_table(hsg, 2);
595         sg_set_page(hsg, sg_page(assoc), assoc->length, assoc->offset);
596         sg_set_page(hsg + 1, sg_page(assoc2), assoc2->length, assoc2->offset);
597
598         sg_init_table(tsg, 1);
599         sg_set_page(tsg, sg_page(assoc1), assoc1->length, assoc1->offset);
600
601         areq_ctx->cryptlen = cryptlen;
602         areq_ctx->headlen = assoc->length + assoc2->length;
603         areq_ctx->trailen = assoc1->length;
604         areq_ctx->sg = src;
605
606         areq_ctx->complete = authenc_esn_verify_ahash_done;
607         areq_ctx->update_complete = authenc_esn_verify_ahash_update_done;
608         areq_ctx->update_complete2 = authenc_esn_verify_ahash_update_done2;
609
610         return crypto_authenc_esn_verify(req);
611 }
612
613 static int crypto_authenc_esn_decrypt(struct aead_request *req)
614 {
615         struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
616         struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
617         struct ablkcipher_request *abreq = aead_request_ctx(req);
618         unsigned int cryptlen = req->cryptlen;
619         unsigned int authsize = crypto_aead_authsize(authenc_esn);
620         u8 *iv = req->iv;
621         int err;
622
623         if (cryptlen < authsize)
624                 return -EINVAL;
625         cryptlen -= authsize;
626
627         err = crypto_authenc_esn_iverify(req, iv, cryptlen);
628         if (err)
629                 return err;
630
631         ablkcipher_request_set_tfm(abreq, ctx->enc);
632         ablkcipher_request_set_callback(abreq, aead_request_flags(req),
633                                         req->base.complete, req->base.data);
634         ablkcipher_request_set_crypt(abreq, req->src, req->dst, cryptlen, iv);
635
636         return crypto_ablkcipher_decrypt(abreq);
637 }
638
639 static int crypto_authenc_esn_init_tfm(struct crypto_tfm *tfm)
640 {
641         struct crypto_instance *inst = crypto_tfm_alg_instance(tfm);
642         struct authenc_esn_instance_ctx *ictx = crypto_instance_ctx(inst);
643         struct crypto_authenc_esn_ctx *ctx = crypto_tfm_ctx(tfm);
644         struct crypto_ahash *auth;
645         struct crypto_ablkcipher *enc;
646         int err;
647
648         auth = crypto_spawn_ahash(&ictx->auth);
649         if (IS_ERR(auth))
650                 return PTR_ERR(auth);
651
652         enc = crypto_spawn_skcipher(&ictx->enc);
653         err = PTR_ERR(enc);
654         if (IS_ERR(enc))
655                 goto err_free_ahash;
656
657         ctx->auth = auth;
658         ctx->enc = enc;
659
660         ctx->reqoff = ALIGN(2 * crypto_ahash_digestsize(auth) +
661                             crypto_ahash_alignmask(auth),
662                             crypto_ahash_alignmask(auth) + 1) +
663                       crypto_ablkcipher_ivsize(enc);
664
665         tfm->crt_aead.reqsize = sizeof(struct authenc_esn_request_ctx) +
666                                 ctx->reqoff +
667                                 max_t(unsigned int,
668                                 crypto_ahash_reqsize(auth) +
669                                 sizeof(struct ahash_request),
670                                 sizeof(struct skcipher_givcrypt_request) +
671                                 crypto_ablkcipher_reqsize(enc));
672
673         return 0;
674
675 err_free_ahash:
676         crypto_free_ahash(auth);
677         return err;
678 }
679
680 static void crypto_authenc_esn_exit_tfm(struct crypto_tfm *tfm)
681 {
682         struct crypto_authenc_esn_ctx *ctx = crypto_tfm_ctx(tfm);
683
684         crypto_free_ahash(ctx->auth);
685         crypto_free_ablkcipher(ctx->enc);
686 }
687
688 static struct crypto_instance *crypto_authenc_esn_alloc(struct rtattr **tb)
689 {
690         struct crypto_attr_type *algt;
691         struct crypto_instance *inst;
692         struct hash_alg_common *auth;
693         struct crypto_alg *auth_base;
694         struct crypto_alg *enc;
695         struct authenc_esn_instance_ctx *ctx;
696         const char *enc_name;
697         int err;
698
699         algt = crypto_get_attr_type(tb);
700         if (IS_ERR(algt))
701                 return ERR_CAST(algt);
702
703         if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
704                 return ERR_PTR(-EINVAL);
705
706         auth = ahash_attr_alg(tb[1], CRYPTO_ALG_TYPE_HASH,
707                                CRYPTO_ALG_TYPE_AHASH_MASK);
708         if (IS_ERR(auth))
709                 return ERR_CAST(auth);
710
711         auth_base = &auth->base;
712
713         enc_name = crypto_attr_alg_name(tb[2]);
714         err = PTR_ERR(enc_name);
715         if (IS_ERR(enc_name))
716                 goto out_put_auth;
717
718         inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
719         err = -ENOMEM;
720         if (!inst)
721                 goto out_put_auth;
722
723         ctx = crypto_instance_ctx(inst);
724
725         err = crypto_init_ahash_spawn(&ctx->auth, auth, inst);
726         if (err)
727                 goto err_free_inst;
728
729         crypto_set_skcipher_spawn(&ctx->enc, inst);
730         err = crypto_grab_skcipher(&ctx->enc, enc_name, 0,
731                                    crypto_requires_sync(algt->type,
732                                                         algt->mask));
733         if (err)
734                 goto err_drop_auth;
735
736         enc = crypto_skcipher_spawn_alg(&ctx->enc);
737
738         err = -ENAMETOOLONG;
739         if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME,
740                      "authencesn(%s,%s)", auth_base->cra_name, enc->cra_name) >=
741             CRYPTO_MAX_ALG_NAME)
742                 goto err_drop_enc;
743
744         if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
745                      "authencesn(%s,%s)", auth_base->cra_driver_name,
746                      enc->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
747                 goto err_drop_enc;
748
749         inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD;
750         inst->alg.cra_flags |= enc->cra_flags & CRYPTO_ALG_ASYNC;
751         inst->alg.cra_priority = enc->cra_priority *
752                                  10 + auth_base->cra_priority;
753         inst->alg.cra_blocksize = enc->cra_blocksize;
754         inst->alg.cra_alignmask = auth_base->cra_alignmask | enc->cra_alignmask;
755         inst->alg.cra_type = &crypto_aead_type;
756
757         inst->alg.cra_aead.ivsize = enc->cra_ablkcipher.ivsize;
758         inst->alg.cra_aead.maxauthsize = auth->digestsize;
759
760         inst->alg.cra_ctxsize = sizeof(struct crypto_authenc_esn_ctx);
761
762         inst->alg.cra_init = crypto_authenc_esn_init_tfm;
763         inst->alg.cra_exit = crypto_authenc_esn_exit_tfm;
764
765         inst->alg.cra_aead.setkey = crypto_authenc_esn_setkey;
766         inst->alg.cra_aead.encrypt = crypto_authenc_esn_encrypt;
767         inst->alg.cra_aead.decrypt = crypto_authenc_esn_decrypt;
768         inst->alg.cra_aead.givencrypt = crypto_authenc_esn_givencrypt;
769
770 out:
771         crypto_mod_put(auth_base);
772         return inst;
773
774 err_drop_enc:
775         crypto_drop_skcipher(&ctx->enc);
776 err_drop_auth:
777         crypto_drop_ahash(&ctx->auth);
778 err_free_inst:
779         kfree(inst);
780 out_put_auth:
781         inst = ERR_PTR(err);
782         goto out;
783 }
784
785 static void crypto_authenc_esn_free(struct crypto_instance *inst)
786 {
787         struct authenc_esn_instance_ctx *ctx = crypto_instance_ctx(inst);
788
789         crypto_drop_skcipher(&ctx->enc);
790         crypto_drop_ahash(&ctx->auth);
791         kfree(inst);
792 }
793
794 static struct crypto_template crypto_authenc_esn_tmpl = {
795         .name = "authencesn",
796         .alloc = crypto_authenc_esn_alloc,
797         .free = crypto_authenc_esn_free,
798         .module = THIS_MODULE,
799 };
800
801 static int __init crypto_authenc_esn_module_init(void)
802 {
803         return crypto_register_template(&crypto_authenc_esn_tmpl);
804 }
805
806 static void __exit crypto_authenc_esn_module_exit(void)
807 {
808         crypto_unregister_template(&crypto_authenc_esn_tmpl);
809 }
810
811 module_init(crypto_authenc_esn_module_init);
812 module_exit(crypto_authenc_esn_module_exit);
813
814 MODULE_LICENSE("GPL");
815 MODULE_AUTHOR("Steffen Klassert <steffen.klassert@secunet.com>");
816 MODULE_DESCRIPTION("AEAD wrapper for IPsec with extended sequence numbers");