/*
 * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/******************************************************************************
 * @file     ck_aes.c
 * @brief    CSI Source File for aes driver
 * @version  V1.0
 * @date     02. June 2017
 ******************************************************************************/
#include <string.h>
#include "csi_core.h"
#include "drv_aes.h"
#include "ck_aes.h"

#define ERR_AES(errno) (CSI_DRV_ERRNO_AES_BASE | errno)
#define AES_NULL_PARA_CHK(para)                         \
        do {                                        \
            if (para == NULL) {                     \
                return ERR_AES(EDRV_PARAMETER);   \
            }                                       \
        } while (0)
static ck_aes_reg_t *aes_reg = NULL;
volatile static uint8_t block_cal_done = 0;

typedef struct {
    uint32_t base;
    uint32_t irq;
    void *iv;
    uint8_t *result_out;
    uint32_t len;
    aes_event_cb_t cb;
    aes_mode_e mode;
    aes_key_len_bits_e keylen;
    aes_endian_mode_e endian;
    aes_crypto_mode_e enc;
    aes_status_t status;
} ck_aes_priv_t;

extern int32_t target_get_aes_count(void);
extern int32_t target_get_aes(int32_t idx, uint32_t *base, uint32_t *irq);

static ck_aes_priv_t aes_handle[CONFIG_AES_NUM];

/* Driver Capabilities */
static const aes_capabilities_t driver_capabilities = {
    .ecb_mode = 1, /* ECB mode */
    .cbc_mode = 1, /* CBC mode */
    .cfb_mode = 0, /* CFB mode */
    .ofb_mode = 0, /* OFB mode */
    .ctr_mode = 0, /* CTR mode */
    .bits_128 = 1, /* 128bits key length mode */
    .bits_192 = 1, /* 192bits key lenght mode */
    .bits_256 = 1  /* 256bits key length mode */
};

extern int32_t target_get_aes(int32_t idx, uint32_t *base, uint32_t *irq);
extern int32_t target_get_aes_count(void);
//
// Functions
//

static inline void aes_set_opcode(aes_crypto_mode_e opcode)
{
    aes_reg->ctrl &= ~(3 << AES_OPCODE_OFFSET);          //clear bit[7:6]
    aes_reg->ctrl |= (opcode << AES_OPCODE_OFFSET);    //set opcode
}

static inline void aes_set_endian(aes_endian_mode_e endian)
{
    if (endian == AES_ENDIAN_LITTLE) {
        aes_reg->ctrl &= ~AES_LITTLE_ENDIAN;
    } else {
        aes_reg->ctrl |= AES_LITTLE_ENDIAN;
    }
}

static inline uint32_t aes_set_keylen(aes_key_len_bits_e keylength)
{
    aes_reg->ctrl &= ~(3 << AES_KEY_LEN_OFFSET);        //clear bit[5:4]
    aes_reg->ctrl |= (keylength << AES_KEY_LEN_OFFSET);// Set key length

    return 0;
}

static inline void aes_set_mode(aes_mode_e mode)
{
    aes_reg->ctrl &= ~(1 << AES_MODE_OFFSET);      //clear bit 3
    aes_reg->ctrl |= (mode << AES_MODE_OFFSET);  //set mode
}

static inline void aes_enable(void)
{
    aes_reg->ctrl |= (1 << AES_WORK_ENABLE_OFFSET);
}

static inline void aes_disable(void)
{
    aes_reg->ctrl &= ~(1 << AES_WORK_ENABLE_OFFSET);
}

static inline void aes_enable_interrupt(void)
{
    aes_reg->ctrl |= (1 << AES_INT_ENABLE_OFFSET);
}

static inline void aes_disable_interrupt(void)
{
    aes_reg->ctrl &= ~(1 << AES_INT_ENABLE_OFFSET);
}

static inline void aes_clear_interrupt(void)
{
    aes_reg->state = 0x0;
}

static inline uint32_t aes_get_intstatus(uint32_t AES_IT)
{
    return (aes_reg->state & AES_IT) ? 1 : 0;
}

