Blame view

crypto/crypto_user_base.c 12 KB
a61127c21   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
a38f7907b   Steffen Klassert   crypto: Add users...
2
3
4
5
6
  /*
   * Crypto user configuration API.
   *
   * Copyright (C) 2011 secunet Security Networks AG
   * Copyright (C) 2011 Steffen Klassert <steffen.klassert@secunet.com>
a38f7907b   Steffen Klassert   crypto: Add users...
7
8
9
10
11
   */
  
  #include <linux/module.h>
  #include <linux/crypto.h>
  #include <linux/cryptouser.h>
1e1229940   Steffen Klassert   crypto: user - Fi...
12
  #include <linux/sched.h>
a38f7907b   Steffen Klassert   crypto: Add users...
13
  #include <linux/security.h>
91b05a7e7   Ondrej Mosnacek   crypto: user - ma...
14
  #include <net/netlink.h>
a38f7907b   Steffen Klassert   crypto: Add users...
15
  #include <net/net_namespace.h>
91b05a7e7   Ondrej Mosnacek   crypto: user - ma...
16
  #include <net/sock.h>
1e1229940   Steffen Klassert   crypto: user - Fi...
17
  #include <crypto/internal/skcipher.h>
9aa867e46   Herbert Xu   crypto: user - Ad...
18
  #include <crypto/internal/rng.h>
3c339ab83   Tadeusz Struk   crypto: akcipher ...
19
  #include <crypto/akcipher.h>
4e5f2c400   Salvatore Benedetto   crypto: kpp - Key...
20
  #include <crypto/kpp.h>
cac5818c2   Corentin Labbe   crypto: user - Im...
21
  #include <crypto/internal/cryptouser.h>
1e1229940   Steffen Klassert   crypto: user - Fi...
22

a38f7907b   Steffen Klassert   crypto: Add users...
23
  #include "internal.h"
8fd61d342   Mathias Krause   crypto: user - en...
24
  #define null_terminated(x)	(strnlen(x, sizeof(x)) < sizeof(x))
66ce0b0f2   Jussi Kivilinna   crypto: crypto_us...
25
  static DEFINE_MUTEX(crypto_cfg_mutex);
a38f7907b   Steffen Klassert   crypto: Add users...
26

a38f7907b   Steffen Klassert   crypto: Add users...
27
28
29
30
31
32
  struct crypto_dump_info {
  	struct sk_buff *in_skb;
  	struct sk_buff *out_skb;
  	u32 nlmsg_seq;
  	u16 nlmsg_flags;
  };
cac5818c2   Corentin Labbe   crypto: user - Im...
33
  struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact)
a38f7907b   Steffen Klassert   crypto: Add users...
34
  {
a38f7907b   Steffen Klassert   crypto: Add users...
35
36
37
  	struct crypto_alg *q, *alg = NULL;
  
  	down_read(&crypto_alg_sem);
a38f7907b   Steffen Klassert   crypto: Add users...
38
  	list_for_each_entry(q, &crypto_alg_list, cra_list) {
e6ea64ece   Herbert Xu   crypto: user - In...
39
  		int match = 0;
a38f7907b   Steffen Klassert   crypto: Add users...
40

21d4120ec   Eric Biggers   crypto: user - pr...
41
42
  		if (crypto_is_larval(q))
  			continue;
a38f7907b   Steffen Klassert   crypto: Add users...
43
44
45
46
47
48
49
50
  		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);
016baaa11   Herbert Xu   crypto: user - Fi...
51
52
53
54
55
56
57
58
  		if (!match)
  			continue;
  
  		if (unlikely(!crypto_mod_get(q)))
  			continue;
  
  		alg = q;
  		break;
a38f7907b   Steffen Klassert   crypto: Add users...
59
60
61
62
63
64
  	}
  
  	up_read(&crypto_alg_sem);
  
  	return alg;
  }
07a5fa4ab   Steffen Klassert   crypto: Add users...
65
66
67
  static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg)
  {
  	struct crypto_report_cipher rcipher;
37db69e0b   Eric Biggers   crypto: user - cl...
68
69
70
  	memset(&rcipher, 0, sizeof(rcipher));
  
  	strscpy(rcipher.type, "cipher", sizeof(rcipher.type));
07a5fa4ab   Steffen Klassert   crypto: Add users...
71
72
73
74
  
  	rcipher.blocksize = alg->cra_blocksize;
  	rcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
  	rcipher.max_keysize = alg->cra_cipher.cia_max_keysize;
37db69e0b   Eric Biggers   crypto: user - cl...
75
76
  	return nla_put(skb, CRYPTOCFGA_REPORT_CIPHER,
  		       sizeof(rcipher), &rcipher);
07a5fa4ab   Steffen Klassert   crypto: Add users...
77
  }
