Blame view

crypto/algapi.c 29.5 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
2
3
4
5
  /*
   * Cryptographic API for algorithms (i.e., low-level API).
   *
   * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
6
   */
13c935bb0   Salvatore Mesoraca   crypto: api - lay...
7
  #include <crypto/algapi.h>
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
8
  #include <linux/err.h>
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
9
  #include <linux/errno.h>
3133d76fc   Herbert Xu   crypto: api - Inc...
10
  #include <linux/fips.h>
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
11
12
  #include <linux/init.h>
  #include <linux/kernel.h>
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
13
  #include <linux/list.h>
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
14
  #include <linux/module.h>
7fed0bf27   Herbert Xu   [CRYPTO] api: Add...
15
  #include <linux/rtnetlink.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
16
  #include <linux/slab.h>
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
17
18
19
  #include <linux/string.h>
  
  #include "internal.h"
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
20
  static LIST_HEAD(crypto_template_list);
002c77a48   Jarod Wilson   crypto: fips - on...
21
22
  static inline void crypto_check_module_sig(struct module *mod)
  {
59afdc7b3   Herbert Xu   crypto: api - Mov...
23
  	if (fips_enabled && mod && !module_sig_ok(mod))
002c77a48   Jarod Wilson   crypto: fips - on...
24
25
  		panic("Module %s signature verification failed in FIPS mode
  ",
bd4a7c69a   Herbert Xu   crypto: api - Fix...
26
  		      module_name(mod));
002c77a48   Jarod Wilson   crypto: fips - on...
27
  }
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
28
  static int crypto_check_alg(struct crypto_alg *alg)
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
29
  {
002c77a48   Jarod Wilson   crypto: fips - on...
30
  	crypto_check_module_sig(alg->cra_module);
177f87d06   Eric Biggers   crypto: algapi - ...
31
32
  	if (!alg->cra_name[0] || !alg->cra_driver_name[0])
  		return -EINVAL;
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
33
34
  	if (alg->cra_alignmask & (alg->cra_alignmask + 1))
  		return -EINVAL;
a9f7f88a1   Kees Cook   crypto: api - Int...
35
36
  	/* General maximums for all algs. */
  	if (alg->cra_alignmask > MAX_ALGAPI_ALIGNMASK)
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
37
  		return -EINVAL;
a9f7f88a1   Kees Cook   crypto: api - Int...
38
39
40
41
  	if (alg->cra_blocksize > MAX_ALGAPI_BLOCKSIZE)
  		return -EINVAL;
  
  	/* Lower maximums for specific alg types. */
13c935bb0   Salvatore Mesoraca   crypto: api - lay...
42
43
44
45
46
47
48
49
  	if (!alg->cra_type && (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
  			       CRYPTO_ALG_TYPE_CIPHER) {
  		if (alg->cra_alignmask > MAX_CIPHER_ALIGNMASK)
  			return -EINVAL;
  
  		if (alg->cra_blocksize > MAX_CIPHER_BLOCKSIZE)
  			return -EINVAL;
  	}
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
50
51
  	if (alg->cra_priority < 0)
  		return -EINVAL;
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
52

ce8614a31   Eric Biggers   crypto: algapi - ...
53
  	refcount_set(&alg->cra_refcnt, 1);
e9b8e5beb   Herbert Xu   crypto: api - Mov...
54

177f87d06   Eric Biggers   crypto: algapi - ...
55
  	return 0;
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
56
  }
319382a69   Herbert Xu   crypto: api - Add...
57
58
  static void crypto_free_instance(struct crypto_instance *inst)
  {
319382a69   Herbert Xu   crypto: api - Add...
59
60
  	inst->alg.cra_type->free(inst);
  }
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
61
62
63
64
  static void crypto_destroy_instance(struct crypto_alg *alg)
  {
  	struct crypto_instance *inst = (void *)alg;
  	struct crypto_template *tmpl = inst->tmpl;
319382a69   Herbert Xu   crypto: api - Add...
65
  	crypto_free_instance(inst);
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
66
67
  	crypto_tmpl_put(tmpl);
  }
02244ba44   Herbert Xu   crypto: api - Add...
68
69
70
71
72
73
74
75
76
  /*
   * This function adds a spawn to the list secondary_spawns which
   * will be used at the end of crypto_remove_spawns to unregister
   * instances, unless the spawn happens to be one that is depended
   * on by the new algorithm (nalg in crypto_remove_spawns).
   *
   * This function is also responsible for resurrecting any algorithms
   * in the dependency chain of nalg by unsetting n->dead.
   */
2bf290166   Herbert Xu   crypto: api - Do ...
77
78
79
80
81
82
  static struct list_head *crypto_more_spawns(struct crypto_alg *alg,
  					    struct list_head *stack,
  					    struct list_head *top,
  					    struct list_head *secondary_spawns)
  {
  	struct crypto_spawn *spawn, *n;
304e4818d   Geliang Tang   crypto: api - use...
83
84
  	spawn = list_first_entry_or_null(stack, struct crypto_spawn, list);
  	if (!spawn)
2bf290166   Herbert Xu   crypto: api - Do ...
85
  		return NULL;
4f87ee118   Herbert Xu   crypto: api - Do ...
86
87
  	n = list_prev_entry(spawn, list);
  	list_move(&spawn->list, secondary_spawns);
2bf290166   Herbert Xu   crypto: api - Do ...
88

4f87ee118   Herbert Xu   crypto: api - Do ...
89
90
  	if (list_is_last(&n->list, stack))
  		return top;
2bf290166   Herbert Xu   crypto: api - Do ...
91

4f87ee118   Herbert Xu   crypto: api - Do ...
92
93
94
  	n = list_next_entry(n, list);
  	if (!spawn->dead)
  		n->dead = false;
2bf290166   Herbert Xu   crypto: api - Do ...
95

4f87ee118   Herbert Xu   crypto: api - Do ...
96
  	return &n->inst->alg.cra_users;
2bf290166   Herbert Xu   crypto: api - Do ...
97
  }
1f7237109   Herbert Xu   crypto: api - Fix...
98
99
  static void crypto_remove_instance(struct crypto_instance *inst,
  				   struct list_head *list)
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
100
  {
a73e69965   Herbert Xu   [CRYPTO] api: Do ...
101
  	struct crypto_template *tmpl = inst->tmpl;
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
102

a73e69965   Herbert Xu   [CRYPTO] api: Do ...
103
104
  	if (crypto_is_dead(&inst->alg))
  		return;
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
105

a73e69965   Herbert Xu   [CRYPTO] api: Do ...
106
  	inst->alg.cra_flags |= CRYPTO_ALG_DEAD;
38cb2419f   Herbert Xu   [CRYPTO] api: Fix...
107

a73e69965   Herbert Xu   [CRYPTO] api: Do ...
108
109
  	if (!tmpl || !crypto_tmpl_get(tmpl))
  		return;
a73e69965   Herbert Xu   [CRYPTO] api: Do ...
110
111
112
  	list_move(&inst->alg.cra_list, list);
  	hlist_del(&inst->list);
  	inst->alg.cra_destroy = crypto_destroy_instance;
2bf290166   Herbert Xu   crypto: api - Do ...
113
  	BUG_ON(!list_empty(&inst->alg.cra_users));
a73e69965   Herbert Xu   [CRYPTO] api: Do ...
114
  }
02244ba44   Herbert Xu   crypto: api - Add...
115
116
117
118
119
120
  /*
   * Given an algorithm alg, remove all algorithms that depend on it
   * through spawns.  If nalg is not null, then exempt any algorithms
   * that is depended on by nalg.  This is useful when nalg itself
   * depends on alg.
   */
89b596ba2   Steffen Klassert   crypto: Export cr...
121
122
  void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list,
  			  struct crypto_alg *nalg)
