All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gilad Ben-Yossef <gilad@benyossef.com>
To: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>,
	"David S. Miller" <davem@davemloft.net>,
	Vitaly Chikunov <vt@altlinux.org>,
	Eric Biggers <ebiggers@google.com>,
	Eric Biggers <ebiggers@kernel.org>,
	Ard Biesheuvel <ardb@kernel.org>,
	Jussi Kivilinna <jussi.kivilinna@iki.fi>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	"H. Peter Anvin" <hpa@zytor.com>,
	Linux Crypto Mailing List <linux-crypto@vger.kernel.org>,
	x86@kernel.org, Linux ARM <linux-arm-kernel@lists.infradead.org>,
	Linux kernel mailing list <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v2 1/6] crypto: sm3 - create SM3 stand-alone library
Date: Wed, 22 Dec 2021 08:59:11 +0200	[thread overview]
Message-ID: <CAOtvUMehn2_HW+b0etPKAV+H=V=PoENkO1xAdL78dCuHma4m_A@mail.gmail.com> (raw)
In-Reply-To: <20211222045022.27069-2-tianjia.zhang@linux.alibaba.com>

On Wed, Dec 22, 2021 at 6:50 AM Tianjia Zhang
<tianjia.zhang@linux.alibaba.com> wrote:
>
> Stand-alone implementation of the SM3 algorithm. It is designed
> to have as little dependencies as possible. In other cases you
> should generally use the hash APIs from include/crypto/hash.h.
> Especially when hashing large amounts of data as those APIs may
> be hw-accelerated. In the new SM3 stand-alone library,
> sm3_compress() has also been optimized, instead of simply using
> the code in sm3_generic.
>

I have a really minor nitpick: the commit message talks about changes
to sm3_compress() which was there in the original code but there is no
such function in the current code which is in a different patch and
file, so if you do another iteration for other reason, perhaps change
the commit message to refer to sm3_transform() instead? it's not
really important enough to warrant a new iteration on it's own...

Otherwise, I'm not smart enough to evaluate the changes to
sm3_transform() cryptographically  but the overall approach of moving
to a standalone library seems sane to me.

So, for what it's worth -

Reviewed-by: Gilad Ben-Yossef <gilad@benyosef.com>

Gilad


> Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
> ---
>  include/crypto/sm3.h |  31 ++++++
>  lib/crypto/Kconfig   |   3 +
>  lib/crypto/Makefile  |   3 +
>  lib/crypto/sm3.c     | 246 +++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 283 insertions(+)
>  create mode 100644 lib/crypto/sm3.c
>
> diff --git a/include/crypto/sm3.h b/include/crypto/sm3.h
> index 42ea21289ba9..315adaf38007 100644
> --- a/include/crypto/sm3.h
> +++ b/include/crypto/sm3.h
> @@ -1,5 +1,9 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
>  /*
>   * Common values for SM3 algorithm
> + *
> + * Copyright (C) 2017 ARM Limited or its affiliates.
> + * Copyright (C) 2021 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
>   */
>
>  #ifndef _CRYPTO_SM3_H
> @@ -39,4 +43,31 @@ extern int crypto_sm3_final(struct shash_desc *desc, u8 *out);
>
>  extern int crypto_sm3_finup(struct shash_desc *desc, const u8 *data,
>                              unsigned int len, u8 *hash);
> +
> +/*
> + * Stand-alone implementation of the SM3 algorithm. It is designed to
> + * have as little dependencies as possible so it can be used in the
> + * kexec_file purgatory. In other cases you should generally use the
> + * hash APIs from include/crypto/hash.h. Especially when hashing large
> + * amounts of data as those APIs may be hw-accelerated.
> + *
> + * For details see lib/crypto/sm3.c
> + */
> +
> +static inline void sm3_init(struct sm3_state *sctx)
> +{
> +       sctx->state[0] = SM3_IVA;
> +       sctx->state[1] = SM3_IVB;
> +       sctx->state[2] = SM3_IVC;
> +       sctx->state[3] = SM3_IVD;
> +       sctx->state[4] = SM3_IVE;
> +       sctx->state[5] = SM3_IVF;
> +       sctx->state[6] = SM3_IVG;
> +       sctx->state[7] = SM3_IVH;
> +       sctx->count = 0;
> +}
> +
> +void sm3_update(struct sm3_state *sctx, const u8 *data, unsigned int len);
> +void sm3_final(struct sm3_state *sctx, u8 *out);
> +
>  #endif
> diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig
> index 545ccbddf6a1..36963e8f4eaa 100644
> --- a/lib/crypto/Kconfig
> +++ b/lib/crypto/Kconfig
> @@ -129,5 +129,8 @@ config CRYPTO_LIB_CHACHA20POLY1305
>  config CRYPTO_LIB_SHA256
>         tristate
>
> +config CRYPTO_LIB_SM3
> +       tristate
> +
>  config CRYPTO_LIB_SM4
>         tristate
> diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile
> index 73205ed269ba..8149bc00b627 100644
> --- a/lib/crypto/Makefile
> +++ b/lib/crypto/Makefile
> @@ -38,6 +38,9 @@ libpoly1305-y                                 += poly1305.o
>  obj-$(CONFIG_CRYPTO_LIB_SHA256)                        += libsha256.o
>  libsha256-y                                    := sha256.o
>
> +obj-$(CONFIG_CRYPTO_LIB_SM3)                   += libsm3.o
> +libsm3-y                                       := sm3.o
> +
>  obj-$(CONFIG_CRYPTO_LIB_SM4)                   += libsm4.o
>  libsm4-y                                       := sm4.o
>
> diff --git a/lib/crypto/sm3.c b/lib/crypto/sm3.c
> new file mode 100644
> index 000000000000..d473e358a873
> --- /dev/null
> +++ b/lib/crypto/sm3.c
> @@ -0,0 +1,246 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * SM3 secure hash, as specified by OSCCA GM/T 0004-2012 SM3 and described
> + * at https://datatracker.ietf.org/doc/html/draft-sca-cfrg-sm3-02
> + *
> + * Copyright (C) 2017 ARM Limited or its affiliates.
> + * Copyright (C) 2017 Gilad Ben-Yossef <gilad@benyossef.com>
> + * Copyright (C) 2021 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
> + */
> +
> +#include <linux/module.h>
> +#include <asm/unaligned.h>
> +#include <crypto/sm3.h>
> +
> +static const u32 ____cacheline_aligned K[64] = {
> +       0x79cc4519, 0xf3988a32, 0xe7311465, 0xce6228cb,
> +       0x9cc45197, 0x3988a32f, 0x7311465e, 0xe6228cbc,
> +       0xcc451979, 0x988a32f3, 0x311465e7, 0x6228cbce,
> +       0xc451979c, 0x88a32f39, 0x11465e73, 0x228cbce6,
> +       0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c,
> +       0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce,
> +       0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec,
> +       0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5,
> +       0x7a879d8a, 0xf50f3b14, 0xea1e7629, 0xd43cec53,
> +       0xa879d8a7, 0x50f3b14f, 0xa1e7629e, 0x43cec53d,
> +       0x879d8a7a, 0x0f3b14f5, 0x1e7629ea, 0x3cec53d4,
> +       0x79d8a7a8, 0xf3b14f50, 0xe7629ea1, 0xcec53d43,
> +       0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c,
> +       0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce,
> +       0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec,
> +       0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5
> +};
> +
> +/*
> + * Transform the message X which consists of 16 32-bit-words. See
> + * GM/T 004-2012 for details.
> + */
> +#define R(i, a, b, c, d, e, f, g, h, t, w1, w2)                        \
> +       do {                                                    \
> +               ss1 = rol32((rol32((a), 12) + (e) + (t)), 7);   \
> +               ss2 = ss1 ^ rol32((a), 12);                     \
> +               d += FF ## i(a, b, c) + ss2 + ((w1) ^ (w2));    \
> +               h += GG ## i(e, f, g) + ss1 + (w1);             \
> +               b = rol32((b), 9);                              \
> +               f = rol32((f), 19);                             \
> +               h = P0((h));                                    \
> +       } while (0)
> +
> +#define R1(a, b, c, d, e, f, g, h, t, w1, w2) \
> +       R(1, a, b, c, d, e, f, g, h, t, w1, w2)
> +#define R2(a, b, c, d, e, f, g, h, t, w1, w2) \
> +       R(2, a, b, c, d, e, f, g, h, t, w1, w2)
> +
> +#define FF1(x, y, z)  (x ^ y ^ z)
> +#define FF2(x, y, z)  ((x & y) | (x & z) | (y & z))
> +
> +#define GG1(x, y, z)  FF1(x, y, z)
> +#define GG2(x, y, z)  ((x & y) | (~x & z))
> +
> +/* Message expansion */
> +#define P0(x) ((x) ^ rol32((x), 9) ^ rol32((x), 17))
> +#define P1(x) ((x) ^ rol32((x), 15) ^ rol32((x), 23))
> +#define I(i)  (W[i] = get_unaligned_be32(data + i * 4))
> +#define W1(i) (W[i & 0x0f])
> +#define W2(i) (W[i & 0x0f] =                           \
> +               P1(W[i & 0x0f]                          \
> +                       ^ W[(i-9) & 0x0f]               \
> +                       ^ rol32(W[(i-3) & 0x0f], 15))   \
> +               ^ rol32(W[(i-13) & 0x0f], 7)            \
> +               ^ W[(i-6) & 0x0f])
> +
> +static void sm3_transform(struct sm3_state *sctx, u8 const *data, u32 W[16])
> +{
> +       u32 a, b, c, d, e, f, g, h, ss1, ss2;
> +
> +       a = sctx->state[0];
> +       b = sctx->state[1];
> +       c = sctx->state[2];
> +       d = sctx->state[3];
> +       e = sctx->state[4];
> +       f = sctx->state[5];
> +       g = sctx->state[6];
> +       h = sctx->state[7];
> +
> +       R1(a, b, c, d, e, f, g, h, K[0], I(0), I(4));
> +       R1(d, a, b, c, h, e, f, g, K[1], I(1), I(5));
> +       R1(c, d, a, b, g, h, e, f, K[2], I(2), I(6));
> +       R1(b, c, d, a, f, g, h, e, K[3], I(3), I(7));
> +       R1(a, b, c, d, e, f, g, h, K[4], W1(4), I(8));
> +       R1(d, a, b, c, h, e, f, g, K[5], W1(5), I(9));
> +       R1(c, d, a, b, g, h, e, f, K[6], W1(6), I(10));
> +       R1(b, c, d, a, f, g, h, e, K[7], W1(7), I(11));
> +       R1(a, b, c, d, e, f, g, h, K[8], W1(8), I(12));
> +       R1(d, a, b, c, h, e, f, g, K[9], W1(9), I(13));
> +       R1(c, d, a, b, g, h, e, f, K[10], W1(10), I(14));
> +       R1(b, c, d, a, f, g, h, e, K[11], W1(11), I(15));
> +       R1(a, b, c, d, e, f, g, h, K[12], W1(12), W2(16));
> +       R1(d, a, b, c, h, e, f, g, K[13], W1(13), W2(17));
> +       R1(c, d, a, b, g, h, e, f, K[14], W1(14), W2(18));
> +       R1(b, c, d, a, f, g, h, e, K[15], W1(15), W2(19));
> +
> +       R2(a, b, c, d, e, f, g, h, K[16], W1(16), W2(20));
> +       R2(d, a, b, c, h, e, f, g, K[17], W1(17), W2(21));
> +       R2(c, d, a, b, g, h, e, f, K[18], W1(18), W2(22));
> +       R2(b, c, d, a, f, g, h, e, K[19], W1(19), W2(23));
> +       R2(a, b, c, d, e, f, g, h, K[20], W1(20), W2(24));
> +       R2(d, a, b, c, h, e, f, g, K[21], W1(21), W2(25));
> +       R2(c, d, a, b, g, h, e, f, K[22], W1(22), W2(26));
> +       R2(b, c, d, a, f, g, h, e, K[23], W1(23), W2(27));
> +       R2(a, b, c, d, e, f, g, h, K[24], W1(24), W2(28));
> +       R2(d, a, b, c, h, e, f, g, K[25], W1(25), W2(29));
> +       R2(c, d, a, b, g, h, e, f, K[26], W1(26), W2(30));
> +       R2(b, c, d, a, f, g, h, e, K[27], W1(27), W2(31));
> +       R2(a, b, c, d, e, f, g, h, K[28], W1(28), W2(32));
> +       R2(d, a, b, c, h, e, f, g, K[29], W1(29), W2(33));
> +       R2(c, d, a, b, g, h, e, f, K[30], W1(30), W2(34));
> +       R2(b, c, d, a, f, g, h, e, K[31], W1(31), W2(35));
> +
> +       R2(a, b, c, d, e, f, g, h, K[32], W1(32), W2(36));
> +       R2(d, a, b, c, h, e, f, g, K[33], W1(33), W2(37));
> +       R2(c, d, a, b, g, h, e, f, K[34], W1(34), W2(38));
> +       R2(b, c, d, a, f, g, h, e, K[35], W1(35), W2(39));
> +       R2(a, b, c, d, e, f, g, h, K[36], W1(36), W2(40));
> +       R2(d, a, b, c, h, e, f, g, K[37], W1(37), W2(41));
> +       R2(c, d, a, b, g, h, e, f, K[38], W1(38), W2(42));
> +       R2(b, c, d, a, f, g, h, e, K[39], W1(39), W2(43));
> +       R2(a, b, c, d, e, f, g, h, K[40], W1(40), W2(44));
> +       R2(d, a, b, c, h, e, f, g, K[41], W1(41), W2(45));
> +       R2(c, d, a, b, g, h, e, f, K[42], W1(42), W2(46));
> +       R2(b, c, d, a, f, g, h, e, K[43], W1(43), W2(47));
> +       R2(a, b, c, d, e, f, g, h, K[44], W1(44), W2(48));
> +       R2(d, a, b, c, h, e, f, g, K[45], W1(45), W2(49));
> +       R2(c, d, a, b, g, h, e, f, K[46], W1(46), W2(50));
> +       R2(b, c, d, a, f, g, h, e, K[47], W1(47), W2(51));
> +
> +       R2(a, b, c, d, e, f, g, h, K[48], W1(48), W2(52));
> +       R2(d, a, b, c, h, e, f, g, K[49], W1(49), W2(53));
> +       R2(c, d, a, b, g, h, e, f, K[50], W1(50), W2(54));
> +       R2(b, c, d, a, f, g, h, e, K[51], W1(51), W2(55));
> +       R2(a, b, c, d, e, f, g, h, K[52], W1(52), W2(56));
> +       R2(d, a, b, c, h, e, f, g, K[53], W1(53), W2(57));
> +       R2(c, d, a, b, g, h, e, f, K[54], W1(54), W2(58));
> +       R2(b, c, d, a, f, g, h, e, K[55], W1(55), W2(59));
> +       R2(a, b, c, d, e, f, g, h, K[56], W1(56), W2(60));
> +       R2(d, a, b, c, h, e, f, g, K[57], W1(57), W2(61));
> +       R2(c, d, a, b, g, h, e, f, K[58], W1(58), W2(62));
> +       R2(b, c, d, a, f, g, h, e, K[59], W1(59), W2(63));
> +       R2(a, b, c, d, e, f, g, h, K[60], W1(60), W2(64));
> +       R2(d, a, b, c, h, e, f, g, K[61], W1(61), W2(65));
> +       R2(c, d, a, b, g, h, e, f, K[62], W1(62), W2(66));
> +       R2(b, c, d, a, f, g, h, e, K[63], W1(63), W2(67));
> +
> +       sctx->state[0] ^= a;
> +       sctx->state[1] ^= b;
> +       sctx->state[2] ^= c;
> +       sctx->state[3] ^= d;
> +       sctx->state[4] ^= e;
> +       sctx->state[5] ^= f;
> +       sctx->state[6] ^= g;
> +       sctx->state[7] ^= h;
> +}
> +#undef R
> +#undef R1
> +#undef R2
> +#undef I
> +#undef W1
> +#undef W2
> +
> +static inline void sm3_block(struct sm3_state *sctx,
> +               u8 const *data, int blocks, u32 W[16])
> +{
> +       while (blocks--) {
> +               sm3_transform(sctx, data, W);
> +               data += SM3_BLOCK_SIZE;
> +       }
> +}
> +
> +void sm3_update(struct sm3_state *sctx, const u8 *data, unsigned int len)
> +{
> +       unsigned int partial = sctx->count % SM3_BLOCK_SIZE;
> +       u32 W[16];
> +
> +       sctx->count += len;
> +
> +       if ((partial + len) >= SM3_BLOCK_SIZE) {
> +               int blocks;
> +
> +               if (partial) {
> +                       int p = SM3_BLOCK_SIZE - partial;
> +
> +                       memcpy(sctx->buffer + partial, data, p);
> +                       data += p;
> +                       len -= p;
> +
> +                       sm3_block(sctx, sctx->buffer, 1, W);
> +               }
> +
> +               blocks = len / SM3_BLOCK_SIZE;
> +               len %= SM3_BLOCK_SIZE;
> +
> +               if (blocks) {
> +                       sm3_block(sctx, data, blocks, W);
> +                       data += blocks * SM3_BLOCK_SIZE;
> +               }
> +
> +               memzero_explicit(W, sizeof(W));
> +
> +               partial = 0;
> +       }
> +       if (len)
> +               memcpy(sctx->buffer + partial, data, len);
> +}
> +EXPORT_SYMBOL_GPL(sm3_update);
> +
> +void sm3_final(struct sm3_state *sctx, u8 *out)
> +{
> +       const int bit_offset = SM3_BLOCK_SIZE - sizeof(u64);
> +       __be64 *bits = (__be64 *)(sctx->buffer + bit_offset);
> +       __be32 *digest = (__be32 *)out;
> +       unsigned int partial = sctx->count % SM3_BLOCK_SIZE;
> +       u32 W[16];
> +       int i;
> +
> +       sctx->buffer[partial++] = 0x80;
> +       if (partial > bit_offset) {
> +               memset(sctx->buffer + partial, 0, SM3_BLOCK_SIZE - partial);
> +               partial = 0;
> +
> +               sm3_block(sctx, sctx->buffer, 1, W);
> +       }
> +
> +       memset(sctx->buffer + partial, 0, bit_offset - partial);
> +       *bits = cpu_to_be64(sctx->count << 3);
> +       sm3_block(sctx, sctx->buffer, 1, W);
> +
> +       for (i = 0; i < 8; i++)
> +               put_unaligned_be32(sctx->state[i], digest++);
> +
> +       /* Zeroize sensitive information. */
> +       memzero_explicit(W, sizeof(W));
> +       memzero_explicit(sctx, sizeof(*sctx));
> +}
> +EXPORT_SYMBOL_GPL(sm3_final);
> +
> +MODULE_DESCRIPTION("Generic SM3 library");
> +MODULE_LICENSE("GPL v2");
> --
> 2.32.0
>


