#ifndef CRYPTO_H
#define CRYPTO_H
#include <openssl/aes.h>
#include <openssl/evp.h>
#ifdef __cplusplus
extern "C" {
#endif
#define ALIGN_AES_BLOCK(size)   (((size + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE)

#define	MD5_VALUE_LEN			(16)
#define MD5_STR_VALUE_LEN		(MD5_VALUE_LEN * 2)

typedef enum
{
    CRYPTO_AES_ENCRYPT          = 0,
    CRYPTO_AES_DECRYPT,
    CRYPTO_BASE64_ENCODE,
    CRYPTO_BASE64_DECODE,
    CRYPTO_MD5_FILE,
} CRYPTO_TYPE;

void EvpSystemInit(void);

//*****************************************************
// AES
//*****************************************************
typedef void (*OnEVPCrypto)(CRYPTO_TYPE type, 
                            const unsigned char* pData, 
                            int iSize, 
                            const unsigned char* pSrcData,
                            int iError);



int EvpAESEncrypto(unsigned char* pInBuf, 
                    int iSize, 
                    unsigned char* pOutBuf, 
                    int* pOutSize, 
                    unsigned char* pKey);
                    
int EvpAESDecrypto(unsigned char* pInBuf, 
                    int iSize, 
                    unsigned char* pOutBuf, 
                    int* pOutSize, 
                    unsigned char* pKey);
                  
//*****************************************************
//  BASE64
//*****************************************************
const char* EvpBase64Encode(const char* pSrc);
const char* EvpBase64Decode(const char* pBase64);
const char* EvpBase64EncodeNoAlign(const char *pSrc);
const char* EvpBase64DecodeNoAlign(const char *pBase64);
const char* EvpBase64EncodeNoAlignV2(unsigned char *pSrc, int sLen);
unsigned char* EvpBase64DecodeNoAlignV2(const char *pBase64, int *pOutSize);
//*****************************************************
//  MD5
//*****************************************************
const char* EvpMD5HashFile(const char* pFileName);
int EvpMD5HashFileV2(const char *pFileName, unsigned char md5[16]);;
int EvpMD5HashBuf(const unsigned char *pBuf, int iBufLen, unsigned char *pOutBuf, int *pOutSize);
const char* EvpMD5HashBufV2(const unsigned char *pBuf, int iBufLen);
//*****************************************************
//  Async Engine
//*****************************************************
int EvpAddCryptoTask(CRYPTO_TYPE type,
                    unsigned char* pInBuf, 
                    int iSize, 
                    unsigned char* pOutBuf, 
                    char* pKey,
                    OnEVPCrypto onEvpCryptCb);  

//*****************************************************
//  Compress
//*****************************************************
int GZipFileCompress(const char *pInput, const char *pOutput);

#ifdef __cplusplus
}
#endif                    
#endif