a73e69965   Herbert Xu   [CRYPTO] api: Do ...
123
  {
2bf290166   Herbert Xu   crypto: api - Do ...
124
  	u32 new_type = (nalg ?: alg)->cra_flags;
a73e69965   Herbert Xu   [CRYPTO] api: Do ...
125
126
  	struct crypto_spawn *spawn, *n;
  	LIST_HEAD(secondary_spawns);
2bf290166   Herbert Xu   crypto: api - Do ...
127
128
129
  	struct list_head *spawns;
  	LIST_HEAD(stack);
  	LIST_HEAD(top);
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
130

2bf290166   Herbert Xu   crypto: api - Do ...
131
  	spawns = &alg->cra_users;
a73e69965   Herbert Xu   [CRYPTO] api: Do ...
132
133
  	list_for_each_entry_safe(spawn, n, spawns, list) {
  		if ((spawn->alg->cra_flags ^ new_type) & spawn->mask)
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
134
  			continue;
2bf290166   Herbert Xu   crypto: api - Do ...
135
  		list_move(&spawn->list, &top);
a73e69965   Herbert Xu   [CRYPTO] api: Do ...
136
  	}
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
137

02244ba44   Herbert Xu   crypto: api - Add...
138
139
140
141
142
  	/*
  	 * Perform a depth-first walk starting from alg through
  	 * the cra_users tree.  The list stack records the path
  	 * from alg to the current spawn.
  	 */
2bf290166   Herbert Xu   crypto: api - Do ...
143
144
145
146
147
148
149
150
  	spawns = &top;
  	do {
  		while (!list_empty(spawns)) {
  			struct crypto_instance *inst;
  
  			spawn = list_first_entry(spawns, struct crypto_spawn,
  						 list);
  			inst = spawn->inst;
2bf290166   Herbert Xu   crypto: api - Do ...
151
  			list_move(&spawn->list, &stack);
5f567fffa   Herbert Xu   crypto: api - Ret...
152
153
154
155
156
157
  			spawn->dead = !spawn->registered || &inst->alg != nalg;
  
  			if (!spawn->registered)
  				break;
  
  			BUG_ON(&inst->alg == alg);
2bf290166   Herbert Xu   crypto: api - Do ...
158
159
160
  
  			if (&inst->alg == nalg)
  				break;
2bf290166   Herbert Xu   crypto: api - Do ...
161
  			spawns = &inst->alg.cra_users;
9a0067421   Eric Biggers   crypto: algapi - ...
162
163
  
  			/*
5f567fffa   Herbert Xu   crypto: api - Ret...
164
165
166
167
168
169
  			 * Even if spawn->registered is true, the
  			 * instance itself may still be unregistered.
  			 * This is because it may have failed during
  			 * registration.  Therefore we still need to
  			 * make the following test.
  			 *
9a0067421   Eric Biggers   crypto: algapi - ...
170
171
172
173
174
175
176
177
178
179
  			 * We may encounter an unregistered instance here, since
  			 * an instance's spawns are set up prior to the instance
  			 * being registered.  An unregistered instance will have
  			 * NULL ->cra_users.next, since ->cra_users isn't
  			 * properly initialized until registration.  But an
  			 * unregistered instance cannot have any users, so treat
  			 * it the same as ->cra_users being empty.
  			 */
  			if (spawns->next == NULL)
  				break;
2bf290166   Herbert Xu   crypto: api - Do ...
180
181
182
  		}
  	} while ((spawns = crypto_more_spawns(alg, &stack, &top,
  					      &secondary_spawns)));
02244ba44   Herbert Xu   crypto: api - Add...
183
184
185
186
187
  	/*
  	 * Remove all instances that are marked as dead.  Also
  	 * complete the resurrection of the others by moving them
  	 * back to the cra_users list.
  	 */
2bf290166   Herbert Xu   crypto: api - Do ...
188
  	list_for_each_entry_safe(spawn, n, &secondary_spawns, list) {
4f87ee118   Herbert Xu   crypto: api - Do ...
189
  		if (!spawn->dead)
2bf290166   Herbert Xu   crypto: api - Do ...
190
  			list_move(&spawn->list, &spawn->alg->cra_users);
5f567fffa   Herbert Xu   crypto: api - Ret...
191
  		else if (spawn->registered)
1f7237109   Herbert Xu   crypto: api - Fix...
192
  			crypto_remove_instance(spawn->inst, list);
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
193
194
  	}
  }
89b596ba2   Steffen Klassert   crypto: Export cr...
195
  EXPORT_SYMBOL_GPL(crypto_remove_spawns);
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
196

73d3864a4   Herbert Xu   crypto: api - Use...
197
  static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
