Skip to content

Commit

Permalink
crypto: skcipher - Add skcipher_ialg_simple helper
Browse files Browse the repository at this point in the history
This patch introduces the skcipher_ialg_simple helper which fetches
the crypto_alg structure from a simple skcipher instance's spawn.

This allows us to remove the third argument from the function
skcipher_alloc_instance_simple.

In doing so the reference count to the algorithm is now maintained
by the Crypto API and the caller no longer needs to drop the alg
refcount.

Signed-off-by: Herbert Xu <[email protected]>
  • Loading branch information
herbertx committed Dec 27, 2019
1 parent 93e23eb commit b3c16bf
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 43 deletions.
15 changes: 7 additions & 8 deletions crypto/cbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,12 @@ static int crypto_cbc_create(struct crypto_template *tmpl, struct rtattr **tb)
struct crypto_alg *alg;
int err;

inst = skcipher_alloc_instance_simple(tmpl, tb, &alg);
inst = skcipher_alloc_instance_simple(tmpl, tb);
if (IS_ERR(inst))
return PTR_ERR(inst);

alg = skcipher_ialg_simple(inst);

err = -EINVAL;
if (!is_power_of_2(alg->cra_blocksize))
goto out_free_inst;
Expand All @@ -66,14 +68,11 @@ static int crypto_cbc_create(struct crypto_template *tmpl, struct rtattr **tb)
inst->alg.decrypt = crypto_cbc_decrypt;

err = skcipher_register_instance(tmpl, inst);
if (err)
goto out_free_inst;
goto out_put_alg;

if (err) {
out_free_inst:
inst->free(inst);
out_put_alg:
crypto_mod_put(alg);
inst->free(inst);
}

return err;
}

Expand Down
5 changes: 3 additions & 2 deletions crypto/cfb.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,12 @@ static int crypto_cfb_create(struct crypto_template *tmpl, struct rtattr **tb)
struct crypto_alg *alg;
int err;

inst = skcipher_alloc_instance_simple(tmpl, tb, &alg);
inst = skcipher_alloc_instance_simple(tmpl, tb);
if (IS_ERR(inst))
return PTR_ERR(inst);

alg = skcipher_ialg_simple(inst);

/* CFB mode is a stream cipher. */
inst->alg.base.cra_blocksize = 1;

Expand All @@ -223,7 +225,6 @@ static int crypto_cfb_create(struct crypto_template *tmpl, struct rtattr **tb)
if (err)
inst->free(inst);

crypto_mod_put(alg);
return err;
}

Expand Down
15 changes: 7 additions & 8 deletions crypto/ctr.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,12 @@ static int crypto_ctr_create(struct crypto_template *tmpl, struct rtattr **tb)
struct crypto_alg *alg;
int err;

inst = skcipher_alloc_instance_simple(tmpl, tb, &alg);
inst = skcipher_alloc_instance_simple(tmpl, tb);
if (IS_ERR(inst))
return PTR_ERR(inst);

alg = skcipher_ialg_simple(inst);

/* Block size must be >= 4 bytes. */
err = -EINVAL;
if (alg->cra_blocksize < 4)
Expand All @@ -155,14 +157,11 @@ static int crypto_ctr_create(struct crypto_template *tmpl, struct rtattr **tb)
inst->alg.decrypt = crypto_ctr_crypt;

err = skcipher_register_instance(tmpl, inst);
if (err)
goto out_free_inst;
goto out_put_alg;

if (err) {
out_free_inst:
inst->free(inst);
out_put_alg:
crypto_mod_put(alg);
inst->free(inst);
}

return err;
}

Expand Down
5 changes: 2 additions & 3 deletions crypto/ecb.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,9 @@ static int crypto_ecb_decrypt(struct skcipher_request *req)
static int crypto_ecb_create(struct crypto_template *tmpl, struct rtattr **tb)
{
struct skcipher_instance *inst;
struct crypto_alg *alg;
int err;

inst = skcipher_alloc_instance_simple(tmpl, tb, &alg);
inst = skcipher_alloc_instance_simple(tmpl, tb);
if (IS_ERR(inst))
return PTR_ERR(inst);

Expand All @@ -76,7 +75,7 @@ static int crypto_ecb_create(struct crypto_template *tmpl, struct rtattr **tb)
err = skcipher_register_instance(tmpl, inst);
if (err)
inst->free(inst);
crypto_mod_put(alg);

return err;
}

Expand Down
15 changes: 7 additions & 8 deletions crypto/keywrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,12 @@ static int crypto_kw_create(struct crypto_template *tmpl, struct rtattr **tb)
struct crypto_alg *alg;
int err;

inst = skcipher_alloc_instance_simple(tmpl, tb, &alg);
inst = skcipher_alloc_instance_simple(tmpl, tb);
if (IS_ERR(inst))
return PTR_ERR(inst);

