changeset 38912:0a0ea008436e

New module: crypto/gc-sm3 * lib/gc.h: Declare SM3-related stuffs. * lib/gc-gnulib.c: Support sm3 in internal functions. * lib/gc-libgcrypt.c: Support sm3 with libgcrypt. * m4/gc-sm3.m4: m4 file for gc-sm3 module. * modules/crypto/gc-sm3: Define gc-sm3 module. * tests/test-gc-sm3.c: Implement SM3 test case with libgcrypt. * modules/crypto/gc-sm3-tests: Define gc-sm3 test module. * MODULES.html.sh: List gc-sm3 module.
author Jia Zhang <qianyue.zj@alibaba-inc.com>
date Sat, 28 Oct 2017 23:58:20 -0400
parents 7558397ac799
children e910a1f5a7db
files ChangeLog MODULES.html.sh lib/gc-gnulib.c lib/gc-libgcrypt.c lib/gc.h m4/gc-sm3.m4 modules/crypto/gc-sm3 modules/crypto/gc-sm3-tests tests/test-gc-sm3.c
diffstat 9 files changed, 280 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Oct 29 08:38:54 2017 +0100
+++ b/ChangeLog	Sat Oct 28 23:58:20 2017 -0400
@@ -1,3 +1,15 @@
+2017-10-29  Jia Zhang  <qianyue.zj@alibaba-inc.com>
+
+	New module: crypto/gc-sm3
+	* lib/gc.h: Declare SM3-related stuffs.
+	* lib/gc-gnulib.c: Support sm3 in internal functions.
+	* lib/gc-libgcrypt.c: Support sm3 with libgcrypt.
+	* m4/gc-sm3.m4: m4 file for gc-sm3 module.
+	* modules/crypto/gc-sm3: Define gc-sm3 module.
+	* tests/test-gc-sm3.c: Implement SM3 test case with libgcrypt.
+	* modules/crypto/gc-sm3-tests: Define gc-sm3 test module.
+	* MODULES.html.sh: List gc-sm3 module.
+
 2017-10-29  Bruno Haible  <bruno@clisp.org>
 
 	random, random_r: Mention different prototypes on Haiku.
--- a/MODULES.html.sh	Sun Oct 29 08:38:54 2017 +0100
+++ b/MODULES.html.sh	Sat Oct 28 23:58:20 2017 -0400
@@ -1988,6 +1988,7 @@
   func_module crypto/gc-random
   func_module crypto/gc-rijndael
   func_module crypto/gc-sha1
+  func_module crypto/gc-sm3
   func_end_table
 
   element="Compiler warning management"
--- a/lib/gc-gnulib.c	Sun Oct 29 08:38:54 2017 +0100
+++ b/lib/gc-gnulib.c	Sat Oct 28 23:58:20 2017 -0400
@@ -48,6 +48,9 @@
 #ifdef GNULIB_GC_SHA1
 # include "sha1.h"
 #endif
+#ifdef GNULIB_GC_SM3
+# include "sm3.h"
+#endif
 #if defined(GNULIB_GC_HMAC_MD5) || defined(GNULIB_GC_HMAC_SHA1) || defined(GNULIB_GC_HMAC_SHA256) || defined(GNULIB_GC_HMAC_SHA512)
 # include "hmac.h"
 #endif
@@ -618,6 +621,9 @@
 #ifdef GNULIB_GC_SHA1
   struct sha1_ctx sha1Context;
 #endif
+#ifdef GNULIB_GC_SM3
+  struct sm3_ctx sm3Context;
+#endif
 } _gc_hash_ctx;
 
 Gc_rc
@@ -662,6 +668,12 @@
       break;
 #endif
 
+#ifdef GNULIB_GC_SM3
+    case GC_SM3:
+      sm3_init_ctx (&ctx->sm3Context);
+      break;
+#endif
+
     default:
       rc = GC_INVALID_HASH;
       break;
@@ -717,6 +729,10 @@
       len = GC_SHA1_DIGEST_SIZE;
       break;
 
+    case GC_SM3:
+      len = GC_SM3_DIGEST_SIZE;
+      break;
+
     default:
       return 0;
     }
@@ -755,6 +771,12 @@
       break;
 #endif
 
+#ifdef GNULIB_GC_SM3
+    case GC_SM3:
+      sm3_process_bytes (data, len, &ctx->sm3Context);
+      break;
+#endif
+
     default:
       break;
     }
@@ -796,6 +818,13 @@
       break;
 #endif
 
+#ifdef GNULIB_GC_SM3
+    case GC_SM3:
+      sm3_finish_ctx (&ctx->sm3Context, ctx->hash);
+      ret = ctx->hash;
+      break;
+#endif
+
     default:
       return NULL;
     }
