Skip to contentSkip to conversation

crypto: arm32-optimized BLAKE2b and BLAKE2s

PATCH Superseded Eric Biggers 3 participants 18 messages Dec 17, 2020 – Dec 22, 2020

Subsystems (5)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore

Eric Biggers

author maintainer
#0 lore raw

v2 cover crypto: arm32-optimized BLAKE2b and BLAKE2s

This patchset adds 32-bit ARM assembly language implementations of BLAKE2b and BLAKE2s.

The BLAKE2b implementation is NEON-accelerated, while the BLAKE2s implementation uses scalar instructions since NEON doesn't work very well for it. The BLAKE2b implementation is faster and is expected to be useful as a replacement for SHA-1 in dm-verity, while the BLAKE2s implementation would be useful for WireGuard which uses BLAKE2s.

Both implementations are provided via the shash API, while BLAKE2s is also provided via the library API.

While adding these, I also reworked the generic implementations of BLAKE2b and BLAKE2s to provide helper functions that make implementing other "shash" providers for these algorithms much easier.

See the individual commits for full details, including benchmarks.

This patchset was tested on a Raspberry Pi 2 (which uses a Cortex-A7 processor) with CONFIG_CRYPTO_MANAGER_EXTRA_TESTS=y, plus other tests.

This patchset applies to mainline commit 0c6c887835b5.

Changed since v1:
- Added BLAKE2s implementation.
- Adjusted the BLAKE2b helper functions to be consistent with what I decided to do for BLAKE2s.
- Fixed build error in blake2b-neon-core.S in some configurations.

Eric Biggers (11):
crypto: blake2b - rename constants for consistency with blake2s
crypto: blake2b - define shash_alg structs using macros
crypto: blake2b - export helpers for optimized implementations
crypto: blake2b - update file comment
crypto: arm/blake2b - add NEON-accelerated BLAKE2b
crypto: blake2s - define shash_alg structs using macros
crypto: x86/blake2s - define shash_alg structs using macros
crypto: blake2s - remove unneeded includes
crypto: blake2s - share the "shash" API boilerplate code
crypto: arm/blake2s - add ARM scalar optimized BLAKE2s
wireguard: Kconfig: select CRYPTO_BLAKE2S_ARM

 arch/arm/crypto/Kconfig             |  20 ++
 arch/arm/crypto/Makefile            |   4 +
 arch/arm/crypto/blake2b-neon-core.S | 345 ++++++++++++++++++++++++++++
 arch/arm/crypto/blake2b-neon-glue.c | 105 +++++++++
 arch/arm/crypto/blake2s-core.S      | 272 ++++++++++++++++++++++
 arch/arm/crypto/blake2s-glue.c      |  78 +++++++
 arch/x86/crypto/blake2s-glue.c      | 150 +++---------
 crypto/Kconfig                      |   5 +
 crypto/Makefile                     |   1 +
 crypto/blake2b_generic.c            | 200 +++++++---------
 crypto/blake2s_generic.c            | 161 +++----------
 crypto/blake2s_helpers.c            |  87 +++++++
 drivers/net/Kconfig                 |   1 +
 include/crypto/blake2b.h            |  27 +++
 include/crypto/internal/blake2b.h   |  33 +++
 include/crypto/internal/blake2s.h   |  17 ++
 16 files changed, 1139 insertions(+), 367 deletions(-)
 create mode 100644 arch/arm/crypto/blake2b-neon-core.S
 create mode 100644 arch/arm/crypto/blake2b-neon-glue.c
 create mode 100644 arch/arm/crypto/blake2s-core.S
 create mode 100644 arch/arm/crypto/blake2s-glue.c
 create mode 100644 crypto/blake2s_helpers.c
 create mode 100644 include/crypto/blake2b.h
 create mode 100644 include/crypto/internal/blake2b.h

base-commit: 0c6c887835b59c10602add88057c9c06f265effe

Signature · 1 line
2.29.2
author maintainer
#1 lore raw

PATCH v2 1/11 crypto: blake2b - rename constants for consistency with blake2s

From: Eric Biggers <[email protected]>

Rename some BLAKE2b-related constants to be consistent with the names used in the BLAKE2s implementation (see include/crypto/blake2s.h):

	BLAKE2B_*_DIGEST_SIZE  => BLAKE2B_*_HASH_SIZE
	BLAKE2B_BLOCKBYTES     => BLAKE2B_BLOCK_SIZE
	BLAKE2B_KEYBYTES       => BLAKE2B_KEY_SIZE
---
 crypto/blake2b_generic.c | 58 +++++++++++++++++++++-------------------
 1 file changed, 30 insertions(+), 28 deletions(-)
crypto/blake2b_generic.c +30 -28
index a2ffe60e06d34..83942f511075e 100644
@@ -25,21 +25,22 @@
 #include <linux/bitops.h>
 #include <crypto/internal/hash.h>
 
