Skip to contentSkip to conversation

crypto: stop supporting alignmask in shash

PATCH In review Eric Biggers 2 participants 19 messages Oct 19, 2023 – Oct 27, 2023

Subsystems (8)
lore
Share & tools
lore
#0 lore raw

cover crypto: stop supporting alignmask in shash

The alignmask support in the shash algorithm type is virtually unused and has no real point. This patch series removes it in order to reduce API overhead and complexity.

This series does not change anything for ahash.

Eric Biggers (17):
crypto: sparc/crc32c - stop using the shash alignmask
crypto: stm32 - remove unnecessary alignmask
crypto: xilinx/zynqmp-sha - remove unnecessary alignmask
crypto: mips/crc32 - remove redundant setting of alignmask to 0
crypto: loongarch/crc32 - remove redundant setting of alignmask to 0
crypto: cbcmac - remove unnecessary alignment logic
crypto: cmac - remove unnecessary alignment logic
crypto: hmac - remove unnecessary alignment logic
crypto: vmac - don't set alignmask
crypto: xcbc - remove unnecessary alignment logic
crypto: shash - remove support for nonzero alignmask
libceph: stop checking crypto_shash_alignmask
crypto: drbg - stop checking crypto_shash_alignmask
crypto: testmgr - stop checking crypto_shash_alignmask
crypto: adiantum - stop using alignmask of shash_alg
crypto: hctr2 - stop using alignmask of shash_alg
crypto: shash - remove crypto_shash_alignmask

 arch/loongarch/crypto/crc32-loongarch.c |   2 -
 arch/mips/crypto/crc32-mips.c           |   2 -
 arch/sparc/crypto/crc32c_glue.c         |  45 +++++----
 crypto/adiantum.c                       |   3 +-
 crypto/ccm.c                            |  17 ++--
 crypto/cmac.c                           |  39 ++------
 crypto/drbg.c                           |   2 +-
 crypto/hctr2.c                          |   3 +-
 crypto/hmac.c                           |  56 ++++-------
 crypto/shash.c                          | 128 ++----------------------
 crypto/testmgr.c                        |   5 +-
 crypto/vmac.c                           |   1 -
 crypto/xcbc.c                           |  32 ++----
 drivers/crypto/stm32/stm32-crc32.c      |   2 -
 drivers/crypto/xilinx/zynqmp-sha.c      |   1 -
 include/crypto/hash.h                   |   6 --
 net/ceph/messenger_v2.c                 |   4 -
 17 files changed, 87 insertions(+), 261 deletions(-)

base-commit: 5b90073defd1a52aa8120403d79f6e0fc10c87ee
prerequisite-patch-id: 77bd65b07cfc27f172b1698e0c4d43d6aba7ad8f
prerequisite-patch-id: 3ccf94d7048db0fee9407b5b5fa48554e115b56b
prerequisite-patch-id: e447f81a392f2f3955206357d72032cf691c7e11

Signature · 1 line
2.42.0
#1 lore raw

PATCH 1/17 crypto: sparc/crc32c - stop using the shash alignmask

From: Eric Biggers <[email protected]>

As far as I can tell, "crc32c-sparc64" is the only "shash" algorithm in the kernel that sets a nonzero alignmask and actually relies on it to get the crypto API to align the inputs and outputs. This capability is not really useful, though. To unblock removing the support for alignmask from shash_alg, this patch updates crc32c-sparc64 to no longer use the alignmask. This means doing 8-byte alignment of the data when doing an update, using get_unaligned_le32() when setting a non-default initial CRC, and using put_unaligned_le32() to output the final CRC.

Partially tested with:

export ARCH=sparc64 CROSS_COMPILE=sparc64-linux-gnu- make sparc64_defconfig
echo CONFIG_CRYPTO_CRC32C_SPARC64=y >> .config
echo '# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set' >> .config echo CONFIG_DEBUG_KERNEL=y >> .config
echo CONFIG_CRYPTO_MANAGER_EXTRA_TESTS=y >> .config make olddefconfig
make -j$(getconf _NPROCESSORS_ONLN)
qemu-system-sparc64 -kernel arch/sparc/boot/image -nographic

However, qemu doesn't actually support the sparc CRC32C instructions, so for the test I temporarily replaced crc32c_sparc64() with __crc32c_le() and made sparc64_has_crc32c_opcode() always return true. So essentially I tested the glue code, not the actual SPARC part which is unchanged.

---
 arch/sparc/crypto/crc32c_glue.c | 45 ++++++++++++++++++---------------
 1 file changed, 24 insertions(+), 21 deletions(-)
arch/sparc/crypto/crc32c_glue.c +24 -21
index 82efb7f81c288..688db0dcb97d9 100644
@@ -13,97 +13,101 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/crc32.h>
 
 #include <crypto/internal/hash.h>
 
 #include <asm/pstate.h>
 #include <asm/elf.h>
+#include <asm/unaligned.h>
 
 #include "opcodes.h"
 
 /*
  * Setting the seed allows arbitrary accumulators and flexible XOR policy
  * If your algorithm starts with ~0, then XOR with ~0 before you set
  * the seed.
  */
 static int crc32c_sparc64_setkey(struct crypto_shash *hash, const u8 *key,
 				 unsigned int keylen)
 {
 	u32 *mctx = crypto_shash_ctx(hash);
 
 	if (keylen != sizeof(u32))
 		return -EINVAL;
-	*mctx = le32_to_cpup((__le32 *)key);
+	*mctx = get_unaligned_le32(key);
 	return 0;
 }
 
 static int crc32c_sparc64_init(struct shash_desc *desc)
 {
 	u32 *mctx = crypto_shash_ctx(desc->tfm);
 	u32 *crcp = shash_desc_ctx(desc);
 
 	*crcp = *mctx;
 
 	return 0;
 }
 
 extern void crc32c_sparc64(u32 *crcp, const u64 *data, unsigned int len);
 
-static void crc32c_compute(u32 *crcp, const u64 *data, unsigned int len)
+static u32 crc32c_compute(u32 crc, const u8 *data, unsigned int len)
 {
-	unsigned int asm_len;
-
-	asm_len = len & ~7U;
-	if (asm_len) {
-		crc32c_sparc64(crcp, data, asm_len);
-		data += asm_len / 8;
-		len -= asm_len;
+	unsigned int n = -(uintptr_t)data & 7;
+
+	if (n) {
+		/* Data isn't 8-byte aligned.  Align it. */
+		n = min(n, len);
+		crc = __crc32c_le(crc, data, n);
+		data += n;
+		len -= n;
+	}
+	n = len & ~7U;
+	if (n) {
+		crc32c_sparc64(&crc, (const u64 *)data, n);
+		data += n;
+		len -= n;
 	}
 	if (len)
-		*crcp = __crc32c_le(*crcp, (const unsigned char *) data, len);
+		crc = __crc32c_le(crc, data, len);
+	return crc;
 }
 
 static int crc32c_sparc64_update(struct shash_desc *desc, const u8 *data,
 				 unsigned int len)
 {
 	u32 *crcp = shash_desc_ctx(desc);
 
-	crc32c_compute(crcp, (const u64 *) data, len);
-
+	*crcp = crc32c_compute(*crcp, data, len);
 	return 0;
 }
 
-static int __crc32c_sparc64_finup(u32 *crcp, const u8 *data, unsigned int len,
-				  u8 *out)
+static int __crc32c_sparc64_finup(const u32 *crcp, const u8 *data,
+				  unsigned int len, u8 *out)
 {
-	u32 tmp = *crcp;
-
-	crc32c_compute(&tmp, (const u64 *) data, len);
-
-	*(__le32 *) out = ~cpu_to_le32(tmp);
+	put_unaligned_le32(~crc32c_compute(*crcp, data, len), out);
 	return 0;
 }
 
 static int crc32c_sparc64_finup(struct shash_desc *desc, const u8 *data,
 				unsigned int len, u8 *out)
 {
 	return __crc32c_sparc64_finup(shash_desc_ctx(desc), data, len, out);
 }
 
 static int crc32c_sparc64_final(struct shash_desc *desc, u8 *out)
 {
 	u32 *crcp = shash_desc_ctx(desc);
 
-	*(__le32 *) out = ~cpu_to_le32p(crcp);
+	put_unaligned_le32(~*crcp, out);
 	return 0;
 }
 
 static int crc32c_sparc64_digest(struct shash_desc *desc, const u8 *data,
 				 unsigned int len, u8 *out)
 {
 	return __crc32c_sparc64_finup(crypto_shash_ctx(desc->tfm), data, len,
 				      out);
 }
 
@@ -128,21 +132,20 @@ static struct shash_alg alg = {
 	.digest			=	crc32c_sparc64_digest,
 	.descsize		=	sizeof(u32),
 	.digestsize		=	CHKSUM_DIGEST_SIZE,
 	.base			=	{
 		.cra_name		=	"crc32c",
 		.cra_driver_name	=	"crc32c-sparc64",
 		.cra_priority		=	SPARC_CR_OPCODE_PRIORITY,
 		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
 		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
 		.cra_ctxsize		=	sizeof(u32),
-		.cra_alignmask		=	7,
 		.cra_module		=	THIS_MODULE,
 		.cra_init		=	crc32c_sparc64_cra_init,
 	}
 };
 
 static bool __init sparc64_has_crc32c_opcode(void)
 {
 	unsigned long cfr;
 
 	if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
Signature · 1 line
2.42.0
#2 lore raw

PATCH 2/17 crypto: stm32 - remove unnecessary alignmask

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

The stm32 crc32 algorithms set a nonzero alignmask, but they don't seem to actually need it. Their ->update function already has code that handles aligning the data to the same alignment that the alignmask specifies, their ->setkey function already uses get_unaligned_le32(), and their ->final function already uses put_unaligned_le32(). Therefore, stop setting the alignmask. This will allow these algorithms to keep being registered after alignmask support is removed from shash.

---
 drivers/crypto/stm32/stm32-crc32.c | 2 --
 1 file changed, 2 deletions(-)
drivers/crypto/stm32/stm32-crc32.c +0 -2
index 90a920e7f6642..fa4fec31fcfc4 100644
@@ -276,21 +276,20 @@ static struct shash_alg algs[] = {
 		.finup          = stm32_crc_finup,
 		.digest         = stm32_crc_digest,
 		.descsize       = sizeof(struct stm32_crc_desc_ctx),
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32",
 			.cra_driver_name        = "stm32-crc32-crc32",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,
-			.cra_alignmask          = 3,
 			.cra_ctxsize            = sizeof(struct stm32_crc_ctx),
 			.cra_module             = THIS_MODULE,
 			.cra_init               = stm32_crc32_cra_init,
 		}
 	},
 	/* CRC-32Castagnoli */
 	{
 		.setkey         = stm32_crc_setkey,
 		.init           = stm32_crc_init,
 		.update         = stm32_crc_update,
@@ -298,21 +297,20 @@ static struct shash_alg algs[] = {
 		.finup          = stm32_crc_finup,
 		.digest         = stm32_crc_digest,
 		.descsize       = sizeof(struct stm32_crc_desc_ctx),
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32c",
 			.cra_driver_name        = "stm32-crc32-crc32c",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,
-			.cra_alignmask          = 3,
 			.cra_ctxsize            = sizeof(struct stm32_crc_ctx),
 			.cra_module             = THIS_MODULE,
 			.cra_init               = stm32_crc32c_cra_init,
 		}
 	}
 };
 
 static int stm32_crc_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
