Blame view

crypto/algif_skcipher.c 9.87 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
8ff590903   Herbert Xu   crypto: algif_skc...
2
3
4
5
6
7
8
  /*
   * algif_skcipher: User-space interface for skcipher algorithms
   *
   * This file provides the user-space API for symmetric key ciphers.
   *
   * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au>
   *
e870456d8   Stephan Mueller   crypto: algif_skc...
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
   * The following concept of the memory management is used:
   *
   * The kernel maintains two SGLs, the TX SGL and the RX SGL. The TX SGL is
   * filled by user space with the data submitted via sendpage/sendmsg. Filling
   * up the TX SGL does not cause a crypto operation -- the data will only be
   * tracked by the kernel. Upon receipt of one recvmsg call, the caller must
   * provide a buffer which is tracked with the RX SGL.
   *
   * During the processing of the recvmsg operation, the cipher request is
   * allocated and prepared. As part of the recvmsg operation, the processed
   * TX buffers are extracted from the TX SGL into a separate SGL.
   *
   * After the completion of the crypto operation, the RX SGL and the cipher
   * request is released. The extracted TX SGL parts are released together with
   * the RX SGL release.
8ff590903   Herbert Xu   crypto: algif_skc...
24
25
26
27
28
29
30
31
32
33
34
35
   */
  
  #include <crypto/scatterwalk.h>
  #include <crypto/skcipher.h>
  #include <crypto/if_alg.h>
  #include <linux/init.h>
  #include <linux/list.h>
  #include <linux/kernel.h>
  #include <linux/mm.h>
  #include <linux/module.h>
  #include <linux/net.h>
  #include <net/sock.h>
1b7841404   Ying Xue   net: Remove iocb ...
36
37
  static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg,
  			    size_t size)
8ff590903   Herbert Xu   crypto: algif_skc...
38
39
40
  {
  	struct sock *sk = sock->sk;
  	struct alg_sock *ask = alg_sk(sk);
6454c2b83   Herbert Xu   crypto: algif_skc...
41
42
  	struct sock *psk = ask->parent;
  	struct alg_sock *pask = alg_sk(psk);
f8d33fac8   Eric Biggers   crypto: skcipher ...
43
  	struct crypto_skcipher *tfm = pask->private;
0d96e4bab   Herbert Xu   crypto: algif_skc...
44
  	unsigned ivsize = crypto_skcipher_ivsize(tfm);
8ff590903   Herbert Xu   crypto: algif_skc...
45

2d97591ef   Stephan Mueller   crypto: af_alg - ...
46
  	return af_alg_sendmsg(sock, msg, size, ivsize);
a596999b7   Tadeusz Struk   crypto: algif - c...
47
  }
e870456d8   Stephan Mueller   crypto: algif_skc...
48
49
  static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
  			     size_t ignored, int flags)