198
199
  {
  	struct crypto_alg *q;
73d3864a4   Herbert Xu   crypto: api - Use...
200
  	struct crypto_larval *larval;
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
201
202
203
  	int ret = -EAGAIN;
  
  	if (crypto_is_dead(alg))
73d3864a4   Herbert Xu   crypto: api - Use...
204
  		goto err;
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
205
206
  
  	INIT_LIST_HEAD(&alg->cra_users);
73d3864a4   Herbert Xu   crypto: api - Use...
207
208
  	/* No cheating! */
  	alg->cra_flags &= ~CRYPTO_ALG_TESTED;
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
209
  	ret = -EEXIST;
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
210

cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
211
  	list_for_each_entry(q, &crypto_alg_list, cra_list) {
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
212
  		if (q == alg)
73d3864a4   Herbert Xu   crypto: api - Use...
213
  			goto err;
b8e15992b   Herbert Xu   crypto: api - Fix...
214
215
  		if (crypto_is_moribund(q))
  			continue;
73d3864a4   Herbert Xu   crypto: api - Use...
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
  		if (crypto_is_larval(q)) {
  			if (!strcmp(alg->cra_driver_name, q->cra_driver_name))
  				goto err;
  			continue;
  		}
  
  		if (!strcmp(q->cra_driver_name, alg->cra_name) ||
  		    !strcmp(q->cra_name, alg->cra_driver_name))
  			goto err;
  	}
  
  	larval = crypto_larval_alloc(alg->cra_name,
  				     alg->cra_flags | CRYPTO_ALG_TESTED, 0);
  	if (IS_ERR(larval))
  		goto out;
  
  	ret = -ENOENT;
  	larval->adult = crypto_mod_get(alg);
  	if (!larval->adult)
  		goto free_larval;
ce8614a31   Eric Biggers   crypto: algapi - ...
236
  	refcount_set(&larval->alg.cra_refcnt, 1);
73d3864a4   Herbert Xu   crypto: api - Use...
237
238
239
240
241
242
  	memcpy(larval->alg.cra_driver_name, alg->cra_driver_name,
  	       CRYPTO_MAX_ALG_NAME);
  	larval->alg.cra_priority = alg->cra_priority;
  
  	list_add(&alg->cra_list, &crypto_alg_list);
  	list_add(&larval->alg.cra_list, &crypto_alg_list);
1f6669b97   Corentin Labbe   crypto: user - Ad...
243
  	crypto_stats_init(alg);
cac5818c2   Corentin Labbe   crypto: user - Im...
244

5357c6c43   Richard Hartmann   crypto: algapi - ...
245
  out:
73d3864a4   Herbert Xu   crypto: api - Use...
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
  	return larval;
  
  free_larval:
  	kfree(larval);
  err:
  	larval = ERR_PTR(ret);
  	goto out;
  }
  
  void crypto_alg_tested(const char *name, int err)
  {
  	struct crypto_larval *test;
  	struct crypto_alg *alg;
  	struct crypto_alg *q;
  	LIST_HEAD(list);
2bbb3375d   Herbert Xu   crypto: api - fix...
261
  	bool best;
73d3864a4   Herbert Xu   crypto: api - Use...
262
263
264
  
  	down_write(&crypto_alg_sem);
  	list_for_each_entry(q, &crypto_alg_list, cra_list) {
b8e15992b   Herbert Xu   crypto: api - Fix...
265
  		if (crypto_is_moribund(q) || !crypto_is_larval(q))
73d3864a4   Herbert Xu   crypto: api - Use...
266
267
268
269
270
271
272
  			continue;
  
  		test = (struct crypto_larval *)q;
  
  		if (!strcmp(q->cra_driver_name, name))
  			goto found;
  	}
c72358571   Karim Eshapa   crypto: algapi - ...
273
274
  	pr_err("alg: Unexpected test result for %s: %d
  ", name, err);
73d3864a4   Herbert Xu   crypto: api - Use...
275
276
277
  	goto unlock;
  
  found:
b8e15992b   Herbert Xu   crypto: api - Fix...
278
  	q->cra_flags |= CRYPTO_ALG_DEAD;
73d3864a4   Herbert Xu   crypto: api - Use...
279
280
281
282
283
  	alg = test->adult;
  	if (err || list_empty(&alg->cra_list))
  		goto complete;
  
  	alg->cra_flags |= CRYPTO_ALG_TESTED;
2bbb3375d   Herbert Xu   crypto: api - fix...
284
285
286
287
288
289
290
291
292
293
294
295
296
297
  	/* Only satisfy larval waiters if we are the best. */
  	best = true;
  	list_for_each_entry(q, &crypto_alg_list, cra_list) {
  		if (crypto_is_moribund(q) || !crypto_is_larval(q))
  			continue;
  
  		if (strcmp(alg->cra_name, q->cra_name))
  			continue;
  
  		if (q->cra_priority > alg->cra_priority) {
  			best = false;
  			break;
  		}
  	}
73d3864a4   Herbert Xu   crypto: api - Use...
298
299
300
  	list_for_each_entry(q, &crypto_alg_list, cra_list) {
  		if (q == alg)
  			continue;
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
301
302
303
304
305
  
  		if (crypto_is_moribund(q))
  			continue;
  
  		if (crypto_is_larval(q)) {
2825982d9   Herbert Xu   [CRYPTO] api: Add...
306
  			struct crypto_larval *larval = (void *)q;
d8058480b   Herbert Xu   [CRYPTO] api: Exp...
307
308
309
310
311
  			/*
  			 * Check to see if either our generic name or
  			 * specific name can satisfy the name requested
  			 * by the larval entry q.
  			 */
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
312
313
314
315
316
317
  			if (strcmp(alg->cra_name, q->cra_name) &&
  			    strcmp(alg->cra_driver_name, q->cra_name))
  				continue;
  
  			if (larval->adult)
  				continue;
492e2b63e   Herbert Xu   [CRYPTO] api: All...
318
319
  			if ((q->cra_flags ^ alg->cra_flags) & larval->mask)
  				continue;
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
320

2bbb3375d   Herbert Xu   crypto: api - fix...
321
322
323
324
  			if (best && crypto_mod_get(alg))
  				larval->adult = alg;
  			else
  				larval->adult = ERR_PTR(-EAGAIN);
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
325
  			continue;
2825982d9   Herbert Xu   [CRYPTO] api: Add...
326
  		}
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
327
328
329
330
331
332
333
  
  		if (strcmp(alg->cra_name, q->cra_name))
  			continue;
  
  		if (strcmp(alg->cra_driver_name, q->cra_driver_name) &&
  		    q->cra_priority > alg->cra_priority)
  			continue;
2bf290166   Herbert Xu   crypto: api - Do ...
334
  		crypto_remove_spawns(q, &list, alg);
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
335
  	}
2825982d9   Herbert Xu   [CRYPTO] api: Add...
336

73d3864a4   Herbert Xu   crypto: api - Use...
337
338
  complete:
  	complete_all(&test->completion);
2825982d9   Herbert Xu   [CRYPTO] api: Add...
339

73d3864a4   Herbert Xu   crypto: api - Use...
340
341
342
343
  unlock:
  	up_write(&crypto_alg_sem);
  
  	crypto_remove_final(&list);
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
344
  }
73d3864a4   Herbert Xu   crypto: api - Use...
345
  EXPORT_SYMBOL_GPL(crypto_alg_tested);
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
346

22e5b20be   Steffen Klassert   crypto: Export cr...
347
  void crypto_remove_final(struct list_head *list)
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
348
349
350
351
352
353
354
355
356
  {
  	struct crypto_alg *alg;
  	struct crypto_alg *n;
  
  	list_for_each_entry_safe(alg, n, list, cra_list) {
  		list_del_init(&alg->cra_list);
  		crypto_alg_put(alg);
  	}
  }
22e5b20be   Steffen Klassert   crypto: Export cr...
357
  EXPORT_SYMBOL_GPL(crypto_remove_final);
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
358

73d3864a4   Herbert Xu   crypto: api - Use...
359
360
361
362
363
364
365
366
367
368
  static void crypto_wait_for_test(struct crypto_larval *larval)
  {
  	int err;
  
  	err = crypto_probing_notify(CRYPTO_MSG_ALG_REGISTER, larval->adult);
  	if (err != NOTIFY_STOP) {
  		if (WARN_ON(err != NOTIFY_DONE))
  			goto out;
  		crypto_alg_tested(larval->alg.cra_driver_name, 0);
  	}
3fc89adb9   Herbert Xu   crypto: api - Onl...
369
  	err = wait_for_completion_killable(&larval->completion);
73d3864a4   Herbert Xu   crypto: api - Use...
370
  	WARN_ON(err);
dd8b083f9   Martin K. Petersen   crypto: api - Int...
371
  	if (!err)
beeb460cd   Eric Biggers   crypto: algapi - ...
372
  		crypto_notify(CRYPTO_MSG_ALG_LOADED, larval);
73d3864a4   Herbert Xu   crypto: api - Use...
373
374
375
376
  
  out:
  	crypto_larval_kill(&larval->alg);
  }
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
377
378
  int crypto_register_alg(struct crypto_alg *alg)
  {
73d3864a4   Herbert Xu   crypto: api - Use...
379
  	struct crypto_larval *larval;
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
380
  	int err;
d6040764a   Salvatore Benedetto   crypto: api - Cle...
381
  	alg->cra_flags &= ~CRYPTO_ALG_DEAD;
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
382
383
384
385
386
  	err = crypto_check_alg(alg);
  	if (err)
  		return err;
  
  	down_write(&crypto_alg_sem);
73d3864a4   Herbert Xu   crypto: api - Use...
387
  	larval = __crypto_register_alg(alg);
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
388
  	up_write(&crypto_alg_sem);
73d3864a4   Herbert Xu   crypto: api - Use...
389
390
391
392
393
  	if (IS_ERR(larval))
  		return PTR_ERR(larval);
  
  	crypto_wait_for_test(larval);
  	return 0;
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
394
  }
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
395
  EXPORT_SYMBOL_GPL(crypto_register_alg);
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
396
397
398
399
400
401
  static int crypto_remove_alg(struct crypto_alg *alg, struct list_head *list)
  {
  	if (unlikely(list_empty(&alg->cra_list)))
  		return -ENOENT;
  
  	alg->cra_flags |= CRYPTO_ALG_DEAD;
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
402
  	list_del_init(&alg->cra_list);
2bf290166   Herbert Xu   crypto: api - Do ...
403
  	crypto_remove_spawns(alg, list, NULL);
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
404
405
406
  
  	return 0;
  }
c6d633a92   Eric Biggers   crypto: algapi - ...
407
  void crypto_unregister_alg(struct crypto_alg *alg)
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
408
  {
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
409
410
  	int ret;
  	LIST_HEAD(list);
5357c6c43   Richard Hartmann   crypto: algapi - ...
411

cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
412
  	down_write(&crypto_alg_sem);
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
413
  	ret = crypto_remove_alg(alg, &list);
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
414
  	up_write(&crypto_alg_sem);
c6d633a92   Eric Biggers   crypto: algapi - ...
415
416
  	if (WARN(ret, "Algorithm %s is not registered", alg->cra_driver_name))
  		return;
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
417

ce8614a31   Eric Biggers   crypto: algapi - ...
418
  	BUG_ON(refcount_read(&alg->cra_refcnt) != 1);
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
419
420
  	if (alg->cra_destroy)
  		alg->cra_destroy(alg);
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
421
  	crypto_remove_final(&list);
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
422
423
  }
  EXPORT_SYMBOL_GPL(crypto_unregister_alg);
4b004346f   Mark Brown   crypto: Add bulk ...
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
  int crypto_register_algs(struct crypto_alg *algs, int count)
  {
  	int i, ret;
  
  	for (i = 0; i < count; i++) {
  		ret = crypto_register_alg(&algs[i]);
  		if (ret)
  			goto err;
  	}
  
  	return 0;
  
  err:
  	for (--i; i >= 0; --i)
  		crypto_unregister_alg(&algs[i]);
  
  	return ret;
  }
  EXPORT_SYMBOL_GPL(crypto_register_algs);
c6d633a92   Eric Biggers   crypto: algapi - ...
443
  void crypto_unregister_algs(struct crypto_alg *algs, int count)
4b004346f   Mark Brown   crypto: Add bulk ...
444
  {
c6d633a92   Eric Biggers   crypto: algapi - ...
445
  	int i;
4b004346f   Mark Brown   crypto: Add bulk ...
446

c6d633a92   Eric Biggers   crypto: algapi - ...
447
448
  	for (i = 0; i < count; i++)
  		crypto_unregister_alg(&algs[i]);
4b004346f   Mark Brown   crypto: Add bulk ...
449
450
  }
  EXPORT_SYMBOL_GPL(crypto_unregister_algs);
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
451
452
453
454
455
456
  int crypto_register_template(struct crypto_template *tmpl)
  {
  	struct crypto_template *q;
  	int err = -EEXIST;
  
  	down_write(&crypto_alg_sem);
002c77a48   Jarod Wilson   crypto: fips - on...
457
  	crypto_check_module_sig(tmpl->module);
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
458
459
460
461
462
463
464
465
466
467
468
469
  	list_for_each_entry(q, &crypto_template_list, list) {
  		if (q == tmpl)
  			goto out;
  	}
  
  	list_add(&tmpl->list, &crypto_template_list);
  	err = 0;
  out:
  	up_write(&crypto_alg_sem);
  	return err;
  }
  EXPORT_SYMBOL_GPL(crypto_register_template);
9572442dc   Xiongfeng Wang   crypto: api - add...
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
  int crypto_register_templates(struct crypto_template *tmpls, int count)
  {
  	int i, err;
  
  	for (i = 0; i < count; i++) {
  		err = crypto_register_template(&tmpls[i]);
  		if (err)
  			goto out;
  	}
  	return 0;
  
  out:
  	for (--i; i >= 0; --i)
  		crypto_unregister_template(&tmpls[i]);
  	return err;
  }
  EXPORT_SYMBOL_GPL(crypto_register_templates);
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
487
488
489
  void crypto_unregister_template(struct crypto_template *tmpl)
  {
  	struct crypto_instance *inst;
b67bfe0d4   Sasha Levin   hlist: drop the n...
490
  	struct hlist_node *n;
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
491
  	struct hlist_head *list;
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
492
  	LIST_HEAD(users);
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
493
494
495
496
497
498
499
  
  	down_write(&crypto_alg_sem);
  
  	BUG_ON(list_empty(&tmpl->list));
  	list_del_init(&tmpl->list);
  
  	list = &tmpl->instances;
b67bfe0d4   Sasha Levin   hlist: drop the n...
500
  	hlist_for_each_entry(inst, list, list) {
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
501
  		int err = crypto_remove_alg(&inst->alg, &users);
0efcb8d5b   Joshua I. James   crypto: api - fix...
502

6bfd48096   Herbert Xu   [CRYPTO] api: Add...
503
  		BUG_ON(err);
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
504
505
506
  	}
  
  	up_write(&crypto_alg_sem);
b67bfe0d4   Sasha Levin   hlist: drop the n...
507
  	hlist_for_each_entry_safe(inst, n, list, list) {
ce8614a31   Eric Biggers   crypto: algapi - ...
508
  		BUG_ON(refcount_read(&inst->alg.cra_refcnt) != 1);
319382a69   Herbert Xu   crypto: api - Add...
509
  		crypto_free_instance(inst);
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
510
  	}
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
511
  	crypto_remove_final(&users);
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
512
513
  }
  EXPORT_SYMBOL_GPL(crypto_unregister_template);
9572442dc   Xiongfeng Wang   crypto: api - add...
514
515
516
517
518
519
520
521
  void crypto_unregister_templates(struct crypto_template *tmpls, int count)
  {
  	int i;
  
  	for (i = count - 1; i >= 0; --i)
  		crypto_unregister_template(&tmpls[i]);
  }
  EXPORT_SYMBOL_GPL(crypto_unregister_templates);
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
  static struct crypto_template *__crypto_lookup_template(const char *name)
  {
  	struct crypto_template *q, *tmpl = NULL;
  
  	down_read(&crypto_alg_sem);
  	list_for_each_entry(q, &crypto_template_list, list) {
  		if (strcmp(q->name, name))
  			continue;
  		if (unlikely(!crypto_tmpl_get(q)))
  			continue;
  
  		tmpl = q;
  		break;
  	}
  	up_read(&crypto_alg_sem);
  
  	return tmpl;
  }
  
  struct crypto_template *crypto_lookup_template(const char *name)
  {
4943ba16b   Kees Cook   crypto: include c...
543
544
  	return try_then_request_module(__crypto_lookup_template(name),
  				       "crypto-%s", name);
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
545
546
547
548
549
550
  }
  EXPORT_SYMBOL_GPL(crypto_lookup_template);
  
  int crypto_register_instance(struct crypto_template *tmpl,
  			     struct crypto_instance *inst)
  {
73d3864a4   Herbert Xu   crypto: api - Use...
551
  	struct crypto_larval *larval;
5f567fffa   Herbert Xu   crypto: api - Ret...
552
  	struct crypto_spawn *spawn;
73d3864a4   Herbert Xu   crypto: api - Use...
553
  	int err;
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
554

4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
555
556
  	err = crypto_check_alg(&inst->alg);
  	if (err)
9c521a200   Stephan Mueller   crypto: api - rem...
557
  		return err;
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
558
  	inst->alg.cra_module = tmpl->module;
64a947b13   Steffen Klassert   crypto: Add a fla...
559
  	inst->alg.cra_flags |= CRYPTO_ALG_INSTANCE;
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
560
561
  
  	down_write(&crypto_alg_sem);
5f567fffa   Herbert Xu   crypto: api - Ret...
562
563
564
565
566
567
568
569
570
571
  	larval = ERR_PTR(-EAGAIN);
  	for (spawn = inst->spawns; spawn;) {
  		struct crypto_spawn *next;
  
  		if (spawn->dead)
  			goto unlock;
  
  		next = spawn->next;
  		spawn->inst = inst;
  		spawn->registered = true;
aed11cf57   Eric Biggers   crypto: algapi - ...
572
  		crypto_mod_put(spawn->alg);
5f567fffa   Herbert Xu   crypto: api - Ret...
573
574
575
  
  		spawn = next;
  	}
73d3864a4   Herbert Xu   crypto: api - Use...
576
577
  	larval = __crypto_register_alg(&inst->alg);
  	if (IS_ERR(larval))
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
578
579
580
581
582
583
584
  		goto unlock;
  
  	hlist_add_head(&inst->list, &tmpl->instances);
  	inst->tmpl = tmpl;
  
  unlock:
  	up_write(&crypto_alg_sem);
73d3864a4   Herbert Xu   crypto: api - Use...
585
586
587
588
589
590
  	err = PTR_ERR(larval);
  	if (IS_ERR(larval))
  		goto err;
  
  	crypto_wait_for_test(larval);
  	err = 0;
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
591

4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
592
593
594
595
  err:
  	return err;
  }
  EXPORT_SYMBOL_GPL(crypto_register_instance);
ce3fd840f   Steffen Klassert   crypto: Unlink an...
596

c6d633a92   Eric Biggers   crypto: algapi - ...
597
  void crypto_unregister_instance(struct crypto_instance *inst)
ce3fd840f   Steffen Klassert   crypto: Unlink an...
598
  {
1f7237109   Herbert Xu   crypto: api - Fix...
599
  	LIST_HEAD(list);
ce3fd840f   Steffen Klassert   crypto: Unlink an...
600

ce3fd840f   Steffen Klassert   crypto: Unlink an...
601
  	down_write(&crypto_alg_sem);
87b167563   Herbert Xu   crypto: api - Cha...
602
  	crypto_remove_spawns(&inst->alg, &list, NULL);
1f7237109   Herbert Xu   crypto: api - Fix...
603
  	crypto_remove_instance(inst, &list);
ce3fd840f   Steffen Klassert   crypto: Unlink an...
604
605
  
  	up_write(&crypto_alg_sem);
1f7237109   Herbert Xu   crypto: api - Fix...
606
  	crypto_remove_final(&list);
ce3fd840f   Steffen Klassert   crypto: Unlink an...
607
608
  }
  EXPORT_SYMBOL_GPL(crypto_unregister_instance);
4cc7720cd   Herbert Xu   [CRYPTO] api: Add...
609

aed11cf57   Eric Biggers   crypto: algapi - ...
610
611
  int crypto_grab_spawn(struct crypto_spawn *spawn, struct crypto_instance *inst,
  		      const char *name, u32 type, u32 mask)
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
612
  {
aed11cf57   Eric Biggers   crypto: algapi - ...
613
  	struct crypto_alg *alg;
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
614
  	int err = -EAGAIN;
6b476662b   Eric Biggers   crypto: algapi - ...
615
616
  	if (WARN_ON_ONCE(inst == NULL))
  		return -EINVAL;
aed11cf57   Eric Biggers   crypto: algapi - ...
617
618
619
  	/* Allow the result of crypto_attr_alg_name() to be passed directly */
  	if (IS_ERR(name))
  		return PTR_ERR(name);
5f567fffa   Herbert Xu   crypto: api - Ret...
620

aed11cf57   Eric Biggers   crypto: algapi - ...
621
622
623
  	alg = crypto_find_alg(name, spawn->frontend, type, mask);
  	if (IS_ERR(alg))
  		return PTR_ERR(alg);
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
624
625
626
627
628
  
  	down_write(&crypto_alg_sem);
  	if (!crypto_is_moribund(alg)) {
  		list_add(&spawn->list, &alg->cra_users);
  		spawn->alg = alg;
aed11cf57   Eric Biggers   crypto: algapi - ...
629
630
631
  		spawn->mask = mask;
  		spawn->next = inst->spawns;
  		inst->spawns = spawn;
7bcb2c99f   Eric Biggers   crypto: algapi - ...
632
633
  		inst->alg.cra_flags |=
  			(alg->cra_flags & CRYPTO_ALG_INHERITED_FLAGS);
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
634
635
636
  		err = 0;
  	}
  	up_write(&crypto_alg_sem);
5f567fffa   Herbert Xu   crypto: api - Ret...
637
638
  	if (err)
  		crypto_mod_put(alg);
d6ef2f198   Herbert Xu   crypto: api - Add...
639
640
641
  	return err;
  }
  EXPORT_SYMBOL_GPL(crypto_grab_spawn);
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
642
643
  void crypto_drop_spawn(struct crypto_spawn *spawn)
  {
ff6706279   Eric Biggers   crypto: algapi - ...
644
645
  	if (!spawn->alg) /* not yet initialized? */
  		return;
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
646
  	down_write(&crypto_alg_sem);
4f87ee118   Herbert Xu   crypto: api - Do ...
647
  	if (!spawn->dead)
7db3b61b6   Herbert Xu   crypto: api - Che...
648
  		list_del(&spawn->list);
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
649
  	up_write(&crypto_alg_sem);
5f567fffa   Herbert Xu   crypto: api - Ret...
650

aed11cf57   Eric Biggers   crypto: algapi - ...
651
  	if (!spawn->registered)
5f567fffa   Herbert Xu   crypto: api - Ret...
652
  		crypto_mod_put(spawn->alg);
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
653
654
  }
  EXPORT_SYMBOL_GPL(crypto_drop_spawn);
97eedce1a   Herbert Xu   crypto: api - Add...
655
  static struct crypto_alg *crypto_spawn_alg(struct crypto_spawn *spawn)
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
656
  {
6603523bf   Herbert Xu   crypto: api - Fix...
657
658
659
  	struct crypto_alg *alg = ERR_PTR(-EAGAIN);
  	struct crypto_alg *target;
  	bool shoot = false;
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
660
661
  
  	down_read(&crypto_alg_sem);
6603523bf   Herbert Xu   crypto: api - Fix...
662
663
664
665
666
667
668
  	if (!spawn->dead) {
  		alg = spawn->alg;
  		if (!crypto_mod_get(alg)) {
  			target = crypto_alg_get(alg);
  			shoot = true;
  			alg = ERR_PTR(-EAGAIN);
  		}
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
669
  	}
73669cc55   Herbert Xu   crypto: api - Fix...
670
  	up_read(&crypto_alg_sem);
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
671

6603523bf   Herbert Xu   crypto: api - Fix...
672
673
674
675
676
677
  	if (shoot) {
  		crypto_shoot_alg(target);
  		crypto_alg_put(target);
  	}
  
  	return alg;
97eedce1a   Herbert Xu   crypto: api - Add...
678
679
680
681
682
683
684
685
686
687
688
  }
  
  struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type,
  				    u32 mask)
  {
  	struct crypto_alg *alg;
  	struct crypto_tfm *tfm;
  
  	alg = crypto_spawn_alg(spawn);
  	if (IS_ERR(alg))
  		return ERR_CAST(alg);
2e306ee01   Herbert Xu   [CRYPTO] api: Add...
689
690
691
  	tfm = ERR_PTR(-EINVAL);
  	if (unlikely((alg->cra_flags ^ type) & mask))
  		goto out_put_alg;
27d2a3300   Herbert Xu   [CRYPTO] api: All...
692
  	tfm = __crypto_alloc_tfm(alg, type, mask);
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
693
  	if (IS_ERR(tfm))
2e306ee01   Herbert Xu   [CRYPTO] api: Add...
694
695
696
  		goto out_put_alg;
  
  	return tfm;
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
697

2e306ee01   Herbert Xu   [CRYPTO] api: Add...
698
699
  out_put_alg:
  	crypto_mod_put(alg);
6bfd48096   Herbert Xu   [CRYPTO] api: Add...
700
701
702
  	return tfm;
  }
  EXPORT_SYMBOL_GPL(crypto_spawn_tfm);
