Blame view

crypto/crypto_user.c 12.4 KB
a38f7907b   Steffen Klassert   crypto: Add users...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  /*
   * Crypto user configuration API.
   *
   * Copyright (C) 2011 secunet Security Networks AG
   * Copyright (C) 2011 Steffen Klassert <steffen.klassert@secunet.com>
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms and conditions of the GNU General Public License,
   * version 2, as published by the Free Software Foundation.
   *
   * This program is distributed in the hope it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   * more details.
   *
   * You should have received a copy of the GNU General Public License along with
   * this program; if not, write to the Free Software Foundation, Inc.,
   * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
   */
  
  #include <linux/module.h>
  #include <linux/crypto.h>
  #include <linux/cryptouser.h>
1e1229940   Steffen Klassert   crypto: user - Fi...
24
  #include <linux/sched.h>
a38f7907b   Steffen Klassert   crypto: Add users...
25
26
27
  #include <net/netlink.h>
  #include <linux/security.h>
  #include <net/net_namespace.h>
1e1229940   Steffen Klassert   crypto: user - Fi...
28
29
  #include <crypto/internal/aead.h>
  #include <crypto/internal/skcipher.h>
a38f7907b   Steffen Klassert   crypto: Add users...
30
  #include "internal.h"
8fd61d342   Mathias Krause   crypto: user - en...
31
  #define null_terminated(x)	(strnlen(x, sizeof(x)) < sizeof(x))
66ce0b0f2   Jussi Kivilinna   crypto: crypto_us...
32
  static DEFINE_MUTEX(crypto_cfg_mutex);
a38f7907b   Steffen Klassert   crypto: Add users...
33
34
35
36
37
38
39
40
41
42
43
44
45
  
  /* The crypto netlink socket */
  static struct sock *crypto_nlsk;
  
  struct crypto_dump_info {
  	struct sk_buff *in_skb;
  	struct sk_buff *out_skb;
  	u32 nlmsg_seq;
  	u16 nlmsg_flags;
  };
  
  static struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact)
  {
a38f7907b   Steffen Klassert   crypto: Add users...
46
47
48
  	struct crypto_alg *q, *alg = NULL;
  
  	down_read(&crypto_alg_sem);
a38f7907b   Steffen Klassert   crypto: Add users...
49
  	list_for_each_entry(q, &crypto_alg_list, cra_list) {
e6ea64ece   Herbert Xu   crypto: user - In...
50
  		int match = 0;
a38f7907b   Steffen Klassert   crypto: Add users...
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
  
  		if ((q->cra_flags ^ p->cru_type) & p->cru_mask)
  			continue;
  
  		if (strlen(p->cru_driver_name))
  			match = !strcmp(q->cra_driver_name,
  					p->cru_driver_name);
  		else if (!exact)
  			match = !strcmp(q->cra_name, p->cru_name);
  
  		if (match) {
  			alg = q;
  			break;
  		}
  	}
  
  	up_read(&crypto_alg_sem);
  
  	return alg;
  }
07a5fa4ab   Steffen Klassert   crypto: Add users...
71
72
73
  static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg)
  {
  	struct crypto_report_cipher rcipher;
9a5467bf7   Mathias Krause   crypto: user - fi...
74
  	strncpy(rcipher.type, "cipher", sizeof(rcipher.type));
07a5fa4ab   Steffen Klassert   crypto: Add users...
75
76
77
78
  
  	rcipher.blocksize = alg->cra_blocksize;
  	rcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
  	rcipher.max_keysize = alg->cra_cipher.cia_max_keysize;
6662df33f   David S. Miller   crypto: Stop usin...
79
80
81
  	if (nla_put(skb, CRYPTOCFGA_REPORT_CIPHER,
  		    sizeof(struct crypto_report_cipher), &rcipher))
  		goto nla_put_failure;
07a5fa4ab   Steffen Klassert   crypto: Add users...
82
83
84
85
86
  	return 0;
  
  nla_put_failure:
  	return -EMSGSIZE;
  }
540b97c1d   Steffen Klassert   crypto: Add users...
87
88
89
  static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg)
  {
  	struct crypto_report_comp rcomp;
9a5467bf7   Mathias Krause   crypto: user - fi...
90
  	strncpy(rcomp.type, "compression", sizeof(rcomp.type));
6662df33f   David S. Miller   crypto: Stop usin...
91
92
93
  	if (nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS,
  		    sizeof(struct crypto_report_comp), &rcomp))
  		goto nla_put_failure;