@@ -840,6 +869,12 @@
       break;
 #endif
 
+#ifdef GNULIB_GC_SM3
+    case GC_SM3:
+      sm3_buffer (in, inlen, resbuf);
+      break;
+#endif
+
     default:
       return GC_INVALID_HASH;
     }
@@ -883,6 +918,15 @@
 }
 #endif
 
+#ifdef GNULIB_GC_SM3
+Gc_rc
+gc_sm3 (const void *in, size_t inlen, void *resbuf)
+{
+  sm3_buffer (in, inlen, resbuf);
+  return GC_OK;
+}
+#endif
+
 #ifdef GNULIB_GC_HMAC_MD5
 Gc_rc
 gc_hmac_md5 (const void *key, size_t keylen,
--- a/lib/gc-libgcrypt.c	Sun Oct 29 08:38:54 2017 +0100
+++ b/lib/gc-libgcrypt.c	Sat Oct 28 23:58:20 2017 -0400
@@ -304,6 +304,10 @@
       gcryalg = GCRY_MD_RMD160;
       break;
 
+    case GC_SM3:
+      gcryalg = GCRY_MD_SM3;
+      break;
+
     default:
       rc = GC_INVALID_HASH;
     }
@@ -403,6 +407,10 @@
       len = GC_SHA224_DIGEST_SIZE;
       break;
 
+    case GC_SM3:
+      len = GC_SM3_DIGEST_SIZE;
+      break;
+
     default:
       return 0;
     }
@@ -530,6 +538,12 @@
       break;
 #endif
 
+#ifdef GNULIB_GC_SM3
+    case GC_SM3:
+      gcryalg = GCRY_MD_SM3;
+      break;
+#endif
+
     default:
       return GC_INVALID_HASH;
     }
@@ -646,6 +660,38 @@
 }
 #endif
 
+#ifdef GNULIB_GC_SM3
+Gc_rc
+gc_sm3  (const void *in, size_t inlen, void *resbuf)
+{
+  size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_SM3);
+  gcry_md_hd_t hd;
+  gpg_error_t err;
+  unsigned char *p;
+
+  assert (outlen == GC_SM3_DIGEST_SIZE);
+
+  err = gcry_md_open (&hd, GCRY_MD_SM3, 0);
+  if (err != GPG_ERR_NO_ERROR)
+    return GC_INVALID_HASH;
+
+  gcry_md_write (hd, in, inlen);
+
+  p = gcry_md_read (hd, GCRY_MD_SM3);
+  if (p == NULL)
+    {
+      gcry_md_close (hd);
+      return GC_INVALID_HASH;
+    }
+
+  memcpy (resbuf, p, outlen);
+
+  gcry_md_close (hd);
+
+  return GC_OK;
+}
+#endif
+
 #ifdef GNULIB_GC_HMAC_MD5
 Gc_rc
 gc_hmac_md5 (const void *key, size_t keylen,
--- a/lib/gc.h	Sun Oct 29 08:38:54 2017 +0100
+++ b/lib/gc.h	Sat Oct 28 23:58:20 2017 -0400
@@ -47,7 +47,8 @@
   GC_SHA256,
   GC_SHA384,
   GC_SHA512,
-  GC_SHA224
+  GC_SHA224,
+  GC_SM3
 };
 typedef enum Gc_hash Gc_hash;
 
@@ -69,6 +70,7 @@
 #define GC_SHA384_DIGEST_SIZE 48
 #define GC_SHA512_DIGEST_SIZE 64
 #define GC_SHA224_DIGEST_SIZE 24
+#define GC_SM3_DIGEST_SIZE 32
 
 /* Cipher types. */
 enum Gc_cipher
@@ -156,6 +158,7 @@
 extern Gc_rc gc_md4 (const void *in, size_t inlen, void *resbuf);
 extern Gc_rc gc_md5 (const void *in, size_t inlen, void *resbuf);
 extern Gc_rc gc_sha1 (const void *in, size_t inlen, void *resbuf);