97eedce1a   Herbert Xu   crypto: api - Add...
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
  void *crypto_spawn_tfm2(struct crypto_spawn *spawn)
  {
  	struct crypto_alg *alg;
  	struct crypto_tfm *tfm;
  
  	alg = crypto_spawn_alg(spawn);
  	if (IS_ERR(alg))
  		return ERR_CAST(alg);
  
  	tfm = crypto_create_tfm(alg, spawn->frontend);
  	if (IS_ERR(tfm))
  		goto out_put_alg;
  
  	return tfm;
  
  out_put_alg:
  	crypto_mod_put(alg);
  	return tfm;
  }
  EXPORT_SYMBOL_GPL(crypto_spawn_tfm2);
2825982d9   Herbert Xu   [CRYPTO] api: Add...
723
724
725
726
727
728
729
730
731
732
733
  int crypto_register_notifier(struct notifier_block *nb)
  {
  	return blocking_notifier_chain_register(&crypto_chain, nb);
  }
  EXPORT_SYMBOL_GPL(crypto_register_notifier);
  
  int crypto_unregister_notifier(struct notifier_block *nb)
  {
  	return blocking_notifier_chain_unregister(&crypto_chain, nb);
  }
  EXPORT_SYMBOL_GPL(crypto_unregister_notifier);
