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