a596999b7   Tadeusz Struk   crypto: algif - c...
50
51
52
  {
  	struct sock *sk = sock->sk;
  	struct alg_sock *ask = alg_sk(sk);
ec69bbfb9   Herbert Xu   crypto: algif_skc...
53
54
  	struct sock *psk = ask->parent;
  	struct alg_sock *pask = alg_sk(psk);
2d97591ef   Stephan Mueller   crypto: af_alg - ...
55
  	struct af_alg_ctx *ctx = ask->private;
f8d33fac8   Eric Biggers   crypto: skcipher ...
56
  	struct crypto_skcipher *tfm = pask->private;
d7835f2b8   Herbert Xu   crypto: algif_skc...
57
  	unsigned int bs = crypto_skcipher_chunksize(tfm);
2d97591ef   Stephan Mueller   crypto: af_alg - ...
58
  	struct af_alg_async_req *areq;
e870456d8   Stephan Mueller   crypto: algif_skc...
59
60
  	int err = 0;
  	size_t len = 0;
ec69bbfb9   Herbert Xu   crypto: algif_skc...
61

11edb5559   Stephan Mueller   crypto: af_alg - ...
62
63
64
65
66
  	if (!ctx->used) {
  		err = af_alg_wait_for_data(sk, flags);
  		if (err)
  			return err;
  	}
e870456d8   Stephan Mueller   crypto: algif_skc...
67
  	/* Allocate cipher request for current operation. */
2d97591ef   Stephan Mueller   crypto: af_alg - ...
68
69
70
71
  	areq = af_alg_alloc_areq(sk, sizeof(struct af_alg_async_req) +
  				     crypto_skcipher_reqsize(tfm));
  	if (IS_ERR(areq))
  		return PTR_ERR(areq);
a596999b7   Tadeusz Struk   crypto: algif - c...
72

e870456d8   Stephan Mueller   crypto: algif_skc...
73
  	/* convert iovecs of output buffers into RX SGL */
2d97591ef   Stephan Mueller   crypto: af_alg - ...
74
75
76
  	err = af_alg_get_rsgl(sk, msg, flags, areq, -1, &len);
  	if (err)
  		goto free;
a596999b7   Tadeusz Struk   crypto: algif - c...
77

e870456d8   Stephan Mueller   crypto: algif_skc...
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
  	/* Process only as much RX buffers for which we have TX data */
  	if (len > ctx->used)
  		len = ctx->used;
  
  	/*
  	 * If more buffers are to be expected to be processed, process only
  	 * full block size buffers.
  	 */
  	if (ctx->more || len < ctx->used)
  		len -= len % bs;
  
  	/*
  	 * Create a per request TX SGL for this request which tracks the
  	 * SG entries from the global TX SGL.
  	 */
2d97591ef   Stephan Mueller   crypto: af_alg - ...
93
  	areq->tsgl_entries = af_alg_count_tsgl(sk, len, 0);
e870456d8   Stephan Mueller   crypto: algif_skc...
94
95
  	if (!areq->tsgl_entries)
  		areq->tsgl_entries = 1;
76e43e37a   Kees Cook   treewide: Use arr...
96
97
  	areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
  						 areq->tsgl_entries),
e870456d8   Stephan Mueller   crypto: algif_skc...
98
99
100
101
102
103
  				  GFP_KERNEL);
  	if (!areq->tsgl) {
  		err = -ENOMEM;
  		goto free;
  	}
  	sg_init_table(areq->tsgl, areq->tsgl_entries);
2d97591ef   Stephan Mueller   crypto: af_alg - ...
104
  	af_alg_pull_tsgl(sk, len, areq->tsgl, 0);
e870456d8   Stephan Mueller   crypto: algif_skc...
105
106
  
  	/* Initialize the crypto operation */
2d97591ef   Stephan Mueller   crypto: af_alg - ...
107
108
109
  	skcipher_request_set_tfm(&areq->cra_u.skcipher_req, tfm);
  	skcipher_request_set_crypt(&areq->cra_u.skcipher_req, areq->tsgl,
  				   areq->first_rsgl.sgl.sg, len, ctx->iv);
e870456d8   Stephan Mueller   crypto: algif_skc...
110
111
112
  
  	if (msg->msg_iocb && !is_sync_kiocb(msg->msg_iocb)) {
  		/* AIO operation */
7d2c3f54e   Stephan Mueller   crypto: af_alg - ...
113
  		sock_hold(sk);
e870456d8   Stephan Mueller   crypto: algif_skc...
114
  		areq->iocb = msg->msg_iocb;
d53c51357   Stephan Mueller   crypto: af_alg - ...
115
116
117
  
  		/* Remember output size that will be generated. */
  		areq->outlen = len;
2d97591ef   Stephan Mueller   crypto: af_alg - ...
118
  		skcipher_request_set_callback(&areq->cra_u.skcipher_req,
e870456d8   Stephan Mueller   crypto: algif_skc...
119
  					      CRYPTO_TFM_REQ_MAY_SLEEP,
2d97591ef   Stephan Mueller   crypto: af_alg - ...
120
121
122
123
  					      af_alg_async_cb, areq);
  		err = ctx->enc ?
  			crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) :
  			crypto_skcipher_decrypt(&areq->cra_u.skcipher_req);