ebc610e5b   Herbert Xu   [CRYPTO] template...
734
  struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb)
7fed0bf27   Herbert Xu   [CRYPTO] api: Add...
735
  {
39e1ee011   Herbert Xu   [CRYPTO] api: Add...
736
  	struct rtattr *rta = tb[0];
ebc610e5b   Herbert Xu   [CRYPTO] template...
737
738
739
740
741
742
  	struct crypto_attr_type *algt;
  
  	if (!rta)
  		return ERR_PTR(-ENOENT);
  	if (RTA_PAYLOAD(rta) < sizeof(*algt))
  		return ERR_PTR(-EINVAL);
39e1ee011   Herbert Xu   [CRYPTO] api: Add...
743
744
  	if (rta->rta_type != CRYPTOA_TYPE)
  		return ERR_PTR(-EINVAL);
ebc610e5b   Herbert Xu   [CRYPTO] template...
745
746
747
748
749
750
  
  	algt = RTA_DATA(rta);
  
  	return algt;
  }
  EXPORT_SYMBOL_GPL(crypto_get_attr_type);
7bcb2c99f   Eric Biggers   crypto: algapi - ...
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
  /**
   * crypto_check_attr_type() - check algorithm type and compute inherited mask
   * @tb: the template parameters
   * @type: the algorithm type the template would be instantiated as
   * @mask_ret: (output) the mask that should be passed to crypto_grab_*()
   *	      to restrict the flags of any inner algorithms
   *
   * Validate that the algorithm type the user requested is compatible with the
   * one the template would actually be instantiated as.  E.g., if the user is
   * doing crypto_alloc_shash("cbc(aes)", ...), this would return an error because
   * the "cbc" template creates an "skcipher" algorithm, not an "shash" algorithm.
   *
   * Also compute the mask to use to restrict the flags of any inner algorithms.
   *
   * Return: 0 on success; -errno on failure
   */
  int crypto_check_attr_type(struct rtattr **tb, u32 type, u32 *mask_ret)
