123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- /*
- * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
- * Copyright 2017 Ribose Inc. All Rights Reserved.
- * Ported from Ribose contributions from Botan.
- *
- * Licensed under the Apache License 2.0 (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
- #include "internal/deprecated.h"
- #include "internal/cryptlib.h"
- #ifndef OPENSSL_NO_SM4
- # include <openssl/evp.h>
- # include <openssl/modes.h>
- # include "crypto/sm4.h"
- # include "crypto/evp.h"
- # include "crypto/sm4_platform.h"
- # include "evp_local.h"
- typedef struct {
- union {
- OSSL_UNION_ALIGN;
- SM4_KEY ks;
- } ks;
- block128_f block;
- union {
- ecb128_f ecb;
- cbc128_f cbc;
- ctr128_f ctr;
- } stream;
- } EVP_SM4_KEY;
- # define BLOCK_CIPHER_generic(nid,blocksize,ivlen,nmode,mode,MODE,flags) \
- static const EVP_CIPHER sm4_##mode = { \
- nid##_##nmode,blocksize,128/8,ivlen, \
- flags|EVP_CIPH_##MODE##_MODE, \
- EVP_ORIG_GLOBAL, \
- sm4_init_key, \
- sm4_##mode##_cipher, \
- NULL, \
- sizeof(EVP_SM4_KEY), \
- NULL,NULL,NULL,NULL }; \
- const EVP_CIPHER *EVP_sm4_##mode(void) \
- { return &sm4_##mode; }
- #define DEFINE_BLOCK_CIPHERS(nid,flags) \
- BLOCK_CIPHER_generic(nid,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
- BLOCK_CIPHER_generic(nid,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
- BLOCK_CIPHER_generic(nid,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
- BLOCK_CIPHER_generic(nid,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
- BLOCK_CIPHER_generic(nid,1,16,ctr,ctr,CTR,flags)
- static int sm4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
- const unsigned char *iv, int enc)
- {
- int mode;
- EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY,ctx);
- mode = EVP_CIPHER_CTX_get_mode(ctx);
- if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
- && !enc) {
- #ifdef HWSM4_CAPABLE
- if (HWSM4_CAPABLE) {
- HWSM4_set_decrypt_key(key, &dat->ks.ks);
- dat->block = (block128_f) HWSM4_decrypt;
- dat->stream.cbc = NULL;
- # ifdef HWSM4_cbc_encrypt
- if (mode == EVP_CIPH_CBC_MODE)
- dat->stream.cbc = (cbc128_f) HWSM4_cbc_encrypt;
- # endif
- # ifdef HWSM4_ecb_encrypt
- if (mode == EVP_CIPH_ECB_MODE)
- dat->stream.ecb = (ecb128_f) HWSM4_ecb_encrypt;
- # endif
- } else
- #endif
- #ifdef VPSM4_CAPABLE
- if (VPSM4_CAPABLE) {
- vpsm4_set_decrypt_key(key, &dat->ks.ks);
- dat->block = (block128_f) vpsm4_decrypt;
- dat->stream.cbc = NULL;
- if (mode == EVP_CIPH_CBC_MODE)
- dat->stream.cbc = (cbc128_f) vpsm4_cbc_encrypt;
- else if (mode == EVP_CIPH_ECB_MODE)
- dat->stream.ecb = (ecb128_f) vpsm4_ecb_encrypt;
- } else
- #endif
- {
- dat->block = (block128_f) ossl_sm4_decrypt;
- ossl_sm4_set_key(key, EVP_CIPHER_CTX_get_cipher_data(ctx));
- }
- } else
- #ifdef HWSM4_CAPABLE
- if (HWSM4_CAPABLE) {
- HWSM4_set_encrypt_key(key, &dat->ks.ks);
- dat->block = (block128_f) HWSM4_encrypt;
- dat->stream.cbc = NULL;
- # ifdef HWSM4_cbc_encrypt
- if (mode == EVP_CIPH_CBC_MODE)
- dat->stream.cbc = (cbc128_f) HWSM4_cbc_encrypt;
- else
- # endif
- # ifdef HWSM4_ecb_encrypt
- if (mode == EVP_CIPH_ECB_MODE)
- dat->stream.ecb = (ecb128_f) HWSM4_ecb_encrypt;
- else
- # endif
- # ifdef HWSM4_ctr32_encrypt_blocks
- if (mode == EVP_CIPH_CTR_MODE)
- dat->stream.ctr = (ctr128_f) HWSM4_ctr32_encrypt_blocks;
- else
- # endif
- (void)0; /* terminate potentially open 'else' */
- } else
- #endif
- #ifdef VPSM4_CAPABLE
- if (VPSM4_CAPABLE) {
- vpsm4_set_encrypt_key(key, &dat->ks.ks);
- dat->block = (block128_f) vpsm4_encrypt;
- dat->stream.cbc = NULL;
- if (mode == EVP_CIPH_CBC_MODE)
- dat->stream.cbc = (cbc128_f) vpsm4_cbc_encrypt;
- else if (mode == EVP_CIPH_ECB_MODE)
- dat->stream.ecb = (ecb128_f) vpsm4_ecb_encrypt;
- else if (mode == EVP_CIPH_CTR_MODE)
- dat->stream.ctr = (ctr128_f) vpsm4_ctr32_encrypt_blocks;
- } else
- #endif
- {
- dat->block = (block128_f) ossl_sm4_encrypt;
- ossl_sm4_set_key(key, EVP_CIPHER_CTX_get_cipher_data(ctx));
- }
- return 1;
- }
- static int sm4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, size_t len)
- {
- EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY,ctx);
- if (dat->stream.cbc)
- (*dat->stream.cbc) (in, out, len, &dat->ks.ks, ctx->iv,
- EVP_CIPHER_CTX_is_encrypting(ctx));
- else if (EVP_CIPHER_CTX_is_encrypting(ctx))
- CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv,
- dat->block);
- else
- CRYPTO_cbc128_decrypt(in, out, len, &dat->ks,
- ctx->iv, dat->block);
- return 1;
- }
- static int sm4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, size_t len)
- {
- EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY,ctx);
- int num = EVP_CIPHER_CTX_get_num(ctx);
- CRYPTO_cfb128_encrypt(in, out, len, &dat->ks,
- ctx->iv, &num,
- EVP_CIPHER_CTX_is_encrypting(ctx), dat->block);
- EVP_CIPHER_CTX_set_num(ctx, num);
- return 1;
- }
- static int sm4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, size_t len)
- {
- size_t bl = EVP_CIPHER_CTX_get_block_size(ctx);
- size_t i;
- EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY,ctx);
- if (len < bl)
- return 1;
- if (dat->stream.ecb != NULL)
- (*dat->stream.ecb) (in, out, len, &dat->ks.ks,
- EVP_CIPHER_CTX_is_encrypting(ctx));
- else
- for (i = 0, len -= bl; i <= len; i += bl)
- (*dat->block) (in + i, out + i, &dat->ks);
- return 1;
- }
- static int sm4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, size_t len)
- {
- EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY,ctx);
- int num = EVP_CIPHER_CTX_get_num(ctx);
- CRYPTO_ofb128_encrypt(in, out, len, &dat->ks,
- ctx->iv, &num, dat->block);
- EVP_CIPHER_CTX_set_num(ctx, num);
- return 1;
- }
- static int sm4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, size_t len)
- {
- int n = EVP_CIPHER_CTX_get_num(ctx);
- unsigned int num;
- EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY,ctx);
- if (n < 0)
- return 0;
- num = (unsigned int)n;
- if (dat->stream.ctr)
- CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks,
- ctx->iv,
- EVP_CIPHER_CTX_buf_noconst(ctx),
- &num, dat->stream.ctr);
- else
- CRYPTO_ctr128_encrypt(in, out, len, &dat->ks,
- ctx->iv,
- EVP_CIPHER_CTX_buf_noconst(ctx), &num,
- dat->block);
- EVP_CIPHER_CTX_set_num(ctx, num);
- return 1;
- }
- DEFINE_BLOCK_CIPHERS(NID_sm4, 0)
- #endif
|