/*
 * Copyright 2017-2021 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
        {
            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
    {
        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