7d2c3f54e   Stephan Mueller   crypto: af_alg - ...
124
125
  
  		/* AIO operation in progress */
d53c51357   Stephan Mueller   crypto: af_alg - ...
126
  		if (err == -EINPROGRESS || err == -EBUSY)
7d2c3f54e   Stephan Mueller   crypto: af_alg - ...
127
  			return -EIOCBQUEUED;
7d2c3f54e   Stephan Mueller   crypto: af_alg - ...
128
129
  
  		sock_put(sk);
e870456d8   Stephan Mueller   crypto: algif_skc...
130
131
  	} else {
  		/* Synchronous operation */
2d97591ef   Stephan Mueller   crypto: af_alg - ...
132
  		skcipher_request_set_callback(&areq->cra_u.skcipher_req,
e870456d8   Stephan Mueller   crypto: algif_skc...
133
134
  					      CRYPTO_TFM_REQ_MAY_SLEEP |
  					      CRYPTO_TFM_REQ_MAY_BACKLOG,
2c3f8b162   Gilad Ben-Yossef   crypto: algif - m...
135
136
  					      crypto_req_done, &ctx->wait);
  		err = crypto_wait_req(ctx->enc ?
2d97591ef   Stephan Mueller   crypto: af_alg - ...
137
138
  			crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) :
  			crypto_skcipher_decrypt(&areq->cra_u.skcipher_req),
2c3f8b162   Gilad Ben-Yossef   crypto: algif - m...
139
  						 &ctx->wait);
e870456d8   Stephan Mueller   crypto: algif_skc...
140
  	}
033f46b3c   tadeusz.struk@intel.com   crypto: algif - e...
141

e870456d8   Stephan Mueller   crypto: algif_skc...
142

a596999b7   Tadeusz Struk   crypto: algif - c...
143
  free:
7d2c3f54e   Stephan Mueller   crypto: af_alg - ...
144
  	af_alg_free_resources(areq);
e870456d8   Stephan Mueller   crypto: algif_skc...
145
146
  
  	return err ? err : len;
a596999b7   Tadeusz Struk   crypto: algif - c...
147
  }
e870456d8   Stephan Mueller   crypto: algif_skc...
148
149
  static int skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
  			    size_t ignored, int flags)
8ff590903   Herbert Xu   crypto: algif_skc...
150
151
  {
  	struct sock *sk = sock->sk;
e870456d8   Stephan Mueller   crypto: algif_skc...
152
  	int ret = 0;
8ff590903   Herbert Xu   crypto: algif_skc...
153
154
  
  	lock_sock(sk);
01e97e651   Al Viro   new helper: msg_d...
155
  	while (msg_data_left(msg)) {
e870456d8   Stephan Mueller   crypto: algif_skc...
156
157
158
159
160
161
162
  		int err = _skcipher_recvmsg(sock, msg, ignored, flags);
  
  		/*
  		 * This error covers -EIOCBQUEUED which implies that we can
  		 * only handle one AIO request. If the caller wants to have
  		 * multiple AIO requests in parallel, he must make multiple
  		 * separate AIO calls.
5703c826b   Stephan Mueller   crypto: algif - r...
163
164
  		 *
  		 * Also return the error if no data has been processed so far.
e870456d8   Stephan Mueller   crypto: algif_skc...
165
166
  		 */
  		if (err <= 0) {
5703c826b   Stephan Mueller   crypto: algif - r...
167
  			if (err == -EIOCBQUEUED || !ret)
e870456d8   Stephan Mueller   crypto: algif_skc...
168
169
  				ret = err;
  			goto out;
1d10eb2f1   Al Viro   crypto: switch af...
170
  		}
e870456d8   Stephan Mueller   crypto: algif_skc...
171
  		ret += err;
8ff590903   Herbert Xu   crypto: algif_skc...
172
  	}
e870456d8   Stephan Mueller   crypto: algif_skc...
173
  out:
2d97591ef   Stephan Mueller   crypto: af_alg - ...
174
  	af_alg_wmem_wakeup(sk);
8ff590903   Herbert Xu   crypto: algif_skc...
175
  	release_sock(sk);
e870456d8   Stephan Mueller   crypto: algif_skc...
176
  	return ret;
a596999b7   Tadeusz Struk   crypto: algif - c...
177
  }