alg = skcipher_ialg_simple(inst);

err = -EINVAL;
/* Section 5.1 requirement for KW */
if (alg->cra_blocksize != sizeof(struct crypto_kw_block))
Expand All @@ -283,14 +285,11 @@ static int crypto_kw_create(struct crypto_template *tmpl, struct rtattr **tb)
inst->alg.decrypt = crypto_kw_decrypt;

err = skcipher_register_instance(tmpl, inst);
if (err)
goto out_free_inst;
goto out_put_alg;

if (err) {
out_free_inst:
inst->free(inst);
out_put_alg:
crypto_mod_put(alg);
inst->free(inst);
}

return err;
}

Expand Down
5 changes: 3 additions & 2 deletions crypto/ofb.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,12 @@ static int crypto_ofb_create(struct crypto_template *tmpl, struct rtattr **tb)
struct crypto_alg *alg;
int err;

inst = skcipher_alloc_instance_simple(tmpl, tb, &alg);
inst = skcipher_alloc_instance_simple(tmpl, tb);
if (IS_ERR(inst))
return PTR_ERR(inst);

alg = skcipher_ialg_simple(inst);

/* OFB mode is a stream cipher. */
inst->alg.base.cra_blocksize = 1;

Expand All @@ -75,7 +77,6 @@ static int crypto_ofb_create(struct crypto_template *tmpl, struct rtattr **tb)
if (err)
inst->free(inst);

crypto_mod_put(alg);
return err;
}

Expand Down
5 changes: 2 additions & 3 deletions crypto/pcbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,9 @@ static int crypto_pcbc_decrypt(struct skcipher_request *req)
static int crypto_pcbc_create(struct crypto_template *tmpl, struct rtattr **tb)
{
struct skcipher_instance *inst;
struct crypto_alg *alg;
int err;

inst = skcipher_alloc_instance_simple(tmpl, tb, &alg);
inst = skcipher_alloc_instance_simple(tmpl, tb);
if (IS_ERR(inst))
return PTR_ERR(inst);

Expand All @@ -166,7 +165,7 @@ static int crypto_pcbc_create(struct crypto_template *tmpl, struct rtattr **tb)
err = skcipher_register_instance(tmpl, inst);
if (err)
inst->free(inst);
crypto_mod_put(alg);

return err;
}

Expand Down
9 changes: 3 additions & 6 deletions crypto/skcipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -938,15 +938,12 @@ static void skcipher_free_instance_simple(struct skcipher_instance *inst)
*
* @tmpl: the template being instantiated
* @tb: the template parameters
* @cipher_alg_ret: on success, a pointer to the underlying cipher algorithm is
* returned here. It must be dropped with crypto_mod_put().
*
* Return: a pointer to the new instance, or an ERR_PTR(). The caller still
* needs to register the instance.
*/
struct skcipher_instance *
skcipher_alloc_instance_simple(struct crypto_template *tmpl, struct rtattr **tb,
struct crypto_alg **cipher_alg_ret)
struct skcipher_instance *skcipher_alloc_instance_simple(
struct crypto_template *tmpl, struct rtattr **tb)
{
struct crypto_attr_type *algt;
struct crypto_alg *cipher_alg;
Expand Down Expand Up @@ -982,6 +979,7 @@ skcipher_alloc_instance_simple(struct crypto_template *tmpl, struct rtattr **tb,
if (err)
goto err_free_inst;

spawn->dropref = true;
err = crypto_init_spawn(spawn, cipher_alg,
skcipher_crypto_instance(inst),
CRYPTO_ALG_TYPE_MASK);
Expand All @@ -1003,7 +1001,6 @@ skcipher_alloc_instance_simple(struct crypto_template *tmpl, struct rtattr **tb,
inst->alg.init = skcipher_init_tfm_simple;
inst->alg.exit = skcipher_exit_tfm_simple;

*cipher_alg_ret = cipher_alg;
return inst;

err_free_inst:
Expand Down
14 changes: 11 additions & 3 deletions include/crypto/internal/skcipher.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,17 @@ skcipher_cipher_simple(struct crypto_skcipher *tfm)

return ctx->cipher;
}
struct skcipher_instance *
skcipher_alloc_instance_simple(struct crypto_template *tmpl, struct rtattr **tb,
struct crypto_alg **cipher_alg_ret);

struct skcipher_instance *skcipher_alloc_instance_simple(
struct crypto_template *tmpl, struct rtattr **tb);

static inline struct crypto_alg *skcipher_ialg_simple(
struct skcipher_instance *inst)
{
struct crypto_spawn *spawn = skcipher_instance_ctx(inst);

return spawn->alg;
}

#endif /* _CRYPTO_INTERNAL_SKCIPHER_H */

0 comments on commit b3c16bf

Please sign in to comment.