SM4: Add SM4 block cipher to EVP
authorRonald Tse <ronald.tse@ribose.com>
Tue, 31 Oct 2017 05:19:14 +0000 (15:19 +1000)
committerPauli <paul.dale@oracle.com>
Tue, 31 Oct 2017 05:19:14 +0000 (15:19 +1000)
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/4552)

22 files changed:
CHANGES
Configure
INSTALL
config
crypto/evp/build.info
crypto/evp/c_allc.c
crypto/evp/e_sm4.c [new file with mode: 0644]
crypto/include/internal/sm4.h [new file with mode: 0644]
crypto/objects/obj_dat.h
crypto/objects/obj_mac.num
crypto/objects/objects.txt
crypto/sm4/build.info [new file with mode: 0644]
crypto/sm4/sm4.c [new file with mode: 0644]
doc/man3/EVP_sm4.pod [new file with mode: 0644]
include/openssl/evp.h
include/openssl/obj_mac.h
test/build.info
test/recipes/03-test_internal_sm4.t [new file with mode: 0755]
test/recipes/30-test_evp_data/evpciph.txt
test/sm4_internal_test.c [new file with mode: 0644]
util/libcrypto.num
util/mkdef.pl

diff --git a/CHANGES b/CHANGES
index 2e77eb1..9ef85d6 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,11 @@
 
  Changes between 1.1.0f and 1.1.1 [xx XXX xxxx]
 
 
  Changes between 1.1.0f and 1.1.1 [xx XXX xxxx]
 
+  *) Add SM4 implemented according to GB/T 32907-2016.
+     [ Jack Lloyd <jack.lloyd@ribose.com>,
+       Ronald Tse <ronald.tse@ribose.com>,
+       Erick Borsboom <erick.borsboom@ribose.com> ]
+
   *) Reimplement -newreq-nodes and ERR_error_string_n; the
      original author does not agree with the license change.
      [Rich Salz]
   *) Reimplement -newreq-nodes and ERR_error_string_n; the
      original author does not agree with the license change.
      [Rich Salz]
index b1b847c..247f276 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -308,7 +308,7 @@ $config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "
 $config{sdirs} = [
     "objects",
     "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2", "siphash",
 $config{sdirs} = [
     "objects",
     "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2", "siphash",
-    "des", "aes", "rc2", "rc4", "rc5", "idea", "aria", "bf", "cast", "camellia", "seed", "chacha", "modes",
+    "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",
     "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui",
     "bn", "ec", "rsa", "dsa", "dh", "dso", "engine",
     "buffer", "bio", "stack", "lhash", "rand", "err",
     "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui",
@@ -394,6 +394,7 @@ my @disablables = (
     "seed",
     "shared",
     "siphash",
     "seed",
     "shared",
     "siphash",
+    "sm4",
     "sock",
     "srp",
     "srtp",
     "sock",
     "srp",
     "srtp",
diff --git a/INSTALL b/INSTALL
index 064b2f8..c4fcc05 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,
                    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 or whirlpool. The
-                   "ripemd" algorithm is deprecated and if used is synonymous
-                   with rmd160.
+                   rc2, rc4, rmd160, scrypt, seed, siphash, 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
 
   -Dxxx, lxxx, -Lxxx, -Wl, -rpath, -R, -framework, -static
                    These system specific options will be recognised and
diff --git a/config b/config
index 6c01ebd..14d735c 100755 (executable)
--- a/config
+++ b/config
@@ -848,7 +848,7 @@ case "$GUESSOS" in
   i386-*) options="$options 386" ;;
 esac
 
   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 sha
+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
 do
   if [ ! -d $THERE/crypto/$i ]
   then
 do
   if [ ! -d $THERE/crypto/$i ]
   then
index d65276a..0305738 100644 (file)
@@ -2,7 +2,7 @@ LIBS=../../libcrypto
 SOURCE[../../libcrypto]=\
         encode.c digest.c evp_enc.c evp_key.c evp_cnf.c \
         e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\
 SOURCE[../../libcrypto]=\
         encode.c digest.c evp_enc.c evp_key.c evp_cnf.c \
         e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\
-        e_rc4.c e_aes.c names.c e_seed.c e_aria.c \
+        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 \
         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 \
@@ -19,5 +19,6 @@ INCLUDE[e_aes_cbc_hmac_sha1.o]=../modes
 INCLUDE[e_aes_cbc_hmac_sha256.o]=../modes
 INCLUDE[e_aria.o]=.. ../modes
 INCLUDE[e_camellia.o]=.. ../modes
 INCLUDE[e_aes_cbc_hmac_sha256.o]=../modes
 INCLUDE[e_aria.o]=.. ../modes
 INCLUDE[e_camellia.o]=.. ../modes
+INCLUDE[e_sm4.o]=.. ../modes
 INCLUDE[e_des.o]=..
 INCLUDE[e_des3.o]=..
 INCLUDE[e_des.o]=..
 INCLUDE[e_des3.o]=..
index ee77d65..086b3c4 100644 (file)
@@ -79,6 +79,16 @@ void openssl_add_all_ciphers_int(void)
     EVP_add_cipher_alias(SN_seed_cbc, "seed");
 #endif
 
     EVP_add_cipher_alias(SN_seed_cbc, "seed");
 #endif
 
+#ifndef OPENSSL_NO_SM4
+    EVP_add_cipher(EVP_sm4_ecb());
+    EVP_add_cipher(EVP_sm4_cbc());
+    EVP_add_cipher(EVP_sm4_cfb());
+    EVP_add_cipher(EVP_sm4_ofb());
+    EVP_add_cipher(EVP_sm4_ctr());
+    EVP_add_cipher_alias(SN_sm4_cbc, "SM4");
+    EVP_add_cipher_alias(SN_sm4_cbc, "sm4");
+#endif
+
 #ifndef OPENSSL_NO_RC2
     EVP_add_cipher(EVP_rc2_ecb());
     EVP_add_cipher(EVP_rc2_cfb());
 #ifndef OPENSSL_NO_RC2
     EVP_add_cipher(EVP_rc2_ecb());
     EVP_add_cipher(EVP_rc2_cfb());
diff --git a/crypto/evp/e_sm4.c b/crypto/evp/e_sm4.c
new file mode 100644 (file)
index 0000000..79deb65
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * 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 "internal/cryptlib.h"
+#ifndef OPENSSL_NO_SM4
+# include <openssl/evp.h>
+# include <openssl/modes.h>
+# include "internal/sm4.h"
+# include "internal/evp_int.h"
+
+typedef struct {
+    SM4_KEY ks;
+} EVP_SM4_KEY;
+
+static int sm4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                        const unsigned char *iv, int enc)
+{
+    SM4_set_key(key, EVP_CIPHER_CTX_get_cipher_data(ctx));
+    return 1;
+}
+
+static void sm4_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                            size_t len, const SM4_KEY *key,
+                            unsigned char *ivec, const int enc)
+{
+    if (enc)
+        CRYPTO_cbc128_encrypt(in, out, len, key, ivec,
+                              (block128_f)SM4_encrypt);
+    else
+        CRYPTO_cbc128_decrypt(in, out, len, key, ivec,
+                              (block128_f)SM4_decrypt);
+}
+
+static void sm4_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+                               size_t length, const SM4_KEY *key,
+                               unsigned char *ivec, int *num, const int enc)
+{
+    CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
+                          (block128_f)SM4_encrypt);
+}
+
+static void sm4_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                            const SM4_KEY *key, const int enc)
+{
+    if (enc)
+        SM4_encrypt(in, out, key);
+    else
+        SM4_decrypt(in, out, key);
+}
+
+static void sm4_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+                               size_t length, const SM4_KEY *key,
+                               unsigned char *ivec, int *num)
+{
+    CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
+                          (block128_f)SM4_encrypt);
+}
+
+IMPLEMENT_BLOCK_CIPHER(sm4, ks, sm4, EVP_SM4_KEY, NID_sm4,
+                       16, 16, 16, 128, EVP_CIPH_FLAG_DEFAULT_ASN1,
+                       sm4_init_key, 0, 0, 0, 0)
+
+static int sm4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                          const unsigned char *in, size_t len)
+{
+    unsigned int num = EVP_CIPHER_CTX_num(ctx);
+    EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY, ctx);
+
+    CRYPTO_ctr128_encrypt(in, out, len, &dat->ks,
+                          EVP_CIPHER_CTX_iv_noconst(ctx),
+                          EVP_CIPHER_CTX_buf_noconst(ctx), &num,
+                          (block128_f)SM4_encrypt);
+    EVP_CIPHER_CTX_set_num(ctx, num);
+    return 1;
+}
+
+static const EVP_CIPHER sm4_ctr_mode = {
+    NID_sm4_ctr, 1, 16, 16,
+    EVP_CIPH_CTR_MODE,
+    sm4_init_key,
+    sm4_ctr_cipher,
+    NULL,
+    sizeof(EVP_SM4_KEY),
+    NULL, NULL, NULL, NULL
+};
+
+const EVP_CIPHER *EVP_sm4_ctr(void)
+{
+    return &sm4_ctr_mode;
+}
+
+#endif
diff --git a/crypto/include/internal/sm4.h b/crypto/include/internal/sm4.h
new file mode 100644 (file)
index 0000000..f1f157e
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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
+ */
+
+#ifndef HEADER_SM4_H
+# define HEADER_SM4_H
+
+# include <openssl/opensslconf.h>
+# include <openssl/e_os2.h>
+
+# ifdef OPENSSL_NO_SM4
+#  error SM4 is disabled.
+# endif
+
+# define SM4_ENCRYPT     1
+# define SM4_DECRYPT     0
+
+# define SM4_BLOCK_SIZE    16
+# define SM4_KEY_SCHEDULE  32
+
+typedef struct SM4_KEY_st {
+    uint32_t rk[SM4_KEY_SCHEDULE];
+} SM4_KEY;
+
+int SM4_set_key(const uint8_t *key, SM4_KEY *ks);
+
+void SM4_encrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *ks);
+
+void SM4_decrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *ks);
+
+#endif
index 471202f..866fa34 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /* Serialized OID's */
  */
 
 /* Serialized OID's */
-static const unsigned char so[7238] = {
+static const unsigned char so[7308] = {
     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 */
     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 */
@@ -1018,9 +1018,19 @@ static const unsigned char so[7238] = {
     0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x24,  /* [ 7212] OBJ_aria_256_gcm */
     0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1B,       /* [ 7221] OBJ_cmcCA */
     0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1C,       /* [ 7229] OBJ_cmcRA */
     0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x24,  /* [ 7212] OBJ_aria_256_gcm */
     0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1B,       /* [ 7221] OBJ_cmcCA */
     0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1C,       /* [ 7229] OBJ_cmcRA */
+    0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x01,       /* [ 7237] OBJ_sm4_ecb */
+    0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x02,       /* [ 7245] OBJ_sm4_cbc */
+    0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x03,       /* [ 7253] OBJ_sm4_ofb128 */
+    0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x05,       /* [ 7261] OBJ_sm4_cfb1 */
+    0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x04,       /* [ 7269] OBJ_sm4_cfb128 */
+    0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x06,       /* [ 7277] OBJ_sm4_cfb8 */
+    0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x07,       /* [ 7285] OBJ_sm4_ctr */
+    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 */
 };
 
 };
 
-#define NUM_NID 1133
+#define NUM_NID 1143
 static const ASN1_OBJECT nid_objs[NUM_NID] = {
     {"UNDEF", "undefined", NID_undef},
     {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
 static const ASN1_OBJECT nid_objs[NUM_NID] = {
     {"UNDEF", "undefined", NID_undef},
     {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
@@ -2155,9 +2165,19 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
     {"ffdhe8192", "ffdhe8192", NID_ffdhe8192},
     {"cmcCA", "CMC Certificate Authority", NID_cmcCA, 8, &so[7221]},
     {"cmcRA", "CMC Registration Authority", NID_cmcRA, 8, &so[7229]},
     {"ffdhe8192", "ffdhe8192", NID_ffdhe8192},
     {"cmcCA", "CMC Certificate Authority", NID_cmcCA, 8, &so[7221]},
     {"cmcRA", "CMC Registration Authority", NID_cmcRA, 8, &so[7229]},
+    {"SM4-ECB", "sm4-ecb", NID_sm4_ecb, 8, &so[7237]},
+    {"SM4-CBC", "sm4-cbc", NID_sm4_cbc, 8, &so[7245]},
+    {"SM4-OFB", "sm4-ofb", NID_sm4_ofb128, 8, &so[7253]},
+    {"SM4-CFB1", "sm4-cfb1", NID_sm4_cfb1, 8, &so[7261]},
+    {"SM4-CFB", "sm4-cfb", NID_sm4_cfb128, 8, &so[7269]},
+    {"SM4-CFB8", "sm4-cfb8", NID_sm4_cfb8, 8, &so[7277]},
+    {"SM4-CTR", "sm4-ctr", NID_sm4_ctr, 8, &so[7285]},
+    {"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]},
 };
 
 };
 
-#define NUM_SN 1124
+#define NUM_SN 1134
 static const unsigned int sn_objs[NUM_SN] = {
      364,    /* "AD_DVCS" */
      419,    /* "AES-128-CBC" */
 static const unsigned int sn_objs[NUM_SN] = {
      364,    /* "AD_DVCS" */
      419,    /* "AES-128-CBC" */
@@ -2316,6 +2336,7 @@ static const unsigned int sn_objs[NUM_SN] = {
       46,    /* "IDEA-OFB" */
     1004,    /* "INN" */
      181,    /* "ISO" */
       46,    /* "IDEA-OFB" */
     1004,    /* "INN" */
      181,    /* "ISO" */
+    1140,    /* "ISO-CN" */
      183,    /* "ISO-US" */
      645,    /* "ITU-T" */
      646,    /* "JOINT-ISO-ITU-T" */
      183,    /* "ISO-US" */
      645,    /* "ITU-T" */
      646,    /* "JOINT-ISO-ITU-T" */
@@ -2417,6 +2438,13 @@ static const unsigned int sn_objs[NUM_SN] = {
     1095,    /* "SHA512-256" */
     1100,    /* "SHAKE128" */
     1101,    /* "SHAKE256" */
     1095,    /* "SHA512-256" */
     1100,    /* "SHAKE128" */
     1101,    /* "SHAKE256" */
+    1134,    /* "SM4-CBC" */
+    1137,    /* "SM4-CFB" */
+    1136,    /* "SM4-CFB1" */
+    1138,    /* "SM4-CFB8" */
+    1139,    /* "SM4-CTR" */
+    1133,    /* "SM4-ECB" */
+    1135,    /* "SM4-OFB" */
      188,    /* "SMIME" */
      167,    /* "SMIME-CAPS" */
      100,    /* "SN" */
      188,    /* "SMIME" */
      167,    /* "SMIME-CAPS" */
      100,    /* "SN" */
@@ -2979,6 +3007,7 @@ static const unsigned int sn_objs[NUM_SN] = {
      681,    /* "onBasis" */
     1089,    /* "organizationIdentifier" */
      491,    /* "organizationalStatus" */
      681,    /* "onBasis" */
     1089,    /* "organizationIdentifier" */
      491,    /* "organizationalStatus" */
+    1141,    /* "oscca" */
      475,    /* "otherMailbox" */
      876,    /* "owner" */
      489,    /* "pagerTelephoneNumber" */
      475,    /* "otherMailbox" */
      876,    /* "owner" */
      489,    /* "pagerTelephoneNumber" */
@@ -3233,6 +3262,7 @@ static const unsigned int sn_objs[NUM_SN] = {
       52,    /* "signingTime" */
      454,    /* "simpleSecurityObject" */
      496,    /* "singleLevelQuality" */
       52,    /* "signingTime" */
      454,    /* "simpleSecurityObject" */
      496,    /* "singleLevelQuality" */
+    1142,    /* "sm-scheme" */
      387,    /* "snmpv2" */
      660,    /* "street" */
       85,    /* "subjectAltName" */
      387,    /* "snmpv2" */
      660,    /* "street" */
       85,    /* "subjectAltName" */
@@ -3285,7 +3315,7 @@ static const unsigned int sn_objs[NUM_SN] = {
     1093,    /* "x509ExtAdmission" */
 };
 
     1093,    /* "x509ExtAdmission" */
 };
 
-#define NUM_LN 1124
+#define NUM_LN 1134
 static const unsigned int ln_objs[NUM_LN] = {
      363,    /* "AD Time Stamping" */
      405,    /* "ANSI X9.62" */
 static const unsigned int ln_objs[NUM_LN] = {
      363,    /* "AD Time Stamping" */
      405,    /* "ANSI X9.62" */
@@ -3354,6 +3384,7 @@ static const unsigned int ln_objs[NUM_LN] = {
      294,    /* "IPSec End System" */
      295,    /* "IPSec Tunnel" */
      296,    /* "IPSec User" */
      294,    /* "IPSec End System" */
      295,    /* "IPSec Tunnel" */
      296,    /* "IPSec User" */
+    1140,    /* "ISO CN Member Body" */
      182,    /* "ISO Member Body" */
      183,    /* "ISO US Member Body" */
      667,    /* "Independent" */
      182,    /* "ISO Member Body" */
      183,    /* "ISO US Member Body" */
      667,    /* "Independent" */
@@ -4082,6 +4113,7 @@ static const unsigned int ln_objs[NUM_LN] = {
       17,    /* "organizationName" */
      491,    /* "organizationalStatus" */
       18,    /* "organizationalUnitName" */
       17,    /* "organizationName" */
      491,    /* "organizationalStatus" */
       18,    /* "organizationalUnitName" */
+    1141,    /* "oscca" */
      475,    /* "otherMailbox" */
      876,    /* "owner" */
      935,    /* "pSpecified" */
      475,    /* "otherMailbox" */
      876,    /* "owner" */
      935,    /* "pSpecified" */
@@ -4366,6 +4398,14 @@ static const unsigned int ln_objs[NUM_LN] = {
      454,    /* "simpleSecurityObject" */
      496,    /* "singleLevelQuality" */
     1062,    /* "siphash" */
      454,    /* "simpleSecurityObject" */
      496,    /* "singleLevelQuality" */
     1062,    /* "siphash" */
+    1142,    /* "sm-scheme" */
+    1134,    /* "sm4-cbc" */
+    1137,    /* "sm4-cfb" */
+    1136,    /* "sm4-cfb1" */
+    1138,    /* "sm4-cfb8" */
+    1139,    /* "sm4-ctr" */
+    1133,    /* "sm4-ecb" */
+    1135,    /* "sm4-ofb" */
       16,    /* "stateOrProvinceName" */
      660,    /* "streetAddress" */
      498,    /* "subtreeMaximumQuality" */
       16,    /* "stateOrProvinceName" */
      660,    /* "streetAddress" */
      498,    /* "subtreeMaximumQuality" */
@@ -4413,7 +4453,7 @@ static const unsigned int ln_objs[NUM_LN] = {
      125,    /* "zlib compression" */
 };
 
      125,    /* "zlib compression" */
 };
 
-#define NUM_OBJ 1013
+#define NUM_OBJ 1023
 static const unsigned int obj_objs[NUM_OBJ] = {
        0,    /* OBJ_undef                        0 */
      181,    /* OBJ_iso                          1 */
 static const unsigned int obj_objs[NUM_OBJ] = {
        0,    /* OBJ_undef                        0 */
      181,    /* OBJ_iso                          1 */
@@ -4434,6 +4474,7 @@ static const unsigned int obj_objs[NUM_OBJ] = {
      512,    /* OBJ_id_set                       2 23 42 */
      678,    /* OBJ_wap                          2 23 43 */
      435,    /* OBJ_pss                          0 9 2342 */
      512,    /* OBJ_id_set                       2 23 42 */
      678,    /* OBJ_wap                          2 23 43 */
      435,    /* OBJ_pss                          0 9 2342 */
+    1140,    /* OBJ_ISO_CN                       1 2 156 */
      183,    /* OBJ_ISO_US                       1 2 840 */
      381,    /* OBJ_iana                         1 3 6 1 */
     1034,    /* OBJ_X25519                       1 3 101 110 */
      183,    /* OBJ_ISO_US                       1 2 840 */
      381,    /* OBJ_iana                         1 3 6 1 */
     1034,    /* OBJ_X25519                       1 3 101 110 */
@@ -4657,6 +4698,7 @@ static const unsigned int obj_objs[NUM_OBJ] = {
      637,    /* OBJ_set_brand_Diners             2 23 42 8 30 */
      638,    /* OBJ_set_brand_AmericanExpress    2 23 42 8 34 */
      639,    /* OBJ_set_brand_JCB                2 23 42 8 35 */
      637,    /* OBJ_set_brand_Diners             2 23 42 8 30 */
      638,    /* OBJ_set_brand_AmericanExpress    2 23 42 8 34 */
      639,    /* OBJ_set_brand_JCB                2 23 42 8 35 */
+    1141,    /* OBJ_oscca                        1 2 156 10197 */
      805,    /* OBJ_cryptopro                    1 2 643 2 2 */
      806,    /* OBJ_cryptocom                    1 2 643 2 9 */
      974,    /* OBJ_id_tc26                      1 2 643 7 1 */
      805,    /* OBJ_cryptopro                    1 2 643 2 2 */
      806,    /* OBJ_cryptocom                    1 2 643 2 9 */
      974,    /* OBJ_id_tc26                      1 2 643 7 1 */
@@ -4736,6 +4778,7 @@ static const unsigned int obj_objs[NUM_OBJ] = {
      744,    /* OBJ_wap_wsg_idm_ecid_wtls11      2 23 43 1 4 11 */
      745,    /* OBJ_wap_wsg_idm_ecid_wtls12      2 23 43 1 4 12 */
      804,    /* OBJ_whirlpool                    1 0 10118 3 0 55 */
      744,    /* OBJ_wap_wsg_idm_ecid_wtls11      2 23 43 1 4 11 */
      745,    /* OBJ_wap_wsg_idm_ecid_wtls12      2 23 43 1 4 12 */
      804,    /* OBJ_whirlpool                    1 0 10118 3 0 55 */
+    1142,    /* OBJ_sm_scheme                    1 2 156 10197 1 */
      773,    /* OBJ_kisa                         1 2 410 200004 */
      807,    /* OBJ_id_GostR3411_94_with_GostR3410_2001 1 2 643 2 2 3 */
      808,    /* OBJ_id_GostR3411_94_with_GostR3410_94 1 2 643 2 2 4 */
      773,    /* OBJ_kisa                         1 2 410 200004 */
      807,    /* OBJ_id_GostR3411_94_with_GostR3410_2001 1 2 643 2 2 3 */
      808,    /* OBJ_id_GostR3411_94_with_GostR3410_94 1 2 643 2 2 4 */
@@ -4865,6 +4908,13 @@ static const unsigned int obj_objs[NUM_OBJ] = {
      971,    /* OBJ_camellia_256_ctr             0 3 4401 5 3 1 9 49 */
      972,    /* OBJ_camellia_256_cmac            0 3 4401 5 3 1 9 50 */
      437,    /* OBJ_pilot                        0 9 2342 19200300 100 */
      971,    /* OBJ_camellia_256_ctr             0 3 4401 5 3 1 9 49 */
      972,    /* OBJ_camellia_256_cmac            0 3 4401 5 3 1 9 50 */
      437,    /* OBJ_pilot                        0 9 2342 19200300 100 */
+    1133,    /* OBJ_sm4_ecb                      1 2 156 10197 1 104 1 */
+    1134,    /* OBJ_sm4_cbc                      1 2 156 10197 1 104 2 */
+    1135,    /* OBJ_sm4_ofb128                   1 2 156 10197 1 104 3 */
+    1137,    /* OBJ_sm4_cfb128                   1 2 156 10197 1 104 4 */
+    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 */
      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 */
      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 26495f2..4e5f702 100644 (file)
@@ -1130,3 +1130,13 @@ ffdhe6144                1129
 ffdhe8192              1130
 cmcCA          1131
 cmcRA          1132
 ffdhe8192              1130
 cmcCA          1131
 cmcRA          1132
+sm4_ecb                1133
+sm4_cbc                1134
+sm4_ofb128             1135
+sm4_cfb1               1136
+sm4_cfb128             1137
+sm4_cfb8               1138
+sm4_ctr                1139
+ISO_CN         1140
+oscca          1141
+sm_scheme              1142
index 9aecacf..22e69b8 100644 (file)
@@ -1368,7 +1368,7 @@ member-body 643 100 112   : issuerSignTool        : Signing Tool of Issuer
 # Definitions for Camellia cipher - ECB, CFB, OFB MODE
 
 !Alias ntt-ds 0 3 4401 5
 # Definitions for Camellia cipher - ECB, CFB, OFB MODE
 
 !Alias ntt-ds 0 3 4401 5
-!Alias camellia ntt-ds 3 1 9 
+!Alias camellia ntt-ds 3 1 9
 
 camellia 1             : CAMELLIA-128-ECB              : camellia-128-ecb
 !Cname camellia-128-ofb128
 
 camellia 1             : CAMELLIA-128-ECB              : camellia-128-ecb
 !Cname camellia-128-ofb128
@@ -1461,6 +1461,23 @@ kisa 1 5                : SEED-CFB      : seed-cfb
 !Cname seed-ofb128
 kisa 1 6                : SEED-OFB      : seed-ofb
 
 !Cname seed-ofb128
 kisa 1 6                : SEED-OFB      : seed-ofb
 
+
+# Definitions for SM4 cipher
+
+member-body 156         : ISO-CN        : ISO CN Member Body
+ISO-CN 10197            : oscca
+oscca 1                 : sm-scheme
+
+sm-scheme 104 1         : SM4-ECB             : sm4-ecb
+sm-scheme 104 2         : SM4-CBC             : sm4-cbc
+!Cname sm4-ofb128
+sm-scheme 104 3         : SM4-OFB             : sm4-ofb
+!Cname sm4-cfb128
+sm-scheme 104 4         : SM4-CFB             : sm4-cfb
+sm-scheme 104 5         : SM4-CFB1            : sm4-cfb1
+sm-scheme 104 6         : SM4-CFB8            : sm4-cfb8
+sm-scheme 104 7         : SM4-CTR             : sm4-ctr
+
 # There is no OID that just denotes "HMAC" oddly enough...
 
                        : HMAC                          : hmac
 # There is no OID that just denotes "HMAC" oddly enough...
 
                        : HMAC                          : hmac
@@ -1498,7 +1515,7 @@ ISO-US 10046 2 1  : dhpublicnumber                : X9.42 DH
 1 3 36 3 3 2 8 1 1 11 : brainpoolP384r1
 1 3 36 3 3 2 8 1 1 12 : brainpoolP384t1
 1 3 36 3 3 2 8 1 1 13 : brainpoolP512r1
 1 3 36 3 3 2 8 1 1 11 : brainpoolP384r1
 1 3 36 3 3 2 8 1 1 12 : brainpoolP384t1
 1 3 36 3 3 2 8 1 1 13 : brainpoolP512r1
-1 3 36 3 3 2 8 1 1 14 : brainpoolP512t1            
+1 3 36 3 3 2 8 1 1 14 : brainpoolP512t1
 
 # ECDH schemes from RFC5753
 !Alias x9-63-scheme 1 3 133 16 840 63 0
 
 # ECDH schemes from RFC5753
 !Alias x9-63-scheme 1 3 133 16 840 63 0
diff --git a/crypto/sm4/build.info b/crypto/sm4/build.info
new file mode 100644 (file)
index 0000000..b65a7d1
--- /dev/null
@@ -0,0 +1,4 @@
+LIBS=../../libcrypto
+SOURCE[../../libcrypto]=\
+        sm4.c
+
diff --git a/crypto/sm4/sm4.c b/crypto/sm4/sm4.c
new file mode 100644 (file)
index 0000000..0c819a4
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * 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 <openssl/e_os2.h>
+#include "internal/sm4.h"
+
+static const uint8_t SM4_S[256] = {
+    0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2,
+    0x28, 0xFB, 0x2C, 0x05, 0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3,
+    0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9C, 0x42, 0x50, 0xF4,
+    0x91, 0xEF, 0x98, 0x7A, 0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62,
+    0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95, 0x80, 0xDF, 0x94, 0xFA,
+    0x75, 0x8F, 0x3F, 0xA6, 0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA,
+    0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8, 0x68, 0x6B, 0x81, 0xB2,
+    0x71, 0x64, 0xDA, 0x8B, 0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35,
+    0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2, 0x25, 0x22, 0x7C, 0x3B,
+    0x01, 0x21, 0x78, 0x87, 0xD4, 0x00, 0x46, 0x57, 0x9F, 0xD3, 0x27, 0x52,
+    0x4C, 0x36, 0x02, 0xE7, 0xA0, 0xC4, 0xC8, 0x9E, 0xEA, 0xBF, 0x8A, 0xD2,
+    0x40, 0xC7, 0x38, 0xB5, 0xA3, 0xF7, 0xF2, 0xCE, 0xF9, 0x61, 0x15, 0xA1,
+    0xE0, 0xAE, 0x5D, 0xA4, 0x9B, 0x34, 0x1A, 0x55, 0xAD, 0x93, 0x32, 0x30,
+    0xF5, 0x8C, 0xB1, 0xE3, 0x1D, 0xF6, 0xE2, 0x2E, 0x82, 0x66, 0xCA, 0x60,
+    0xC0, 0x29, 0x23, 0xAB, 0x0D, 0x53, 0x4E, 0x6F, 0xD5, 0xDB, 0x37, 0x45,
+    0xDE, 0xFD, 0x8E, 0x2F, 0x03, 0xFF, 0x6A, 0x72, 0x6D, 0x6C, 0x5B, 0x51,
+    0x8D, 0x1B, 0xAF, 0x92, 0xBB, 0xDD, 0xBC, 0x7F, 0x11, 0xD9, 0x5C, 0x41,
+    0x1F, 0x10, 0x5A, 0xD8, 0x0A, 0xC1, 0x31, 0x88, 0xA5, 0xCD, 0x7B, 0xBD,
+    0x2D, 0x74, 0xD0, 0x12, 0xB8, 0xE5, 0xB4, 0xB0, 0x89, 0x69, 0x97, 0x4A,
+    0x0C, 0x96, 0x77, 0x7E, 0x65, 0xB9, 0xF1, 0x09, 0xC5, 0x6E, 0xC6, 0x84,
+    0x18, 0xF0, 0x7D, 0xEC, 0x3A, 0xDC, 0x4D, 0x20, 0x79, 0xEE, 0x5F, 0x3E,
+    0xD7, 0xCB, 0x39, 0x48
+};
+
+/*
+ * SM4_SBOX_T[j] == L(SM4_SBOX[j]).
+ */
+static const uint32_t SM4_SBOX_T[256] = {
+    0x8ED55B5B, 0xD0924242, 0x4DEAA7A7, 0x06FDFBFB, 0xFCCF3333, 0x65E28787,
+    0xC93DF4F4, 0x6BB5DEDE, 0x4E165858, 0x6EB4DADA, 0x44145050, 0xCAC10B0B,
+    0x8828A0A0, 0x17F8EFEF, 0x9C2CB0B0, 0x11051414, 0x872BACAC, 0xFB669D9D,
+    0xF2986A6A, 0xAE77D9D9, 0x822AA8A8, 0x46BCFAFA, 0x14041010, 0xCFC00F0F,
+    0x02A8AAAA, 0x54451111, 0x5F134C4C, 0xBE269898, 0x6D482525, 0x9E841A1A,
+    0x1E061818, 0xFD9B6666, 0xEC9E7272, 0x4A430909, 0x10514141, 0x24F7D3D3,
+    0xD5934646, 0x53ECBFBF, 0xF89A6262, 0x927BE9E9, 0xFF33CCCC, 0x04555151,
+    0x270B2C2C, 0x4F420D0D, 0x59EEB7B7, 0xF3CC3F3F, 0x1CAEB2B2, 0xEA638989,
+    0x74E79393, 0x7FB1CECE, 0x6C1C7070, 0x0DABA6A6, 0xEDCA2727, 0x28082020,
+    0x48EBA3A3, 0xC1975656, 0x80820202, 0xA3DC7F7F, 0xC4965252, 0x12F9EBEB,
+    0xA174D5D5, 0xB38D3E3E, 0xC33FFCFC, 0x3EA49A9A, 0x5B461D1D, 0x1B071C1C,
+    0x3BA59E9E, 0x0CFFF3F3, 0x3FF0CFCF, 0xBF72CDCD, 0x4B175C5C, 0x52B8EAEA,
+    0x8F810E0E, 0x3D586565, 0xCC3CF0F0, 0x7D196464, 0x7EE59B9B, 0x91871616,
+    0x734E3D3D, 0x08AAA2A2, 0xC869A1A1, 0xC76AADAD, 0x85830606, 0x7AB0CACA,
+    0xB570C5C5, 0xF4659191, 0xB2D96B6B, 0xA7892E2E, 0x18FBE3E3, 0x47E8AFAF,
+    0x330F3C3C, 0x674A2D2D, 0xB071C1C1, 0x0E575959, 0xE99F7676, 0xE135D4D4,
+    0x661E7878, 0xB4249090, 0x360E3838, 0x265F7979, 0xEF628D8D, 0x38596161,
+    0x95D24747, 0x2AA08A8A, 0xB1259494, 0xAA228888, 0x8C7DF1F1, 0xD73BECEC,
+    0x05010404, 0xA5218484, 0x9879E1E1, 0x9B851E1E, 0x84D75353, 0x00000000,
+    0x5E471919, 0x0B565D5D, 0xE39D7E7E, 0x9FD04F4F, 0xBB279C9C, 0x1A534949,
+    0x7C4D3131, 0xEE36D8D8, 0x0A020808, 0x7BE49F9F, 0x20A28282, 0xD4C71313,
+    0xE8CB2323, 0xE69C7A7A, 0x42E9ABAB, 0x43BDFEFE, 0xA2882A2A, 0x9AD14B4B,
+    0x40410101, 0xDBC41F1F, 0xD838E0E0, 0x61B7D6D6, 0x2FA18E8E, 0x2BF4DFDF,
+    0x3AF1CBCB, 0xF6CD3B3B, 0x1DFAE7E7, 0xE5608585, 0x41155454, 0x25A38686,
+    0x60E38383, 0x16ACBABA, 0x295C7575, 0x34A69292, 0xF7996E6E, 0xE434D0D0,
+    0x721A6868, 0x01545555, 0x19AFB6B6, 0xDF914E4E, 0xFA32C8C8, 0xF030C0C0,
+    0x21F6D7D7, 0xBC8E3232, 0x75B3C6C6, 0x6FE08F8F, 0x691D7474, 0x2EF5DBDB,
+    0x6AE18B8B, 0x962EB8B8, 0x8A800A0A, 0xFE679999, 0xE2C92B2B, 0xE0618181,
+    0xC0C30303, 0x8D29A4A4, 0xAF238C8C, 0x07A9AEAE, 0x390D3434, 0x1F524D4D,
+    0x764F3939, 0xD36EBDBD, 0x81D65757, 0xB7D86F6F, 0xEB37DCDC, 0x51441515,
+    0xA6DD7B7B, 0x09FEF7F7, 0xB68C3A3A, 0x932FBCBC, 0x0F030C0C, 0x03FCFFFF,
+    0xC26BA9A9, 0xBA73C9C9, 0xD96CB5B5, 0xDC6DB1B1, 0x375A6D6D, 0x15504545,
+    0xB98F3636, 0x771B6C6C, 0x13ADBEBE, 0xDA904A4A, 0x57B9EEEE, 0xA9DE7777,
+    0x4CBEF2F2, 0x837EFDFD, 0x55114444, 0xBDDA6767, 0x2C5D7171, 0x45400505,
+    0x631F7C7C, 0x50104040, 0x325B6969, 0xB8DB6363, 0x220A2828, 0xC5C20707,
+    0xF531C4C4, 0xA88A2222, 0x31A79696, 0xF9CE3737, 0x977AEDED, 0x49BFF6F6,
+    0x992DB4B4, 0xA475D1D1, 0x90D34343, 0x5A124848, 0x58BAE2E2, 0x71E69797,
+    0x64B6D2D2, 0x70B2C2C2, 0xAD8B2626, 0xCD68A5A5, 0xCB955E5E, 0x624B2929,
+    0x3C0C3030, 0xCE945A5A, 0xAB76DDDD, 0x867FF9F9, 0xF1649595, 0x5DBBE6E6,
+    0x35F2C7C7, 0x2D092424, 0xD1C61717, 0xD66FB9B9, 0xDEC51B1B, 0x94861212,
+    0x78186060, 0x30F3C3C3, 0x897CF5F5, 0x5CEFB3B3, 0xD23AE8E8, 0xACDF7373,
+    0x794C3535, 0xA0208080, 0x9D78E5E5, 0x56EDBBBB, 0x235E7D7D, 0xC63EF8F8,
+    0x8BD45F5F, 0xE7C82F2F, 0xDD39E4E4, 0x68492121 };
+
+static ossl_inline uint32_t rotl(uint32_t a, uint8_t n)
+{
+    return (a << n) | (a >> (32 - n));
+}
+
+static ossl_inline uint32_t load_u32_be(const uint8_t *b, uint32_t n)
+{
+    return ((uint32_t)b[4 * n] << 24) |
+           ((uint32_t)b[4 * n + 1] << 16) |
+           ((uint32_t)b[4 * n + 2] << 8) |
+           ((uint32_t)b[4 * n + 3]);
+}
+
+static ossl_inline void store_u32_be(uint32_t v, uint8_t *b)
+{
+    b[0] = (uint8_t)(v >> 24);
+    b[1] = (uint8_t)(v >> 16);
+    b[2] = (uint8_t)(v >> 8);
+    b[3] = (uint8_t)(v);
+}
+
+static ossl_inline uint32_t SM4_T_slow(uint32_t X)
+{
+    uint32_t t = 0;
+
+    t |= ((uint32_t)SM4_S[(uint8_t)(X >> 24)]) << 24;
+    t |= ((uint32_t)SM4_S[(uint8_t)(X >> 16)]) << 16;
+    t |= ((uint32_t)SM4_S[(uint8_t)(X >> 8)]) << 8;
+    t |= SM4_S[(uint8_t)X];
+
+    /*
+     * L linear transform
+     */
+    return t ^ rotl(t, 2) ^ rotl(t, 10) ^ rotl(t, 18) ^ rotl(t, 24);
+}
+
+static ossl_inline uint32_t SM4_T(uint32_t X)
+{
+    return SM4_SBOX_T[(uint8_t)(X >> 24)] ^
+           rotl(SM4_SBOX_T[(uint8_t)(X >> 16)], 24) ^
+           rotl(SM4_SBOX_T[(uint8_t)(X >> 8)], 16) ^
+           rotl(SM4_SBOX_T[(uint8_t)X], 8);
+}
+
+int SM4_set_key(const uint8_t *key, SM4_KEY *ks)
+{
+    /*
+     * Family Key
+     */
+    static const uint32_t FK[4] =
+        { 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc };
+
+    /*
+     * Constant Key
+     */
+    static const uint32_t CK[32] = {
+        0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269,
+        0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9,
+        0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249,
+        0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9,
+        0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229,
+        0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299,
+        0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209,
+        0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279
+    };
+
+    uint32_t K[4];
+    int i;
+
+    K[0] = load_u32_be(key, 0) ^ FK[0];
+    K[1] = load_u32_be(key, 1) ^ FK[1];
+    K[2] = load_u32_be(key, 2) ^ FK[2];
+    K[3] = load_u32_be(key, 3) ^ FK[3];
+
+    for (i = 0; i != SM4_KEY_SCHEDULE; ++i) {
+        uint32_t X = K[(i + 1) % 4] ^ K[(i + 2) % 4] ^ K[(i + 3) % 4] ^ CK[i];
+        uint32_t t = 0;
+
+        t |= ((uint32_t)SM4_S[(uint8_t)(X >> 24)]) << 24;
+        t |= ((uint32_t)SM4_S[(uint8_t)(X >> 16)]) << 16;
+        t |= ((uint32_t)SM4_S[(uint8_t)(X >> 8)]) << 8;
+        t |= SM4_S[(uint8_t)X];
+
+        t = t ^ rotl(t, 13) ^ rotl(t, 23);
+        K[i % 4] ^= t;
+        ks->rk[i] = K[i % 4];
+    }
+
+    return 1;
+}
+
+#define SM4_RNDS(k0, k1, k2, k3, F)          \
+      do {                                   \
+         B0 ^= F(B1 ^ B2 ^ B3 ^ ks->rk[k0]); \
+         B1 ^= F(B0 ^ B2 ^ B3 ^ ks->rk[k1]); \
+         B2 ^= F(B0 ^ B1 ^ B3 ^ ks->rk[k2]); \
+         B3 ^= F(B0 ^ B1 ^ B2 ^ ks->rk[k3]); \
+      } while(0)
+
+void SM4_encrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *ks)
+{
+    uint32_t B0 = load_u32_be(in, 0);
+    uint32_t B1 = load_u32_be(in, 1);
+    uint32_t B2 = load_u32_be(in, 2);
+    uint32_t B3 = load_u32_be(in, 3);
+
+    /*
+     * Uses byte-wise sbox in the first and last rounds to provide some
+     * protection from cache based side channels.
+     */
+    SM4_RNDS( 0,  1,  2,  3, SM4_T_slow);
+    SM4_RNDS( 4,  5,  6,  7, SM4_T);
+    SM4_RNDS( 8,  9, 10, 11, SM4_T);
+    SM4_RNDS(12, 13, 14, 15, SM4_T);
+    SM4_RNDS(16, 17, 18, 19, SM4_T);
+    SM4_RNDS(20, 21, 22, 23, SM4_T);
+    SM4_RNDS(24, 25, 26, 27, SM4_T);
+    SM4_RNDS(28, 29, 30, 31, SM4_T_slow);
+
+    store_u32_be(B3, out);
+    store_u32_be(B2, out + 4);
+    store_u32_be(B1, out + 8);
+    store_u32_be(B0, out + 12);
+}
+
+void SM4_decrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *ks)
+{
+    uint32_t B0 = load_u32_be(in, 0);
+    uint32_t B1 = load_u32_be(in, 1);
+    uint32_t B2 = load_u32_be(in, 2);
+    uint32_t B3 = load_u32_be(in, 3);
+
+    SM4_RNDS(31, 30, 29, 28, SM4_T_slow);
+    SM4_RNDS(27, 26, 25, 24, SM4_T);
+    SM4_RNDS(23, 22, 21, 20, SM4_T);
+    SM4_RNDS(19, 18, 17, 16, SM4_T);
+    SM4_RNDS(15, 14, 13, 12, SM4_T);
+    SM4_RNDS(11, 10,  9,  8, SM4_T);
+    SM4_RNDS( 7,  6,  5,  4, SM4_T);
+    SM4_RNDS( 3,  2,  1,  0, SM4_T_slow);
+
+    store_u32_be(B3, out);
+    store_u32_be(B2, out + 4);
+    store_u32_be(B1, out + 8);
+    store_u32_be(B0, out + 12);
+}
diff --git a/doc/man3/EVP_sm4.pod b/doc/man3/EVP_sm4.pod
new file mode 100644 (file)
index 0000000..d5c99cd
--- /dev/null
@@ -0,0 +1,65 @@
+=pod
+
+=head1 NAME
+
+EVP_sm4_cbc,
+EVP_sm4_ecb,
+EVP_sm4_cfb,
+EVP_sm4_ofb,
+EVP_sm4_ctr
+- EVP SM4 cipher
+
+=head1 SYNOPSIS
+
+=for comment generic
+
+ #include <openssl/evp.h>
+
+ const EVP_CIPHER *EVP_ciphername(void)
+
+I<EVP_ciphername> is used a placeholder for any of the described cipher
+functions, such as I<EVP_sm4_cbc>.
+
+=head1 DESCRIPTION
+
+The SM4 blockcipher (GB/T 32907-2016) for EVP.
+
+All modes below use a key length of 128 bits and acts on blocks of 128 bits.
+
+=over 4
+
+=item EVP_sm4_cbc(),
+EVP_sm4_ecb(),
+EVP_sm4_cfb(),
+EVP_sm4_ofb(),
+EVP_sm4_ctr()
+
+The SM4 blockcipher with a 128-bit key in CBC, ECB, CFB, OFB and CTR modes
+respectively.
+
+=back
+
+=head1 RETURN VALUES
+
+These functions return a B<EVP_CIPHER> structure that contains the
+implementation of the symmetric cipher. See L<EVP_CIPHER_meth_new(3)> for
+details of the B<EVP_CIPHER> structure.
+
+=head1 SEE ALSO
+
+L<evp(7)>,
+L<EVP_EncryptInit(3)>,
+L<EVP_CIPHER_meth_new(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 90add83..3a98e1d 100644 (file)
@@ -916,6 +916,15 @@ const EVP_CIPHER *EVP_seed_cfb128(void);
 const EVP_CIPHER *EVP_seed_ofb(void);
 # endif
 
 const EVP_CIPHER *EVP_seed_ofb(void);
 # endif
 
+# ifndef OPENSSL_NO_SM4
+const EVP_CIPHER *EVP_sm4_ecb(void);
+const EVP_CIPHER *EVP_sm4_cbc(void);
+const EVP_CIPHER *EVP_sm4_cfb128(void);
+#  define EVP_sm4_cfb EVP_sm4_cfb128
+const EVP_CIPHER *EVP_sm4_ofb(void);
+const EVP_CIPHER *EVP_sm4_ctr(void);
+# endif
+
 # if OPENSSL_API_COMPAT < 0x10100000L
 #  define OPENSSL_add_all_algorithms_conf() \
     OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
 # if OPENSSL_API_COMPAT < 0x10100000L
 #  define OPENSSL_add_all_algorithms_conf() \
     OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
index 58c44f0..02447dc 100644 (file)
 #define NID_seed_ofb128         778
 #define OBJ_seed_ofb128         OBJ_kisa,1L,6L
 
 #define NID_seed_ofb128         778
 #define OBJ_seed_ofb128         OBJ_kisa,1L,6L
 
+#define SN_ISO_CN               "ISO-CN"
+#define LN_ISO_CN               "ISO CN Member Body"
+#define NID_ISO_CN              1140
+#define OBJ_ISO_CN              OBJ_member_body,156L
+
+#define SN_oscca                "oscca"
+#define NID_oscca               1141
+#define OBJ_oscca               OBJ_ISO_CN,10197L
+
+#define SN_sm_scheme            "sm-scheme"
+#define NID_sm_scheme           1142
+#define OBJ_sm_scheme           OBJ_oscca,1L
+
+#define SN_sm4_ecb              "SM4-ECB"
+#define LN_sm4_ecb              "sm4-ecb"
+#define NID_sm4_ecb             1133
+#define OBJ_sm4_ecb             OBJ_sm_scheme,104L,1L
+
+#define SN_sm4_cbc              "SM4-CBC"
+#define LN_sm4_cbc              "sm4-cbc"
+#define NID_sm4_cbc             1134
+#define OBJ_sm4_cbc             OBJ_sm_scheme,104L,2L
+
+#define SN_sm4_ofb128           "SM4-OFB"
+#define LN_sm4_ofb128           "sm4-ofb"
+#define NID_sm4_ofb128          1135
+#define OBJ_sm4_ofb128          OBJ_sm_scheme,104L,3L
+
+#define SN_sm4_cfb128           "SM4-CFB"
+#define LN_sm4_cfb128           "sm4-cfb"
+#define NID_sm4_cfb128          1137
+#define OBJ_sm4_cfb128          OBJ_sm_scheme,104L,4L
+
+#define SN_sm4_cfb1             "SM4-CFB1"
+#define LN_sm4_cfb1             "sm4-cfb1"
+#define NID_sm4_cfb1            1136
+#define OBJ_sm4_cfb1            OBJ_sm_scheme,104L,5L
+
+#define SN_sm4_cfb8             "SM4-CFB8"
+#define LN_sm4_cfb8             "sm4-cfb8"
+#define NID_sm4_cfb8            1138
+#define OBJ_sm4_cfb8            OBJ_sm_scheme,104L,6L
+
+#define SN_sm4_ctr              "SM4-CTR"
+#define LN_sm4_ctr              "sm4-ctr"
+#define NID_sm4_ctr             1139
+#define OBJ_sm4_ctr             OBJ_sm_scheme,104L,7L
+
 #define SN_hmac         "HMAC"
 #define LN_hmac         "hmac"
 #define NID_hmac                855
 #define SN_hmac         "HMAC"
 #define LN_hmac         "hmac"
 #define NID_hmac                855
index 06e77f7..0698668 100644 (file)
@@ -395,6 +395,9 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN
     IF[{- !$disabled{siphash} -}]
       PROGRAMS_NO_INST=siphash_internal_test
     ENDIF
     IF[{- !$disabled{siphash} -}]
       PROGRAMS_NO_INST=siphash_internal_test
     ENDIF
+    IF[{- !$disabled{sm4} -}]
+      PROGRAMS_NO_INST=sm4_internal_test
+    ENDIF
 
     SOURCE[poly1305_internal_test]=poly1305_internal_test.c
     INCLUDE[poly1305_internal_test]=.. ../include ../crypto/include
 
     SOURCE[poly1305_internal_test]=poly1305_internal_test.c
     INCLUDE[poly1305_internal_test]=.. ../include ../crypto/include
@@ -431,6 +434,10 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN
     SOURCE[siphash_internal_test]=siphash_internal_test.c
     INCLUDE[siphash_internal_test]=.. ../include ../crypto/include
     DEPEND[siphash_internal_test]=../libcrypto.a libtestutil.a
     SOURCE[siphash_internal_test]=siphash_internal_test.c
     INCLUDE[siphash_internal_test]=.. ../include ../crypto/include
     DEPEND[siphash_internal_test]=../libcrypto.a libtestutil.a
+
+    SOURCE[sm4_internal_test]=sm4_internal_test.c
+    INCLUDE[sm4_internal_test]=.. ../include ../crypto/include
+    DEPEND[sm4_internal_test]=../libcrypto.a libtestutil.a
   ENDIF
 
   IF[{- !$disabled{mdc2} -}]
   ENDIF
 
   IF[{- !$disabled{mdc2} -}]
diff --git a/test/recipes/03-test_internal_sm4.t b/test/recipes/03-test_internal_sm4.t
new file mode 100755 (executable)
index 0000000..f0ecc28
--- /dev/null
@@ -0,0 +1,20 @@
+#! /usr/bin/env perl
+# 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
+
+use strict;
+use OpenSSL::Test;              # get 'plan'
+use OpenSSL::Test::Simple;
+use OpenSSL::Test::Utils;
+
+setup("test_internal_sm4");
+
+plan skip_all => "This test is unsupported in a shared library build on Windows"
+    if $^O eq 'MSWin32' && !disabled("shared");
+
+simple_test("test_internal_sm4", "sm4_internal_test", "sm4");
index af98200..bd78964 100644 (file)
@@ -2078,6 +2078,36 @@ Operation = ENCRYPT
 Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223
 Ciphertext = A4DA23FCE6A5FFAA6D64AE9A0652A42CD161A34B65F9679F75C01F101F71276F15EF0D8D
 
 Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223
 Ciphertext = A4DA23FCE6A5FFAA6D64AE9A0652A42CD161A34B65F9679F75C01F101F71276F15EF0D8D
 
+Title = SM4 test vectors from IETF draft-ribose-cfrg-sm4
+
+Cipher = SM4-ECB
+Key = 0123456789ABCDEFFEDCBA9876543210
+Plaintext  = 0123456789ABCDEFFEDCBA9876543210
+Ciphertext = 681EDF34D206965E86B3E94F536E4246
+
+Cipher = SM4-CBC
+Key = 0123456789ABCDEFFEDCBA9876543210
+IV  = 0123456789ABCDEFFEDCBA9876543210
+Plaintext = 0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210
+Ciphertext = 2677F46B09C122CC975533105BD4A22AF6125F7275CE552C3A2BBCF533DE8A3B
+
+Cipher = SM4-OFB
+Key = 0123456789ABCDEFFEDCBA9876543210
+IV  = 0123456789ABCDEFFEDCBA9876543210
+Plaintext = 0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210
+Ciphertext = 693D9A535BAD5BB1786F53D7253A7056F2075D28B5235F58D50027E4177D2BCE
+
+Cipher = SM4-CFB
+Key = 0123456789ABCDEFFEDCBA9876543210
+IV  = 0123456789ABCDEFFEDCBA9876543210
+Plaintext = 0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210
+Ciphertext = 693D9A535BAD5BB1786F53D7253A70569ED258A85A0467CC92AAB393DD978995
+
+Cipher = SM4-CTR
+Key = 0123456789ABCDEFFEDCBA9876543210
+IV  = 0123456789ABCDEFFEDCBA9876543210
+Plaintext = AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAA
+Ciphertext = C2B4759E78AC3CF43D0852F4E8D5F9FD7256E8A5FCB65A350EE00630912E44492A0B17E1B85B060D0FBA612D8A95831638B361FD5FFACD942F081485A83CA35D
 
 Title = ARIA test vectors from RFC5794 (and others)
 
 
 Title = ARIA test vectors from RFC5794 (and others)
 
diff --git a/test/sm4_internal_test.c b/test/sm4_internal_test.c
new file mode 100644 (file)
index 0000000..2f3eaec
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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
+ */
+
+/*
+ * Internal tests for the SM4 module.
+ */
+
+#include <string.h>
+#include <openssl/opensslconf.h>
+#include "testutil.h"
+
+#ifndef OPENSSL_NO_SM4
+# include "internal/sm4.h"
+
+static int test_sm4_ecb(void)
+{
+    static const uint8_t k[SM4_BLOCK_SIZE] = {
+        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+        0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10
+    };
+
+    static const uint8_t input[SM4_BLOCK_SIZE] = {
+        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+        0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10
+    };
+
+    /*
+     * This test vector comes from Example 1 of GB/T 32907-2016,
+     * and described in Internet Draft draft-ribose-cfrg-sm4-02.
+     */
+    static const uint8_t expected[SM4_BLOCK_SIZE] = {
+        0x68, 0x1e, 0xdf, 0x34, 0xd2, 0x06, 0x96, 0x5e,
+        0x86, 0xb3, 0xe9, 0x4f, 0x53, 0x6e, 0x42, 0x46
+    };
+
+    /*
+     * This test vector comes from Example 2 from GB/T 32907-2016,
+     * and described in Internet Draft draft-ribose-cfrg-sm4-02.
+     * After 1,000,000 iterations.
+     */
+    static const uint8_t expected_iter[SM4_BLOCK_SIZE] = {
+        0x59, 0x52, 0x98, 0xc7, 0xc6, 0xfd, 0x27, 0x1f,
+        0x04, 0x02, 0xf8, 0x04, 0xc3, 0x3d, 0x3f, 0x66
+    };
+
+    int i;
+    SM4_KEY key;
+    uint8_t block[SM4_BLOCK_SIZE];
+
+    SM4_set_key(k, &key);
+    memcpy(block, input, SM4_BLOCK_SIZE);
+
+    SM4_encrypt(block, block, &key);
+    if (!TEST_mem_eq(block, SM4_BLOCK_SIZE, expected, SM4_BLOCK_SIZE))
+        return 0;
+
+    for (i = 0; i != 999999; ++i)
+        SM4_encrypt(block, block, &key);
+
+    if (!TEST_mem_eq(block, SM4_BLOCK_SIZE, expected_iter, SM4_BLOCK_SIZE))
+        return 0;
+
+    for (i = 0; i != 1000000; ++i)
+        SM4_decrypt(block, block, &key);
+
+    if (!TEST_mem_eq(block, SM4_BLOCK_SIZE, input, SM4_BLOCK_SIZE))
+        return 0;
+
+    return 1;
+}
+#endif
+
+int setup_tests(void)
+{
+#ifndef OPENSSL_NO_SM4
+    ADD_TEST(test_sm4_ecb);
+#endif
+    return 1;
+}
index a9281ce..bbaa50b 100644 (file)
@@ -4420,3 +4420,8 @@ RAND_POOL_acquire_entropy               4364      1_1_1   EXIST::FUNCTION:
 OPENSSL_sk_new_reserve                  4365   1_1_1   EXIST::FUNCTION:
 EVP_PKEY_asn1_set_check                 4366   1_1_1   EXIST::FUNCTION:
 EVP_PKEY_asn1_set_siginf                4367   1_1_1   EXIST::FUNCTION:
 OPENSSL_sk_new_reserve                  4365   1_1_1   EXIST::FUNCTION:
 EVP_PKEY_asn1_set_check                 4366   1_1_1   EXIST::FUNCTION:
 EVP_PKEY_asn1_set_siginf                4367   1_1_1   EXIST::FUNCTION:
+EVP_sm4_ctr                             4368   1_1_1   EXIST::FUNCTION:SM4
+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
index 7a4e455..1ca1112 100755 (executable)
@@ -83,7 +83,7 @@ my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF",
                         "CAST", "MD2", "MD4", "MD5", "SHA", "SHA0", "SHA1",
                         "SHA256", "SHA512", "RMD160",
                         "MDC2", "WHIRLPOOL", "RSA", "DSA", "DH", "EC", "EC2M",
                         "CAST", "MD2", "MD4", "MD5", "SHA", "SHA0", "SHA1",
                         "SHA256", "SHA512", "RMD160",
                         "MDC2", "WHIRLPOOL", "RSA", "DSA", "DH", "EC", "EC2M",
-                        "HMAC", "AES", "CAMELLIA", "SEED", "GOST", "ARIA",
+                        "HMAC", "AES", "CAMELLIA", "SEED", "GOST", "ARIA", "SM4",
                          "SCRYPT", "CHACHA", "POLY1305", "BLAKE2",
                         "SIPHASH",
                         # EC_NISTP_64_GCC_128
                          "SCRYPT", "CHACHA", "POLY1305", "BLAKE2",
                         "SIPHASH",
                         # EC_NISTP_64_GCC_128