+ unsigned int tfmsize;
+ unsigned int total;
+ int err = -ENOMEM;
+
+ tfmsize = frontend->tfmsize;
+ total = tfmsize + sizeof(*tfm) + frontend->extsize(alg, frontend);
+
+ mem = kzalloc(total, GFP_KERNEL);
+ if (mem == NULL)
+ goto out_err;
+
+ tfm = (struct crypto_tfm *)(mem + tfmsize);
+ tfm->__crt_alg = alg;
+
+ err = frontend->init_tfm(tfm, frontend);
+ 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:
+ mem = ERR_PTR(err);
+out:
+ return mem;
+}
+EXPORT_SYMBOL_GPL(crypto_create_tfm);
+
+struct crypto_alg *crypto_find_alg(const char *alg_name,
+ const struct crypto_type *frontend,
+ u32 type, u32 mask)
+{
+ struct crypto_alg *(*lookup)(const char *name, u32 type, u32 mask) =
+ crypto_alg_mod_lookup;
+
+ if (frontend) {
+ type &= frontend->maskclear;
+ mask &= frontend->maskclear;
+ type |= frontend->type;
+ mask |= frontend->maskset;
+
+ if (frontend->lookup)
+ lookup = frontend->lookup;
+ }
+
+ return lookup(alg_name, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_find_alg);
+
+/*
+ * crypto_alloc_tfm - Locate algorithm and allocate transform
+ * @alg_name: Name of algorithm
+ * @frontend: Frontend algorithm type
+ * @type: Type of algorithm
+ * @mask: Mask for type comparison
+ *
+ * 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
+ * crypto_alloc_blkcipher.
+ *
+ * In case of error the return value is an error pointer.
+ */
+void *crypto_alloc_tfm(const char *alg_name,
+ const struct crypto_type *frontend, u32 type, u32 mask)
+{
+ void *tfm;