#include #include #include #include #include "log.h" #include "smart_sound.h" #include "crypto.h" #include "libuv_dbus.h" static uv_mutex_t *pEvpMutex = NULL; typedef struct { CRYPTO_TYPE type; unsigned char* pInData; int iInSize; unsigned char* pOutData; unsigned char pKey[EVP_MAX_KEY_LENGTH + 1]; OnEVPCrypto onEvpEventCb; } CRYPT_TASK_PARAMS, *PCRYPT_TASK_PARAMS; static void FreeEVPWorkCb(uv_work_t* pWork, int status) { PCRYPT_TASK_PARAMS pTask = (PCRYPT_TASK_PARAMS)pWork->data; free(pTask->pInData); free(pTask); free(pWork); } static void OnEVPWorkCb(uv_work_t* pWork) { PCRYPT_TASK_PARAMS pTask = (PCRYPT_TASK_PARAMS)pWork->data; int iOutSize = 0; int iError = 0; switch(pTask->type) { case CRYPTO_AES_ENCRYPT: iError = EvpAESEncrypto(pTask->pInData, pTask->iInSize, pTask->pOutData, &iOutSize, pTask->pKey); break; case CRYPTO_AES_DECRYPT: iError = EvpAESDecrypto(pTask->pInData, pTask->iInSize, pTask->pOutData, &iOutSize, pTask->pKey); break; case CRYPTO_BASE64_ENCODE: pTask->pOutData = (unsigned char*)EvpBase64Encode((const char*)pTask->pInData); iOutSize = strlen((char*)pTask->pOutData); break; case CRYPTO_BASE64_DECODE: pTask->pOutData = (unsigned char*)EvpBase64Decode((const char*)pTask->pInData); iOutSize = strlen((char*)pTask->pOutData); break; case CRYPTO_MD5_FILE: pTask->pOutData = (unsigned char*)EvpMD5HashFile((const char*)pTask->pInData); iOutSize = strlen((char*)pTask->pOutData); break; default: iError = -ERR_UNSUP_EVP_TYPE; } if(iError != 0) { pTask->onEvpEventCb(pTask->type, pTask->pOutData, 0, pTask->pInData, iError); } else { pTask->onEvpEventCb(pTask->type, pTask->pOutData, iOutSize, pTask->pInData, 0); } } int EvpAddCryptoTask(CRYPTO_TYPE type, unsigned char* pInBuf, int iSize, unsigned char* pOutBuf, char* pKey, OnEVPCrypto onEvpCryptCb) { uv_work_t* puvWork = NULL; PCRYPT_TASK_PARAMS pTask = NULL; PLIBUV_DBUS_PARAMS pContext = DBusLibuvGetRuntime(); if(!pContext || !onEvpCryptCb) { return -ERR_INPUT_PARAMS; } if(type == CRYPTO_AES_ENCRYPT || type == CRYPTO_AES_DECRYPT) { if(pKey == NULL || pOutBuf == NULL) { return -ERR_INPUT_PARAMS; } switch(strlen(pKey) * 8) { case 128: case 192: case 256: break; default: return -ERR_EVP_KEY_SIZE; } } else if(type == CRYPTO_MD5_FILE) { uv_fs_t uvFs; if(uv_fs_access(pContext->pLoop, &uvFs, (const char*)pInBuf, F_OK, NULL) != 0) { return -ERR_FILE_NOT_EXISTS; } } pTask = (PCRYPT_TASK_PARAMS)malloc(sizeof(CRYPT_TASK_PARAMS)); puvWork = (uv_work_t*)malloc(sizeof(uv_work_t)); puvWork->data = (void*)pTask; pTask->type = type; pTask->pInData = (unsigned char*)malloc(iSize + 1); pTask->iInSize = iSize; pTask->pOutData = pOutBuf; pTask->onEvpEventCb = onEvpCryptCb; memset(pTask->pInData, 0, iSize + 1); memset(pTask->pKey, 0, EVP_MAX_KEY_LENGTH + 1); if(pKey) { strncpy(pTask->pKey, pKey, EVP_MAX_KEY_LENGTH); } memcpy(pTask->pInData, pInBuf, iSize); uv_queue_work(pContext->pLoop, puvWork, OnEVPWorkCb, FreeEVPWorkCb); return 0; } static void __evpLockCb(int mode, int n, const char *pFile, int line) { if(n >= CRYPTO_num_locks()) { return; } if(mode & CRYPTO_LOCK) { uv_mutex_lock(&pEvpMutex[n]); } else { uv_mutex_unlock(&pEvpMutex[n]); } } static unsigned long __evpIdCb(void) { return ((unsigned long)uv_thread_self()); } void EvpSystemInit(void) { int i = 0; pEvpMutex = (uv_mutex_t *)malloc(CRYPTO_num_locks() * sizeof(uv_mutex_t)); for(i = 0; i < CRYPTO_num_locks(); i++) { uv_mutex_init(&pEvpMutex[i]); } CRYPTO_set_id_callback(__evpIdCb); CRYPTO_set_locking_callback(__evpLockCb); }