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