2023-10-03 03:44:16

by Herbert Xu

[permalink] [raw]
Subject: [PATCH 0/16] crypto: Only use common fields on skcipher spawn algs

The lskcipher conversion broke essiv. The superficial reason is
that it was missed during the lskcipher addition as it does something
similar to cryptd by being capable of both creating skciphers as well
as aead algorithms.

However, this also revealed that users of skcipher spawns were
dereferencing fields that may be specific to skcipher_alg. This
is invalid as the underlying algorithm may be an lskcipher_alg.
Only fields in skcipher_alg_common may be used.

This series adds the necessary helper for this and converts all
users of skcipher spawns to use the new helper.

The first patch is a left-over from the previous series and simply
converts arc4 to an lskcipher.

Cheers,
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


2023-10-03 03:44:43

by Herbert Xu

[permalink] [raw]
Subject: [PATCH 01/16] crypto: arc4 - Convert from skcipher to lskcipher

Replace skcipher implementation with lskcipher.

Signed-off-by: Herbert Xu <[email protected]>
---
crypto/arc4.c | 60 +++++++++++++++++++-----------------------------
crypto/testmgr.c | 2 +-
2 files changed, 24 insertions(+), 38 deletions(-)

diff --git a/crypto/arc4.c b/crypto/arc4.c
index 3254dcc34368..eb3590dc9282 100644
--- a/crypto/arc4.c
+++ b/crypto/arc4.c
@@ -7,7 +7,6 @@
* Jon Oberheide <[email protected]>
*/

-#include <crypto/algapi.h>
#include <crypto/arc4.h>
#include <crypto/internal/skcipher.h>
#include <linux/init.h>
@@ -15,33 +14,24 @@
#include <linux/module.h>
#include <linux/sched.h>

-static int crypto_arc4_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
+static int crypto_arc4_setkey(struct crypto_lskcipher *tfm, const u8 *in_key,
unsigned int key_len)
{
- struct arc4_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct arc4_ctx *ctx = crypto_lskcipher_ctx(tfm);

return arc4_setkey(ctx, in_key, key_len);
}

-static int crypto_arc4_crypt(struct skcipher_request *req)
+static int crypto_arc4_crypt(struct crypto_lskcipher *tfm, const u8 *src,
+ u8 *dst, unsigned nbytes, u8 *iv, bool final)
{
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct arc4_ctx *ctx = crypto_skcipher_ctx(tfm);
- struct skcipher_walk walk;
- int err;
+ struct arc4_ctx *ctx = crypto_lskcipher_ctx(tfm);

- err = skcipher_walk_virt(&walk, req, false);
-
- while (walk.nbytes > 0) {
- arc4_crypt(ctx, walk.dst.virt.addr, walk.src.virt.addr,
- walk.nbytes);
- err = skcipher_walk_done(&walk, 0);
- }
-
- return err;
+ arc4_crypt(ctx, dst, src, nbytes);
+ return 0;
}

-static int crypto_arc4_init(struct crypto_skcipher *tfm)
+static int crypto_arc4_init(struct crypto_lskcipher *tfm)
{
pr_warn_ratelimited("\"%s\" (%ld) uses obsolete ecb(arc4) skcipher\n",
current->comm, (unsigned long)current->pid);
@@ -49,33 +39,29 @@ static int crypto_arc4_init(struct crypto_skcipher *tfm)
return 0;
}

-static struct skcipher_alg arc4_alg = {
- /*
- * For legacy reasons, this is named "ecb(arc4)", not "arc4".
- * Nevertheless it's actually a stream cipher, not a block cipher.
- */
- .base.cra_name = "ecb(arc4)",
- .base.cra_driver_name = "ecb(arc4)-generic",
- .base.cra_priority = 100,
- .base.cra_blocksize = ARC4_BLOCK_SIZE,
- .base.cra_ctxsize = sizeof(struct arc4_ctx),
- .base.cra_module = THIS_MODULE,
- .min_keysize = ARC4_MIN_KEY_SIZE,
- .max_keysize = ARC4_MAX_KEY_SIZE,
- .setkey = crypto_arc4_setkey,
- .encrypt = crypto_arc4_crypt,
- .decrypt = crypto_arc4_crypt,
- .init = crypto_arc4_init,
+static struct lskcipher_alg arc4_alg = {
+ .co.base.cra_name = "arc4",
+ .co.base.cra_driver_name = "arc4-generic",
+ .co.base.cra_priority = 100,
+ .co.base.cra_blocksize = ARC4_BLOCK_SIZE,
+ .co.base.cra_ctxsize = sizeof(struct arc4_ctx),
+ .co.base.cra_module = THIS_MODULE,
+ .co.min_keysize = ARC4_MIN_KEY_SIZE,
+ .co.max_keysize = ARC4_MAX_KEY_SIZE,
+ .setkey = crypto_arc4_setkey,
+ .encrypt = crypto_arc4_crypt,
+ .decrypt = crypto_arc4_crypt,
+ .init = crypto_arc4_init,
};

static int __init arc4_init(void)
{
- return crypto_register_skcipher(&arc4_alg);
+ return crypto_register_lskcipher(&arc4_alg);
}

static void __exit arc4_exit(void)
{
- crypto_unregister_skcipher(&arc4_alg);
+ crypto_unregister_lskcipher(&arc4_alg);
}

subsys_initcall(arc4_init);
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index aed4a6bf47ad..5d5aee597eeb 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -4963,7 +4963,7 @@ static const struct alg_test_desc alg_test_descs[] = {
}
}, {
.alg = "ecb(arc4)",
- .generic_driver = "ecb(arc4)-generic",
+ .generic_driver = "arc4-generic",
.test = alg_test_skcipher,
.suite = {
.cipher = __VECS(arc4_tv_template)
--
2.39.2

2023-10-03 03:44:44

by Herbert Xu

[permalink] [raw]
Subject: [PATCH 02/16] crypto: skcipher - Add crypto_spawn_skcipher_alg_common

As skcipher spawns can be of two different types (skcipher vs.
lskcipher), only the common fields can be accessed. Add a helper
to return the common algorithm object.

Signed-off-by: Herbert Xu <[email protected]>
---
include/crypto/internal/skcipher.h | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/include/crypto/internal/skcipher.h b/include/crypto/internal/skcipher.h
index 4382fd707b8a..c767b5cfbd9c 100644
--- a/include/crypto/internal/skcipher.h
+++ b/include/crypto/internal/skcipher.h
@@ -160,6 +160,12 @@ static inline struct lskcipher_alg *crypto_lskcipher_spawn_alg(
return container_of(spawn->base.alg, struct lskcipher_alg, co.base);
}

+static inline struct skcipher_alg_common *crypto_spawn_skcipher_alg_common(
+ struct crypto_skcipher_spawn *spawn)
+{
+ return container_of(spawn->base.alg, struct skcipher_alg_common, base);
+}
+
static inline struct skcipher_alg *crypto_spawn_skcipher_alg(
struct crypto_skcipher_spawn *spawn)
{
--
2.39.2

2023-10-03 03:44:44

by Herbert Xu

[permalink] [raw]
Subject: [PATCH 03/16] crypto: essiv - Handle lskcipher spawns

Add code to handle an underlying lskcihper object when grabbing
an skcipher spawn.

Fixes: 31865c4c4db2 ("crypto: skcipher - Add lskcipher")
Signed-off-by: Herbert Xu <[email protected]>
---
crypto/essiv.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/crypto/essiv.c b/crypto/essiv.c
index f7d4ef4837e5..e63fc6442e32 100644
--- a/crypto/essiv.c
+++ b/crypto/essiv.c
@@ -442,6 +442,7 @@ static bool essiv_supported_algorithms(const char *essiv_cipher_name,

static int essiv_create(struct crypto_template *tmpl, struct rtattr **tb)
{
+ struct skcipher_alg_common *skcipher_alg = NULL;
struct crypto_attr_type *algt;
const char *inner_cipher_name;
const char *shash_name;
@@ -450,7 +451,6 @@ static int essiv_create(struct crypto_template *tmpl, struct rtattr **tb)
struct crypto_instance *inst;
struct crypto_alg *base, *block_base;
struct essiv_instance_ctx *ictx;
- struct skcipher_alg *skcipher_alg = NULL;
struct aead_alg *aead_alg = NULL;
struct crypto_alg *_hash_alg;
struct shash_alg *hash_alg;
@@ -475,7 +475,7 @@ static int essiv_create(struct crypto_template *tmpl, struct rtattr **tb)
mask = crypto_algt_inherited_mask(algt);

switch (type) {
- case CRYPTO_ALG_TYPE_SKCIPHER:
+ case CRYPTO_ALG_TYPE_LSKCIPHER:
skcipher_inst = kzalloc(sizeof(*skcipher_inst) +
sizeof(*ictx), GFP_KERNEL);
if (!skcipher_inst)
@@ -489,9 +489,10 @@ static int essiv_create(struct crypto_template *tmpl, struct rtattr **tb)
inner_cipher_name, 0, mask);
if (err)
goto out_free_inst;
- skcipher_alg = crypto_spawn_skcipher_alg(&ictx->u.skcipher_spawn);
+ skcipher_alg = crypto_spawn_skcipher_alg_common(
+ &ictx->u.skcipher_spawn);
block_base = &skcipher_alg->base;
- ivsize = crypto_skcipher_alg_ivsize(skcipher_alg);
+ ivsize = skcipher_alg->ivsize;
break;

case CRYPTO_ALG_TYPE_AEAD:
@@ -574,18 +575,17 @@ static int essiv_create(struct crypto_template *tmpl, struct rtattr **tb)
base->cra_alignmask = block_base->cra_alignmask;
base->cra_priority = block_base->cra_priority;

- if (type == CRYPTO_ALG_TYPE_SKCIPHER) {
+ if (type == CRYPTO_ALG_TYPE_LSKCIPHER) {
skcipher_inst->alg.setkey = essiv_skcipher_setkey;
skcipher_inst->alg.encrypt = essiv_skcipher_encrypt;
skcipher_inst->alg.decrypt = essiv_skcipher_decrypt;
skcipher_inst->alg.init = essiv_skcipher_init_tfm;
skcipher_inst->alg.exit = essiv_skcipher_exit_tfm;

- skcipher_inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(skcipher_alg);
- skcipher_inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(skcipher_alg);
+ skcipher_inst->alg.min_keysize = skcipher_alg->min_keysize;
+ skcipher_inst->alg.max_keysize = skcipher_alg->max_keysize;
skcipher_inst->alg.ivsize = ivsize;
- skcipher_inst->alg.chunksize = crypto_skcipher_alg_chunksize(skcipher_alg);
- skcipher_inst->alg.walksize = crypto_skcipher_alg_walksize(skcipher_alg);
+ skcipher_inst->alg.chunksize = skcipher_alg->chunksize;

skcipher_inst->free = essiv_skcipher_free_instance;

@@ -616,7 +616,7 @@ static int essiv_create(struct crypto_template *tmpl, struct rtattr **tb)
out_free_hash:
crypto_mod_put(_hash_alg);
out_drop_skcipher:
- if (type == CRYPTO_ALG_TYPE_SKCIPHER)
+ if (type == CRYPTO_ALG_TYPE_LSKCIPHER)
crypto_drop_skcipher(&ictx->u.skcipher_spawn);
else
crypto_drop_aead(&ictx->u.aead_spawn);
--
2.39.2

2023-10-03 03:44:45

by Herbert Xu

[permalink] [raw]
Subject: [PATCH 04/16] crypto: cryptd - Only access common skcipher fields on spawn

As skcipher spawns may be of the type lskcipher, only the common
fields may be accessed. This was already the case but use the
correct helpers to make this more obvious.

Signed-off-by: Herbert Xu <[email protected]>
---
crypto/cryptd.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/crypto/cryptd.c b/crypto/cryptd.c
index 194a92d677b9..31d022d47f7a 100644
--- a/crypto/cryptd.c
+++ b/crypto/cryptd.c
@@ -377,7 +377,7 @@ static int cryptd_create_skcipher(struct crypto_template *tmpl,
{
struct skcipherd_instance_ctx *ctx;
struct skcipher_instance *inst;
- struct skcipher_alg *alg;
+ struct skcipher_alg_common *alg;
u32 type;
u32 mask;
int err;
@@ -396,17 +396,17 @@ static int cryptd_create_skcipher(struct crypto_template *tmpl,
if (err)
goto err_free_inst;

- alg = crypto_spawn_skcipher_alg(&ctx->spawn);
+ alg = crypto_spawn_skcipher_alg_common(&ctx->spawn);
err = cryptd_init_instance(skcipher_crypto_instance(inst), &alg->base);
if (err)
goto err_free_inst;

inst->alg.base.cra_flags |= CRYPTO_ALG_ASYNC |
(alg->base.cra_flags & CRYPTO_ALG_INTERNAL);
- inst->alg.ivsize = crypto_skcipher_alg_ivsize(alg);
- inst->alg.chunksize = crypto_skcipher_alg_chunksize(alg);
- inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(alg);
- inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(alg);
+ inst->alg.ivsize = alg->ivsize;
+ inst->alg.chunksize = alg->chunksize;
+ inst->alg.min_keysize = alg->min_keysize;
+ inst->alg.max_keysize = alg->max_keysize;

inst->alg.base.cra_ctxsize = sizeof(struct cryptd_skcipher_ctx);

--
2.39.2

2023-10-03 03:44:50

by Herbert Xu

[permalink] [raw]
Subject: [PATCH 05/16] crypto: adiantum - Only access common skcipher fields on spawn

As skcipher spawns may be of the type lskcipher, only the common
fields may be accessed. This was already the case but use the
correct helpers to make this more obvious.

Signed-off-by: Herbert Xu <[email protected]>
---
crypto/adiantum.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/crypto/adiantum.c b/crypto/adiantum.c
index c33ba22a6638..51703746d91e 100644
--- a/crypto/adiantum.c
+++ b/crypto/adiantum.c
@@ -468,7 +468,7 @@ static void adiantum_free_instance(struct skcipher_instance *inst)
* Check for a supported set of inner algorithms.
* See the comment at the beginning of this file.
*/
-static bool adiantum_supported_algorithms(struct skcipher_alg *streamcipher_alg,
+static bool adiantum_supported_algorithms(struct skcipher_alg_common *streamcipher_alg,
struct crypto_alg *blockcipher_alg,
struct shash_alg *hash_alg)
{
@@ -494,7 +494,7 @@ static int adiantum_create(struct crypto_template *tmpl, struct rtattr **tb)
const char *nhpoly1305_name;
struct skcipher_instance *inst;
struct adiantum_instance_ctx *ictx;
- struct skcipher_alg *streamcipher_alg;
+ struct skcipher_alg_common *streamcipher_alg;
struct crypto_alg *blockcipher_alg;
struct shash_alg *hash_alg;
int err;
@@ -514,7 +514,7 @@ static int adiantum_create(struct crypto_template *tmpl, struct rtattr **tb)
crypto_attr_alg_name(tb[1]), 0, mask);
if (err)
goto err_free_inst;
- streamcipher_alg = crypto_spawn_skcipher_alg(&ictx->streamcipher_spawn);
+ streamcipher_alg = crypto_spawn_skcipher_alg_common(&ictx->streamcipher_spawn);

/* Block cipher, e.g. "aes" */
err = crypto_grab_cipher(&ictx->blockcipher_spawn,
@@ -578,8 +578,8 @@ static int adiantum_create(struct crypto_template *tmpl, struct rtattr **tb)
inst->alg.decrypt = adiantum_decrypt;
inst->alg.init = adiantum_init_tfm;
inst->alg.exit = adiantum_exit_tfm;
- inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(streamcipher_alg);
- inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(streamcipher_alg);
+ inst->alg.min_keysize = streamcipher_alg->min_keysize;
+ inst->alg.max_keysize = streamcipher_alg->max_keysize;
inst->alg.ivsize = TWEAK_SIZE;

inst->free = adiantum_free_instance;
--
2.39.2

2023-10-03 03:44:51

by Herbert Xu

[permalink] [raw]
Subject: [PATCH 06/16] crypto: authenc - Only access common skcipher fields on spawn

As skcipher spawns may be of the type lskcipher, only the common
fields may be accessed. This was already the case but use the
correct helpers to make this more obvious.

Signed-off-by: Herbert Xu <[email protected]>
---
crypto/authenc.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/crypto/authenc.c b/crypto/authenc.c
index 3326c7343e86..fa896ab143bd 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -373,9 +373,9 @@ static int crypto_authenc_create(struct crypto_template *tmpl,
u32 mask;
struct aead_instance *inst;
struct authenc_instance_ctx *ctx;
+ struct skcipher_alg_common *enc;
struct hash_alg_common *auth;
struct crypto_alg *auth_base;
- struct skcipher_alg *enc;
int err;

err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AEAD, &mask);
@@ -398,7 +398,7 @@ static int crypto_authenc_create(struct crypto_template *tmpl,
crypto_attr_alg_name(tb[2]), 0, mask);
if (err)
goto err_free_inst;
- enc = crypto_spawn_skcipher_alg(&ctx->enc);
+ enc = crypto_spawn_skcipher_alg_common(&ctx->enc);

ctx->reqoff = ALIGN(2 * auth->digestsize + auth_base->cra_alignmask,
auth_base->cra_alignmask + 1);
@@ -422,8 +422,8 @@ static int crypto_authenc_create(struct crypto_template *tmpl,
enc->base.cra_alignmask;
inst->alg.base.cra_ctxsize = sizeof(struct crypto_authenc_ctx);

- inst->alg.ivsize = crypto_skcipher_alg_ivsize(enc);
- inst->alg.chunksize = crypto_skcipher_alg_chunksize(enc);
+ inst->alg.ivsize = enc->ivsize;
+ inst->alg.chunksize = enc->chunksize;
inst->alg.maxauthsize = auth->digestsize;

inst->alg.init = crypto_authenc_init_tfm;
--
2.39.2

2023-10-03 03:44:52

by Herbert Xu

[permalink] [raw]
Subject: [PATCH 07/16] crypto: authencesn - Only access common skcipher fields on spawn

As skcipher spawns may be of the type lskcipher, only the common
fields may be accessed. This was already the case but use the
correct helpers to make this more obvious.

Signed-off-by: Herbert Xu <[email protected]>
---
crypto/authencesn.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/crypto/authencesn.c b/crypto/authencesn.c
index 91424e791d5c..60e9568f023f 100644
--- a/crypto/authencesn.c
+++ b/crypto/authencesn.c
@@ -390,9 +390,9 @@ static int crypto_authenc_esn_create(struct crypto_template *tmpl,
u32 mask;
struct aead_instance *inst;
struct authenc_esn_instance_ctx *ctx;
+ struct skcipher_alg_common *enc;
struct hash_alg_common *auth;
struct crypto_alg *auth_base;
- struct skcipher_alg *enc;
int err;

err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AEAD, &mask);
@@ -415,7 +415,7 @@ static int crypto_authenc_esn_create(struct crypto_template *tmpl,
crypto_attr_alg_name(tb[2]), 0, mask);
if (err)
goto err_free_inst;
- enc = crypto_spawn_skcipher_alg(&ctx->enc);
+ enc = crypto_spawn_skcipher_alg_common(&ctx->enc);

err = -ENAMETOOLONG;
if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
@@ -435,8 +435,8 @@ static int crypto_authenc_esn_create(struct crypto_template *tmpl,
enc->base.cra_alignmask;
inst->alg.base.cra_ctxsize = sizeof(struct crypto_authenc_esn_ctx);

- inst->alg.ivsize = crypto_skcipher_alg_ivsize(enc);
- inst->alg.chunksize = crypto_skcipher_alg_chunksize(enc);
+ inst->alg.ivsize = enc->ivsize;
+ inst->alg.chunksize = enc->chunksize;
inst->alg.maxauthsize = auth->digestsize;

inst->alg.init = crypto_authenc_esn_init_tfm;
--
2.39.2

2023-10-03 03:44:53

by Herbert Xu

[permalink] [raw]
Subject: [PATCH 11/16] crypto: cts - Only access common skcipher fields on spawn

As skcipher spawns may be of the type lskcipher, only the common
fields may be accessed. This was already the case but use the
correct helpers to make this more obvious.

Signed-off-by: Herbert Xu <[email protected]>
---
crypto/cts.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/crypto/cts.c b/crypto/cts.c
index 8f604f6554b1..f5b42156b6c7 100644
--- a/crypto/cts.c
+++ b/crypto/cts.c
@@ -324,8 +324,8 @@ static void crypto_cts_free(struct skcipher_instance *inst)
static int crypto_cts_create(struct crypto_template *tmpl, struct rtattr **tb)
{
struct crypto_skcipher_spawn *spawn;
+ struct skcipher_alg_common *alg;
struct skcipher_instance *inst;
- struct skcipher_alg *alg;
u32 mask;
int err;

@@ -344,10 +344,10 @@ static int crypto_cts_create(struct crypto_template *tmpl, struct rtattr **tb)
if (err)
goto err_free_inst;

- alg = crypto_spawn_skcipher_alg(spawn);
+ alg = crypto_spawn_skcipher_alg_common(spawn);

err = -EINVAL;
- if (crypto_skcipher_alg_ivsize(alg) != alg->base.cra_blocksize)
+ if (alg->ivsize != alg->base.cra_blocksize)
goto err_free_inst;

if (strncmp(alg->base.cra_name, "cbc(", 4))
@@ -363,9 +363,9 @@ static int crypto_cts_create(struct crypto_template *tmpl, struct rtattr **tb)
inst->alg.base.cra_alignmask = alg->base.cra_alignmask;

inst->alg.ivsize = alg->base.cra_blocksize;
- inst->alg.chunksize = crypto_skcipher_alg_chunksize(alg);
- inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(alg);
- inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(alg);
+ inst->alg.chunksize = alg->chunksize;
+ inst->alg.min_keysize = alg->min_keysize;
+ inst->alg.max_keysize = alg->max_keysize;

inst->alg.base.cra_ctxsize = sizeof(struct crypto_cts_ctx);

--
2.39.2

2023-10-03 03:44:53

by Herbert Xu

[permalink] [raw]
Subject: [PATCH 12/16] crypto: gcm - Only access common skcipher fields on spawn

As skcipher spawns may be of the type lskcipher, only the common
fields may be accessed. This was already the case but use the
correct helpers to make this more obvious.

Signed-off-by: Herbert Xu <[email protected]>
---
crypto/gcm.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/crypto/gcm.c b/crypto/gcm.c
index 4ba624450c3f..91ce6e0e2afc 100644
--- a/crypto/gcm.c
+++ b/crypto/gcm.c
@@ -576,10 +576,10 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl,
const char *ctr_name,
const char *ghash_name)
{
+ struct skcipher_alg_common *ctr;
u32 mask;
struct aead_instance *inst;
struct gcm_instance_ctx *ctx;
- struct skcipher_alg *ctr;
struct hash_alg_common *ghash;
int err;

@@ -607,13 +607,12 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl,
ctr_name, 0, mask);
if (err)
goto err_free_inst;
- ctr = crypto_spawn_skcipher_alg(&ctx->ctr);
+ ctr = crypto_spawn_skcipher_alg_common(&ctx->ctr);

/* The skcipher algorithm must be CTR mode, using 16-byte blocks. */
err = -EINVAL;
if (strncmp(ctr->base.cra_name, "ctr(", 4) != 0 ||
- crypto_skcipher_alg_ivsize(ctr) != 16 ||
- ctr->base.cra_blocksize != 1)
+ ctr->ivsize != 16 || ctr->base.cra_blocksize != 1)
goto err_free_inst;

err = -ENAMETOOLONG;
@@ -634,7 +633,7 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl,
ctr->base.cra_alignmask;
inst->alg.base.cra_ctxsize = sizeof(struct crypto_gcm_ctx);
inst->alg.ivsize = GCM_AES_IV_SIZE;
- inst->alg.chunksize = crypto_skcipher_alg_chunksize(ctr);
+ inst->alg.chunksize = ctr->chunksize;
inst->alg.maxauthsize = 16;
inst->alg.init = crypto_gcm_init_tfm;
inst->alg.exit = crypto_gcm_exit_tfm;
--
2.39.2

2023-10-03 03:44:55

by Herbert Xu

[permalink] [raw]
Subject: [PATCH 10/16] crypto: ctr - Only access common skcipher fields on spawn

As skcipher spawns may be of the type lskcipher, only the common
fields may be accessed. This was already the case but use the
correct helpers to make this more obvious.

Signed-off-by: Herbert Xu <[email protected]>
---
crypto/ctr.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/crypto/ctr.c b/crypto/ctr.c
index 23c698b22013..1420496062d5 100644
--- a/crypto/ctr.c
+++ b/crypto/ctr.c
@@ -258,8 +258,8 @@ static int crypto_rfc3686_create(struct crypto_template *tmpl,
struct rtattr **tb)
{
struct skcipher_instance *inst;
- struct skcipher_alg *alg;
struct crypto_skcipher_spawn *spawn;
+ struct skcipher_alg_common *alg;
u32 mask;
int err;

@@ -278,11 +278,11 @@ static int crypto_rfc3686_create(struct crypto_template *tmpl,
if (err)
goto err_free_inst;

- alg = crypto_spawn_skcipher_alg(spawn);
+ alg = crypto_spawn_skcipher_alg_common(spawn);

/* We only support 16-byte blocks. */
err = -EINVAL;
- if (crypto_skcipher_alg_ivsize(alg) != CTR_RFC3686_BLOCK_SIZE)
+ if (alg->ivsize != CTR_RFC3686_BLOCK_SIZE)
goto err_free_inst;

/* Not a stream cipher? */
@@ -303,11 +303,9 @@ static int crypto_rfc3686_create(struct crypto_template *tmpl,
inst->alg.base.cra_alignmask = alg->base.cra_alignmask;

inst->alg.ivsize = CTR_RFC3686_IV_SIZE;
- inst->alg.chunksize = crypto_skcipher_alg_chunksize(alg);
- inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(alg) +
- CTR_RFC3686_NONCE_SIZE;
- inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(alg) +
- CTR_RFC3686_NONCE_SIZE;
+ inst->alg.chunksize = alg->chunksize;
+ inst->alg.min_keysize = alg->min_keysize + CTR_RFC3686_NONCE_SIZE;
+ inst->alg.max_keysize = alg->max_keysize + CTR_RFC3686_NONCE_SIZE;

inst->alg.setkey = crypto_rfc3686_setkey;
inst->alg.encrypt = crypto_rfc3686_crypt;
--
2.39.2

2023-10-03 03:45:02

by Herbert Xu

[permalink] [raw]
Subject: [PATCH 13/16] crypto: hctr2 - Only access common skcipher fields on spawn

As skcipher spawns may be of the type lskcipher, only the common
fields may be accessed. This was already the case but use the
correct helpers to make this more obvious.

Signed-off-by: Herbert Xu <[email protected]>
---
crypto/hctr2.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/crypto/hctr2.c b/crypto/hctr2.c
index 6f4c1884d0e9..653fde727f0f 100644
--- a/crypto/hctr2.c
+++ b/crypto/hctr2.c
@@ -406,10 +406,10 @@ static int hctr2_create_common(struct crypto_template *tmpl,
const char *xctr_name,
const char *polyval_name)
{
+ struct skcipher_alg_common *xctr_alg;
u32 mask;
struct skcipher_instance *inst;
struct hctr2_instance_ctx *ictx;
- struct skcipher_alg *xctr_alg;
struct crypto_alg *blockcipher_alg;
struct shash_alg *polyval_alg;
char blockcipher_name[CRYPTO_MAX_ALG_NAME];
@@ -431,7 +431,7 @@ static int hctr2_create_common(struct crypto_template *tmpl,
xctr_name, 0, mask);
if (err)
goto err_free_inst;
- xctr_alg = crypto_spawn_skcipher_alg(&ictx->xctr_spawn);
+ xctr_alg = crypto_spawn_skcipher_alg_common(&ictx->xctr_spawn);

err = -EINVAL;
if (strncmp(xctr_alg->base.cra_name, "xctr(", 5))
@@ -500,8 +500,8 @@ static int hctr2_create_common(struct crypto_template *tmpl,
inst->alg.decrypt = hctr2_decrypt;
inst->alg.init = hctr2_init_tfm;
inst->alg.exit = hctr2_exit_tfm;
- inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(xctr_alg);
- inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(xctr_alg);
+ inst->alg.min_keysize = xctr_alg->min_keysize;
+ inst->alg.max_keysize = xctr_alg->max_keysize;
inst->alg.ivsize = TWEAK_SIZE;

inst->free = hctr2_free_instance;
--
2.39.2

2023-10-03 03:45:08

by Herbert Xu

[permalink] [raw]
Subject: [PATCH 14/16] crypto: lrw - Only access common skcipher fields on spawn

As skcipher spawns may be of the type lskcipher, only the common
fields may be accessed. This was already the case but use the
correct helpers to make this more obvious.

Signed-off-by: Herbert Xu <[email protected]>
---
crypto/lrw.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/crypto/lrw.c b/crypto/lrw.c
index 59260aefed28..e216fbf2b786 100644
--- a/crypto/lrw.c
+++ b/crypto/lrw.c
@@ -299,8 +299,8 @@ static void lrw_free_instance(struct skcipher_instance *inst)
static int lrw_create(struct crypto_template *tmpl, struct rtattr **tb)
{
struct crypto_skcipher_spawn *spawn;
+ struct skcipher_alg_common *alg;
struct skcipher_instance *inst;
- struct skcipher_alg *alg;
const char *cipher_name;
char ecb_name[CRYPTO_MAX_ALG_NAME];
u32 mask;
@@ -336,13 +336,13 @@ static int lrw_create(struct crypto_template *tmpl, struct rtattr **tb)
if (err)
goto err_free_inst;

- alg = crypto_skcipher_spawn_alg(spawn);
+ alg = crypto_spawn_skcipher_alg_common(spawn);

err = -EINVAL;
if (alg->base.cra_blocksize != LRW_BLOCK_SIZE)
goto err_free_inst;

- if (crypto_skcipher_alg_ivsize(alg))
+ if (alg->ivsize)
goto err_free_inst;

err = crypto_inst_setname(skcipher_crypto_instance(inst), "lrw",
@@ -382,10 +382,8 @@ static int lrw_create(struct crypto_template *tmpl, struct rtattr **tb)
(__alignof__(be128) - 1);

inst->alg.ivsize = LRW_BLOCK_SIZE;
- inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(alg) +
- LRW_BLOCK_SIZE;
- inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(alg) +
- LRW_BLOCK_SIZE;
+ inst->alg.min_keysize = alg->min_keysize + LRW_BLOCK_SIZE;
+ inst->alg.max_keysize = alg->max_keysize + LRW_BLOCK_SIZE;

inst->alg.base.cra_ctxsize = sizeof(struct lrw_tfm_ctx);

--
2.39.2

2023-10-03 03:46:06

by Herbert Xu

[permalink] [raw]
Subject: [PATCH 15/16] crypto: xts - Only access common skcipher fields on spawn

As skcipher spawns may be of the type lskcipher, only the common
fields may be accessed. This was already the case but use the
correct helpers to make this more obvious.

Signed-off-by: Herbert Xu <[email protected]>
---
crypto/xts.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/crypto/xts.c b/crypto/xts.c
index 548b302c6c6a..9237b1433367 100644
--- a/crypto/xts.c
+++ b/crypto/xts.c
@@ -338,9 +338,9 @@ static void xts_free_instance(struct skcipher_instance *inst)

static int xts_create(struct crypto_template *tmpl, struct rtattr **tb)
{
+ struct skcipher_alg_common *alg;
struct skcipher_instance *inst;
struct xts_instance_ctx *ctx;
- struct skcipher_alg *alg;
const char *cipher_name;
u32 mask;
int err;
@@ -375,13 +375,13 @@ static int xts_create(struct crypto_template *tmpl, struct rtattr **tb)
if (err)
goto err_free_inst;

- alg = crypto_skcipher_spawn_alg(&ctx->spawn);
+ alg = crypto_spawn_skcipher_alg_common(&ctx->spawn);

err = -EINVAL;
if (alg->base.cra_blocksize != XTS_BLOCK_SIZE)
goto err_free_inst;

- if (crypto_skcipher_alg_ivsize(alg))
+ if (alg->ivsize)
goto err_free_inst;

err = crypto_inst_setname(skcipher_crypto_instance(inst), "xts",
@@ -421,8 +421,8 @@ static int xts_create(struct crypto_template *tmpl, struct rtattr **tb)
(__alignof__(u64) - 1);

inst->alg.ivsize = XTS_BLOCK_SIZE;
- inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(alg) * 2;
- inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(alg) * 2;
+ inst->alg.min_keysize = alg->min_keysize * 2;
+ inst->alg.max_keysize = alg->max_keysize * 2;

inst->alg.base.cra_ctxsize = sizeof(struct xts_tfm_ctx);

--
2.39.2

2023-10-03 03:46:06

by Herbert Xu

[permalink] [raw]
Subject: [PATCH 16/16] crypto: skcipher - Remove obsolete skcipher_alg helpers

As skcipher spawn users can no longer assume the spawn is of type
struct skcipher_alg, these helpers are no longer used. Remove them.

Signed-off-by: Herbert Xu <[email protected]>
---
include/crypto/internal/skcipher.h | 42 ------------------------------
include/crypto/skcipher.h | 25 +-----------------
2 files changed, 1 insertion(+), 66 deletions(-)

diff --git a/include/crypto/internal/skcipher.h b/include/crypto/internal/skcipher.h
index c767b5cfbd9c..7ae42afdcf3e 100644
--- a/include/crypto/internal/skcipher.h
+++ b/include/crypto/internal/skcipher.h
@@ -148,12 +148,6 @@ static inline void crypto_drop_lskcipher(struct crypto_lskcipher_spawn *spawn)
crypto_drop_spawn(&spawn->base);
}

-static inline struct skcipher_alg *crypto_skcipher_spawn_alg(
- struct crypto_skcipher_spawn *spawn)
-{
- return container_of(spawn->base.alg, struct skcipher_alg, base);
-}
-
static inline struct lskcipher_alg *crypto_lskcipher_spawn_alg(
struct crypto_lskcipher_spawn *spawn)
{
@@ -166,12 +160,6 @@ static inline struct skcipher_alg_common *crypto_spawn_skcipher_alg_common(
return container_of(spawn->base.alg, struct skcipher_alg_common, base);
}

-static inline struct skcipher_alg *crypto_spawn_skcipher_alg(
- struct crypto_skcipher_spawn *spawn)
-{
- return crypto_skcipher_spawn_alg(spawn);
-}
-
static inline struct lskcipher_alg *crypto_spawn_lskcipher_alg(
struct crypto_lskcipher_spawn *spawn)
{
@@ -269,36 +257,6 @@ static inline u32 skcipher_request_flags(struct skcipher_request *req)
return req->base.flags;
}

-static inline unsigned int crypto_skcipher_alg_min_keysize(
- struct skcipher_alg *alg)
-{
- return alg->min_keysize;
-}
-
-static inline unsigned int crypto_skcipher_alg_max_keysize(
- struct skcipher_alg *alg)
-{
- return alg->max_keysize;
-}
-
-static inline unsigned int crypto_skcipher_alg_walksize(
- struct skcipher_alg *alg)
-{
- return alg->walksize;
-}
-
-static inline unsigned int crypto_lskcipher_alg_min_keysize(
- struct lskcipher_alg *alg)
-{
- return alg->co.min_keysize;
-}
-
-static inline unsigned int crypto_lskcipher_alg_max_keysize(
- struct lskcipher_alg *alg)
-{
- return alg->co.max_keysize;
-}
-
/* Helpers for simple block cipher modes of operation */
struct skcipher_ctx_simple {
struct crypto_cipher *cipher; /* underlying block cipher */
diff --git a/include/crypto/skcipher.h b/include/crypto/skcipher.h
index a648ef5ce897..ea18af48346b 100644
--- a/include/crypto/skcipher.h
+++ b/include/crypto/skcipher.h
@@ -395,17 +395,6 @@ static inline struct lskcipher_alg *crypto_lskcipher_alg(
struct lskcipher_alg, co.base);
}

-static inline unsigned int crypto_skcipher_alg_ivsize(struct skcipher_alg *alg)
-{
- return alg->ivsize;
-}
-
-static inline unsigned int crypto_lskcipher_alg_ivsize(
- struct lskcipher_alg *alg)
-{
- return alg->co.ivsize;
-}
-
/**
* crypto_skcipher_ivsize() - obtain IV size
* @tfm: cipher handle
@@ -473,18 +462,6 @@ static inline unsigned int crypto_lskcipher_blocksize(
return crypto_tfm_alg_blocksize(crypto_lskcipher_tfm(tfm));
}

-static inline unsigned int crypto_skcipher_alg_chunksize(
- struct skcipher_alg *alg)
-{
- return alg->chunksize;
-}
-
-static inline unsigned int crypto_lskcipher_alg_chunksize(
- struct lskcipher_alg *alg)
-{
- return alg->co.chunksize;
-}
-
/**
* crypto_skcipher_chunksize() - obtain chunk size
* @tfm: cipher handle
@@ -516,7 +493,7 @@ static inline unsigned int crypto_skcipher_chunksize(
static inline unsigned int crypto_lskcipher_chunksize(
struct crypto_lskcipher *tfm)
{
- return crypto_lskcipher_alg_chunksize(crypto_lskcipher_alg(tfm));
+ return crypto_lskcipher_alg(tfm)->co.chunksize;
}

static inline unsigned int crypto_sync_skcipher_blocksize(
--
2.39.2

2023-10-03 03:48:36

by Herbert Xu

[permalink] [raw]
Subject: [PATCH 08/16] crypto: ccm - Only access common skcipher fields on spawn

As skcipher spawns may be of the type lskcipher, only the common
fields may be accessed. This was already the case but use the
correct helpers to make this more obvious.

Signed-off-by: Herbert Xu <[email protected]>
---
crypto/ccm.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/crypto/ccm.c b/crypto/ccm.c
index a9453129c51c..7af89a5b745c 100644
--- a/crypto/ccm.c
+++ b/crypto/ccm.c
@@ -447,10 +447,10 @@ static int crypto_ccm_create_common(struct crypto_template *tmpl,
const char *ctr_name,
const char *mac_name)
{
+ struct skcipher_alg_common *ctr;
u32 mask;
struct aead_instance *inst;
struct ccm_instance_ctx *ictx;
- struct skcipher_alg *ctr;
struct hash_alg_common *mac;
int err;

@@ -478,13 +478,12 @@ static int crypto_ccm_create_common(struct crypto_template *tmpl,
ctr_name, 0, mask);
if (err)
goto err_free_inst;
- ctr = crypto_spawn_skcipher_alg(&ictx->ctr);
+ ctr = crypto_spawn_skcipher_alg_common(&ictx->ctr);

/* The skcipher algorithm must be CTR mode, using 16-byte blocks. */
err = -EINVAL;
if (strncmp(ctr->base.cra_name, "ctr(", 4) != 0 ||
- crypto_skcipher_alg_ivsize(ctr) != 16 ||
- ctr->base.cra_blocksize != 1)
+ ctr->ivsize != 16 || ctr->base.cra_blocksize != 1)
goto err_free_inst;

/* ctr and cbcmac must use the same underlying block cipher. */
@@ -507,7 +506,7 @@ static int crypto_ccm_create_common(struct crypto_template *tmpl,
inst->alg.base.cra_alignmask = mac->base.cra_alignmask |
ctr->base.cra_alignmask;
inst->alg.ivsize = 16;
- inst->alg.chunksize = crypto_skcipher_alg_chunksize(ctr);
+ inst->alg.chunksize = ctr->chunksize;
inst->alg.maxauthsize = 16;
inst->alg.base.cra_ctxsize = sizeof(struct crypto_ccm_ctx);
inst->alg.init = crypto_ccm_init_tfm;
--
2.39.2

2023-10-03 03:48:39

by Herbert Xu

[permalink] [raw]
Subject: [PATCH 09/16] crypto: chacha20poly1305 - Only access common skcipher fields on spawn

As skcipher spawns may be of the type lskcipher, only the common
fields may be accessed. This was already the case but use the
correct helpers to make this more obvious.

Signed-off-by: Herbert Xu <[email protected]>
---
crypto/chacha20poly1305.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/crypto/chacha20poly1305.c b/crypto/chacha20poly1305.c
index 3a905c5d8f53..0e2e208d98f9 100644
--- a/crypto/chacha20poly1305.c
+++ b/crypto/chacha20poly1305.c
@@ -558,7 +558,7 @@ static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb,
u32 mask;
struct aead_instance *inst;
struct chachapoly_instance_ctx *ctx;
- struct skcipher_alg *chacha;
+ struct skcipher_alg_common *chacha;
struct hash_alg_common *poly;
int err;

@@ -579,7 +579,7 @@ static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb,
crypto_attr_alg_name(tb[1]), 0, mask);
if (err)
goto err_free_inst;
- chacha = crypto_spawn_skcipher_alg(&ctx->chacha);
+ chacha = crypto_spawn_skcipher_alg_common(&ctx->chacha);

err = crypto_grab_ahash(&ctx->poly, aead_crypto_instance(inst),
crypto_attr_alg_name(tb[2]), 0, mask);
@@ -591,7 +591,7 @@ static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb,
if (poly->digestsize != POLY1305_DIGEST_SIZE)
goto err_free_inst;
/* Need 16-byte IV size, including Initial Block Counter value */
- if (crypto_skcipher_alg_ivsize(chacha) != CHACHA_IV_SIZE)
+ if (chacha->ivsize != CHACHA_IV_SIZE)
goto err_free_inst;
/* Not a stream cipher? */
if (chacha->base.cra_blocksize != 1)
@@ -615,7 +615,7 @@ static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb,
inst->alg.base.cra_ctxsize = sizeof(struct chachapoly_ctx) +
ctx->saltlen;
inst->alg.ivsize = ivsize;
- inst->alg.chunksize = crypto_skcipher_alg_chunksize(chacha);
+ inst->alg.chunksize = chacha->chunksize;
inst->alg.maxauthsize = POLY1305_DIGEST_SIZE;
inst->alg.init = chachapoly_init;
inst->alg.exit = chachapoly_exit;
--
2.39.2

2023-10-03 11:40:09

by Shinichiro Kawasaki

[permalink] [raw]
Subject: Re: [PATCH 0/16] crypto: Only use common fields on skcipher spawn algs

On Oct 03, 2023 / 11:43, Herbert Xu wrote:
> The lskcipher conversion broke essiv. The superficial reason is
> that it was missed during the lskcipher addition as it does something
> similar to cryptd by being capable of both creating skciphers as well
> as aead algorithms.
>
> However, this also revealed that users of skcipher spawns were
> dereferencing fields that may be specific to skcipher_alg. This
> is invalid as the underlying algorithm may be an lskcipher_alg.
> Only fields in skcipher_alg_common may be used.
>
> This series adds the necessary helper for this and converts all
> users of skcipher spawns to use the new helper.

Thanks Herbert. I applied this series on top of the kernel next-20230929 and
confirmed the failure I reported [1] goes away. Also I ran my test sets on some
dm-crypt devices and saw no regression. Looks good from testing point of view.

[1] https://lore.kernel.org/dm-devel/4u6ffcrzr5xg6tzoczkfnuqy7v2e3w6243oxdsu3g4uughh6go@6owks5linnxi/