static void aes_set_key(void *context, uint8_t *key, aes_key_len_bits_e keylen, uint32_t enc, uint32_t endian)
{
    uint8_t keynum = 0;

    if (keylen == AES_KEY_LEN_BITS_128) {
        keynum = 4;
    } else if (keylen == AES_KEY_LEN_BITS_192) {
        keynum = 6;
    } else if (keylen == AES_KEY_LEN_BITS_256) {
        keynum = 8;
    }

    uint32_t i;
    uint32_t temp = 0;
    /* set key according to the endian mode */
    if (endian == AES_ENDIAN_LITTLE) {
        for (i = 0; i < keynum; i++) {
            temp = key[3] << 24 | key[2] << 16 | key[1] << 8 | key[0];
            aes_reg->key[keynum - 1 - i] = temp;
            key += 4;
        }
    } else if (endian == AES_ENDIAN_BIG) {
        for (i = 0; i < keynum; i++) {
            temp = key[3] << 24 | key[2] << 16 | key[1] << 8 | key[0];
            aes_reg->key[i] = temp;
            key += 4;
        }
    }

    if (enc == AES_CRYPTO_MODE_DECRYPT) {
        aes_set_opcode(AES_CRYPTO_KEYEXP);      /* if the mode is decrypt before decrypt you have to keyexpand */
        aes_enable();
//        while(block_cal_done == 0);
//        block_cal_done = 0;

        while (aes_get_intstatus(AES_IT_KEYINT));

        aes_set_opcode(AES_CRYPTO_MODE_DECRYPT);
    } else if (enc == AES_CRYPTO_MODE_ENCRYPT) {
        aes_set_opcode(AES_CRYPTO_MODE_ENCRYPT);
    }

    aes_disable();
}

static void aes_set_iv(uint32_t mode, uint32_t endian, uint8_t *iv)
{
    uint32_t temp;
    uint32_t i;
    /* set iv if the mode is CBC */
    if (mode == AES_MODE_CBC) {
        if (endian == AES_ENDIAN_BIG) {
            for (i = 0; i < 4; i++) {
                temp = iv[3] << 24 | iv[2] << 16 | iv[1] << 8 | iv[0];
                aes_reg->iv[i] = temp;
                iv += 4;
            }
        } else if (endian == AES_ENDIAN_LITTLE) {
            for (i = 0; i < 4; i++) {
                temp = iv[3] << 24 | iv[2] << 16 | iv[1] << 8 | iv[0];
                aes_reg->iv[3 - i] = temp;
                iv += 4;
            }
        }
    }
}

static int aes_crypto(void *context, uint8_t *in, uint8_t *out,
               uint32_t len, uint8_t *iv, uint32_t mode, uint32_t endian, uint32_t enc)
{

    uint32_t temp[4];
    aes_set_iv(mode, endian, iv);

    uint32_t i = 0;
    uint32_t j = 0;
    /* set the text before aes calculating */
    for (i = 0; i < len; i = i + 16) {
        for (j = 0; j < 4; j++) {
            temp[j] = in[3] << 24 | in[2] << 16 | in[1] << 8 | in[0];
            if (endian == AES_ENDIAN_BIG) {
                aes_reg->datain[j] = temp[j];
            } else if (endian == AES_ENDIAN_LITTLE) {
                aes_reg->datain[3 - j] = temp[j];
            }

            in += 4;
        }
        aes_enable();

        while(block_cal_done == 0);
        block_cal_done = 0;

        if (enc == AES_CRYPTO_MODE_ENCRYPT && mode == AES_MODE_CBC) {
            aes_set_iv(mode, endian, out);
            memcpy(iv, out, 16);
            out += 16;
        } else if (enc == AES_CRYPTO_MODE_DECRYPT && mode == AES_MODE_CBC) {
            aes_set_iv(mode, endian, (uint8_t *)&temp);
            memcpy(iv, temp, 16);
        }
    }

    return 0;
}

void ck_aes_irqhandler(int32_t idx)
{
    ck_aes_priv_t *aes_priv = &aes_handle[idx];

    volatile uint32_t j;
    uint32_t tmp = 0;
    /* get the result after aes calculating*/
    if (aes_priv->result_out != NULL) {
        for (j = 0; j < 4; j++) {
            if (aes_priv->endian == AES_ENDIAN_BIG) {
                tmp = aes_reg->dataout[j];
            } else if (aes_priv->endian == AES_ENDIAN_LITTLE) {
                tmp = aes_reg->dataout[3 - j];
            }

            memcpy(aes_priv->result_out, &tmp, 4);
            aes_priv->result_out += 4;
            aes_priv->len -= 4;
        }
    }

    block_cal_done = 1;
    /* disable aes and clear the aes interrupt */
    aes_disable();
    aes_clear_interrupt();

    /* execute the callback function */
    if (aes_priv->len == 0) {
        if (aes_priv->cb) {
            aes_priv->cb(AES_EVENT_CRYPTO_COMPLETE);
        }
    }
}

