Hi: [CRYPTO] api: Abstract out common instance initialisation code This patch adds the helpers crypto_get_attr_alg and crypto_alloc_instance which can be used by simple one-argument templates like hmac to process input parameters and allocate instances. Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} <herbert@xxxxxxxxxxxxxxxxxxx> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- diff --git a/crypto/hmac.c b/crypto/hmac.c --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -19,7 +19,6 @@ #include <linux/err.h> #include <linux/kernel.h> #include <linux/mm.h> -#include <linux/rtnetlink.h> #include <linux/slab.h> #include <linux/scatterlist.h> @@ -132,49 +131,19 @@ static void crypto_hmac_exit_tfm(struct static struct crypto_instance *crypto_hmac_alloc(void *param, unsigned int len) { - struct rtattr *rta = param; struct crypto_instance *inst; - struct crypto_attr_alg *alga; struct crypto_alg *alg; - struct crypto_spawn *spawn; - int err; - if (!RTA_OK(rta, len)) - return ERR_PTR(-EBADR); - if (rta->rta_type != CRYPTOA_ALG || RTA_PAYLOAD(rta) < sizeof(*alga)) - return ERR_PTR(-EINVAL); - - alga = RTA_DATA(rta); - - inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); - if (!inst) - return ERR_PTR(-ENOMEM); - - inst->alg.cra_flags = CRYPTO_ALG_TYPE_DIGEST; - - alg = crypto_alg_mod_lookup(alga->name, CRYPTO_ALG_TYPE_DIGEST, - CRYPTO_ALG_TYPE_MASK); - err = PTR_ERR(alg); + alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_DIGEST, + CRYPTO_ALG_TYPE_MASK); if (IS_ERR(alg)) - goto err_free_inst; + return ERR_PTR(PTR_ERR(alg)); - err = -ENAMETOOLONG; - if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, - "hmac(%s)", alg->cra_name) >= CRYPTO_MAX_ALG_NAME) - goto put_alg; - - if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, - "hmac(%s)", alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) - goto put_alg; - - spawn = crypto_instance_ctx(inst); - err = crypto_init_spawn(spawn, alg, inst); - -put_alg: - crypto_mod_put(alg); - if (err) - goto err_free_inst; + inst = crypto_alloc_instance("hmac", alg); + if (IS_ERR(inst)) + goto out_put_alg; + inst->alg.cra_flags = CRYPTO_ALG_TYPE_DIGEST; inst->alg.cra_priority = alg->cra_priority; inst->alg.cra_blocksize = alg->cra_blocksize; inst->alg.cra_alignmask = alg->cra_alignmask; @@ -191,11 +160,9 @@ put_alg: inst->alg.cra_digest.dia_final = crypto_hmac_digest_final; inst->alg.cra_digest.dia_setkey = crypto_hmac_digest_setkey; +out_put_alg: + crypto_mod_put(alg); return inst; - -err_free_inst: - kfree(inst); - return ERR_PTR(err); } static void crypto_hmac_free(struct crypto_instance *inst) diff --git a/crypto/lowapi.c b/crypto/lowapi.c --- a/crypto/lowapi.c +++ b/crypto/lowapi.c @@ -16,6 +16,7 @@ #include <linux/kernel.h> #include <linux/list.h> #include <linux/module.h> +#include <linux/rtnetlink.h> #include <linux/string.h> #include "internal.h" @@ -414,6 +415,58 @@ int crypto_unregister_notifier(struct no } EXPORT_SYMBOL_GPL(crypto_unregister_notifier); +struct crypto_alg *crypto_get_attr_alg(void *param, unsigned int len, + u32 type, u32 mask) +{ + struct rtattr *rta = param; + struct crypto_attr_alg *alga; + + if (!RTA_OK(rta, len)) + return ERR_PTR(-EBADR); + if (rta->rta_type != CRYPTOA_ALG || RTA_PAYLOAD(rta) < sizeof(*alga)) + return ERR_PTR(-EINVAL); + + alga = RTA_DATA(rta); + alga->name[CRYPTO_MAX_ALG_NAME - 1] = 0; + + return crypto_alg_mod_lookup(alga->name, type, mask); +} +EXPORT_SYMBOL_GPL(crypto_get_attr_alg); + +struct crypto_instance *crypto_alloc_instance(const char *name, + struct crypto_alg *alg) +{ + struct crypto_instance *inst; + struct crypto_spawn *spawn; + int err; + + inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); + if (!inst) + return ERR_PTR(-ENOMEM); + + err = -ENAMETOOLONG; + if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, "%s(%s)", name, + alg->cra_name) >= CRYPTO_MAX_ALG_NAME) + goto err_free_inst; + + if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s(%s)", + name, alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) + goto err_free_inst; + + spawn = crypto_instance_ctx(inst); + err = crypto_init_spawn(spawn, alg, inst); + + if (err) + goto err_free_inst; + + return inst; + +err_free_inst: + kfree(inst); + return ERR_PTR(err); +} +EXPORT_SYMBOL_GPL(crypto_alloc_instance); + static int __init crypto_lowapi_init(void) { printk(KERN_INFO "Initializing Cryptographic API\n"); diff --git a/include/crypto/lowapi.h b/include/crypto/lowapi.h --- a/include/crypto/lowapi.h +++ b/include/crypto/lowapi.h @@ -56,6 +56,11 @@ int crypto_init_spawn(struct crypto_spaw void crypto_drop_spawn(struct crypto_spawn *spawn); struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn); +struct crypto_alg *crypto_get_attr_alg(void *param, unsigned int len, + u32 type, u32 mask); +struct crypto_instance *crypto_alloc_instance(const char *name, + struct crypto_alg *alg); + static inline void *crypto_instance_ctx(struct crypto_instance *inst) { return inst->__ctx; - : send the line "unsubscribe linux-crypto" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html