diff options
Diffstat (limited to 'crypto/api.c')
-rw-r--r-- | crypto/api.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/crypto/api.c b/crypto/api.c index 1e4692a13474..bc4b7901acdf 100644 --- a/crypto/api.c +++ b/crypto/api.c | |||
@@ -372,6 +372,66 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) | |||
372 | return tfm; | 372 | return tfm; |
373 | } | 373 | } |
374 | 374 | ||
375 | /* | ||
376 | * crypto_alloc_base - Locate algorithm and allocate transform | ||
377 | * @alg_name: Name of algorithm | ||
378 | * @type: Type of algorithm | ||
379 | * @mask: Mask for type comparison | ||
380 | * | ||
381 | * crypto_alloc_base() will first attempt to locate an already loaded | ||
382 | * algorithm. If that fails and the kernel supports dynamically loadable | ||
383 | * modules, it will then attempt to load a module of the same name or | ||
384 | * alias. If that fails it will send a query to any loaded crypto manager | ||
385 | * to construct an algorithm on the fly. A refcount is grabbed on the | ||
386 | * algorithm which is then associated with the new transform. | ||
387 | * | ||
388 | * The returned transform is of a non-determinate type. Most people | ||
389 | * should use one of the more specific allocation functions such as | ||
390 | * crypto_alloc_blkcipher. | ||
391 | * | ||
392 | * In case of error the return value is an error pointer. | ||
393 | */ | ||
394 | struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask) | ||
395 | { | ||
396 | struct crypto_tfm *tfm; | ||
397 | int err; | ||
398 | |||
399 | for (;;) { | ||
400 | struct crypto_alg *alg; | ||
401 | |||
402 | alg = crypto_alg_mod_lookup(alg_name, type, mask); | ||
403 | err = PTR_ERR(alg); | ||
404 | tfm = ERR_PTR(err); | ||
405 | if (IS_ERR(alg)) | ||
406 | goto err; | ||
407 | |||
408 | tfm = __crypto_alloc_tfm(alg, 0); | ||
409 | if (!IS_ERR(tfm)) | ||
410 | break; | ||
411 | |||
412 | crypto_mod_put(alg); | ||
413 | err = PTR_ERR(tfm); | ||
414 | |||
415 | err: | ||
416 | if (err != -EAGAIN) | ||
417 | break; | ||
418 | if (signal_pending(current)) { | ||
419 | err = -EINTR; | ||
420 | break; | ||
421 | } | ||
422 | }; | ||
423 | |||
424 | return tfm; | ||
425 | } | ||
426 | EXPORT_SYMBOL_GPL(crypto_alloc_base); | ||
427 | |||
428 | /* | ||
429 | * crypto_free_tfm - Free crypto transform | ||
430 | * @tfm: Transform to free | ||
431 | * | ||
432 | * crypto_free_tfm() frees up the transform and any associated resources, | ||
433 | * then drops the refcount on the associated algorithm. | ||
434 | */ | ||
375 | void crypto_free_tfm(struct crypto_tfm *tfm) | 435 | void crypto_free_tfm(struct crypto_tfm *tfm) |
376 | { | 436 | { |
377 | struct crypto_alg *alg; | 437 | struct crypto_alg *alg; |