/**
  \brief       get aes instance count.
  \return      aes handle count
*/
int32_t csi_aes_get_instance_count(void)
{
    return target_get_aes_count();
}

/**
  \brief       Initialize AES Interface. 1. Initializes the resources needed for the AES interface 2.registers event callback function
  \param[in]   idx must not exceed return value of csi_aes_get_instance_count().
  \param[in]   cb_event  Pointer to \ref aes_event_cb_t
  \return      return aes handle if success
*/
aes_handle_t csi_aes_initialize(int32_t idx, aes_event_cb_t cb_event)
{

    if (idx < 0 || idx >= CONFIG_AES_NUM) {
        return NULL;
    }

    uint32_t irq = 0u;
    uint32_t base = 0u;
    /* obtain the aes information */
    int32_t real_idx = target_get_aes(idx, &base, &irq);

    if (real_idx != idx) {
        return NULL;
    }

    ck_aes_priv_t *aes_priv = &aes_handle[idx];

    aes_priv->base = base;
    aes_priv->irq  = irq;

    /* initialize the aes context */
    aes_reg = (ck_aes_reg_t *)(aes_priv->base);
    aes_priv->cb = cb_event;
    aes_priv->iv = NULL;
    aes_priv->len = 16;
    aes_priv->result_out = NULL;
    aes_priv->mode = AES_MODE_CBC;
    aes_priv->keylen = AES_KEY_LEN_BITS_128;
    aes_priv->endian = AES_ENDIAN_LITTLE;
    aes_priv->status.busy = 0;

    aes_enable_interrupt();             /* enable the aes interrupt */

    drv_nvic_enable_irq(aes_priv->irq); /* enable the aes bit in nvic */

    return (aes_handle_t)aes_priv;
}

/**
  \brief       De-initialize AES Interface. stops operation and releases the software resources used by the interface
  \param[in]   handle  aes handle to operate.
  \return      error code
*/
int32_t csi_aes_uninitialize(aes_handle_t handle)
{
    AES_NULL_PARA_CHK(handle);

    ck_aes_priv_t *aes_priv = handle;
    aes_priv->cb = NULL;

    aes_disable_interrupt();            /* disable the aes interrupt */

    drv_nvic_disable_irq(aes_priv->irq);

    return 0;
}

/**
  \brief       Get driver capabilities.
  \param[in]   handle  aes handle to operate.
  \return      \ref aes_capabilities_t
*/
aes_capabilities_t csi_aes_get_capabilities(aes_handle_t handle)
{
    return driver_capabilities;
}

/**
  \brief       config aes mode.
  \param[in]   handle  aes handle to operate.
  \param[in]   mode      \ref aes_mode_e
  \param[in]   keylen_bits \ref aes_key_len_bits_e
  \param[in]   endian    \ref aes_endian_mode_e
  \param[in]   arg       Pointer to the iv address when mode is cbc_mode
  \return      error code
*/
int32_t csi_aes_config(aes_handle_t handle, aes_mode_e mode, aes_key_len_bits_e keylen_bits, aes_endian_mode_e endian, uint32_t arg)
{
    AES_NULL_PARA_CHK(handle);

    ck_aes_priv_t *aes_priv = handle;
    aes_reg = (ck_aes_reg_t *)(aes_priv->base);

    /* config the aes mode */
    switch (mode) {
        case AES_MODE_CBC:
            aes_priv->iv = (void *)arg;
            aes_priv->mode = mode;
            aes_set_mode(mode);
            break;

        case AES_MODE_ECB:
            aes_priv->mode = mode;
            aes_set_mode(mode);
            break;

        case AES_MODE_CFB:
        case AES_MODE_OFB:
        case AES_MODE_CTR:
            return ERR_AES(EDRV_UNSUPPORTED);

        default:
            return ERR_AES(EDRV_PARAMETER);
    }

    /* config the key length */
    switch (keylen_bits) {
        case AES_KEY_LEN_BITS_128:
        case AES_KEY_LEN_BITS_192:
        case AES_KEY_LEN_BITS_256:
            aes_priv->keylen = keylen_bits;
            aes_set_keylen(keylen_bits);
            break;

        default:
            return ERR_AES(EDRV_PARAMETER);
    }

    /* config the endian mode */
    switch (endian) {
        case AES_ENDIAN_LITTLE:
            aes_priv->endian = endian;
            aes_set_endian(endian);
            break;

        case AES_ENDIAN_BIG:
            aes_priv->endian = endian;
            aes_set_endian(endian);
            break;

        default:
            return ERR_AES(EDRV_PARAMETER);
    }

    return 0;
}

