Blame view

crypto/algif_skcipher.c 10.7 KB
8ff590903   Herbert Xu   crypto: algif_skc...
1
2
3
4
5
6
7
8
9
10
11
12
  /*
   * 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>
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License as published by the Free
   * Software Foundation; either version 2 of the License, or (at your option)
   * any later version.
   *
e870456d8   Stephan Mueller   crypto: algif_skc...
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
   * 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...
28
29
30
31
32
33
34
35
36
37
38
39
   */
  
  #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>
dd5045895   Herbert Xu   crypto: algif_skc...
40
41
42
43
  struct skcipher_tfm {
  	struct crypto_skcipher *skcipher;
  	bool has_key;
  };
1b7841404   Ying Xue   net: Remove iocb ...
44
45
  static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg,
  			    size_t size)
8ff590903   Herbert Xu   crypto: algif_skc...
46
47
48
  {
  	struct sock *sk = sock->sk;
  	struct alg_sock *ask = alg_sk(sk);
6454c2b83   Herbert Xu   crypto: algif_skc...
49
50
  	struct sock *psk = ask->parent;
  	struct alg_sock *pask = alg_sk(psk);
6454c2b83   Herbert Xu   crypto: algif_skc...
51
52
  	struct skcipher_tfm *skc = pask->private;
  	struct crypto_skcipher *tfm = skc->skcipher;
0d96e4bab   Herbert Xu   crypto: algif_skc...
53
  	unsigned ivsize = crypto_skcipher_ivsize(tfm);
8ff590903   Herbert Xu   crypto: algif_skc...
54

2d97591ef   Stephan Mueller   crypto: af_alg - ...
55
  	return af_alg_sendmsg(sock, msg, size, ivsize);
a596999b7   Tadeusz Struk   crypto: algif - c...
56
  }
e870456d8   Stephan Mueller   crypto: algif_skc...
57
58
  static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
  			     size_t ignored, int flags)
a596999b7   Tadeusz Struk   crypto: algif - c...
59
60
61
  {
  	struct sock *sk = sock->sk;
  	struct alg_sock *ask = alg_sk(sk);
ec69bbfb9   Herbert Xu   crypto: algif_skc...
62
63
  	struct sock *psk = ask->parent;
  	struct alg_sock *pask = alg_sk(psk);
2d97591ef   Stephan Mueller   crypto: af_alg - ...
64
  	struct af_alg_ctx *ctx = ask->private;
ec69bbfb9   Herbert Xu   crypto: algif_skc...
65
66
  	struct skcipher_tfm *skc = pask->private;
  	struct crypto_skcipher *tfm = skc->skcipher;
e870456d8   Stephan Mueller   crypto: algif_skc...
67
  	unsigned int bs = crypto_skcipher_blocksize(tfm);
2d97591ef   Stephan Mueller   crypto: af_alg - ...
68
  	struct af_alg_async_req *areq;
e870456d8   Stephan Mueller   crypto: algif_skc...
69
70
  	int err = 0;
  	size_t len = 0;
ec69bbfb9   Herbert Xu   crypto: algif_skc...
71

c692698eb   Stephan Mueller   crypto: af_alg - ...
72
73
74
75
76
  	if (!ctx->used) {
  		err = af_alg_wait_for_data(sk, flags);
  		if (err)
  			return err;
  	}
e870456d8   Stephan Mueller   crypto: algif_skc...
77
  	/* Allocate cipher request for current operation. */
2d97591ef   Stephan Mueller   crypto: af_alg - ...
78
79
80
81
  	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...
82

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

e870456d8   Stephan Mueller   crypto: algif_skc...
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  	/* 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 - ...
103
  	areq->tsgl_entries = af_alg_count_tsgl(sk, len, 0);
e870456d8   Stephan Mueller   crypto: algif_skc...
104
105
106
107
108
109
110
111
112
  	if (!areq->tsgl_entries)
  		areq->tsgl_entries = 1;
  	areq->tsgl = sock_kmalloc(sk, sizeof(*areq->tsgl) * areq->tsgl_entries,
  				  GFP_KERNEL);
  	if (!areq->tsgl) {
  		err = -ENOMEM;
  		goto free;
  	}
  	sg_init_table(areq->tsgl, areq->tsgl_entries);
2d97591ef   Stephan Mueller   crypto: af_alg - ...
113
  	af_alg_pull_tsgl(sk, len, areq->tsgl, 0);
e870456d8   Stephan Mueller   crypto: algif_skc...
114
115
  
  	/* Initialize the crypto operation */
2d97591ef   Stephan Mueller   crypto: af_alg - ...
116
117
118
  	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...
119
120
121
  
  	if (msg->msg_iocb && !is_sync_kiocb(msg->msg_iocb)) {
  		/* AIO operation */
7f21961a2   Stephan Mueller   crypto: af_alg - ...
122
  		sock_hold(sk);
e870456d8   Stephan Mueller   crypto: algif_skc...
123
  		areq->iocb = msg->msg_iocb;
f09fca41e   Stephan Mueller   crypto: af_alg - ...
124
125
126
  
  		/* Remember output size that will be generated. */
  		areq->outlen = len;
2d97591ef   Stephan Mueller   crypto: af_alg - ...
127
  		skcipher_request_set_callback(&areq->cra_u.skcipher_req,
e870456d8   Stephan Mueller   crypto: algif_skc...
128
  					      CRYPTO_TFM_REQ_MAY_SLEEP,
2d97591ef   Stephan Mueller   crypto: af_alg - ...
129
130
131
132
  					      af_alg_async_cb, areq);
  		err = ctx->enc ?
  			crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) :
  			crypto_skcipher_decrypt(&areq->cra_u.skcipher_req);
7f21961a2   Stephan Mueller   crypto: af_alg - ...
133
134
  
  		/* AIO operation in progress */
f09fca41e   Stephan Mueller   crypto: af_alg - ...
135
  		if (err == -EINPROGRESS || err == -EBUSY)
7f21961a2   Stephan Mueller   crypto: af_alg - ...
136
  			return -EIOCBQUEUED;
7f21961a2   Stephan Mueller   crypto: af_alg - ...
137
138
  
  		sock_put(sk);
e870456d8   Stephan Mueller   crypto: algif_skc...
139
140
  	} else {
  		/* Synchronous operation */
2d97591ef   Stephan Mueller   crypto: af_alg - ...
141
  		skcipher_request_set_callback(&areq->cra_u.skcipher_req,
e870456d8   Stephan Mueller   crypto: algif_skc...
142
143
144
145
146
  					      CRYPTO_TFM_REQ_MAY_SLEEP |
  					      CRYPTO_TFM_REQ_MAY_BACKLOG,
  					      af_alg_complete,
  					      &ctx->completion);
  		err = af_alg_wait_for_completion(ctx->enc ?
2d97591ef   Stephan Mueller   crypto: af_alg - ...
147
148
  			crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) :
  			crypto_skcipher_decrypt(&areq->cra_u.skcipher_req),
e870456d8   Stephan Mueller   crypto: algif_skc...
149
150
  						 &ctx->completion);
  	}
