xref: /openbsd-src/lib/libcrypto/evp/e_sm4.c (revision 9bac3682a248384cde711fdda825c3b5960b1005)
1*9bac3682Sbeck /*	$OpenBSD: e_sm4.c,v 1.13 2024/04/09 13:52:41 beck Exp $	*/
285824259Stb /*
385824259Stb  * Copyright (c) 2017, 2019 Ribose Inc
485824259Stb  *
585824259Stb  * Permission to use, copy, modify, and/or distribute this software for any
685824259Stb  * purpose with or without fee is hereby granted, provided that the above
785824259Stb  * copyright notice and this permission notice appear in all copies.
885824259Stb  *
985824259Stb  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1085824259Stb  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1185824259Stb  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1285824259Stb  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1385824259Stb  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1485824259Stb  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1585824259Stb  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1685824259Stb  */
1785824259Stb 
1885824259Stb #include <openssl/opensslconf.h>
1985824259Stb 
2085824259Stb #ifndef OPENSSL_NO_SM4
2185824259Stb #include <openssl/evp.h>
2285824259Stb #include <openssl/modes.h>
2385824259Stb #include <openssl/sm4.h>
2485824259Stb 
25c9675a23Stb #include "evp_local.h"
2685824259Stb 
2785824259Stb typedef struct {
2885824259Stb 	SM4_KEY ks;
2985824259Stb } EVP_SM4_KEY;
3085824259Stb 
3185824259Stb static int
sm4_init_key(EVP_CIPHER_CTX * ctx,const unsigned char * key,const unsigned char * iv,int enc)3285824259Stb sm4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
3385824259Stb     const unsigned char *iv, int enc)
3485824259Stb {
3585824259Stb 	SM4_set_key(key, ctx->cipher_data);
3685824259Stb 	return 1;
3785824259Stb }
3885824259Stb 
3985824259Stb 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)4085824259Stb sm4_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len,
4185824259Stb     const SM4_KEY *key, unsigned char *ivec, const int enc)
4285824259Stb {
4385824259Stb 	if (enc)
4485824259Stb 		CRYPTO_cbc128_encrypt(in, out, len, key, ivec,
4585824259Stb 		    (block128_f)SM4_encrypt);
4685824259Stb 	else
4785824259Stb 		CRYPTO_cbc128_decrypt(in, out, len, key, ivec,
4885824259Stb 		    (block128_f)SM4_decrypt);
4985824259Stb }
5085824259Stb 
5185824259Stb 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)5285824259Stb sm4_cfb128_encrypt(const unsigned char *in, unsigned char *out, size_t length,
5385824259Stb     const SM4_KEY *key, unsigned char *ivec, int *num, const int enc)
5485824259Stb {
5585824259Stb 	CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
5685824259Stb 	    (block128_f)SM4_encrypt);
5785824259Stb }
5885824259Stb 
5985824259Stb static void
sm4_ecb_encrypt(const unsigned char * in,unsigned char * out,const SM4_KEY * key,const int enc)6085824259Stb sm4_ecb_encrypt(const unsigned char *in, unsigned char *out, const SM4_KEY *key,
6185824259Stb     const int enc)
6285824259Stb {
6385824259Stb 	if (enc)
6485824259Stb 		SM4_encrypt(in, out, key);
6585824259Stb 	else
6685824259Stb 		SM4_decrypt(in, out, key);
6785824259Stb }
6885824259Stb 
6985824259Stb static void
sm4_ofb128_encrypt(const unsigned char * in,unsigned char * out,size_t length,const SM4_KEY * key,unsigned char * ivec,int * num)7085824259Stb sm4_ofb128_encrypt(const unsigned char *in, unsigned char *out, size_t length,
7185824259Stb     const SM4_KEY *key, unsigned char *ivec, int *num)
7285824259Stb {
7385824259Stb 	CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
7485824259Stb 	    (block128_f)SM4_encrypt);
7585824259Stb }
7685824259Stb 
778dc670f6Sjsing static int
sm4_cbc_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)788dc670f6Sjsing sm4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
798dc670f6Sjsing {
808dc670f6Sjsing 	while (inl >= EVP_MAXCHUNK) {
81d5650aa3Sjsing 		sm4_cbc_encrypt(in, out, EVP_MAXCHUNK, &((EVP_SM4_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
828dc670f6Sjsing 		inl -= EVP_MAXCHUNK;
838dc670f6Sjsing 		in += EVP_MAXCHUNK;
848dc670f6Sjsing 		out += EVP_MAXCHUNK;
858dc670f6Sjsing 	}
868dc670f6Sjsing 
878dc670f6Sjsing 	if (inl)
88d5650aa3Sjsing 		sm4_cbc_encrypt(in, out, inl, &((EVP_SM4_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
898dc670f6Sjsing 
908dc670f6Sjsing 	return 1;
918dc670f6Sjsing }
928dc670f6Sjsing 
938dc670f6Sjsing static int
sm4_cfb128_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)948dc670f6Sjsing sm4_cfb128_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
958dc670f6Sjsing {
968dc670f6Sjsing 	size_t chunk = EVP_MAXCHUNK;
978dc670f6Sjsing 
988dc670f6Sjsing 	if (inl < chunk)
998dc670f6Sjsing 		chunk = inl;
1008dc670f6Sjsing 
1018dc670f6Sjsing 	while (inl && inl >= chunk) {
1027a606269Sjsing 		sm4_cfb128_encrypt(in, out, chunk, &((EVP_SM4_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
1038dc670f6Sjsing 		inl -= chunk;
1048dc670f6Sjsing 		in += chunk;
1058dc670f6Sjsing 		out += chunk;
1068dc670f6Sjsing 		if (inl < chunk)
1078dc670f6Sjsing 			chunk = inl;
1088dc670f6Sjsing 	}
1098dc670f6Sjsing 
1108dc670f6Sjsing 	return 1;
1118dc670f6Sjsing }
1128dc670f6Sjsing 
1138dc670f6Sjsing static int
sm4_ecb_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)1148dc670f6Sjsing sm4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
1158dc670f6Sjsing {
1168dc670f6Sjsing 	size_t i, bl;
1178dc670f6Sjsing 
1188dc670f6Sjsing 	bl = ctx->cipher->block_size;
1198dc670f6Sjsing 
1208dc670f6Sjsing 	if (inl < bl)
1218dc670f6Sjsing 		return 1;
1228dc670f6Sjsing 
1238dc670f6Sjsing 	inl -= bl;
1248dc670f6Sjsing 
1258dc670f6Sjsing 	for (i = 0; i <= inl; i += bl)
1268dc670f6Sjsing 		sm4_ecb_encrypt(in + i, out + i, &((EVP_SM4_KEY *)ctx->cipher_data)->ks, ctx->encrypt);
1278dc670f6Sjsing 
1288dc670f6Sjsing 	return 1;
1298dc670f6Sjsing }
1308dc670f6Sjsing 
1318dc670f6Sjsing static int
sm4_ofb_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)1328dc670f6Sjsing sm4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
1338dc670f6Sjsing {
1348dc670f6Sjsing 	while (inl >= EVP_MAXCHUNK) {
135d5650aa3Sjsing 		sm4_ofb128_encrypt(in, out, EVP_MAXCHUNK, &((EVP_SM4_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
1368dc670f6Sjsing 		inl -= EVP_MAXCHUNK;
1378dc670f6Sjsing 		in += EVP_MAXCHUNK;
1388dc670f6Sjsing 		out += EVP_MAXCHUNK;
1398dc670f6Sjsing 	}
1408dc670f6Sjsing 
1418dc670f6Sjsing 	if (inl)
142d5650aa3Sjsing 		sm4_ofb128_encrypt(in, out, inl, &((EVP_SM4_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
1438dc670f6Sjsing 
1448dc670f6Sjsing 	return 1;
1458dc670f6Sjsing }
1468dc670f6Sjsing 
1478dc670f6Sjsing static const EVP_CIPHER sm4_cbc = {
1488dc670f6Sjsing 	.nid = NID_sm4_cbc,
1498dc670f6Sjsing 	.block_size = 16,
1508dc670f6Sjsing 	.key_len = 16,
1518dc670f6Sjsing 	.iv_len = 16,
1528dc670f6Sjsing 	.flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CBC_MODE,
1538dc670f6Sjsing 	.init = sm4_init_key,
1548dc670f6Sjsing 	.do_cipher = sm4_cbc_cipher,
1558dc670f6Sjsing 	.cleanup = NULL,
1568dc670f6Sjsing 	.ctx_size = sizeof(EVP_SM4_KEY),
157040dcbc5Stb 	.set_asn1_parameters = NULL,
158040dcbc5Stb 	.get_asn1_parameters = NULL,
159040dcbc5Stb 	.ctrl = NULL,
1608dc670f6Sjsing };
1618dc670f6Sjsing 
1628dc670f6Sjsing const EVP_CIPHER *
EVP_sm4_cbc(void)1638dc670f6Sjsing EVP_sm4_cbc(void)
1648dc670f6Sjsing {
1658dc670f6Sjsing 	return &sm4_cbc;
1668dc670f6Sjsing }
167*9bac3682Sbeck LCRYPTO_ALIAS(EVP_sm4_cbc);
1688dc670f6Sjsing 
1698dc670f6Sjsing static const EVP_CIPHER sm4_cfb128 = {
1708dc670f6Sjsing 	.nid = NID_sm4_cfb128,
1718dc670f6Sjsing 	.block_size = 1,
1728dc670f6Sjsing 	.key_len = 16,
1738dc670f6Sjsing 	.iv_len = 16,
1748dc670f6Sjsing 	.flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CFB_MODE,
1758dc670f6Sjsing 	.init = sm4_init_key,
1768dc670f6Sjsing 	.do_cipher = sm4_cfb128_cipher,
1778dc670f6Sjsing 	.cleanup = NULL,
1788dc670f6Sjsing 	.ctx_size = sizeof(EVP_SM4_KEY),
179040dcbc5Stb 	.set_asn1_parameters = NULL,
180040dcbc5Stb 	.get_asn1_parameters = NULL,
181040dcbc5Stb 	.ctrl = NULL,
1828dc670f6Sjsing };
1838dc670f6Sjsing 
1848dc670f6Sjsing const EVP_CIPHER *
EVP_sm4_cfb128(void)1858dc670f6Sjsing EVP_sm4_cfb128(void)
1868dc670f6Sjsing {
1878dc670f6Sjsing 	return &sm4_cfb128;
1888dc670f6Sjsing }
189*9bac3682Sbeck LCRYPTO_ALIAS(EVP_sm4_cfb128);
1908dc670f6Sjsing 
1918dc670f6Sjsing static const EVP_CIPHER sm4_ofb = {
1928dc670f6Sjsing 	.nid = NID_sm4_ofb128,
1938dc670f6Sjsing 	.block_size = 1,
1948dc670f6Sjsing 	.key_len = 16,
1958dc670f6Sjsing 	.iv_len = 16,
1968dc670f6Sjsing 	.flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_OFB_MODE,
1978dc670f6Sjsing 	.init = sm4_init_key,
1988dc670f6Sjsing 	.do_cipher = sm4_ofb_cipher,
1998dc670f6Sjsing 	.cleanup = NULL,
2008dc670f6Sjsing 	.ctx_size = sizeof(EVP_SM4_KEY),
201040dcbc5Stb 	.set_asn1_parameters = NULL,
202040dcbc5Stb 	.get_asn1_parameters = NULL,
203040dcbc5Stb 	.ctrl = NULL,
2048dc670f6Sjsing };
2058dc670f6Sjsing 
2068dc670f6Sjsing const EVP_CIPHER *
EVP_sm4_ofb(void)2078dc670f6Sjsing EVP_sm4_ofb(void)
2088dc670f6Sjsing {
2098dc670f6Sjsing 	return &sm4_ofb;
2108dc670f6Sjsing }
211*9bac3682Sbeck LCRYPTO_ALIAS(EVP_sm4_ofb);
2128dc670f6Sjsing 
2138dc670f6Sjsing static const EVP_CIPHER sm4_ecb = {
2148dc670f6Sjsing 	.nid = NID_sm4_ecb,
2158dc670f6Sjsing 	.block_size = 16,
2168dc670f6Sjsing 	.key_len = 16,
2178dc670f6Sjsing 	.iv_len = 0,
2188dc670f6Sjsing 	.flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_ECB_MODE,
2198dc670f6Sjsing 	.init = sm4_init_key,
2208dc670f6Sjsing 	.do_cipher = sm4_ecb_cipher,
2218dc670f6Sjsing 	.cleanup = NULL,
2228dc670f6Sjsing 	.ctx_size = sizeof(EVP_SM4_KEY),
22363177169Stb 	.set_asn1_parameters = NULL,
22463177169Stb 	.get_asn1_parameters = NULL,
22563177169Stb 	.ctrl = NULL,
2268dc670f6Sjsing };
2278dc670f6Sjsing 
2288dc670f6Sjsing const EVP_CIPHER *
EVP_sm4_ecb(void)2298dc670f6Sjsing EVP_sm4_ecb(void)
2308dc670f6Sjsing {
2318dc670f6Sjsing 	return &sm4_ecb;
2328dc670f6Sjsing }
233*9bac3682Sbeck LCRYPTO_ALIAS(EVP_sm4_ecb);
23485824259Stb 
23585824259Stb static int
sm4_ctr_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t len)23685824259Stb sm4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
23785824259Stb     size_t len)
23885824259Stb {
2398dc670f6Sjsing 	EVP_SM4_KEY *key = ((EVP_SM4_KEY *)(ctx)->cipher_data);
24085824259Stb 
24185824259Stb 	CRYPTO_ctr128_encrypt(in, out, len, &key->ks, ctx->iv, ctx->buf,
24285824259Stb 	    &ctx->num, (block128_f)SM4_encrypt);
24385824259Stb 	return 1;
24485824259Stb }
24585824259Stb 
24685824259Stb static const EVP_CIPHER sm4_ctr_mode = {
24785824259Stb 	.nid = NID_sm4_ctr,
24885824259Stb 	.block_size = 1,
24985824259Stb 	.key_len = 16,
25085824259Stb 	.iv_len = 16,
25185824259Stb 	.flags = EVP_CIPH_CTR_MODE,
25285824259Stb 	.init = sm4_init_key,
25385824259Stb 	.do_cipher = sm4_ctr_cipher,
25485824259Stb 	.cleanup = NULL,
25585824259Stb 	.ctx_size = sizeof(EVP_SM4_KEY),
25685824259Stb 	.set_asn1_parameters = NULL,
25785824259Stb 	.get_asn1_parameters = NULL,
25885824259Stb 	.ctrl = NULL,
25985824259Stb };
26085824259Stb 
26185824259Stb const EVP_CIPHER *
EVP_sm4_ctr(void)26285824259Stb EVP_sm4_ctr(void)
26385824259Stb {
26485824259Stb 	return &sm4_ctr_mode;
26585824259Stb }
266*9bac3682Sbeck LCRYPTO_ALIAS(EVP_sm4_ctr);
26785824259Stb #endif
268