From c8acd603ab3f519a4bfe159fe808dc94fb3d7b1d Mon Sep 17 00:00:00 2001 From: tb <> Date: Sun, 17 Mar 2019 17:42:37 +0000 Subject: Add the SM4 block cipher from the Chinese standard GB/T 32907-2016. This is an ISC licensed version based on the sources by Ribose Inc that were ported to OpenSSL in 2017. Patch from Daniel Wyatt with minor tweaks. ok inoguchi, jsing --- src/lib/libcrypto/evp/c_all.c | 12 ++++- src/lib/libcrypto/evp/e_sm4.c | 113 ++++++++++++++++++++++++++++++++++++++++++ src/lib/libcrypto/evp/evp.h | 11 +++- 3 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 src/lib/libcrypto/evp/e_sm4.c (limited to 'src/lib/libcrypto/evp') diff --git a/src/lib/libcrypto/evp/c_all.c b/src/lib/libcrypto/evp/c_all.c index 5ed55f67f6..cce3640866 100644 --- a/src/lib/libcrypto/evp/c_all.c +++ b/src/lib/libcrypto/evp/c_all.c @@ -1,4 +1,4 @@ -/* $OpenBSD: c_all.c,v 1.24 2018/12/26 15:11:04 tb Exp $ */ +/* $OpenBSD: c_all.c,v 1.25 2019/03/17 17:42:37 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -227,6 +227,16 @@ OpenSSL_add_all_ciphers_internal(void) EVP_add_cipher(EVP_gost2814789_cfb64()); EVP_add_cipher(EVP_gost2814789_cnt()); #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 } void diff --git a/src/lib/libcrypto/evp/e_sm4.c b/src/lib/libcrypto/evp/e_sm4.c new file mode 100644 index 0000000000..554915b29c --- /dev/null +++ b/src/lib/libcrypto/evp/e_sm4.c @@ -0,0 +1,113 @@ +/* $OpenBSD: e_sm4.c,v 1.1 2019/03/17 17:42:37 tb Exp $ */ +/* + * Copyright (c) 2017, 2019 Ribose Inc + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#ifndef OPENSSL_NO_SM4 +#include +#include +#include + +#include "evp_locl.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, ctx->cipher_data); + 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, NULL, 0, 0, 0) + +static int +sm4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, + size_t len) +{ + EVP_SM4_KEY *key = EVP_C_DATA(EVP_SM4_KEY, ctx); + + CRYPTO_ctr128_encrypt(in, out, len, &key->ks, ctx->iv, ctx->buf, + &ctx->num, (block128_f)SM4_encrypt); + return 1; +} + +static const EVP_CIPHER sm4_ctr_mode = { + .nid = NID_sm4_ctr, + .block_size = 1, + .key_len = 16, + .iv_len = 16, + .flags = EVP_CIPH_CTR_MODE, + .init = sm4_init_key, + .do_cipher = sm4_ctr_cipher, + .cleanup = NULL, + .ctx_size = sizeof(EVP_SM4_KEY), + .set_asn1_parameters = NULL, + .get_asn1_parameters = NULL, + .ctrl = NULL, + .app_data = NULL, +}; + +const EVP_CIPHER * +EVP_sm4_ctr(void) +{ + return &sm4_ctr_mode; +} + +#endif diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h index 0645303686..cd9b33c9b8 100644 --- a/src/lib/libcrypto/evp/evp.h +++ b/src/lib/libcrypto/evp/evp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: evp.h,v 1.72 2019/01/22 00:59:21 dlg Exp $ */ +/* $OpenBSD: evp.h,v 1.73 2019/03/17 17:42:37 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -837,6 +837,15 @@ const EVP_CIPHER *EVP_gost2814789_cfb64(void); const EVP_CIPHER *EVP_gost2814789_cnt(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 + void OPENSSL_add_all_algorithms_noconf(void); void OPENSSL_add_all_algorithms_conf(void); -- cgit v1.2.3-55-g6feb