540b97c1d   Steffen Klassert   crypto: Add users...
78
79
80
  static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg)
  {
  	struct crypto_report_comp rcomp;
37db69e0b   Eric Biggers   crypto: user - cl...
81
82
83
  	memset(&rcomp, 0, sizeof(rcomp));
  
  	strscpy(rcomp.type, "compression", sizeof(rcomp.type));
540b97c1d   Steffen Klassert   crypto: Add users...
84

37db69e0b   Eric Biggers   crypto: user - cl...
85
  	return nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS, sizeof(rcomp), &rcomp);
540b97c1d   Steffen Klassert   crypto: Add users...
86
  }
a38f7907b   Steffen Klassert   crypto: Add users...
87
88
89
  static int crypto_report_one(struct crypto_alg *alg,
  			     struct crypto_user_alg *ualg, struct sk_buff *skb)
  {
37db69e0b   Eric Biggers   crypto: user - cl...
90
91
92
93
  	memset(ualg, 0, sizeof(*ualg));
  
  	strscpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name));
  	strscpy(ualg->cru_driver_name, alg->cra_driver_name,
9a5467bf7   Mathias Krause   crypto: user - fi...
94
  		sizeof(ualg->cru_driver_name));
37db69e0b   Eric Biggers   crypto: user - cl...
95
  	strscpy(ualg->cru_module_name, module_name(alg->cra_module),
9a5467bf7   Mathias Krause   crypto: user - fi...
96
97
98
99
  		sizeof(ualg->cru_module_name));
  
  	ualg->cru_type = 0;
  	ualg->cru_mask = 0;
a38f7907b   Steffen Klassert   crypto: Add users...
100
  	ualg->cru_flags = alg->cra_flags;
ce8614a31   Eric Biggers   crypto: algapi - ...
101
  	ualg->cru_refcnt = refcount_read(&alg->cra_refcnt);
a38f7907b   Steffen Klassert   crypto: Add users...
102

6662df33f   David S. Miller   crypto: Stop usin...
103
104
  	if (nla_put_u32(skb, CRYPTOCFGA_PRIORITY_VAL, alg->cra_priority))
  		goto nla_put_failure;
6c5a86f52   Steffen Klassert   crypto: Add users...
105
106
  	if (alg->cra_flags & CRYPTO_ALG_LARVAL) {
  		struct crypto_report_larval rl;
37db69e0b   Eric Biggers   crypto: user - cl...
107
108
109
  		memset(&rl, 0, sizeof(rl));
  		strscpy(rl.type, "larval", sizeof(rl.type));
  		if (nla_put(skb, CRYPTOCFGA_REPORT_LARVAL, sizeof(rl), &rl))
6662df33f   David S. Miller   crypto: Stop usin...
110
  			goto nla_put_failure;
6c5a86f52   Steffen Klassert   crypto: Add users...
111
112
  		goto out;
  	}
b6aa63c09   Steffen Klassert   crypto: Add a rep...
113
114
115
  	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...
116
117
118
119
120
121
122
123
124
125
  
  		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...
126
127
128
129
130
  	case CRYPTO_ALG_TYPE_COMPRESS:
  		if (crypto_report_comp(skb, alg))
  			goto nla_put_failure;
  
  		break;
b6aa63c09   Steffen Klassert   crypto: Add a rep...
131
  	}
6c5a86f52   Steffen Klassert   crypto: Add users...
132
  out:
a38f7907b   Steffen Klassert   crypto: Add users...
133
134
135
136
137
138
139
140
141
142
143
144
145
146
  	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...
147
  	nlh = nlmsg_put(skb, NETLINK_CB(in_skb).portid, info->nlmsg_seq,
a38f7907b   Steffen Klassert   crypto: Add users...
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
  			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)
  {
91b05a7e7   Ondrej Mosnacek   crypto: user - ma...
171
  	struct net *net = sock_net(in_skb->sk);
a38f7907b   Steffen Klassert   crypto: Add users...
172
173
174
175
176
  	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...
177
178
  	if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name))
  		return -EINVAL;
5d4a5e770   Herbert Xu   crypto: user - Al...
179
  	alg = crypto_alg_match(p, 0);
a38f7907b   Steffen Klassert   crypto: Add users...
180
181
  	if (!alg)
  		return -ENOENT;
016baaa11   Herbert Xu   crypto: user - Fi...
182
  	err = -ENOMEM;
9a69b7ae7   Jia-Ju Bai   crypto: user - Re...
183
  	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