540b97c1d   Steffen Klassert   crypto: Add users...
94
95
96
97
98
  	return 0;
  
  nla_put_failure:
  	return -EMSGSIZE;
  }
a38f7907b   Steffen Klassert   crypto: Add users...
99
100
101
  static int crypto_report_one(struct crypto_alg *alg,
  			     struct crypto_user_alg *ualg, struct sk_buff *skb)
  {
9a5467bf7   Mathias Krause   crypto: user - fi...
102
103
104
105
106
107
108
109
  	strncpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name));
  	strncpy(ualg->cru_driver_name, alg->cra_driver_name,
  		sizeof(ualg->cru_driver_name));
  	strncpy(ualg->cru_module_name, module_name(alg->cra_module),
  		sizeof(ualg->cru_module_name));
  
  	ualg->cru_type = 0;
  	ualg->cru_mask = 0;
a38f7907b   Steffen Klassert   crypto: Add users...
110
111
  	ualg->cru_flags = alg->cra_flags;
  	ualg->cru_refcnt = atomic_read(&alg->cra_refcnt);
6662df33f   David S. Miller   crypto: Stop usin...
112
113
  	if (nla_put_u32(skb, CRYPTOCFGA_PRIORITY_VAL, alg->cra_priority))
  		goto nla_put_failure;
6c5a86f52   Steffen Klassert   crypto: Add users...
114
115
  	if (alg->cra_flags & CRYPTO_ALG_LARVAL) {
  		struct crypto_report_larval rl;
9a5467bf7   Mathias Krause   crypto: user - fi...
116
  		strncpy(rl.type, "larval", sizeof(rl.type));
6662df33f   David S. Miller   crypto: Stop usin...
117
118
119
  		if (nla_put(skb, CRYPTOCFGA_REPORT_LARVAL,
  			    sizeof(struct crypto_report_larval), &rl))
  			goto nla_put_failure;
6c5a86f52   Steffen Klassert   crypto: Add users...
120
121
  		goto out;
  	}
b6aa63c09   Steffen Klassert   crypto: Add a rep...
122
123
124
  	if (alg->cra_type && alg->cra_type->report) {
  		if (alg->cra_type->report(skb, alg))
  			goto nla_put_failure;
07a5fa4ab   Steffen Klassert   crypto: Add users...
125
126
127
128
129
130
131
132
133
134
  
  		goto out;
  	}
  
  	switch (alg->cra_flags & (CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_LARVAL)) {
  	case CRYPTO_ALG_TYPE_CIPHER:
  		if (crypto_report_cipher(skb, alg))
  			goto nla_put_failure;
  
  		break;
540b97c1d   Steffen Klassert   crypto: Add users...
135
136
137
138
139
  	case CRYPTO_ALG_TYPE_COMPRESS:
  		if (crypto_report_comp(skb, alg))
  			goto nla_put_failure;
  
  		break;
b6aa63c09   Steffen Klassert   crypto: Add a rep...
140
  	}
6c5a86f52   Steffen Klassert   crypto: Add users...
141
  out:
a38f7907b   Steffen Klassert   crypto: Add users...
142
143
144
145
146
147
148
149
150
151
152
153
154
155
  	return 0;
  
  nla_put_failure:
  	return -EMSGSIZE;
  }
  
  static int crypto_report_alg(struct crypto_alg *alg,
  			     struct crypto_dump_info *info)
  {
  	struct sk_buff *in_skb = info->in_skb;
  	struct sk_buff *skb = info->out_skb;
  	struct nlmsghdr *nlh;
  	struct crypto_user_alg *ualg;
  	int err = 0;
15e473046   Eric W. Biederman   netlink: Rename p...
156
  	nlh = nlmsg_put(skb, NETLINK_CB(in_skb).portid, info->nlmsg_seq,
a38f7907b   Steffen Klassert   crypto: Add users...
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
  			CRYPTO_MSG_GETALG, sizeof(*ualg), info->nlmsg_flags);
  	if (!nlh) {
  		err = -EMSGSIZE;
  		goto out;
  	}
  
  	ualg = nlmsg_data(nlh);
  
  	err = crypto_report_one(alg, ualg, skb);
  	if (err) {
  		nlmsg_cancel(skb, nlh);
  		goto out;
  	}
  
  	nlmsg_end(skb, nlh);
  
  out:
  	return err;
  }
  
  static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
  			 struct nlattr **attrs)
  {
  	struct crypto_user_alg *p = nlmsg_data(in_nlh);
  	struct crypto_alg *alg;
  	struct sk_buff *skb;
  	struct crypto_dump_info info;
  	int err;
8fd61d342   Mathias Krause   crypto: user - en...
185
186
  	if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name))
  		return -EINVAL;
