1 /* 2 * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * Copyright 2017 Ribose Inc. All Rights Reserved. 4 * Ported from Ribose contributions from Botan. 5 * 6 * Licensed under the Apache License 2.0 (the "License"). You may not use 7 * this file except in compliance with the License. You can obtain a copy 8 * in the file LICENSE in the source distribution or at 9 * https://www.openssl.org/source/license.html 10 */ 11 12 #include "internal/deprecated.h" 13 14 #include "internal/cryptlib.h" 15 #ifndef OPENSSL_NO_SM4 16 # include <openssl/evp.h> 17 # include <openssl/modes.h> 18 # include "crypto/sm4.h" 19 # include "crypto/evp.h" 20 # include "evp_local.h" 21 22 typedef struct { 23 SM4_KEY ks; 24 } EVP_SM4_KEY; 25 26 static int sm4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 27 const unsigned char *iv, int enc) 28 { 29 ossl_sm4_set_key(key, EVP_CIPHER_CTX_get_cipher_data(ctx)); 30 return 1; 31 } 32 33 static void sm4_cbc_encrypt(const unsigned char *in, unsigned char *out, 34 size_t len, const SM4_KEY *key, 35 unsigned char *ivec, const int enc) 36 { 37 if (enc) 38 CRYPTO_cbc128_encrypt(in, out, len, key, ivec, 39 (block128_f)ossl_sm4_encrypt); 40 else 41 CRYPTO_cbc128_decrypt(in, out, len, key, ivec, 42 (block128_f)ossl_sm4_decrypt); 43 } 44 45 static void sm4_cfb128_encrypt(const unsigned char *in, unsigned char *out, 46 size_t length, const SM4_KEY *key, 47 unsigned char *ivec, int *num, const int enc) 48 { 49 CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc, 50 (block128_f)ossl_sm4_encrypt); 51 } 52 53 static void sm4_ecb_encrypt(const unsigned char *in, unsigned char *out, 54 const SM4_KEY *key, const int enc) 55 { 56 if (enc) 57 ossl_sm4_encrypt(in, out, key); 58 else 59 ossl_sm4_decrypt(in, out, key); 60 } 61 62 static void sm4_ofb128_encrypt(const unsigned char *in, unsigned char *out, 63 size_t length, const SM4_KEY *key, 64 unsigned char *ivec, int *num) 65 { 66 CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num, 67 (block128_f)ossl_sm4_encrypt); 68 } 69 70 IMPLEMENT_BLOCK_CIPHER(sm4, ks, sm4, EVP_SM4_KEY, NID_sm4, 71 16, 16, 16, 128, EVP_CIPH_FLAG_DEFAULT_ASN1, 72 sm4_init_key, 0, 0, 0, 0) 73 74 static int sm4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 75 const unsigned char *in, size_t len) 76 { 77 int n = EVP_CIPHER_CTX_get_num(ctx); 78 unsigned int num; 79 EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY, ctx); 80 81 if (n < 0) 82 return 0; 83 num = (unsigned int)n; 84 85 CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv, 86 EVP_CIPHER_CTX_buf_noconst(ctx), &num, 87 (block128_f)ossl_sm4_encrypt); 88 EVP_CIPHER_CTX_set_num(ctx, num); 89 return 1; 90 } 91 92 static const EVP_CIPHER sm4_ctr_mode = { 93 NID_sm4_ctr, 1, 16, 16, 94 EVP_CIPH_CTR_MODE, 95 EVP_ORIG_GLOBAL, 96 sm4_init_key, 97 sm4_ctr_cipher, 98 NULL, 99 sizeof(EVP_SM4_KEY), 100 NULL, NULL, NULL, NULL 101 }; 102 103 const EVP_CIPHER *EVP_sm4_ctr(void) 104 { 105 return &sm4_ctr_mode; 106 } 107 108 #endif 109