summaryrefslogtreecommitdiffstats
path: root/crypto/evp
diff options
context:
space:
mode:
authorRonald Tse <ronald.tse@ribose.com>2017-10-31 15:19:14 +1000
committerPauli <paul.dale@oracle.com>2017-10-31 15:19:14 +1000
commitf19a5ff9ab85313f5b30cfc9fbed3a2eea60a59d (patch)
treee93336cc7c31d2a41e19b1c906135a6ec91cabfc /crypto/evp
parentffd23209933ea0ad5543f15ca6303d63d8dac826 (diff)
SM4: Add SM4 block cipher to EVP
Reviewed-by: Richard Levitte <levitte@openssl.org> Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/4552)
Diffstat (limited to 'crypto/evp')
-rw-r--r--crypto/evp/build.info3
-rw-r--r--crypto/evp/c_allc.c10
-rw-r--r--crypto/evp/e_sm4.c100
3 files changed, 112 insertions, 1 deletions
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 <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