033f46b3c   tadeusz.struk@intel.com   crypto: algif - e...
151

e870456d8   Stephan Mueller   crypto: algif_skc...
152

a596999b7   Tadeusz Struk   crypto: algif - c...
153
  free:
7f21961a2   Stephan Mueller   crypto: af_alg - ...
154
  	af_alg_free_resources(areq);
e870456d8   Stephan Mueller   crypto: algif_skc...
155
156
  
  	return err ? err : len;
a596999b7   Tadeusz Struk   crypto: algif - c...
157
  }
e870456d8   Stephan Mueller   crypto: algif_skc...
158
159
  static int skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
  			    size_t ignored, int flags)
8ff590903   Herbert Xu   crypto: algif_skc...
160
161
  {
  	struct sock *sk = sock->sk;
e870456d8   Stephan Mueller   crypto: algif_skc...
162
  	int ret = 0;
8ff590903   Herbert Xu   crypto: algif_skc...
163
164
  
  	lock_sock(sk);
01e97e651   Al Viro   new helper: msg_d...
165
  	while (msg_data_left(msg)) {
e870456d8   Stephan Mueller   crypto: algif_skc...
166
167
168
169
170
171
172
  		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...
173
174
  		 *
  		 * Also return the error if no data has been processed so far.
e870456d8   Stephan Mueller   crypto: algif_skc...
175
176
  		 */
  		if (err <= 0) {
5703c826b   Stephan Mueller   crypto: algif - r...
177
  			if (err == -EIOCBQUEUED || !ret)
e870456d8   Stephan Mueller   crypto: algif_skc...
178
179
  				ret = err;
  			goto out;
1d10eb2f1   Al Viro   crypto: switch af...
180
  		}
e870456d8   Stephan Mueller   crypto: algif_skc...
181
  		ret += err;
8ff590903   Herbert Xu   crypto: algif_skc...
182
  	}
e870456d8   Stephan Mueller   crypto: algif_skc...
183
  out:
2d97591ef   Stephan Mueller   crypto: af_alg - ...
184
  	af_alg_wmem_wakeup(sk);
8ff590903   Herbert Xu   crypto: algif_skc...
185
  	release_sock(sk);
e870456d8   Stephan Mueller   crypto: algif_skc...
186
  	return ret;
a596999b7   Tadeusz Struk   crypto: algif - c...
187
  }
