|
@@ -372,6 +372,66 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
|
|
|
return tfm;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * crypto_alloc_base - Locate algorithm and allocate transform
|
|
|
+ * @alg_name: Name of algorithm
|
|
|
+ * @type: Type of algorithm
|
|
|
+ * @mask: Mask for type comparison
|
|
|
+ *
|
|
|
+ * 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
|
|
|
+ * crypto_alloc_blkcipher.
|
|
|
+ *
|
|
|
+ * 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);
|
|
|
+ err = PTR_ERR(alg);
|
|
|
+ tfm = ERR_PTR(err);
|
|
|
+ if (IS_ERR(alg))
|
|
|
+ goto err;
|
|
|
+
|
|
|
+ tfm = __crypto_alloc_tfm(alg, 0);
|
|
|
+ if (!IS_ERR(tfm))
|
|
|
+ break;
|
|
|
+
|
|
|
+ crypto_mod_put(alg);
|
|
|
+ err = PTR_ERR(tfm);
|
|
|
+
|
|
|
+err:
|
|
|
+ if (err != -EAGAIN)
|
|
|
+ break;
|
|
|
+ if (signal_pending(current)) {
|
|
|
+ err = -EINTR;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ return tfm;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(crypto_alloc_base);
|
|
|
+
|
|
|
+/*
|
|
|
+ * crypto_free_tfm - Free crypto transform
|
|
|
+ * @tfm: Transform to free
|
|
|
+ *
|
|
|
+ * crypto_free_tfm() frees up the transform and any associated resources,
|
|
|
+ * then drops the refcount on the associated algorithm.
|
|
|
+ */
|
|
|
void crypto_free_tfm(struct crypto_tfm *tfm)
|
|
|
{
|
|
|
struct crypto_alg *alg;
|