#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#include "log.h"
#include "smart_sound.h"
#include "crypto.h"
#include "libuv_dbus.h"

int EvpAESEncrypto(unsigned char* pInBuf, 
                    int iSize, 
                    unsigned char* pOutBuf, 
                    int* pOutSize, 
                    unsigned char* pKey)
{
    int                 enBytes     = 0;
    EVP_CIPHER_CTX      ctx;
    //int                 decDataLen  = 0;
    if(!pInBuf || !pOutBuf || !pOutSize || !pKey)
    {
        return -ERR_INPUT_PARAMS;
    }
    
    *pOutSize   = 0;
    //decDataLen  = ((iSize + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
    
    EVP_CIPHER_CTX_init(&ctx);
    
    if(EVP_EncryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, pKey, NULL) == 0)
    {
        LOG_EX(LOG_Error, "EVP_EncryptInit_ex Error\n");
        return -ERR_EVP_INIT_KEY;
    }

    if(EVP_EncryptUpdate(&ctx, pOutBuf, &enBytes, pInBuf, iSize) == 0)
    {
        LOG_EX(LOG_Error, "EVP_EncryptUpdate Error\n");
        return -ERR_EVP_UPDATE;
    }

    pOutBuf     += enBytes;
    pInBuf      += enBytes;
    *pOutSize   += enBytes;

    if(EVP_EncryptFinal_ex(&ctx, pOutBuf, &enBytes) == 0)
    {
        LOG_EX(LOG_Error, "EVP_EncryptFinal_ex Error\n");
        return -ERR_EVP_FINALE;
    }

    *pOutSize   += enBytes;        

    EVP_CIPHER_CTX_cleanup(&ctx);
    
    return 0;
}

int EvpAESDecrypto(unsigned char* pInBuf, 
                    int iSize, 
                    unsigned char* pOutBuf, 
                    int* pOutSize, 
                    unsigned char* pKey)
{
    int                 deBytes     = 0;
    EVP_CIPHER_CTX      ctx;

    if(!pInBuf || !pOutBuf || !pOutSize || !pKey)
    {
        return -ERR_INPUT_PARAMS;
    }

    EVP_CIPHER_CTX_init(&ctx);

    *pOutSize = 0;

    if(EVP_DecryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, pKey, NULL) == 0)
    {
        LOG_EX(LOG_Error, "EVP_DecryptInit_ex Error\n");
        return -ERR_EVP_INIT_KEY;
    }

    if(EVP_DecryptUpdate(&ctx, pOutBuf, &deBytes, pInBuf, iSize) == 0)
    {
        LOG_EX(LOG_Error, "EVP_EncryptUpdate Error\n");
        return -ERR_EVP_UPDATE;
    }

    pOutBuf     += deBytes;
    pInBuf      += deBytes;
    *pOutSize   += deBytes;

    if(EVP_DecryptFinal_ex(&ctx, pOutBuf, &deBytes) == 0)
    {
        LOG_EX(LOG_Error, "EVP_EncryptFinal_ex Error\n");
        return -ERR_EVP_FINALE;
    }

    *pOutSize   += deBytes;  
    EVP_CIPHER_CTX_cleanup(&ctx);
    
    return 0;
}

