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