]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
gcm: Add SM4 as the GCM underlying cipher
authorTianjia Zhang <tianjia.zhang@linux.alibaba.com>
Mon, 21 Feb 2022 08:37:15 +0000 (16:37 +0800)
committerNiels Möller <nisse@lysator.liu.se>
Thu, 18 Aug 2022 09:33:54 +0000 (11:33 +0200)
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Makefile.in
gcm-sm4-meta.c [new file with mode: 0644]
gcm-sm4.c [new file with mode: 0644]
gcm.h
nettle-meta-aeads.c
nettle-meta.h
testsuite/gcm-test.c
testsuite/meta-aead-test.c

index 6f957aefea8ce4c4758bcf45b68a41526fcb4a4c..4d60aef38f468011c8ad23f038d923e1429c7c56 100644 (file)
@@ -112,6 +112,7 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c aes-decrypt-table.c \
                 gcm-aes256.c gcm-aes256-meta.c \
                 gcm-camellia128.c gcm-camellia128-meta.c \
                 gcm-camellia256.c gcm-camellia256-meta.c \
+                gcm-sm4.c gcm-sm4-meta.c \
                 cmac.c cmac64.c cmac-aes128.c cmac-aes256.c cmac-des3.c \
                 cmac-aes128-meta.c cmac-aes256-meta.c cmac-des3-meta.c \
                 gost28147.c gosthash94.c gosthash94-meta.c \
