SM3: Add SM3 hash function
authorJack Lloyd <jack.lloyd@ribose.com>
Wed, 25 Oct 2017 17:19:02 +0000 (13:19 -0400)
committerRonald Tse <ronald.tse@ribose.com>
Sun, 5 Nov 2017 23:21:11 +0000 (07:21 +0800)
SM3 is a secure hash function which is part of the Chinese
"Commercial Cryptography" suite of algorithms which use is
required for certain commercial applications in China.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/4616)

20 files changed:
CHANGES
Configure
INSTALL
config
crypto/evp/build.info
crypto/evp/c_alld.c
crypto/evp/m_sm3.c [new file with mode: 0644]
crypto/objects/obj_dat.h
crypto/objects/obj_mac.num
crypto/objects/objects.txt
crypto/sm3/build.info [new file with mode: 0644]
crypto/sm3/sm3.c [new file with mode: 0644]
crypto/sm3/sm3_locl.h [new file with mode: 0644]
doc/man3/SM3.pod [new file with mode: 0644]
include/openssl/evp.h
include/openssl/obj_mac.h
include/openssl/sm3.h [new file with mode: 0644]
test/recipes/30-test_evp_data/evpdigest.txt
util/libcrypto.num
util/mkdef.pl

diff --git a/CHANGES b/CHANGES
index 71c700c..c35990e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,11 @@
 
  Changes between 1.1.0f and 1.1.1 [xx XXX xxxx]
 
+  *) Add SM3 implemented according to GB/T 32905-2016
+     [ Jack Lloyd <jack.lloyd@ribose.com>,
+       Ronald Tse <ronald.tse@ribose.com>,
+       Erick Borsboom <erick.borsboom@ribose.com> ]
+
   *) Add 'Maximum Fragment Length' TLS extension negotiation and support
      as documented in RFC6066.
      Based on a patch from Tomasz Moń
