From 1e212a6a562f781f00cba6c7ece93817857e0f32 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Thu, 2 Jan 2020 19:59:04 -0800 Subject: crypto: xcbc - use crypto_grab_cipher() and simplify error paths Make the xcbc template use the new function crypto_grab_cipher() to initialize its cipher spawn. This is needed to make all spawns be initialized in a consistent way. This required making xcbc_create() allocate the instance directly rather than use shash_alloc_instance(). Also simplify the error handling by taking advantage of crypto_drop_*() now accepting (as a no-op) spawns that haven't been initialized yet, and by taking advantage of crypto_grab_*() now handling ERR_PTR() names. Signed-off-by: Eric Biggers Signed-off-by: Herbert Xu --- crypto/xcbc.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) (limited to 'crypto/xcbc.c') diff --git a/crypto/xcbc.c b/crypto/xcbc.c index 0bb26e8f6f5a..9b97fa511f10 100644 --- a/crypto/xcbc.c +++ b/crypto/xcbc.c @@ -188,6 +188,7 @@ static void xcbc_exit_tfm(struct crypto_tfm *tfm) static int xcbc_create(struct crypto_template *tmpl, struct rtattr **tb) { struct shash_instance *inst; + struct crypto_cipher_spawn *spawn; struct crypto_alg *alg; unsigned long alignmask; int err; @@ -196,28 +197,24 @@ static int xcbc_create(struct crypto_template *tmpl, struct rtattr **tb) if (err) return err; - alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER, - CRYPTO_ALG_TYPE_MASK); - if (IS_ERR(alg)) - return PTR_ERR(alg); + inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); + if (!inst) + return -ENOMEM; + spawn = shash_instance_ctx(inst); - switch(alg->cra_blocksize) { - case XCBC_BLOCKSIZE: - break; - default: - goto out_put_alg; - } + err = crypto_grab_cipher(spawn, shash_crypto_instance(inst), + crypto_attr_alg_name(tb[1]), 0, 0); + if (err) + goto err_free_inst; + alg = crypto_spawn_cipher_alg(spawn); - inst = shash_alloc_instance("xcbc", alg); - err = PTR_ERR(inst); - if (IS_ERR(inst)) - goto out_put_alg; + err = -EINVAL; + if (alg->cra_blocksize != XCBC_BLOCKSIZE) + goto err_free_inst; - err = crypto_init_spawn(shash_instance_ctx(inst), alg, - shash_crypto_instance(inst), - CRYPTO_ALG_TYPE_MASK); + err = crypto_inst_setname(shash_crypto_instance(inst), tmpl->name, alg); if (err) - goto out_free_inst; + goto err_free_inst; alignmask = alg->cra_alignmask | 3; inst->alg.base.cra_alignmask = alignmask; @@ -244,12 +241,9 @@ static int xcbc_create(struct crypto_template *tmpl, struct rtattr **tb) err = shash_register_instance(tmpl, inst); if (err) { -out_free_inst: +err_free_inst: shash_free_instance(shash_crypto_instance(inst)); } - -out_put_alg: - crypto_mod_put(alg); return err; } -- cgit v1.2.3 From d5ed3b65f7012a6592809f7f928f3e3660df8fd9 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Thu, 2 Jan 2020 19:59:05 -0800 Subject: crypto: cipher - make crypto_spawn_cipher() take a crypto_cipher_spawn Now that all users of single-block cipher spawns have been converted to use 'struct crypto_cipher_spawn' rather than the less specifically typed 'struct crypto_spawn', make crypto_spawn_cipher() take a pointer to a 'struct crypto_cipher_spawn' rather than a 'struct crypto_spawn'. Signed-off-by: Eric Biggers Signed-off-by: Herbert Xu --- crypto/adiantum.c | 2 +- crypto/ccm.c | 2 +- crypto/cmac.c | 2 +- crypto/skcipher.c | 2 +- crypto/vmac.c | 2 +- crypto/xcbc.c | 2 +- include/crypto/algapi.h | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) (limited to 'crypto/xcbc.c') diff --git a/crypto/adiantum.c b/crypto/adiantum.c index 5b8aa14ccb55..4d7a6cac82ed 100644 --- a/crypto/adiantum.c +++ b/crypto/adiantum.c @@ -408,7 +408,7 @@ static int adiantum_init_tfm(struct crypto_skcipher *tfm) if (IS_ERR(streamcipher)) return PTR_ERR(streamcipher); - blockcipher = crypto_spawn_cipher(&ictx->blockcipher_spawn.base); + blockcipher = crypto_spawn_cipher(&ictx->blockcipher_spawn); if (IS_ERR(blockcipher)) { err = PTR_ERR(blockcipher); goto err_free_streamcipher; diff --git a/crypto/ccm.c b/crypto/ccm.c index 411c3973b95c..f4abaefd9df5 100644 --- a/crypto/ccm.c +++ b/crypto/ccm.c @@ -866,7 +866,7 @@ static int cbcmac_init_tfm(struct crypto_tfm *tfm) { struct crypto_cipher *cipher; struct crypto_instance *inst = (void *)tfm->__crt_alg; - struct crypto_spawn *spawn = crypto_instance_ctx(inst); + struct crypto_cipher_spawn *spawn = crypto_instance_ctx(inst); struct cbcmac_tfm_ctx *ctx = crypto_tfm_ctx(tfm); cipher = crypto_spawn_cipher(spawn); diff --git a/crypto/cmac.c b/crypto/cmac.c index c6bf78b5321a..58dc644416bb 100644 --- a/crypto/cmac.c +++ b/crypto/cmac.c @@ -201,7 +201,7 @@ static int cmac_init_tfm(struct crypto_tfm *tfm) { struct crypto_cipher *cipher; struct crypto_instance *inst = (void *)tfm->__crt_alg; - struct crypto_spawn *spawn = crypto_instance_ctx(inst); + struct crypto_cipher_spawn *spawn = crypto_instance_ctx(inst); struct cmac_tfm_ctx *ctx = crypto_tfm_ctx(tfm); cipher = crypto_spawn_cipher(spawn); diff --git a/crypto/skcipher.c b/crypto/skcipher.c index 950ff1438131..42add1e0814f 100644 --- a/crypto/skcipher.c +++ b/crypto/skcipher.c @@ -887,7 +887,7 @@ static int skcipher_setkey_simple(struct crypto_skcipher *tfm, const u8 *key, static int skcipher_init_tfm_simple(struct crypto_skcipher *tfm) { struct skcipher_instance *inst = skcipher_alg_instance(tfm); - struct crypto_spawn *spawn = skcipher_instance_ctx(inst); + struct crypto_cipher_spawn *spawn = skcipher_instance_ctx(inst); struct skcipher_ctx_simple *ctx = crypto_skcipher_ctx(tfm); struct crypto_cipher *cipher; diff --git a/crypto/vmac.c b/crypto/vmac.c index 9b000aaa20a8..28358a6aef9f 100644 --- a/crypto/vmac.c +++ b/crypto/vmac.c @@ -596,7 +596,7 @@ static int vmac_final(struct shash_desc *desc, u8 *out) static int vmac_init_tfm(struct crypto_tfm *tfm) { struct crypto_instance *inst = crypto_tfm_alg_instance(tfm); - struct crypto_spawn *spawn = crypto_instance_ctx(inst); + struct crypto_cipher_spawn *spawn = crypto_instance_ctx(inst); struct vmac_tfm_ctx *tctx = crypto_tfm_ctx(tfm); struct crypto_cipher *cipher; diff --git a/crypto/xcbc.c b/crypto/xcbc.c index 9b97fa511f10..9265e00ea663 100644 --- a/crypto/xcbc.c +++ b/crypto/xcbc.c @@ -167,7 +167,7 @@ static int xcbc_init_tfm(struct crypto_tfm *tfm) { struct crypto_cipher *cipher; struct crypto_instance *inst = (void *)tfm->__crt_alg; - struct crypto_spawn *spawn = crypto_instance_ctx(inst); + struct crypto_cipher_spawn *spawn = crypto_instance_ctx(inst); struct xcbc_tfm_ctx *ctx = crypto_tfm_ctx(tfm); cipher = crypto_spawn_cipher(spawn); diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 7705387f9459..bbf85a854a42 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -234,12 +234,12 @@ static inline struct crypto_alg *crypto_spawn_cipher_alg( } static inline struct crypto_cipher *crypto_spawn_cipher( - struct crypto_spawn *spawn) + struct crypto_cipher_spawn *spawn) { u32 type = CRYPTO_ALG_TYPE_CIPHER; u32 mask = CRYPTO_ALG_TYPE_MASK; - return __crypto_cipher_cast(crypto_spawn_tfm(spawn, type, mask)); + return __crypto_cipher_cast(crypto_spawn_tfm(&spawn->base, type, mask)); } static inline struct cipher_alg *crypto_cipher_alg(struct crypto_cipher *tfm) -- cgit v1.2.3 From a39c66cc2f6108c8346dc882bdcf72861aaca956 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Thu, 2 Jan 2020 20:04:38 -0800 Subject: crypto: shash - convert shash_free_instance() to new style Convert shash_free_instance() and its users to the new way of freeing instances, where a ->free() method is installed to the instance struct itself. This replaces the weakly-typed method crypto_template::free(). This will allow removing support for the old way of freeing instances. Also give shash_free_instance() a more descriptive name to reflect that it's only for instances with a single spawn, not for any instance. Signed-off-by: Eric Biggers Signed-off-by: Herbert Xu --- crypto/ccm.c | 5 +++-- crypto/cmac.c | 5 +++-- crypto/hmac.c | 5 +++-- crypto/shash.c | 8 ++++---- crypto/vmac.c | 5 +++-- crypto/xcbc.c | 5 +++-- include/crypto/internal/hash.h | 2 +- 7 files changed, 20 insertions(+), 15 deletions(-) (limited to 'crypto/xcbc.c') diff --git a/crypto/ccm.c b/crypto/ccm.c index f4abaefd9df5..241ecdc5c4e0 100644 --- a/crypto/ccm.c +++ b/crypto/ccm.c @@ -927,10 +927,12 @@ static int cbcmac_create(struct crypto_template *tmpl, struct rtattr **tb) inst->alg.final = crypto_cbcmac_digest_final; inst->alg.setkey = crypto_cbcmac_digest_setkey; + inst->free = shash_free_singlespawn_instance; + err = shash_register_instance(tmpl, inst); if (err) { err_free_inst: - shash_free_instance(shash_crypto_instance(inst)); + shash_free_singlespawn_instance(inst); } return err; } @@ -939,7 +941,6 @@ static struct crypto_template crypto_ccm_tmpls[] = { { .name = "cbcmac", .create = cbcmac_create, - .free = shash_free_instance, .module = THIS_MODULE, }, { .name = "ccm_base", diff --git a/crypto/cmac.c b/crypto/cmac.c index 58dc644416bb..143a6544c873 100644 --- a/crypto/cmac.c +++ b/crypto/cmac.c @@ -280,10 +280,12 @@ static int cmac_create(struct crypto_template *tmpl, struct rtattr **tb) inst->alg.final = crypto_cmac_digest_final; inst->alg.setkey = crypto_cmac_digest_setkey; + inst->free = shash_free_singlespawn_instance; + err = shash_register_instance(tmpl, inst); if (err) { err_free_inst: - shash_free_instance(shash_crypto_instance(inst)); + shash_free_singlespawn_instance(inst); } return err; } @@ -291,7 +293,6 @@ err_free_inst: static struct crypto_template crypto_cmac_tmpl = { .name = "cmac", .create = cmac_create, - .free = shash_free_instance, .module = THIS_MODULE, }; diff --git a/crypto/hmac.c b/crypto/hmac.c index 0a42b7075763..e38bfb948278 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -224,10 +224,12 @@ static int hmac_create(struct crypto_template *tmpl, struct rtattr **tb) inst->alg.init_tfm = hmac_init_tfm; inst->alg.exit_tfm = hmac_exit_tfm; + inst->free = shash_free_singlespawn_instance; + err = shash_register_instance(tmpl, inst); if (err) { err_free_inst: - shash_free_instance(shash_crypto_instance(inst)); + shash_free_singlespawn_instance(inst); } return err; } @@ -235,7 +237,6 @@ err_free_inst: static struct crypto_template hmac_tmpl = { .name = "hmac", .create = hmac_create, - .free = shash_free_instance, .module = THIS_MODULE, }; diff --git a/crypto/shash.c b/crypto/shash.c index 2f6adb49727b..e05e75b0f402 100644 --- a/crypto/shash.c +++ b/crypto/shash.c @@ -590,12 +590,12 @@ int shash_register_instance(struct crypto_template *tmpl, } EXPORT_SYMBOL_GPL(shash_register_instance); -void shash_free_instance(struct crypto_instance *inst) +void shash_free_singlespawn_instance(struct shash_instance *inst) { - crypto_drop_spawn(crypto_instance_ctx(inst)); - kfree(shash_instance(inst)); + crypto_drop_spawn(shash_instance_ctx(inst)); + kfree(inst); } -EXPORT_SYMBOL_GPL(shash_free_instance); +EXPORT_SYMBOL_GPL(shash_free_singlespawn_instance); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Synchronous cryptographic hash type"); diff --git a/crypto/vmac.c b/crypto/vmac.c index 28358a6aef9f..2d906830df96 100644 --- a/crypto/vmac.c +++ b/crypto/vmac.c @@ -660,10 +660,12 @@ static int vmac_create(struct crypto_template *tmpl, struct rtattr **tb) inst->alg.final = vmac_final; inst->alg.setkey = vmac_setkey; + inst->free = shash_free_singlespawn_instance; + err = shash_register_instance(tmpl, inst); if (err) { err_free_inst: - shash_free_instance(shash_crypto_instance(inst)); + shash_free_singlespawn_instance(inst); } return err; } @@ -671,7 +673,6 @@ err_free_inst: static struct crypto_template vmac64_tmpl = { .name = "vmac64", .create = vmac_create, - .free = shash_free_instance, .module = THIS_MODULE, }; diff --git a/crypto/xcbc.c b/crypto/xcbc.c index 9265e00ea663..598ec88abf0f 100644 --- a/crypto/xcbc.c +++ b/crypto/xcbc.c @@ -239,10 +239,12 @@ static int xcbc_create(struct crypto_template *tmpl, struct rtattr **tb) inst->alg.final = crypto_xcbc_digest_final; inst->alg.setkey = crypto_xcbc_digest_setkey; + inst->free = shash_free_singlespawn_instance; + err = shash_register_instance(tmpl, inst); if (err) { err_free_inst: - shash_free_instance(shash_crypto_instance(inst)); + shash_free_singlespawn_instance(inst); } return err; } @@ -250,7 +252,6 @@ err_free_inst: static struct crypto_template crypto_xcbc_tmpl = { .name = "xcbc", .create = xcbc_create, - .free = shash_free_instance, .module = THIS_MODULE, }; diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h index c550386221bb..89f6f46ab2b8 100644 --- a/include/crypto/internal/hash.h +++ b/include/crypto/internal/hash.h @@ -125,7 +125,7 @@ int crypto_register_shashes(struct shash_alg *algs, int count); void crypto_unregister_shashes(struct shash_alg *algs, int count); int shash_register_instance(struct crypto_template *tmpl, struct shash_instance *inst); -void shash_free_instance(struct crypto_instance *inst); +void shash_free_singlespawn_instance(struct shash_instance *inst); int crypto_grab_shash(struct crypto_shash_spawn *spawn, struct crypto_instance *inst, -- cgit v1.2.3