8ff590903   Herbert Xu   crypto: algif_skc...
188

8ff590903   Herbert Xu   crypto: algif_skc...
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
  
  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 - ...
207
  	.sendpage	=	af_alg_sendpage,
8ff590903   Herbert Xu   crypto: algif_skc...
208
  	.recvmsg	=	skcipher_recvmsg,
2d97591ef   Stephan Mueller   crypto: af_alg - ...
209
  	.poll		=	af_alg_poll,
8ff590903   Herbert Xu   crypto: algif_skc...
210
  };
a0fa2d037   Herbert Xu   crypto: algif_skc...
211
212
  static int skcipher_check_key(struct socket *sock)
  {
1822793a5   Herbert Xu   crypto: algif_skc...
213
  	int err = 0;
a0fa2d037   Herbert Xu   crypto: algif_skc...
214
215
216
217
218
  	struct sock *psk;
  	struct alg_sock *pask;
  	struct skcipher_tfm *tfm;
  	struct sock *sk = sock->sk;
  	struct alg_sock *ask = alg_sk(sk);
1822793a5   Herbert Xu   crypto: algif_skc...
219
  	lock_sock(sk);
a0fa2d037   Herbert Xu   crypto: algif_skc...
220
  	if (ask->refcnt)
1822793a5   Herbert Xu   crypto: algif_skc...
221
  		goto unlock_child;
a0fa2d037   Herbert Xu   crypto: algif_skc...
222
223
224
225
226
227
  
  	psk = ask->parent;
  	pask = alg_sk(ask->parent);
  	tfm = pask->private;
  
  	err = -ENOKEY;
1822793a5   Herbert Xu   crypto: algif_skc...
228
  	lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
a0fa2d037   Herbert Xu   crypto: algif_skc...
229
230
231
232
233
234
235
236
237
238
239
240
241
  	if (!tfm->has_key)
  		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...
242
243
  unlock_child:
  	release_sock(sk);
a0fa2d037   Herbert Xu   crypto: algif_skc...
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
  
  	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 - ...
268
  	return af_alg_sendpage(sock, page, offset, size, flags);
a0fa2d037   Herbert Xu   crypto: algif_skc...
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
  }
  
  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,
2d97591ef   Stephan Mueller   crypto: af_alg - ...
302
  	.poll		=	af_alg_poll,
a0fa2d037   Herbert Xu   crypto: algif_skc...
303
  };
8ff590903   Herbert Xu   crypto: algif_skc...
304
305
  static void *skcipher_bind(const char *name, u32 type, u32 mask)
  {
dd5045895   Herbert Xu   crypto: algif_skc...
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
  	struct skcipher_tfm *tfm;
  	struct crypto_skcipher *skcipher;
  
  	tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
  	if (!tfm)
  		return ERR_PTR(-ENOMEM);
  
  	skcipher = crypto_alloc_skcipher(name, type, mask);
  	if (IS_ERR(skcipher)) {
  		kfree(tfm);
  		return ERR_CAST(skcipher);
  	}
  
  	tfm->skcipher = skcipher;
  
  	return tfm;
8ff590903   Herbert Xu   crypto: algif_skc...
322
323
324
325
  }
  
  static void skcipher_release(void *private)
  {
dd5045895   Herbert Xu   crypto: algif_skc...
326
327
328
329
  	struct skcipher_tfm *tfm = private;
  
  	crypto_free_skcipher(tfm->skcipher);
  	kfree(tfm);
8ff590903   Herbert Xu   crypto: algif_skc...
330
331
332
333
  }
  
  static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
  {
dd5045895   Herbert Xu   crypto: algif_skc...
334
335
336
337
338
339
340
  	struct skcipher_tfm *tfm = private;
  	int err;
  
  	err = crypto_skcipher_setkey(tfm->skcipher, key, keylen);
  	tfm->has_key = !err;
  
  	return err;
8ff590903   Herbert Xu   crypto: algif_skc...
341
342
343
344
345
  }
  
  static void skcipher_sock_destruct(struct sock *sk)
  {
  	struct alg_sock *ask = alg_sk(sk);
2d97591ef   Stephan Mueller   crypto: af_alg - ...
346
  	struct af_alg_ctx *ctx = ask->private;
e870456d8   Stephan Mueller   crypto: algif_skc...
347
348
349
350
  	struct sock *psk = ask->parent;
  	struct alg_sock *pask = alg_sk(psk);
  	struct skcipher_tfm *skc = pask->private;
  	struct crypto_skcipher *tfm = skc->skcipher;
a596999b7   Tadeusz Struk   crypto: algif - c...
351

2d97591ef   Stephan Mueller   crypto: af_alg - ...
352
  	af_alg_pull_tsgl(sk, ctx->used, NULL, 0);
0d96e4bab   Herbert Xu   crypto: algif_skc...
353
  	sock_kzfree_s(sk, ctx->iv, crypto_skcipher_ivsize(tfm));
8ff590903   Herbert Xu   crypto: algif_skc...
354
355
356
  	sock_kfree_s(sk, ctx, ctx->len);
  	af_alg_release_parent(sk);
  }