ebc610e5b   Herbert Xu   [CRYPTO] template...
768
769
770
771
772
773
774
775
776
  {
  	struct crypto_attr_type *algt;
  
  	algt = crypto_get_attr_type(tb);
  	if (IS_ERR(algt))
  		return PTR_ERR(algt);
  
  	if ((algt->type ^ type) & algt->mask)
  		return -EINVAL;
7bcb2c99f   Eric Biggers   crypto: algapi - ...
777
  	*mask_ret = crypto_algt_inherited_mask(algt);
ebc610e5b   Herbert Xu   [CRYPTO] template...
778
779
780
  	return 0;
  }
  EXPORT_SYMBOL_GPL(crypto_check_attr_type);
68b6c7d69   Herbert Xu   [CRYPTO] api: Add...
781
  const char *crypto_attr_alg_name(struct rtattr *rta)
ebc610e5b   Herbert Xu   [CRYPTO] template...
782
  {
7fed0bf27   Herbert Xu   [CRYPTO] api: Add...
783
  	struct crypto_attr_alg *alga;
ebc610e5b   Herbert Xu   [CRYPTO] template...
784
785
786
  	if (!rta)
  		return ERR_PTR(-ENOENT);
  	if (RTA_PAYLOAD(rta) < sizeof(*alga))
7fed0bf27   Herbert Xu   [CRYPTO] api: Add...
787
  		return ERR_PTR(-EINVAL);
39e1ee011   Herbert Xu   [CRYPTO] api: Add...
788
789
  	if (rta->rta_type != CRYPTOA_ALG)
  		return ERR_PTR(-EINVAL);
7fed0bf27   Herbert Xu   [CRYPTO] api: Add...
790
791
792
  
  	alga = RTA_DATA(rta);
  	alga->name[CRYPTO_MAX_ALG_NAME - 1] = 0;
68b6c7d69   Herbert Xu   [CRYPTO] api: Add...
793
794
795
  	return alga->name;
  }
  EXPORT_SYMBOL_GPL(crypto_attr_alg_name);
3c09f17c3   Herbert Xu   [CRYPTO] aead: Ad...
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
  int crypto_attr_u32(struct rtattr *rta, u32 *num)
  {
  	struct crypto_attr_u32 *nu32;
  
  	if (!rta)
  		return -ENOENT;
  	if (RTA_PAYLOAD(rta) < sizeof(*nu32))
  		return -EINVAL;
  	if (rta->rta_type != CRYPTOA_U32)
  		return -EINVAL;
  
  	nu32 = RTA_DATA(rta);
  	*num = nu32->num;
  
  	return 0;
  }
  EXPORT_SYMBOL_GPL(crypto_attr_u32);
7fed0bf27   Herbert Xu   [CRYPTO] api: Add...
813

32f27c745   Herbert Xu   crypto: api - Add...
814
815
816
817
818
819
820
821
822
823
824
825
826
827
  int crypto_inst_setname(struct crypto_instance *inst, const char *name,
  			struct crypto_alg *alg)
  {
  	if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, "%s(%s)", name,
  		     alg->cra_name) >= CRYPTO_MAX_ALG_NAME)
  		return -ENAMETOOLONG;
  
  	if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s(%s)",
  		     name, alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
  		return -ENAMETOOLONG;
  
  	return 0;
  }
  EXPORT_SYMBOL_GPL(crypto_inst_setname);
b5b7f0886   Herbert Xu   [CRYPTO] api: Add...
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
  void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen)
  {
  	INIT_LIST_HEAD(&queue->list);
  	queue->backlog = &queue->list;
  	queue->qlen = 0;
  	queue->max_qlen = max_qlen;
  }
  EXPORT_SYMBOL_GPL(crypto_init_queue);
  
  int crypto_enqueue_request(struct crypto_queue *queue,
  			   struct crypto_async_request *request)
  {
  	int err = -EINPROGRESS;
  
  	if (unlikely(queue->qlen >= queue->max_qlen)) {
6b80ea389   Gilad Ben-Yossef   crypto: change tr...
843
844
  		if (!(request->flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
  			err = -ENOSPC;
b5b7f0886   Herbert Xu   [CRYPTO] api: Add...
845
  			goto out;
6b80ea389   Gilad Ben-Yossef   crypto: change tr...
846
847
  		}
  		err = -EBUSY;
b5b7f0886   Herbert Xu   [CRYPTO] api: Add...
848
849
850
851
852
853
854
855
856
857
858
  		if (queue->backlog == &queue->list)
  			queue->backlog = &request->list;
  	}
  
  	queue->qlen++;
  	list_add_tail(&request->list, &queue->list);
  
  out:
  	return err;
  }
  EXPORT_SYMBOL_GPL(crypto_enqueue_request);
ec6e2bf33   Iuliana Prodan   crypto: algapi - ...
859
860
861
862
863
864
865
  void crypto_enqueue_request_head(struct crypto_queue *queue,
  				 struct crypto_async_request *request)
  {
  	queue->qlen++;
  	list_add(&request->list, &queue->list);
  }
  EXPORT_SYMBOL_GPL(crypto_enqueue_request_head);
31d228cc6   Herbert Xu   crypto: api - Rem...
866
  struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
b5b7f0886   Herbert Xu   [CRYPTO] api: Add...
867
868
869
870
871
872
873
874
875
876
877
878
879
  {
  	struct list_head *request;
  
  	if (unlikely(!queue->qlen))
  		return NULL;
  
  	queue->qlen--;
  
  	if (queue->backlog != &queue->list)
  		queue->backlog = queue->backlog->next;
  
  	request = queue->list.next;
  	list_del(request);
31d228cc6   Herbert Xu   crypto: api - Rem...
880
  	return list_entry(request, struct crypto_async_request, list);
b5b7f0886   Herbert Xu   [CRYPTO] api: Add...
881
882
  }
  EXPORT_SYMBOL_GPL(crypto_dequeue_request);
7613636de   Herbert Xu   [CRYPTO] api: Add...
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
  static inline void crypto_inc_byte(u8 *a, unsigned int size)
  {
  	u8 *b = (a + size);
  	u8 c;
  
  	for (; size; size--) {
  		c = *--b + 1;
  		*b = c;
  		if (c)
  			break;
  	}
  }
  
  void crypto_inc(u8 *a, unsigned int size)
  {
  	__be32 *b = (__be32 *)(a + size);
  	u32 c;
db91af0fb   Ard Biesheuvel   crypto: algapi - ...
900
  	if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ||
27c539aef   Ard Biesheuvel   crypto: algapi - ...
901
  	    IS_ALIGNED((unsigned long)b, __alignof__(*b)))
db91af0fb   Ard Biesheuvel   crypto: algapi - ...
902
903
904
  		for (; size >= 4; size -= 4) {
  			c = be32_to_cpu(*--b) + 1;
  			*b = cpu_to_be32(c);
27c539aef   Ard Biesheuvel   crypto: algapi - ...
905
  			if (likely(c))
db91af0fb   Ard Biesheuvel   crypto: algapi - ...
906
907
  				return;
  		}
7613636de   Herbert Xu   [CRYPTO] api: Add...
908
909
910
911
  
  	crypto_inc_byte(a, size);
  }
  EXPORT_SYMBOL_GPL(crypto_inc);
a7c391f04   Ard Biesheuvel   crypto: algapi - ...
912
  void __crypto_xor(u8 *dst, const u8 *src1, const u8 *src2, unsigned int len)
7613636de   Herbert Xu   [CRYPTO] api: Add...
913
  {
db91af0fb   Ard Biesheuvel   crypto: algapi - ...
914
915
916
917
  	int relalign = 0;
  
  	if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
  		int size = sizeof(unsigned long);
a7c391f04   Ard Biesheuvel   crypto: algapi - ...
918
919
920
  		int d = (((unsigned long)dst ^ (unsigned long)src1) |
  			 ((unsigned long)dst ^ (unsigned long)src2)) &
  			(size - 1);
db91af0fb   Ard Biesheuvel   crypto: algapi - ...
921
922
923
924
925
926
927
928
929
930
  
  		relalign = d ? 1 << __ffs(d) : size;
  
  		/*
  		 * If we care about alignment, process as many bytes as
  		 * needed to advance dst and src to values whose alignments
  		 * equal their relative alignment. This will allow us to
  		 * process the remainder of the input using optimal strides.
  		 */
  		while (((unsigned long)dst & (relalign - 1)) && len > 0) {
a7c391f04   Ard Biesheuvel   crypto: algapi - ...
931
  			*dst++ = *src1++ ^ *src2++;
db91af0fb   Ard Biesheuvel   crypto: algapi - ...
932
933
934
  			len--;
  		}
  	}
