1 /*
2 * algif_aead: User-space interface for AEAD algorithms
3 *
4 * Copyright (C) 2014, Stephan Mueller <smueller@chronox.de>
5 *
6 * This file provides the user-space API for AEAD ciphers.
7 *
8 * This file is derived from algif_skcipher.c.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 */
15
16 #include <crypto/aead.h>
17 #include <crypto/scatterwalk.h>
18 #include <crypto/if_alg.h>
19 #include <linux/init.h>
20 #include <linux/list.h>
21 #include <linux/kernel.h>
22 #include <linux/mm.h>
23 #include <linux/module.h>
24 #include <linux/net.h>
25 #include <net/sock.h>
26
27 struct aead_sg_list {
28 unsigned int cur;
29 struct scatterlist sg[ALG_MAX_PAGES];
30 };
31
32 struct aead_tfm {
33 struct crypto_aead *aead;
34 bool has_key;
35 };
36
37 struct aead_ctx {
38 struct aead_sg_list tsgl;
39 /*
40 * RSGL_MAX_ENTRIES is an artificial limit where user space at maximum
41 * can cause the kernel to allocate RSGL_MAX_ENTRIES * ALG_MAX_PAGES
42 * pages
43 */
44 #define RSGL_MAX_ENTRIES ALG_MAX_PAGES
45 struct af_alg_sgl rsgl[RSGL_MAX_ENTRIES];
46
47 void *iv;
48
49 struct af_alg_completion completion;
50
51 unsigned long used;
52
53 unsigned int len;
54 bool more;
55 bool merge;
56 bool enc;
57
58 size_t aead_assoclen;
59 struct aead_request aead_req;
60 };
61
aead_sndbuf(struct sock * sk)62 static inline int aead_sndbuf(struct sock *sk)
63 {
64 struct alg_sock *ask = alg_sk(sk);
65 struct aead_ctx *ctx = ask->private;
66
67 return max_t(int, max_t(int, sk->sk_sndbuf & PAGE_MASK, PAGE_SIZE) -
68 ctx->used, 0);
69 }
70
aead_writable(struct sock * sk)71 static inline bool aead_writable(struct sock *sk)
72 {
73 return PAGE_SIZE <= aead_sndbuf(sk);
74 }
75
aead_sufficient_data(struct aead_ctx * ctx)76 static inline bool aead_sufficient_data(struct aead_ctx *ctx)
77 {
78 unsigned as = crypto_aead_authsize(crypto_aead_reqtfm(&ctx->aead_req));
79
80 return ctx->used >= ctx->aead_assoclen + as;
81 }
82
aead_put_sgl(struct sock * sk)83 static void aead_put_sgl(struct sock *sk)
84 {
85 struct alg_sock *ask = alg_sk(sk);
86 struct aead_ctx *ctx = ask->private;
87 struct aead_sg_list *sgl = &ctx->tsgl;
88 struct scatterlist *sg = sgl->sg;
89 unsigned int i;
90
91 for (i = 0; i < sgl->cur; i++) {
92 if (!sg_page(sg + i))
93 continue;
94
95 put_page(sg_page(sg + i));
96 sg_assign_page(sg + i, NULL);
97 }
98 sg_init_table(sg, ALG_MAX_PAGES);
99 sgl->cur = 0;
100 ctx->used = 0;
101 ctx->more = 0;
102 ctx->merge = 0;
103 }
104
aead_wmem_wakeup(struct sock * sk)105 static void aead_wmem_wakeup(struct sock *sk)
106 {
107 struct socket_wq *wq;
108
109 if (!aead_writable(sk))
110 return;
111
112 rcu_read_lock();
113 wq = rcu_dereference(sk->sk_wq);
114 if (wq_has_sleeper(wq))
115 wake_up_interruptible_sync_poll(&wq->wait, POLLIN |
116 POLLRDNORM |
117 POLLRDBAND);
118 sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
119 rcu_read_unlock();
120 }
121
aead_wait_for_data(struct sock * sk,unsigned flags)122 static int aead_wait_for_data(struct sock *sk, unsigned flags)
123 {
124 struct alg_sock *ask = alg_sk(sk);
125 struct aead_ctx *ctx = ask->private;
126 long timeout;
127 DEFINE_WAIT(wait);
128 int err = -ERESTARTSYS;
129
130 if (flags & MSG_DONTWAIT)
131 return -EAGAIN;
132
133 sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
134
135 for (;;) {
136 if (signal_pending(current))
137 break;
138 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
139 timeout = MAX_SCHEDULE_TIMEOUT;
140 if (sk_wait_event(sk, &timeout, !ctx->more)) {
141 err = 0;
142 break;
143 }
144 }
145 finish_wait(sk_sleep(sk), &wait);
146
147 sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
148
149 return err;
150 }
151
aead_data_wakeup(struct sock * sk)152 static void aead_data_wakeup(struct sock *sk)
153 {
154 struct alg_sock *ask = alg_sk(sk);
155 struct aead_ctx *ctx = ask->private;
156 struct socket_wq *wq;
157
158 if (ctx->more)
159 return;
160 if (!ctx->used)
161 return;
162
163 rcu_read_lock();
164 wq = rcu_dereference(sk->sk_wq);
165 if (wq_has_sleeper(wq))
166 wake_up_interruptible_sync_poll(&wq->wait, POLLOUT |
167 POLLRDNORM |
168 POLLRDBAND);
169 sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
170 rcu_read_unlock();
171 }
172
aead_sendmsg(struct socket * sock,struct msghdr * msg,size_t size)173 static int aead_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
174 {
175 struct sock *sk = sock->sk;
176 struct alg_sock *ask = alg_sk(sk);
177 struct aead_ctx *ctx = ask->private;
178 unsigned ivsize =
179 crypto_aead_ivsize(crypto_aead_reqtfm(&ctx->aead_req));
180 struct aead_sg_list *sgl = &ctx->tsgl;
181 struct af_alg_control con = {};
182 long copied = 0;
183 bool enc = 0;
184 bool init = 0;
185 int err = -EINVAL;
186
187 if (msg->msg_controllen) {
188 err = af_alg_cmsg_send(msg, &con);
189 if (err)
190 return err;
191
192 init = 1;
193 switch (con.op) {
194 case ALG_OP_ENCRYPT:
195 enc = 1;
196 break;
197 case ALG_OP_DECRYPT:
198 enc = 0;
199 break;
200 default:
201 return -EINVAL;
202 }
203
204 if (con.iv && con.iv->ivlen != ivsize)
205 return -EINVAL;
206 }
207
208 lock_sock(sk);
209 if (!ctx->more && ctx->used)
210 goto unlock;
211
212 if (init) {
213 ctx->enc = enc;
214 if (con.iv)
215 memcpy(ctx->iv, con.iv->iv, ivsize);
216
217 ctx->aead_assoclen = con.aead_assoclen;
218 }
219
220 while (size) {
221 unsigned long len = size;
222 struct scatterlist *sg = NULL;
223
224 /* use the existing memory in an allocated page */
225 if (ctx->merge) {
226 sg = sgl->sg + sgl->cur - 1;
227 len = min_t(unsigned long, len,
228 PAGE_SIZE - sg->offset - sg->length);
229 err = memcpy_from_msg(page_address(sg_page(sg)) +
230 sg->offset + sg->length,
231 msg, len);
232 if (err)
233 goto unlock;
234
235 sg->length += len;
236 ctx->merge = (sg->offset + sg->length) &
237 (PAGE_SIZE - 1);
238
239 ctx->used += len;
240 copied += len;
241 size -= len;
242 continue;
243 }
244
245 if (!aead_writable(sk)) {
246 /* user space sent too much data */
247 aead_put_sgl(sk);
248 err = -EMSGSIZE;
249 goto unlock;
250 }
251
252 /* allocate a new page */
253 len = min_t(unsigned long, size, aead_sndbuf(sk));
254 while (len) {
255 int plen = 0;
256
257 if (sgl->cur >= ALG_MAX_PAGES) {
258 aead_put_sgl(sk);
259 err = -E2BIG;
260 goto unlock;
261 }
262
263 sg = sgl->sg + sgl->cur;
264 plen = min_t(int, len, PAGE_SIZE);
265
266 sg_assign_page(sg, alloc_page(GFP_KERNEL));
267 err = -ENOMEM;
268 if (!sg_page(sg))
269 goto unlock;
270
271 err = memcpy_from_msg(page_address(sg_page(sg)),
272 msg, plen);
273 if (err) {
274 __free_page(sg_page(sg));
275 sg_assign_page(sg, NULL);
276 goto unlock;
277 }
278
279 sg->offset = 0;
280 sg->length = plen;
281 len -= plen;
282 ctx->used += plen;
283 copied += plen;
284 sgl->cur++;
285 size -= plen;
286 ctx->merge = plen & (PAGE_SIZE - 1);
287 }
288 }
289
290 err = 0;
291
292 ctx->more = msg->msg_flags & MSG_MORE;
293 if (!ctx->more && !aead_sufficient_data(ctx)) {
294 aead_put_sgl(sk);
295 err = -EMSGSIZE;
296 }
297
298 unlock:
299 aead_data_wakeup(sk);
300 release_sock(sk);
301
302 return err ?: copied;
303 }
304
aead_sendpage(struct socket * sock,struct page * page,int offset,size_t size,int flags)305 static ssize_t aead_sendpage(struct socket *sock, struct page *page,
306 int offset, size_t size, int flags)
307 {
308 struct sock *sk = sock->sk;
309 struct alg_sock *ask = alg_sk(sk);
310 struct aead_ctx *ctx = ask->private;
311 struct aead_sg_list *sgl = &ctx->tsgl;
312 int err = -EINVAL;
313
314 if (flags & MSG_SENDPAGE_NOTLAST)
315 flags |= MSG_MORE;
316
317 if (sgl->cur >= ALG_MAX_PAGES)
318 return -E2BIG;
319
320 lock_sock(sk);
321 if (!ctx->more && ctx->used)
322 goto unlock;
323
324 if (!size)
325 goto done;
326
327 if (!aead_writable(sk)) {
328 /* user space sent too much data */
329 aead_put_sgl(sk);
330 err = -EMSGSIZE;
331 goto unlock;
332 }
333
334 ctx->merge = 0;
335
336 get_page(page);
337 sg_set_page(sgl->sg + sgl->cur, page, size, offset);
338 sgl->cur++;
339 ctx->used += size;
340
341 err = 0;
342
343 done:
344 ctx->more = flags & MSG_MORE;
345 if (!ctx->more && !aead_sufficient_data(ctx)) {
346 aead_put_sgl(sk);
347 err = -EMSGSIZE;
348 }
349
350 unlock:
351 aead_data_wakeup(sk);
352 release_sock(sk);
353
354 return err ?: size;
355 }
356
aead_recvmsg(struct socket * sock,struct msghdr * msg,size_t ignored,int flags)357 static int aead_recvmsg(struct socket *sock, struct msghdr *msg, size_t ignored, int flags)
358 {
359 struct sock *sk = sock->sk;
360 struct alg_sock *ask = alg_sk(sk);
361 struct aead_ctx *ctx = ask->private;
362 unsigned as = crypto_aead_authsize(crypto_aead_reqtfm(&ctx->aead_req));
363 struct aead_sg_list *sgl = &ctx->tsgl;
364 unsigned int i = 0;
365 int err = -EINVAL;
366 unsigned long used = 0;
367 size_t outlen = 0;
368 size_t usedpages = 0;
369 unsigned int cnt = 0;
370
371 /* Limit number of IOV blocks to be accessed below */
372 if (msg->msg_iter.nr_segs > RSGL_MAX_ENTRIES)
373 return -ENOMSG;
374
375 lock_sock(sk);
376
377 /*
378 * AEAD memory structure: For encryption, the tag is appended to the
379 * ciphertext which implies that the memory allocated for the ciphertext
380 * must be increased by the tag length. For decryption, the tag
381 * is expected to be concatenated to the ciphertext. The plaintext
382 * therefore has a memory size of the ciphertext minus the tag length.
383 *
384 * The memory structure for cipher operation has the following
385 * structure:
386 * AEAD encryption input: assoc data || plaintext
387 * AEAD encryption output: cipherntext || auth tag
388 * AEAD decryption input: assoc data || ciphertext || auth tag
389 * AEAD decryption output: plaintext
390 */
391
392 if (ctx->more) {
393 err = aead_wait_for_data(sk, flags);
394 if (err)
395 goto unlock;
396 }
397
398 used = ctx->used;
399
400 /*
401 * Make sure sufficient data is present -- note, the same check is
402 * is also present in sendmsg/sendpage. The checks in sendpage/sendmsg
403 * shall provide an information to the data sender that something is
404 * wrong, but they are irrelevant to maintain the kernel integrity.
405 * We need this check here too in case user space decides to not honor
406 * the error message in sendmsg/sendpage and still call recvmsg. This
407 * check here protects the kernel integrity.
408 */
409 if (!aead_sufficient_data(ctx))
410 goto unlock;
411
412 outlen = used;
413
414 /*
415 * The cipher operation input data is reduced by the associated data
416 * length as this data is processed separately later on.
417 */
418 used -= ctx->aead_assoclen + (ctx->enc ? as : 0);
419
420 /* convert iovecs of output buffers into scatterlists */
421 while (iov_iter_count(&msg->msg_iter)) {
422 size_t seglen = min_t(size_t, iov_iter_count(&msg->msg_iter),
423 (outlen - usedpages));
424
425 /* make one iovec available as scatterlist */
426 err = af_alg_make_sg(&ctx->rsgl[cnt], &msg->msg_iter,
427 seglen);
428 if (err < 0)
429 goto unlock;
430 usedpages += err;
431 /* chain the new scatterlist with previous one */
432 if (cnt)
433 af_alg_link_sg(&ctx->rsgl[cnt-1], &ctx->rsgl[cnt]);
434
435 /* we do not need more iovecs as we have sufficient memory */
436 if (outlen <= usedpages)
437 break;
438 iov_iter_advance(&msg->msg_iter, err);
439 cnt++;
440 }
441
442 err = -EINVAL;
443 /* ensure output buffer is sufficiently large */
444 if (usedpages < outlen)
445 goto unlock;
446
447 sg_mark_end(sgl->sg + sgl->cur - 1);
448
449 aead_request_set_crypt(&ctx->aead_req, sgl->sg, ctx->rsgl[0].sg,
450 used, ctx->iv);
451 aead_request_set_ad(&ctx->aead_req, ctx->aead_assoclen);
452
453 err = af_alg_wait_for_completion(ctx->enc ?
454 crypto_aead_encrypt(&ctx->aead_req) :
455 crypto_aead_decrypt(&ctx->aead_req),
456 &ctx->completion);
457
458 if (err) {
459 /* EBADMSG implies a valid cipher operation took place */
460 if (err == -EBADMSG)
461 aead_put_sgl(sk);
462 goto unlock;
463 }
464
465 aead_put_sgl(sk);
466
467 err = 0;
468
469 unlock:
470 for (i = 0; i < cnt; i++)
471 af_alg_free_sg(&ctx->rsgl[i]);
472
473 aead_wmem_wakeup(sk);
474 release_sock(sk);
475
476 return err ? err : outlen;
477 }
478
aead_poll(struct file * file,struct socket * sock,poll_table * wait)479 static unsigned int aead_poll(struct file *file, struct socket *sock,
480 poll_table *wait)
481 {
482 struct sock *sk = sock->sk;
483 struct alg_sock *ask = alg_sk(sk);
484 struct aead_ctx *ctx = ask->private;
485 unsigned int mask;
486
487 sock_poll_wait(file, sk_sleep(sk), wait);
488 mask = 0;
489
490 if (!ctx->more)
491 mask |= POLLIN | POLLRDNORM;
492
493 if (aead_writable(sk))
494 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
495
496 return mask;
497 }
498
499 static struct proto_ops algif_aead_ops = {
500 .family = PF_ALG,
501
502 .connect = sock_no_connect,
503 .socketpair = sock_no_socketpair,
504 .getname = sock_no_getname,
505 .ioctl = sock_no_ioctl,
506 .listen = sock_no_listen,
507 .shutdown = sock_no_shutdown,
508 .getsockopt = sock_no_getsockopt,
509 .mmap = sock_no_mmap,
510 .bind = sock_no_bind,
511 .accept = sock_no_accept,
512 .setsockopt = sock_no_setsockopt,
513
514 .release = af_alg_release,
515 .sendmsg = aead_sendmsg,
516 .sendpage = aead_sendpage,
517 .recvmsg = aead_recvmsg,
518 .poll = aead_poll,
519 };
520
aead_check_key(struct socket * sock)521 static int aead_check_key(struct socket *sock)
522 {
523 int err = 0;
524 struct sock *psk;
525 struct alg_sock *pask;
526 struct aead_tfm *tfm;
527 struct sock *sk = sock->sk;
528 struct alg_sock *ask = alg_sk(sk);
529
530 lock_sock(sk);
531 if (!atomic_read(&ask->nokey_refcnt))
532 goto unlock_child;
533
534 psk = ask->parent;
535 pask = alg_sk(ask->parent);
536 tfm = pask->private;
537
538 err = -ENOKEY;
539 lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
540 if (!tfm->has_key)
541 goto unlock;
542
543 atomic_dec(&pask->nokey_refcnt);
544 atomic_set(&ask->nokey_refcnt, 0);
545
546 err = 0;
547
548 unlock:
549 release_sock(psk);
550 unlock_child:
551 release_sock(sk);
552
553 return err;
554 }
555
aead_sendmsg_nokey(struct socket * sock,struct msghdr * msg,size_t size)556 static int aead_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
557 size_t size)
558 {
559 int err;
560
561 err = aead_check_key(sock);
562 if (err)
563 return err;
564
565 return aead_sendmsg(sock, msg, size);
566 }
567
aead_sendpage_nokey(struct socket * sock,struct page * page,int offset,size_t size,int flags)568 static ssize_t aead_sendpage_nokey(struct socket *sock, struct page *page,
569 int offset, size_t size, int flags)
570 {
571 int err;
572
573 err = aead_check_key(sock);
574 if (err)
575 return err;
576
577 return aead_sendpage(sock, page, offset, size, flags);
578 }
579
aead_recvmsg_nokey(struct socket * sock,struct msghdr * msg,size_t ignored,int flags)580 static int aead_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
581 size_t ignored, int flags)
582 {
583 int err;
584
585 err = aead_check_key(sock);
586 if (err)
587 return err;
588
589 return aead_recvmsg(sock, msg, ignored, flags);
590 }
591
592 static struct proto_ops algif_aead_ops_nokey = {
593 .family = PF_ALG,
594
595 .connect = sock_no_connect,
596 .socketpair = sock_no_socketpair,
597 .getname = sock_no_getname,
598 .ioctl = sock_no_ioctl,
599 .listen = sock_no_listen,
600 .shutdown = sock_no_shutdown,
601 .getsockopt = sock_no_getsockopt,
602 .mmap = sock_no_mmap,
603 .bind = sock_no_bind,
604 .accept = sock_no_accept,
605 .setsockopt = sock_no_setsockopt,
606
607 .release = af_alg_release,
608 .sendmsg = aead_sendmsg_nokey,
609 .sendpage = aead_sendpage_nokey,
610 .recvmsg = aead_recvmsg_nokey,
611 .poll = aead_poll,
612 };
613
aead_bind(const char * name,u32 type,u32 mask)614 static void *aead_bind(const char *name, u32 type, u32 mask)
615 {
616 struct aead_tfm *tfm;
617 struct crypto_aead *aead;
618
619 tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
620 if (!tfm)
621 return ERR_PTR(-ENOMEM);
622
623 aead = crypto_alloc_aead(name, type, mask);
624 if (IS_ERR(aead)) {
625 kfree(tfm);
626 return ERR_CAST(aead);
627 }
628
629 tfm->aead = aead;
630
631 return tfm;
632 }
633
aead_release(void * private)634 static void aead_release(void *private)
635 {
636 struct aead_tfm *tfm = private;
637
638 crypto_free_aead(tfm->aead);
639 kfree(tfm);
640 }
641
aead_setauthsize(void * private,unsigned int authsize)642 static int aead_setauthsize(void *private, unsigned int authsize)
643 {
644 struct aead_tfm *tfm = private;
645
646 return crypto_aead_setauthsize(tfm->aead, authsize);
647 }
648
aead_setkey(void * private,const u8 * key,unsigned int keylen)649 static int aead_setkey(void *private, const u8 *key, unsigned int keylen)
650 {
651 struct aead_tfm *tfm = private;
652 int err;
653
654 err = crypto_aead_setkey(tfm->aead, key, keylen);
655 tfm->has_key = !err;
656
657 return err;
658 }
659
aead_sock_destruct(struct sock * sk)660 static void aead_sock_destruct(struct sock *sk)
661 {
662 struct alg_sock *ask = alg_sk(sk);
663 struct aead_ctx *ctx = ask->private;
664 unsigned int ivlen = crypto_aead_ivsize(
665 crypto_aead_reqtfm(&ctx->aead_req));
666
667 aead_put_sgl(sk);
668 sock_kzfree_s(sk, ctx->iv, ivlen);
669 sock_kfree_s(sk, ctx, ctx->len);
670 af_alg_release_parent(sk);
671 }
672
aead_accept_parent_nokey(void * private,struct sock * sk)673 static int aead_accept_parent_nokey(void *private, struct sock *sk)
674 {
675 struct aead_ctx *ctx;
676 struct alg_sock *ask = alg_sk(sk);
677 struct aead_tfm *tfm = private;
678 struct crypto_aead *aead = tfm->aead;
679 unsigned int len = sizeof(*ctx) + crypto_aead_reqsize(aead);
680 unsigned int ivlen = crypto_aead_ivsize(aead);
681
682 ctx = sock_kmalloc(sk, len, GFP_KERNEL);
683 if (!ctx)
684 return -ENOMEM;
685 memset(ctx, 0, len);
686
687 ctx->iv = sock_kmalloc(sk, ivlen, GFP_KERNEL);
688 if (!ctx->iv) {
689 sock_kfree_s(sk, ctx, len);
690 return -ENOMEM;
691 }
692 memset(ctx->iv, 0, ivlen);
693
694 ctx->len = len;
695 ctx->used = 0;
696 ctx->more = 0;
697 ctx->merge = 0;
698 ctx->enc = 0;
699 ctx->tsgl.cur = 0;
700 ctx->aead_assoclen = 0;
701 af_alg_init_completion(&ctx->completion);
702 sg_init_table(ctx->tsgl.sg, ALG_MAX_PAGES);
703
704 ask->private = ctx;
705
706 aead_request_set_tfm(&ctx->aead_req, aead);
707 aead_request_set_callback(&ctx->aead_req, CRYPTO_TFM_REQ_MAY_BACKLOG,
708 af_alg_complete, &ctx->completion);
709
710 sk->sk_destruct = aead_sock_destruct;
711
712 return 0;
713 }
714
aead_accept_parent(void * private,struct sock * sk)715 static int aead_accept_parent(void *private, struct sock *sk)
716 {
717 struct aead_tfm *tfm = private;
718
719 if (!tfm->has_key)
720 return -ENOKEY;
721
722 return aead_accept_parent_nokey(private, sk);
723 }
724
725 static const struct af_alg_type algif_type_aead = {
726 .bind = aead_bind,
727 .release = aead_release,
728 .setkey = aead_setkey,
729 .setauthsize = aead_setauthsize,
730 .accept = aead_accept_parent,
731 .accept_nokey = aead_accept_parent_nokey,
732 .ops = &algif_aead_ops,
733 .ops_nokey = &algif_aead_ops_nokey,
734 .name = "aead",
735 .owner = THIS_MODULE
736 };
737
algif_aead_init(void)738 static int __init algif_aead_init(void)
739 {
740 return af_alg_register_type(&algif_type_aead);
741 }
742
algif_aead_exit(void)743 static void __exit algif_aead_exit(void)
744 {
745 int err = af_alg_unregister_type(&algif_type_aead);
746 BUG_ON(err);
747 }
748
749 module_init(algif_aead_init);
750 module_exit(algif_aead_exit);
751 MODULE_LICENSE("GPL");
752 MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
753 MODULE_DESCRIPTION("AEAD kernel crypto API user space interface");
754