/*
 * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved.
 *
 * 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 "cipher_sm4.h"

static int cipher_hw_sm4_initkey(PROV_CIPHER_CTX *ctx,
                                 const unsigned char *key, size_t keylen)
{
    PROV_SM4_CTX *sctx =  (PROV_SM4_CTX *)ctx;
    SM4_KEY *ks = &sctx->ks.ks;

    ctx->ks = ks;
    if (ctx->enc
            || (ctx->mode != EVP_CIPH_ECB_MODE
                && ctx->mode != EVP_CIPH_CBC_MODE)) {
#ifdef HWSM4_CAPABLE
        if (HWSM4_CAPABLE) {
            HWSM4_set_encrypt_key(key, ks);
            ctx->block = (block128_f)HWSM4_encrypt;
            ctx->stream.cbc = NULL;
#ifdef HWSM4_cbc_encrypt
            if (ctx->mode == EVP_CIPH_CBC_MODE)
                ctx->stream.cbc = (cbc128_f)HWSM4_cbc_encrypt;
            else
#endif
#ifdef HWSM4_ecb_encrypt
            if (ctx->mode == EVP_CIPH_ECB_MODE)
                ctx->stream.ecb = (ecb128_f)HWSM4_ecb_encrypt;
            else
#endif
#ifdef HWSM4_ctr32_encrypt_blocks
            if (ctx->mode == EVP_CIPH_CTR_MODE)
                ctx->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, ks);
            ctx->block = (block128_f)vpsm4_encrypt;
            ctx->stream.cbc = NULL;
            if (ctx->mode == EVP_CIPH_CBC_MODE)
                ctx->stream.cbc = (cbc128_f)vpsm4_cbc_encrypt;
            else if (ctx->mode == EVP_CIPH_ECB_MODE)
                ctx->stream.ecb = (ecb128_f)vpsm4_ecb_encrypt;
            else if (ctx->mode == EVP_CIPH_CTR_MODE)
                ctx->stream.ctr = (ctr128_f)vpsm4_ctr32_encrypt_blocks;
        } else
#endif
        {
            ossl_sm4_set_key(key, ks);
            ctx->block = (block128_f)ossl_sm4_encrypt;
        }
    } else {
#ifdef HWSM4_CAPABLE
        if (HWSM4_CAPABLE) {
            HWSM4_set_decrypt_key(key, ks);
            ctx->block = (block128_f)HWSM4_decrypt;
            ctx->stream.cbc = NULL;
#ifdef HWSM4_cbc_encrypt
            if (ctx->mode == EVP_CIPH_CBC_MODE)
                ctx->stream.cbc = (cbc128_f)HWSM4_cbc_encrypt;
#endif
#ifdef HWSM4_ecb_encrypt
            if (ctx->mode == EVP_CIPH_ECB_MODE)
                ctx->stream.ecb = (ecb128_f)HWSM4_ecb_encrypt;
#endif
        } else
#endif
#ifdef VPSM4_CAPABLE
        if (VPSM4_CAPABLE) {
            vpsm4_set_decrypt_key(key, ks);
            ctx->block = (block128_f)vpsm4_decrypt;
            ctx->stream.cbc = NULL;
            if (ctx->mode == EVP_CIPH_CBC_MODE)
                ctx->stream.cbc = (cbc128_f)vpsm4_cbc_encrypt;
        else if (ctx->mode == EVP_CIPH_ECB_MODE)
                ctx->stream.ecb = (ecb128_f)vpsm4_ecb_encrypt;
        } else
#endif
        {
            ossl_sm4_set_key(key, ks);
            ctx->block = (block128_f)ossl_sm4_decrypt;
        }
    }

    return 1;
}

IMPLEMENT_CIPHER_HW_COPYCTX(cipher_hw_sm4_copyctx, PROV_SM4_CTX)

# define PROV_CIPHER_HW_sm4_mode(mode)                                         \
static const PROV_CIPHER_HW sm4_##mode = {                                     \
    cipher_hw_sm4_initkey,                                                     \
    ossl_cipher_hw_generic_##mode,                                             \
    cipher_hw_sm4_copyctx                                                      \
};                                                                             \
const PROV_CIPHER_HW *ossl_prov_cipher_hw_sm4_##mode(size_t keybits)           \
{                                                                              \
    return &sm4_##mode;                                                        \
}

PROV_CIPHER_HW_sm4_mode(cbc)
PROV_CIPHER_HW_sm4_mode(ecb)
PROV_CIPHER_HW_sm4_mode(ofb128)
PROV_CIPHER_HW_sm4_mode(cfb128)
PROV_CIPHER_HW_sm4_mode(ctr)