8ff590903   Herbert Xu   crypto: algif_skc...
178

8ff590903   Herbert Xu   crypto: algif_skc...
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
  static struct proto_ops algif_skcipher_ops = {
  	.family		=	PF_ALG,
  
  	.connect	=	sock_no_connect,
  	.socketpair	=	sock_no_socketpair,
  	.getname	=	sock_no_getname,
  	.ioctl		=	sock_no_ioctl,
  	.listen		=	sock_no_listen,
  	.shutdown	=	sock_no_shutdown,
  	.getsockopt	=	sock_no_getsockopt,
  	.mmap		=	sock_no_mmap,
  	.bind		=	sock_no_bind,
  	.accept		=	sock_no_accept,
  	.setsockopt	=	sock_no_setsockopt,
  
  	.release	=	af_alg_release,
  	.sendmsg	=	skcipher_sendmsg,
2d97591ef   Stephan Mueller   crypto: af_alg - ...
196
  	.sendpage	=	af_alg_sendpage,
8ff590903   Herbert Xu   crypto: algif_skc...
197
  	.recvmsg	=	skcipher_recvmsg,
a11e1d432   Linus Torvalds   Revert changes to...
198
  	.poll		=	af_alg_poll,
8ff590903   Herbert Xu   crypto: algif_skc...
199
  };
a0fa2d037   Herbert Xu   crypto: algif_skc...
200
201
  static int skcipher_check_key(struct socket *sock)
  {
1822793a5   Herbert Xu   crypto: algif_skc...
202
  	int err = 0;
a0fa2d037   Herbert Xu   crypto: algif_skc...
203
204
  	struct sock *psk;
  	struct alg_sock *pask;
f8d33fac8   Eric Biggers   crypto: skcipher ...
205
  	struct crypto_skcipher *tfm;
a0fa2d037   Herbert Xu   crypto: algif_skc...
206
207
  	struct sock *sk = sock->sk;
  	struct alg_sock *ask = alg_sk(sk);
1822793a5   Herbert Xu   crypto: algif_skc...
208
  	lock_sock(sk);
a0fa2d037   Herbert Xu   crypto: algif_skc...
209
  	if (ask->refcnt)
1822793a5   Herbert Xu   crypto: algif_skc...
210
  		goto unlock_child;
a0fa2d037   Herbert Xu   crypto: algif_skc...
211
212
213
214
215
216
  
  	psk = ask->parent;
  	pask = alg_sk(ask->parent);
  	tfm = pask->private;
  
  	err = -ENOKEY;
1822793a5   Herbert Xu   crypto: algif_skc...
217
  	lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
f8d33fac8   Eric Biggers   crypto: skcipher ...
218
  	if (crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
a0fa2d037   Herbert Xu   crypto: algif_skc...
219
220
221
222
223
224
225
226
227
228
229
230
  		goto unlock;
  
  	if (!pask->refcnt++)
  		sock_hold(psk);
  
  	ask->refcnt = 1;
  	sock_put(psk);
  
  	err = 0;
  
  unlock:
  	release_sock(psk);
1822793a5   Herbert Xu   crypto: algif_skc...
231
232
  unlock_child:
  	release_sock(sk);
a0fa2d037   Herbert Xu   crypto: algif_skc...
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
  
  	return err;
  }
  
  static int skcipher_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
  				  size_t size)
  {
  	int err;
  
  	err = skcipher_check_key(sock);
  	if (err)
  		return err;
  
  	return skcipher_sendmsg(sock, msg, size);
  }
  
  static ssize_t skcipher_sendpage_nokey(struct socket *sock, struct page *page,
  				       int offset, size_t size, int flags)
  {
  	int err;
  
  	err = skcipher_check_key(sock);
  	if (err)
  		return err;
2d97591ef   Stephan Mueller   crypto: af_alg - ...
257
  	return af_alg_sendpage(sock, page, offset, size, flags);
a0fa2d037   Herbert Xu   crypto: algif_skc...
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
  }
  
  static int skcipher_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
  				  size_t ignored, int flags)
  {
  	int err;
  
  	err = skcipher_check_key(sock);
  	if (err)
  		return err;
  
  	return skcipher_recvmsg(sock, msg, ignored, flags);
  }
  
  static struct proto_ops algif_skcipher_ops_nokey = {
  	.family		=	PF_ALG,
  
  	.connect	=	sock_no_connect,
  	.socketpair	=	sock_no_socketpair,
  	.getname	=	sock_no_getname,
  	.ioctl		=	sock_no_ioctl,
  	.listen		=	sock_no_listen,
  	.shutdown	=	sock_no_shutdown,
  	.getsockopt	=	sock_no_getsockopt,
  	.mmap		=	sock_no_mmap,
  	.bind		=	sock_no_bind,
  	.accept		=	sock_no_accept,
  	.setsockopt	=	sock_no_setsockopt,
  
  	.release	=	af_alg_release,
  	.sendmsg	=	skcipher_sendmsg_nokey,
  	.sendpage	=	skcipher_sendpage_nokey,
  	.recvmsg	=	skcipher_recvmsg_nokey,
a11e1d432   Linus Torvalds   Revert changes to...
291
  	.poll		=	af_alg_poll,
a0fa2d037   Herbert Xu   crypto: algif_skc...
292
  };