-- 
Gilad Ben-Yossef
Chief Coffee Drinker

values of β will give rise to dom!

WARNING: multiple messages have this Message-ID (diff)
From: Gilad Ben-Yossef <gilad@benyossef.com>
To: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>,
	"David S. Miller" <davem@davemloft.net>,
	 Vitaly Chikunov <vt@altlinux.org>,
	Eric Biggers <ebiggers@google.com>,
	 Eric Biggers <ebiggers@kernel.org>,
	Ard Biesheuvel <ardb@kernel.org>,
	 Jussi Kivilinna <jussi.kivilinna@iki.fi>,
	Catalin Marinas <catalin.marinas@arm.com>,
	 Will Deacon <will@kernel.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>,  Borislav Petkov <bp@alien8.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	 "H. Peter Anvin" <hpa@zytor.com>,
	Linux Crypto Mailing List <linux-crypto@vger.kernel.org>,
	x86@kernel.org,  Linux ARM <linux-arm-kernel@lists.infradead.org>,
	 Linux kernel mailing list <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v2 1/6] crypto: sm3 - create SM3 stand-alone library
Date: Wed, 22 Dec 2021 08:59:11 +0200	[thread overview]
Message-ID: <CAOtvUMehn2_HW+b0etPKAV+H=V=PoENkO1xAdL78dCuHma4m_A@mail.gmail.com> (raw)
In-Reply-To: <20211222045022.27069-2-tianjia.zhang@linux.alibaba.com>