d7b65aee1   Herbert Xu   crypto: algif_skc...
357
  static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
8ff590903   Herbert Xu   crypto: algif_skc...
358
  {
2d97591ef   Stephan Mueller   crypto: af_alg - ...
359
  	struct af_alg_ctx *ctx;
8ff590903   Herbert Xu   crypto: algif_skc...
360
  	struct alg_sock *ask = alg_sk(sk);
dd5045895   Herbert Xu   crypto: algif_skc...
361
362
  	struct skcipher_tfm *tfm = private;
  	struct crypto_skcipher *skcipher = tfm->skcipher;
e870456d8   Stephan Mueller   crypto: algif_skc...
363
  	unsigned int len = sizeof(*ctx);
8ff590903   Herbert Xu   crypto: algif_skc...
364
365
366
367
  
  	ctx = sock_kmalloc(sk, len, GFP_KERNEL);
  	if (!ctx)
  		return -ENOMEM;
dd5045895   Herbert Xu   crypto: algif_skc...
368
  	ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(skcipher),
8ff590903   Herbert Xu   crypto: algif_skc...
369
370
371
372
373
  			       GFP_KERNEL);
  	if (!ctx->iv) {
  		sock_kfree_s(sk, ctx, len);
  		return -ENOMEM;
  	}
dd5045895   Herbert Xu   crypto: algif_skc...
374
  	memset(ctx->iv, 0, crypto_skcipher_ivsize(skcipher));
8ff590903   Herbert Xu   crypto: algif_skc...
375

e870456d8   Stephan Mueller   crypto: algif_skc...
376
  	INIT_LIST_HEAD(&ctx->tsgl_list);
8ff590903   Herbert Xu   crypto: algif_skc...
377
378
  	ctx->len = len;
  	ctx->used = 0;
36d0a678f   Jonathan Cameron   crypto: af_alg - ...
379
  	atomic_set(&ctx->rcvused, 0);
8ff590903   Herbert Xu   crypto: algif_skc...
380
381
382
383
384
385
  	ctx->more = 0;
  	ctx->merge = 0;
  	ctx->enc = 0;
  	af_alg_init_completion(&ctx->completion);
  
  	ask->private = ctx;
8ff590903   Herbert Xu   crypto: algif_skc...
386
387
388
389
  	sk->sk_destruct = skcipher_sock_destruct;
  
  	return 0;
  }
a0fa2d037   Herbert Xu   crypto: algif_skc...
390
391
392
  static int skcipher_accept_parent(void *private, struct sock *sk)
  {
  	struct skcipher_tfm *tfm = private;
6e8d8ecf4   Herbert Xu   crypto: algif_skc...
393
  	if (!tfm->has_key && crypto_skcipher_has_setkey(tfm->skcipher))
a0fa2d037   Herbert Xu   crypto: algif_skc...
394
  		return -ENOKEY;
d7b65aee1   Herbert Xu   crypto: algif_skc...
395
  	return skcipher_accept_parent_nokey(private, sk);
a0fa2d037   Herbert Xu   crypto: algif_skc...
396
  }
8ff590903   Herbert Xu   crypto: algif_skc...
397
398
399
400
401
  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...
402
  	.accept_nokey	=	skcipher_accept_parent_nokey,
8ff590903   Herbert Xu   crypto: algif_skc...
403
  	.ops		=	&algif_skcipher_ops,
a0fa2d037   Herbert Xu   crypto: algif_skc...
404
  	.ops_nokey	=	&algif_skcipher_ops_nokey,
8ff590903   Herbert Xu   crypto: algif_skc...
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
  	.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");