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