Blame view
crypto/api.c
13.8 KB
2874c5fd2 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 5 6 |
/* * Scatterlist Cryptographic API. * * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> * Copyright (c) 2002 David S. Miller (davem@redhat.com) |
5cb1454b8 [CRYPTO] Allow mu... |
7 |
* Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au> |
1da177e4c Linux-2.6.12-rc2 |
8 9 |
* * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no> |
991d17403 crypto: convert "... |
10 |
* and Nettle, by Niels Möller. |
1da177e4c Linux-2.6.12-rc2 |
11 |
*/ |
a61cc4481 [CRYPTO] Add null... |
12 |
|
6bfd48096 [CRYPTO] api: Add... |
13 |
#include <linux/err.h> |
1da177e4c Linux-2.6.12-rc2 |
14 |
#include <linux/errno.h> |
5cb1454b8 [CRYPTO] Allow mu... |
15 |
#include <linux/kernel.h> |
176c3652c [CRYPTO] Make cry... |
16 |
#include <linux/kmod.h> |
2b8c19dbd [CRYPTO] api: Add... |
17 |
#include <linux/module.h> |
2825982d9 [CRYPTO] api: Add... |
18 |
#include <linux/param.h> |
174cd4b1e sched/headers: Pr... |
19 |
#include <linux/sched/signal.h> |
1da177e4c Linux-2.6.12-rc2 |
20 |
#include <linux/slab.h> |
5cb1454b8 [CRYPTO] Allow mu... |
21 |
#include <linux/string.h> |
ada69a163 crypto: introduce... |
22 |
#include <linux/completion.h> |
1da177e4c Linux-2.6.12-rc2 |
23 24 25 |
#include "internal.h" LIST_HEAD(crypto_alg_list); |
cce9e06d1 [CRYPTO] api: Spl... |
26 |
EXPORT_SYMBOL_GPL(crypto_alg_list); |
1da177e4c Linux-2.6.12-rc2 |
27 |
DECLARE_RWSEM(crypto_alg_sem); |
cce9e06d1 [CRYPTO] api: Spl... |
28 |
EXPORT_SYMBOL_GPL(crypto_alg_sem); |
1da177e4c Linux-2.6.12-rc2 |
29 |
|
2825982d9 [CRYPTO] api: Add... |
30 31 |
BLOCKING_NOTIFIER_HEAD(crypto_chain); EXPORT_SYMBOL_GPL(crypto_chain); |
77dbd7a95 crypto: api - Fix... |
32 |
static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg); |
2825982d9 [CRYPTO] api: Add... |
33 |
struct crypto_alg *crypto_mod_get(struct crypto_alg *alg) |
6521f3027 [CRYPTO] api: Add... |
34 35 |
{ return try_module_get(alg->cra_module) ? crypto_alg_get(alg) : NULL; |
1da177e4c Linux-2.6.12-rc2 |
36 |
} |
2825982d9 [CRYPTO] api: Add... |
37 |
EXPORT_SYMBOL_GPL(crypto_mod_get); |
1da177e4c Linux-2.6.12-rc2 |
38 |
|
2825982d9 [CRYPTO] api: Add... |
39 |
void crypto_mod_put(struct crypto_alg *alg) |
1da177e4c Linux-2.6.12-rc2 |
40 |
{ |
da7cd59ab [CRYPTO] api: Rea... |
41 |
struct module *module = alg->cra_module; |
6521f3027 [CRYPTO] api: Add... |
42 |
crypto_alg_put(alg); |
da7cd59ab [CRYPTO] api: Rea... |
43 |
module_put(module); |
1da177e4c Linux-2.6.12-rc2 |
44 |
} |
2825982d9 [CRYPTO] api: Add... |
45 |
EXPORT_SYMBOL_GPL(crypto_mod_put); |
1da177e4c Linux-2.6.12-rc2 |
46 |
|
73d3864a4 crypto: api - Use... |
47 48 49 50 |
static inline int crypto_is_test_larval(struct crypto_larval *larval) { return larval->alg.cra_driver_name[0]; } |
c51b6c810 crypto: api - Exp... |
51 52 |
static struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask) |
1da177e4c Linux-2.6.12-rc2 |
53 54 |
{ struct crypto_alg *q, *alg = NULL; |
2825982d9 [CRYPTO] api: Add... |
55 |
int best = -2; |
1da177e4c Linux-2.6.12-rc2 |
56 |
|
1da177e4c Linux-2.6.12-rc2 |
57 |
list_for_each_entry(q, &crypto_alg_list, cra_list) { |
5cb1454b8 [CRYPTO] Allow mu... |
58 |
int exact, fuzzy; |
6bfd48096 [CRYPTO] api: Add... |
59 60 |
if (crypto_is_moribund(q)) continue; |
492e2b63e [CRYPTO] api: All... |
61 62 63 64 |
if ((q->cra_flags ^ type) & mask) continue; if (crypto_is_larval(q) && |
73d3864a4 crypto: api - Use... |
65 |
!crypto_is_test_larval((struct crypto_larval *)q) && |
492e2b63e [CRYPTO] api: All... |
66 67 |
((struct crypto_larval *)q)->mask != mask) continue; |
5cb1454b8 [CRYPTO] Allow mu... |
68 69 70 71 |
exact = !strcmp(q->cra_driver_name, name); fuzzy = !strcmp(q->cra_name, name); if (!exact && !(fuzzy && q->cra_priority > best)) continue; |
72fa49191 [CRYPTO] api: Ren... |
72 |
if (unlikely(!crypto_mod_get(q))) |
5cb1454b8 [CRYPTO] Allow mu... |
73 74 75 76 |
continue; best = q->cra_priority; if (alg) |
72fa49191 [CRYPTO] api: Ren... |
77 |
crypto_mod_put(alg); |
5cb1454b8 [CRYPTO] Allow mu... |
78 79 80 |
alg = q; if (exact) |
1da177e4c Linux-2.6.12-rc2 |
81 |
break; |
1da177e4c Linux-2.6.12-rc2 |
82 |
} |
2825982d9 [CRYPTO] api: Add... |
83 84 85 |
return alg; } |
2825982d9 [CRYPTO] api: Add... |
86 87 88 89 90 91 |
static void crypto_larval_destroy(struct crypto_alg *alg) { struct crypto_larval *larval = (void *)alg; BUG_ON(!crypto_is_larval(alg)); |
2bbb3375d crypto: api - fix... |
92 |
if (!IS_ERR_OR_NULL(larval->adult)) |
2825982d9 [CRYPTO] api: Add... |
93 94 95 |
crypto_mod_put(larval->adult); kfree(larval); } |
73d3864a4 crypto: api - Use... |
96 |
struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask) |
2825982d9 [CRYPTO] api: Add... |
97 |
{ |
2825982d9 [CRYPTO] api: Add... |
98 99 100 101 |
struct crypto_larval *larval; larval = kzalloc(sizeof(*larval), GFP_KERNEL); if (!larval) |
6bfd48096 [CRYPTO] api: Add... |
102 |
return ERR_PTR(-ENOMEM); |
2825982d9 [CRYPTO] api: Add... |
103 |
|
492e2b63e [CRYPTO] api: All... |
104 105 |
larval->mask = mask; larval->alg.cra_flags = CRYPTO_ALG_LARVAL | type; |
2825982d9 [CRYPTO] api: Add... |
106 107 |
larval->alg.cra_priority = -1; larval->alg.cra_destroy = crypto_larval_destroy; |
2825982d9 [CRYPTO] api: Add... |
108 109 |
strlcpy(larval->alg.cra_name, name, CRYPTO_MAX_ALG_NAME); init_completion(&larval->completion); |
73d3864a4 crypto: api - Use... |
110 111 112 113 114 115 116 117 118 119 120 121 122 |
return larval; } EXPORT_SYMBOL_GPL(crypto_larval_alloc); static struct crypto_alg *crypto_larval_add(const char *name, u32 type, u32 mask) { struct crypto_alg *alg; struct crypto_larval *larval; larval = crypto_larval_alloc(name, type, mask); if (IS_ERR(larval)) return ERR_CAST(larval); |
ce8614a31 crypto: algapi - ... |
123 |
refcount_set(&larval->alg.cra_refcnt, 2); |
73d3864a4 crypto: api - Use... |
124 |
|
2825982d9 [CRYPTO] api: Add... |
125 |
down_write(&crypto_alg_sem); |
492e2b63e [CRYPTO] api: All... |
126 |
alg = __crypto_alg_lookup(name, type, mask); |
2825982d9 [CRYPTO] api: Add... |
127 128 129 130 131 |
if (!alg) { alg = &larval->alg; list_add(&alg->cra_list, &crypto_alg_list); } up_write(&crypto_alg_sem); |
77dbd7a95 crypto: api - Fix... |
132 |
if (alg != &larval->alg) { |
2825982d9 [CRYPTO] api: Add... |
133 |
kfree(larval); |
77dbd7a95 crypto: api - Fix... |
134 135 136 |
if (crypto_is_larval(alg)) alg = crypto_larval_wait(alg); } |
2825982d9 [CRYPTO] api: Add... |
137 138 139 |
return alg; } |
b9c55aa47 [CRYPTO] skcipher... |
140 |
void crypto_larval_kill(struct crypto_alg *alg) |
2825982d9 [CRYPTO] api: Add... |
141 142 143 144 145 146 |
{ struct crypto_larval *larval = (void *)alg; down_write(&crypto_alg_sem); list_del(&alg->cra_list); up_write(&crypto_alg_sem); |
fe3c5206a [CRYPTO] api: Wak... |
147 |
complete_all(&larval->completion); |
2825982d9 [CRYPTO] api: Add... |
148 149 |
crypto_alg_put(alg); } |
b9c55aa47 [CRYPTO] skcipher... |
150 |
EXPORT_SYMBOL_GPL(crypto_larval_kill); |
2825982d9 [CRYPTO] api: Add... |
151 152 153 154 |
static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg) { struct crypto_larval *larval = (void *)alg; |
73d3864a4 crypto: api - Use... |
155 |
long timeout; |
3fc89adb9 crypto: api - Onl... |
156 |
timeout = wait_for_completion_killable_timeout( |
73d3864a4 crypto: api - Use... |
157 |
&larval->completion, 60 * HZ); |
2825982d9 [CRYPTO] api: Add... |
158 |
|
2825982d9 [CRYPTO] api: Add... |
159 |
alg = larval->adult; |
73d3864a4 crypto: api - Use... |
160 161 162 163 164 |
if (timeout < 0) alg = ERR_PTR(-EINTR); else if (!timeout) alg = ERR_PTR(-ETIMEDOUT); else if (!alg) |
6bfd48096 [CRYPTO] api: Add... |
165 |
alg = ERR_PTR(-ENOENT); |
2bbb3375d crypto: api - fix... |
166 167 |
else if (IS_ERR(alg)) ; |
73d3864a4 crypto: api - Use... |
168 169 170 171 172 |
else if (crypto_is_test_larval(larval) && !(alg->cra_flags & CRYPTO_ALG_TESTED)) alg = ERR_PTR(-EAGAIN); else if (!crypto_mod_get(alg)) alg = ERR_PTR(-EAGAIN); |
2825982d9 [CRYPTO] api: Add... |
173 174 175 176 |
crypto_mod_put(&larval->alg); return alg; } |
3ca1e9948 crypto: api - Mak... |
177 178 |
static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type, u32 mask) |
2825982d9 [CRYPTO] api: Add... |
179 180 |
{ struct crypto_alg *alg; |
eb02c38f0 crypto: api - Kee... |
181 182 183 184 |
u32 test = 0; if (!((type | mask) & CRYPTO_ALG_TESTED)) test |= CRYPTO_ALG_TESTED; |
2825982d9 [CRYPTO] api: Add... |
185 |
|
2825982d9 [CRYPTO] api: Add... |
186 |
down_read(&crypto_alg_sem); |
eb02c38f0 crypto: api - Kee... |
187 |
alg = __crypto_alg_lookup(name, type | test, mask | test); |
b346e492d crypto: api - fix... |
188 189 190 191 192 193 194 195 |
if (!alg && test) { alg = __crypto_alg_lookup(name, type, mask); if (alg && !crypto_is_larval(alg)) { /* Test failed */ crypto_mod_put(alg); alg = ERR_PTR(-ELIBBAD); } } |
1da177e4c Linux-2.6.12-rc2 |
196 |
up_read(&crypto_alg_sem); |
2825982d9 [CRYPTO] api: Add... |
197 |
|
1da177e4c Linux-2.6.12-rc2 |
198 199 |
return alg; } |
cadc9ab50 crypto: api - Une... |
200 201 |
static struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask) |
176c3652c [CRYPTO] Make cry... |
202 |
{ |
2825982d9 [CRYPTO] api: Add... |
203 |
struct crypto_alg *alg; |
2825982d9 [CRYPTO] api: Add... |
204 |
|
6bfd48096 [CRYPTO] api: Add... |
205 206 |
if (!name) return ERR_PTR(-ENOENT); |
430b441cd crypto: api - Do ... |
207 |
type &= ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD); |
6bfd48096 [CRYPTO] api: Add... |
208 |
mask &= ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD); |
492e2b63e [CRYPTO] api: All... |
209 |
|
a760a6656 crypto: api - Fix... |
210 |
alg = crypto_alg_lookup(name, type, mask); |
e2861fa71 evm: Don't deadlo... |
211 |
if (!alg && !(mask & CRYPTO_NOLOAD)) { |
5d26a105b crypto: prefix mo... |
212 |
request_module("crypto-%s", name); |
a760a6656 crypto: api - Fix... |
213 |
|
37fc334cc crypto: api - Fix... |
214 |
if (!((type ^ CRYPTO_ALG_NEED_FALLBACK) & mask & |
aa07a6990 crypto: api - Use... |
215 |
CRYPTO_ALG_NEED_FALLBACK)) |
5d26a105b crypto: prefix mo... |
216 |
request_module("crypto-%s-all", name); |
a760a6656 crypto: api - Fix... |
217 218 219 |
alg = crypto_alg_lookup(name, type, mask); } |
eb02c38f0 crypto: api - Kee... |
220 221 222 223 |
if (!IS_ERR_OR_NULL(alg) && crypto_is_larval(alg)) alg = crypto_larval_wait(alg); else if (!alg) alg = crypto_larval_add(name, type, mask); |
2825982d9 [CRYPTO] api: Add... |
224 |
|
eb02c38f0 crypto: api - Kee... |
225 |
return alg; |
b9c55aa47 [CRYPTO] skcipher... |
226 |
} |
b9c55aa47 [CRYPTO] skcipher... |
227 |
|
73d3864a4 crypto: api - Use... |
228 229 230 231 232 233 234 235 236 237 238 239 240 |
int crypto_probing_notify(unsigned long val, void *v) { int ok; ok = blocking_notifier_call_chain(&crypto_chain, val, v); if (ok == NOTIFY_DONE) { request_module("cryptomgr"); ok = blocking_notifier_call_chain(&crypto_chain, val, v); } return ok; } EXPORT_SYMBOL_GPL(crypto_probing_notify); |
b9c55aa47 [CRYPTO] skcipher... |
241 242 243 244 245 |
struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask) { struct crypto_alg *alg; struct crypto_alg *larval; int ok; |
06ca7f68d crypto: api - pre... |
246 247 248 249 250 251 252 253 254 |
/* * If the internal flag is set for a cipher, require a caller to * to invoke the cipher with the internal flag to use that cipher. * Also, if a caller wants to allocate a cipher that may or may * not be an internal cipher, use type | CRYPTO_ALG_INTERNAL and * !(mask & CRYPTO_ALG_INTERNAL). */ if (!((type | mask) & CRYPTO_ALG_INTERNAL)) mask |= CRYPTO_ALG_INTERNAL; |
b9c55aa47 [CRYPTO] skcipher... |
255 |
larval = crypto_larval_lookup(name, type, mask); |
6bfd48096 [CRYPTO] api: Add... |
256 |
if (IS_ERR(larval) || !crypto_is_larval(larval)) |
2825982d9 [CRYPTO] api: Add... |
257 |
return larval; |
73d3864a4 crypto: api - Use... |
258 |
ok = crypto_probing_notify(CRYPTO_MSG_ALG_REQUEST, larval); |
2b8c19dbd [CRYPTO] api: Add... |
259 260 |
if (ok == NOTIFY_STOP) |
2825982d9 [CRYPTO] api: Add... |
261 262 263 |
alg = crypto_larval_wait(larval); else { crypto_mod_put(larval); |
6bfd48096 [CRYPTO] api: Add... |
264 |
alg = ERR_PTR(-ENOENT); |
2825982d9 [CRYPTO] api: Add... |
265 266 267 |
} crypto_larval_kill(larval); return alg; |
176c3652c [CRYPTO] Make cry... |
268 |
} |
492e2b63e [CRYPTO] api: All... |
269 |
EXPORT_SYMBOL_GPL(crypto_alg_mod_lookup); |
176c3652c [CRYPTO] Make cry... |
270 |
|
27d2a3300 [CRYPTO] api: All... |
271 |
static int crypto_init_ops(struct crypto_tfm *tfm, u32 type, u32 mask) |
1da177e4c Linux-2.6.12-rc2 |
272 |
{ |
27d2a3300 [CRYPTO] api: All... |
273 |
const struct crypto_type *type_obj = tfm->__crt_alg->cra_type; |
e853c3cfa [CRYPTO] api: Add... |
274 |
|
27d2a3300 [CRYPTO] api: All... |
275 276 |
if (type_obj) return type_obj->init(tfm, type, mask); |
e8cfed5e4 crypto: cipher - ... |
277 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
278 279 280 281 |
} static void crypto_exit_ops(struct crypto_tfm *tfm) { |
e853c3cfa [CRYPTO] api: Add... |
282 |
const struct crypto_type *type = tfm->__crt_alg->cra_type; |
9c8ae17bb crypto: api - Rem... |
283 284 |
if (type && tfm->exit) tfm->exit(tfm); |
1da177e4c Linux-2.6.12-rc2 |
285 |
} |
27d2a3300 [CRYPTO] api: All... |
286 |
static unsigned int crypto_ctxsize(struct crypto_alg *alg, u32 type, u32 mask) |
fbdae9f3e [CRYPTO] Ensure c... |
287 |
{ |
27d2a3300 [CRYPTO] api: All... |
288 |
const struct crypto_type *type_obj = alg->cra_type; |
fbdae9f3e [CRYPTO] Ensure c... |
289 |
unsigned int len; |
e853c3cfa [CRYPTO] api: Add... |
290 |
len = alg->cra_alignmask & ~(crypto_tfm_ctx_alignment() - 1); |
27d2a3300 [CRYPTO] api: All... |
291 292 |
if (type_obj) return len + type_obj->ctxsize(alg, type, mask); |
e853c3cfa [CRYPTO] api: Add... |
293 |
|
fbdae9f3e [CRYPTO] Ensure c... |
294 295 296 297 298 |
switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) { default: BUG(); case CRYPTO_ALG_TYPE_CIPHER: |
f1ddcaf33 [CRYPTO] api: Rem... |
299 |
len += crypto_cipher_ctxsize(alg); |
fbdae9f3e [CRYPTO] Ensure c... |
300 |
break; |
6941c3a0a crypto: hash - Re... |
301 |
|
fbdae9f3e [CRYPTO] Ensure c... |
302 |
case CRYPTO_ALG_TYPE_COMPRESS: |
f1ddcaf33 [CRYPTO] api: Rem... |
303 |
len += crypto_compress_ctxsize(alg); |
fbdae9f3e [CRYPTO] Ensure c... |
304 305 |
break; } |
e853c3cfa [CRYPTO] api: Add... |
306 |
return len; |
fbdae9f3e [CRYPTO] Ensure c... |
307 |
} |
6603523bf crypto: api - Fix... |
308 |
void crypto_shoot_alg(struct crypto_alg *alg) |
6bfd48096 [CRYPTO] api: Add... |
309 310 311 312 313 |
{ down_write(&crypto_alg_sem); alg->cra_flags |= CRYPTO_ALG_DYING; up_write(&crypto_alg_sem); } |
6603523bf crypto: api - Fix... |
314 |
EXPORT_SYMBOL_GPL(crypto_shoot_alg); |
6bfd48096 [CRYPTO] api: Add... |
315 |
|
27d2a3300 [CRYPTO] api: All... |
316 317 |
struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type, u32 mask) |
1da177e4c Linux-2.6.12-rc2 |
318 319 |
{ struct crypto_tfm *tfm = NULL; |
fbdae9f3e [CRYPTO] Ensure c... |
320 |
unsigned int tfm_size; |
6bfd48096 [CRYPTO] api: Add... |
321 |
int err = -ENOMEM; |
fbdae9f3e [CRYPTO] Ensure c... |
322 |
|
27d2a3300 [CRYPTO] api: All... |
323 |
tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, type, mask); |
bbeb563f7 [CRYPTO] all: Use... |
324 |
tfm = kzalloc(tfm_size, GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
325 |
if (tfm == NULL) |
9765d262b [CRYPTO] api: fix... |
326 |
goto out_err; |
1da177e4c Linux-2.6.12-rc2 |
327 |
|
1da177e4c Linux-2.6.12-rc2 |
328 |
tfm->__crt_alg = alg; |
6bfd48096 [CRYPTO] api: Add... |
329 |
|
27d2a3300 [CRYPTO] api: All... |
330 |
err = crypto_init_ops(tfm, type, mask); |
6bfd48096 [CRYPTO] api: Add... |
331 |
if (err) |
1da177e4c Linux-2.6.12-rc2 |
332 |
goto out_free_tfm; |
c7fc05992 [CRYPTO] api: Add... |
333 |
|
4a7794860 crypto: api - Mov... |
334 |
if (!tfm->exit && alg->cra_init && (err = alg->cra_init(tfm))) |
c7fc05992 [CRYPTO] api: Add... |
335 |
goto cra_init_failed; |
1da177e4c Linux-2.6.12-rc2 |
336 337 |
goto out; |
c7fc05992 [CRYPTO] api: Add... |
338 339 |
cra_init_failed: crypto_exit_ops(tfm); |
1da177e4c Linux-2.6.12-rc2 |
340 |
out_free_tfm: |
4a7794860 crypto: api - Mov... |
341 342 |
if (err == -EAGAIN) crypto_shoot_alg(alg); |
1da177e4c Linux-2.6.12-rc2 |
343 |
kfree(tfm); |
9765d262b [CRYPTO] api: fix... |
344 |
out_err: |
6bfd48096 [CRYPTO] api: Add... |
345 |
tfm = ERR_PTR(err); |
1da177e4c Linux-2.6.12-rc2 |
346 347 348 |
out: return tfm; } |
6bfd48096 [CRYPTO] api: Add... |
349 |
EXPORT_SYMBOL_GPL(__crypto_alloc_tfm); |
6d7d684d6 [CRYPTO] api: Add... |
350 351 352 353 354 355 |
/* * crypto_alloc_base - Locate algorithm and allocate transform * @alg_name: Name of algorithm * @type: Type of algorithm * @mask: Mask for type comparison * |
7b0bac64c crypto: api - Reb... |
356 |
* This function should not be used by new algorithm types. |
fd1a19002 crypto: fix typo ... |
357 |
* Please use crypto_alloc_tfm instead. |
7b0bac64c crypto: api - Reb... |
358 |
* |
6d7d684d6 [CRYPTO] api: Add... |
359 360 361 362 363 364 365 366 367 |
* crypto_alloc_base() will first attempt to locate an already loaded * algorithm. If that fails and the kernel supports dynamically loadable * modules, it will then attempt to load a module of the same name or * alias. If that fails it will send a query to any loaded crypto manager * to construct an algorithm on the fly. A refcount is grabbed on the * algorithm which is then associated with the new transform. * * The returned transform is of a non-determinate type. Most people * should use one of the more specific allocation functions such as |
c65058b75 crypto: skcipher ... |
368 |
* crypto_alloc_skcipher(). |
6d7d684d6 [CRYPTO] api: Add... |
369 370 371 372 373 374 375 376 377 378 379 380 |
* * In case of error the return value is an error pointer. */ struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask) { struct crypto_tfm *tfm; int err; for (;;) { struct crypto_alg *alg; alg = crypto_alg_mod_lookup(alg_name, type, mask); |
9765d262b [CRYPTO] api: fix... |
381 382 |
if (IS_ERR(alg)) { err = PTR_ERR(alg); |
6d7d684d6 [CRYPTO] api: Add... |
383 |
goto err; |
9765d262b [CRYPTO] api: fix... |
384 |
} |
6d7d684d6 [CRYPTO] api: Add... |
385 |
|
27d2a3300 [CRYPTO] api: All... |
386 |
tfm = __crypto_alloc_tfm(alg, type, mask); |
6d7d684d6 [CRYPTO] api: Add... |
387 |
if (!IS_ERR(tfm)) |
9765d262b [CRYPTO] api: fix... |
388 |
return tfm; |
6d7d684d6 [CRYPTO] api: Add... |
389 390 391 392 393 394 395 |
crypto_mod_put(alg); err = PTR_ERR(tfm); err: if (err != -EAGAIN) break; |
3fc89adb9 crypto: api - Onl... |
396 |
if (fatal_signal_pending(current)) { |
6d7d684d6 [CRYPTO] api: Add... |
397 398 399 |
err = -EINTR; break; } |
9765d262b [CRYPTO] api: fix... |
400 |
} |
6d7d684d6 [CRYPTO] api: Add... |
401 |
|
9765d262b [CRYPTO] api: fix... |
402 |
return ERR_PTR(err); |
6d7d684d6 [CRYPTO] api: Add... |
403 404 |
} EXPORT_SYMBOL_GPL(crypto_alloc_base); |
7b0bac64c crypto: api - Reb... |
405 |
|
7bc13b5b6 crypto: api - per... |
406 407 408 |
void *crypto_create_tfm_node(struct crypto_alg *alg, const struct crypto_type *frontend, int node) |
7b0bac64c crypto: api - Reb... |
409 410 411 412 413 414 415 416 |
{ char *mem; struct crypto_tfm *tfm = NULL; unsigned int tfmsize; unsigned int total; int err = -ENOMEM; tfmsize = frontend->tfmsize; |
2ca33da1d crypto: api - Rem... |
417 |
total = tfmsize + sizeof(*tfm) + frontend->extsize(alg); |
7b0bac64c crypto: api - Reb... |
418 |
|
7bc13b5b6 crypto: api - per... |
419 |
mem = kzalloc_node(total, GFP_KERNEL, node); |
7b0bac64c crypto: api - Reb... |
420 421 422 423 424 |
if (mem == NULL) goto out_err; tfm = (struct crypto_tfm *)(mem + tfmsize); tfm->__crt_alg = alg; |
7bc13b5b6 crypto: api - per... |
425 |
tfm->node = node; |
7b0bac64c crypto: api - Reb... |
426 |
|
2ca33da1d crypto: api - Rem... |
427 |
err = frontend->init_tfm(tfm); |
7b0bac64c crypto: api - Reb... |
428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 |
if (err) goto out_free_tfm; if (!tfm->exit && alg->cra_init && (err = alg->cra_init(tfm))) goto cra_init_failed; goto out; cra_init_failed: crypto_exit_ops(tfm); out_free_tfm: if (err == -EAGAIN) crypto_shoot_alg(alg); kfree(mem); out_err: |
3f683d617 crypto: api - Fix... |
443 |
mem = ERR_PTR(err); |
7b0bac64c crypto: api - Reb... |
444 |
out: |
3f683d617 crypto: api - Fix... |
445 |
return mem; |
7b0bac64c crypto: api - Reb... |
446 |
} |
7bc13b5b6 crypto: api - per... |
447 |
EXPORT_SYMBOL_GPL(crypto_create_tfm_node); |
7b0bac64c crypto: api - Reb... |
448 |
|
d06854f02 crypto: api - Add... |
449 450 451 452 |
struct crypto_alg *crypto_find_alg(const char *alg_name, const struct crypto_type *frontend, u32 type, u32 mask) { |
d06854f02 crypto: api - Add... |
453 454 455 456 457 |
if (frontend) { type &= frontend->maskclear; mask &= frontend->maskclear; type |= frontend->type; mask |= frontend->maskset; |
d06854f02 crypto: api - Add... |
458 |
} |
4989d4f07 crypto: api - Rem... |
459 |
return crypto_alg_mod_lookup(alg_name, type, mask); |
d06854f02 crypto: api - Add... |
460 461 |
} EXPORT_SYMBOL_GPL(crypto_find_alg); |
7b0bac64c crypto: api - Reb... |
462 |
/* |
7bc13b5b6 crypto: api - per... |
463 |
* crypto_alloc_tfm_node - Locate algorithm and allocate transform |
7b0bac64c crypto: api - Reb... |
464 465 466 467 |
* @alg_name: Name of algorithm * @frontend: Frontend algorithm type * @type: Type of algorithm * @mask: Mask for type comparison |
7bc13b5b6 crypto: api - per... |
468 469 |
* @node: NUMA node in which users desire to put requests, if node is * NUMA_NO_NODE, it means users have no special requirement. |
7b0bac64c crypto: api - Reb... |
470 471 472 473 474 475 476 477 478 479 |
* * crypto_alloc_tfm() will first attempt to locate an already loaded * algorithm. If that fails and the kernel supports dynamically loadable * modules, it will then attempt to load a module of the same name or * alias. If that fails it will send a query to any loaded crypto manager * to construct an algorithm on the fly. A refcount is grabbed on the * algorithm which is then associated with the new transform. * * The returned transform is of a non-determinate type. Most people * should use one of the more specific allocation functions such as |
0a940d4e2 crypto: api - rem... |
480 |
* crypto_alloc_skcipher(). |
7b0bac64c crypto: api - Reb... |
481 482 483 |
* * In case of error the return value is an error pointer. */ |
7bc13b5b6 crypto: api - per... |
484 485 486 487 |
void *crypto_alloc_tfm_node(const char *alg_name, const struct crypto_type *frontend, u32 type, u32 mask, int node) |
7b0bac64c crypto: api - Reb... |
488 |
{ |
3f683d617 crypto: api - Fix... |
489 |
void *tfm; |
7b0bac64c crypto: api - Reb... |
490 |
int err; |
7b0bac64c crypto: api - Reb... |
491 492 |
for (;;) { struct crypto_alg *alg; |
d06854f02 crypto: api - Add... |
493 |
alg = crypto_find_alg(alg_name, frontend, type, mask); |
7b0bac64c crypto: api - Reb... |
494 495 496 497 |
if (IS_ERR(alg)) { err = PTR_ERR(alg); goto err; } |
7bc13b5b6 crypto: api - per... |
498 |
tfm = crypto_create_tfm_node(alg, frontend, node); |
7b0bac64c crypto: api - Reb... |
499 500 501 502 503 504 505 506 507 |
if (!IS_ERR(tfm)) return tfm; crypto_mod_put(alg); err = PTR_ERR(tfm); err: if (err != -EAGAIN) break; |
3fc89adb9 crypto: api - Onl... |
508 |
if (fatal_signal_pending(current)) { |
7b0bac64c crypto: api - Reb... |
509 510 511 512 513 514 515 |
err = -EINTR; break; } } return ERR_PTR(err); } |
7bc13b5b6 crypto: api - per... |
516 |
EXPORT_SYMBOL_GPL(crypto_alloc_tfm_node); |
7b2cd92ad crypto: api - Fix... |
517 |
|
6d7d684d6 [CRYPTO] api: Add... |
518 |
/* |
7b2cd92ad crypto: api - Fix... |
519 520 |
* crypto_destroy_tfm - Free crypto transform * @mem: Start of tfm slab |
6d7d684d6 [CRYPTO] api: Add... |
521 522 |
* @tfm: Transform to free * |
7b2cd92ad crypto: api - Fix... |
523 |
* This function frees up the transform and any associated resources, |
6d7d684d6 [CRYPTO] api: Add... |
524 525 |
* then drops the refcount on the associated algorithm. */ |
7b2cd92ad crypto: api - Fix... |
526 |
void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm) |
1da177e4c Linux-2.6.12-rc2 |
527 |
{ |
a61cc4481 [CRYPTO] Add null... |
528 |
struct crypto_alg *alg; |
a61cc4481 [CRYPTO] Add null... |
529 |
|
7b2cd92ad crypto: api - Fix... |
530 |
if (unlikely(!mem)) |
a61cc4481 [CRYPTO] Add null... |
531 532 533 |
return; alg = tfm->__crt_alg; |
1da177e4c Linux-2.6.12-rc2 |
534 |
|
4a7794860 crypto: api - Mov... |
535 |
if (!tfm->exit && alg->cra_exit) |
c7fc05992 [CRYPTO] api: Add... |
536 |
alg->cra_exit(tfm); |
1da177e4c Linux-2.6.12-rc2 |
537 |
crypto_exit_ops(tfm); |
72fa49191 [CRYPTO] api: Ren... |
538 |
crypto_mod_put(alg); |
453431a54 mm, treewide: ren... |
539 |
kfree_sensitive(mem); |
1da177e4c Linux-2.6.12-rc2 |
540 |
} |
7b2cd92ad crypto: api - Fix... |
541 |
EXPORT_SYMBOL_GPL(crypto_destroy_tfm); |
fce32d70b [CRYPTO] api: Add... |
542 543 544 545 546 |
int crypto_has_alg(const char *name, u32 type, u32 mask) { int ret = 0; struct crypto_alg *alg = crypto_alg_mod_lookup(name, type, mask); |
3d01a33b7 crypto: api - Fix... |
547 |
|
fce32d70b [CRYPTO] api: Add... |
548 549 550 551 |
if (!IS_ERR(alg)) { crypto_mod_put(alg); ret = 1; } |
3d01a33b7 crypto: api - Fix... |
552 |
|
fce32d70b [CRYPTO] api: Add... |
553 554 555 |
return ret; } EXPORT_SYMBOL_GPL(crypto_has_alg); |
c3715cb90 [CRYPTO] api: Mak... |
556 |
|
ada69a163 crypto: introduce... |
557 558 559 560 561 562 563 564 565 566 567 |
void crypto_req_done(struct crypto_async_request *req, int err) { struct crypto_wait *wait = req->data; if (err == -EINPROGRESS) return; wait->err = err; complete(&wait->completion); } EXPORT_SYMBOL_GPL(crypto_req_done); |
c3715cb90 [CRYPTO] api: Mak... |
568 569 |
MODULE_DESCRIPTION("Cryptographic core API"); MODULE_LICENSE("GPL"); |
8ab23d547 crypto: api - Add... |
570 |
MODULE_SOFTDEP("pre: cryptomgr"); |