-#define BLAKE2B_160_DIGEST_SIZE		(160 / 8)
-#define BLAKE2B_256_DIGEST_SIZE		(256 / 8)
-#define BLAKE2B_384_DIGEST_SIZE		(384 / 8)
-#define BLAKE2B_512_DIGEST_SIZE		(512 / 8)
-
-enum blake2b_constant {
-	BLAKE2B_BLOCKBYTES    = 128,
-	BLAKE2B_KEYBYTES      = 64,
+
+enum blake2b_lengths {
+	BLAKE2B_BLOCK_SIZE = 128,
+	BLAKE2B_KEY_SIZE = 64,
+
+	BLAKE2B_160_HASH_SIZE = 20,
+	BLAKE2B_256_HASH_SIZE =	32,
+	BLAKE2B_384_HASH_SIZE = 48,
+	BLAKE2B_512_HASH_SIZE = 64,
 };
 
 struct blake2b_state {
 	u64      h[8];
 	u64      t[2];
 	u64      f[2];
-	u8       buf[BLAKE2B_BLOCKBYTES];
+	u8       buf[BLAKE2B_BLOCK_SIZE];
 	size_t   buflen;
 };
 
@@ -96,7 +97,7 @@ static void blake2b_increment_counter(struct blake2b_state *S, const u64 inc)
 	} while (0)
 
 static void blake2b_compress(struct blake2b_state *S,
-			     const u8 block[BLAKE2B_BLOCKBYTES])
+			     const u8 block[BLAKE2B_BLOCK_SIZE])
 {
 	u64 m[16];
 	u64 v[16];
@@ -140,7 +141,7 @@ static void blake2b_compress(struct blake2b_state *S,
 #undef ROUND
 
 struct blake2b_tfm_ctx {
-	u8 key[BLAKE2B_KEYBYTES];
+	u8 key[BLAKE2B_KEY_SIZE];
 	unsigned int keylen;
 };
 
@@ -149,7 +150,7 @@ static int blake2b_setkey(struct crypto_shash *tfm, const u8 *key,
 {
 	struct blake2b_tfm_ctx *tctx = crypto_shash_ctx(tfm);
 
-	if (keylen == 0 || keylen > BLAKE2B_KEYBYTES)
+	if (keylen == 0 || keylen > BLAKE2B_KEY_SIZE)
 		return -EINVAL;
 
 	memcpy(tctx->key, key, keylen);
@@ -176,7 +177,7 @@ static int blake2b_init(struct shash_desc *desc)
 		 * _final will process it
 		 */
 		memcpy(state->buf, tctx->key, tctx->keylen);
-		state->buflen = BLAKE2B_BLOCKBYTES;
+		state->buflen = BLAKE2B_BLOCK_SIZE;
 	}
 	return 0;
 }
@@ -186,7 +187,7 @@ static int blake2b_update(struct shash_desc *desc, const u8 *in,
 {
 	struct blake2b_state *state = shash_desc_ctx(desc);
 	const size_t left = state->buflen;
-	const size_t fill = BLAKE2B_BLOCKBYTES - left;
+	const size_t fill = BLAKE2B_BLOCK_SIZE - left;
 
 	if (!inlen)
 		return 0;
@@ -195,16 +196,16 @@ static int blake2b_update(struct shash_desc *desc, const u8 *in,
 		state->buflen = 0;
 		/* Fill buffer */
 		memcpy(state->buf + left, in, fill);
-		blake2b_increment_counter(state, BLAKE2B_BLOCKBYTES);
+		blake2b_increment_counter(state, BLAKE2B_BLOCK_SIZE);
 		/* Compress */
 		blake2b_compress(state, state->buf);
 		in += fill;
 		inlen -= fill;
-		while (inlen > BLAKE2B_BLOCKBYTES) {
-			blake2b_increment_counter(state, BLAKE2B_BLOCKBYTES);
+		while (inlen > BLAKE2B_BLOCK_SIZE) {
+			blake2b_increment_counter(state, BLAKE2B_BLOCK_SIZE);
 			blake2b_compress(state, in);
-			in += BLAKE2B_BLOCKBYTES;
-			inlen -= BLAKE2B_BLOCKBYTES;
+			in += BLAKE2B_BLOCK_SIZE;
+			inlen -= BLAKE2B_BLOCK_SIZE;
 		}
 	}
 	memcpy(state->buf + state->buflen, in, inlen);
@@ -223,7 +224,8 @@ static int blake2b_final(struct shash_desc *desc, u8 *out)
 	/* Set last block */
 	state->f[0] = (u64)-1;
 	/* Padding */
-	memset(state->buf + state->buflen, 0, BLAKE2B_BLOCKBYTES - state->buflen);
+	memset(state->buf + state->buflen, 0,
+	       BLAKE2B_BLOCK_SIZE - state->buflen);
 	blake2b_compress(state, state->buf);
 
 	/* Avoid temporary buffer and switch the internal output to LE order */
@@ -240,10 +242,10 @@ static struct shash_alg blake2b_algs[] = {
 		.base.cra_driver_name	= "blake2b-160-generic",
 		.base.cra_priority	= 100,
 		.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-		.base.cra_blocksize	= BLAKE2B_BLOCKBYTES,
+		.base.cra_blocksize	= BLAKE2B_BLOCK_SIZE,
 		.base.cra_ctxsize	= sizeof(struct blake2b_tfm_ctx),
 		.base.cra_module	= THIS_MODULE,
-		.digestsize		= BLAKE2B_160_DIGEST_SIZE,
+		.digestsize		= BLAKE2B_160_HASH_SIZE,
 		.setkey			= blake2b_setkey,
 		.init			= blake2b_init,
 		.update			= blake2b_update,
@@ -254,10 +256,10 @@ static struct shash_alg blake2b_algs[] = {
 		.base.cra_driver_name	= "blake2b-256-generic",
 		.base.cra_priority	= 100,
 		.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-		.base.cra_blocksize	= BLAKE2B_BLOCKBYTES,
+		.base.cra_blocksize	= BLAKE2B_BLOCK_SIZE,
 		.base.cra_ctxsize	= sizeof(struct blake2b_tfm_ctx),
 		.base.cra_module	= THIS_MODULE,
-		.digestsize		= BLAKE2B_256_DIGEST_SIZE,
+		.digestsize		= BLAKE2B_256_HASH_SIZE,
 		.setkey			= blake2b_setkey,
 		.init			= blake2b_init,
 		.update			= blake2b_update,
@@ -268,10 +270,10 @@ static struct shash_alg blake2b_algs[] = {
 		.base.cra_driver_name	= "blake2b-384-generic",
 		.base.cra_priority	= 100,
 		.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-		.base.cra_blocksize	= BLAKE2B_BLOCKBYTES,
+		.base.cra_blocksize	= BLAKE2B_BLOCK_SIZE,
 		.base.cra_ctxsize	= sizeof(struct blake2b_tfm_ctx),
 		.base.cra_module	= THIS_MODULE,
-		.digestsize		= BLAKE2B_384_DIGEST_SIZE,
+		.digestsize		= BLAKE2B_384_HASH_SIZE,
 		.setkey			= blake2b_setkey,
 		.init			= blake2b_init,
 		.update			= blake2b_update,
@@ -282,10 +284,10 @@ static struct shash_alg blake2b_algs[] = {
 		.base.cra_driver_name	= "blake2b-512-generic",
 		.base.cra_priority	= 100,
 		.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-		.base.cra_blocksize	= BLAKE2B_BLOCKBYTES,
+		.base.cra_blocksize	= BLAKE2B_BLOCK_SIZE,
 		.base.cra_ctxsize	= sizeof(struct blake2b_tfm_ctx),
 		.base.cra_module	= THIS_MODULE,
-		.digestsize		= BLAKE2B_512_DIGEST_SIZE,
+		.digestsize		= BLAKE2B_512_HASH_SIZE,
 		.setkey			= blake2b_setkey,
 		.init			= blake2b_init,
 		.update			= blake2b_update,

base-commit: 0c6c887835b59c10602add88057c9c06f265effe

Signature · 1 line
2.29.2
author maintainer
#2 lore raw

PATCH v2 2/11 crypto: blake2b - define shash_alg structs using macros

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

The shash_alg structs for the four variants of BLAKE2b are identical except for the algorithm name, driver name, and digest size. So, avoid code duplication by using a macro to define these structs.

---
 crypto/blake2b_generic.c | 82 ++++++++++++----------------------------
 1 file changed, 25 insertions(+), 57 deletions(-)
crypto/blake2b_generic.c +25 -57
index 83942f511075e..0e38e3e48297c 100644
@@ -236,64 +236,32 @@ static int blake2b_final(struct shash_desc *desc, u8 *out)
 	return 0;
 }
 
-static struct shash_alg blake2b_algs[] = {
-	{
-		.base.cra_name		= "blake2b-160",
-		.base.cra_driver_name	= "blake2b-160-generic",
-		.base.cra_priority	= 100,
-		.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-		.base.cra_blocksize	= BLAKE2B_BLOCK_SIZE,
-		.base.cra_ctxsize	= sizeof(struct blake2b_tfm_ctx),
-		.base.cra_module	= THIS_MODULE,
-		.digestsize		= BLAKE2B_160_HASH_SIZE,
-		.setkey			= blake2b_setkey,
-		.init			= blake2b_init,
-		.update			= blake2b_update,
-		.final			= blake2b_final,
-		.descsize		= sizeof(struct blake2b_state),
-	}, {
-		.base.cra_name		= "blake2b-256",
-		.base.cra_driver_name	= "blake2b-256-generic",
-		.base.cra_priority	= 100,
-		.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-		.base.cra_blocksize	= BLAKE2B_BLOCK_SIZE,
-		.base.cra_ctxsize	= sizeof(struct blake2b_tfm_ctx),
-		.base.cra_module	= THIS_MODULE,
-		.digestsize		= BLAKE2B_256_HASH_SIZE,
-		.setkey			= blake2b_setkey,
-		.init			= blake2b_init,
-		.update			= blake2b_update,
-		.final			= blake2b_final,
-		.descsize		= sizeof(struct blake2b_state),
-	}, {
-		.base.cra_name		= "blake2b-384",
-		.base.cra_driver_name	= "blake2b-384-generic",
-		.base.cra_priority	= 100,
-		.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-		.base.cra_blocksize	= BLAKE2B_BLOCK_SIZE,
-		.base.cra_ctxsize	= sizeof(struct blake2b_tfm_ctx),
-		.base.cra_module	= THIS_MODULE,
-		.digestsize		= BLAKE2B_384_HASH_SIZE,
-		.setkey			= blake2b_setkey,
-		.init			= blake2b_init,
-		.update			= blake2b_update,
-		.final			= blake2b_final,
-		.descsize		= sizeof(struct blake2b_state),
-	}, {
-		.base.cra_name		= "blake2b-512",
-		.base.cra_driver_name	= "blake2b-512-generic",
-		.base.cra_priority	= 100,
-		.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-		.base.cra_blocksize	= BLAKE2B_BLOCK_SIZE,
-		.base.cra_ctxsize	= sizeof(struct blake2b_tfm_ctx),
-		.base.cra_module	= THIS_MODULE,
-		.digestsize		= BLAKE2B_512_HASH_SIZE,
-		.setkey			= blake2b_setkey,
-		.init			= blake2b_init,
-		.update			= blake2b_update,
-		.final			= blake2b_final,
-		.descsize		= sizeof(struct blake2b_state),
+#define BLAKE2B_ALG(name, driver_name, digest_size)			\
+	{								\
+		.base.cra_name		= name,				\
+		.base.cra_driver_name	= driver_name,			\
+		.base.cra_priority	= 100,				\
+		.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,	\
+		.base.cra_blocksize	= BLAKE2B_BLOCK_SIZE,		\
+		.base.cra_ctxsize	= sizeof(struct blake2b_tfm_ctx), \
+		.base.cra_module	= THIS_MODULE,			\
+		.digestsize		= digest_size,			\
+		.setkey			= blake2b_setkey,		\
+		.init			= blake2b_init,			\
+		.update			= blake2b_update,		\
+		.final			= blake2b_final,		\
+		.descsize		= sizeof(struct blake2b_state),	\
 	}
+
+static struct shash_alg blake2b_algs[] = {
+	BLAKE2B_ALG("blake2b-160", "blake2b-160-generic",
+		    BLAKE2B_160_HASH_SIZE),
+	BLAKE2B_ALG("blake2b-256", "blake2b-256-generic",
+		    BLAKE2B_256_HASH_SIZE),
+	BLAKE2B_ALG("blake2b-384", "blake2b-384-generic",
+		    BLAKE2B_384_HASH_SIZE),
+	BLAKE2B_ALG("blake2b-512", "blake2b-512-generic",
+		    BLAKE2B_512_HASH_SIZE),
 };
 
 static int __init blake2b_mod_init(void)
Signature · 1 line
2.29.2
author maintainer
#3 lore raw

PATCH v2 3/11 crypto: blake2b - export helpers for optimized implementations

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

In preparation for adding optimized implementations of BLAKE2b (as well as possibly supporting BLAKE2b through the library API in the future), create headers <crypto/blake2b.h> and <crypto/internal/blake2b.h> that contain common constants, structs, and helper functions for BLAKE2b.

Furthermore, export helper functions that reduce the amount of boilerplate that needs to be duplicated in optimized implementations of BLAKE2b. This includes exporting the generic setkey() and init() functions as-is, as well as exporting the update() and final() functions with a function pointer argument added to provide an implementation of the compression function. (The compression function is the only thing that optimized implementations really want to override.)

This is similar to what is already done for nhpoly1305, sha1, and sha256. It's also similar to what I'll be doing for blake2s.

I didn't go so far as to put the helper functions in a separate module blake2b_helpers.ko, like I'm doing for BLAKE2s. This would be needed if BLAKE2b gets exposed through the library API, but it can be done later.

---
 crypto/blake2b_generic.c          | 95 ++++++++++++++++---------------
 include/crypto/blake2b.h          | 27 +++++++++
 include/crypto/internal/blake2b.h | 33 +++++++++++
 3 files changed, 110 insertions(+), 45 deletions(-)
 create mode 100644 include/crypto/blake2b.h
 create mode 100644 include/crypto/internal/blake2b.h
crypto/blake2b_generic.c +50 -45
index 0e38e3e48297c..ee5084f3c92e1 100644
@@ -23,27 +23,9 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/bitops.h>
+#include <crypto/internal/blake2b.h>
 #include <crypto/internal/hash.h>
 
-
-enum blake2b_lengths {
-	BLAKE2B_BLOCK_SIZE = 128,
-	BLAKE2B_KEY_SIZE = 64,
-
-	BLAKE2B_160_HASH_SIZE = 20,
-	BLAKE2B_256_HASH_SIZE =	32,
-	BLAKE2B_384_HASH_SIZE = 48,
-	BLAKE2B_512_HASH_SIZE = 64,
-};
-
-struct blake2b_state {
-	u64      h[8];
-	u64      t[2];
-	u64      f[2];
-	u8       buf[BLAKE2B_BLOCK_SIZE];
-	size_t   buflen;
-};
-
 static const u64 blake2b_IV[8] = {
 	0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
 	0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
@@ -96,8 +78,8 @@ static void blake2b_increment_counter(struct blake2b_state *S, const u64 inc)
 		G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
 	} while (0)
 
-static void blake2b_compress(struct blake2b_state *S,
-			     const u8 block[BLAKE2B_BLOCK_SIZE])
+static void blake2b_compress_one_generic(struct blake2b_state *S,
+					 const u8 block[BLAKE2B_BLOCK_SIZE])
 {
 	u64 m[16];
 	u64 v[16];
@@ -140,12 +122,18 @@ static void blake2b_compress(struct blake2b_state *S,
 #undef G
 #undef ROUND
 
-struct blake2b_tfm_ctx {
-	u8 key[BLAKE2B_KEY_SIZE];
-	unsigned int keylen;
-};
+void blake2b_compress_generic(struct blake2b_state *state,
+			      const u8 *block, size_t nblocks, u32 inc)
+{
+	do {
+		blake2b_increment_counter(state, inc);
+		blake2b_compress_one_generic(state, block);
+		block += BLAKE2B_BLOCK_SIZE;
+	} while (--nblocks);
+}
+EXPORT_SYMBOL_GPL(blake2b_compress_generic);
 
-static int blake2b_setkey(struct crypto_shash *tfm, const u8 *key,
+int crypto_blake2b_setkey(struct crypto_shash *tfm, const u8 *key,
 			  unsigned int keylen)
 {
 	struct blake2b_tfm_ctx *tctx = crypto_shash_ctx(tfm);
@@ -158,8 +146,9 @@ static int blake2b_setkey(struct crypto_shash *tfm, const u8 *key,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(crypto_blake2b_setkey);
 
-static int blake2b_init(struct shash_desc *desc)
+int crypto_blake2b_init(struct shash_desc *desc)
 {
 	struct blake2b_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
 	struct blake2b_state *state = shash_desc_ctx(desc);
@@ -181,9 +170,10 @@ static int blake2b_init(struct shash_desc *desc)
 	}
 	return 0;
 }
+EXPORT_SYMBOL_GPL(crypto_blake2b_init);
 
-static int blake2b_update(struct shash_desc *desc, const u8 *in,
-			  unsigned int inlen)
+int crypto_blake2b_update(struct shash_desc *desc, const u8 *in,
+			  unsigned int inlen, blake2b_compress_t compress)
 {
 	struct blake2b_state *state = shash_desc_ctx(desc);
 	const size_t left = state->buflen;
@@ -194,18 +184,19 @@ static int blake2b_update(struct shash_desc *desc, const u8 *in,
 
 	if (inlen > fill) {
 		state->buflen = 0;
-		/* Fill buffer */
 		memcpy(state->buf + left, in, fill);
-		blake2b_increment_counter(state, BLAKE2B_BLOCK_SIZE);
-		/* Compress */
-		blake2b_compress(state, state->buf);
+		(*compress)(state, state->buf, 1, BLAKE2B_BLOCK_SIZE);
 		in += fill;
 		inlen -= fill;
-		while (inlen > BLAKE2B_BLOCK_SIZE) {
-			blake2b_increment_counter(state, BLAKE2B_BLOCK_SIZE);
-			blake2b_compress(state, in);
-			in += BLAKE2B_BLOCK_SIZE;
-			inlen -= BLAKE2B_BLOCK_SIZE;
+		if (inlen > BLAKE2B_BLOCK_SIZE) {
+			/* Hash one less (full) block than strictly possible */
+			size_t nbytes = round_up(inlen - BLAKE2B_BLOCK_SIZE,
+						 BLAKE2B_BLOCK_SIZE);
+
+			(*compress)(state, in, nbytes / BLAKE2B_BLOCK_SIZE,
+				    BLAKE2B_BLOCK_SIZE);
+			in += nbytes;
+			inlen -= nbytes;
 		}
 	}
 	memcpy(state->buf + state->buflen, in, inlen);
@@ -213,20 +204,28 @@ static int blake2b_update(struct shash_desc *desc, const u8 *in,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(crypto_blake2b_update);
+
+static int crypto_blake2b_update_generic(struct shash_desc *desc,
+					 const u8 *in, unsigned int inlen)
+{
+	return crypto_blake2b_update(desc, in, inlen, blake2b_compress_generic);
+}
 
-static int blake2b_final(struct shash_desc *desc, u8 *out)
+int crypto_blake2b_final(struct shash_desc *desc, u8 *out,
+			 blake2b_compress_t compress)
 {
 	struct blake2b_state *state = shash_desc_ctx(desc);
 	const int digestsize = crypto_shash_digestsize(desc->tfm);
 	size_t i;
 
-	blake2b_increment_counter(state, state->buflen);
 	/* Set last block */
 	state->f[0] = (u64)-1;
 	/* Padding */
 	memset(state->buf + state->buflen, 0,
 	       BLAKE2B_BLOCK_SIZE - state->buflen);
-	blake2b_compress(state, state->buf);
+
+	(*compress)(state, state->buf, 1, state->buflen);
 
 	/* Avoid temporary buffer and switch the internal output to LE order */
 	for (i = 0; i < ARRAY_SIZE(state->h); i++)
@@ -235,6 +234,12 @@ static int blake2b_final(struct shash_desc *desc, u8 *out)
 	memcpy(out, state->h, digestsize);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(crypto_blake2b_final);
+
+static int crypto_blake2b_final_generic(struct shash_desc *desc, u8 *out)
+{
+	return crypto_blake2b_final(desc, out, blake2b_compress_generic);
+}
 
 #define BLAKE2B_ALG(name, driver_name, digest_size)			\
 	{								\
@@ -246,10 +251,10 @@ static int blake2b_final(struct shash_desc *desc, u8 *out)
 		.base.cra_ctxsize	= sizeof(struct blake2b_tfm_ctx), \
 		.base.cra_module	= THIS_MODULE,			\
 		.digestsize		= digest_size,			\
-		.setkey			= blake2b_setkey,		\
-		.init			= blake2b_init,			\
-		.update			= blake2b_update,		\
-		.final			= blake2b_final,		\
+		.setkey			= crypto_blake2b_setkey,	\
+		.init			= crypto_blake2b_init,		\
+		.update			= crypto_blake2b_update_generic, \
+		.final			= crypto_blake2b_final_generic,	\
 		.descsize		= sizeof(struct blake2b_state),	\
 	}
 
include/crypto/blake2b.h new file +27 -0
new file mode 100644
index 0000000000000..7c3045df597c0
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _CRYPTO_BLAKE2B_H
+#define _CRYPTO_BLAKE2B_H
+
+#include <linux/types.h>
+
+enum blake2b_lengths {
+	BLAKE2B_BLOCK_SIZE = 128,
+	BLAKE2B_KEY_SIZE = 64,
+
+	BLAKE2B_160_HASH_SIZE = 20,
+	BLAKE2B_256_HASH_SIZE =	32,
+	BLAKE2B_384_HASH_SIZE = 48,
+	BLAKE2B_512_HASH_SIZE = 64,
+};
+
+struct blake2b_state {
+	/* 'h', 't', and 'f' are used in assembly code, so keep them as-is. */
+	u64      h[8];
+	u64      t[2];
+	u64      f[2];
+	u8       buf[BLAKE2B_BLOCK_SIZE];
+	size_t   buflen;
+};
+
+#endif /* _CRYPTO_BLAKE2B_H */
include/crypto/internal/blake2b.h new file +33 -0
new file mode 100644
index 0000000000000..822dff79bab91
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _CRYPTO_INTERNAL_BLAKE2B_H
+#define _CRYPTO_INTERNAL_BLAKE2B_H
+
+#include <crypto/blake2b.h>
+
+struct blake2b_tfm_ctx {
+	u8 key[BLAKE2B_KEY_SIZE];
+	unsigned int keylen;
+};
+
+void blake2b_compress_generic(struct blake2b_state *state,
+			      const u8 *block, size_t nblocks, u32 inc);
+
+typedef void (*blake2b_compress_t)(struct blake2b_state *state,
+				   const u8 *block, size_t nblocks, u32 inc);
+
+struct crypto_shash;
+struct shash_desc;
+
+int crypto_blake2b_setkey(struct crypto_shash *tfm, const u8 *key,
+			  unsigned int keylen);
+
+int crypto_blake2b_init(struct shash_desc *desc);
+
+int crypto_blake2b_update(struct shash_desc *desc, const u8 *in,
+			  unsigned int inlen, blake2b_compress_t compress);
+
+int crypto_blake2b_final(struct shash_desc *desc, u8 *out,
+			 blake2b_compress_t compress);
+
+#endif /* _CRYPTO_INTERNAL_BLAKE2B_H */
Signature · 1 line
2.29.2
author maintainer
#4 lore raw

PATCH v2 4/11 crypto: blake2b - update file comment

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

The file comment for blake2b_generic.c makes it sound like it's the reference implementation of BLAKE2b with only minor changes. But it's actually been changed a lot. Update the comment to make this clearer.

---
 crypto/blake2b_generic.c | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)
crypto/blake2b_generic.c +10 -13
index ee5084f3c92e1..9d6c0dbf1a8b5 100644
@@ -1,21 +1,18 @@
 // SPDX-License-Identifier: (GPL-2.0-only OR Apache-2.0)
 /*
- * BLAKE2b reference source code package - reference C implementations
+ * Generic implementation of the BLAKE2b digest algorithm.  Based on the BLAKE2b
+ * reference implementation, but it has been heavily modified for use in the
+ * kernel.  The reference implementation was:
  *
- * Copyright 2012, Samuel Neves <[email protected]>.  You may use this under the
- * terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
- * your option.  The terms of these licenses can be found at:
+ *	Copyright 2012, Samuel Neves <[email protected]>.  You may use this under
+ *	the terms of the CC0, the OpenSSL Licence, or the Apache Public License
+ *	2.0, at your option.  The terms of these licenses can be found at:
  *
- * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- * - OpenSSL license   : https://www.openssl.org/source/license.html
- * - Apache 2.0        : https://www.apache.org/licenses/LICENSE-2.0
+ *	- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
+ *	- OpenSSL license   : https://www.openssl.org/source/license.html
+ *	- Apache 2.0        : https://www.apache.org/licenses/LICENSE-2.0
  *
- * More information about the BLAKE2 hash function can be found at
- * https://blake2.net.
- *
- * Note: the original sources have been modified for inclusion in linux kernel
- * in terms of coding style, using generic helpers and simplifications of error
- * handling.
+ * More information about BLAKE2 can be found at https://blake2.net.
  */
 
 #include <asm/unaligned.h>
Signature · 1 line
2.29.2
author maintainer
#5 lore raw

PATCH v2 5/11 crypto: arm/blake2b - add NEON-accelerated BLAKE2b

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

Add a NEON-accelerated implementation of BLAKE2b.

On Cortex-A7 (which these days is the most common ARM processor that doesn't have the ARMv8 Crypto Extensions), this is over twice as fast as SHA-256, and slightly faster than SHA-1. It is also almost three times as fast as the generic implementation of BLAKE2b:

	Algorithm            Cycles per byte (on 4096-byte messages)
	===================  =======================================
	blake2b-256-neon     14.0
	sha1-neon            16.3
	sha1-asm             20.8
	blake2s-256-generic  26.1
	sha256-neon	     28.9
	sha256-asm	     32.0
	blake2b-256-generic  39.9

This implementation isn't directly based on any other implementation, but it borrows some ideas from previous NEON code I've written as well as from chacha-neon-core.S. At least on Cortex-A7, it is faster than the other NEON implementations of BLAKE2b I'm aware of (the implementation in the BLAKE2 official repository using intrinsics, and Andrew Moon's implementation which can be found in SUPERCOP). It does only one block at a time, so it performs well on short messages too.

NEON-accelerated BLAKE2b is useful because there is interest in using BLAKE2b-256 for dm-verity on low-end Android devices (specifically, devices that lack the ARMv8 Crypto Extensions) to replace SHA-1. On these devices, the performance cost of upgrading to SHA-256 may be unacceptable, whereas BLAKE2b-256 would actually improve performance.

Although BLAKE2b is intended for 64-bit platforms (unlike BLAKE2s which is intended for 32-bit platforms), on 32-bit ARM processors with NEON, BLAKE2b is actually faster than BLAKE2s. This is because NEON supports 64-bit operations, and because BLAKE2s's block size is too small for NEON to be helpful for it. The best I've been able to do with BLAKE2s on Cortex-A7 is 19.0 cpb with an optimized scalar implementation.

(I didn't try BLAKE2sp and BLAKE3, which in theory would be faster, but they're more complex as they require running multiple hashes at once. Note that BLAKE2b already uses all the NEON bandwidth on the Cortex-A7, so I expect that any speedup from BLAKE2sp or BLAKE3 would come only from the smaller number of rounds, not from the extra parallelism.)

For now this BLAKE2b implementation is only exposed via the shash API, since the library API doesn't support BLAKE2b yet. However, I've tried to keep things somewhat consistent with BLAKE2s, e.g. by defining blake2b_compress_arch() which is analogous to blake2s_compress_arch() and could be exported for use by the library API later if needed.

---
 arch/arm/crypto/Kconfig             |  10 +
 arch/arm/crypto/Makefile            |   2 +
 arch/arm/crypto/blake2b-neon-core.S | 345 ++++++++++++++++++++++++++++
 arch/arm/crypto/blake2b-neon-glue.c | 105 +++++++++
 4 files changed, 462 insertions(+)
 create mode 100644 arch/arm/crypto/blake2b-neon-core.S
 create mode 100644 arch/arm/crypto/blake2b-neon-glue.c
arch/arm/crypto/Kconfig +10 -0
index c9bf2df85cb90..f6a14c186b4ec 100644
@@ -62,6 +62,16 @@ config CRYPTO_SHA512_ARM
 	  SHA-512 secure hash standard (DFIPS 180-2) implemented
 	  using optimized ARM assembler and NEON, when available.
 
+config CRYPTO_BLAKE2B_NEON
+	tristate "BLAKE2b digest algorithm (ARM NEON)"
+	depends on KERNEL_MODE_NEON
+	select CRYPTO_BLAKE2B
+	help
+	  BLAKE2b digest algorithm optimized with ARM NEON instructions.
+	  On ARM processors that have NEON support but not the ARMv8
+	  Crypto Extensions, typically this BLAKE2b implementation is
+	  much faster than SHA-2 and slightly faster than SHA-1.
+
 config CRYPTO_AES_ARM
 	tristate "Scalar AES cipher for ARM"
 	select CRYPTO_ALGAPI
arch/arm/crypto/Makefile +2 -0
index b745c17d356fe..ab835ceeb4f2e 100644
@@ -9,6 +9,7 @@ obj-$(CONFIG_CRYPTO_SHA1_ARM) += sha1-arm.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM_NEON) += sha1-arm-neon.o
 obj-$(CONFIG_CRYPTO_SHA256_ARM) += sha256-arm.o
 obj-$(CONFIG_CRYPTO_SHA512_ARM) += sha512-arm.o
+obj-$(CONFIG_CRYPTO_BLAKE2B_NEON) += blake2b-neon.o
 obj-$(CONFIG_CRYPTO_CHACHA20_NEON) += chacha-neon.o
 obj-$(CONFIG_CRYPTO_POLY1305_ARM) += poly1305-arm.o
 obj-$(CONFIG_CRYPTO_NHPOLY1305_NEON) += nhpoly1305-neon.o
@@ -29,6 +30,7 @@ sha256-arm-neon-$(CONFIG_KERNEL_MODE_NEON) := sha256_neon_glue.o
 sha256-arm-y	:= sha256-core.o sha256_glue.o $(sha256-arm-neon-y)
 sha512-arm-neon-$(CONFIG_KERNEL_MODE_NEON) := sha512-neon-glue.o
 sha512-arm-y	:= sha512-core.o sha512-glue.o $(sha512-arm-neon-y)
+blake2b-neon-y  := blake2b-neon-core.o blake2b-neon-glue.o
 sha1-arm-ce-y	:= sha1-ce-core.o sha1-ce-glue.o
 sha2-arm-ce-y	:= sha2-ce-core.o sha2-ce-glue.o
 aes-arm-ce-y	:= aes-ce-core.o aes-ce-glue.o
arch/arm/crypto/blake2b-neon-core.S new file +345 -0

345 lines not on this page · raw message

arch/arm/crypto/blake2b-neon-glue.c new file +105 -0

105 lines not on this page · raw message

Signature · 1 line
2.29.2
author maintainer
#6 lore raw

PATCH v2 6/11 crypto: blake2s - define shash_alg structs using macros

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

The shash_alg structs for the four variants of BLAKE2s are identical except for the algorithm name, driver name, and digest size. So, avoid code duplication by using a macro to define these structs.

---
 crypto/blake2s_generic.c | 88 ++++++++++++----------------------------
 1 file changed, 27 insertions(+), 61 deletions(-)
crypto/blake2s_generic.c +27 -61
index 005783ff45ad0..e3aa6e7ff3d83 100644
@@ -83,67 +83,33 @@ static int crypto_blake2s_final(struct shash_desc *desc, u8 *out)
 	return 0;
 }
 
-static struct shash_alg blake2s_algs[] = {{
-	.base.cra_name		= "blake2s-128",
-	.base.cra_driver_name	= "blake2s-128-generic",
-	.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-	.base.cra_ctxsize	= sizeof(struct blake2s_tfm_ctx),
-	.base.cra_priority	= 200,
-	.base.cra_blocksize     = BLAKE2S_BLOCK_SIZE,
-	.base.cra_module	= THIS_MODULE,
-
-	.digestsize		= BLAKE2S_128_HASH_SIZE,
-	.setkey			= crypto_blake2s_setkey,
-	.init			= crypto_blake2s_init,
-	.update			= crypto_blake2s_update,
-	.final			= crypto_blake2s_final,
-	.descsize		= sizeof(struct blake2s_state),
-}, {
-	.base.cra_name		= "blake2s-160",
-	.base.cra_driver_name	= "blake2s-160-generic",
-	.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-	.base.cra_ctxsize	= sizeof(struct blake2s_tfm_ctx),
-	.base.cra_priority	= 200,
-	.base.cra_blocksize     = BLAKE2S_BLOCK_SIZE,
-	.base.cra_module	= THIS_MODULE,
-
-	.digestsize		= BLAKE2S_160_HASH_SIZE,
-	.setkey			= crypto_blake2s_setkey,
-	.init			= crypto_blake2s_init,
-	.update			= crypto_blake2s_update,
-	.final			= crypto_blake2s_final,
-	.descsize		= sizeof(struct blake2s_state),
-}, {
-	.base.cra_name		= "blake2s-224",
-	.base.cra_driver_name	= "blake2s-224-generic",
-	.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-	.base.cra_ctxsize	= sizeof(struct blake2s_tfm_ctx),
-	.base.cra_priority	= 200,
-	.base.cra_blocksize     = BLAKE2S_BLOCK_SIZE,
-	.base.cra_module	= THIS_MODULE,
-
-	.digestsize		= BLAKE2S_224_HASH_SIZE,
-	.setkey			= crypto_blake2s_setkey,
-	.init			= crypto_blake2s_init,
-	.update			= crypto_blake2s_update,
-	.final			= crypto_blake2s_final,
-	.descsize		= sizeof(struct blake2s_state),
-}, {
-	.base.cra_name		= "blake2s-256",
-	.base.cra_driver_name	= "blake2s-256-generic",
-	.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-	.base.cra_ctxsize	= sizeof(struct blake2s_tfm_ctx),
-	.base.cra_priority	= 200,
-	.base.cra_blocksize     = BLAKE2S_BLOCK_SIZE,
-	.base.cra_module	= THIS_MODULE,
-
-	.digestsize		= BLAKE2S_256_HASH_SIZE,
-	.setkey			= crypto_blake2s_setkey,
-	.init			= crypto_blake2s_init,
-	.update			= crypto_blake2s_update,
-	.final			= crypto_blake2s_final,
-	.descsize		= sizeof(struct blake2s_state),
-}};
+#define BLAKE2S_ALG(name, driver_name, digest_size)			\
+	{								\
+		.base.cra_name		= name,				\
+		.base.cra_driver_name	= driver_name,			\
+		.base.cra_priority	= 100,				\
+		.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,	\
+		.base.cra_blocksize	= BLAKE2S_BLOCK_SIZE,		\
+		.base.cra_ctxsize	= sizeof(struct blake2s_tfm_ctx), \
+		.base.cra_module	= THIS_MODULE,			\
+		.digestsize		= digest_size,			\
+		.setkey			= crypto_blake2s_setkey,	\
+		.init			= crypto_blake2s_init,		\
+		.update			= crypto_blake2s_update,	\
+		.final			= crypto_blake2s_final,		\
+		.descsize		= sizeof(struct blake2s_state),	\
+	}
+
+static struct shash_alg blake2s_algs[] = {
+	BLAKE2S_ALG("blake2s-128", "blake2s-128-generic",
+		    BLAKE2S_128_HASH_SIZE),
+	BLAKE2S_ALG("blake2s-160", "blake2s-160-generic",
+		    BLAKE2S_160_HASH_SIZE),
+	BLAKE2S_ALG("blake2s-224", "blake2s-224-generic",
+		    BLAKE2S_224_HASH_SIZE),
+	BLAKE2S_ALG("blake2s-256", "blake2s-256-generic",
+		    BLAKE2S_256_HASH_SIZE),
+};
 
 static int __init blake2s_mod_init(void)
 {
Signature · 1 line
2.29.2
author maintainer
#7 lore raw

PATCH v2 7/11 crypto: x86/blake2s - define shash_alg structs using macros

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

The shash_alg structs for the four variants of BLAKE2s are identical except for the algorithm name, driver name, and digest size. So, avoid code duplication by using a macro to define these structs.

---
 arch/x86/crypto/blake2s-glue.c | 84 ++++++++++------------------------
 1 file changed, 23 insertions(+), 61 deletions(-)
arch/x86/crypto/blake2s-glue.c +23 -61
index c025a01cf7084..4dcb2ee89efc9 100644
@@ -129,67 +129,29 @@ static int crypto_blake2s_final(struct shash_desc *desc, u8 *out)
 	return 0;
 }
 
-static struct shash_alg blake2s_algs[] = {{
-	.base.cra_name		= "blake2s-128",
-	.base.cra_driver_name	= "blake2s-128-x86",
-	.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-	.base.cra_ctxsize	= sizeof(struct blake2s_tfm_ctx),
-	.base.cra_priority	= 200,
-	.base.cra_blocksize     = BLAKE2S_BLOCK_SIZE,
-	.base.cra_module	= THIS_MODULE,
-
-	.digestsize		= BLAKE2S_128_HASH_SIZE,
-	.setkey			= crypto_blake2s_setkey,
-	.init			= crypto_blake2s_init,
-	.update			= crypto_blake2s_update,
-	.final			= crypto_blake2s_final,
-	.descsize		= sizeof(struct blake2s_state),
-}, {
-	.base.cra_name		= "blake2s-160",
-	.base.cra_driver_name	= "blake2s-160-x86",
-	.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-	.base.cra_ctxsize	= sizeof(struct blake2s_tfm_ctx),
-	.base.cra_priority	= 200,
-	.base.cra_blocksize     = BLAKE2S_BLOCK_SIZE,
-	.base.cra_module	= THIS_MODULE,
-
-	.digestsize		= BLAKE2S_160_HASH_SIZE,
-	.setkey			= crypto_blake2s_setkey,
-	.init			= crypto_blake2s_init,
-	.update			= crypto_blake2s_update,
-	.final			= crypto_blake2s_final,
-	.descsize		= sizeof(struct blake2s_state),
-}, {
-	.base.cra_name		= "blake2s-224",
-	.base.cra_driver_name	= "blake2s-224-x86",
-	.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-	.base.cra_ctxsize	= sizeof(struct blake2s_tfm_ctx),
-	.base.cra_priority	= 200,
-	.base.cra_blocksize     = BLAKE2S_BLOCK_SIZE,
-	.base.cra_module	= THIS_MODULE,
-
-	.digestsize		= BLAKE2S_224_HASH_SIZE,
-	.setkey			= crypto_blake2s_setkey,
-	.init			= crypto_blake2s_init,
-	.update			= crypto_blake2s_update,
-	.final			= crypto_blake2s_final,
-	.descsize		= sizeof(struct blake2s_state),
-}, {
-	.base.cra_name		= "blake2s-256",
-	.base.cra_driver_name	= "blake2s-256-x86",
-	.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-	.base.cra_ctxsize	= sizeof(struct blake2s_tfm_ctx),
-	.base.cra_priority	= 200,
-	.base.cra_blocksize     = BLAKE2S_BLOCK_SIZE,
-	.base.cra_module	= THIS_MODULE,
-
-	.digestsize		= BLAKE2S_256_HASH_SIZE,
-	.setkey			= crypto_blake2s_setkey,
-	.init			= crypto_blake2s_init,
-	.update			= crypto_blake2s_update,
-	.final			= crypto_blake2s_final,
-	.descsize		= sizeof(struct blake2s_state),
-}};
+#define BLAKE2S_ALG(name, driver_name, digest_size)			\
+	{								\
+		.base.cra_name		= name,				\
+		.base.cra_driver_name	= driver_name,			\
+		.base.cra_priority	= 200,				\
+		.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,	\
+		.base.cra_blocksize	= BLAKE2S_BLOCK_SIZE,		\
+		.base.cra_ctxsize	= sizeof(struct blake2s_tfm_ctx), \
+		.base.cra_module	= THIS_MODULE,			\
+		.digestsize		= digest_size,			\
+		.setkey			= crypto_blake2s_setkey,	\
+		.init			= crypto_blake2s_init,		\
+		.update			= crypto_blake2s_update,	\
+		.final			= crypto_blake2s_final,		\
+		.descsize		= sizeof(struct blake2s_state),	\
+	}
+
+static struct shash_alg blake2s_algs[] = {
+	BLAKE2S_ALG("blake2s-128", "blake2s-128-x86", BLAKE2S_128_HASH_SIZE),
+	BLAKE2S_ALG("blake2s-160", "blake2s-160-x86", BLAKE2S_160_HASH_SIZE),
+	BLAKE2S_ALG("blake2s-224", "blake2s-224-x86", BLAKE2S_224_HASH_SIZE),
+	BLAKE2S_ALG("blake2s-256", "blake2s-256-x86", BLAKE2S_256_HASH_SIZE),
+};
 
 static int __init blake2s_mod_init(void)
 {
Signature · 1 line
2.29.2
author maintainer
#8 lore raw

PATCH v2 8/11 crypto: blake2s - remove unneeded includes

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

It doesn't make sense for the generic implementation of BLAKE2s to include <crypto/internal/simd.h> and <linux/jump_label.h>, as these are things that would only be useful in an architecture-specific implementation. Remove these unnecessary includes.

---
 crypto/blake2s_generic.c | 2 --
 1 file changed, 2 deletions(-)
crypto/blake2s_generic.c +0 -2
index e3aa6e7ff3d83..b89536c3671cf 100644
@@ -4,11 +4,9 @@
  */
 
 #include <crypto/internal/blake2s.h>
-#include <crypto/internal/simd.h>
 #include <crypto/internal/hash.h>
 
 #include <linux/types.h>
-#include <linux/jump_label.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 
Signature · 1 line
2.29.2
author maintainer
#9 lore raw

PATCH v2 9/11 crypto: blake2s - share the "shash" API boilerplate code

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

Move the boilerplate code for setkey(), init(), update(), and final() from blake2s_generic.ko into a new module blake2s_helpers.ko, and export it so that it can be used by other shash implementations of BLAKE2s.

setkey() and init() are exported as-is, while update() and final() have a blake2s_compress_t function pointer argument added. This allows the implementation of the compression function to be overridden, which is the only part that optimized implementations really care about.

The helper functions are defined in a separate module blake2s_helpers.ko (rather than just than in blake2s_generic.ko) because we can't simply select CRYPTO_BLAKE2B from CRYPTO_BLAKE2S_X86. Doing this selection unconditionally would make the library API select the shash API, while doing it conditionally on CRYPTO_HASH would create a recursive kconfig dependency on CRYPTO_HASH. As a bonus, using a separate module also allows the generic implementation to be omitted when unneeded.

These helper functions very closely match the ones I defined for BLAKE2b, except the BLAKE2b ones didn't go in a separate module yet because BLAKE2b isn't exposed through the library API yet.

Finally, use these new helper functions in the x86 implementation of BLAKE2s. (This part should be a separate patch, but unfortunately the x86 implementation used the exact same function names like "crypto_blake2s_update()", so it had to be updated at the same time.)

---
 arch/x86/crypto/blake2s-glue.c    | 74 +++-----------------------
 crypto/Kconfig                    |  5 ++
 crypto/Makefile                   |  1 +
 crypto/blake2s_generic.c          | 79 ++++------------------------
 crypto/blake2s_helpers.c          | 87 +++++++++++++++++++++++++++++++
 include/crypto/internal/blake2s.h | 17 ++++++
 6 files changed, 126 insertions(+), 137 deletions(-)
 create mode 100644 crypto/blake2s_helpers.c
arch/x86/crypto/blake2s-glue.c +7 -67
index 4dcb2ee89efc9..1306b3272c77f 100644
@@ -58,75 +58,15 @@ void blake2s_compress_arch(struct blake2s_state *state,
 }
 EXPORT_SYMBOL(blake2s_compress_arch);
 
-static int crypto_blake2s_setkey(struct crypto_shash *tfm, const u8 *key,
-				 unsigned int keylen)
+static int crypto_blake2s_update_x86(struct shash_desc *desc, const u8 *in,
+				     unsigned int inlen)
 {
-	struct blake2s_tfm_ctx *tctx = crypto_shash_ctx(tfm);
-
-	if (keylen == 0 || keylen > BLAKE2S_KEY_SIZE)
-		return -EINVAL;
-
-	memcpy(tctx->key, key, keylen);
-	tctx->keylen = keylen;
-
-	return 0;
-}
-
-static int crypto_blake2s_init(struct shash_desc *desc)
-{
-	struct blake2s_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
-	struct blake2s_state *state = shash_desc_ctx(desc);
-	const int outlen = crypto_shash_digestsize(desc->tfm);
-
-	if (tctx->keylen)
-		blake2s_init_key(state, outlen, tctx->key, tctx->keylen);
-	else
-		blake2s_init(state, outlen);
-
-	return 0;
-}
-
-static int crypto_blake2s_update(struct shash_desc *desc, const u8 *in,
-				 unsigned int inlen)
-{
-	struct blake2s_state *state = shash_desc_ctx(desc);
-	const size_t fill = BLAKE2S_BLOCK_SIZE - state->buflen;
-
-	if (unlikely(!inlen))
-		return 0;
-	if (inlen > fill) {
-		memcpy(state->buf + state->buflen, in, fill);
-		blake2s_compress_arch(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
-		state->buflen = 0;
-		in += fill;
-		inlen -= fill;
-	}
-	if (inlen > BLAKE2S_BLOCK_SIZE) {
-		const size_t nblocks = DIV_ROUND_UP(inlen, BLAKE2S_BLOCK_SIZE);
-		/* Hash one less (full) block than strictly possible */
-		blake2s_compress_arch(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
-		in += BLAKE2S_BLOCK_SIZE * (nblocks - 1);
-		inlen -= BLAKE2S_BLOCK_SIZE * (nblocks - 1);
-	}
-	memcpy(state->buf + state->buflen, in, inlen);
-	state->buflen += inlen;
-
-	return 0;
+	return crypto_blake2s_update(desc, in, inlen, blake2s_compress_arch);
 }
 
-static int crypto_blake2s_final(struct shash_desc *desc, u8 *out)
+static int crypto_blake2s_final_x86(struct shash_desc *desc, u8 *out)
 {
-	struct blake2s_state *state = shash_desc_ctx(desc);
-
-	blake2s_set_lastblock(state);
-	memset(state->buf + state->buflen, 0,
-	       BLAKE2S_BLOCK_SIZE - state->buflen); /* Padding */
-	blake2s_compress_arch(state, state->buf, 1, state->buflen);
-	cpu_to_le32_array(state->h, ARRAY_SIZE(state->h));
-	memcpy(out, state->h, state->outlen);
-	memzero_explicit(state, sizeof(*state));
-
-	return 0;
+	return crypto_blake2s_final(desc, out, blake2s_compress_arch);
 }
 
 #define BLAKE2S_ALG(name, driver_name, digest_size)			\
@@ -141,8 +81,8 @@ static int crypto_blake2s_final(struct shash_desc *desc, u8 *out)
 		.digestsize		= digest_size,			\
 		.setkey			= crypto_blake2s_setkey,	\
 		.init			= crypto_blake2s_init,		\
-		.update			= crypto_blake2s_update,	\
-		.final			= crypto_blake2s_final,		\
+		.update			= crypto_blake2s_update_x86,	\
+		.final			= crypto_blake2s_final_x86,	\
 		.descsize		= sizeof(struct blake2s_state),	\
 	}
 
crypto/Kconfig +5 -0
index a367fcfeb5d45..e3a51154ac0cf 100644
@@ -681,6 +681,7 @@ config CRYPTO_BLAKE2B
 config CRYPTO_BLAKE2S
 	tristate "BLAKE2s digest algorithm"
 	select CRYPTO_LIB_BLAKE2S_GENERIC
+	select CRYPTO_BLAKE2S_HELPERS
 	select CRYPTO_HASH
 	help
 	  Implementation of cryptographic hash function BLAKE2s
@@ -696,11 +697,15 @@ config CRYPTO_BLAKE2S
 
 	  See https://blake2.net for further information.
 
+config CRYPTO_BLAKE2S_HELPERS
+	tristate
+
 config CRYPTO_BLAKE2S_X86
 	tristate "BLAKE2s digest algorithm (x86 accelerated version)"
 	depends on X86 && 64BIT
 	select CRYPTO_LIB_BLAKE2S_GENERIC
 	select CRYPTO_ARCH_HAVE_LIB_BLAKE2S
+	select CRYPTO_BLAKE2S_HELPERS if CRYPTO_HASH
 
 config CRYPTO_CRCT10DIF
 	tristate "CRCT10DIF algorithm"
crypto/Makefile +1 -0
index b279483fba50b..75f99ab82bfc2 100644
@@ -82,6 +82,7 @@ CFLAGS_wp512.o := $(call cc-option,-fno-schedule-insns)  # https://gcc.gnu.org/b
 obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o
 obj-$(CONFIG_CRYPTO_BLAKE2B) += blake2b_generic.o
 obj-$(CONFIG_CRYPTO_BLAKE2S) += blake2s_generic.o
+obj-$(CONFIG_CRYPTO_BLAKE2S_HELPERS) += blake2s_helpers.o
 obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o
 obj-$(CONFIG_CRYPTO_ECB) += ecb.o
 obj-$(CONFIG_CRYPTO_CBC) += cbc.o
crypto/blake2s_generic.c +9 -70

101 lines not on this page · raw message

crypto/blake2s_helpers.c new file +87 -0

87 lines not on this page · raw message

include/crypto/internal/blake2s.h +17 -0
index 6e376ae6b6b58..8c79af7662aa2 100644
@@ -23,4 +23,21 @@ static inline void blake2s_set_lastblock(struct blake2s_state *state)
 	state->f[0] = -1;
 }
 
+typedef void (*blake2s_compress_t)(struct blake2s_state *state,
+				   const u8 *block, size_t nblocks, u32 inc);
+
+struct crypto_shash;
+struct shash_desc;
+
+int crypto_blake2s_setkey(struct crypto_shash *tfm, const u8 *key,
+			  unsigned int keylen);
+
+int crypto_blake2s_init(struct shash_desc *desc);
+
+int crypto_blake2s_update(struct shash_desc *desc, const u8 *in,
+			  unsigned int inlen, blake2s_compress_t compress);
+
+int crypto_blake2s_final(struct shash_desc *desc, u8 *out,
+			 blake2s_compress_t compress);
+
 #endif /* BLAKE2S_INTERNAL_H */
Signature · 1 line
2.29.2
#10 lore raw

Re: [PATCH v2 09/11] crypto: blake2s - share the "shash" API boilerplate code

Quoted 20 lines · Eric Biggers

From: Eric Biggers <[email protected]>

Move the boilerplate code for setkey(), init(), update(), and final() from blake2s_generic.ko into a new module blake2s_helpers.ko, and export it so that it can be used by other shash implementations of BLAKE2s.

setkey() and init() are exported as-is, while update() and final() have a blake2s_compress_t function pointer argument added. This allows the implementation of the compression function to be overridden, which is the only part that optimized implementations really care about.

The helper functions are defined in a separate module blake2s_helpers.ko (rather than just than in blake2s_generic.ko) because we can't simply select CRYPTO_BLAKE2B from CRYPTO_BLAKE2S_X86. Doing this selection unconditionally would make the library API select the shash API, while doing it conditionally on CRYPTO_HASH would create a recursive kconfig dependency on CRYPTO_HASH. As a bonus, using a separate module also allows the generic implementation to be omitted when unneeded.

Quoted 8 lines

These helper functions very closely match the ones I defined for BLAKE2b, except the BLAKE2b ones didn't go in a separate module yet because BLAKE2b isn't exposed through the library API yet.

Finally, use these new helper functions in the x86 implementation of BLAKE2s. (This part should be a separate patch, but unfortunately the x86 implementation used the exact same function names like "crypto_blake2s_update()", so it had to be updated at the same time.)

There's a similar situation happening with chacha20poly1305 and with curve25519. Each of these uses a mildly different approach to how we split things up between library and crypto api code. The _helpers.ko is another one. There any opportunity here to take a more unified/consistant approach? Or is shash slightly different than the others and benefits from a third way?

Jason

author maintainer
#11 lore raw

Re: [PATCH v2 09/11] crypto: blake2s - share the "shash" API boilerplate code

Quoted 30 lines · Jason A. Donenfeld
Quoted 20 lines · Eric Biggers

From: Eric Biggers <[email protected]>

Move the boilerplate code for setkey(), init(), update(), and final() from blake2s_generic.ko into a new module blake2s_helpers.ko, and export it so that it can be used by other shash implementations of BLAKE2s.

setkey() and init() are exported as-is, while update() and final() have a blake2s_compress_t function pointer argument added. This allows the implementation of the compression function to be overridden, which is the only part that optimized implementations really care about.

The helper functions are defined in a separate module blake2s_helpers.ko (rather than just than in blake2s_generic.ko) because we can't simply select CRYPTO_BLAKE2B from CRYPTO_BLAKE2S_X86. Doing this selection unconditionally would make the library API select the shash API, while doing it conditionally on CRYPTO_HASH would create a recursive kconfig dependency on CRYPTO_HASH. As a bonus, using a separate module also allows the generic implementation to be omitted when unneeded.

Quoted 8 lines

These helper functions very closely match the ones I defined for BLAKE2b, except the BLAKE2b ones didn't go in a separate module yet because BLAKE2b isn't exposed through the library API yet.

Finally, use these new helper functions in the x86 implementation of BLAKE2s. (This part should be a separate patch, but unfortunately the x86 implementation used the exact same function names like "crypto_blake2s_update()", so it had to be updated at the same time.)

Quoted 6 lines

There's a similar situation happening with chacha20poly1305 and with curve25519. Each of these uses a mildly different approach to how we split things up between library and crypto api code. The _helpers.ko is another one. There any opportunity here to take a more unified/consistant approach? Or is shash slightly different than the others and benefits from a third way?

What I'm doing isn't that new; it's basically the same thing that's already done for sha1, sha256, sha512, sm3, and nhpoly1305. The difference is just where the shash helper functions are defined. For sha1, sha256, sha512, and sm3 it's in headers (include/crypto/{sha1,sha256,sha512,sm3}_base.h). For nhpoly1305 it's in the same module as the generic implementation (crypto/nhpoly1305.c).

As I mentioned in the commit message, putting the shash helpers in the same module as the generic implementation doesn't work for blake2s due to the need for the architecture-specific blake2s modules to support the library API (and possibly *only* the library API) too. So that mainly leaves the options of adding include/crypto/blake2s_base.h, or adding blake2s_helpers.ko. But these approaches aren't fundamentally different -- it's just a matter of whether the code is short enough for it to make sense to always inline it or not.

It's hard to compare to chacha20 and curve25519 (or chacha20poly1305), as those are different types of algorithms. poly1305 is the most comparable, but for poly1305 the library API works differently in that there are poly1305_{init,update,final}_arch(), not just blake2s_compress_arch(). This seems to be due to some of the characteristics that optimized poly1305 implementations usually have -- they need to compute key powers differently, and they may have an optimized implementation of emitting the final hash value, not just processing blocks.

So that is going to result in a different implementation, as the architecture-specific poly1305 modules have to implement the full init/update/final sequence for the library API, while for blake2s they only need that full sequence for the shash API. Hence the usefulness of adding helper functions for blake2s shash implementations but not poly1305. I don't think this difference is necessarily bad; it just means that optimized blake2s implementations don't need to do as much themselves, in comparison to poly1305.

What we *could* do to reuse even more code than what I've proposed is to make the functions in lib/crypto/blake2s.c usable as the helper functions for shash implementations, like the following. Then blake2s_helpers.ko wouldn't really be necessary. (A few bits would still be needed, but they could be inline functions in a header.) I thought this might be controversial though, as it would add some indirection into the library implementation:

lib/crypto/blake2s.c +25 -18
index 41025a30c524c..5188e1ca43c60 100644
@@ -20,6 +20,16 @@
 bool blake2s_selftest(void);
 
 void blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen)
+{
+	if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S))
+		__blake2s_update(state, in, inlen, blake2s_compress_arch);
+	else
+		__blake2s_update(state, in, inlen, blake2s_compress_generic);
+}
+EXPORT_SYMBOL(blake2s_update);
+
+void __blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen,
+		      blake2s_compress_t compress)
 {
 	const size_t fill = BLAKE2S_BLOCK_SIZE - state->buflen;
 
@@ -27,12 +37,7 @@ void blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen)
 		return;
 	if (inlen > fill) {
 		memcpy(state->buf + state->buflen, in, fill);
-		if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S))
-			blake2s_compress_arch(state, state->buf, 1,
-					      BLAKE2S_BLOCK_SIZE);
-		else
-			blake2s_compress_generic(state, state->buf, 1,
-						 BLAKE2S_BLOCK_SIZE);
+		(*compress)(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
 		state->buflen = 0;
 		in += fill;
 		inlen -= fill;
@@ -40,35 +45,37 @@ void blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen)
 	if (inlen > BLAKE2S_BLOCK_SIZE) {
 		const size_t nblocks = DIV_ROUND_UP(inlen, BLAKE2S_BLOCK_SIZE);
 		/* Hash one less (full) block than strictly possible */
-		if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S))
-			blake2s_compress_arch(state, in, nblocks - 1,
-					      BLAKE2S_BLOCK_SIZE);
-		else
-			blake2s_compress_generic(state, in, nblocks - 1,
-						 BLAKE2S_BLOCK_SIZE);
+		(*compress)(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
 		in += BLAKE2S_BLOCK_SIZE * (nblocks - 1);
 		inlen -= BLAKE2S_BLOCK_SIZE * (nblocks - 1);
 	}
 	memcpy(state->buf + state->buflen, in, inlen);
 	state->buflen += inlen;
 }
-EXPORT_SYMBOL(blake2s_update);
+EXPORT_SYMBOL(__blake2s_update);
 
 void blake2s_final(struct blake2s_state *state, u8 *out)
+{
+	if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S))
+		__blake2s_final(state, out, blake2s_compress_arch);
+	else
+		__blake2s_final(state, out, blake2s_compress_generic);
+}
+EXPORT_SYMBOL(blake2s_final);
+
+void __blake2s_final(struct blake2s_state *state, u8 *out,
+		     blake2s_compress_t compress)
 {
 	WARN_ON(IS_ENABLED(DEBUG) && !out);
 	blake2s_set_lastblock(state);
 	memset(state->buf + state->buflen, 0,
 	       BLAKE2S_BLOCK_SIZE - state->buflen); /* Padding */
-	if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S))
-		blake2s_compress_arch(state, state->buf, 1, state->buflen);
-	else
-		blake2s_compress_generic(state, state->buf, 1, state->buflen);
+	(*compress)(state, state->buf, 1, state->buflen);
 	cpu_to_le32_array(state->h, ARRAY_SIZE(state->h));
 	memcpy(out, state->h, state->outlen);
 	memzero_explicit(state, sizeof(*state));
 }
-EXPORT_SYMBOL(blake2s_final);
+EXPORT_SYMBOL(__blake2s_final);
 
 void blake2s256_hmac(u8 *out, const u8 *in, const u8 *key, const size_t inlen,
 		     const size_t keylen)
#12 lore raw

Re: [PATCH v2 09/11] crypto: blake2s - share the "shash" API boilerplate code

Hey Eric,

The solution you've proposed at the end of your email is actually kind of similar to what we do with curve25519. Check out include/crypto/curve25519.h. The critical difference between that and the blake proposal is that it's in the header for curve25519, so the indirection disappears.

Could we do that with headers for blake?

Jason

author maintainer
#13 lore raw

Re: [PATCH v2 09/11] crypto: blake2s - share the "shash" API boilerplate code

Quoted 10 lines · Jason A. Donenfeld

Hey Eric,

The solution you've proposed at the end of your email is actually kind of similar to what we do with curve25519. Check out include/crypto/curve25519.h. The critical difference between that and the blake proposal is that it's in the header for curve25519, so the indirection disappears.

Could we do that with headers for blake?

That doesn't look too similar, since most of include/crypto/curve25519.h is just for the library API. curve25519_generate_secret() is shared, but it's only a few lines of code and there's no function pointer argument.

Either way, it would be possible to add __blake2s_update() and __blake2s_final() (taking a blake2s_compress_t argument) to include/crypto/internal/blake2s.h, and make these used by (and inlined into) both the library and shash functions.

Note, that's mostly separate from the question of whether blake2s_helpers.ko should exist, since that depends on whether we want the functions in it to get inlined into every shash implementation or not. I don't really have a strong preference. They did seem long enough to make them out-of-line; however, indirect calls are bad too. If we go with inlining, then the shash helper functions (crypto_blake2s_{setkey,init,update,final}()) would just be inline functions in include/crypto/internal/blake2s.h too, similar to sha256_base.h, and they would get compiled into both blake2s_generic.ko and blake2s-${arch}.ko.

- Eric

author maintainer
#14 lore raw

PATCH v2 10/11 crypto: arm/blake2s - add ARM scalar optimized BLAKE2s

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

Add an ARM scalar optimized implementation of BLAKE2s.

NEON isn't very useful for BLAKE2s because the BLAKE2s block size is too small for NEON to help. Each NEON instruction would depend on the previous one, resulting in poor performance.

With scalar instructions, on the other hand, we can take advantage of ARM's "free" rotations (like I did in chacha-scalar-core.S) to get an implementation get runs much faster than the C implementation.

Performance results on Cortex-A7 in cycles per byte using the shash API:

	4096-byte messages:
		blake2s-256-arm:     18.8
		blake2s-256-generic: 26.1

	500-byte messages:
		blake2s-256-arm:     20.7
		blake2s-256-generic: 28.3

	100-byte messages:
		blake2s-256-arm:     32.3
		blake2s-256-generic: 42.4

	32-byte messages:
		blake2s-256-arm:     55.8
		blake2s-256-generic: 72.1

Except on very short messages, this is still slower than the NEON implementation of BLAKE2b which I've written; that is 14.0, 16.7, 26.2, and 80.6 cpb on 4096, 500, 100, and 32-byte messages, respectively. However, optimized BLAKE2s is useful for cases where BLAKE2s is used instead of BLAKE2b, such as WireGuard.

This new implementation is added in the form of a new module blake2s-arm.ko, which is analogous to blake2s-x86_64.ko in that it provides blake2s_compress_arch() for use by the library API as well as optionally register the algorithms with the shash API.

---
 arch/arm/crypto/Kconfig        |  10 ++
 arch/arm/crypto/Makefile       |   2 +
 arch/arm/crypto/blake2s-core.S | 272 +++++++++++++++++++++++++++++++++
 arch/arm/crypto/blake2s-glue.c |  78 ++++++++++
 4 files changed, 362 insertions(+)
 create mode 100644 arch/arm/crypto/blake2s-core.S
 create mode 100644 arch/arm/crypto/blake2s-glue.c
arch/arm/crypto/Kconfig +10 -0
index f6a14c186b4ec..e87e3bc9b6d5e 100644
@@ -72,6 +72,16 @@ config CRYPTO_BLAKE2B_NEON
 	  Crypto Extensions, typically this BLAKE2b implementation is
 	  much faster than SHA-2 and slightly faster than SHA-1.
 
+config CRYPTO_BLAKE2S_ARM
+	tristate "BLAKE2s digest algorithm (ARM)"
+	select CRYPTO_ARCH_HAVE_LIB_BLAKE2S
+	select CRYPTO_BLAKE2S_HELPERS if CRYPTO_HASH
+	help
+	  BLAKE2s digest algorithm optimized with ARM scalar instructions.  This
+	  is faster than the generic implementations of BLAKE2s and BLAKE2b, but
+	  slower than the NEON implementation of BLAKE2b.  (There is no NEON
+	  implementation of BLAKE2s, since NEON doesn't really help with it.)
+
 config CRYPTO_AES_ARM
 	tristate "Scalar AES cipher for ARM"
 	select CRYPTO_ALGAPI
arch/arm/crypto/Makefile +2 -0
index ab835ceeb4f2e..fcd80f660b762 100644
@@ -10,6 +10,7 @@ obj-$(CONFIG_CRYPTO_SHA1_ARM_NEON) += sha1-arm-neon.o
 obj-$(CONFIG_CRYPTO_SHA256_ARM) += sha256-arm.o
 obj-$(CONFIG_CRYPTO_SHA512_ARM) += sha512-arm.o
 obj-$(CONFIG_CRYPTO_BLAKE2B_NEON) += blake2b-neon.o
+obj-$(CONFIG_CRYPTO_BLAKE2S_ARM) += blake2s-arm.o
 obj-$(CONFIG_CRYPTO_CHACHA20_NEON) += chacha-neon.o
 obj-$(CONFIG_CRYPTO_POLY1305_ARM) += poly1305-arm.o
 obj-$(CONFIG_CRYPTO_NHPOLY1305_NEON) += nhpoly1305-neon.o
@@ -31,6 +32,7 @@ sha256-arm-y	:= sha256-core.o sha256_glue.o $(sha256-arm-neon-y)
 sha512-arm-neon-$(CONFIG_KERNEL_MODE_NEON) := sha512-neon-glue.o
 sha512-arm-y	:= sha512-core.o sha512-glue.o $(sha512-arm-neon-y)
 blake2b-neon-y  := blake2b-neon-core.o blake2b-neon-glue.o
+blake2s-arm-y   := blake2s-core.o blake2s-glue.o
 sha1-arm-ce-y	:= sha1-ce-core.o sha1-ce-glue.o
 sha2-arm-ce-y	:= sha2-ce-core.o sha2-ce-glue.o
 aes-arm-ce-y	:= aes-ce-core.o aes-ce-glue.o
arch/arm/crypto/blake2s-core.S new file +272 -0

272 lines not on this page · raw message

arch/arm/crypto/blake2s-glue.c new file +78 -0

78 lines not on this page · raw message

Signature · 1 line
2.29.2
author maintainer
#15 lore raw

PATCH v2 11/11 wireguard: Kconfig: select CRYPTO_BLAKE2S_ARM

In reply to Eric Biggers

From: Eric Biggers <[email protected]>

When available, select the new implementation of BLAKE2s for 32-bit ARM. This is faster than the generic C implementation.

---
 drivers/net/Kconfig | 1 +
 1 file changed, 1 insertion(+)
drivers/net/Kconfig +1 -0
index 260f9f46668b8..672fcdd9aecbb 100644
@@ -90,6 +90,7 @@ config WIREGUARD
 	select CRYPTO_CHACHA20_NEON if (ARM || ARM64) && KERNEL_MODE_NEON
 	select CRYPTO_POLY1305_NEON if ARM64 && KERNEL_MODE_NEON
 	select CRYPTO_POLY1305_ARM if ARM
+	select CRYPTO_BLAKE2S_ARM if ARM
 	select CRYPTO_CURVE25519_NEON if ARM && KERNEL_MODE_NEON
 	select CRYPTO_CHACHA_MIPS if CPU_MIPS32_R2
 	select CRYPTO_POLY1305_MIPS if CPU_MIPS32 || (CPU_MIPS64 && 64BIT)
Signature · 1 line
2.29.2
maintainer Reviewed-by on v2 11/11
#16 lore raw

Re: [PATCH v2 11/11] wireguard: Kconfig: select CRYPTO_BLAKE2S_ARM

Quoted 7 lines · Eric Biggers

From: Eric Biggers <[email protected]>

When available, select the new implementation of BLAKE2s for 32-bit ARM. This is faster than the generic C implementation.

When this series is ready, feel free to pull this commit in via Herbert's tree, rather than my usual wireguard-linux.git->net-next.git route. That will ensure the blake2s stuff lands all at once and we won't have to synchronize anything.

maintainer Acked-by on the v2 series
#17 lore raw
In reply to Eric Biggers
Quoted 30 lines · Eric Biggers

This patchset adds 32-bit ARM assembly language implementations of BLAKE2b and BLAKE2s.

The BLAKE2b implementation is NEON-accelerated, while the BLAKE2s implementation uses scalar instructions since NEON doesn't work very well for it. The BLAKE2b implementation is faster and is expected to be useful as a replacement for SHA-1 in dm-verity, while the BLAKE2s implementation would be useful for WireGuard which uses BLAKE2s.

Both implementations are provided via the shash API, while BLAKE2s is also provided via the library API.

While adding these, I also reworked the generic implementations of BLAKE2b and BLAKE2s to provide helper functions that make implementing other "shash" providers for these algorithms much easier.

See the individual commits for full details, including benchmarks.

This patchset was tested on a Raspberry Pi 2 (which uses a Cortex-A7 processor) with CONFIG_CRYPTO_MANAGER_EXTRA_TESTS=y, plus other tests.

This patchset applies to mainline commit 0c6c887835b5.

Changed since v1:
- Added BLAKE2s implementation.
- Adjusted the BLAKE2b helper functions to be consistent with what I decided to do for BLAKE2s.
- Fixed build error in blake2b-neon-core.S in some configurations.

Quoted 13 lines

Eric Biggers (11):
crypto: blake2b - rename constants for consistency with blake2s
crypto: blake2b - define shash_alg structs using macros
crypto: blake2b - export helpers for optimized implementations
crypto: blake2b - update file comment
crypto: arm/blake2b - add NEON-accelerated BLAKE2b
crypto: blake2s - define shash_alg structs using macros
crypto: x86/blake2s - define shash_alg structs using macros
crypto: blake2s - remove unneeded includes
crypto: blake2s - share the "shash" API boilerplate code
crypto: arm/blake2s - add ARM scalar optimized BLAKE2s
wireguard: Kconfig: select CRYPTO_BLAKE2S_ARM

Very nice!

For the series,

Quoted 30 lines
 arch/arm/crypto/Kconfig             |  20 ++
 arch/arm/crypto/Makefile            |   4 +
 arch/arm/crypto/blake2b-neon-core.S | 345 ++++++++++++++++++++++++++++
 arch/arm/crypto/blake2b-neon-glue.c | 105 +++++++++
 arch/arm/crypto/blake2s-core.S      | 272 ++++++++++++++++++++++
 arch/arm/crypto/blake2s-glue.c      |  78 +++++++
 arch/x86/crypto/blake2s-glue.c      | 150 +++---------
 crypto/Kconfig                      |   5 +
 crypto/Makefile                     |   1 +
 crypto/blake2b_generic.c            | 200 +++++++---------
 crypto/blake2s_generic.c            | 161 +++----------
 crypto/blake2s_helpers.c            |  87 +++++++
 drivers/net/Kconfig                 |   1 +
 include/crypto/blake2b.h            |  27 +++
 include/crypto/internal/blake2b.h   |  33 +++
 include/crypto/internal/blake2s.h   |  17 ++
 16 files changed, 1139 insertions(+), 367 deletions(-)
 create mode 100644 arch/arm/crypto/blake2b-neon-core.S
 create mode 100644 arch/arm/crypto/blake2b-neon-glue.c
 create mode 100644 arch/arm/crypto/blake2s-core.S
 create mode 100644 arch/arm/crypto/blake2s-glue.c
 create mode 100644 crypto/blake2s_helpers.c
 create mode 100644 include/crypto/blake2b.h
 create mode 100644 include/crypto/internal/blake2b.h

base-commit: 0c6c887835b59c10602add88057c9c06f265effe --
2.29.2