Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / crypto / algif_skcipher.c
1 /*
2  * algif_skcipher: User-space interface for skcipher algorithms
3  *
4  * This file provides the user-space API for symmetric key ciphers.
5  *
6  * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au>
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/scatterwalk.h>
16 #include <crypto/skcipher.h>
17 #include <crypto/if_alg.h>
18 #include <linux/init.h>
19 #include <linux/list.h>
20 #include <linux/kernel.h>
21 #include <linux/mm.h>
22 #include <linux/module.h>
23 #include <linux/net.h>
24 #include <net/sock.h>
25
26 struct skcipher_sg_list {
27         struct list_head list;
28
29         int cur;
30
31         struct scatterlist sg[0];
32 };
33
34 struct skcipher_tfm {
35         struct crypto_ablkcipher *skcipher;
36         bool has_key;
37 };
38
39 struct skcipher_ctx {
40         struct list_head tsgl;
41         struct af_alg_sgl rsgl;
42
43         void *iv;
44
45         struct af_alg_completion completion;
46
47         unsigned used;
48
49         unsigned int len;
50         bool more;
51         bool merge;
52         bool enc;
53
54         struct ablkcipher_request req;
55 };
56
57 #define MAX_SGL_ENTS ((4096 - sizeof(struct skcipher_sg_list)) / \
58                       sizeof(struct scatterlist) - 1)
59
60 static inline int skcipher_sndbuf(struct sock *sk)
61 {
62         struct alg_sock *ask = alg_sk(sk);
63         struct skcipher_ctx *ctx = ask->private;
64
65         return max_t(int, max_t(int, sk->sk_sndbuf & PAGE_MASK, PAGE_SIZE) -
66                           ctx->used, 0);
67 }
68
69 static inline bool skcipher_writable(struct sock *sk)
70 {
71         return PAGE_SIZE <= skcipher_sndbuf(sk);
72 }
73
74 static int skcipher_alloc_sgl(struct sock *sk)
75 {
76         struct alg_sock *ask = alg_sk(sk);
77         struct skcipher_ctx *ctx = ask->private;
78         struct skcipher_sg_list *sgl;
79         struct scatterlist *sg = NULL;
80
81         sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
82         if (!list_empty(&ctx->tsgl))
83                 sg = sgl->sg;
84
85         if (!sg || sgl->cur >= MAX_SGL_ENTS) {
86                 sgl = sock_kmalloc(sk, sizeof(*sgl) +
87                                        sizeof(sgl->sg[0]) * (MAX_SGL_ENTS + 1),
88                                    GFP_KERNEL);
89                 if (!sgl)
90                         return -ENOMEM;
91
92                 sg_init_table(sgl->sg, MAX_SGL_ENTS + 1);
93                 sgl->cur = 0;
94
95                 if (sg)
96                         scatterwalk_sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg);
97
98                 list_add_tail(&sgl->list, &ctx->tsgl);
99         }
100
101         return 0;
102 }
103
104 static void skcipher_pull_sgl(struct sock *sk, int used)
105 {
106         struct alg_sock *ask = alg_sk(sk);
107         struct skcipher_ctx *ctx = ask->private;
108         struct skcipher_sg_list *sgl;
109         struct scatterlist *sg;
110         int i;
111
112         while (!list_empty(&ctx->tsgl)) {
113                 sgl = list_first_entry(&ctx->tsgl, struct skcipher_sg_list,
114                                        list);
115                 sg = sgl->sg;
116
117                 for (i = 0; i < sgl->cur; i++) {
118                         int plen = min_t(int, used, sg[i].length);
119
120                         if (!sg_page(sg + i))
121                                 continue;
122
123                         sg[i].length -= plen;
124                         sg[i].offset += plen;
125
126                         used -= plen;
127                         ctx->used -= plen;
128
129                         if (sg[i].length)
130                                 return;
131
132                         put_page(sg_page(sg + i));
133                         sg_assign_page(sg + i, NULL);
134                 }
135
136                 list_del(&sgl->list);
137                 sock_kfree_s(sk, sgl,
138                              sizeof(*sgl) + sizeof(sgl->sg[0]) *
139                                             (MAX_SGL_ENTS + 1));
140         }
141
142         if (!ctx->used)
143                 ctx->merge = 0;
144 }
145
146 static void skcipher_free_sgl(struct sock *sk)
147 {
148         struct alg_sock *ask = alg_sk(sk);
149         struct skcipher_ctx *ctx = ask->private;
150
151         skcipher_pull_sgl(sk, ctx->used);
152 }
153
154 static int skcipher_wait_for_wmem(struct sock *sk, unsigned flags)
155 {
156         long timeout;
157         DEFINE_WAIT(wait);
158         int err = -ERESTARTSYS;
159
160         if (flags & MSG_DONTWAIT)
161                 return -EAGAIN;
162
163         set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
164
165         for (;;) {
166                 if (signal_pending(current))
167                         break;
168                 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
169                 timeout = MAX_SCHEDULE_TIMEOUT;
170                 if (sk_wait_event(sk, &timeout, skcipher_writable(sk))) {
171                         err = 0;
172                         break;
173                 }
174         }
175         finish_wait(sk_sleep(sk), &wait);
176
177         return err;
178 }
179
180 static void skcipher_wmem_wakeup(struct sock *sk)
181 {
182         struct socket_wq *wq;
183
184         if (!skcipher_writable(sk))
185                 return;
186
187         rcu_read_lock();
188         wq = rcu_dereference(sk->sk_wq);
189         if (wq_has_sleeper(wq))
190                 wake_up_interruptible_sync_poll(&wq->wait, POLLIN |
191                                                            POLLRDNORM |
192                                                            POLLRDBAND);
193         sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
194         rcu_read_unlock();
195 }
196
197 static int skcipher_wait_for_data(struct sock *sk, unsigned flags)
198 {
199         struct alg_sock *ask = alg_sk(sk);
200         struct skcipher_ctx *ctx = ask->private;
201         long timeout;
202         DEFINE_WAIT(wait);
203         int err = -ERESTARTSYS;
204
205         if (flags & MSG_DONTWAIT) {
206                 return -EAGAIN;
207         }
208
209         set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
210
211         for (;;) {
212                 if (signal_pending(current))
213                         break;
214                 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
215                 timeout = MAX_SCHEDULE_TIMEOUT;
216                 if (sk_wait_event(sk, &timeout, ctx->used)) {
217                         err = 0;
218                         break;
219                 }
220         }
221         finish_wait(sk_sleep(sk), &wait);
222
223         clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
224
225         return err;
226 }
227
228 static void skcipher_data_wakeup(struct sock *sk)
229 {
230         struct alg_sock *ask = alg_sk(sk);
231         struct skcipher_ctx *ctx = ask->private;
232         struct socket_wq *wq;
233
234         if (!ctx->used)
235                 return;
236
237         rcu_read_lock();
238         wq = rcu_dereference(sk->sk_wq);
239         if (wq_has_sleeper(wq))
240                 wake_up_interruptible_sync_poll(&wq->wait, POLLOUT |
241                                                            POLLRDNORM |
242                                                            POLLRDBAND);
243         sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
244         rcu_read_unlock();
245 }
246
247 static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock,
248                             struct msghdr *msg, size_t size)
249 {
250         struct sock *sk = sock->sk;
251         struct alg_sock *ask = alg_sk(sk);
252         struct sock *psk = ask->parent;
253         struct alg_sock *pask = alg_sk(psk);
254         struct skcipher_ctx *ctx = ask->private;
255         struct ablkcipher_tfm *skc = pask->private;
256         struct crypto_ablkcipher *tfm = skc->base;
257         unsigned ivsize = crypto_ablkcipher_ivsize(tfm);
258         struct skcipher_sg_list *sgl;
259         struct af_alg_control con = {};
260         long copied = 0;
261         bool enc = 0;
262         int err;
263         int i;
264
265         if (msg->msg_controllen) {
266                 err = af_alg_cmsg_send(msg, &con);
267                 if (err)
268                         return err;
269
270                 switch (con.op) {
271                 case ALG_OP_ENCRYPT:
272                         enc = 1;
273                         break;
274                 case ALG_OP_DECRYPT:
275                         enc = 0;
276                         break;
277                 default:
278                         return -EINVAL;
279                 }
280
281                 if (con.iv && con.iv->ivlen != ivsize)
282                         return -EINVAL;
283         }
284
285         err = -EINVAL;
286
287         lock_sock(sk);
288         if (!ctx->more && ctx->used)
289                 goto unlock;
290
291         if (!ctx->used) {
292                 ctx->enc = enc;
293                 if (con.iv)
294                         memcpy(ctx->iv, con.iv->iv, ivsize);
295         }
296
297         while (size) {
298                 struct scatterlist *sg;
299                 unsigned long len = size;
300                 int plen;
301
302                 if (ctx->merge) {
303                         sgl = list_entry(ctx->tsgl.prev,
304                                          struct skcipher_sg_list, list);
305                         sg = sgl->sg + sgl->cur - 1;
306                         len = min_t(unsigned long, len,
307                                     PAGE_SIZE - sg->offset - sg->length);
308
309                         err = memcpy_fromiovec(page_address(sg_page(sg)) +
310                                                sg->offset + sg->length,
311                                                msg->msg_iov, len);
312                         if (err)
313                                 goto unlock;
314
315                         sg->length += len;
316                         ctx->merge = (sg->offset + sg->length) &
317                                      (PAGE_SIZE - 1);
318
319                         ctx->used += len;
320                         copied += len;
321                         size -= len;
322                         continue;
323                 }
324
325                 if (!skcipher_writable(sk)) {
326                         err = skcipher_wait_for_wmem(sk, msg->msg_flags);
327                         if (err)
328                                 goto unlock;
329                 }
330
331                 len = min_t(unsigned long, len, skcipher_sndbuf(sk));
332
333                 err = skcipher_alloc_sgl(sk);
334                 if (err)
335                         goto unlock;
336
337                 sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
338                 sg = sgl->sg;
339                 do {
340                         i = sgl->cur;
341                         plen = min_t(int, len, PAGE_SIZE);
342
343                         sg_assign_page(sg + i, alloc_page(GFP_KERNEL));
344                         err = -ENOMEM;
345                         if (!sg_page(sg + i))
346                                 goto unlock;
347
348                         err = memcpy_fromiovec(page_address(sg_page(sg + i)),
349                                                msg->msg_iov, plen);
350                         if (err) {
351                                 __free_page(sg_page(sg + i));
352                                 sg_assign_page(sg + i, NULL);
353                                 goto unlock;
354                         }
355
356                         sg[i].length = plen;
357                         len -= plen;
358                         ctx->used += plen;
359                         copied += plen;
360                         size -= plen;
361                         sgl->cur++;
362                 } while (len && sgl->cur < MAX_SGL_ENTS);
363
364                 ctx->merge = plen & (PAGE_SIZE - 1);
365         }
366
367         err = 0;
368
369         ctx->more = msg->msg_flags & MSG_MORE;
370         if (!ctx->more && !list_empty(&ctx->tsgl))
371                 sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
372
373 unlock:
374         skcipher_data_wakeup(sk);
375         release_sock(sk);
376
377         return copied ?: err;
378 }
379
380 static ssize_t skcipher_sendpage(struct socket *sock, struct page *page,
381                                  int offset, size_t size, int flags)
382 {
383         struct sock *sk = sock->sk;
384         struct alg_sock *ask = alg_sk(sk);
385         struct skcipher_ctx *ctx = ask->private;
386         struct skcipher_sg_list *sgl;
387         int err = -EINVAL;
388
389         if (flags & MSG_SENDPAGE_NOTLAST)
390                 flags |= MSG_MORE;
391
392         lock_sock(sk);
393         if (!ctx->more && ctx->used)
394                 goto unlock;
395
396         if (!size)
397                 goto done;
398
399         if (!skcipher_writable(sk)) {
400                 err = skcipher_wait_for_wmem(sk, flags);
401                 if (err)
402                         goto unlock;
403         }
404
405         err = skcipher_alloc_sgl(sk);
406         if (err)
407                 goto unlock;
408
409         ctx->merge = 0;
410         sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
411
412         get_page(page);
413         sg_set_page(sgl->sg + sgl->cur, page, size, offset);
414         sgl->cur++;
415         ctx->used += size;
416
417 done:
418         ctx->more = flags & MSG_MORE;
419         if (!ctx->more && !list_empty(&ctx->tsgl))
420                 sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
421
422 unlock:
423         skcipher_data_wakeup(sk);
424         release_sock(sk);
425
426         return err ?: size;
427 }
428
429 static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock,
430                             struct msghdr *msg, size_t ignored, int flags)
431 {
432         struct sock *sk = sock->sk;
433         struct alg_sock *ask = alg_sk(sk);
434         struct skcipher_ctx *ctx = ask->private;
435         unsigned bs = crypto_ablkcipher_blocksize(crypto_ablkcipher_reqtfm(
436                 &ctx->req));
437         struct skcipher_sg_list *sgl;
438         struct scatterlist *sg;
439         unsigned long iovlen;
440         struct iovec *iov;
441         int err = -EAGAIN;
442         int used;
443         long copied = 0;
444
445         lock_sock(sk);
446         for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0;
447              iovlen--, iov++) {
448                 unsigned long seglen = iov->iov_len;
449                 char __user *from = iov->iov_base;
450
451                 while (seglen) {
452                         used = ctx->used;
453                         if (!used) {
454                                 err = skcipher_wait_for_data(sk, flags);
455                                 if (err)
456                                         goto unlock;
457                         }
458
459                         used = min_t(unsigned long, used, seglen);
460
461                         used = af_alg_make_sg(&ctx->rsgl, from, used, 1);
462                         err = used;
463                         if (err < 0)
464                                 goto unlock;
465
466                         if (ctx->more || used < ctx->used)
467                                 used -= used % bs;
468
469                         err = -EINVAL;
470                         if (!used)
471                                 goto free;
472
473                         sgl = list_first_entry(&ctx->tsgl,
474                                                struct skcipher_sg_list, list);
475                         sg = sgl->sg;
476
477                         while (!sg->length)
478                                 sg++;
479
480                         ablkcipher_request_set_crypt(&ctx->req, sg,
481                                                      ctx->rsgl.sg, used,
482                                                      ctx->iv);
483
484                         err = af_alg_wait_for_completion(
485                                 ctx->enc ?
486                                         crypto_ablkcipher_encrypt(&ctx->req) :
487                                         crypto_ablkcipher_decrypt(&ctx->req),
488                                 &ctx->completion);
489
490 free:
491                         af_alg_free_sg(&ctx->rsgl);
492
493                         if (err)
494                                 goto unlock;
495
496                         copied += used;
497                         from += used;
498                         seglen -= used;
499                         skcipher_pull_sgl(sk, used);
500                 }
501         }
502
503         err = 0;
504
505 unlock:
506         skcipher_wmem_wakeup(sk);
507         release_sock(sk);
508
509         return copied ?: err;
510 }
511
512
513 static unsigned int skcipher_poll(struct file *file, struct socket *sock,
514                                   poll_table *wait)
515 {
516         struct sock *sk = sock->sk;
517         struct alg_sock *ask = alg_sk(sk);
518         struct skcipher_ctx *ctx = ask->private;
519         unsigned int mask;
520
521         sock_poll_wait(file, sk_sleep(sk), wait);
522         mask = 0;
523
524         if (ctx->used)
525                 mask |= POLLIN | POLLRDNORM;
526
527         if (skcipher_writable(sk))
528                 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
529
530         return mask;
531 }
532
533 static struct proto_ops algif_skcipher_ops = {
534         .family         =       PF_ALG,
535
536         .connect        =       sock_no_connect,
537         .socketpair     =       sock_no_socketpair,
538         .getname        =       sock_no_getname,
539         .ioctl          =       sock_no_ioctl,
540         .listen         =       sock_no_listen,
541         .shutdown       =       sock_no_shutdown,
542         .getsockopt     =       sock_no_getsockopt,
543         .mmap           =       sock_no_mmap,
544         .bind           =       sock_no_bind,
545         .accept         =       sock_no_accept,
546         .setsockopt     =       sock_no_setsockopt,
547
548         .release        =       af_alg_release,
549         .sendmsg        =       skcipher_sendmsg,
550         .sendpage       =       skcipher_sendpage,
551         .recvmsg        =       skcipher_recvmsg,
552         .poll           =       skcipher_poll,
553 };
554
555 static int skcipher_check_key(struct socket *sock)
556 {
557         int err = 0;
558         struct sock *psk;
559         struct alg_sock *pask;
560         struct skcipher_tfm *tfm;
561         struct sock *sk = sock->sk;
562         struct alg_sock *ask = alg_sk(sk);
563
564         lock_sock(sk);
565         if (ask->refcnt)
566                 goto unlock_child;
567
568         psk = ask->parent;
569         pask = alg_sk(ask->parent);
570         tfm = pask->private;
571
572         err = -ENOKEY;
573         lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
574         if (!tfm->has_key)
575                 goto unlock;
576
577         if (!pask->refcnt++)
578                 sock_hold(psk);
579
580         ask->refcnt = 1;
581         sock_put(psk);
582
583         err = 0;
584
585 unlock:
586         release_sock(psk);
587 unlock_child:
588         release_sock(sk);
589
590         return err;
591 }
592
593 static int skcipher_sendmsg_nokey(struct kiocb *unused, struct socket *sock,
594                                   struct msghdr *msg, size_t size)
595 {
596         int err;
597
598         err = skcipher_check_key(sock);
599         if (err)
600                 return err;
601
602         return skcipher_sendmsg(unused, sock, msg, size);
603 }
604
605 static ssize_t skcipher_sendpage_nokey(struct socket *sock, struct page *page,
606                                        int offset, size_t size, int flags)
607 {
608         int err;
609
610         err = skcipher_check_key(sock);
611         if (err)
612                 return err;
613
614         return skcipher_sendpage(sock, page, offset, size, flags);
615 }
616
617 static int skcipher_recvmsg_nokey(struct kiocb *unused, struct socket *sock,
618                                   struct msghdr *msg, size_t ignored, int flags)
619 {
620         int err;
621
622         err = skcipher_check_key(sock);
623         if (err)
624                 return err;
625
626         return skcipher_recvmsg(unused, sock, msg, ignored, flags);
627 }
628
629 static struct proto_ops algif_skcipher_ops_nokey = {
630         .family         =       PF_ALG,
631
632         .connect        =       sock_no_connect,
633         .socketpair     =       sock_no_socketpair,
634         .getname        =       sock_no_getname,
635         .ioctl          =       sock_no_ioctl,
636         .listen         =       sock_no_listen,
637         .shutdown       =       sock_no_shutdown,
638         .getsockopt     =       sock_no_getsockopt,
639         .mmap           =       sock_no_mmap,
640         .bind           =       sock_no_bind,
641         .accept         =       sock_no_accept,
642         .setsockopt     =       sock_no_setsockopt,
643
644         .release        =       af_alg_release,
645         .sendmsg        =       skcipher_sendmsg_nokey,
646         .sendpage       =       skcipher_sendpage_nokey,
647         .recvmsg        =       skcipher_recvmsg_nokey,
648         .poll           =       skcipher_poll,
649 };
650
651 static void *skcipher_bind(const char *name, u32 type, u32 mask)
652 {
653         struct skcipher_tfm *tfm;
654         struct crypto_ablkcipher *skcipher;
655
656         tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
657         if (!tfm)
658                 return ERR_PTR(-ENOMEM);
659
660         skcipher = crypto_alloc_ablkcipher(name, type, mask);
661         if (IS_ERR(skcipher)) {
662                 kfree(tfm);
663                 return ERR_CAST(skcipher);
664         }
665
666         tfm->skcipher = skcipher;
667
668         return tfm;
669 }
670
671 static void skcipher_release(void *private)
672 {
673         struct skcipher_tfm *tfm = private;
674
675         crypto_free_ablkcipher(tfm->skcipher);
676         kfree(tfm);
677 }
678
679 static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
680 {
681         struct skcipher_tfm *tfm = private;
682         int err;
683
684         err = crypto_ablkcipher_setkey(tfm->skcipher, key, keylen);
685         tfm->has_key = !err;
686
687         return err;
688 }
689
690 static void skcipher_sock_destruct(struct sock *sk)
691 {
692         struct alg_sock *ask = alg_sk(sk);
693         struct skcipher_ctx *ctx = ask->private;
694         struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(&ctx->req);
695
696         skcipher_free_sgl(sk);
697         sock_kfree_s(sk, ctx->iv, crypto_ablkcipher_ivsize(tfm));
698         sock_kfree_s(sk, ctx, ctx->len);
699         af_alg_release_parent(sk);
700 }
701
702 static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
703 {
704         struct skcipher_ctx *ctx;
705         struct alg_sock *ask = alg_sk(sk);
706         struct skcipher_tfm *tfm = private;
707         struct crypto_ablkcipher *skcipher = tfm->skcipher;
708         unsigned int len = sizeof(*ctx) + crypto_ablkcipher_reqsize(skcipher);
709
710         ctx = sock_kmalloc(sk, len, GFP_KERNEL);
711         if (!ctx)
712                 return -ENOMEM;
713
714         ctx->iv = sock_kmalloc(sk, crypto_ablkcipher_ivsize(skcipher),
715                                GFP_KERNEL);
716         if (!ctx->iv) {
717                 sock_kfree_s(sk, ctx, len);
718                 return -ENOMEM;
719         }
720
721         memset(ctx->iv, 0, crypto_ablkcipher_ivsize(skcipher));
722
723         INIT_LIST_HEAD(&ctx->tsgl);
724         ctx->len = len;
725         ctx->used = 0;
726         ctx->more = 0;
727         ctx->merge = 0;
728         ctx->enc = 0;
729         af_alg_init_completion(&ctx->completion);
730
731         ask->private = ctx;
732
733         ablkcipher_request_set_tfm(&ctx->req, skcipher);
734         ablkcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
735                                         af_alg_complete, &ctx->completion);
736
737         sk->sk_destruct = skcipher_sock_destruct;
738
739         return 0;
740 }
741
742 static int skcipher_accept_parent(void *private, struct sock *sk)
743 {
744         struct skcipher_tfm *tfm = private;
745
746         if (!tfm->has_key && crypto_ablkcipher_has_setkey(tfm->skcipher))
747                 return -ENOKEY;
748
749         return skcipher_accept_parent_nokey(private, sk);
750 }
751
752 static const struct af_alg_type algif_type_skcipher = {
753         .bind           =       skcipher_bind,
754         .release        =       skcipher_release,
755         .setkey         =       skcipher_setkey,
756         .accept         =       skcipher_accept_parent,
757         .accept_nokey   =       skcipher_accept_parent_nokey,
758         .ops            =       &algif_skcipher_ops,
759         .ops_nokey      =       &algif_skcipher_ops_nokey,
760         .name           =       "skcipher",
761         .owner          =       THIS_MODULE
762 };
763
764 static int __init algif_skcipher_init(void)
765 {
766         return af_alg_register_type(&algif_type_skcipher);
767 }
768
769 static void __exit algif_skcipher_exit(void)
770 {
771         int err = af_alg_unregister_type(&algif_type_skcipher);
772         BUG_ON(err);
773 }
774
775 module_init(algif_skcipher_init);
776 module_exit(algif_skcipher_exit);
777 MODULE_LICENSE("GPL");