5d4a5e770   Herbert Xu   crypto: user - Al...
187
  	alg = crypto_alg_match(p, 0);
a38f7907b   Steffen Klassert   crypto: Add users...
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
  	if (!alg)
  		return -ENOENT;
  
  	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
  	if (!skb)
  		return -ENOMEM;
  
  	info.in_skb = in_skb;
  	info.out_skb = skb;
  	info.nlmsg_seq = in_nlh->nlmsg_seq;
  	info.nlmsg_flags = 0;
  
  	err = crypto_report_alg(alg, &info);
  	if (err)
  		return err;
15e473046   Eric W. Biederman   netlink: Rename p...
203
  	return nlmsg_unicast(crypto_nlsk, skb, NETLINK_CB(in_skb).portid);
a38f7907b   Steffen Klassert   crypto: Add users...
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
  }
  
  static int crypto_dump_report(struct sk_buff *skb, struct netlink_callback *cb)
  {
  	struct crypto_alg *alg;
  	struct crypto_dump_info info;
  	int err;
  
  	if (cb->args[0])
  		goto out;
  
  	cb->args[0] = 1;
  
  	info.in_skb = cb->skb;
  	info.out_skb = skb;
  	info.nlmsg_seq = cb->nlh->nlmsg_seq;
  	info.nlmsg_flags = NLM_F_MULTI;
  
  	list_for_each_entry(alg, &crypto_alg_list, cra_list) {
  		err = crypto_report_alg(alg, &info);
  		if (err)
  			goto out_err;
  	}
  
  out:
  	return skb->len;
  out_err:
  	return err;
  }
  
  static int crypto_dump_report_done(struct netlink_callback *cb)
  {
  	return 0;
  }
  
  static int crypto_update_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
  			     struct nlattr **attrs)
  {
  	struct crypto_alg *alg;
  	struct crypto_user_alg *p = nlmsg_data(nlh);
  	struct nlattr *priority = attrs[CRYPTOCFGA_PRIORITY_VAL];
  	LIST_HEAD(list);
639b4ac69   Linus Torvalds   Merge git://git.k...
246
  	if (!netlink_capable(skb, CAP_NET_ADMIN))
c568398aa   Matthias-Christian Ott   crypto: user - Al...
247
  		return -EPERM;
8fd61d342   Mathias Krause   crypto: user - en...
248
249
  	if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name))
  		return -EINVAL;
a38f7907b   Steffen Klassert   crypto: Add users...
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
  	if (priority && !strlen(p->cru_driver_name))
  		return -EINVAL;
  
  	alg = crypto_alg_match(p, 1);
  	if (!alg)
  		return -ENOENT;
  
  	down_write(&crypto_alg_sem);
  
  	crypto_remove_spawns(alg, &list, NULL);
  
  	if (priority)
  		alg->cra_priority = nla_get_u32(priority);
  
  	up_write(&crypto_alg_sem);
  
  	crypto_remove_final(&list);
  
  	return 0;
  }
  
  static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
  			  struct nlattr **attrs)
  {
  	struct crypto_alg *alg;
  	struct crypto_user_alg *p = nlmsg_data(nlh);
639b4ac69   Linus Torvalds   Merge git://git.k...
276
  	if (!netlink_capable(skb, CAP_NET_ADMIN))
c568398aa   Matthias-Christian Ott   crypto: user - Al...
277
  		return -EPERM;
8fd61d342   Mathias Krause   crypto: user - en...
278
279
  	if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name))
  		return -EINVAL;
a38f7907b   Steffen Klassert   crypto: Add users...
280
281
282
283
284
285
286
287
288
289
290
291
292
293
  	alg = crypto_alg_match(p, 1);
  	if (!alg)
  		return -ENOENT;
  
  	/* We can not unregister core algorithms such as aes-generic.
  	 * We would loose the reference in the crypto_alg_list to this algorithm
  	 * if we try to unregister. Unregistering such an algorithm without
  	 * removing the module is not possible, so we restrict to crypto
  	 * instances that are build from templates. */
  	if (!(alg->cra_flags & CRYPTO_ALG_INSTANCE))
  		return -EINVAL;
  
  	if (atomic_read(&alg->cra_refcnt) != 1)
  		return -EBUSY;
ce3fd840f   Steffen Klassert   crypto: Unlink an...
294
  	return crypto_unregister_instance(alg);
a38f7907b   Steffen Klassert   crypto: Add users...
295
  }
1e1229940   Steffen Klassert   crypto: user - Fi...
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
  static struct crypto_alg *crypto_user_skcipher_alg(const char *name, u32 type,
  						   u32 mask)
  {
  	int err;
  	struct crypto_alg *alg;
  
  	type = crypto_skcipher_type(type);
  	mask = crypto_skcipher_mask(mask);
  
  	for (;;) {
  		alg = crypto_lookup_skcipher(name,  type, mask);
  		if (!IS_ERR(alg))
  			return alg;
  
  		err = PTR_ERR(alg);
  		if (err != -EAGAIN)
  			break;
  		if (signal_pending(current)) {
  			err = -EINTR;
  			break;
  		}
  	}
  
  	return ERR_PTR(err);
  }
  
  static struct crypto_alg *crypto_user_aead_alg(const char *name, u32 type,
  					       u32 mask)
  {
  	int err;
  	struct crypto_alg *alg;
  
  	type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
  	type |= CRYPTO_ALG_TYPE_AEAD;
  	mask &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
  	mask |= CRYPTO_ALG_TYPE_MASK;
  
  	for (;;) {
  		alg = crypto_lookup_aead(name,  type, mask);
  		if (!IS_ERR(alg))
  			return alg;
  
  		err = PTR_ERR(alg);
  		if (err != -EAGAIN)
  			break;
  		if (signal_pending(current)) {
  			err = -EINTR;
  			break;
  		}
  	}
  
  	return ERR_PTR(err);
  }
a38f7907b   Steffen Klassert   crypto: Add users...
349
350
351
  static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
  			  struct nlattr **attrs)
  {
0cfdec7a6   Jesper Juhl   crypto: In crypto...
352
  	int exact = 0;
a38f7907b   Steffen Klassert   crypto: Add users...
353
354
355
356
  	const char *name;
  	struct crypto_alg *alg;
  	struct crypto_user_alg *p = nlmsg_data(nlh);
  	struct nlattr *priority = attrs[CRYPTOCFGA_PRIORITY_VAL];
639b4ac69   Linus Torvalds   Merge git://git.k...
357
  	if (!netlink_capable(skb, CAP_NET_ADMIN))
c568398aa   Matthias-Christian Ott   crypto: user - Al...
358
  		return -EPERM;
8fd61d342   Mathias Krause   crypto: user - en...
359
360
  	if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name))
  		return -EINVAL;
a38f7907b   Steffen Klassert   crypto: Add users...
361
362
363
364
365
366
367
368
369
370
371
372
373
374
  	if (strlen(p->cru_driver_name))
  		exact = 1;
  
  	if (priority && !exact)
  		return -EINVAL;
  
  	alg = crypto_alg_match(p, exact);
  	if (alg)
  		return -EEXIST;
  
  	if (strlen(p->cru_driver_name))
  		name = p->cru_driver_name;
  	else
  		name = p->cru_name;
1e1229940   Steffen Klassert   crypto: user - Fi...
375
376
377
378
379
380
381
382
383
384
385
386
  	switch (p->cru_type & p->cru_mask & CRYPTO_ALG_TYPE_MASK) {
  	case CRYPTO_ALG_TYPE_AEAD:
  		alg = crypto_user_aead_alg(name, p->cru_type, p->cru_mask);
  		break;
  	case CRYPTO_ALG_TYPE_GIVCIPHER:
  	case CRYPTO_ALG_TYPE_BLKCIPHER:
  	case CRYPTO_ALG_TYPE_ABLKCIPHER:
  		alg = crypto_user_skcipher_alg(name, p->cru_type, p->cru_mask);
  		break;
  	default:
  		alg = crypto_alg_mod_lookup(name, p->cru_type, p->cru_mask);
  	}