7613636de   Herbert Xu   [CRYPTO] api: Add...
935

db91af0fb   Ard Biesheuvel   crypto: algapi - ...
936
  	while (IS_ENABLED(CONFIG_64BIT) && len >= 8 && !(relalign & 7)) {
a7c391f04   Ard Biesheuvel   crypto: algapi - ...
937
  		*(u64 *)dst = *(u64 *)src1 ^  *(u64 *)src2;
db91af0fb   Ard Biesheuvel   crypto: algapi - ...
938
  		dst += 8;
a7c391f04   Ard Biesheuvel   crypto: algapi - ...
939
940
  		src1 += 8;
  		src2 += 8;
db91af0fb   Ard Biesheuvel   crypto: algapi - ...
941
942
  		len -= 8;
  	}
7613636de   Herbert Xu   [CRYPTO] api: Add...
943

db91af0fb   Ard Biesheuvel   crypto: algapi - ...
944
  	while (len >= 4 && !(relalign & 3)) {
a7c391f04   Ard Biesheuvel   crypto: algapi - ...
945
  		*(u32 *)dst = *(u32 *)src1 ^ *(u32 *)src2;
db91af0fb   Ard Biesheuvel   crypto: algapi - ...
946
  		dst += 4;
a7c391f04   Ard Biesheuvel   crypto: algapi - ...
947
948
  		src1 += 4;
  		src2 += 4;
db91af0fb   Ard Biesheuvel   crypto: algapi - ...
949
950
951
952
  		len -= 4;
  	}
  
  	while (len >= 2 && !(relalign & 1)) {
a7c391f04   Ard Biesheuvel   crypto: algapi - ...
953
  		*(u16 *)dst = *(u16 *)src1 ^ *(u16 *)src2;
db91af0fb   Ard Biesheuvel   crypto: algapi - ...
954
  		dst += 2;
a7c391f04   Ard Biesheuvel   crypto: algapi - ...
955
956
  		src1 += 2;
  		src2 += 2;
db91af0fb   Ard Biesheuvel   crypto: algapi - ...
957
958
  		len -= 2;
  	}
7613636de   Herbert Xu   [CRYPTO] api: Add...
959

db91af0fb   Ard Biesheuvel   crypto: algapi - ...
960
  	while (len--)
a7c391f04   Ard Biesheuvel   crypto: algapi - ...
961
  		*dst++ = *src1++ ^ *src2++;
7613636de   Herbert Xu   [CRYPTO] api: Add...
962
  }
db91af0fb   Ard Biesheuvel   crypto: algapi - ...
963
  EXPORT_SYMBOL_GPL(__crypto_xor);
7613636de   Herbert Xu   [CRYPTO] api: Add...
964

38d214331   Herbert Xu   crypto: api - Add...
965
966
  unsigned int crypto_alg_extsize(struct crypto_alg *alg)
  {
c2110f283   Herbert Xu   crypto: api - Inc...
967
968
  	return alg->cra_ctxsize +
  	       (alg->cra_alignmask & ~(crypto_tfm_ctx_alignment() - 1));
38d214331   Herbert Xu   crypto: api - Add...
969
970
  }
  EXPORT_SYMBOL_GPL(crypto_alg_extsize);
f2aefdab5   Herbert Xu   crypto: api - Add...
971
972
973
974
975
976
977
978
979
980
981
982
983
984
  int crypto_type_has_alg(const char *name, const struct crypto_type *frontend,
  			u32 type, u32 mask)
  {
  	int ret = 0;
  	struct crypto_alg *alg = crypto_find_alg(name, frontend, type, mask);
  
  	if (!IS_ERR(alg)) {
  		crypto_mod_put(alg);
  		ret = 1;
  	}
  
  	return ret;
  }
  EXPORT_SYMBOL_GPL(crypto_type_has_alg);
f7d76e05d   Corentin Labbe   crypto: user - fi...
985
  #ifdef CONFIG_CRYPTO_STATS
1f6669b97   Corentin Labbe   crypto: user - Ad...
986
987
988
989
990
  void crypto_stats_init(struct crypto_alg *alg)
  {
  	memset(&alg->stats, 0, sizeof(alg->stats));
  }
  EXPORT_SYMBOL_GPL(crypto_stats_init);
f7d76e05d   Corentin Labbe   crypto: user - fi...
991
992
993
994
995
  void crypto_stats_get(struct crypto_alg *alg)
  {
  	crypto_alg_get(alg);
  }
  EXPORT_SYMBOL_GPL(crypto_stats_get);