diff --git a/gcm-sm4-meta.c b/gcm-sm4-meta.c
new file mode 100644 (file)
index 0000000..090460d
--- /dev/null
@@ -0,0 +1,60 @@
+/* gcm-sm4-meta.c
+
+   Copyright (C) 2022 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 "nettle-meta.h"
+
+#include "gcm.h"
+
+static nettle_set_key_func gcm_sm4_set_nonce_wrapper;
+static void
+gcm_sm4_set_nonce_wrapper (void *ctx, const uint8_t *nonce)
+{
+  gcm_sm4_set_iv (ctx, GCM_IV_SIZE, nonce);
+}
+
+const struct nettle_aead nettle_gcm_sm4 =
+  { "gcm_sm4", sizeof(struct gcm_sm4_ctx),
+    GCM_BLOCK_SIZE, SM4_KEY_SIZE,
+    GCM_IV_SIZE, GCM_DIGEST_SIZE,
+    (nettle_set_key_func *) gcm_sm4_set_key,
+    (nettle_set_key_func *) gcm_sm4_set_key,
+    gcm_sm4_set_nonce_wrapper,
+    (nettle_hash_update_func *) gcm_sm4_update,
+    (nettle_crypt_func *) gcm_sm4_encrypt,
+    (nettle_crypt_func *) gcm_sm4_decrypt,
+    (nettle_hash_digest_func *) gcm_sm4_digest,
+  };
diff --git a/gcm-sm4.c b/gcm-sm4.c
new file mode 100644 (file)
index 0000000..19d91ae
--- /dev/null
+++ b/gcm-sm4.c
@@ -0,0 +1,81 @@
+/* gcm-sm4.c
+
+   Galois counter mode using SM4 as the underlying cipher.
+
+   Copyright (C) 2022 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 "gcm.h"
+
+void
+gcm_sm4_set_key(struct gcm_sm4_ctx *ctx, const uint8_t *key)
+{
+  GCM_SET_KEY(ctx, sm4_set_encrypt_key, sm4_crypt, key);
+}
+
+void
+gcm_sm4_set_iv(struct gcm_sm4_ctx *ctx,
+              size_t length, const uint8_t *iv)
+{
+  GCM_SET_IV (ctx, length, iv);
+}
+
+void
+gcm_sm4_update(struct gcm_sm4_ctx *ctx,
+              size_t length, const uint8_t *data)
+{
+  GCM_UPDATE (ctx, length, data);
+}
+
+void
+gcm_sm4_encrypt(struct gcm_sm4_ctx *ctx,
+               size_t length, uint8_t *dst, const uint8_t *src)
+{
+  GCM_ENCRYPT(ctx, sm4_crypt, length, dst, src);
+}
+
+void
+gcm_sm4_decrypt(struct gcm_sm4_ctx *ctx,
+               size_t length, uint8_t *dst, const uint8_t *src)
+{
+  GCM_DECRYPT(ctx, sm4_crypt, length, dst, src);
+}
+
+void
+gcm_sm4_digest(struct gcm_sm4_ctx *ctx,
+              size_t length, uint8_t *digest)
+{
+  GCM_DIGEST(ctx, sm4_crypt, length, digest);
+}
diff --git a/gcm.h b/gcm.h
index 96578530619c98f86ca99b2d058c3b66f78e69a9..39af5ab03bb16bd8cc2826d6bfb949378ca116b7 100644 (file)
--- a/gcm.h
+++ b/gcm.h
@@ -40,6 +40,7 @@
 
 #include "aes.h"
 #include "camellia.h"
+#include "sm4.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -95,6 +96,13 @@ extern "C" {
 #define gcm_camellia256_decrypt nettle_gcm_camellia256_decrypt
 #define gcm_camellia256_digest nettle_gcm_camellia256_digest
 
+#define gcm_sm4_set_key nettle_gcm_sm4_set_key
+#define gcm_sm4_set_iv nettle_gcm_sm4_set_iv
+#define gcm_sm4_update nettle_gcm_sm4_update
+#define gcm_sm4_encrypt nettle_gcm_sm4_encrypt
+#define gcm_sm4_decrypt nettle_gcm_sm4_decrypt
+#define gcm_sm4_digest nettle_gcm_sm4_digest
+
 #define GCM_BLOCK_SIZE 16
 #define GCM_IV_SIZE (GCM_BLOCK_SIZE - 4)
 #define GCM_DIGEST_SIZE 16
@@ -322,7 +330,22 @@ void gcm_camellia256_decrypt(struct gcm_camellia256_ctx *ctx,
 void gcm_camellia256_digest(struct gcm_camellia256_ctx *ctx,
                            size_t length, uint8_t *digest);
 
-  
+
+struct gcm_sm4_ctx GCM_CTX(struct sm4_ctx);
+
+void gcm_sm4_set_key(struct gcm_sm4_ctx *ctx, const uint8_t *key);
+void gcm_sm4_set_iv(struct gcm_sm4_ctx *ctx,
+                   size_t length, const uint8_t *iv);
+void gcm_sm4_update(struct gcm_sm4_ctx *ctx,
+                   size_t length, const uint8_t *data);
+void gcm_sm4_encrypt(struct gcm_sm4_ctx *ctx,
+                    size_t length, uint8_t *dst, const uint8_t *src);
+void gcm_sm4_decrypt(struct gcm_sm4_ctx *ctx,
+                    size_t length, uint8_t *dst, const uint8_t *src);
+void gcm_sm4_digest(struct gcm_sm4_ctx *ctx,
+                   size_t length, uint8_t *digest);
+
+
 #ifdef __cplusplus
 }
 #endif
index c99cc46518dd38cee6450a8435ff505d26a27a81..78f38a3c0140bd025efe7d30c5769a75e3ab4123 100644 (file)
@@ -43,6 +43,7 @@ const struct nettle_aead * const _nettle_aeads[] = {
   &nettle_gcm_aes256,
   &nettle_gcm_camellia128,
   &nettle_gcm_camellia256,
+  &nettle_gcm_sm4,
   &nettle_eax_aes128,
   &nettle_chacha_poly1305,
   NULL
index 3d0440e847ddb36b19be74bfa23e5f1ba395bce7..19dc96c5b3a93f7fe1ac4f6e32e2151e35435017 100644 (file)
@@ -200,6 +200,7 @@ extern const struct nettle_aead nettle_gcm_aes192;
 extern const struct nettle_aead nettle_gcm_aes256;
 extern const struct nettle_aead nettle_gcm_camellia128;
 extern const struct nettle_aead nettle_gcm_camellia256;
+extern const struct nettle_aead nettle_gcm_sm4;
 extern const struct nettle_aead nettle_eax_aes128;
 extern const struct nettle_aead nettle_chacha_poly1305;
 
index 8955e9b80ce9de586d979b546c41401d948beaf4..d70cdd1e98b68816efe92bf3fe78f926d2d8e26d 100644 (file)
@@ -577,6 +577,24 @@ test_main(void)
                 "16aedbf5a0de6a57 a637b39b"),  /* iv */
            SHEX("5791883f822013f8bd136fc36fb9946b"));  /* tag */
 
+  /*
+   * GCM-SM4 Test Vectors from
+   * https://datatracker.ietf.org/doc/html/rfc8998
+   */
+  test_aead(&nettle_gcm_sm4, NULL,
+           SHEX("0123456789ABCDEFFEDCBA9876543210"),
+           SHEX("FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2"),
+           SHEX("AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB"
+                "CCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDD"
+                "EEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFF"
+                "EEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAA"),
+           SHEX("17F399F08C67D5EE19D0DC9969C4BB7D"
+                "5FD46FD3756489069157B282BB200735"
+                "D82710CA5C22F0CCFA7CBF93D496AC15"
+                "A56834CBCF98C397B4024A2691233B8D"),
+           SHEX("00001234567800000000ABCD"),
+           SHEX("83DE3541E4C2B58177E065A9BF7B62EC"));
+
   /* Test gcm_hash, with varying message size, keys and iv all zero.
      Not compared to any other implementation. */
   test_gcm_hash (SDATA("a"),
index 1fcede408c9c897ff65f503c706d4d582c7bd32d..ceeca227dae67a33c5bc9dd38c4053026a8326df 100644 (file)
@@ -8,6 +8,7 @@ const char* aeads[] = {
   "gcm_aes256",
   "gcm_camellia128",
   "gcm_camellia256",
+  "gcm_sm4",
   "eax_aes128",
   "chacha_poly1305",
 };