On Wed, Dec 22, 2021 at 6:50 AM Tianjia Zhang
<tianjia.zhang@linux.alibaba.com> wrote:
>
> Stand-alone implementation of the SM3 algorithm. It is designed
> to have as little dependencies as possible. In other cases you
> should generally use the hash APIs from include/crypto/hash.h.
> Especially when hashing large amounts of data as those APIs may
> be hw-accelerated. In the new SM3 stand-alone library,
> sm3_compress() has also been optimized, instead of simply using
> the code in sm3_generic.
>

I have a really minor nitpick: the commit message talks about changes
to sm3_compress() which was there in the original code but there is no
such function in the current code which is in a different patch and
file, so if you do another iteration for other reason, perhaps change
the commit message to refer to sm3_transform() instead? it's not
really important enough to warrant a new iteration on it's own...

Otherwise, I'm not smart enough to evaluate the changes to
sm3_transform() cryptographically  but the overall approach of moving
to a standalone library seems sane to me.

So, for what it's worth -

Reviewed-by: Gilad Ben-Yossef <gilad@benyosef.com>

Gilad


> Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
> ---
>  include/crypto/sm3.h |  31 ++++++
>  lib/crypto/Kconfig   |   3 +
>  lib/crypto/Makefile  |   3 +
>  lib/crypto/sm3.c     | 246 +++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 283 insertions(+)
>  create mode 100644 lib/crypto/sm3.c
>
> diff --git a/include/crypto/sm3.h b/include/crypto/sm3.h
> index 42ea21289ba9..315adaf38007 100644
> --- a/include/crypto/sm3.h
> +++ b/include/crypto/sm3.h
> @@ -1,5 +1,9 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
>  /*
>   * Common values for SM3 algorithm
> + *
> + * Copyright (C) 2017 ARM Limited or its affiliates.
> + * Copyright (C) 2021 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
>   */
>
>  #ifndef _CRYPTO_SM3_H
> @@ -39,4 +43,31 @@ extern int crypto_sm3_final(struct shash_desc *desc, u8 *out);
>
>  extern int crypto_sm3_finup(struct shash_desc *desc, const u8 *data,
>                              unsigned int len, u8 *hash);
> +
> +/*
> + * Stand-alone implementation of the SM3 algorithm. It is designed to
> + * have as little dependencies as possible so it can be used in the
> + * kexec_file purgatory. In other cases you should generally use the
> + * hash APIs from include/crypto/hash.h. Especially when hashing large
> + * amounts of data as those APIs may be hw-accelerated.
> + *
> + * For details see lib/crypto/sm3.c
> + */
> +
> +static inline void sm3_init(struct sm3_state *sctx)
> +{
> +       sctx->state[0] = SM3_IVA;
> +       sctx->state[1] = SM3_IVB;
> +       sctx->state[2] = SM3_IVC;
> +       sctx->state[3] = SM3_IVD;
> +       sctx->state[4] = SM3_IVE;
> +       sctx->state[5] = SM3_IVF;
> +       sctx->state[6] = SM3_IVG;
> +       sctx->state[7] = SM3_IVH;
> +       sctx->count = 0;
> +}
> +
> +void sm3_update(struct sm3_state *sctx, const u8 *data, unsigned int len);
> +void sm3_final(struct sm3_state *sctx, u8 *out);
> +
>  #endif
> diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig
> index 545ccbddf6a1..36963e8f4eaa 100644
> --- a/lib/crypto/Kconfig
> +++ b/lib/crypto/Kconfig
> @@ -129,5 +129,8 @@ config CRYPTO_LIB_CHACHA20POLY1305
>  config CRYPTO_LIB_SHA256
>         tristate
>
> +config CRYPTO_LIB_SM3
> +       tristate
> +
>  config CRYPTO_LIB_SM4
>         tristate
> diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile
> index 73205ed269ba..8149bc00b627 100644
> --- a/lib/crypto/Makefile
> +++ b/lib/crypto/Makefile
> @@ -38,6 +38,9 @@ libpoly1305-y                                 += poly1305.o
>  obj-$(CONFIG_CRYPTO_LIB_SHA256)                        += libsha256.o
>  libsha256-y                                    := sha256.o
>
> +obj-$(CONFIG_CRYPTO_LIB_SM3)                   += libsm3.o
> +libsm3-y                                       := sm3.o
> +
>  obj-$(CONFIG_CRYPTO_LIB_SM4)                   += libsm4.o
>  libsm4-y                                       := sm4.o
>
> diff --git a/lib/crypto/sm3.c b/lib/crypto/sm3.c
> new file mode 100644
> index 000000000000..d473e358a873
> --- /dev/null
> +++ b/lib/crypto/sm3.c
> @@ -0,0 +1,246 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * SM3 secure hash, as specified by OSCCA GM/T 0004-2012 SM3 and described
> + * at https://datatracker.ietf.org/doc/html/draft-sca-cfrg-sm3-02
> + *
> + * Copyright (C) 2017 ARM Limited or its affiliates.
> + * Copyright (C) 2017 Gilad Ben-Yossef <gilad@benyossef.com>
> + * Copyright (C) 2021 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
> + */
> +
> +#include <linux/module.h>
> +#include <asm/unaligned.h>
> +#include <crypto/sm3.h>
> +
> +static const u32 ____cacheline_aligned K[64] = {
> +       0x79cc4519, 0xf3988a32, 0xe7311465, 0xce6228cb,
> +       0x9cc45197, 0x3988a32f, 0x7311465e, 0xe6228cbc,
> +       0xcc451979, 0x988a32f3, 0x311465e7, 0x6228cbce,
> +       0xc451979c, 0x88a32f39, 0x11465e73, 0x228cbce6,
> +       0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c,
> +       0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce,
> +       0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec,
> +       0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5,
> +       0x7a879d8a, 0xf50f3b14, 0xea1e7629, 0xd43cec53,
> +       0xa879d8a7, 0x50f3b14f, 0xa1e7629e, 0x43cec53d,
> +       0x879d8a7a, 0x0f3b14f5, 0x1e7629ea, 0x3cec53d4,
> +       0x79d8a7a8, 0xf3b14f50, 0xe7629ea1, 0xcec53d43,
> +       0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c,
> +       0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce,
> +       0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec,
> +       0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5
> +};
> +
> +/*
> + * Transform the message X which consists of 16 32-bit-words. See
> + * GM/T 004-2012 for details.
> + */
> +#define R(i, a, b, c, d, e, f, g, h, t, w1, w2)                        \
> +       do {                                                    \
> +               ss1 = rol32((rol32((a), 12) + (e) + (t)), 7);   \
> +               ss2 = ss1 ^ rol32((a), 12);                     \
> +               d += FF ## i(a, b, c) + ss2 + ((w1) ^ (w2));    \
> +               h += GG ## i(e, f, g) + ss1 + (w1);             \
> +               b = rol32((b), 9);                              \
> +               f = rol32((f), 19);                             \
> +               h = P0((h));                                    \
> +       } while (0)
> +
> +#define R1(a, b, c, d, e, f, g, h, t, w1, w2) \
> +       R(1, a, b, c, d, e, f, g, h, t, w1, w2)
> +#define R2(a, b, c, d, e, f, g, h, t, w1, w2) \
> +       R(2, a, b, c, d, e, f, g, h, t, w1, w2)
> +
> +#define FF1(x, y, z)  (x ^ y ^ z)
> +#define FF2(x, y, z)  ((x & y) | (x & z) | (y & z))
> +
> +#define GG1(x, y, z)  FF1(x, y, z)
> +#define GG2(x, y, z)  ((x & y) | (~x & z))
> +
> +/* Message expansion */
> +#define P0(x) ((x) ^ rol32((x), 9) ^ rol32((x), 17))
> +#define P1(x) ((x) ^ rol32((x), 15) ^ rol32((x), 23))
> +#define I(i)  (W[i] = get_unaligned_be32(data + i * 4))
> +#define W1(i) (W[i & 0x0f])
> +#define W2(i) (W[i & 0x0f] =                           \
> +               P1(W[i & 0x0f]                          \
> +                       ^ W[(i-9) & 0x0f]               \
> +                       ^ rol32(W[(i-3) & 0x0f], 15))   \
> +               ^ rol32(W[(i-13) & 0x0f], 7)            \
> +               ^ W[(i-6) & 0x0f])
> +
> +static void sm3_transform(struct sm3_state *sctx, u8 const *data, u32 W[16])
> +{
> +       u32 a, b, c, d, e, f, g, h, ss1, ss2;
> +
> +       a = sctx->state[0];
> +       b = sctx->state[1];
> +       c = sctx->state[2];
> +       d = sctx->state[3];
> +       e = sctx->state[4];
> +       f = sctx->state[5];
> +       g = sctx->state[6];
> +       h = sctx->state[7];
> +
> +       R1(a, b, c, d, e, f, g, h, K[0], I(0), I(4));
> +       R1(d, a, b, c, h, e, f, g, K[1], I(1), I(5));
> +       R1(c, d, a, b, g, h, e, f, K[2], I(2), I(6));
> +       R1(b, c, d, a, f, g, h, e, K[3], I(3), I(7));
> +       R1(a, b, c, d, e, f, g, h, K[4], W1(4), I(8));
> +       R1(d, a, b, c, h, e, f, g, K[5], W1(5), I(9));
> +       R1(c, d, a, b, g, h, e, f, K[6], W1(6), I(10));
> +       R1(b, c, d, a, f, g, h, e, K[7], W1(7), I(11));
> +       R1(a, b, c, d, e, f, g, h, K[8], W1(8), I(12));
> +       R1(d, a, b, c, h, e, f, g, K[9], W1(9), I(13));
> +       R1(c, d, a, b, g, h, e, f, K[10], W1(10), I(14));
> +       R1(b, c, d, a, f, g, h, e, K[11], W1(11), I(15));
> +       R1(a, b, c, d, e, f, g, h, K[12], W1(12), W2(16));
> +       R1(d, a, b, c, h, e, f, g, K[13], W1(13), W2(17));
> +       R1(c, d, a, b, g, h, e, f, K[14], W1(14), W2(18));
> +       R1(b, c, d, a, f, g, h, e, K[15], W1(15), W2(19));
> +
> +       R2(a, b, c, d, e, f, g, h, K[16], W1(16), W2(20));
> +       R2(d, a, b, c, h, e, f, g, K[17], W1(17), W2(21));
> +       R2(c, d, a, b, g, h, e, f, K[18], W1(18), W2(22));
> +       R2(b, c, d, a, f, g, h, e, K[19], W1(19), W2(23));
> +       R2(a, b, c, d, e, f, g, h, K[20], W1(20), W2(24));
> +       R2(d, a, b, c, h, e, f, g, K[21], W1(21), W2(25));
> +       R2(c, d, a, b, g, h, e, f, K[22], W1(22), W2(26));
> +       R2(b, c, d, a, f, g, h, e, K[23], W1(23), W2(27));
> +       R2(a, b, c, d, e, f, g, h, K[24], W1(24), W2(28));
> +       R2(d, a, b, c, h, e, f, g, K[25], W1(25), W2(29));
> +       R2(c, d, a, b, g, h, e, f, K[26], W1(26), W2(30));
> +       R2(b, c, d, a, f, g, h, e, K[27], W1(27), W2(31));
> +       R2(a, b, c, d, e, f, g, h, K[28], W1(28), W2(32));
> +       R2(d, a, b, c, h, e, f, g, K[29], W1(29), W2(33));
> +       R2(c, d, a, b, g, h, e, f, K[30], W1(30), W2(34));
> +       R2(b, c, d, a, f, g, h, e, K[31], W1(31), W2(35));
> +
> +       R2(a, b, c, d, e, f, g, h, K[32], W1(32), W2(36));
> +       R2(d, a, b, c, h, e, f, g, K[33], W1(33), W2(37));
> +       R2(c, d, a, b, g, h, e, f, K[34], W1(34), W2(38));
> +       R2(b, c, d, a, f, g, h, e, K[35], W1(35), W2(39));
> +       R2(a, b, c, d, e, f, g, h, K[36], W1(36), W2(40));
> +       R2(d, a, b, c, h, e, f, g, K[37], W1(37), W2(41));
> +       R2(c, d, a, b, g, h, e, f, K[38], W1(38), W2(42));
> +       R2(b, c, d, a, f, g, h, e, K[39], W1(39), W2(43));
> +       R2(a, b, c, d, e, f, g, h, K[40], W1(40), W2(44));
> +       R2(d, a, b, c, h, e, f, g, K[41], W1(41), W2(45));
> +       R2(c, d, a, b, g, h, e, f, K[42], W1(42), W2(46));
> +       R2(b, c, d, a, f, g, h, e, K[43], W1(43), W2(47));
> +       R2(a, b, c, d, e, f, g, h, K[44], W1(44), W2(48));
> +       R2(d, a, b, c, h, e, f, g, K[45], W1(45), W2(49));
> +       R2(c, d, a, b, g, h, e, f, K[46], W1(46), W2(50));
> +       R2(b, c, d, a, f, g, h, e, K[47], W1(47), W2(51));
> +
> +       R2(a, b, c, d, e, f, g, h, K[48], W1(48), W2(52));
> +       R2(d, a, b, c, h, e, f, g, K[49], W1(49), W2(53));
> +       R2(c, d, a, b, g, h, e, f, K[50], W1(50), W2(54));
> +       R2(b, c, d, a, f, g, h, e, K[51], W1(51), W2(55));
> +       R2(a, b, c, d, e, f, g, h, K[52], W1(52), W2(56));
> +       R2(d, a, b, c, h, e, f, g, K[53], W1(53), W2(57));
> +       R2(c, d, a, b, g, h, e, f, K[54], W1(54), W2(58));
> +       R2(b, c, d, a, f, g, h, e, K[55], W1(55), W2(59));
> +       R2(a, b, c, d, e, f, g, h, K[56], W1(56), W2(60));
> +       R2(d, a, b, c, h, e, f, g, K[57], W1(57), W2(61));
> +       R2(c, d, a, b, g, h, e, f, K[58], W1(58), W2(62));
> +       R2(b, c, d, a, f, g, h, e, K[59], W1(59), W2(63));
> +       R2(a, b, c, d, e, f, g, h, K[60], W1(60), W2(64));
> +       R2(d, a, b, c, h, e, f, g, K[61], W1(61), W2(65));
> +       R2(c, d, a, b, g, h, e, f, K[62], W1(62), W2(66));
> +       R2(b, c, d, a, f, g, h, e, K[63], W1(63), W2(67));
> +
> +       sctx->state[0] ^= a;
> +       sctx->state[1] ^= b;
> +       sctx->state[2] ^= c;
> +       sctx->state[3] ^= d;
> +       sctx->state[4] ^= e;
> +       sctx->state[5] ^= f;
> +       sctx->state[6] ^= g;
> +       sctx->state[7] ^= h;
> +}
> +#undef R
> +#undef R1
> +#undef R2
> +#undef I
> +#undef W1
> +#undef W2
> +
> +static inline void sm3_block(struct sm3_state *sctx,
> +               u8 const *data, int blocks, u32 W[16])
> +{
> +       while (blocks--) {
> +               sm3_transform(sctx, data, W);
> +               data += SM3_BLOCK_SIZE;
> +       }
> +}
> +
> +void sm3_update(struct sm3_state *sctx, const u8 *data, unsigned int len)
> +{
> +       unsigned int partial = sctx->count % SM3_BLOCK_SIZE;
> +       u32 W[16];
> +
> +       sctx->count += len;
> +
> +       if ((partial + len) >= SM3_BLOCK_SIZE) {
> +               int blocks;
> +
> +               if (partial) {
> +                       int p = SM3_BLOCK_SIZE - partial;
> +
> +                       memcpy(sctx->buffer + partial, data, p);
> +                       data += p;
> +                       len -= p;
> +
> +                       sm3_block(sctx, sctx->buffer, 1, W);
> +               }
> +
> +               blocks = len / SM3_BLOCK_SIZE;
> +               len %= SM3_BLOCK_SIZE;
> +
> +               if (blocks) {
> +                       sm3_block(sctx, data, blocks, W);
> +                       data += blocks * SM3_BLOCK_SIZE;
> +               }
> +
> +               memzero_explicit(W, sizeof(W));
> +
> +               partial = 0;
> +       }
> +       if (len)
> +               memcpy(sctx->buffer + partial, data, len);
> +}
> +EXPORT_SYMBOL_GPL(sm3_update);
> +
> +void sm3_final(struct sm3_state *sctx, u8 *out)
> +{
> +       const int bit_offset = SM3_BLOCK_SIZE - sizeof(u64);
> +       __be64 *bits = (__be64 *)(sctx->buffer + bit_offset);
> +       __be32 *digest = (__be32 *)out;
> +       unsigned int partial = sctx->count % SM3_BLOCK_SIZE;
> +       u32 W[16];
> +       int i;
> +
> +       sctx->buffer[partial++] = 0x80;
> +       if (partial > bit_offset) {
> +               memset(sctx->buffer + partial, 0, SM3_BLOCK_SIZE - partial);
> +               partial = 0;
> +
> +               sm3_block(sctx, sctx->buffer, 1, W);
> +       }
> +
> +       memset(sctx->buffer + partial, 0, bit_offset - partial);
> +       *bits = cpu_to_be64(sctx->count << 3);
> +       sm3_block(sctx, sctx->buffer, 1, W);
> +
> +       for (i = 0; i < 8; i++)
> +               put_unaligned_be32(sctx->state[i], digest++);
> +
> +       /* Zeroize sensitive information. */
> +       memzero_explicit(W, sizeof(W));
> +       memzero_explicit(sctx, sizeof(*sctx));
> +}
> +EXPORT_SYMBOL_GPL(sm3_final);
> +
> +MODULE_DESCRIPTION("Generic SM3 library");
> +MODULE_LICENSE("GPL v2");
> --
> 2.32.0
>