/**
  \brief       set crypto key.
  \param[in]   handle    aes handle to operate.
  \param[in]   context   aes information context(NULL when hardware implementation)
  \param[in]   key       Pointer to the key buf
  \param[in]   key_len   Pointer to the aes_key_len_bits_e
  \param[in]   enc       \ref aes_crypto_mode_e
  \return      error code
*/
int32_t csi_aes_set_key(aes_handle_t handle, void *context, void *key, aes_key_len_bits_e key_len, aes_crypto_mode_e enc)
{
    AES_NULL_PARA_CHK(handle);
    AES_NULL_PARA_CHK(key);
    if ((key_len != AES_KEY_LEN_BITS_128 &&
        key_len != AES_KEY_LEN_BITS_192 &&
        key_len != AES_KEY_LEN_BITS_256) ||
        (enc != AES_CRYPTO_MODE_ENCRYPT &&
        enc != AES_CRYPTO_MODE_DECRYPT)) {
        return ERR_AES(EDRV_PARAMETER);
    }

    ck_aes_priv_t *aes_priv = handle;
    aes_priv->enc = enc;
    aes_set_key(context, key, key_len, enc, aes_priv->endian);

    return 0;
}

/**
  \brief       encrypt or decrypt
  \param[in]   handle  aes handle to operate.
  \param[in]   context aes information context(NULL when hardware implementation)
  \param[in]   in   Pointer to the Source data
  \param[out]  out  Pointer to the Result data.
  \param[in]   len  the Source data len.
  \param[in]   padding \ref aes_padding_mode_e.
  \return      error code
*/
int32_t csi_aes_crypto(aes_handle_t handle, void *context, void *in, void *out, uint32_t len, aes_padding_mode_e padding)
{
    AES_NULL_PARA_CHK(handle);
    AES_NULL_PARA_CHK(in);
    AES_NULL_PARA_CHK(out);
    AES_NULL_PARA_CHK(len);

    ck_aes_priv_t *aes_priv = handle;

    aes_priv->status.busy = 1;

    uint8_t left_len = len & 0xf;
    switch (padding) {
        case AES_PADDING_MODE_NO:
            if (left_len) {
                return ERR_AES(EDRV_PARAMETER);
            }

            /* crypto in padding no mode */
            aes_priv->result_out = out;
            aes_priv->len = len;
            aes_crypto(context, in, out, len, aes_priv->iv, aes_priv->mode, aes_priv->endian, aes_priv->enc);
            break;

        case AES_PADDING_MODE_ZERO:
            if (left_len == 0) {
                return ERR_AES(EDRV_PARAMETER);
            }

            uint8_t i = 0;
            for (i = 0; i < (16 - left_len); i++) {
                *((uint8_t *)in + len + i) = 0x0;
            }

            /* crypto in padding zero mode */
            aes_priv->result_out = out;
            aes_priv->len = len + 16 -left_len;
            aes_crypto(context, in, out, len + 16 - left_len, aes_priv->iv, aes_priv->mode, aes_priv->endian, aes_priv->enc);
            break;

        case AES_PADDING_MODE_PKCS5:
            return ERR_AES(EDRV_UNSUPPORTED);

        default:
            return ERR_AES(EDRV_PARAMETER);
    }

    aes_priv->status.busy = 0;
    return 0;
}

/**
  \brief       Get AES status.
  \param[in]   handle  aes handle to operate.
  \return      AES status \ref aes_status_t
*/
aes_status_t csi_aes_get_status(aes_handle_t handle)
{
    ck_aes_priv_t *aes_priv = handle;
    return aes_priv->status;
}