8ff590903   Herbert Xu   crypto: algif_skc...
293
294
  static void *skcipher_bind(const char *name, u32 type, u32 mask)
  {
f8d33fac8   Eric Biggers   crypto: skcipher ...
295
  	return crypto_alloc_skcipher(name, type, mask);
8ff590903   Herbert Xu   crypto: algif_skc...
296
297
298
299
  }
  
  static void skcipher_release(void *private)
  {
f8d33fac8   Eric Biggers   crypto: skcipher ...
300
  	crypto_free_skcipher(private);
8ff590903   Herbert Xu   crypto: algif_skc...
301
302
303
304
  }
  
  static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
  {
f8d33fac8   Eric Biggers   crypto: skcipher ...
305
  	return crypto_skcipher_setkey(private, key, keylen);
8ff590903   Herbert Xu   crypto: algif_skc...
306
307
308
309
310
  }
  
  static void skcipher_sock_destruct(struct sock *sk)
  {
  	struct alg_sock *ask = alg_sk(sk);
2d97591ef   Stephan Mueller   crypto: af_alg - ...
311
  	struct af_alg_ctx *ctx = ask->private;
e870456d8   Stephan Mueller   crypto: algif_skc...
312
313
  	struct sock *psk = ask->parent;
  	struct alg_sock *pask = alg_sk(psk);
f8d33fac8   Eric Biggers   crypto: skcipher ...
314
  	struct crypto_skcipher *tfm = pask->private;
a596999b7   Tadeusz Struk   crypto: algif - c...
315

2d97591ef   Stephan Mueller   crypto: af_alg - ...
316
  	af_alg_pull_tsgl(sk, ctx->used, NULL, 0);
0d96e4bab   Herbert Xu   crypto: algif_skc...
317
  	sock_kzfree_s(sk, ctx->iv, crypto_skcipher_ivsize(tfm));
8ff590903   Herbert Xu   crypto: algif_skc...
318
319
320
  	sock_kfree_s(sk, ctx, ctx->len);
  	af_alg_release_parent(sk);
  }
d7b65aee1   Herbert Xu   crypto: algif_skc...
321
  static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