a38f7907b   Steffen Klassert   crypto: Add users...
184
  	if (!skb)
016baaa11   Herbert Xu   crypto: user - Fi...
185
  		goto drop_alg;
a38f7907b   Steffen Klassert   crypto: Add users...
186
187
188
189
190
191
192
  
  	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);
016baaa11   Herbert Xu   crypto: user - Fi...
193
194
195
  
  drop_alg:
  	crypto_mod_put(alg);
ffdde5932   Navid Emamdoost   crypto: user - fi...
196
197
  	if (err) {
  		kfree_skb(skb);
a38f7907b   Steffen Klassert   crypto: Add users...
198
  		return err;
ffdde5932   Navid Emamdoost   crypto: user - fi...
199
  	}
a38f7907b   Steffen Klassert   crypto: Add users...
200

91b05a7e7   Ondrej Mosnacek   crypto: user - ma...
201
  	return nlmsg_unicast(net->crypto_nlsk, skb, NETLINK_CB(in_skb).portid);
a38f7907b   Steffen Klassert   crypto: Add users...
202
203
204
205
  }
  
  static int crypto_dump_report(struct sk_buff *skb, struct netlink_callback *cb)
  {
0ac6b8fb2   Eric Biggers   crypto: user - su...
206
207
  	const size_t start_pos = cb->args[0];
  	size_t pos = 0;
a38f7907b   Steffen Klassert   crypto: Add users...
208
  	struct crypto_dump_info info;
0ac6b8fb2   Eric Biggers   crypto: user - su...
209
210
  	struct crypto_alg *alg;
  	int res;
a38f7907b   Steffen Klassert   crypto: Add users...
211
212
213
214
215
  
  	info.in_skb = cb->skb;
  	info.out_skb = skb;
  	info.nlmsg_seq = cb->nlh->nlmsg_seq;
  	info.nlmsg_flags = NLM_F_MULTI;
0ac6b8fb2   Eric Biggers   crypto: user - su...
216
  	down_read(&crypto_alg_sem);
a38f7907b   Steffen Klassert   crypto: Add users...
217
  	list_for_each_entry(alg, &crypto_alg_list, cra_list) {
0ac6b8fb2   Eric Biggers   crypto: user - su...
218
219
220
221
222
223
224
225
  		if (pos >= start_pos) {
  			res = crypto_report_alg(alg, &info);
  			if (res == -EMSGSIZE)
  				break;
  			if (res)
  				goto out;
  		}
  		pos++;
a38f7907b   Steffen Klassert   crypto: Add users...
226
  	}
0ac6b8fb2   Eric Biggers   crypto: user - su...
227
228
  	cb->args[0] = pos;
  	res = skb->len;
a38f7907b   Steffen Klassert   crypto: Add users...
229
  out:
0ac6b8fb2   Eric Biggers   crypto: user - su...
230
231
  	up_read(&crypto_alg_sem);
  	return res;
a38f7907b   Steffen Klassert   crypto: Add users...
232
233
234
235
236
237
238
239
240
241
242
243
244
245
  }
  
  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
  	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);
016baaa11   Herbert Xu   crypto: user - Fi...
265
  	crypto_mod_put(alg);
a38f7907b   Steffen Klassert   crypto: Add users...
266
267
268
269
270
271
272
273
274
275
  	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);
016baaa11   Herbert Xu   crypto: user - Fi...
276
  	int err;
a38f7907b   Steffen Klassert   crypto: Add users...
277

639b4ac69   Linus Torvalds   Merge git://git.k...
278
  	if (!netlink_capable(skb, CAP_NET_ADMIN))
c568398aa   Matthias-Christian Ott   crypto: user - Al...
279
  		return -EPERM;
8fd61d342   Mathias Krause   crypto: user - en...
280
281
  	if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name))
  		return -EINVAL;
a38f7907b   Steffen Klassert   crypto: Add users...
282
283
284
285
286
287
288
289
290
  	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. */
016baaa11   Herbert Xu   crypto: user - Fi...
291
  	err = -EINVAL;
a38f7907b   Steffen Klassert   crypto: Add users...
292
  	if (!(alg->cra_flags & CRYPTO_ALG_INSTANCE))
016baaa11   Herbert Xu   crypto: user - Fi...
293
  		goto drop_alg;
a38f7907b   Steffen Klassert   crypto: Add users...
294

016baaa11   Herbert Xu   crypto: user - Fi...
295
  	err = -EBUSY;
ce8614a31   Eric Biggers   crypto: algapi - ...
296
  	if (refcount_read(&alg->cra_refcnt) > 2)
