* 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 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.
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"
#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
#ifdef GNULIB_GC_SHA1
struct sha1_ctx sha1Context;
#endif
+#ifdef GNULIB_GC_SM3
+ struct sm3_ctx sm3Context;
+#endif
} _gc_hash_ctx;
Gc_rc
break;
#endif
+#ifdef GNULIB_GC_SM3
+ case GC_SM3:
+ sm3_init_ctx (&ctx->sm3Context);
+ break;
+#endif
+
default:
rc = GC_INVALID_HASH;
break;
len = GC_SHA1_DIGEST_SIZE;
break;
+ case GC_SM3:
+ len = GC_SM3_DIGEST_SIZE;
+ break;
+
default:
return 0;
}
break;
#endif
+#ifdef GNULIB_GC_SM3
+ case GC_SM3:
+ sm3_process_bytes (data, len, &ctx->sm3Context);
+ break;
+#endif
+
default:
break;
}
break;
#endif
+#ifdef GNULIB_GC_SM3
+ case GC_SM3:
+ sm3_finish_ctx (&ctx->sm3Context, ctx->hash);
+ ret = ctx->hash;
+ break;
+#endif
+
default:
return NULL;
}
break;
#endif
+#ifdef GNULIB_GC_SM3
+ case GC_SM3:
+ sm3_buffer (in, inlen, resbuf);
+ break;
+#endif
+
default:
return GC_INVALID_HASH;
}
}
#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,
gcryalg = GCRY_MD_RMD160;
break;
+ case GC_SM3:
+ gcryalg = GCRY_MD_SM3;
+ break;
+
default:
rc = GC_INVALID_HASH;
}
len = GC_SHA224_DIGEST_SIZE;
break;
+ case GC_SM3:
+ len = GC_SM3_DIGEST_SIZE;
+ break;
+
default:
return 0;
}
break;
#endif
+#ifdef GNULIB_GC_SM3
+ case GC_SM3:
+ gcryalg = GCRY_MD_SM3;
+ break;
+#endif
+
default:
return GC_INVALID_HASH;
}
}
#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,
GC_SHA256,
GC_SHA384,
GC_SHA512,
- GC_SHA224
+ GC_SHA224,
+ GC_SM3
};
typedef enum Gc_hash Gc_hash;
#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
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
+# 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
+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
+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
+/*
+ * 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;
+}