index 247f276..3821741 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -307,7 +307,7 @@ $config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "
 # crypto/ subdirectories to build
 $config{sdirs} = [
     "objects",
-    "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2", "siphash",
+    "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2", "siphash", "sm3",
     "des", "aes", "rc2", "rc4", "rc5", "idea", "aria", "bf", "cast", "camellia", "seed", "sm4", "chacha", "modes",
     "bn", "ec", "rsa", "dsa", "dh", "dso", "engine",
     "buffer", "bio", "stack", "lhash", "rand", "err",
@@ -394,6 +394,7 @@ my @disablables = (
     "seed",
     "shared",
     "siphash",
+    "sm3",
     "sm4",
     "sock",
     "srp",
diff --git a/INSTALL b/INSTALL
index c4fcc05..4e954e3 100644 (file)
--- a/INSTALL
+++ b/INSTALL
                    Build without support for the specified algorithm, where
                    <alg> is one of: bf, blake2, camellia, cast, chacha, cmac,
                    des, dh, dsa, ecdh, ecdsa, idea, md4, mdc2, ocb, poly1305,
-                   rc2, rc4, rmd160, scrypt, seed, siphash, sm4 or whirlpool.
-                   The "ripemd" algorithm is deprecated and if used is
-                   synonymous with rmd160.
+                                  rc2, rc4, rmd160, scrypt, seed, siphash, sm3, sm4 or
+                                  whirlpool.  The "ripemd" algorithm is deprecated and if used
+                                  is synonymous with rmd160.
 
   -Dxxx, lxxx, -Lxxx, -Wl, -rpath, -R, -framework, -static
                    These system specific options will be recognised and
diff --git a/config b/config
index 14d735c..a341af2 100755 (executable)
--- a/config
+++ b/config
@@ -848,7 +848,7 @@ case "$GUESSOS" in
   i386-*) options="$options 386" ;;
 esac
 
-for i in aes aria bf camellia cast des dh dsa ec hmac idea md2 md5 mdc2 rc2 rc4 rc5 ripemd rsa seed sm4 sha
+for i in aes aria bf camellia cast des dh dsa ec hmac idea md2 md5 mdc2 rc2 rc4 rc5 ripemd rsa seed sha sm3 sm4
 do
   if [ ! -d $THERE/crypto/$i ]
   then
index 0305738..96b44ef 100644 (file)
@@ -5,7 +5,7 @@ SOURCE[../../libcrypto]=\
         e_rc4.c e_aes.c names.c e_seed.c e_aria.c e_sm4.c \
         e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c \
         m_null.c m_md2.c m_md4.c m_md5.c m_sha1.c m_wp.c \
-        m_md5_sha1.c m_mdc2.c m_ripemd.c m_sha3.c \
+        m_md5_sha1.c m_mdc2.c m_ripemd.c m_sha3.c m_sm3.c \
         p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \
         bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \
         c_allc.c c_alld.c evp_lib.c bio_ok.c \
index 088f65c..257d405 100644 (file)
@@ -42,6 +42,9 @@ void openssl_add_all_digests_int(void)
 #ifndef OPENSSL_NO_WHIRLPOOL
     EVP_add_digest(EVP_whirlpool());
 #endif
+#ifndef OPENSSL_NO_SM3
+    EVP_add_digest(EVP_sm3());
+#endif
 #ifndef OPENSSL_NO_BLAKE2
     EVP_add_digest(EVP_blake2b512());
     EVP_add_digest(EVP_blake2s256());
diff --git a/crypto/evp/m_sm3.c b/crypto/evp/m_sm3.c
new file mode 100644 (file)
index 0000000..21ee1de
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017 Ribose Inc. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+
+#ifndef OPENSSL_NO_SM3
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/sm3.h>
+# include "internal/evp_int.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+    return SM3_Init(EVP_MD_CTX_md_data(ctx));
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    return SM3_Update(EVP_MD_CTX_md_data(ctx), data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+    return SM3_Final(md, EVP_MD_CTX_md_data(ctx));
+}
+
+static const EVP_MD sm3_md = {
+    NID_sm3,
+    NID_sm3WithRSAEncryption,
+    SM3_DIGEST_LENGTH,
+    0,
+    init,
+    update,
+    final,
+    NULL,
+    NULL,
+    SM3_CBLOCK,
+    sizeof(EVP_MD *) + sizeof(SM3_CTX),
+};
+
+const EVP_MD *EVP_sm3(void)
+{
+    return &sm3_md;
+}
+#endif
+
index 866fa34..535d315 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /* Serialized OID's */
-static const unsigned char so[7308] = {
+static const unsigned char so[7324] = {
     0x2A,0x86,0x48,0x86,0xF7,0x0D,                 /* [    0] OBJ_rsadsi */
     0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,            /* [    6] OBJ_pkcs */
     0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02,       /* [   13] OBJ_md2 */
@@ -1028,9 +1028,11 @@ static const unsigned char so[7308] = {
     0x2A,0x81,0x1C,                                /* [ 7293] OBJ_ISO_CN */
     0x2A,0x81,0x1C,0xCF,0x55,                      /* [ 7296] OBJ_oscca */
     0x2A,0x81,0x1C,0xCF,0x55,0x01,                 /* [ 7301] OBJ_sm_scheme */
+    0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x11,       /* [ 7307] OBJ_sm3 */
+    0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x78,       /* [ 7315] OBJ_sm3WithRSAEncryption */
 };
 
-#define NUM_NID 1143
+#define NUM_NID 1145
 static const ASN1_OBJECT nid_objs[NUM_NID] = {
     {"UNDEF", "undefined", NID_undef},
     {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
@@ -2175,9 +2177,11 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
     {"ISO-CN", "ISO CN Member Body", NID_ISO_CN, 3, &so[7293]},
     {"oscca", "oscca", NID_oscca, 5, &so[7296]},
     {"sm-scheme", "sm-scheme", NID_sm_scheme, 6, &so[7301]},
+    {"SM3", "sm3", NID_sm3, 8, &so[7307]},
+    {"RSA-SM3", "sm3WithRSAEncryption", NID_sm3WithRSAEncryption, 8, &so[7315]},
 };
 
-#define NUM_SN 1134
+#define NUM_SN 1136
 static const unsigned int sn_objs[NUM_SN] = {
      364,    /* "AD_DVCS" */
      419,    /* "AES-128-CBC" */
@@ -2418,6 +2422,7 @@ static const unsigned int sn_objs[NUM_SN] = {
      668,    /* "RSA-SHA256" */
      669,    /* "RSA-SHA384" */
      670,    /* "RSA-SHA512" */
+    1144,    /* "RSA-SM3" */
      919,    /* "RSAES-OAEP" */
      912,    /* "RSASSA-PSS" */
      777,    /* "SEED-CBC" */
@@ -2438,6 +2443,7 @@ static const unsigned int sn_objs[NUM_SN] = {
     1095,    /* "SHA512-256" */
     1100,    /* "SHAKE128" */
     1101,    /* "SHAKE256" */
+    1143,    /* "SM3" */
     1134,    /* "SM4-CBC" */
     1137,    /* "SM4-CFB" */
     1136,    /* "SM4-CFB1" */
@@ -3315,7 +3321,7 @@ static const unsigned int sn_objs[NUM_SN] = {
     1093,    /* "x509ExtAdmission" */
 };
 
-#define NUM_LN 1134
+#define NUM_LN 1136
 static const unsigned int ln_objs[NUM_LN] = {
      363,    /* "AD Time Stamping" */
      405,    /* "ANSI X9.62" */
@@ -4399,6 +4405,8 @@ static const unsigned int ln_objs[NUM_LN] = {
      496,    /* "singleLevelQuality" */
     1062,    /* "siphash" */
     1142,    /* "sm-scheme" */
+    1143,    /* "sm3" */
+    1144,    /* "sm3WithRSAEncryption" */
     1134,    /* "sm4-cbc" */
     1137,    /* "sm4-cfb" */
     1136,    /* "sm4-cfb1" */
@@ -4453,7 +4461,7 @@ static const unsigned int ln_objs[NUM_LN] = {
      125,    /* "zlib compression" */
 };
 
-#define NUM_OBJ 1023
+#define NUM_OBJ 1025
 static const unsigned int obj_objs[NUM_OBJ] = {
        0,    /* OBJ_undef                        0 */
      181,    /* OBJ_iso                          1 */
@@ -4915,6 +4923,8 @@ static const unsigned int obj_objs[NUM_OBJ] = {
     1136,    /* OBJ_sm4_cfb1                     1 2 156 10197 1 104 5 */
     1138,    /* OBJ_sm4_cfb8                     1 2 156 10197 1 104 6 */
     1139,    /* OBJ_sm4_ctr                      1 2 156 10197 1 104 7 */
+    1143,    /* OBJ_sm3                          1 2 156 10197 1 401 */
+    1144,    /* OBJ_sm3WithRSAEncryption         1 2 156 10197 1 504 */
      776,    /* OBJ_seed_ecb                     1 2 410 200004 1 3 */
      777,    /* OBJ_seed_cbc                     1 2 410 200004 1 4 */
      779,    /* OBJ_seed_cfb128                  1 2 410 200004 1 5 */
index 4e5f702..83641c4 100644 (file)
@@ -1140,3 +1140,5 @@ sm4_ctr           1139
 ISO_CN         1140
 oscca          1141
 sm_scheme              1142
+sm3            1143
+sm3WithRSAEncryption           1144
index 22e69b8..bbef44e 100644 (file)
@@ -371,6 +371,9 @@ rsadsi 2 5          : MD5                   : md5
 rsadsi 2 6             :                       : hmacWithMD5
 rsadsi 2 7             :                       : hmacWithSHA1
 
+member-body 156 10197 1 401 : SM3               : sm3
+member-body 156 10197 1 504 : RSA-SM3          : sm3WithRSAEncryption
+
 # From RFC4231
 rsadsi 2 8             :                       : hmacWithSHA224
 rsadsi 2 9             :                       : hmacWithSHA256
diff --git a/crypto/sm3/build.info b/crypto/sm3/build.info
new file mode 100644 (file)
index 0000000..239ac87
--- /dev/null
@@ -0,0 +1,2 @@
+LIBS=../../libcrypto
+SOURCE[../../libcrypto]=sm3.c
diff --git a/crypto/sm3/sm3.c b/crypto/sm3/sm3.c
new file mode 100644 (file)
index 0000000..615fcb2
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017 Ribose Inc. All Rights Reserved.
+ * Ported from Ribose contributions from Botan.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+
+#ifndef OPENSSL_NO_SM3
+
+#include "sm3_locl.h"
+#include <openssl/opensslv.h>
+
+int SM3_Init(SM3_CTX *c)
+{
+    memset(c, 0, sizeof(*c));
+    c->A = SM3_A;
+    c->B = SM3_B;
+    c->C = SM3_C;
+    c->D = SM3_D;
+    c->E = SM3_E;
+    c->F = SM3_F;
+    c->G = SM3_G;
+    c->H = SM3_H;
+    return 1;
+}
+
+unsigned char *SM3(const unsigned char *d, size_t n, unsigned char *md)
+{
+    SM3_CTX c;
+    static unsigned char m[SM3_DIGEST_LENGTH];
+
+    if (md == NULL)
+        md = m;
+    if (!SM3_Init(&c))
+        return NULL;
+    SM3_Update(&c, d, n);
+    SM3_Final(md, &c);
+    OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */
+    return md;
+}
+
+void sm3_block_data_order(SM3_CTX *ctx, const void *p, size_t num)
+{
+    const unsigned char *data = p;
+    register unsigned MD32_REG_T A, B, C, D, E, F, G, H;
+
+    unsigned MD32_REG_T W00, W01, W02, W03, W04, W05, W06, W07,
+        W08, W09, W10, W11, W12, W13, W14, W15;
+
+    for (; num--;) {
+
+        A = ctx->A;
+        B = ctx->B;
+        C = ctx->C;
+        D = ctx->D;
+        E = ctx->E;
+        F = ctx->F;
+        G = ctx->G;
+        H = ctx->H;
+
+        /*
+        * We have to load all message bytes immediately since SM3 reads
+        * them slightly out of order.
+        */
+        (void)HOST_c2l(data, W00);
+        (void)HOST_c2l(data, W01);
+        (void)HOST_c2l(data, W02);
+        (void)HOST_c2l(data, W03);
+        (void)HOST_c2l(data, W04);
+        (void)HOST_c2l(data, W05);
+        (void)HOST_c2l(data, W06);
+        (void)HOST_c2l(data, W07);
+        (void)HOST_c2l(data, W08);
+        (void)HOST_c2l(data, W09);
+        (void)HOST_c2l(data, W10);
+        (void)HOST_c2l(data, W11);
+        (void)HOST_c2l(data, W12);
+        (void)HOST_c2l(data, W13);
+        (void)HOST_c2l(data, W14);
+        (void)HOST_c2l(data, W15);
+
+        R1(A, B, C, D, E, F, G, H, 0x79CC4519, W00, W00 ^ W04);
+        W00 = EXPAND(W00, W07, W13, W03, W10);
+        R1(D, A, B, C, H, E, F, G, 0xF3988A32, W01, W01 ^ W05);
+        W01 = EXPAND(W01, W08, W14, W04, W11);
+        R1(C, D, A, B, G, H, E, F, 0xE7311465, W02, W02 ^ W06);
+        W02 = EXPAND(W02, W09, W15, W05, W12);
+        R1(B, C, D, A, F, G, H, E, 0xCE6228CB, W03, W03 ^ W07);
+        W03 = EXPAND(W03, W10, W00, W06, W13);
+        R1(A, B, C, D, E, F, G, H, 0x9CC45197, W04, W04 ^ W08);
+        W04 = EXPAND(W04, W11, W01, W07, W14);
+        R1(D, A, B, C, H, E, F, G, 0x3988A32F, W05, W05 ^ W09);
+        W05 = EXPAND(W05, W12, W02, W08, W15);
+        R1(C, D, A, B, G, H, E, F, 0x7311465E, W06, W06 ^ W10);
+        W06 = EXPAND(W06, W13, W03, W09, W00);
+        R1(B, C, D, A, F, G, H, E, 0xE6228CBC, W07, W07 ^ W11);
+        W07 = EXPAND(W07, W14, W04, W10, W01);
+        R1(A, B, C, D, E, F, G, H, 0xCC451979, W08, W08 ^ W12);
+        W08 = EXPAND(W08, W15, W05, W11, W02);
+        R1(D, A, B, C, H, E, F, G, 0x988A32F3, W09, W09 ^ W13);
+        W09 = EXPAND(W09, W00, W06, W12, W03);
+        R1(C, D, A, B, G, H, E, F, 0x311465E7, W10, W10 ^ W14);
+        W10 = EXPAND(W10, W01, W07, W13, W04);
+        R1(B, C, D, A, F, G, H, E, 0x6228CBCE, W11, W11 ^ W15);
+        W11 = EXPAND(W11, W02, W08, W14, W05);
+        R1(A, B, C, D, E, F, G, H, 0xC451979C, W12, W12 ^ W00);
+        W12 = EXPAND(W12, W03, W09, W15, W06);
+        R1(D, A, B, C, H, E, F, G, 0x88A32F39, W13, W13 ^ W01);
+        W13 = EXPAND(W13, W04, W10, W00, W07);
+        R1(C, D, A, B, G, H, E, F, 0x11465E73, W14, W14 ^ W02);
+        W14 = EXPAND(W14, W05, W11, W01, W08);
+        R1(B, C, D, A, F, G, H, E, 0x228CBCE6, W15, W15 ^ W03);
+        W15 = EXPAND(W15, W06, W12, W02, W09);
+        R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04);
+        W00 = EXPAND(W00, W07, W13, W03, W10);
+        R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05);
+        W01 = EXPAND(W01, W08, W14, W04, W11);
+        R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06);
+        W02 = EXPAND(W02, W09, W15, W05, W12);
+        R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07);
+        W03 = EXPAND(W03, W10, W00, W06, W13);
+        R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08);
+        W04 = EXPAND(W04, W11, W01, W07, W14);
+        R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09);
+        W05 = EXPAND(W05, W12, W02, W08, W15);
+        R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10);
+        W06 = EXPAND(W06, W13, W03, W09, W00);
+        R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11);
+        W07 = EXPAND(W07, W14, W04, W10, W01);
+        R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12);
+        W08 = EXPAND(W08, W15, W05, W11, W02);
+        R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13);
+        W09 = EXPAND(W09, W00, W06, W12, W03);
+        R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14);
+        W10 = EXPAND(W10, W01, W07, W13, W04);
+        R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15);
+        W11 = EXPAND(W11, W02, W08, W14, W05);
+        R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00);
+        W12 = EXPAND(W12, W03, W09, W15, W06);
+        R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01);
+        W13 = EXPAND(W13, W04, W10, W00, W07);
+        R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02);
+        W14 = EXPAND(W14, W05, W11, W01, W08);
+        R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03);
+        W15 = EXPAND(W15, W06, W12, W02, W09);
+        R2(A, B, C, D, E, F, G, H, 0x7A879D8A, W00, W00 ^ W04);
+        W00 = EXPAND(W00, W07, W13, W03, W10);
+        R2(D, A, B, C, H, E, F, G, 0xF50F3B14, W01, W01 ^ W05);
+        W01 = EXPAND(W01, W08, W14, W04, W11);
+        R2(C, D, A, B, G, H, E, F, 0xEA1E7629, W02, W02 ^ W06);
+        W02 = EXPAND(W02, W09, W15, W05, W12);
+        R2(B, C, D, A, F, G, H, E, 0xD43CEC53, W03, W03 ^ W07);
+        W03 = EXPAND(W03, W10, W00, W06, W13);
+        R2(A, B, C, D, E, F, G, H, 0xA879D8A7, W04, W04 ^ W08);
+        W04 = EXPAND(W04, W11, W01, W07, W14);
+        R2(D, A, B, C, H, E, F, G, 0x50F3B14F, W05, W05 ^ W09);
+        W05 = EXPAND(W05, W12, W02, W08, W15);
+        R2(C, D, A, B, G, H, E, F, 0xA1E7629E, W06, W06 ^ W10);
+        W06 = EXPAND(W06, W13, W03, W09, W00);
+        R2(B, C, D, A, F, G, H, E, 0x43CEC53D, W07, W07 ^ W11);
+        W07 = EXPAND(W07, W14, W04, W10, W01);
+        R2(A, B, C, D, E, F, G, H, 0x879D8A7A, W08, W08 ^ W12);
+        W08 = EXPAND(W08, W15, W05, W11, W02);
+        R2(D, A, B, C, H, E, F, G, 0x0F3B14F5, W09, W09 ^ W13);
+        W09 = EXPAND(W09, W00, W06, W12, W03);
+        R2(C, D, A, B, G, H, E, F, 0x1E7629EA, W10, W10 ^ W14);
+        W10 = EXPAND(W10, W01, W07, W13, W04);
+        R2(B, C, D, A, F, G, H, E, 0x3CEC53D4, W11, W11 ^ W15);
+        W11 = EXPAND(W11, W02, W08, W14, W05);
+        R2(A, B, C, D, E, F, G, H, 0x79D8A7A8, W12, W12 ^ W00);
+        W12 = EXPAND(W12, W03, W09, W15, W06);
+        R2(D, A, B, C, H, E, F, G, 0xF3B14F50, W13, W13 ^ W01);
+        W13 = EXPAND(W13, W04, W10, W00, W07);
+        R2(C, D, A, B, G, H, E, F, 0xE7629EA1, W14, W14 ^ W02);
+        W14 = EXPAND(W14, W05, W11, W01, W08);
+        R2(B, C, D, A, F, G, H, E, 0xCEC53D43, W15, W15 ^ W03);
+        W15 = EXPAND(W15, W06, W12, W02, W09);
+        R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04);
+        W00 = EXPAND(W00, W07, W13, W03, W10);
+        R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05);
+        W01 = EXPAND(W01, W08, W14, W04, W11);
+        R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06);
+        W02 = EXPAND(W02, W09, W15, W05, W12);
+        R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07);
+        W03 = EXPAND(W03, W10, W00, W06, W13);
+        R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08);
+        R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09);
+        R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10);
+        R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11);
+        R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12);
+        R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13);
+        R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14);
+        R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15);
+        R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00);
+        R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01);
+        R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02);
+        R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03);
+
+        ctx->A ^= A;
+        ctx->B ^= B;
+        ctx->C ^= C;
+        ctx->D ^= D;
+        ctx->E ^= E;
+        ctx->F ^= F;
+        ctx->G ^= G;
+        ctx->H ^= H;
+    }
+}
+#endif
diff --git a/crypto/sm3/sm3_locl.h b/crypto/sm3/sm3_locl.h
new file mode 100644 (file)
index 0000000..598c80a
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017 Ribose Inc. All Rights Reserved.
+ * Ported from Ribose contributions from Botan.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/e_os2.h>
+#include <openssl/sm3.h>
+
+void sm3_block_data_order(SM3_CTX *c, const void *p, size_t num);
+
+#define DATA_ORDER_IS_BIG_ENDIAN
+
+#define HASH_LONG               SM3_WORD
+#define HASH_CTX                SM3_CTX
+#define HASH_CBLOCK             SM3_CBLOCK
+#define HASH_UPDATE             SM3_Update
+#define HASH_TRANSFORM          SM3_Transform
+#define HASH_FINAL              SM3_Final
+#define HASH_MAKE_STRING(c,s)   do {    \
+        unsigned long ll;               \
+        ll=(c)->A; (void)HOST_l2c(ll,(s));      \
+        ll=(c)->B; (void)HOST_l2c(ll,(s));      \
+        ll=(c)->C; (void)HOST_l2c(ll,(s));      \
+        ll=(c)->D; (void)HOST_l2c(ll,(s));      \
+        ll=(c)->E; (void)HOST_l2c(ll,(s));      \
+        ll=(c)->F; (void)HOST_l2c(ll,(s));      \
+        ll=(c)->G; (void)HOST_l2c(ll,(s));      \
+        ll=(c)->H; (void)HOST_l2c(ll,(s));      \
+        } while (0)
+#define HASH_BLOCK_DATA_ORDER   sm3_block_data_order
+
+#include "internal/md32_common.h"
+
+#define P0(X) (X ^ ROTATE(X, 9) ^ ROTATE(X, 17))
+#define P1(X) (X ^ ROTATE(X, 15) ^ ROTATE(X, 23))
+
+#define FF0(X,Y,Z) (X ^ Y ^ Z)
+#define GG0(X,Y,Z) (X ^ Y ^ Z)
+
+#define FF1(X,Y,Z) ((X & Y) | ((X | Y) & Z))
+#define GG1(X,Y,Z) ((Z ^ (X & (Y ^ Z))))
+
+#define EXPAND(W0,W7,W13,W3,W10) \
+   (P1(W0 ^ W7 ^ ROTATE(W13, 15)) ^ ROTATE(W3, 7) ^ W10)
+
+#define RND(A,B,C,D,E,F,G,H,TJ,Wi,Wj,FF,GG) do {                      \
+   const SM3_WORD A12 = ROTATE(A, 12);                                \
+   const SM3_WORD A12_SM = A12 + E + TJ;                              \
+   const SM3_WORD SS1 = ROTATE(A12_SM, 7);                            \
+   const SM3_WORD TT1 = FF(A,B,C) + D + (SS1 ^ A12) + (Wj);           \
+   const SM3_WORD TT2 = GG(E,F,G) + H + SS1 + Wi;                     \
+   B = ROTATE(B, 9);                                                  \
+   D = TT1;                                                           \
+   F = ROTATE(F, 19);                                                 \
+   H = P0(TT2);                                                       \
+   } while(0);
+
+#define R1(A,B,C,D,E,F,G,H,TJ,Wi,Wj) \
+   RND(A,B,C,D,E,F,G,H,TJ,Wi,Wj,FF0,GG0)
+
+#define R2(A,B,C,D,E,F,G,H,TJ,Wi,Wj) \
+   RND(A,B,C,D,E,F,G,H,TJ,Wi,Wj,FF1,GG1)
+
+#define SM3_A 0x7380166fUL
+#define SM3_B 0x4914b2b9UL
+#define SM3_C 0x172442d7UL
+#define SM3_D 0xda8a0600UL
+#define SM3_E 0xa96f30bcUL
+#define SM3_F 0x163138aaUL
+#define SM3_G 0xe38dee4dUL
+#define SM3_H 0xb0fb0e4eUL
diff --git a/doc/man3/SM3.pod b/doc/man3/SM3.pod
new file mode 100644 (file)
index 0000000..afa7082
--- /dev/null
@@ -0,0 +1,76 @@
+=pod
+
+=head1 NAME
+
+SM3_Init,
+SM3_Update,
+SM3_Final
+
+=head1 SYNOPSIS
+
+ #include <openssl/sm3.h>
+
+ unsigned char *SM3(const unsigned char *d, size_t n, unsigned char *md);
+
+ int SM3_Init(SM3_CTX *c);
+ int SM3_Update(SM3_CTX *c, const void *data, size_t len);
+ int SM3_Final(unsigned char *md, SM3_CTX *c);
+
+=head1 DESCRIPTION
+
+SM3 is a cryptographic hash function with a 256-bit output, defined in GB/T
+32905-2016.
+
+SM3() computes the SM3 message digest of the B<n> bytes at B<d> and places it
+in B<md> (which must have space for SM3_DIGEST_LENGTH == 32 bytes of output).
+If B<md> is NULL, the digest is placed in a static array.
+
+The following functions may be used if the message is not completely stored in
+memory:
+
+SM3_Init() initializes a B<SM3_CTX> structure.
+
+SM3_Update() can be called repeatedly with chunks of the message to be hashed
+(B<len> bytes at B<data>).
+
+SM3_Final() places the message digest in B<md>, which must have space for
+B<SM3_DIGEST_LENGTH> == 32 bytes of output, and erases the B<SM3_CTX>.
+
+=head1 RETURN VALUES
+
+=over 4
+
+=item SM3()
+
+Returns pointers to the hash value.
+
+=item SM3_Init(), SM3_Update(), SM3_Final()
+
+Returns 1 for success, 0 otherwise.
+
+=back
+
+=head1 NOTE
+
+Applications should use the higher level functions such as L<EVP_DigestInit(3)>
+instead of calling these functions directly.
+
+=head1 CONFORMING TO
+
+GB/T 32905-2016 and GM/T 0004-2012.
+
+=head1 SEE ALSO
+
+L<EVP_DigestInit(3)>
+
+=head1 COPYRIGHT
+
+Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2017 Ribose Inc. All Rights Reserved.
+
+Licensed under the OpenSSL license (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
index 3a98e1d..e002d63 100644 (file)
@@ -717,6 +717,9 @@ const EVP_MD *EVP_ripemd160(void);
 # ifndef OPENSSL_NO_WHIRLPOOL
 const EVP_MD *EVP_whirlpool(void);
 # endif
+# ifndef OPENSSL_NO_SM3
+const EVP_MD *EVP_sm3(void);
+# endif
 const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */
 # ifndef OPENSSL_NO_DES
 const EVP_CIPHER *EVP_des_ecb(void);
index 02447dc..8a9e252 100644 (file)
 #define NID_hmacWithSHA1                163
 #define OBJ_hmacWithSHA1                OBJ_rsadsi,2L,7L
 
+#define SN_sm3          "SM3"
+#define LN_sm3          "sm3"
+#define NID_sm3         1143
+#define OBJ_sm3         OBJ_member_body,156L,10197L,1L,401L
+
+#define SN_sm3WithRSAEncryption         "RSA-SM3"
+#define LN_sm3WithRSAEncryption         "sm3WithRSAEncryption"
+#define NID_sm3WithRSAEncryption                1144
+#define OBJ_sm3WithRSAEncryption                OBJ_member_body,156L,10197L,1L,504L
+
 #define LN_hmacWithSHA224               "hmacWithSHA224"
 #define NID_hmacWithSHA224              798
 #define OBJ_hmacWithSHA224              OBJ_rsadsi,2L,8L
diff --git a/include/openssl/sm3.h b/include/openssl/sm3.h
new file mode 100644 (file)
index 0000000..84f8570
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017 [Ribose Inc.](https://www.ribose.com). All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_SM3_H
+# define HEADER_SM3_H
+
+# include <openssl/opensslconf.h>
+
+# ifdef OPENSSL_NO_SM3
+#  error SM3 is disabled.
+# endif
+
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+#define SM3_DIGEST_LENGTH 32
+#define SM3_WORD unsigned int
+
+# define SM3_CBLOCK      64
+# define SM3_LBLOCK      (SM3_CBLOCK/4)
+
+typedef struct SM3state_st {
+   SM3_WORD A, B, C, D, E, F, G, H;
+   SM3_WORD Nl, Nh;
+   SM3_WORD data[SM3_LBLOCK];
+   unsigned int num;
+} SM3_CTX;
+
+int SM3_Init(SM3_CTX *c);
+int SM3_Update(SM3_CTX *c, const void *data, size_t len);
+int SM3_Final(unsigned char *md, SM3_CTX *c);
+void SM3_Transform(SM3_CTX *c, const unsigned char *data);
+unsigned char *SM3(const unsigned char *d, size_t n, unsigned char *md);
+
+# ifdef  __cplusplus
+}
+# endif
+
+#endif
index 456358e..d01ff64 100644 (file)
@@ -431,3 +431,42 @@ Output = b9b92544fb25cfe4ec6fe437d8da2bbe00f7bdaface3de97b8775a44d753c3adca3f7c6
 Digest = SHAKE256
 Input = 8d8001e2c096f1b88e7c9224a086efd4797fbf74a8033a2d422a2b6b8f6747e4
 Output = 2e975f6a8a14f0704d51b13667d8195c219f71e6345696c49fa4b9d08e9225d3d39393425152c97e71dd24601c11abcfa0f12f53c680bd3ae757b8134a9c10d429615869217fdd5885c4db174985703a6d6de94a667eac3023443a8337ae1bc601b76d7d38ec3c34463105f0d3949d78e562a039e4469548b609395de5a4fd43c46ca9fd6ee29ada5efc07d84d553249450dab4a49c483ded250c9338f85cd937ae66bb436f3b4026e859fda1ca571432f3bfc09e7c03ca4d183b741111ca0483d0edabc03feb23b17ee48e844ba2408d9dcfd0139d2e8c7310125aee801c61ab7900d1efc47c078281766f361c5e6111346235e1dc38325666c
+
+Title = SM3 Tests
+
+# From https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02
+
+Digest = SM3
+Input = 0090414C494345313233405941484F4F2E434F4D787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E49863E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A20AE4C7798AA0F119471BEE11825BE46202BB79E2A5844495E97C04FF4DF2548A7C0240F88F1CD4E16352A73C17B7F16F07353E53A176D684A9FE0C6BB798E857
+Output = F4A38489E32B45B6F876E3AC2168CA392362DC8F23459C1D1146FC3DBFB7BC9A
+
+# From https://tools.ietf.org/html/draft-shen-sm3-hash-01
+Digest = SM3
+Input = 616263
+Output = 66C7F0F462EEEDD9D1F2D46BDC10E4E24167C4875CF2F7A2297DA02B8F4BA8E0
+
+Digest = SM3
+Input = 61626364616263646162636461626364616263646162636461626364616263646162636461626364616263646162636461626364616263646162636461626364
+Output = DEBE9FF92275B8A138604889C18E5A4D6FDB70E5387E5765293dCbA39C0C5732
+
+# From GmSSL test suite
+
+Digest = SM3
+Input = 0090414C494345313233405941484F4F2E434F4D787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E49863E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A20AE4C7798AA0F119471BEE11825BE46202BB79E2A5844495E97C04FF4DF2548A7C0240F88F1CD4E16352A73C17B7F16F07353E53A176D684A9FE0C6BB798E857
+Output = F4A38489E32B45B6F876E3AC2168CA392362DC8F23459C1D1146FC3DBFB7BC9A
+
+Digest = SM3
+Input = 0090414C494345313233405941484F4F2E434F4D00000000000000000000000000000000000000000000000000000000000000000000E78BCD09746C202378A7E72B12BCE00266B9627ECB0B5A25367AD1AD4CC6242B00CDB9CA7F1E6B0441F658343F4B10297C0EF9B6491082400A62E7A7485735FADD013DE74DA65951C4D76DC89220D5F7777A611B1C38BAE260B175951DC8060C2B3E0165961645281A8626607B917F657D7E9382F1EA5CD931F40F6627F357542653B201686522130D590FB8DE635D8FCA715CC6BF3D05BEF3F75DA5D543454448166612
+Output = 26352AF82EC19F207BBC6F9474E11E90CE0F7DDACE03B27F801817E897A81FD5
+
+Digest = SM3
+Input = 0090414C494345313233405941484F4F2E434F4D787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E49863E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A23099093BF3C137D8FCBBCDF4A2AE50F3B0F216C3122D79425FE03A45DBFE16553DF79E8DAC1CF0ECBAA2F2B49D51A4B387F2EFAF482339086A27A8E05BAED98B
+Output = E4D1D0C3CA4C7F11BC8FF8CB3F4C02A78F108FA098E51A668487240F75E20F31
+
+Digest = SM3
+Input = 008842494C4C343536405941484F4F2E434F4D787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E49863E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2245493D446C38D8CC0F118374690E7DF633A8A4BFB3329B5ECE604B2B4F37F4353C0869F4B9E17773DE68FEC45E14904E0DEA45BF6CECF9918C85EA047C60A4C
+Output = 6B4B6D0E276691BD4A11BF72F4FB501AE309FDACB72FA6CC336E6656119ABD67
+
+Digest = SM3
+Input = 4D38D2958CA7FD2CFAE3AF04486959CF92C8EF48E8B83A05C112E739D5F181D03082020CA003020102020900AF28725D98D33143300C06082A811CCF550183750500307D310B300906035504060C02636E310B300906035504080C02626A310B300906035504070C02626A310F300D060355040A0C06746F70736563310F300D060355040B0C06746F707365633111300F06035504030C08546F707365634341311F301D06092A864886F70D0109010C10626A40746F707365632E636F6D2E636E301E170D3132303632343037353433395A170D3332303632303037353433395A307D310B300906035504060C02636E310B300906035504080C02626A310B300906035504070C02626A310F300D060355040A0C06746F70736563310F300D060355040B0C06746F707365633111300F06035504030C08546F707365634341311F301D06092A864886F70D0109010C10626A40746F707365632E636F6D2E636E3059301306072A8648CE3D020106082A811CCF5501822D03420004D69C2F1EEC3BFB6B95B30C28085C77B125D77A9C39525D8190768F37D6B205B589DCD316BBE7D89A9DC21917F17799E698531F5E6E3E10BD31370B259C3F81C3A3733071300F0603551D130101FF040530030101FF301D0603551D0E041604148E5D90347858BAAAD870D8BDFBA6A85E7B563B64301F0603551D230418301680148E5D90347858BAAAD870D8BDFBA6A85E7B563B64300B0603551D0F040403020106301106096086480186F8420101040403020057
+Output = C3B02E500A8B60B77DEDCF6F4C11BEF8D56E5CDE708C72065654FD7B2167915A
index bbaa50b..cf7575d 100644 (file)
@@ -4425,3 +4425,8 @@ EVP_sm4_cbc                             4369      1_1_1   EXIST::FUNCTION:SM4
 EVP_sm4_ofb                             4370   1_1_1   EXIST::FUNCTION:SM4
 EVP_sm4_ecb                             4371   1_1_1   EXIST::FUNCTION:SM4
 EVP_sm4_cfb128                          4372   1_1_1   EXIST::FUNCTION:SM4
+EVP_sm3                                 4373   1_1_1   EXIST::FUNCTION:SM3
+SM3_Update                              4374   1_1_1   EXIST::FUNCTION:SM3
+SM3                                     4375   1_1_1   EXIST::FUNCTION:SM3
+SM3_Init                                4376   1_1_1   EXIST::FUNCTION:SM3
+SM3_Final                               4377   1_1_1   EXIST::FUNCTION:SM3
index 1ca1112..20af2e8 100755 (executable)
@@ -85,7 +85,7 @@ my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF",
                         "MDC2", "WHIRLPOOL", "RSA", "DSA", "DH", "EC", "EC2M",
                         "HMAC", "AES", "CAMELLIA", "SEED", "GOST", "ARIA", "SM4",
                          "SCRYPT", "CHACHA", "POLY1305", "BLAKE2",
-                        "SIPHASH",
+                        "SIPHASH", "SM3",
                         # EC_NISTP_64_GCC_128
                         "EC_NISTP_64_GCC_128",
                         # Envelope "algorithms"