Add OSCCA SM3 secure hash generic hash algorithm, described in OSCCA GM/T 0004-2012 SM3, the corresponding English specification: http://www.gmbz.org.cn/upload/2018-07-24/1532401392982079739.pdf
Tianjia Zhang (4): Add OSCCA SM3 hash algorithm testsuite: add test for SM3 hash function hmac: add support for SM3 hash function nettle-benchmark: bench SM3 hashes
Makefile.in | 7 +- examples/nettle-benchmark.c | 2 +- hmac-sm3-meta.c | 47 +++++++ hmac-sm3.c | 59 +++++++++ hmac.h | 19 +++ nettle-meta-hashes.c | 1 + nettle-meta-macs.c | 1 + nettle-meta.h | 2 + sm3-meta.c | 42 ++++++ sm3.c | 251 ++++++++++++++++++++++++++++++++++++ sm3.h | 82 ++++++++++++ testsuite/.gitignore | 1 + testsuite/Makefile.in | 2 +- testsuite/hmac-test.c | 6 + testsuite/meta-hash-test.c | 3 +- testsuite/meta-mac-test.c | 1 + testsuite/sm3-test.c | 20 +++ 17 files changed, 540 insertions(+), 6 deletions(-) create mode 100644 hmac-sm3-meta.c create mode 100644 hmac-sm3.c create mode 100644 sm3-meta.c create mode 100644 sm3.c create mode 100644 sm3.h create mode 100644 testsuite/sm3-test.c
Add OSCCA SM3 secure hash (OSCCA GM/T 0004-2012 SM3) generic hash transformation.
Signed-off-by: Tianjia Zhang tianjia.zhang@linux.alibaba.com --- Makefile.in | 3 +- nettle-meta-hashes.c | 1 + nettle-meta.h | 1 + sm3-meta.c | 42 +++++++ sm3.c | 251 +++++++++++++++++++++++++++++++++++++ sm3.h | 82 ++++++++++++ testsuite/meta-hash-test.c | 3 +- 7 files changed, 381 insertions(+), 2 deletions(-) create mode 100644 sm3-meta.c create mode 100644 sm3.c create mode 100644 sm3.h
diff --git a/Makefile.in b/Makefile.in index e6fc25b8..77f474c3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -145,6 +145,7 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c aes-decrypt-table.c \ sha3-224.c sha3-224-meta.c sha3-256.c sha3-256-meta.c \ sha3-384.c sha3-384-meta.c sha3-512.c sha3-512-meta.c \ shake256.c \ + sm3.c sm3-meta.c \ serpent-set-key.c serpent-encrypt.c serpent-decrypt.c \ serpent-meta.c \ streebog.c streebog-meta.c \ @@ -233,7 +234,7 @@ HEADERS = aes.h arcfour.h arctwo.h asn1.h blowfish.h \ pbkdf2.h \ pgp.h pkcs1.h pss.h pss-mgf1.h realloc.h ripemd160.h rsa.h \ salsa20.h sexp.h \ - serpent.h sha.h sha1.h sha2.h sha3.h streebog.h twofish.h \ + serpent.h sha.h sha1.h sha2.h sha3.h sm3.h streebog.h twofish.h \ umac.h yarrow.h xts.h poly1305.h nist-keywrap.h
INSTALL_HEADERS = $(HEADERS) version.h @IF_MINI_GMP@ mini-gmp.h diff --git a/nettle-meta-hashes.c b/nettle-meta-hashes.c index 8e96dd41..4d421182 100644 --- a/nettle-meta-hashes.c +++ b/nettle-meta-hashes.c @@ -55,6 +55,7 @@ const struct nettle_hash * const _nettle_hashes[] = { &nettle_sha3_512, &nettle_streebog256, &nettle_streebog512, + &nettle_sm3, NULL };
diff --git a/nettle-meta.h b/nettle-meta.h index 6a62b653..664321d8 100644 --- a/nettle-meta.h +++ b/nettle-meta.h @@ -145,6 +145,7 @@ extern const struct nettle_hash nettle_sha3_384; extern const struct nettle_hash nettle_sha3_512; extern const struct nettle_hash nettle_streebog256; extern const struct nettle_hash nettle_streebog512; +extern const struct nettle_hash nettle_sm3;
struct nettle_mac { diff --git a/sm3-meta.c b/sm3-meta.c new file mode 100644 index 00000000..036e9e95 --- /dev/null +++ b/sm3-meta.c @@ -0,0 +1,42 @@ +/* sm3-meta.c + + Copyright (C) 2017 Jia Zhang + Copyright (C) 2021 Tianjia Zhang tianjia.zhang@linux.alibaba.com + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "sm3.h" + +const struct nettle_hash nettle_sm3 += _NETTLE_HASH(sm3, SM3); diff --git a/sm3.c b/sm3.c new file mode 100644 index 00000000..ac58cb38 --- /dev/null +++ b/sm3.c @@ -0,0 +1,251 @@ +/* sm3.c + + The SM3 hash function. + + Copyright (C) 2017 Jia Zhang + Copyright (C) 2021 Tianjia Zhang tianjia.zhang@linux.alibaba.com + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <assert.h> +#include <string.h> + +#include "sm3.h" + +#include "macros.h" +#include "nettle-write.h" + +static const uint32_t K[64] = +{ + 0x79cc4519UL, 0xf3988a32UL, 0xe7311465UL, 0xce6228cbUL, + 0x9cc45197UL, 0x3988a32fUL, 0x7311465eUL, 0xe6228cbcUL, + 0xcc451979UL, 0x988a32f3UL, 0x311465e7UL, 0x6228cbceUL, + 0xc451979cUL, 0x88a32f39UL, 0x11465e73UL, 0x228cbce6UL, + 0x9d8a7a87UL, 0x3b14f50fUL, 0x7629ea1eUL, 0xec53d43cUL, + 0xd8a7a879UL, 0xb14f50f3UL, 0x629ea1e7UL, 0xc53d43ceUL, + 0x8a7a879dUL, 0x14f50f3bUL, 0x29ea1e76UL, 0x53d43cecUL, + 0xa7a879d8UL, 0x4f50f3b1UL, 0x9ea1e762UL, 0x3d43cec5UL, + 0x7a879d8aUL, 0xf50f3b14UL, 0xea1e7629UL, 0xd43cec53UL, + 0xa879d8a7UL, 0x50f3b14fUL, 0xa1e7629eUL, 0x43cec53dUL, + 0x879d8a7aUL, 0x0f3b14f5UL, 0x1e7629eaUL, 0x3cec53d4UL, + 0x79d8a7a8UL, 0xf3b14f50UL, 0xe7629ea1UL, 0xcec53d43UL, + 0x9d8a7a87UL, 0x3b14f50fUL, 0x7629ea1eUL, 0xec53d43cUL, + 0xd8a7a879UL, 0xb14f50f3UL, 0x629ea1e7UL, 0xc53d43ceUL, + 0x8a7a879dUL, 0x14f50f3bUL, 0x29ea1e76UL, 0x53d43cecUL, + 0xa7a879d8UL, 0x4f50f3b1UL, 0x9ea1e762UL, 0x3d43cec5UL +}; + +/* + 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 = ROTL32(7, (ROTL32(12, (a)) + (e) + (t))); \ + ss2 = ss1 ^ ROTL32(12, (a)); \ + d += FF ## i(a, b, c) + ss2 + ((w1) ^ (w2)); \ + h += GG ## i(e, f, g) + ss1 + (w1); \ + b = ROTL32(9, (b)); \ + f = ROTL32(19, (f)); \ + 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) (x ^ y ^ z) +#define GG2(x, y, z) ((x & y) | ( ~x & z)) + +/* Message expansion */ +#define P0(x) ((x) ^ ROTL32(9, (x)) ^ ROTL32(17, (x))) +#define P1(x) ((x) ^ ROTL32(15, (x)) ^ ROTL32(23, (x))) +#define I(i) (w[i] = READ_UINT32(input + i * 4)) +#define W1(i) (w[i & 0x0f]) +#define W2(i) (w[i & 0x0f] = \ + P1(w[i & 0x0f] ^ w[(i-9) & 0x0f] ^ ROTL32(15, w[(i-3) & 0x0f])) \ + ^ ROTL32(7, w[(i-13) & 0x0f]) \ + ^ w[(i-6) & 0x0f]) + + +static void +sm3_compress(uint32_t *state, const uint8_t *input) +{ + uint32_t a, b, c, d, e, f, g, h, ss1, ss2; + uint32_t w[16]; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = 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)); + + state[0] ^= a; + state[1] ^= b; + state[2] ^= c; + state[3] ^= d; + state[4] ^= e; + state[5] ^= f; + state[6] ^= g; + state[7] ^= h; +} + +void +sm3_init(struct sm3_ctx *ctx) +{ + static const uint32_t H0[_SM3_DIGEST_LENGTH] = + { + 0x7380166fUL, 0x4914b2b9UL, 0x172442d7UL, 0xda8a0600UL, + 0xa96f30bcUL, 0x163138aaUL, 0xe38dee4dUL, 0xb0fb0e4eUL + }; + + memcpy(ctx->state, H0, sizeof(H0)); + + /* Initialize bit count */ + ctx->count = 0; + + /* Initialize buffer */ + ctx->index = 0; +} + +#define COMPRESS(ctx, data) (sm3_compress((ctx)->state, (data))) + +void +sm3_update(struct sm3_ctx *ctx, + size_t length, const uint8_t *data) +{ + MD_UPDATE(ctx, length, data, COMPRESS, ctx->count++); +} + +static void +sm3_write_digest(struct sm3_ctx *ctx, + size_t length, + uint8_t *digest) +{ + uint64_t bit_count; + + assert(length <= SM3_DIGEST_SIZE); + + MD_PAD(ctx, 8, COMPRESS); + + /* There are 512 = 2^9 bits in one block */ + bit_count = (ctx->count << 9) | (ctx->index << 3); + + /* This is slightly inefficient, as the numbers are converted to + big-endian format, and will be converted back by the compression + function. It's probably not worth the effort to fix this. */ + WRITE_UINT64(ctx->block + (SM3_BLOCK_SIZE - 8), bit_count); + COMPRESS(ctx, ctx->block); + + _nettle_write_be32(length, digest, ctx->state); +} + +void +sm3_digest(struct sm3_ctx *ctx, + size_t length, + uint8_t *digest) +{ + sm3_write_digest(ctx, length, digest); + sm3_init(ctx); +} diff --git a/sm3.h b/sm3.h new file mode 100644 index 00000000..8017a543 --- /dev/null +++ b/sm3.h @@ -0,0 +1,82 @@ +/* sm3.h + + The SM3 hash function. + + Copyright (C) 2017 Jia Zhang + Copyright (C) 2021 Tianjia Zhang tianjia.zhang@linux.alibaba.com + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_SM3_H_INCLUDED +#define NETTLE_SM3_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define sm3_init nettle_sm3_init +#define sm3_update nettle_sm3_update +#define sm3_digest nettle_sm3_digest + +#define SM3_DIGEST_SIZE 32 +#define SM3_BLOCK_SIZE 64 +/* For backwards compatibility */ +#define SM3_DATA_SIZE SM3_BLOCK_SIZE + +/* Digest is kept internally as 8 32-bit words. */ +#define _SM3_DIGEST_LENGTH 8 + +struct sm3_ctx +{ + uint32_t state[_SM3_DIGEST_LENGTH]; + uint64_t count; /* Block count */ + unsigned index; /* Into buffer */ + uint8_t block[SM3_BLOCK_SIZE]; /* Block buffer */ +}; + +void +sm3_init(struct sm3_ctx *ctx); + +void +sm3_update(struct sm3_ctx *ctx, + size_t length, + const uint8_t *data); + +void +sm3_digest(struct sm3_ctx *ctx, + size_t length, + uint8_t *digest); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_SM3_H_INCLUDED */ diff --git a/testsuite/meta-hash-test.c b/testsuite/meta-hash-test.c index eb9f3698..3aed43fc 100644 --- a/testsuite/meta-hash-test.c +++ b/testsuite/meta-hash-test.c @@ -21,7 +21,8 @@ const char* hashes[] = { "sha3_384", "sha3_512", "streebog256", - "streebog512" + "streebog512", + "sm3", };
void
Tianjia Zhang tianjia.zhang@linux.alibaba.com writes:
Add OSCCA SM3 secure hash (OSCCA GM/T 0004-2012 SM3) generic hash transformation.
Thanks, merged the patch series onto a branch "sm3" for testing, with only minor changes.
--- /dev/null +++ b/sm3.h
[...]
+#define SM3_DIGEST_SIZE 32 +#define SM3_BLOCK_SIZE 64 +/* For backwards compatibility */ +#define SM3_DATA_SIZE SM3_BLOCK_SIZE
I dropped the definition of SM3_DATA_SIZE, since this is a new feature in Nettle, there's no old version to be compatible with.
Would you mind writing a short description of the algorithm for the manual? I think it should go under "Miscellaneous hash functions". Would be nice with some brief background on this hash function (origin, intended applications, when and where it's useful) plus reference docs for the defined constants and functions.
Regards, /Niels
Hi Niels,
On 12/2/21 3:40 AM, Niels Möller wrote:
Tianjia Zhang tianjia.zhang@linux.alibaba.com writes:
Add OSCCA SM3 secure hash (OSCCA GM/T 0004-2012 SM3) generic hash transformation.
Thanks, merged the patch series onto a branch "sm3" for testing, with only minor changes.
--- /dev/null +++ b/sm3.h
[...]
+#define SM3_DIGEST_SIZE 32 +#define SM3_BLOCK_SIZE 64 +/* For backwards compatibility */ +#define SM3_DATA_SIZE SM3_BLOCK_SIZE
I dropped the definition of SM3_DATA_SIZE, since this is a new feature in Nettle, there's no old version to be compatible with.
Thanks for pointing it out.
Would you mind writing a short description of the algorithm for the manual? I think it should go under "Miscellaneous hash functions". Would be nice with some brief background on this hash function (origin, intended applications, when and where it's useful) plus reference docs for the defined constants and functions.
SM3 is a cryptographic hash function standard adopted by the government of the People's Republic of China, which was issued by the Cryptography Standardization Technical Committee of China on December 17, 2010. The corresponding standard is "GM/T 0004-2012 "SM3 Cryptographic Hash Algorithm"".
SM3 algorithm is a hash algorithm in ShangMi cryptosystems. SM3 is mainly used for digital signature and verification, message authentication code generation and verification, random number generation, etc. Its algorithm is public. Combined with the public key algorithm SM2 and the symmetric encryption algorithm SM4, it can be used in various data security and network security scenarios such as the TLS 1.3 protocol, disk encryption, standard digital certificates, and digital signatures. According to the State Cryptography Administration of China, its security and efficiency are equivalent to SHA-256.
Reference specification: 1. http://gmbz.org.cn/main/viewfile/20180108023812835219.html 2. http://www.gmbz.org.cn/upload/2018-07-24/1532401392982079739.pdf 3. https://datatracker.ietf.org/doc/html/draft-oscca-cfrg-sm3-02 4. https://datatracker.ietf.org/doc/html/rfc8998
Thanks for your reminder, the above is the information I provided. Do I need to submit it to the document through PATCH?
Best regards, Tianjia
Tianjia Zhang tianjia.zhang@linux.alibaba.com writes:
Hi Niels,
Would you mind writing a short description of the algorithm for the manual? I think it should go under "Miscellaneous hash functions". Would be nice with some brief background on this hash function (origin, intended applications, when and where it's useful) plus reference docs for the defined constants and functions.
SM3 is a cryptographic hash function standard adopted by the government of the People's Republic of China, which was issued by the Cryptography Standardization Technical Committee of China on December 17, 2010. The corresponding standard is "GM/T 0004-2012 "SM3 Cryptographic Hash Algorithm"".
SM3 algorithm is a hash algorithm in ShangMi cryptosystems. SM3 is mainly used for digital signature and verification, message authentication code generation and verification, random number generation, etc.
Thanks for the backround.
Its algorithm is public. Combined with the public key
algorithm SM2 and the symmetric encryption algorithm SM4, it can be used in various data security and network security scenarios such as the TLS 1.3 protocol, disk encryption, standard digital certificates, and digital signatures.
I think the above two sentences could be removed or shortened. I think the mention of TLS, with reference to RFC 8998, is the part most relevant for the Nettle manual. Besides that I think your text provides right level of detail.
According to the State Cryptography
Administration of China, its security and efficiency are equivalent to SHA-256.
This is relevant too.
Thanks for your reminder, the above is the information I provided. Do I need to submit it to the document through PATCH?
If you can prepare a patch for nettle.texinfo, that would be ideal.
Regards, /Niels
Hi Niels,
On 12/3/21 4:09 AM, Niels Möller wrote:
Tianjia Zhang tianjia.zhang@linux.alibaba.com writes:
Hi Niels,
Would you mind writing a short description of the algorithm for the manual? I think it should go under "Miscellaneous hash functions". Would be nice with some brief background on this hash function (origin, intended applications, when and where it's useful) plus reference docs for the defined constants and functions.
SM3 is a cryptographic hash function standard adopted by the government of the People's Republic of China, which was issued by the Cryptography Standardization Technical Committee of China on December 17, 2010. The corresponding standard is "GM/T 0004-2012 "SM3 Cryptographic Hash Algorithm"".
SM3 algorithm is a hash algorithm in ShangMi cryptosystems. SM3 is mainly used for digital signature and verification, message authentication code generation and verification, random number generation, etc.
Thanks for the backround.
Its algorithm is public. Combined with the public key
algorithm SM2 and the symmetric encryption algorithm SM4, it can be used in various data security and network security scenarios such as the TLS 1.3 protocol, disk encryption, standard digital certificates, and digital signatures.
I think the above two sentences could be removed or shortened. I think the mention of TLS, with reference to RFC 8998, is the part most relevant for the Nettle manual. Besides that I think your text provides right level of detail.
Will update in next patch.
According to the State Cryptography
Administration of China, its security and efficiency are equivalent to SHA-256.
This is relevant too.
Thanks for your reminder, the above is the information I provided. Do I need to submit it to the document through PATCH?
If you can prepare a patch for nettle.texinfo, that would be ideal.
Regards, /Niels
Thanks for your suggestion, I will send another patch to update nettle.texinfo.
Best regards, Tianjia
Add a testuite for SM3 hash function. Test vectors are based on: https://datatracker.ietf.org/doc/html/draft-shen-sm3-hash-01
Signed-off-by: Tianjia Zhang tianjia.zhang@linux.alibaba.com --- testsuite/.gitignore | 1 + testsuite/Makefile.in | 2 +- testsuite/sm3-test.c | 20 ++++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 testsuite/sm3-test.c
diff --git a/testsuite/.gitignore b/testsuite/.gitignore index 9d8a7681..ca41472e 100644 --- a/testsuite/.gitignore +++ b/testsuite/.gitignore @@ -97,6 +97,7 @@ /sha512-224-test /sha512-256-test /sha512-test +/sm3-test /streebog-test /twofish-test /umac-test diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in index 2b554261..6734d3e6 100644 --- a/testsuite/Makefile.in +++ b/testsuite/Makefile.in @@ -24,7 +24,7 @@ TS_NETTLE_SOURCES = aes-test.c aes-keywrap-test.c arcfour-test.c arctwo-test.c \ sha384-test.c sha512-test.c sha512-224-test.c sha512-256-test.c \ sha3-permute-test.c sha3-224-test.c sha3-256-test.c \ sha3-384-test.c sha3-512-test.c \ - shake256-test.c streebog-test.c \ + shake256-test.c streebog-test.c sm3-test.c \ serpent-test.c twofish-test.c version-test.c \ knuth-lfib-test.c \ cbc-test.c cfb-test.c ctr-test.c gcm-test.c eax-test.c ccm-test.c \ diff --git a/testsuite/sm3-test.c b/testsuite/sm3-test.c new file mode 100644 index 00000000..d3684afd --- /dev/null +++ b/testsuite/sm3-test.c @@ -0,0 +1,20 @@ +#include "testutils.h" +#include "sm3.h" + +void +test_main(void) +{ + /* test vectors from: + * https://datatracker.ietf.org/doc/html/draft-shen-sm3-hash-01 + */ + test_hash(&nettle_sm3, + SDATA("abc"), + SHEX("66c7f0f462eeedd9 d1f2d46bdc10e4e2" + "4167c4875cf2f7a2 297da02b8f4ba8e0")); + + test_hash(&nettle_sm3, + SDATA("abcdabcdabcdabcdabcdabcdabcdabcd" + "abcdabcdabcdabcdabcdabcdabcdabcd"), + SHEX("debe9ff92275b8a1 38604889c18e5a4d" + "6fdb70e5387e5765 293dcba39c0c5732")); +}
Add support for calculating HMAC using SM3 hash functions.
Signed-off-by: Tianjia Zhang tianjia.zhang@linux.alibaba.com --- Makefile.in | 4 +-- hmac-sm3-meta.c | 47 +++++++++++++++++++++++++++++++ hmac-sm3.c | 59 +++++++++++++++++++++++++++++++++++++++ hmac.h | 19 +++++++++++++ nettle-meta-macs.c | 1 + nettle-meta.h | 1 + testsuite/hmac-test.c | 6 ++++ testsuite/meta-mac-test.c | 1 + 8 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 hmac-sm3-meta.c create mode 100644 hmac-sm3.c
diff --git a/Makefile.in b/Makefile.in index 77f474c3..0590c370 100644 --- a/Makefile.in +++ b/Makefile.in @@ -117,10 +117,10 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c aes-decrypt-table.c \ gost28147.c gosthash94.c gosthash94-meta.c \ hmac.c hmac-gosthash94.c hmac-md5.c hmac-ripemd160.c \ hmac-sha1.c hmac-sha224.c hmac-sha256.c hmac-sha384.c \ - hmac-sha512.c hmac-streebog.c \ + hmac-sha512.c hmac-streebog.c hmac-sm3.c \ hmac-md5-meta.c hmac-ripemd160-meta.c hmac-sha1-meta.c \ hmac-sha224-meta.c hmac-sha256-meta.c hmac-sha384-meta.c \ - hmac-sha512-meta.c hmac-streebog-meta.c \ + hmac-sha512-meta.c hmac-streebog-meta.c hmac-sm3-meta.c \ knuth-lfib.c hkdf.c \ md2.c md2-meta.c md4.c md4-meta.c \ md5.c md5-compress.c md5-compat.c md5-meta.c \ diff --git a/hmac-sm3-meta.c b/hmac-sm3-meta.c new file mode 100644 index 00000000..d3d7f3d2 --- /dev/null +++ b/hmac-sm3-meta.c @@ -0,0 +1,47 @@ +/* hmac-sm3-meta.c + + Copyright (C) 2021 Tianjia Zhang tianjia.zhang@linux.alibaba.com + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "hmac.h" + +static void +hmac_sm3_set_key_wrapper (void *ctx, const uint8_t *key) +{ + hmac_sm3_set_key (ctx, SM3_DIGEST_SIZE, key); +} + +const struct nettle_mac nettle_hmac_sm3 += _NETTLE_HMAC(hmac_sm3, SM3); diff --git a/hmac-sm3.c b/hmac-sm3.c new file mode 100644 index 00000000..decb4a2d --- /dev/null +++ b/hmac-sm3.c @@ -0,0 +1,59 @@ +/* hmac-sm3.c + + HMAC-SM3 message authentication code. + + Copyright (C) 2021 Tianjia Zhang tianjia.zhang@linux.alibaba.com + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "hmac.h" + +void +hmac_sm3_set_key(struct hmac_sm3_ctx *ctx, + size_t key_length, const uint8_t *key) +{ + HMAC_SET_KEY(ctx, &nettle_sm3, key_length, key); +} + +void +hmac_sm3_update(struct hmac_sm3_ctx *ctx, + size_t length, const uint8_t *data) +{ + sm3_update(&ctx->state, length, data); +} + +void +hmac_sm3_digest(struct hmac_sm3_ctx *ctx, + size_t length, uint8_t *digest) +{ + HMAC_DIGEST(ctx, &nettle_sm3, length, digest); +} diff --git a/hmac.h b/hmac.h index 72c8fd57..453a67af 100644 --- a/hmac.h +++ b/hmac.h @@ -42,6 +42,7 @@ #include "sha1.h" #include "sha2.h" #include "streebog.h" +#include "sm3.h"
#ifdef __cplusplus extern "C" { @@ -81,6 +82,9 @@ extern "C" { #define hmac_streebog512_set_key nettle_hmac_streebog512_set_key #define hmac_streebog512_update nettle_hmac_streebog512_update #define hmac_streebog512_digest nettle_hmac_streebog512_digest +#define hmac_sm3_set_key nettle_hmac_sm3_set_key +#define hmac_sm3_update nettle_hmac_sm3_update +#define hmac_sm3_digest nettle_hmac_sm3_digest
void hmac_set_key(void *outer, void *inner, void *state, @@ -273,6 +277,21 @@ void hmac_streebog256_digest(struct hmac_streebog256_ctx *ctx, size_t length, uint8_t *digest);
+/* hmac-sm3 */ +struct hmac_sm3_ctx HMAC_CTX(struct sm3_ctx); + +void +hmac_sm3_set_key(struct hmac_sm3_ctx *ctx, + size_t key_length, const uint8_t *key); + +void +hmac_sm3_update(struct hmac_sm3_ctx *ctx, + size_t length, const uint8_t *data); + +void +hmac_sm3_digest(struct hmac_sm3_ctx *ctx, + size_t length, uint8_t *digest); + #ifdef __cplusplus } #endif diff --git a/nettle-meta-macs.c b/nettle-meta-macs.c index 5e8f8713..40aa6dcd 100644 --- a/nettle-meta-macs.c +++ b/nettle-meta-macs.c @@ -50,6 +50,7 @@ const struct nettle_mac * const _nettle_macs[] = { &nettle_hmac_sha512, &nettle_hmac_streebog256, &nettle_hmac_streebog512, + &nettle_hmac_sm3, NULL };
diff --git a/nettle-meta.h b/nettle-meta.h index 664321d8..d684947e 100644 --- a/nettle-meta.h +++ b/nettle-meta.h @@ -291,6 +291,7 @@ extern const struct nettle_mac nettle_hmac_sha384; extern const struct nettle_mac nettle_hmac_sha512; extern const struct nettle_mac nettle_hmac_streebog256; extern const struct nettle_mac nettle_hmac_streebog512; +extern const struct nettle_mac nettle_hmac_sm3;
#ifdef __cplusplus } diff --git a/testsuite/hmac-test.c b/testsuite/hmac-test.c index 348f7920..0d1fb44c 100644 --- a/testsuite/hmac-test.c +++ b/testsuite/hmac-test.c @@ -883,4 +883,10 @@ test_main(void) SHEX("0126bdb87800af214341456563780100"), SHEX("a1aa5f7de402d7b3d323f2991c8d4534" "013137010a83754fd0af6d7cd4922ed9")); + + HMAC_TEST(sm3, + SDATA("monkey monkey monkey monkey"), + SDATA("abc"), + SHEX("7a9388e2ca5343b5d76e7c2c3d84f239" + "f306c0b60d5e0dc4d2771e42860a6a2b")); } diff --git a/testsuite/meta-mac-test.c b/testsuite/meta-mac-test.c index adbd4326..0ff82810 100644 --- a/testsuite/meta-mac-test.c +++ b/testsuite/meta-mac-test.c @@ -14,6 +14,7 @@ const char* macs[] = { "hmac_sha512", "hmac_streebog256", "hmac_streebog512", + "hmac_sm3", };
void
Signed-off-by: Tianjia Zhang tianjia.zhang@linux.alibaba.com --- examples/nettle-benchmark.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/nettle-benchmark.c b/examples/nettle-benchmark.c index 50a5815a..ba5dd284 100644 --- a/examples/nettle-benchmark.c +++ b/examples/nettle-benchmark.c @@ -909,7 +909,7 @@ main(int argc, char **argv) &nettle_sha3_384, &nettle_sha3_512, &nettle_ripemd160, &nettle_gosthash94, &nettle_gosthash94cp, &nettle_streebog256, - &nettle_streebog512, + &nettle_streebog512, &nettle_sm3, NULL };
nettle-bugs@lists.lysator.liu.se