016baaa11   Herbert Xu   crypto: user - Fi...
297
  		goto drop_alg;
a38f7907b   Steffen Klassert   crypto: Add users...
298

c6d633a92   Eric Biggers   crypto: algapi - ...
299
300
  	crypto_unregister_instance((struct crypto_instance *)alg);
  	err = 0;
016baaa11   Herbert Xu   crypto: user - Fi...
301
302
303
304
  
  drop_alg:
  	crypto_mod_put(alg);
  	return err;
a38f7907b   Steffen Klassert   crypto: Add users...
305
306
307
308
309
  }
  
  static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
  			  struct nlattr **attrs)
  {
0cfdec7a6   Jesper Juhl   crypto: In crypto...
310
  	int exact = 0;
a38f7907b   Steffen Klassert   crypto: Add users...
311
312
313
314
  	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...
315
  	if (!netlink_capable(skb, CAP_NET_ADMIN))
c568398aa   Matthias-Christian Ott   crypto: user - Al...
316
  		return -EPERM;
8fd61d342   Mathias Krause   crypto: user - en...
317
318
  	if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name))
  		return -EINVAL;
a38f7907b   Steffen Klassert   crypto: Add users...
319
320
321
322
323
324
325
  	if (strlen(p->cru_driver_name))
  		exact = 1;
  
  	if (priority && !exact)
  		return -EINVAL;
  
  	alg = crypto_alg_match(p, exact);
016baaa11   Herbert Xu   crypto: user - Fi...
326
327
  	if (alg) {
  		crypto_mod_put(alg);
a38f7907b   Steffen Klassert   crypto: Add users...
328
  		return -EEXIST;
016baaa11   Herbert Xu   crypto: user - Fi...
329
  	}
a38f7907b   Steffen Klassert   crypto: Add users...
330
331
332
333
334
  
  	if (strlen(p->cru_driver_name))
  		name = p->cru_driver_name;
  	else
  		name = p->cru_name;
6cf80a296   Herbert Xu   crypto: user - Re...
335
  	alg = crypto_alg_mod_lookup(name, p->cru_type, p->cru_mask);
a38f7907b   Steffen Klassert   crypto: Add users...
336
337
338
339
340
341
342
343
344
345
346
347
348
349
  	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;
  }
9aa867e46   Herbert Xu   crypto: user - Ad...
350
351
352
353
354
355
356
  static int crypto_del_rng(struct sk_buff *skb, struct nlmsghdr *nlh,
  			  struct nlattr **attrs)
  {
  	if (!netlink_capable(skb, CAP_NET_ADMIN))
  		return -EPERM;
  	return crypto_del_default_rng();
  }
a38f7907b   Steffen Klassert   crypto: Add users...
357
358
359
360
361
362
  #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),
055ddaace   Mathias Krause   crypto: user - re...
363
  	[CRYPTO_MSG_GETALG	- CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
9aa867e46   Herbert Xu   crypto: user - Ad...
364
  	[CRYPTO_MSG_DELRNG	- CRYPTO_MSG_BASE] = 0,
cac5818c2   Corentin Labbe   crypto: user - Im...
365
  	[CRYPTO_MSG_GETSTAT	- CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
a38f7907b   Steffen Klassert   crypto: Add users...
366
367
368
369
370
371
372
  };
  
  static const struct nla_policy crypto_policy[CRYPTOCFGA_MAX+1] = {
  	[CRYPTOCFGA_PRIORITY_VAL]   = { .type = NLA_U32},
  };
  
  #undef MSGSIZE
a84fb791c   Mathias Krause   crypto: user - co...
373
  static const struct crypto_link {
a38f7907b   Steffen Klassert   crypto: Add users...
374
375
376
377
378
379
380
381
382
383
  	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},
9aa867e46   Herbert Xu   crypto: user - Ad...
384
  	[CRYPTO_MSG_DELRNG	- CRYPTO_MSG_BASE] = { .doit = crypto_del_rng },
0c99c2a08   Corentin Labbe   crypto: user - re...
385
  	[CRYPTO_MSG_GETSTAT	- CRYPTO_MSG_BASE] = { .doit = crypto_reportstat},
a38f7907b   Steffen Klassert   crypto: Add users...
386
  };
2d4bc9336   Johannes Berg   netlink: extended...
387
388
  static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
  			       struct netlink_ext_ack *extack)