Signature · 1 line
2.42.0
#3 lore raw

PATCH 3/17 crypto: xilinx/zynqmp-sha - remove unnecessary alignmask

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

The zynqmp-sha3-384 algorithm sets a nonzero alignmask, but it doesn't appear to actually need it. Therefore, stop setting it. This will allow this algorithm to keep being registered after alignmask support is removed from shash.

---
 drivers/crypto/xilinx/zynqmp-sha.c | 1 -
 1 file changed, 1 deletion(-)
drivers/crypto/xilinx/zynqmp-sha.c +0 -1
index 426bf1a72ba66..b0dbf6263b0db 100644
@@ -175,21 +175,20 @@ static struct zynqmp_sha_drv_ctx sha3_drv_ctx = {
 		.digestsize = SHA3_384_DIGEST_SIZE,
 		.base = {
 			.cra_name = "sha3-384",
 			.cra_driver_name = "zynqmp-sha3-384",
 			.cra_priority = 300,
 			.cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY |
 				     CRYPTO_ALG_ALLOCATES_MEMORY |
 				     CRYPTO_ALG_NEED_FALLBACK,
 			.cra_blocksize = SHA3_384_BLOCK_SIZE,
 			.cra_ctxsize = sizeof(struct zynqmp_sha_tfm_ctx),
-			.cra_alignmask = 3,
 			.cra_module = THIS_MODULE,
 		}
 	}
 };
 
 static int zynqmp_sha_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	int err;
 	u32 v;
Signature · 1 line
2.42.0
#4 lore raw

PATCH 4/17 crypto: mips/crc32 - remove redundant setting of alignmask to 0

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

This unnecessary explicit setting of cra_alignmask to 0 shows up when grepping for shash algorithms that set an alignmask. Remove it. No change in behavior.

---
 arch/mips/crypto/crc32-mips.c | 2 --
 1 file changed, 2 deletions(-)