a38f7907b   Steffen Klassert   crypto: Add users...
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
  	if (IS_ERR(alg))
  		return PTR_ERR(alg);
  
  	down_write(&crypto_alg_sem);
  
  	if (priority)
  		alg->cra_priority = nla_get_u32(priority);
  
  	up_write(&crypto_alg_sem);
  
  	crypto_mod_put(alg);
  
  	return 0;
  }
  
  #define MSGSIZE(type) sizeof(struct type)
  
  static const int crypto_msg_min[CRYPTO_NR_MSGTYPES] = {
  	[CRYPTO_MSG_NEWALG	- CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
  	[CRYPTO_MSG_DELALG	- CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
  	[CRYPTO_MSG_UPDATEALG	- CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
  	[CRYPTO_MSG_GETALG	- CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
  };
  
  static const struct nla_policy crypto_policy[CRYPTOCFGA_MAX+1] = {
  	[CRYPTOCFGA_PRIORITY_VAL]   = { .type = NLA_U32},
  };
  
  #undef MSGSIZE
a84fb791c   Mathias Krause   crypto: user - co...
416
  static const struct crypto_link {
a38f7907b   Steffen Klassert   crypto: Add users...
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
  	int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **);
  	int (*dump)(struct sk_buff *, struct netlink_callback *);
  	int (*done)(struct netlink_callback *);
  } crypto_dispatch[CRYPTO_NR_MSGTYPES] = {
  	[CRYPTO_MSG_NEWALG	- CRYPTO_MSG_BASE] = { .doit = crypto_add_alg},
  	[CRYPTO_MSG_DELALG	- CRYPTO_MSG_BASE] = { .doit = crypto_del_alg},
  	[CRYPTO_MSG_UPDATEALG	- CRYPTO_MSG_BASE] = { .doit = crypto_update_alg},
  	[CRYPTO_MSG_GETALG	- CRYPTO_MSG_BASE] = { .doit = crypto_report,
  						       .dump = crypto_dump_report,
  						       .done = crypto_dump_report_done},
  };
  
  static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
  {
  	struct nlattr *attrs[CRYPTOCFGA_MAX+1];
a84fb791c   Mathias Krause   crypto: user - co...
432
  	const struct crypto_link *link;
a38f7907b   Steffen Klassert   crypto: Add users...
433
434
435
436
437
438
439
440
  	int type, err;
  
  	type = nlh->nlmsg_type;
  	if (type > CRYPTO_MSG_MAX)
  		return -EINVAL;
  
  	type -= CRYPTO_MSG_BASE;
  	link = &crypto_dispatch[type];
a38f7907b   Steffen Klassert   crypto: Add users...
441
442
  	if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) &&
  	    (nlh->nlmsg_flags & NLM_F_DUMP))) {
5219a5342   Steffen Klassert   crypto: user - Fi...
443
444
  		struct crypto_alg *alg;
  		u16 dump_alloc = 0;
a38f7907b   Steffen Klassert   crypto: Add users...
445
446
  		if (link->dump == NULL)
  			return -EINVAL;
5219a5342   Steffen Klassert   crypto: user - Fi...
447
448
449
  
  		list_for_each_entry(alg, &crypto_alg_list, cra_list)
  			dump_alloc += CRYPTO_REPORT_MAXSIZE;
80d326fab   Pablo Neira Ayuso   netlink: add netl...
450
451
452
453
  		{
  			struct netlink_dump_control c = {
  				.dump = link->dump,
  				.done = link->done,
5219a5342   Steffen Klassert   crypto: user - Fi...
454
  				.min_dump_alloc = dump_alloc,
80d326fab   Pablo Neira Ayuso   netlink: add netl...
455
456
457
  			};
  			return netlink_dump_start(crypto_nlsk, skb, nlh, &c);
  		}
a38f7907b   Steffen Klassert   crypto: Add users...
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
  	}
  
  	err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX,
  			  crypto_policy);
  	if (err < 0)
  		return err;
  
  	if (link->doit == NULL)
  		return -EINVAL;
  
  	return link->doit(skb, nlh, attrs);
  }
  
  static void crypto_netlink_rcv(struct sk_buff *skb)
  {
  	mutex_lock(&crypto_cfg_mutex);
  	netlink_rcv_skb(skb, &crypto_user_rcv_msg);
  	mutex_unlock(&crypto_cfg_mutex);
  }
  
  static int __init crypto_user_init(void)
  {
a31f2d17b   Pablo Neira Ayuso   netlink: add netl...
480
481
482
  	struct netlink_kernel_cfg cfg = {
  		.input	= crypto_netlink_rcv,
  	};
9f00d9776   Pablo Neira Ayuso   netlink: hide str...
483
  	crypto_nlsk = netlink_kernel_create(&init_net, NETLINK_CRYPTO, &cfg);
a38f7907b   Steffen Klassert   crypto: Add users...
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
  	if (!crypto_nlsk)
  		return -ENOMEM;
  
  	return 0;
  }
  
  static void __exit crypto_user_exit(void)
  {
  	netlink_kernel_release(crypto_nlsk);
  }
  
  module_init(crypto_user_init);
  module_exit(crypto_user_exit);
  MODULE_LICENSE("GPL");
  MODULE_AUTHOR("Steffen Klassert <steffen.klassert@secunet.com>");
  MODULE_DESCRIPTION("Crypto userspace configuration API");
476c7fe20   Stephan Mueller   crypto: user - ad...
500
  MODULE_ALIAS("net-pf-16-proto-21");