a38f7907b   Steffen Klassert   crypto: Add users...
389
  {
91b05a7e7   Ondrej Mosnacek   crypto: user - ma...
390
  	struct net *net = sock_net(skb->sk);
a38f7907b   Steffen Klassert   crypto: Add users...
391
  	struct nlattr *attrs[CRYPTOCFGA_MAX+1];
a84fb791c   Mathias Krause   crypto: user - co...
392
  	const struct crypto_link *link;
a38f7907b   Steffen Klassert   crypto: Add users...
393
394
395
396
397
398
399
400
  	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...
401
402
  	if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) &&
  	    (nlh->nlmsg_flags & NLM_F_DUMP))) {
5219a5342   Steffen Klassert   crypto: user - Fi...
403
  		struct crypto_alg *alg;
0ac6b8fb2   Eric Biggers   crypto: user - su...
404
  		unsigned long dump_alloc = 0;
5219a5342   Steffen Klassert   crypto: user - Fi...
405

a38f7907b   Steffen Klassert   crypto: Add users...
406
407
  		if (link->dump == NULL)
  			return -EINVAL;
5219a5342   Steffen Klassert   crypto: user - Fi...
408

63e41ebc6   Mathias Krause   crypto: user - lo...
409
  		down_read(&crypto_alg_sem);
5219a5342   Steffen Klassert   crypto: user - Fi...
410
411
  		list_for_each_entry(alg, &crypto_alg_list, cra_list)
  			dump_alloc += CRYPTO_REPORT_MAXSIZE;
0ac6b8fb2   Eric Biggers   crypto: user - su...
412
  		up_read(&crypto_alg_sem);
5219a5342   Steffen Klassert   crypto: user - Fi...
413

80d326fab   Pablo Neira Ayuso   netlink: add netl...
414
415
416
417
  		{
  			struct netlink_dump_control c = {
  				.dump = link->dump,
  				.done = link->done,
0ac6b8fb2   Eric Biggers   crypto: user - su...
418
  				.min_dump_alloc = min(dump_alloc, 65535UL),
80d326fab   Pablo Neira Ayuso   netlink: add netl...
419
  			};
91b05a7e7   Ondrej Mosnacek   crypto: user - ma...
420
  			err = netlink_dump_start(net->crypto_nlsk, skb, nlh, &c);
80d326fab   Pablo Neira Ayuso   netlink: add netl...
421
  		}
63e41ebc6   Mathias Krause   crypto: user - lo...
422
423
  
  		return err;
a38f7907b   Steffen Klassert   crypto: Add users...
424
  	}
8cb081746   Johannes Berg   netlink: make val...
425
426
  	err = nlmsg_parse_deprecated(nlh, crypto_msg_min[type], attrs,
  				     CRYPTOCFGA_MAX, crypto_policy, extack);
fd2efd93b   Herbert Xu   Revert "crypto: u...
427
428
  	if (err < 0)
  		return err;
a38f7907b   Steffen Klassert   crypto: Add users...
429
430
431
432
433
434
435
436
437
438
439
440
441
  
  	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);
  }
91b05a7e7   Ondrej Mosnacek   crypto: user - ma...
442
  static int __net_init crypto_netlink_init(struct net *net)
a38f7907b   Steffen Klassert   crypto: Add users...
443
  {
a31f2d17b   Pablo Neira Ayuso   netlink: add netl...
444
445
446
  	struct netlink_kernel_cfg cfg = {
  		.input	= crypto_netlink_rcv,
  	};
91b05a7e7   Ondrej Mosnacek   crypto: user - ma...
447
448
449
  	net->crypto_nlsk = netlink_kernel_create(net, NETLINK_CRYPTO, &cfg);
  	return net->crypto_nlsk == NULL ? -ENOMEM : 0;
  }
a38f7907b   Steffen Klassert   crypto: Add users...
450

91b05a7e7   Ondrej Mosnacek   crypto: user - ma...
451
452
453
454
455
456
457
458
459
460
461
462
463
464
  static void __net_exit crypto_netlink_exit(struct net *net)
  {
  	netlink_kernel_release(net->crypto_nlsk);
  	net->crypto_nlsk = NULL;
  }
  
  static struct pernet_operations crypto_netlink_net_ops = {
  	.init = crypto_netlink_init,
  	.exit = crypto_netlink_exit,
  };
  
  static int __init crypto_user_init(void)
  {
  	return register_pernet_subsys(&crypto_netlink_net_ops);
a38f7907b   Steffen Klassert   crypto: Add users...
465
466
467
468
  }
  
  static void __exit crypto_user_exit(void)
  {
91b05a7e7   Ondrej Mosnacek   crypto: user - ma...
469
  	unregister_pernet_subsys(&crypto_netlink_net_ops);
a38f7907b   Steffen Klassert   crypto: Add users...
470
471
472
473
474
475
476
  }
  
  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...
477
  MODULE_ALIAS("net-pf-16-proto-21");