arch/mips/crypto/crc32-mips.c +0 -2
index 3e4f5ba104f89..ec6d58008f8e1 100644
@@ -283,21 +283,20 @@ static struct shash_alg crc32_alg = {
 	.final			=	chksum_final,
 	.finup			=	chksum_finup,
 	.digest			=	chksum_digest,
 	.descsize		=	sizeof(struct chksum_desc_ctx),
 	.base			=	{
 		.cra_name		=	"crc32",
 		.cra_driver_name	=	"crc32-mips-hw",
 		.cra_priority		=	300,
 		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
 		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
-		.cra_alignmask		=	0,
 		.cra_ctxsize		=	sizeof(struct chksum_ctx),
 		.cra_module		=	THIS_MODULE,
 		.cra_init		=	chksum_cra_init,
 	}
 };
 
 static struct shash_alg crc32c_alg = {
 	.digestsize		=	CHKSUM_DIGEST_SIZE,
 	.setkey			=	chksum_setkey,
 	.init			=	chksum_init,
@@ -305,21 +304,20 @@ static struct shash_alg crc32c_alg = {
 	.final			=	chksumc_final,
 	.finup			=	chksumc_finup,
 	.digest			=	chksumc_digest,
 	.descsize		=	sizeof(struct chksum_desc_ctx),
 	.base			=	{
 		.cra_name		=	"crc32c",
 		.cra_driver_name	=	"crc32c-mips-hw",
 		.cra_priority		=	300,
 		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
 		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
-		.cra_alignmask		=	0,
 		.cra_ctxsize		=	sizeof(struct chksum_ctx),
 		.cra_module		=	THIS_MODULE,
 		.cra_init		=	chksum_cra_init,
 	}
 };
 
 static int __init crc32_mod_init(void)
 {
 	int err;
 
Signature · 1 line
2.42.0
#5 lore raw

PATCH 5/17 crypto: loongarch/crc32 - remove redundant setting of alignmask to 0

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

This unnecessary explicit setting of cra_alignmask to 0 shows up when grepping for shash algorithms that set an alignmask. Remove it. No change in behavior.

---
 arch/loongarch/crypto/crc32-loongarch.c | 2 --
 1 file changed, 2 deletions(-)
arch/loongarch/crypto/crc32-loongarch.c +0 -2
index 1f2a2c3839bcb..a49e507af38c0 100644
@@ -232,21 +232,20 @@ static struct shash_alg crc32_alg = {
 	.final			=	chksum_final,
 	.finup			=	chksum_finup,
 	.digest			=	chksum_digest,
 	.descsize		=	sizeof(struct chksum_desc_ctx),
 	.base			=	{
 		.cra_name		=	"crc32",
 		.cra_driver_name	=	"crc32-loongarch",
 		.cra_priority		=	300,
 		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
 		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
-		.cra_alignmask		=	0,
 		.cra_ctxsize		=	sizeof(struct chksum_ctx),
 		.cra_module		=	THIS_MODULE,
 		.cra_init		=	chksum_cra_init,
 	}
 };
 
 static struct shash_alg crc32c_alg = {
 	.digestsize		=	CHKSUM_DIGEST_SIZE,
 	.setkey			=	chksum_setkey,
 	.init			=	chksum_init,
@@ -254,21 +253,20 @@ static struct shash_alg crc32c_alg = {
 	.final			=	chksumc_final,
 	.finup			=	chksumc_finup,
 	.digest			=	chksumc_digest,
 	.descsize		=	sizeof(struct chksum_desc_ctx),
 	.base			=	{
 		.cra_name		=	"crc32c",
 		.cra_driver_name	=	"crc32c-loongarch",
 		.cra_priority		=	300,
 		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
 		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
-		.cra_alignmask		=	0,
 		.cra_ctxsize		=	sizeof(struct chksum_ctx),
 		.cra_module		=	THIS_MODULE,
 		.cra_init		=	chksumc_cra_init,
 	}
 };
 
 static int __init crc32_mod_init(void)
 {
 	int err;
 
Signature · 1 line
2.42.0
#6 lore raw

PATCH 6/17 crypto: cbcmac - remove unnecessary alignment logic

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

The cbcmac template is aligning a field in its desc context to the alignmask of its underlying 'cipher', at runtime. This is almost entirely pointless, since cbcmac is already using the cipher API functions that handle alignment themselves, and few ciphers set a nonzero alignmask anyway. Also, even without runtime alignment, an alignment of at least 4 bytes can be guaranteed.

Thus, at best this code is optimizing for the rare case of ciphers that set an alignmask >= 7, at the cost of hurting the common cases.

Therefore, remove the manual alignment code from cbcmac.

---
 crypto/ccm.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)
crypto/ccm.c +7 -10
index 7af89a5b745c4..dd7aed63efc93 100644
@@ -49,20 +49,21 @@ struct crypto_ccm_req_priv_ctx {
 		struct skcipher_request skreq;
 	};
 };
 
 struct cbcmac_tfm_ctx {
 	struct crypto_cipher *child;
 };
 
 struct cbcmac_desc_ctx {
 	unsigned int len;
+	u8 dg[];
 };
 
 static inline struct crypto_ccm_req_priv_ctx *crypto_ccm_reqctx(
 	struct aead_request *req)
 {
 	unsigned long align = crypto_aead_alignmask(crypto_aead_reqtfm(req));
 
 	return (void *)PTR_ALIGN((u8 *)aead_request_ctx(req), align + 1);
 }
 
@@ -778,68 +779,65 @@ static int crypto_cbcmac_digest_setkey(struct crypto_shash *parent,
 {
 	struct cbcmac_tfm_ctx *ctx = crypto_shash_ctx(parent);
 
 	return crypto_cipher_setkey(ctx->child, inkey, keylen);
 }
 
 static int crypto_cbcmac_digest_init(struct shash_desc *pdesc)
 {
 	struct cbcmac_desc_ctx *ctx = shash_desc_ctx(pdesc);
 	int bs = crypto_shash_digestsize(pdesc->tfm);
-	u8 *dg = (u8 *)ctx + crypto_shash_descsize(pdesc->tfm) - bs;
 
 	ctx->len = 0;
-	memset(dg, 0, bs);
+	memset(ctx->dg, 0, bs);
 
 	return 0;
 }
 
 static int crypto_cbcmac_digest_update(struct shash_desc *pdesc, const u8 *p,
 				       unsigned int len)
 {
 	struct crypto_shash *parent = pdesc->tfm;
 	struct cbcmac_tfm_ctx *tctx = crypto_shash_ctx(parent);
 	struct cbcmac_desc_ctx *ctx = shash_desc_ctx(pdesc);
 	struct crypto_cipher *tfm = tctx->child;
 	int bs = crypto_shash_digestsize(parent);
-	u8 *dg = (u8 *)ctx + crypto_shash_descsize(parent) - bs;
 
 	while (len > 0) {
 		unsigned int l = min(len, bs - ctx->len);
 
-		crypto_xor(dg + ctx->len, p, l);
+		crypto_xor(&ctx->dg[ctx->len], p, l);
 		ctx->len +=l;
 		len -= l;
 		p += l;
 
 		if (ctx->len == bs) {
-			crypto_cipher_encrypt_one(tfm, dg, dg);
+			crypto_cipher_encrypt_one(tfm, ctx->dg, ctx->dg);
 			ctx->len = 0;
 		}
 	}
 
 	return 0;
 }
 
 static int crypto_cbcmac_digest_final(struct shash_desc *pdesc, u8 *out)
 {
 	struct crypto_shash *parent = pdesc->tfm;
 	struct cbcmac_tfm_ctx *tctx = crypto_shash_ctx(parent);
 	struct cbcmac_desc_ctx *ctx = shash_desc_ctx(pdesc);
 	struct crypto_cipher *tfm = tctx->child;
 	int bs = crypto_shash_digestsize(parent);
-	u8 *dg = (u8 *)ctx + crypto_shash_descsize(parent) - bs;
 
 	if (ctx->len)
-		crypto_cipher_encrypt_one(tfm, dg, dg);
+		crypto_cipher_encrypt_one(tfm, ctx->dg, ctx->dg);
 
-	memcpy(out, dg, bs);
+	memcpy(out, ctx->dg, bs);
 	return 0;
 }
 
 static int cbcmac_init_tfm(struct crypto_tfm *tfm)
 {
 	struct crypto_cipher *cipher;
 	struct crypto_instance *inst = (void *)tfm->__crt_alg;
 	struct crypto_cipher_spawn *spawn = crypto_instance_ctx(inst);
 	struct cbcmac_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
 
@@ -882,22 +880,21 @@ static int cbcmac_create(struct crypto_template *tmpl, struct rtattr **tb)
 	alg = crypto_spawn_cipher_alg(spawn);
 
 	err = crypto_inst_setname(shash_crypto_instance(inst), tmpl->name, alg);
 	if (err)
 		goto err_free_inst;
 
 	inst->alg.base.cra_priority = alg->cra_priority;
 	inst->alg.base.cra_blocksize = 1;
 
 	inst->alg.digestsize = alg->cra_blocksize;
-	inst->alg.descsize = ALIGN(sizeof(struct cbcmac_desc_ctx),
-				   alg->cra_alignmask + 1) +
+	inst->alg.descsize = sizeof(struct cbcmac_desc_ctx) +
 			     alg->cra_blocksize;
 
 	inst->alg.base.cra_ctxsize = sizeof(struct cbcmac_tfm_ctx);
 	inst->alg.base.cra_init = cbcmac_init_tfm;
 	inst->alg.base.cra_exit = cbcmac_exit_tfm;
 
 	inst->alg.init = crypto_cbcmac_digest_init;
 	inst->alg.update = crypto_cbcmac_digest_update;
 	inst->alg.final = crypto_cbcmac_digest_final;
 	inst->alg.setkey = crypto_cbcmac_digest_setkey;
Signature · 1 line
2.42.0
#7 lore raw

PATCH 7/17 crypto: cmac - remove unnecessary alignment logic

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

The cmac template is setting its alignmask to that of its underlying 'cipher'. Yet, it doesn't care itself about how its inputs and outputs are aligned, which is ostensibly the point of the alignmask. Instead, cmac actually just uses its alignmask itself to runtime-align certain fields in its tfm and desc contexts appropriately for its underlying cipher. That is almost entirely pointless too, though, since cmac is already using the cipher API functions that handle alignment themselves, and few ciphers set a nonzero alignmask anyway. Also, even without runtime alignment, an alignment of at least 4 bytes can be guaranteed.

Thus, at best this code is optimizing for the rare case of ciphers that set an alignmask >= 7, at the cost of hurting the common cases.

Therefore, this patch removes the manual alignment code from cmac and makes it stop setting an alignmask.

---
 crypto/cmac.c | 39 +++++++++++----------------------------
 1 file changed, 11 insertions(+), 28 deletions(-)
crypto/cmac.c +11 -28
index fce6b0f58e88e..c7aa3665b076e 100644
@@ -21,47 +21,45 @@
  * +------------------------
  * | <parent tfm>
  * +------------------------
  * | cmac_tfm_ctx
  * +------------------------
  * | consts (block size * 2)
  * +------------------------
  */
 struct cmac_tfm_ctx {
 	struct crypto_cipher *child;
-	u8 ctx[];
+	__be64 consts[];
 };
 
 /*
  * +------------------------
  * | <shash desc>
  * +------------------------
  * | cmac_desc_ctx
  * +------------------------
  * | odds (block size)
  * +------------------------
  * | prev (block size)
  * +------------------------
  */
 struct cmac_desc_ctx {
 	unsigned int len;
-	u8 ctx[];
+	u8 odds[];
 };
 
 static int crypto_cmac_digest_setkey(struct crypto_shash *parent,
 				     const u8 *inkey, unsigned int keylen)
 {
-	unsigned long alignmask = crypto_shash_alignmask(parent);
 	struct cmac_tfm_ctx *ctx = crypto_shash_ctx(parent);
 	unsigned int bs = crypto_shash_blocksize(parent);
-	__be64 *consts = PTR_ALIGN((void *)ctx->ctx,
-				   (alignmask | (__alignof__(__be64) - 1)) + 1);
+	__be64 *consts = ctx->consts;
 	u64 _const[2];
 	int i, err = 0;
 	u8 msb_mask, gfmask;
 
 	err = crypto_cipher_setkey(ctx->child, inkey, keylen);
 	if (err)
 		return err;
 
 	/* encrypt the zero block */
 	memset(consts, 0, bs);
@@ -97,41 +95,39 @@ static int crypto_cmac_digest_setkey(struct crypto_shash *parent,
 		}
 
 		break;
 	}
 
 	return 0;
 }
 
 static int crypto_cmac_digest_init(struct shash_desc *pdesc)
 {
-	unsigned long alignmask = crypto_shash_alignmask(pdesc->tfm);
 	struct cmac_desc_ctx *ctx = shash_desc_ctx(pdesc);
 	int bs = crypto_shash_blocksize(pdesc->tfm);
-	u8 *prev = PTR_ALIGN((void *)ctx->ctx, alignmask + 1) + bs;
+	u8 *prev = &ctx->odds[bs];
 
 	ctx->len = 0;
 	memset(prev, 0, bs);
 
 	return 0;
 }
 
 static int crypto_cmac_digest_update(struct shash_desc *pdesc, const u8 *p,
 				     unsigned int len)
 {
 	struct crypto_shash *parent = pdesc->tfm;
-	unsigned long alignmask = crypto_shash_alignmask(parent);
 	struct cmac_tfm_ctx *tctx = crypto_shash_ctx(parent);
 	struct cmac_desc_ctx *ctx = shash_desc_ctx(pdesc);
 	struct crypto_cipher *tfm = tctx->child;
 	int bs = crypto_shash_blocksize(parent);
-	u8 *odds = PTR_ALIGN((void *)ctx->ctx, alignmask + 1);
+	u8 *odds = ctx->odds;
 	u8 *prev = odds + bs;
 
 	/* checking the data can fill the block */
 	if ((ctx->len + len) <= bs) {
 		memcpy(odds + ctx->len, p, len);
 		ctx->len += len;
 		return 0;
 	}
 
 	/* filling odds with new data and encrypting it */
@@ -158,47 +154,44 @@ static int crypto_cmac_digest_update(struct shash_desc *pdesc, const u8 *p,
 		memcpy(odds, p, len);
 		ctx->len = len;
 	}
 
 	return 0;
 }
 
 static int crypto_cmac_digest_final(struct shash_desc *pdesc, u8 *out)
 {
 	struct crypto_shash *parent = pdesc->tfm;
-	unsigned long alignmask = crypto_shash_alignmask(parent);
 	struct cmac_tfm_ctx *tctx = crypto_shash_ctx(parent);
 	struct cmac_desc_ctx *ctx = shash_desc_ctx(pdesc);
 	struct crypto_cipher *tfm = tctx->child;
 	int bs = crypto_shash_blocksize(parent);
-	u8 *consts = PTR_ALIGN((void *)tctx->ctx,
-			       (alignmask | (__alignof__(__be64) - 1)) + 1);
-	u8 *odds = PTR_ALIGN((void *)ctx->ctx, alignmask + 1);
+	u8 *odds = ctx->odds;
 	u8 *prev = odds + bs;
 	unsigned int offset = 0;
 
 	if (ctx->len != bs) {
 		unsigned int rlen;
 		u8 *p = odds + ctx->len;
 
 		*p = 0x80;
 		p++;
 
 		rlen = bs - ctx->len - 1;
 		if (rlen)
 			memset(p, 0, rlen);
 
 		offset += bs;
 	}
 
 	crypto_xor(prev, odds, bs);
-	crypto_xor(prev, consts + offset, bs);
+	crypto_xor(prev, (const u8 *)tctx->consts + offset, bs);
 
 	crypto_cipher_encrypt_one(tfm, out, prev);
 
 	return 0;
 }
 
 static int cmac_init_tfm(struct crypto_shash *tfm)
 {
 	struct shash_instance *inst = shash_alg_instance(tfm);
 	struct cmac_tfm_ctx *ctx = crypto_shash_ctx(tfm);
@@ -234,21 +227,20 @@ static void cmac_exit_tfm(struct crypto_shash *tfm)
 {
 	struct cmac_tfm_ctx *ctx = crypto_shash_ctx(tfm);
 	crypto_free_cipher(ctx->child);
 }
 
 static int cmac_create(struct crypto_template *tmpl, struct rtattr **tb)
 {
 	struct shash_instance *inst;
 	struct crypto_cipher_spawn *spawn;
 	struct crypto_alg *alg;
-	unsigned long alignmask;
 	u32 mask;
 	int err;
 
 	err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH, &mask);
 	if (err)
 		return err;
 
 	inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
 	if (!inst)
 		return -ENOMEM;
@@ -266,37 +258,28 @@ static int cmac_create(struct crypto_template *tmpl, struct rtattr **tb)
 		break;
 	default:
 		err = -EINVAL;
 		goto err_free_inst;
 	}
 
 	err = crypto_inst_setname(shash_crypto_instance(inst), tmpl->name, alg);
 	if (err)
 		goto err_free_inst;
 
-	alignmask = alg->cra_alignmask;
-	inst->alg.base.cra_alignmask = alignmask;
 	inst->alg.base.cra_priority = alg->cra_priority;
 	inst->alg.base.cra_blocksize = alg->cra_blocksize;
+	inst->alg.base.cra_ctxsize = sizeof(struct cmac_tfm_ctx) +
+				     alg->cra_blocksize * 2;
 
 	inst->alg.digestsize = alg->cra_blocksize;
-	inst->alg.descsize =
-		ALIGN(sizeof(struct cmac_desc_ctx), crypto_tfm_ctx_alignment())
-		+ (alignmask & ~(crypto_tfm_ctx_alignment() - 1))
-		+ alg->cra_blocksize * 2;
-
-	inst->alg.base.cra_ctxsize =
-		ALIGN(sizeof(struct cmac_tfm_ctx), crypto_tfm_ctx_alignment())
-		+ ((alignmask | (__alignof__(__be64) - 1)) &
-		   ~(crypto_tfm_ctx_alignment() - 1))
-		+ alg->cra_blocksize * 2;
-
+	inst->alg.descsize = sizeof(struct cmac_desc_ctx) +
+			     alg->cra_blocksize * 2;
 	inst->alg.init = crypto_cmac_digest_init;
 	inst->alg.update = crypto_cmac_digest_update;
 	inst->alg.final = crypto_cmac_digest_final;
 	inst->alg.setkey = crypto_cmac_digest_setkey;
 	inst->alg.init_tfm = cmac_init_tfm;
 	inst->alg.clone_tfm = cmac_clone_tfm;
 	inst->alg.exit_tfm = cmac_exit_tfm;
 
 	inst->free = shash_free_singlespawn_instance;
 
Signature · 1 line
2.42.0
#8 lore raw

PATCH 8/17 crypto: hmac - remove unnecessary alignment logic

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

The hmac template is setting its alignmask to that of its underlying unkeyed hash algorithm, and it is aligning the ipad and opad fields in its tfm context to that alignment. However, hmac does not actually need any sort of alignment itself, which makes this pointless except to keep the pads aligned to what the underlying algorithm prefers. But very few shash algorithms actually set an alignmask, and it is being removed from those remaining ones; also, after setkey, the pads are only passed to crypto_shash_import and crypto_shash_export which ignore the alignmask.

Therefore, make the hmac template stop setting an alignmask and simply use natural alignment for ipad and opad. Note, this change also moves the pads from the beginning of the tfm context to the end, which makes much more sense; the variable-length fields should be at the end.

---
 crypto/hmac.c | 56 ++++++++++++++++++++-------------------------------
 1 file changed, 22 insertions(+), 34 deletions(-)
crypto/hmac.c +22 -34
index ea93f4c55f251..7cec25ff98891 100644
@@ -17,45 +17,34 @@
 #include <linux/err.h>
 #include <linux/fips.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/scatterlist.h>
 #include <linux/string.h>
 
 struct hmac_ctx {
 	struct crypto_shash *hash;
+	/* Contains 'u8 ipad[statesize];', then 'u8 opad[statesize];' */
+	u8 pads[];
 };
 
-static inline void *align_ptr(void *p, unsigned int align)
-{
-	return (void *)ALIGN((unsigned long)p, align);
-}
-
-static inline struct hmac_ctx *hmac_ctx(struct crypto_shash *tfm)
-{
-	return align_ptr(crypto_shash_ctx_aligned(tfm) +
-			 crypto_shash_statesize(tfm) * 2,
-			 crypto_tfm_ctx_alignment());
-}
-
 static int hmac_setkey(struct crypto_shash *parent,
 		       const u8 *inkey, unsigned int keylen)
 {
 	int bs = crypto_shash_blocksize(parent);
 	int ds = crypto_shash_digestsize(parent);
 	int ss = crypto_shash_statesize(parent);
-	char *ipad = crypto_shash_ctx_aligned(parent);
-	char *opad = ipad + ss;
-	struct hmac_ctx *ctx = align_ptr(opad + ss,
-					 crypto_tfm_ctx_alignment());
-	struct crypto_shash *hash = ctx->hash;
+	struct hmac_ctx *tctx = crypto_shash_ctx(parent);
+	struct crypto_shash *hash = tctx->hash;
+	u8 *ipad = &tctx->pads[0];
+	u8 *opad = &tctx->pads[ss];
 	SHASH_DESC_ON_STACK(shash, hash);
 	unsigned int i;
 
 	if (fips_enabled && (keylen < 112 / 8))
 		return -EINVAL;
 
 	shash->tfm = hash;
 
 	if (keylen > bs) {
 		int err;
@@ -87,105 +76,109 @@ static int hmac_setkey(struct crypto_shash *parent,
 static int hmac_export(struct shash_desc *pdesc, void *out)
 {
 	struct shash_desc *desc = shash_desc_ctx(pdesc);
 
 	return crypto_shash_export(desc, out);
 }
 
 static int hmac_import(struct shash_desc *pdesc, const void *in)
 {
 	struct shash_desc *desc = shash_desc_ctx(pdesc);
-	struct hmac_ctx *ctx = hmac_ctx(pdesc->tfm);
+	const struct hmac_ctx *tctx = crypto_shash_ctx(pdesc->tfm);
 
-	desc->tfm = ctx->hash;
+	desc->tfm = tctx->hash;
 
 	return crypto_shash_import(desc, in);
 }
 
 static int hmac_init(struct shash_desc *pdesc)
 {
-	return hmac_import(pdesc, crypto_shash_ctx_aligned(pdesc->tfm));
+	const struct hmac_ctx *tctx = crypto_shash_ctx(pdesc->tfm);
+
+	return hmac_import(pdesc, &tctx->pads[0]);
 }
 
 static int hmac_update(struct shash_desc *pdesc,
 		       const u8 *data, unsigned int nbytes)
 {
 	struct shash_desc *desc = shash_desc_ctx(pdesc);
 
 	return crypto_shash_update(desc, data, nbytes);
 }
 
 static int hmac_final(struct shash_desc *pdesc, u8 *out)
 {
 	struct crypto_shash *parent = pdesc->tfm;
 	int ds = crypto_shash_digestsize(parent);
 	int ss = crypto_shash_statesize(parent);
-	char *opad = crypto_shash_ctx_aligned(parent) + ss;
+	const struct hmac_ctx *tctx = crypto_shash_ctx(parent);
+	const u8 *opad = &tctx->pads[ss];
 	struct shash_desc *desc = shash_desc_ctx(pdesc);
 
 	return crypto_shash_final(desc, out) ?:
 	       crypto_shash_import(desc, opad) ?:
 	       crypto_shash_finup(desc, out, ds, out);
 }
 
 static int hmac_finup(struct shash_desc *pdesc, const u8 *data,
 		      unsigned int nbytes, u8 *out)
 {
 
 	struct crypto_shash *parent = pdesc->tfm;
 	int ds = crypto_shash_digestsize(parent);
 	int ss = crypto_shash_statesize(parent);
-	char *opad = crypto_shash_ctx_aligned(parent) + ss;
+	const struct hmac_ctx *tctx = crypto_shash_ctx(parent);
+	const u8 *opad = &tctx->pads[ss];
 	struct shash_desc *desc = shash_desc_ctx(pdesc);
 
 	return crypto_shash_finup(desc, data, nbytes, out) ?:
 	       crypto_shash_import(desc, opad) ?:
 	       crypto_shash_finup(desc, out, ds, out);
 }
 
 static int hmac_init_tfm(struct crypto_shash *parent)
 {
 	struct crypto_shash *hash;
 	struct shash_instance *inst = shash_alg_instance(parent);
 	struct crypto_shash_spawn *spawn = shash_instance_ctx(inst);
-	struct hmac_ctx *ctx = hmac_ctx(parent);
+	struct hmac_ctx *tctx = crypto_shash_ctx(parent);
 
 	hash = crypto_spawn_shash(spawn);
 	if (IS_ERR(hash))
 		return PTR_ERR(hash);
 
 	parent->descsize = sizeof(struct shash_desc) +
 			   crypto_shash_descsize(hash);
 
-	ctx->hash = hash;
+	tctx->hash = hash;
 	return 0;
 }
 
 static int hmac_clone_tfm(struct crypto_shash *dst, struct crypto_shash *src)
 {
-	struct hmac_ctx *sctx = hmac_ctx(src);
-	struct hmac_ctx *dctx = hmac_ctx(dst);
+	struct hmac_ctx *sctx = crypto_shash_ctx(src);
+	struct hmac_ctx *dctx = crypto_shash_ctx(dst);
 	struct crypto_shash *hash;
 
 	hash = crypto_clone_shash(sctx->hash);
 	if (IS_ERR(hash))
 		return PTR_ERR(hash);
 
 	dctx->hash = hash;
 	return 0;
 }
 
 static void hmac_exit_tfm(struct crypto_shash *parent)
 {
-	struct hmac_ctx *ctx = hmac_ctx(parent);
+	struct hmac_ctx *tctx = crypto_shash_ctx(parent);
 
-	crypto_free_shash(ctx->hash);
+	crypto_free_shash(tctx->hash);
 }
 
 static int hmac_create(struct crypto_template *tmpl, struct rtattr **tb)
 {
 	struct shash_instance *inst;
 	struct crypto_shash_spawn *spawn;
 	struct crypto_alg *alg;
 	struct shash_alg *salg;
 	u32 mask;
 	int err;
@@ -218,29 +211,24 @@ static int hmac_create(struct crypto_template *tmpl, struct rtattr **tb)
 	if (ds > alg->cra_blocksize ||
 	    ss < alg->cra_blocksize)
 		goto err_free_inst;
 
 	err = crypto_inst_setname(shash_crypto_instance(inst), tmpl->name, alg);
 	if (err)
 		goto err_free_inst;
 
 	inst->alg.base.cra_priority = alg->cra_priority;
 	inst->alg.base.cra_blocksize = alg->cra_blocksize;
-	inst->alg.base.cra_alignmask = alg->cra_alignmask;
+	inst->alg.base.cra_ctxsize = sizeof(struct hmac_ctx) + (ss * 2);
 
-	ss = ALIGN(ss, alg->cra_alignmask + 1);
 	inst->alg.digestsize = ds;
 	inst->alg.statesize = ss;
-
-	inst->alg.base.cra_ctxsize = sizeof(struct hmac_ctx) +
-				     ALIGN(ss * 2, crypto_tfm_ctx_alignment());
-
 	inst->alg.init = hmac_init;
 	inst->alg.update = hmac_update;
 	inst->alg.final = hmac_final;
 	inst->alg.finup = hmac_finup;
 	inst->alg.export = hmac_export;
 	inst->alg.import = hmac_import;
 	inst->alg.setkey = hmac_setkey;
 	inst->alg.init_tfm = hmac_init_tfm;
 	inst->alg.clone_tfm = hmac_clone_tfm;
 	inst->alg.exit_tfm = hmac_exit_tfm;
Signature · 1 line
2.42.0
#9 lore raw

PATCH 9/17 crypto: vmac - don't set alignmask

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

The vmac template is setting its alignmask to that of its underlying 'cipher'. This doesn't actually accomplish anything useful, though, so stop doing it. (vmac_update() does have an alignment bug, where it assumes u64 alignment when it shouldn't, but that bug exists both before and after this patch.) This is a prerequisite for removing support for nonzero alignmasks from shash.

---
 crypto/vmac.c | 1 -
 1 file changed, 1 deletion(-)
crypto/vmac.c +0 -1
index 4633b2dda1e0a..0a1d8efa6c1a6 100644
@@ -642,21 +642,20 @@ static int vmac_create(struct crypto_template *tmpl, struct rtattr **tb)
 	err = -EINVAL;
 	if (alg->cra_blocksize != VMAC_NONCEBYTES)
 		goto err_free_inst;
 
 	err = crypto_inst_setname(shash_crypto_instance(inst), tmpl->name, alg);
 	if (err)
 		goto err_free_inst;
 
 	inst->alg.base.cra_priority = alg->cra_priority;
 	inst->alg.base.cra_blocksize = alg->cra_blocksize;
-	inst->alg.base.cra_alignmask = alg->cra_alignmask;
 
 	inst->alg.base.cra_ctxsize = sizeof(struct vmac_tfm_ctx);
 	inst->alg.base.cra_init = vmac_init_tfm;
 	inst->alg.base.cra_exit = vmac_exit_tfm;
 
 	inst->alg.descsize = sizeof(struct vmac_desc_ctx);
 	inst->alg.digestsize = VMAC_TAG_LEN / 8;
 	inst->alg.init = vmac_init;
 	inst->alg.update = vmac_update;
 	inst->alg.final = vmac_final;
Signature · 1 line
2.42.0
#10 lore raw

PATCH 10/17 crypto: xcbc - remove unnecessary alignment logic

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

The xcbc template is setting its alignmask to that of its underlying 'cipher'. Yet, it doesn't care itself about how its inputs and outputs are aligned, which is ostensibly the point of the alignmask. Instead, xcbc actually just uses its alignmask itself to runtime-align certain fields in its tfm and desc contexts appropriately for its underlying cipher. That is almost entirely pointless too, though, since xcbc is already using the cipher API functions that handle alignment themselves, and few ciphers set a nonzero alignmask anyway. Also, even without runtime alignment, an alignment of at least 4 bytes can be guaranteed.

Thus, at best this code is optimizing for the rare case of ciphers that set an alignmask >= 7, at the cost of hurting the common cases.

Therefore, this patch removes the manual alignment code from xcbc and makes it stop setting an alignmask.

---
 crypto/xcbc.c | 32 ++++++++++----------------------
 1 file changed, 10 insertions(+), 22 deletions(-)
crypto/xcbc.c +10 -22
index 6074c5c1da492..a9e8ee9c1949c 100644
@@ -20,85 +20,82 @@ static u_int32_t ks[12] = {0x01010101, 0x01010101, 0x01010101, 0x01010101,
  * +------------------------
  * | <parent tfm>
  * +------------------------
  * | xcbc_tfm_ctx
  * +------------------------
  * | consts (block size * 2)
  * +------------------------
  */
 struct xcbc_tfm_ctx {
 	struct crypto_cipher *child;
-	u8 ctx[];
+	u8 consts[];
 };
 
 /*
  * +------------------------
  * | <shash desc>
  * +------------------------
  * | xcbc_desc_ctx
  * +------------------------
  * | odds (block size)
  * +------------------------
  * | prev (block size)
  * +------------------------
  */
 struct xcbc_desc_ctx {
 	unsigned int len;
-	u8 ctx[];
+	u8 odds[];
 };
 
 #define XCBC_BLOCKSIZE	16
 
 static int crypto_xcbc_digest_setkey(struct crypto_shash *parent,
 				     const u8 *inkey, unsigned int keylen)
 {
-	unsigned long alignmask = crypto_shash_alignmask(parent);
 	struct xcbc_tfm_ctx *ctx = crypto_shash_ctx(parent);
-	u8 *consts = PTR_ALIGN(&ctx->ctx[0], alignmask + 1);
+	u8 *consts = ctx->consts;
 	int err = 0;
 	u8 key1[XCBC_BLOCKSIZE];
 	int bs = sizeof(key1);
 
 	if ((err = crypto_cipher_setkey(ctx->child, inkey, keylen)))
 		return err;
 
 	crypto_cipher_encrypt_one(ctx->child, consts, (u8 *)ks + bs);
 	crypto_cipher_encrypt_one(ctx->child, consts + bs, (u8 *)ks + bs * 2);
 	crypto_cipher_encrypt_one(ctx->child, key1, (u8 *)ks);
 
 	return crypto_cipher_setkey(ctx->child, key1, bs);
 
 }
 
 static int crypto_xcbc_digest_init(struct shash_desc *pdesc)
 {
-	unsigned long alignmask = crypto_shash_alignmask(pdesc->tfm);
 	struct xcbc_desc_ctx *ctx = shash_desc_ctx(pdesc);
 	int bs = crypto_shash_blocksize(pdesc->tfm);
-	u8 *prev = PTR_ALIGN(&ctx->ctx[0], alignmask + 1) + bs;
+	u8 *prev = &ctx->odds[bs];
 
 	ctx->len = 0;
 	memset(prev, 0, bs);
 
 	return 0;
 }
 
 static int crypto_xcbc_digest_update(struct shash_desc *pdesc, const u8 *p,
 				     unsigned int len)
 {
 	struct crypto_shash *parent = pdesc->tfm;
-	unsigned long alignmask = crypto_shash_alignmask(parent);
 	struct xcbc_tfm_ctx *tctx = crypto_shash_ctx(parent);
 	struct xcbc_desc_ctx *ctx = shash_desc_ctx(pdesc);
 	struct crypto_cipher *tfm = tctx->child;
 	int bs = crypto_shash_blocksize(parent);
-	u8 *odds = PTR_ALIGN(&ctx->ctx[0], alignmask + 1);
+	u8 *odds = ctx->odds;
 	u8 *prev = odds + bs;
 
 	/* checking the data can fill the block */
 	if ((ctx->len + len) <= bs) {
 		memcpy(odds + ctx->len, p, len);
 		ctx->len += len;
 		return 0;
 	}
 
 	/* filling odds with new data and encrypting it */
@@ -125,46 +122,44 @@ static int crypto_xcbc_digest_update(struct shash_desc *pdesc, const u8 *p,
 		memcpy(odds, p, len);
 		ctx->len = len;
 	}
 
 	return 0;
 }
 
 static int crypto_xcbc_digest_final(struct shash_desc *pdesc, u8 *out)
 {
 	struct crypto_shash *parent = pdesc->tfm;
-	unsigned long alignmask = crypto_shash_alignmask(parent);
 	struct xcbc_tfm_ctx *tctx = crypto_shash_ctx(parent);
 	struct xcbc_desc_ctx *ctx = shash_desc_ctx(pdesc);
 	struct crypto_cipher *tfm = tctx->child;
 	int bs = crypto_shash_blocksize(parent);
-	u8 *consts = PTR_ALIGN(&tctx->ctx[0], alignmask + 1);
-	u8 *odds = PTR_ALIGN(&ctx->ctx[0], alignmask + 1);
+	u8 *odds = ctx->odds;
 	u8 *prev = odds + bs;
 	unsigned int offset = 0;
 
 	if (ctx->len != bs) {
 		unsigned int rlen;
 		u8 *p = odds + ctx->len;
 
 		*p = 0x80;
 		p++;
 
 		rlen = bs - ctx->len -1;
 		if (rlen)
 			memset(p, 0, rlen);
 
 		offset += bs;
 	}
 
 	crypto_xor(prev, odds, bs);
-	crypto_xor(prev, consts + offset, bs);
+	crypto_xor(prev, &tctx->consts[offset], bs);
 
 	crypto_cipher_encrypt_one(tfm, out, prev);
 
 	return 0;
 }
 
 static int xcbc_init_tfm(struct crypto_tfm *tfm)
 {
 	struct crypto_cipher *cipher;
 	struct crypto_instance *inst = (void *)tfm->__crt_alg;
@@ -184,21 +179,20 @@ static void xcbc_exit_tfm(struct crypto_tfm *tfm)
 {
 	struct xcbc_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
 	crypto_free_cipher(ctx->child);
 }
 
 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;
 	u32 mask;
 	int err;
 
 	err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH, &mask);
 	if (err)
 		return err;
 
 	inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
 	if (!inst)
 		return -ENOMEM;
@@ -211,35 +205,29 @@ static int xcbc_create(struct crypto_template *tmpl, struct rtattr **tb)
 	alg = crypto_spawn_cipher_alg(spawn);
 
 	err = -EINVAL;
 	if (alg->cra_blocksize != XCBC_BLOCKSIZE)
 		goto err_free_inst;
 
 	err = crypto_inst_setname(shash_crypto_instance(inst), tmpl->name, alg);
 	if (err)
 		goto err_free_inst;
 
-	alignmask = alg->cra_alignmask | 3;
-	inst->alg.base.cra_alignmask = alignmask;
 	inst->alg.base.cra_priority = alg->cra_priority;
 	inst->alg.base.cra_blocksize = alg->cra_blocksize;
+	inst->alg.base.cra_ctxsize = sizeof(struct xcbc_tfm_ctx) +
+				     alg->cra_blocksize * 2;
 
 	inst->alg.digestsize = alg->cra_blocksize;
-	inst->alg.descsize = ALIGN(sizeof(struct xcbc_desc_ctx),
-				   crypto_tfm_ctx_alignment()) +
-			     (alignmask &
-			      ~(crypto_tfm_ctx_alignment() - 1)) +
+	inst->alg.descsize = sizeof(struct xcbc_desc_ctx) +
 			     alg->cra_blocksize * 2;
 
-	inst->alg.base.cra_ctxsize = ALIGN(sizeof(struct xcbc_tfm_ctx),
-					   alignmask + 1) +
-				     alg->cra_blocksize * 2;
 	inst->alg.base.cra_init = xcbc_init_tfm;
 	inst->alg.base.cra_exit = xcbc_exit_tfm;
 
 	inst->alg.init = crypto_xcbc_digest_init;
 	inst->alg.update = crypto_xcbc_digest_update;
 	inst->alg.final = crypto_xcbc_digest_final;
 	inst->alg.setkey = crypto_xcbc_digest_setkey;
 
 	inst->free = shash_free_singlespawn_instance;
 
Signature · 1 line
2.42.0
#11 lore raw

PATCH 11/17 crypto: shash - remove support for nonzero alignmask

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

Currently, the shash API checks the alignment of all message, key, and digest buffers against the algorithm's declared alignmask, and for any unaligned buffers it falls back to manually aligned temporary buffers.

This is virtually useless, however. In the case of the message buffer, cryptographic hash functions internally operate on fixed-size blocks, so implementations end up needing to deal with byte-aligned data anyway because the length(s) passed to ->update might not be divisible by the block size. Word-alignment of the message can theoretically be helpful for CRCs, like what was being done in crc32c-sparc64. But in practice it's better for the algorithms to use unaligned accesses or align the message themselves. A similar argument applies to the key and digest.

In any case, no shash algorithms actually set a nonzero alignmask anymore. Therefore, remove support for it from shash. The benefit is that all the code to handle "misaligned" buffers in the shash API goes away, reducing the overhead of the shash API.

---
 crypto/shash.c | 128 ++++---------------------------------------------
 1 file changed, 8 insertions(+), 120 deletions(-)
crypto/shash.c +8 -120
index 52420c41db44a..409b33f9c97cc 100644
@@ -3,264 +3,151 @@
  * Synchronous Cryptographic Hash operations.
  *
  * Copyright (c) 2008 Herbert Xu <[email protected]>
  */
 
 #include <crypto/scatterwalk.h>
 #include <linux/cryptouser.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <linux/string.h>
 #include <net/netlink.h>
 
 #include "hash.h"
 
-#define MAX_SHASH_ALIGNMASK 63
-
 static const struct crypto_type crypto_shash_type;
 
 static inline struct crypto_istat_hash *shash_get_stat(struct shash_alg *alg)
 {
 	return hash_get_stat(&alg->halg);
 }
 
 static inline int crypto_shash_errstat(struct shash_alg *alg, int err)
 {
 	return crypto_hash_errstat(&alg->halg, err);
 }
 
 int shash_no_setkey(struct crypto_shash *tfm, const u8 *key,
 		    unsigned int keylen)
 {
 	return -ENOSYS;
 }
 EXPORT_SYMBOL_GPL(shash_no_setkey);
 
-static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key,
-				  unsigned int keylen)
-{
-	struct shash_alg *shash = crypto_shash_alg(tfm);
-	unsigned long alignmask = crypto_shash_alignmask(tfm);
-	unsigned long absize;
-	u8 *buffer, *alignbuffer;
-	int err;
-
-	absize = keylen + (alignmask & ~(crypto_tfm_ctx_alignment() - 1));
-	buffer = kmalloc(absize, GFP_ATOMIC);
-	if (!buffer)
-		return -ENOMEM;
-
-	alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
-	memcpy(alignbuffer, key, keylen);
-	err = shash->setkey(tfm, alignbuffer, keylen);
-	kfree_sensitive(buffer);
-	return err;
-}
-
 static void shash_set_needkey(struct crypto_shash *tfm, struct shash_alg *alg)
 {
 	if (crypto_shash_alg_needs_key(alg))
 		crypto_shash_set_flags(tfm, CRYPTO_TFM_NEED_KEY);
 }
 
 int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key,
 			unsigned int keylen)
 {
 	struct shash_alg *shash = crypto_shash_alg(tfm);
-	unsigned long alignmask = crypto_shash_alignmask(tfm);
 	int err;
 
-	if ((unsigned long)key & alignmask)
-		err = shash_setkey_unaligned(tfm, key, keylen);
-	else
-		err = shash->setkey(tfm, key, keylen);
-
+	err = shash->setkey(tfm, key, keylen);
 	if (unlikely(err)) {
 		shash_set_needkey(tfm, shash);
 		return err;
 	}
 
 	crypto_shash_clear_flags(tfm, CRYPTO_TFM_NEED_KEY);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(crypto_shash_setkey);
 
-static int shash_update_unaligned(struct shash_desc *desc, const u8 *data,
-				  unsigned int len)
-{
-	struct crypto_shash *tfm = desc->tfm;
-	struct shash_alg *shash = crypto_shash_alg(tfm);
-	unsigned long alignmask = crypto_shash_alignmask(tfm);
-	unsigned int unaligned_len = alignmask + 1 -
-				     ((unsigned long)data & alignmask);
-	/*
-	 * We cannot count on __aligned() working for large values:
-	 * https://patchwork.kernel.org/patch/9507697/
-	 */
-	u8 ubuf[MAX_SHASH_ALIGNMASK * 2];
-	u8 *buf = PTR_ALIGN(&ubuf[0], alignmask + 1);
-	int err;
-
-	if (WARN_ON(buf + unaligned_len > ubuf + sizeof(ubuf)))
-		return -EINVAL;
-
-	if (unaligned_len > len)
-		unaligned_len = len;
-
-	memcpy(buf, data, unaligned_len);
-	err = shash->update(desc, buf, unaligned_len);
-	memset(buf, 0, unaligned_len);
-
-	return err ?:
-	       shash->update(desc, data + unaligned_len, len - unaligned_len);
-}
-
 int crypto_shash_update(struct shash_desc *desc, const u8 *data,
 			unsigned int len)
 {
-	struct crypto_shash *tfm = desc->tfm;
-	struct shash_alg *shash = crypto_shash_alg(tfm);
-	unsigned long alignmask = crypto_shash_alignmask(tfm);
+	struct shash_alg *shash = crypto_shash_alg(desc->tfm);
 	int err;
 
 	if (IS_ENABLED(CONFIG_CRYPTO_STATS))
 		atomic64_add(len, &shash_get_stat(shash)->hash_tlen);
 
-	if ((unsigned long)data & alignmask)
-		err = shash_update_unaligned(desc, data, len);
-	else
-		err = shash->update(desc, data, len);
+	err = shash->update(desc, data, len);
 
 	return crypto_shash_errstat(shash, err);
 }
 EXPORT_SYMBOL_GPL(crypto_shash_update);
 
-static int shash_final_unaligned(struct shash_desc *desc, u8 *out)
-{
-	struct crypto_shash *tfm = desc->tfm;
-	unsigned long alignmask = crypto_shash_alignmask(tfm);
-	struct shash_alg *shash = crypto_shash_alg(tfm);
-	unsigned int ds = crypto_shash_digestsize(tfm);
-	/*
-	 * We cannot count on __aligned() working for large values:
-	 * https://patchwork.kernel.org/patch/9507697/
-	 */
-	u8 ubuf[MAX_SHASH_ALIGNMASK + HASH_MAX_DIGESTSIZE];
-	u8 *buf = PTR_ALIGN(&ubuf[0], alignmask + 1);
-	int err;
-
-	if (WARN_ON(buf + ds > ubuf + sizeof(ubuf)))
-		return -EINVAL;
-
-	err = shash->final(desc, buf);
-	if (err)
-		goto out;
-
-	memcpy(out, buf, ds);
-
-out:
-	memset(buf, 0, ds);
-	return err;
-}
-
 int crypto_shash_final(struct shash_desc *desc, u8 *out)
 {
-	struct crypto_shash *tfm = desc->tfm;
-	struct shash_alg *shash = crypto_shash_alg(tfm);
-	unsigned long alignmask = crypto_shash_alignmask(tfm);
+	struct shash_alg *shash = crypto_shash_alg(desc->tfm);
 	int err;
 
 	if (IS_ENABLED(CONFIG_CRYPTO_STATS))
 		atomic64_inc(&shash_get_stat(shash)->hash_cnt);
 
-	if ((unsigned long)out & alignmask)
-		err = shash_final_unaligned(desc, out);
-	else
-		err = shash->final(desc, out);
+	err = shash->final(desc, out);
 
 	return crypto_shash_errstat(shash, err);
 }
 EXPORT_SYMBOL_GPL(crypto_shash_final);
 
-static int shash_finup_unaligned(struct shash_desc *desc, const u8 *data,
-				 unsigned int len, u8 *out)
-{
-	return shash_update_unaligned(desc, data, len) ?:
-	       shash_final_unaligned(desc, out);
-}
-
 static int shash_default_finup(struct shash_desc *desc, const u8 *data,
 			       unsigned int len, u8 *out)
 {
 	struct shash_alg *shash = crypto_shash_alg(desc->tfm);
 
 	return shash->update(desc, data, len) ?:
 	       shash->final(desc, out);
 }
 
 int crypto_shash_finup(struct shash_desc *desc, const u8 *data,
 		       unsigned int len, u8 *out)
 {
 	struct crypto_shash *tfm = desc->tfm;
 	struct shash_alg *shash = crypto_shash_alg(tfm);
-	unsigned long alignmask = crypto_shash_alignmask(tfm);
 	int err;
 
 	if (IS_ENABLED(CONFIG_CRYPTO_STATS)) {
 		struct crypto_istat_hash *istat = shash_get_stat(shash);
 
 		atomic64_inc(&istat->hash_cnt);
 		atomic64_add(len, &istat->hash_tlen);
 	}
 
-	if (((unsigned long)data | (unsigned long)out) & alignmask)
-		err = shash_finup_unaligned(desc, data, len, out);
-	else
-		err = shash->finup(desc, data, len, out);
-
+	err = shash->finup(desc, data, len, out);
 
 	return crypto_shash_errstat(shash, err);
 }
 EXPORT_SYMBOL_GPL(crypto_shash_finup);
 
 static int shash_default_digest(struct shash_desc *desc, const u8 *data,
 				unsigned int len, u8 *out)
 {
 	struct shash_alg *shash = crypto_shash_alg(desc->tfm);
 
 	return shash->init(desc) ?:
 	       shash->finup(desc, data, len, out);
 }
 
 int crypto_shash_digest(struct shash_desc *desc, const u8 *data,
 			unsigned int len, u8 *out)
 {
 	struct crypto_shash *tfm = desc->tfm;
 	struct shash_alg *shash = crypto_shash_alg(tfm);
-	unsigned long alignmask = crypto_shash_alignmask(tfm);
 	int err;
 
 	if (IS_ENABLED(CONFIG_CRYPTO_STATS)) {
 		struct crypto_istat_hash *istat = shash_get_stat(shash);
 
 		atomic64_inc(&istat->hash_cnt);
 		atomic64_add(len, &istat->hash_tlen);
 	}
 
 	if (crypto_shash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
 		err = -ENOKEY;
-	else if (((unsigned long)data | (unsigned long)out) & alignmask)
-		err = shash->init(desc) ?:
-		      shash_finup_unaligned(desc, data, len, out);
 	else
 		err = shash->digest(desc, data, len, out);
 
 	return crypto_shash_errstat(shash, err);
 }
 EXPORT_SYMBOL_GPL(crypto_shash_digest);
 
 int crypto_shash_tfm_digest(struct crypto_shash *tfm, const u8 *data,
 			    unsigned int len, u8 *out)
 {
@@ -663,21 +550,22 @@ int hash_prepare_alg(struct hash_alg_common *alg)
 }
 
 static int shash_prepare_alg(struct shash_alg *alg)
 {
 	struct crypto_alg *base = &alg->halg.base;
 	int err;
 
 	if (alg->descsize > HASH_MAX_DESCSIZE)
 		return -EINVAL;
 
-	if (base->cra_alignmask > MAX_SHASH_ALIGNMASK)
+	/* alignmask is not useful for shash, so it is not supported. */
+	if (base->cra_alignmask)
 		return -EINVAL;
 
 	if ((alg->export && !alg->import) || (alg->import && !alg->export))
 		return -EINVAL;
 
 	err = hash_prepare_alg(&alg->halg);
 	if (err)
 		return err;
 
 	base->cra_type = &crypto_shash_type;
Signature · 1 line
2.42.0
#12 lore raw

PATCH 12/17 libceph: stop checking crypto_shash_alignmask

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

Now that the shash algorithm type does not support nonzero alignmasks, crypto_shash_alignmask() always returns 0 and will be removed. In preparation for this, stop checking crypto_shash_alignmask() in net/ceph/messenger_v2.c.

---
 net/ceph/messenger_v2.c | 4 ----
 1 file changed, 4 deletions(-)
net/ceph/messenger_v2.c +0 -4
index d09a39ff2cf04..f8ec60e1aba3a 100644
@@ -726,22 +726,20 @@ static int setup_crypto(struct ceph_connection *con,
 	noio_flag = memalloc_noio_save();
 	con->v2.hmac_tfm = crypto_alloc_shash("hmac(sha256)", 0, 0);
 	memalloc_noio_restore(noio_flag);
 	if (IS_ERR(con->v2.hmac_tfm)) {
 		ret = PTR_ERR(con->v2.hmac_tfm);
 		con->v2.hmac_tfm = NULL;
 		pr_err("failed to allocate hmac tfm context: %d\n", ret);
 		return ret;
 	}
 
-	WARN_ON((unsigned long)session_key &
-		crypto_shash_alignmask(con->v2.hmac_tfm));
 	ret = crypto_shash_setkey(con->v2.hmac_tfm, session_key,
 				  session_key_len);
 	if (ret) {
 		pr_err("failed to set hmac key: %d\n", ret);
 		return ret;
 	}
 
 	if (con->v2.con_mode == CEPH_CON_MODE_CRC) {
 		WARN_ON(con_secret_len);
 		return 0;  /* auth_x, plain mode */
@@ -809,22 +807,20 @@ static int hmac_sha256(struct ceph_connection *con, const struct kvec *kvecs,
 		memset(hmac, 0, SHA256_DIGEST_SIZE);
 		return 0;  /* auth_none */
 	}
 
 	desc->tfm = con->v2.hmac_tfm;
 	ret = crypto_shash_init(desc);
 	if (ret)
 		goto out;
 
 	for (i = 0; i < kvec_cnt; i++) {
-		WARN_ON((unsigned long)kvecs[i].iov_base &
-			crypto_shash_alignmask(con->v2.hmac_tfm));
 		ret = crypto_shash_update(desc, kvecs[i].iov_base,
 					  kvecs[i].iov_len);
 		if (ret)
 			goto out;
 	}
 
 	ret = crypto_shash_final(desc, hmac);
 
 out:
 	shash_desc_zero(desc);
Signature · 1 line
2.42.0
#13 lore raw

PATCH 13/17 crypto: drbg - stop checking crypto_shash_alignmask

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

Now that the shash algorithm type does not support nonzero alignmasks, crypto_shash_alignmask() always returns 0 and will be removed. In preparation for this, stop checking crypto_shash_alignmask() in drbg.

---
 crypto/drbg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
crypto/drbg.c +1 -1
index ff4ebbc68efab..e01f8c7769d03 100644
@@ -1691,21 +1691,21 @@ static int drbg_init_hash_kernel(struct drbg_state *drbg)
 	sdesc = kzalloc(sizeof(struct shash_desc) + crypto_shash_descsize(tfm),
 			GFP_KERNEL);
 	if (!sdesc) {
 		crypto_free_shash(tfm);
 		return -ENOMEM;
 	}
 
 	sdesc->shash.tfm = tfm;
 	drbg->priv_data = sdesc;
 
-	return crypto_shash_alignmask(tfm);
+	return 0;
 }
 
 static int drbg_fini_hash_kernel(struct drbg_state *drbg)
 {
 	struct sdesc *sdesc = drbg->priv_data;
 	if (sdesc) {
 		crypto_free_shash(sdesc->shash.tfm);
 		kfree_sensitive(sdesc);
 	}
 	drbg->priv_data = NULL;
Signature · 1 line
2.42.0
#14 lore raw

PATCH 14/17 crypto: testmgr - stop checking crypto_shash_alignmask

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

Now that the shash algorithm type does not support nonzero alignmasks, crypto_shash_alignmask() always returns 0 and will be removed. In preparation for this, stop checking crypto_shash_alignmask() in testmgr.

---
 crypto/testmgr.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
crypto/testmgr.c +2 -3
index 54135c7610f06..48a0929c7a158 100644
@@ -1268,50 +1268,49 @@ static inline int check_shash_op(const char *op, int err,
 
 /* Test one hash test vector in one configuration, using the shash API */
 static int test_shash_vec_cfg(const struct hash_testvec *vec,
 			      const char *vec_name,
 			      const struct testvec_config *cfg,
 			      struct shash_desc *desc,
 			      struct test_sglist *tsgl,
 			      u8 *hashstate)
 {
 	struct crypto_shash *tfm = desc->tfm;
-	const unsigned int alignmask = crypto_shash_alignmask(tfm);
 	const unsigned int digestsize = crypto_shash_digestsize(tfm);
 	const unsigned int statesize = crypto_shash_statesize(tfm);
 	const char *driver = crypto_shash_driver_name(tfm);
 	const struct test_sg_division *divs[XBUFSIZE];
 	unsigned int i;
 	u8 result[HASH_MAX_DIGESTSIZE + TESTMGR_POISON_LEN];
 	int err;
 
 	/* Set the key, if specified */
 	if (vec->ksize) {
 		err = do_setkey(crypto_shash_setkey, tfm, vec->key, vec->ksize,
-				cfg, alignmask);
+				cfg, 0);
 		if (err) {
 			if (err == vec->setkey_error)
 				return 0;
 			pr_err("alg: shash: %s setkey failed on test vector %s; expected_error=%d, actual_error=%d, flags=%#x\n",
 			       driver, vec_name, vec->setkey_error, err,
 			       crypto_shash_get_flags(tfm));
 			return err;
 		}
 		if (vec->setkey_error) {
 			pr_err("alg: shash: %s setkey unexpectedly succeeded on test vector %s; expected_error=%d\n",
 			       driver, vec_name, vec->setkey_error);
 			return -EINVAL;
 		}
 	}
 
 	/* Build the scatterlist for the source data */
-	err = build_hash_sglist(tsgl, vec, cfg, alignmask, divs);
+	err = build_hash_sglist(tsgl, vec, cfg, 0, divs);
 	if (err) {
 		pr_err("alg: shash: %s: error preparing scatterlist for test vector %s, cfg=\"%s\"\n",
 		       driver, vec_name, cfg->name);
 		return err;
 	}
 
 	/* Do the actual hashing */
 
 	testmgr_poison(desc->__ctx, crypto_shash_descsize(tfm));
 	testmgr_poison(result, digestsize + TESTMGR_POISON_LEN);
Signature · 1 line
2.42.0
#15 lore raw

PATCH 15/17 crypto: adiantum - stop using alignmask of shash_alg

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

Now that the shash algorithm type does not support nonzero alignmasks, shash_alg::base.cra_alignmask is always 0, so OR-ing it into another value is a no-op.

---
 crypto/adiantum.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
crypto/adiantum.c +1 -2
index 51703746d91e2..064a0a57c77c1 100644
@@ -554,22 +554,21 @@ static int adiantum_create(struct crypto_template *tmpl, struct rtattr **tb)
 		goto err_free_inst;
 	if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
 		     "adiantum(%s,%s,%s)",
 		     streamcipher_alg->base.cra_driver_name,
 		     blockcipher_alg->cra_driver_name,
 		     hash_alg->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
 		goto err_free_inst;
 
 	inst->alg.base.cra_blocksize = BLOCKCIPHER_BLOCK_SIZE;
 	inst->alg.base.cra_ctxsize = sizeof(struct adiantum_tfm_ctx);
-	inst->alg.base.cra_alignmask = streamcipher_alg->base.cra_alignmask |
-				       hash_alg->base.cra_alignmask;
+	inst->alg.base.cra_alignmask = streamcipher_alg->base.cra_alignmask;
 	/*
 	 * The block cipher is only invoked once per message, so for long
 	 * messages (e.g. sectors for disk encryption) its performance doesn't
 	 * matter as much as that of the stream cipher and hash function.  Thus,
 	 * weigh the block cipher's ->cra_priority less.
 	 */
 	inst->alg.base.cra_priority = (4 * streamcipher_alg->base.cra_priority +
 				       2 * hash_alg->base.cra_priority +
 				       blockcipher_alg->cra_priority) / 7;
 
Signature · 1 line
2.42.0
#16 lore raw

PATCH 16/17 crypto: hctr2 - stop using alignmask of shash_alg

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

Now that the shash algorithm type does not support nonzero alignmasks, shash_alg::base.cra_alignmask is always 0, so OR-ing it into another value is a no-op.

---
 crypto/hctr2.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
crypto/hctr2.c +1 -2
index 653fde727f0fa..87e7547ad1862 100644
@@ -478,22 +478,21 @@ static int hctr2_create_common(struct crypto_template *tmpl,
 		goto err_free_inst;
 	if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
 		     "hctr2_base(%s,%s)",
 		     xctr_alg->base.cra_driver_name,
 		     polyval_alg->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
 		goto err_free_inst;
 
 	inst->alg.base.cra_blocksize = BLOCKCIPHER_BLOCK_SIZE;
 	inst->alg.base.cra_ctxsize = sizeof(struct hctr2_tfm_ctx) +
 				     polyval_alg->statesize * 2;
-	inst->alg.base.cra_alignmask = xctr_alg->base.cra_alignmask |
-				       polyval_alg->base.cra_alignmask;
+	inst->alg.base.cra_alignmask = xctr_alg->base.cra_alignmask;
 	/*
 	 * The hash function is called twice, so it is weighted higher than the
 	 * xctr and blockcipher.
 	 */
 	inst->alg.base.cra_priority = (2 * xctr_alg->base.cra_priority +
 				       4 * polyval_alg->base.cra_priority +
 				       blockcipher_alg->cra_priority) / 7;
 
 	inst->alg.setkey = hctr2_setkey;
 	inst->alg.encrypt = hctr2_encrypt;
Signature · 1 line
2.42.0
#17 lore raw

PATCH 17/17 crypto: shash - remove crypto_shash_alignmask

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

crypto_shash_alignmask() no longer has any callers, and it always returns 0 now that the shash algorithm type no longer supports nonzero alignmasks. Therefore, remove it.

---
 include/crypto/hash.h | 6 ------
 1 file changed, 6 deletions(-)
include/crypto/hash.h +0 -6
index 52e57e93b2f59..d3a380ae894ad 100644
@@ -791,26 +791,20 @@ static inline void crypto_free_shash(struct crypto_shash *tfm)
 static inline const char *crypto_shash_alg_name(struct crypto_shash *tfm)
 {
 	return crypto_tfm_alg_name(crypto_shash_tfm(tfm));
 }
 
 static inline const char *crypto_shash_driver_name(struct crypto_shash *tfm)
 {
 	return crypto_tfm_alg_driver_name(crypto_shash_tfm(tfm));
 }
 
-static inline unsigned int crypto_shash_alignmask(
-	struct crypto_shash *tfm)
-{
-	return crypto_tfm_alg_alignmask(crypto_shash_tfm(tfm));
-}
-
 /**
  * crypto_shash_blocksize() - obtain block size for cipher
  * @tfm: cipher handle
  *
  * The block size for the message digest cipher referenced with the cipher
  * handle is returned.
  *
  * Return: block size of cipher
  */
 static inline unsigned int crypto_shash_blocksize(struct crypto_shash *tfm)
Signature · 1 line
2.42.0
maintainer
#18 lore raw
In reply to Eric Biggers
Quoted 45 lines · Eric Biggers

The alignmask support in the shash algorithm type is virtually unused and has no real point. This patch series removes it in order to reduce API overhead and complexity.

This series does not change anything for ahash.

Eric Biggers (17):
crypto: sparc/crc32c - stop using the shash alignmask
crypto: stm32 - remove unnecessary alignmask
crypto: xilinx/zynqmp-sha - remove unnecessary alignmask
crypto: mips/crc32 - remove redundant setting of alignmask to 0
crypto: loongarch/crc32 - remove redundant setting of alignmask to 0
crypto: cbcmac - remove unnecessary alignment logic
crypto: cmac - remove unnecessary alignment logic
crypto: hmac - remove unnecessary alignment logic
crypto: vmac - don't set alignmask
crypto: xcbc - remove unnecessary alignment logic
crypto: shash - remove support for nonzero alignmask
libceph: stop checking crypto_shash_alignmask
crypto: drbg - stop checking crypto_shash_alignmask
crypto: testmgr - stop checking crypto_shash_alignmask
crypto: adiantum - stop using alignmask of shash_alg
crypto: hctr2 - stop using alignmask of shash_alg
crypto: shash - remove crypto_shash_alignmask

arch/loongarch/crypto/crc32-loongarch.c |   2 -
arch/mips/crypto/crc32-mips.c           |   2 -
arch/sparc/crypto/crc32c_glue.c         |  45 +++++----
crypto/adiantum.c                       |   3 +-
crypto/ccm.c                            |  17 ++--
crypto/cmac.c                           |  39 ++------
crypto/drbg.c                           |   2 +-
crypto/hctr2.c                          |   3 +-
crypto/hmac.c                           |  56 ++++-------
crypto/shash.c                          | 128 ++----------------------
crypto/testmgr.c                        |   5 +-
crypto/vmac.c                           |   1 -
crypto/xcbc.c                           |  32 ++----
drivers/crypto/stm32/stm32-crc32.c      |   2 -
drivers/crypto/xilinx/zynqmp-sha.c      |   1 -
include/crypto/hash.h                   |   6 --
net/ceph/messenger_v2.c                 |   4 -
17 files changed, 87 insertions(+), 261 deletions(-)
Quoted 4 lines

base-commit: 5b90073defd1a52aa8120403d79f6e0fc10c87ee
prerequisite-patch-id: 77bd65b07cfc27f172b1698e0c4d43d6aba7ad8f
prerequisite-patch-id: 3ccf94d7048db0fee9407b5b5fa48554e115b56b
prerequisite-patch-id: e447f81a392f2f3955206357d72032cf691c7e11

All applied. Thanks.

Signature · 3 lines
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt