From f19a5ff9ab85313f5b30cfc9fbed3a2eea60a59d Mon Sep 17 00:00:00 2001 From: Ronald Tse Date: Tue, 31 Oct 2017 15:19:14 +1000 Subject: [PATCH] SM4: Add SM4 block cipher to EVP Reviewed-by: Richard Levitte Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/4552) --- CHANGES | 5 + Configure | 3 +- INSTALL | 6 +- config | 2 +- crypto/evp/build.info | 3 +- crypto/evp/c_allc.c | 10 + crypto/evp/e_sm4.c | 100 ++++++++++ crypto/include/internal/sm4.h | 37 ++++ crypto/objects/obj_dat.h | 60 +++++- crypto/objects/obj_mac.num | 10 + crypto/objects/objects.txt | 21 +- crypto/sm4/build.info | 4 + crypto/sm4/sm4.c | 233 ++++++++++++++++++++++ doc/man3/EVP_sm4.pod | 65 ++++++ include/openssl/evp.h | 9 + include/openssl/obj_mac.h | 48 +++++ test/build.info | 7 + test/recipes/03-test_internal_sm4.t | 20 ++ test/recipes/30-test_evp_data/evpciph.txt | 30 +++ test/sm4_internal_test.c | 86 ++++++++ util/libcrypto.num | 5 + util/mkdef.pl | 2 +- 22 files changed, 752 insertions(+), 14 deletions(-) create mode 100644 crypto/evp/e_sm4.c create mode 100644 crypto/include/internal/sm4.h create mode 100644 crypto/sm4/build.info create mode 100644 crypto/sm4/sm4.c create mode 100644 doc/man3/EVP_sm4.pod create mode 100755 test/recipes/03-test_internal_sm4.t create mode 100644 test/sm4_internal_test.c diff --git a/CHANGES b/CHANGES index 2e77eb1649..9ef85d6c89 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,11 @@ Changes between 1.1.0f and 1.1.1 [xx XXX xxxx] + *) Add SM4 implemented according to GB/T 32907-2016. + [ Jack Lloyd , + Ronald Tse , + Erick Borsboom ] + *) Reimplement -newreq-nodes and ERR_error_string_n; the original author does not agree with the license change. [Rich Salz] diff --git a/Configure b/Configure index b1b847c59d..247f276de4 100755 --- 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", - "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", @@ -394,6 +394,7 @@ my @disablables = ( "seed", "shared", "siphash", + "sm4", "sock", "srp", "srtp", diff --git a/INSTALL b/INSTALL index 064b2f8b00..c4fcc05329 100644 --- a/INSTALL +++ b/INSTALL @@ -512,9 +512,9 @@ Build without support for the specified algorithm, where 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 diff --git a/config b/config index 6c01ebd8b2..14d735c618 100755 --- 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 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 diff --git a/crypto/evp/build.info b/crypto/evp/build.info index d65276a0c7..0305738011 100644 --- a/crypto/evp/build.info +++ b/crypto/evp/build.info @@ -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\ - 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 \ @@ -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_sm4.o]=.. ../modes INCLUDE[e_des.o]=.. INCLUDE[e_des3.o]=.. diff --git a/crypto/evp/c_allc.c b/crypto/evp/c_allc.c index ee77d65be9..086b3c4d51 100644 --- a/crypto/evp/c_allc.c +++ b/crypto/evp/c_allc.c @@ -79,6 +79,16 @@ void openssl_add_all_ciphers_int(void) 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()); diff --git a/crypto/evp/e_sm4.c b/crypto/evp/e_sm4.c new file mode 100644 index 0000000000..79deb65636 --- /dev/null +++ b/crypto/evp/e_sm4.c @@ -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 +# include +# 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 index 0000000000..f1f157ef53 --- /dev/null +++ b/crypto/include/internal/sm4.h @@ -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 +# include + +# 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 diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h index 471202f0b6..866fa34cc1 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[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 */ @@ -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,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]}, @@ -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]}, + {"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" */ @@ -2316,6 +2336,7 @@ static const unsigned int sn_objs[NUM_SN] = { 46, /* "IDEA-OFB" */ 1004, /* "INN" */ 181, /* "ISO" */ + 1140, /* "ISO-CN" */ 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" */ + 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" */ @@ -2979,6 +3007,7 @@ static const unsigned int sn_objs[NUM_SN] = { 681, /* "onBasis" */ 1089, /* "organizationIdentifier" */ 491, /* "organizationalStatus" */ + 1141, /* "oscca" */ 475, /* "otherMailbox" */ 876, /* "owner" */ 489, /* "pagerTelephoneNumber" */ @@ -3233,6 +3262,7 @@ static const unsigned int sn_objs[NUM_SN] = { 52, /* "signingTime" */ 454, /* "simpleSecurityObject" */ 496, /* "singleLevelQuality" */ + 1142, /* "sm-scheme" */ 387, /* "snmpv2" */ 660, /* "street" */ 85, /* "subjectAltName" */ @@ -3285,7 +3315,7 @@ static const unsigned int sn_objs[NUM_SN] = { 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" */ @@ -3354,6 +3384,7 @@ static const unsigned int ln_objs[NUM_LN] = { 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" */ @@ -4082,6 +4113,7 @@ static const unsigned int ln_objs[NUM_LN] = { 17, /* "organizationName" */ 491, /* "organizationalStatus" */ 18, /* "organizationalUnitName" */ + 1141, /* "oscca" */ 475, /* "otherMailbox" */ 876, /* "owner" */ 935, /* "pSpecified" */ @@ -4366,6 +4398,14 @@ static const unsigned int ln_objs[NUM_LN] = { 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" */ @@ -4413,7 +4453,7 @@ static const unsigned int ln_objs[NUM_LN] = { 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 */ @@ -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 */ + 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 */ @@ -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 */ + 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 */ @@ -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 */ + 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 */ @@ -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 */ + 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 */ diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num index 26495f2a05..4e5f702c29 100644 --- a/crypto/objects/obj_mac.num +++ b/crypto/objects/obj_mac.num @@ -1130,3 +1130,13 @@ ffdhe6144 1129 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 diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt index 9aecacf625..22e69b8f1c 100644 --- a/crypto/objects/objects.txt +++ b/crypto/objects/objects.txt @@ -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 -!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 @@ -1461,6 +1461,23 @@ kisa 1 5 : SEED-CFB : seed-cfb !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 @@ -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 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 diff --git a/crypto/sm4/build.info b/crypto/sm4/build.info new file mode 100644 index 0000000000..b65a7d149e --- /dev/null +++ b/crypto/sm4/build.info @@ -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 index 0000000000..0c819a4b68 --- /dev/null +++ b/crypto/sm4/sm4.c @@ -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 +#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 index 0000000000..d5c99cd4d9 --- /dev/null +++ b/doc/man3/EVP_sm4.pod @@ -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 + + const EVP_CIPHER *EVP_ciphername(void) + +I is used a placeholder for any of the described cipher +functions, such as I. + +=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 structure that contains the +implementation of the symmetric cipher. See L for +details of the B structure. + +=head1 SEE ALSO + +L, +L, +L + +=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. + +=cut + diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 90add836c0..3a98e1da9e 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -916,6 +916,15 @@ const EVP_CIPHER *EVP_seed_cfb128(void); 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 \ diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h index 58c44f02f5..02447dcd50 100644 --- a/include/openssl/obj_mac.h +++ b/include/openssl/obj_mac.h @@ -4584,6 +4584,54 @@ #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 diff --git a/test/build.info b/test/build.info index 06e77f7b1b..0698668d7a 100644 --- a/test/build.info +++ b/test/build.info @@ -395,6 +395,9 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN 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 @@ -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[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} -}] diff --git a/test/recipes/03-test_internal_sm4.t b/test/recipes/03-test_internal_sm4.t new file mode 100755 index 0000000000..f0ecc28573 --- /dev/null +++ b/test/recipes/03-test_internal_sm4.t @@ -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"); diff --git a/test/recipes/30-test_evp_data/evpciph.txt b/test/recipes/30-test_evp_data/evpciph.txt index af98200a02..bd7896431a 100644 --- a/test/recipes/30-test_evp_data/evpciph.txt +++ b/test/recipes/30-test_evp_data/evpciph.txt @@ -2078,6 +2078,36 @@ Operation = ENCRYPT 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) diff --git a/test/sm4_internal_test.c b/test/sm4_internal_test.c new file mode 100644 index 0000000000..2f3eaecbce --- /dev/null +++ b/test/sm4_internal_test.c @@ -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 +#include +#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; +} diff --git a/util/libcrypto.num b/util/libcrypto.num index a9281cede0..bbaa50bf1d 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -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: +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 diff --git a/util/mkdef.pl b/util/mkdef.pl index 7a4e455cd9..1ca1112d04 100755 --- a/util/mkdef.pl +++ b/util/mkdef.pl @@ -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", - "HMAC", "AES", "CAMELLIA", "SEED", "GOST", "ARIA", + "HMAC", "AES", "CAMELLIA", "SEED", "GOST", "ARIA", "SM4", "SCRYPT", "CHACHA", "POLY1305", "BLAKE2", "SIPHASH", # EC_NISTP_64_GCC_128 -- GitLab