f7d76e05d   Corentin Labbe   crypto: user - fi...
996
997
998
999
  void crypto_stats_aead_encrypt(unsigned int cryptlen, struct crypto_alg *alg,
  			       int ret)
  {
  	if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
44f13133c   Corentin Labbe   crypto: user - re...
1000
  		atomic64_inc(&alg->stats.aead.err_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1001
  	} else {
17c18f9e3   Corentin Labbe   crypto: user - Sp...
1002
1003
  		atomic64_inc(&alg->stats.aead.encrypt_cnt);
  		atomic64_add(cryptlen, &alg->stats.aead.encrypt_tlen);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1004
1005
1006
1007
1008
1009
1010
1011
1012
  	}
  	crypto_alg_put(alg);
  }
  EXPORT_SYMBOL_GPL(crypto_stats_aead_encrypt);
  
  void crypto_stats_aead_decrypt(unsigned int cryptlen, struct crypto_alg *alg,
  			       int ret)
  {
  	if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
44f13133c   Corentin Labbe   crypto: user - re...
1013
  		atomic64_inc(&alg->stats.aead.err_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1014
  	} else {
17c18f9e3   Corentin Labbe   crypto: user - Sp...
1015
1016
  		atomic64_inc(&alg->stats.aead.decrypt_cnt);
  		atomic64_add(cryptlen, &alg->stats.aead.decrypt_tlen);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1017
1018
1019
1020
1021
1022
1023
1024
1025
  	}
  	crypto_alg_put(alg);
  }
  EXPORT_SYMBOL_GPL(crypto_stats_aead_decrypt);
  
  void crypto_stats_akcipher_encrypt(unsigned int src_len, int ret,
  				   struct crypto_alg *alg)
  {
  	if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
44f13133c   Corentin Labbe   crypto: user - re...
1026
  		atomic64_inc(&alg->stats.akcipher.err_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1027
  	} else {
17c18f9e3   Corentin Labbe   crypto: user - Sp...
1028
1029
  		atomic64_inc(&alg->stats.akcipher.encrypt_cnt);
  		atomic64_add(src_len, &alg->stats.akcipher.encrypt_tlen);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1030
1031
1032
1033
1034
1035
1036
1037
1038
  	}
  	crypto_alg_put(alg);
  }
  EXPORT_SYMBOL_GPL(crypto_stats_akcipher_encrypt);
  
  void crypto_stats_akcipher_decrypt(unsigned int src_len, int ret,
  				   struct crypto_alg *alg)
  {
  	if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
44f13133c   Corentin Labbe   crypto: user - re...
1039
  		atomic64_inc(&alg->stats.akcipher.err_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1040
  	} else {
17c18f9e3   Corentin Labbe   crypto: user - Sp...
1041
1042
  		atomic64_inc(&alg->stats.akcipher.decrypt_cnt);
  		atomic64_add(src_len, &alg->stats.akcipher.decrypt_tlen);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1043
1044
1045
1046
1047
1048
1049
1050
  	}
  	crypto_alg_put(alg);
  }
  EXPORT_SYMBOL_GPL(crypto_stats_akcipher_decrypt);
  
  void crypto_stats_akcipher_sign(int ret, struct crypto_alg *alg)
  {
  	if (ret && ret != -EINPROGRESS && ret != -EBUSY)
44f13133c   Corentin Labbe   crypto: user - re...
1051
  		atomic64_inc(&alg->stats.akcipher.err_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1052
  	else
17c18f9e3   Corentin Labbe   crypto: user - Sp...
1053
  		atomic64_inc(&alg->stats.akcipher.sign_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1054
1055
1056
1057
1058
1059
1060
  	crypto_alg_put(alg);
  }
  EXPORT_SYMBOL_GPL(crypto_stats_akcipher_sign);
  
  void crypto_stats_akcipher_verify(int ret, struct crypto_alg *alg)
  {
  	if (ret && ret != -EINPROGRESS && ret != -EBUSY)
44f13133c   Corentin Labbe   crypto: user - re...
1061
  		atomic64_inc(&alg->stats.akcipher.err_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1062
  	else
17c18f9e3   Corentin Labbe   crypto: user - Sp...
1063
  		atomic64_inc(&alg->stats.akcipher.verify_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1064
1065
1066
1067
1068
1069
1070
  	crypto_alg_put(alg);
  }
  EXPORT_SYMBOL_GPL(crypto_stats_akcipher_verify);
  
  void crypto_stats_compress(unsigned int slen, int ret, struct crypto_alg *alg)
  {
  	if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
44f13133c   Corentin Labbe   crypto: user - re...
1071
  		atomic64_inc(&alg->stats.compress.err_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1072
  	} else {
17c18f9e3   Corentin Labbe   crypto: user - Sp...
1073
1074
  		atomic64_inc(&alg->stats.compress.compress_cnt);
  		atomic64_add(slen, &alg->stats.compress.compress_tlen);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1075
1076
1077
1078
1079
1080
1081
1082
  	}
  	crypto_alg_put(alg);
  }
  EXPORT_SYMBOL_GPL(crypto_stats_compress);
  
  void crypto_stats_decompress(unsigned int slen, int ret, struct crypto_alg *alg)
  {
  	if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
44f13133c   Corentin Labbe   crypto: user - re...
1083
  		atomic64_inc(&alg->stats.compress.err_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1084
  	} else {
17c18f9e3   Corentin Labbe   crypto: user - Sp...
1085
1086
  		atomic64_inc(&alg->stats.compress.decompress_cnt);
  		atomic64_add(slen, &alg->stats.compress.decompress_tlen);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1087
1088
1089
1090
1091
1092
1093
1094
1095
  	}
  	crypto_alg_put(alg);
  }
  EXPORT_SYMBOL_GPL(crypto_stats_decompress);
  
  void crypto_stats_ahash_update(unsigned int nbytes, int ret,
  			       struct crypto_alg *alg)
  {
  	if (ret && ret != -EINPROGRESS && ret != -EBUSY)
44f13133c   Corentin Labbe   crypto: user - re...
1096
  		atomic64_inc(&alg->stats.hash.err_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1097
  	else
17c18f9e3   Corentin Labbe   crypto: user - Sp...
1098
  		atomic64_add(nbytes, &alg->stats.hash.hash_tlen);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1099
1100
1101
1102
1103
1104
1105
1106
  	crypto_alg_put(alg);
  }
  EXPORT_SYMBOL_GPL(crypto_stats_ahash_update);
  
  void crypto_stats_ahash_final(unsigned int nbytes, int ret,
  			      struct crypto_alg *alg)
  {
  	if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
44f13133c   Corentin Labbe   crypto: user - re...
1107
  		atomic64_inc(&alg->stats.hash.err_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1108
  	} else {
17c18f9e3   Corentin Labbe   crypto: user - Sp...
1109
1110
  		atomic64_inc(&alg->stats.hash.hash_cnt);
  		atomic64_add(nbytes, &alg->stats.hash.hash_tlen);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1111
1112
1113
1114
1115
1116
1117
1118
  	}
  	crypto_alg_put(alg);
  }
  EXPORT_SYMBOL_GPL(crypto_stats_ahash_final);
  
  void crypto_stats_kpp_set_secret(struct crypto_alg *alg, int ret)
  {
  	if (ret)
44f13133c   Corentin Labbe   crypto: user - re...
1119
  		atomic64_inc(&alg->stats.kpp.err_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1120
  	else
17c18f9e3   Corentin Labbe   crypto: user - Sp...
1121
  		atomic64_inc(&alg->stats.kpp.setsecret_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1122
1123
1124
1125
1126
1127
1128
  	crypto_alg_put(alg);
  }
  EXPORT_SYMBOL_GPL(crypto_stats_kpp_set_secret);
  
  void crypto_stats_kpp_generate_public_key(struct crypto_alg *alg, int ret)
  {
  	if (ret)
44f13133c   Corentin Labbe   crypto: user - re...
1129
  		atomic64_inc(&alg->stats.kpp.err_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1130
  	else
17c18f9e3   Corentin Labbe   crypto: user - Sp...
1131
  		atomic64_inc(&alg->stats.kpp.generate_public_key_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1132
1133
1134
1135
1136
1137
1138
  	crypto_alg_put(alg);
  }
  EXPORT_SYMBOL_GPL(crypto_stats_kpp_generate_public_key);
  
  void crypto_stats_kpp_compute_shared_secret(struct crypto_alg *alg, int ret)
  {
  	if (ret)
44f13133c   Corentin Labbe   crypto: user - re...
1139
  		atomic64_inc(&alg->stats.kpp.err_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1140
  	else
17c18f9e3   Corentin Labbe   crypto: user - Sp...
1141
  		atomic64_inc(&alg->stats.kpp.compute_shared_secret_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1142
1143
1144
1145
1146
1147
1148
  	crypto_alg_put(alg);
  }
  EXPORT_SYMBOL_GPL(crypto_stats_kpp_compute_shared_secret);
  
  void crypto_stats_rng_seed(struct crypto_alg *alg, int ret)
  {
  	if (ret && ret != -EINPROGRESS && ret != -EBUSY)
44f13133c   Corentin Labbe   crypto: user - re...
1149
  		atomic64_inc(&alg->stats.rng.err_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1150
  	else
17c18f9e3   Corentin Labbe   crypto: user - Sp...
1151
  		atomic64_inc(&alg->stats.rng.seed_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1152
1153
1154
1155
1156
1157
1158
1159
  	crypto_alg_put(alg);
  }
  EXPORT_SYMBOL_GPL(crypto_stats_rng_seed);
  
  void crypto_stats_rng_generate(struct crypto_alg *alg, unsigned int dlen,
  			       int ret)
  {
  	if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
44f13133c   Corentin Labbe   crypto: user - re...
1160
  		atomic64_inc(&alg->stats.rng.err_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1161
  	} else {
17c18f9e3   Corentin Labbe   crypto: user - Sp...
1162
1163
  		atomic64_inc(&alg->stats.rng.generate_cnt);
  		atomic64_add(dlen, &alg->stats.rng.generate_tlen);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1164
1165
1166
1167
1168
1169
1170
1171
1172
  	}
  	crypto_alg_put(alg);
  }
  EXPORT_SYMBOL_GPL(crypto_stats_rng_generate);
  
  void crypto_stats_skcipher_encrypt(unsigned int cryptlen, int ret,
  				   struct crypto_alg *alg)
  {
  	if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
44f13133c   Corentin Labbe   crypto: user - re...
1173
  		atomic64_inc(&alg->stats.cipher.err_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1174
  	} else {
17c18f9e3   Corentin Labbe   crypto: user - Sp...
1175
1176
  		atomic64_inc(&alg->stats.cipher.encrypt_cnt);
  		atomic64_add(cryptlen, &alg->stats.cipher.encrypt_tlen);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1177
1178
1179
1180
1181
1182
1183
1184
1185
  	}
  	crypto_alg_put(alg);
  }
  EXPORT_SYMBOL_GPL(crypto_stats_skcipher_encrypt);
  
  void crypto_stats_skcipher_decrypt(unsigned int cryptlen, int ret,
  				   struct crypto_alg *alg)
  {
  	if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
44f13133c   Corentin Labbe   crypto: user - re...
1186
  		atomic64_inc(&alg->stats.cipher.err_cnt);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1187
  	} else {
17c18f9e3   Corentin Labbe   crypto: user - Sp...
1188
1189
  		atomic64_inc(&alg->stats.cipher.decrypt_cnt);
  		atomic64_add(cryptlen, &alg->stats.cipher.decrypt_tlen);
f7d76e05d   Corentin Labbe   crypto: user - fi...
1190
1191
1192
1193
1194
  	}
  	crypto_alg_put(alg);
  }
  EXPORT_SYMBOL_GPL(crypto_stats_skcipher_decrypt);
  #endif
cce9e06d1   Herbert Xu   [CRYPTO] api: Spl...
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
  static int __init crypto_algapi_init(void)
  {
  	crypto_init_proc();
  	return 0;
  }
  
  static void __exit crypto_algapi_exit(void)
  {
  	crypto_exit_proc();
  }
  
  module_init(crypto_algapi_init);
  module_exit(crypto_algapi_exit);
  
  MODULE_LICENSE("GPL");
  MODULE_DESCRIPTION("Cryptographic algorithms API");