xref: /dragonfly/crypto/libressl/crypto/evp/e_sm4.c (revision 72c33676)
1 /*	$OpenBSD: e_sm4.c,v 1.1 2019/03/17 17:42:37 tb Exp $	*/
2 /*
3  * Copyright (c) 2017, 2019 Ribose Inc
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <openssl/opensslconf.h>
19 
20 #ifndef OPENSSL_NO_SM4
21 #include <openssl/evp.h>
22 #include <openssl/modes.h>
23 #include <openssl/sm4.h>
24 
25 #include "evp_locl.h"
26 
27 typedef struct {
28 	SM4_KEY ks;
29 } EVP_SM4_KEY;
30 
31 static int
32 sm4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
33     const unsigned char *iv, int enc)
34 {
35 	SM4_set_key(key, ctx->cipher_data);
36 	return 1;
37 }
38 
39 static void
40 sm4_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len,
41     const SM4_KEY *key, unsigned char *ivec, const int enc)
42 {
43 	if (enc)
44 		CRYPTO_cbc128_encrypt(in, out, len, key, ivec,
45 		    (block128_f)SM4_encrypt);
46 	else
47 		CRYPTO_cbc128_decrypt(in, out, len, key, ivec,
48 		    (block128_f)SM4_decrypt);
49 }
50 
51 static void
52 sm4_cfb128_encrypt(const unsigned char *in, unsigned char *out, size_t length,
53     const SM4_KEY *key, unsigned char *ivec, int *num, const int enc)
54 {
55 	CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
56 	    (block128_f)SM4_encrypt);
57 }
58 
59 static void
60 sm4_ecb_encrypt(const unsigned char *in, unsigned char *out, const SM4_KEY *key,
61     const int enc)
62 {
63 	if (enc)
64 		SM4_encrypt(in, out, key);
65 	else
66 		SM4_decrypt(in, out, key);
67 }
68 
69 static void
70 sm4_ofb128_encrypt(const unsigned char *in, unsigned char *out, size_t length,
71     const SM4_KEY *key, unsigned char *ivec, int *num)
72 {
73 	CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
74 	    (block128_f)SM4_encrypt);
75 }
76 
77 IMPLEMENT_BLOCK_CIPHER(sm4, ks, sm4, EVP_SM4_KEY, NID_sm4, 16, 16, 16, 128,
78     EVP_CIPH_FLAG_DEFAULT_ASN1, sm4_init_key, NULL, 0, 0, 0)
79 
80 static int
81 sm4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
82     size_t len)
83 {
84 	EVP_SM4_KEY *key = EVP_C_DATA(EVP_SM4_KEY, ctx);
85 
86 	CRYPTO_ctr128_encrypt(in, out, len, &key->ks, ctx->iv, ctx->buf,
87 	    &ctx->num, (block128_f)SM4_encrypt);
88 	return 1;
89 }
90 
91 static const EVP_CIPHER sm4_ctr_mode = {
92 	.nid = NID_sm4_ctr,
93 	.block_size = 1,
94 	.key_len = 16,
95 	.iv_len = 16,
96 	.flags = EVP_CIPH_CTR_MODE,
97 	.init = sm4_init_key,
98 	.do_cipher = sm4_ctr_cipher,
99 	.cleanup = NULL,
100 	.ctx_size = sizeof(EVP_SM4_KEY),
101 	.set_asn1_parameters = NULL,
102 	.get_asn1_parameters = NULL,
103 	.ctrl = NULL,
104 	.app_data = NULL,
105 };
106 
107 const EVP_CIPHER *
108 EVP_sm4_ctr(void)
109 {
110 	return &sm4_ctr_mode;
111 }
112 
113 #endif
114