diff options
author | Jack Lloyd <jack.lloyd@ribose.com> | 2017-10-25 13:19:02 -0400 |
---|---|---|
committer | Ronald Tse <ronald.tse@ribose.com> | 2017-11-06 07:21:11 +0800 |
commit | a0c3e4fa9089f571ff4b406cb914d0a504847b10 (patch) | |
tree | 46bc0fccfcc317d2572145d3a13acf029523973d | |
parent | cf72c7579201086cee303eadcb60bd28eff78dd9 (diff) |
SM3: Add SM3 hash function
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)
-rw-r--r-- | CHANGES | 5 | ||||
-rwxr-xr-x | Configure | 3 | ||||
-rw-r--r-- | INSTALL | 6 | ||||
-rwxr-xr-x | config | 2 | ||||
-rw-r--r-- | crypto/evp/build.info | 2 | ||||
-rw-r--r-- | crypto/evp/c_alld.c | 3 | ||||
-rw-r--r-- | crypto/evp/m_sm3.c | 55 | ||||
-rw-r--r-- | crypto/objects/obj_dat.h | 20 | ||||
-rw-r--r-- | crypto/objects/obj_mac.num | 2 | ||||
-rw-r--r-- | crypto/objects/objects.txt | 3 | ||||
-rw-r--r-- | crypto/sm3/build.info | 2 | ||||
-rw-r--r-- | crypto/sm3/sm3.c | 215 | ||||
-rw-r--r-- | crypto/sm3/sm3_locl.h | 79 | ||||
-rw-r--r-- | doc/man3/SM3.pod | 76 | ||||
-rw-r--r-- | include/openssl/evp.h | 3 | ||||
-rw-r--r-- | include/openssl/obj_mac.h | 10 | ||||
-rw-r--r-- | include/openssl/sm3.h | 47 | ||||
-rw-r--r-- | test/recipes/30-test_evp_data/evpdigest.txt | 39 | ||||
-rw-r--r-- | util/libcrypto.num | 5 | ||||
-rwxr-xr-x | util/mkdef.pl | 2 |
20 files changed, 567 insertions, 12 deletions
@@ -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ń @@ -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", @@ -512,9 +512,9 @@ 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 @@ -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 diff --git a/crypto/evp/build.info b/crypto/evp/build.info index 0305738011..96b44efbfb 100644 --- a/crypto/evp/build.info +++ b/crypto/evp/build.info @@ -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 \ diff --git a/crypto/evp/c_alld.c b/crypto/evp/c_alld.c index 088f65cd80..257d405ba7 100644 --- a/crypto/evp/c_alld.c +++ b/crypto/evp/c_alld.c @@ -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 index 0000000000..21ee1de136 --- /dev/null +++ b/crypto/evp/m_sm3.c @@ -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 + diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h index 866fa34cc1..535d315037 100644 --- a/crypto/objects/obj_dat.h +++ b/crypto/objects/obj_dat.h @@ -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 */ diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num index 4e5f702c29..83641c451e 100644 --- a/crypto/objects/obj_mac.num +++ b/crypto/objects/obj_mac.num @@ -1140,3 +1140,5 @@ sm4_ctr 1139 ISO_CN 1140 oscca 1141 sm_scheme 1142 +sm3 1143 +sm3WithRSAEncryption 1144 diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt index 22e69b8f1c..bbef44e6aa 100644 --- a/crypto/objects/objects.txt +++ b/crypto/objects/objects.txt @@ -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 index 0000000000..239ac8755e --- /dev/null +++ b/crypto/sm3/build.info @@ -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 index 0000000000..615fcb21cd --- /dev/null +++ b/crypto/sm3/sm3.c @@ -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 index 0000000000..598c80aa1d --- /dev/null +++ b/crypto/sm3/sm3_locl.h @@ -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 index 0000000000..afa7082618 --- /dev/null +++ b/doc/man3/SM3.pod @@ -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 diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 3a98e1da9e..e002d63d24 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -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); diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h index 02447dcd50..8a9e25284c 100644 --- a/include/openssl/obj_mac.h +++ b/include/openssl/obj_mac.h @@ -1132,6 +1132,16 @@ #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 index 0000000000..84f8570235 --- /dev/null +++ b/include/openssl/sm3.h @@ -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 diff --git a/test/recipes/30-test_evp_data/evpdigest.txt b/test/recipes/30-test_evp_data/evpdigest.txt index 456358eaa2..d01ff6481a 100644 --- a/test/recipes/30-test_evp_data/evpdigest.txt +++ b/test/recipes/30-test_evp_data/evpdigest.txt @@ -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 |