8ff590903   Herbert Xu   crypto: algif_skc...
322
  {
2d97591ef   Stephan Mueller   crypto: af_alg - ...
323
  	struct af_alg_ctx *ctx;
8ff590903   Herbert Xu   crypto: algif_skc...
324
  	struct alg_sock *ask = alg_sk(sk);
f8d33fac8   Eric Biggers   crypto: skcipher ...
325
  	struct crypto_skcipher *tfm = private;
e870456d8   Stephan Mueller   crypto: algif_skc...
326
  	unsigned int len = sizeof(*ctx);
8ff590903   Herbert Xu   crypto: algif_skc...
327
328
329
330
  
  	ctx = sock_kmalloc(sk, len, GFP_KERNEL);
  	if (!ctx)
  		return -ENOMEM;
f8d33fac8   Eric Biggers   crypto: skcipher ...
331
  	ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(tfm),
8ff590903   Herbert Xu   crypto: algif_skc...
332
333
334
335
336
  			       GFP_KERNEL);
  	if (!ctx->iv) {
  		sock_kfree_s(sk, ctx, len);
  		return -ENOMEM;
  	}
f8d33fac8   Eric Biggers   crypto: skcipher ...
337
  	memset(ctx->iv, 0, crypto_skcipher_ivsize(tfm));
8ff590903   Herbert Xu   crypto: algif_skc...
338

e870456d8   Stephan Mueller   crypto: algif_skc...
339
  	INIT_LIST_HEAD(&ctx->tsgl_list);
8ff590903   Herbert Xu   crypto: algif_skc...
340
341
  	ctx->len = len;
  	ctx->used = 0;
af955bf15   Jonathan Cameron   crypto: af_alg - ...
342
  	atomic_set(&ctx->rcvused, 0);
8ff590903   Herbert Xu   crypto: algif_skc...
343
344
345
  	ctx->more = 0;
  	ctx->merge = 0;
  	ctx->enc = 0;
2c3f8b162   Gilad Ben-Yossef   crypto: algif - m...
346
  	crypto_init_wait(&ctx->wait);
8ff590903   Herbert Xu   crypto: algif_skc...
347
348
  
  	ask->private = ctx;
8ff590903   Herbert Xu   crypto: algif_skc...
349
350
351
352
  	sk->sk_destruct = skcipher_sock_destruct;
  
  	return 0;
  }
a0fa2d037   Herbert Xu   crypto: algif_skc...
353
354
  static int skcipher_accept_parent(void *private, struct sock *sk)
  {
f8d33fac8   Eric Biggers   crypto: skcipher ...
355
  	struct crypto_skcipher *tfm = private;
a0fa2d037   Herbert Xu   crypto: algif_skc...
356

f8d33fac8   Eric Biggers   crypto: skcipher ...
357
  	if (crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
a0fa2d037   Herbert Xu   crypto: algif_skc...
358
  		return -ENOKEY;
d7b65aee1   Herbert Xu   crypto: algif_skc...
359
  	return skcipher_accept_parent_nokey(private, sk);
a0fa2d037   Herbert Xu   crypto: algif_skc...
360
  }
8ff590903   Herbert Xu   crypto: algif_skc...
361
362
363
364
365
  static const struct af_alg_type algif_type_skcipher = {
  	.bind		=	skcipher_bind,
  	.release	=	skcipher_release,
  	.setkey		=	skcipher_setkey,
  	.accept		=	skcipher_accept_parent,
a0fa2d037   Herbert Xu   crypto: algif_skc...
366
  	.accept_nokey	=	skcipher_accept_parent_nokey,
8ff590903   Herbert Xu   crypto: algif_skc...
367
  	.ops		=	&algif_skcipher_ops,
a0fa2d037   Herbert Xu   crypto: algif_skc...
368
  	.ops_nokey	=	&algif_skcipher_ops_nokey,
8ff590903   Herbert Xu   crypto: algif_skc...
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
  	.name		=	"skcipher",
  	.owner		=	THIS_MODULE
  };
  
  static int __init algif_skcipher_init(void)
  {
  	return af_alg_register_type(&algif_type_skcipher);
  }
  
  static void __exit algif_skcipher_exit(void)
  {
  	int err = af_alg_unregister_type(&algif_type_skcipher);
  	BUG_ON(err);
  }
  
  module_init(algif_skcipher_init);
  module_exit(algif_skcipher_exit);
  MODULE_LICENSE("GPL");