-- 
Gilad Ben-Yossef
Chief Coffee Drinker

values of β will give rise to dom!

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2021-12-22  6:59 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-22  4:50 [PATCH v2 0/6] Introduce x86 assembly accelerated implementation for SM3 algorithm Tianjia Zhang
2021-12-22  4:50 ` Tianjia Zhang
2021-12-22  4:50 ` [PATCH v2 1/6] crypto: sm3 - create SM3 stand-alone library Tianjia Zhang
2021-12-22  4:50   ` Tianjia Zhang
2021-12-22  6:59   ` Gilad Ben-Yossef [this message]
2021-12-22  6:59     ` Gilad Ben-Yossef
2021-12-22 13:11     ` Tianjia Zhang
2021-12-22 13:11       ` Tianjia Zhang
2021-12-22  4:50 ` [PATCH v2 2/6] crypto: arm64/sm3-ce - make dependent on sm3 library Tianjia Zhang
2021-12-22  4:50   ` Tianjia Zhang
2021-12-31  7:05   ` liulongfang
2021-12-31  7:05     ` liulongfang
2021-12-31 11:00     ` Tianjia Zhang
2021-12-31 11:00       ` Tianjia Zhang
2021-12-22  4:50 ` [PATCH v2 3/6] crypto: sm2 " Tianjia Zhang
2021-12-22  4:50   ` Tianjia Zhang
2021-12-22  4:50 ` [PATCH v2 4/6] crypto: sm3 " Tianjia Zhang
2021-12-22  4:50   ` Tianjia Zhang
2021-12-22  4:50 ` [PATCH v2 5/6] crypto: x86/sm3 - add AVX assembly implementation Tianjia Zhang
2021-12-22  4:50   ` Tianjia Zhang
2021-12-22  4:50 ` [PATCH v2 6/6] crypto: tcrypt - add asynchronous speed test for SM3 Tianjia Zhang
2021-12-22  4:50   ` Tianjia Zhang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAOtvUMehn2_HW+b0etPKAV+H=V=PoENkO1xAdL78dCuHma4m_A@mail.gmail.com' \
    --to=gilad@benyossef.com \
    --cc=ardb@kernel.org \
    --cc=bp@alien8.de \
    --cc=catalin.marinas@arm.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=davem@davemloft.net \
    --cc=ebiggers@google.com \
    --cc=ebiggers@kernel.org \
    --cc=herbert@gondor.apana.org.au \
    --cc=hpa@zytor.com \
    --cc=jussi.kivilinna@iki.fi \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=tianjia.zhang@linux.alibaba.com \
    --cc=vt@altlinux.org \
    --cc=will@kernel.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.