+extern Gc_rc gc_sm3 (const void *in, size_t inlen, void *resbuf);
 extern Gc_rc gc_hmac_md5 (const void *key, size_t keylen,
                           const void *in, size_t inlen, char *resbuf);
 extern Gc_rc gc_hmac_sha1 (const void *key, size_t keylen,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/m4/gc-sm3.m4	Sat Oct 28 23:58:20 2017 -0400
@@ -0,0 +1,10 @@
+# gc-sm3.m4 serial 1
+dnl Copyright (C) 2017 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_GC_SM3],
+[
+  AC_REQUIRE([gl_GC])
+])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/crypto/gc-sm3	Sat Oct 28 23:58:20 2017 -0400
@@ -0,0 +1,24 @@
+Description:
+Generic crypto wrappers for SM3 functions.
+
+Files:
+m4/gc-sm3.m4
+
+Depends-on:
+crypto/gc
+crypto/sm3 [test "$ac_cv_libgcrypt" != yes]
+
+configure.ac:
+gl_GC_SM3
+gl_MODULE_INDICATOR([gc-sm3])
+
+Makefile.am:
+
+Include:
+"gc.h"
+
+License:
+LGPLv2+
+
+Maintainer:
+Jia Zhang
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/crypto/gc-sm3-tests	Sat Oct 28 23:58:20 2017 -0400
@@ -0,0 +1,11 @@
+Files:
+tests/test-gc-sm3.c
+
+Depends-on:
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-gc-sm3
+check_PROGRAMS += test-gc-sm3
+test_gc_sm3_LDADD = $(LDADD) @LIB_CRYPTO@
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-gc-sm3.c	Sat Oct 28 23:58:20 2017 -0400
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2017 Free Software Foundation, Inc.
+ * Written by Jia Zhang <qianyue.zj@alibaba-inc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program 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 a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+#include "gc.h"
+
+int
+main (int argc, char *argv[])
+{
+  Gc_rc rc;
+  gc_hash_handle h;
+
+  rc = gc_init ();
+  if (rc != GC_OK)
+    {
+      printf ("gc_init() failed\n");
+      return 1;
+    }
+
+  /* Test vector from GM/T 004-2012. */
+
+  {
+    const char *in = "abc";
+    size_t inlen = strlen (in);
+    const char *expect = "\x66\xc7\xf0\xf4\x62\xee\xed\xd9\xd1"
+      "\xf2\xd4\x6b\xdc\x10\xe4\xe2\x41\x67\xc4\x87\x5c"
+      "\xf2\xf7\xa2\x29\x7d\xa0\x2b\x8f\x4b\xa8\xe0";
+    char out[32];
+    const char *p;
+
+    if (gc_sm3 (in, inlen, out) != 0)
+      {
+        printf ("gc_sm3 call failed\n");
+        return 1;
+      }
+
+    if (memcmp (out, expect, 32) != 0)
+      {
+        size_t i;
+        printf ("sm3 mismatch. expected:\n");
+        for (i = 0; i < 32; i++)
+          printf ("%02x ", (unsigned int) expect[i] & 0xFF);
+        printf ("\ncomputed:\n");
+        for (i = 0; i < 32; i++)
+          printf ("%02x ", (unsigned int) out[i] & 0xFF);
+        printf ("\n");
+        return 1;
+      }
+
+    rc = gc_hash_buffer (GC_SM3, "abc", 3, out);
+    if (rc != GC_OK)
+      {
+        printf ("gc_hash_buffer(sm3) call failed: %u\n", rc);
+        return 1;
+      }
+
+    if (memcmp (out, expect, 32) != 0)
+      {
+        size_t i;
+        printf ("sm3' mismatch. expected:\n");
+        for (i = 0; i < 32; i++)
+          printf ("%02x ", (unsigned int) expect[i] & 0xFF);
+        printf ("\ncomputed:\n");
+        for (i = 0; i < 32; i++)
+          printf ("%02x ", (unsigned int) out[i] & 0xFF);
+        printf ("\n");
+        return 1;
+      }
+
+    if (gc_hash_digest_length (GC_SM3) != 32)
+      {
+        printf ("gc_hash_digest_length (GC_SM3) failed\n");
+        return 1;
+      }
+
+    if ((rc = gc_hash_open (GC_SM3, 0, &h)) != GC_OK)
+      {
+        printf ("gc_hash_open(GC_SM3) failed (%u)\n", rc);
+        return 1;
+      }
+
+    gc_hash_write (h, inlen, in);
+
+    p = gc_hash_read (h);
+
+    if (!p)
+      {
+        printf ("gc_hash_read failed\n");
+        return 1;
+      }
+
+    if (memcmp (p, expect, 32) != 0)
+      {
+        size_t i;
+        printf ("sm3 mismatch. expected:\n");
+        for (i = 0; i < 32; i++)
+          printf ("%02x ", (unsigned int) expect[i] & 0xFF);
+        printf ("\ncomputed:\n");
+        for (i = 0; i < 32; i++)
+          printf ("%02x ", (unsigned int) p[i] & 0xFF);
+        printf ("\n");
+        return 1;
+      }
+
+    gc_hash_close (h);
+  }
+
+  gc_done ();
+
+  return 0;
+}