// // Created by xajhu on 2021/7/2 0002. // #include #include #include #include "task_manager.h" #include "user_errno.h" #include "crypto.h" #include "misc.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]; on_evp_crypto onEvpEventCb; } CRYPT_TASK_PARAMS, *PCRYPT_TASK_PARAMS; static void freeEVPWorkCb(uv_work_t *pWork, int UNUSED(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; unsigned int uOutSize = 0; int iError = 0; switch (pTask->type) { #if 0 case CRYPTO_AES_ENCRYPT: iError = EvpAESEncrypto(pTask->pInData, pTask->iInSize, pTask->pOutData, &uOutSize, pTask->pKey); break; case CRYPTO_AES_DECRYPT: iError = EvpAESDecrypto(pTask->pInData, pTask->iInSize, pTask->pOutData, &uOutSize, pTask->pKey); break; #endif case CRYPTO_BASE64_ENCODE: pTask->pOutData = (unsigned char *)base64_encode((unsigned char *)pTask->pInData, pTask->iInSize); uOutSize = strlen((char *)pTask->pOutData); break; case CRYPTO_BASE64_DECODE: pTask->pOutData = (unsigned char *)base64_decode((const char *)pTask->pInData, &uOutSize); //uOutSize = strlen((char *)pTask->pOutData); break; #if 0 case CRYPTO_MD5_FILE: pTask->pOutData = (unsigned char *)EvpMD5HashFile((const char *)pTask->pInData); uOutSize = strlen((char *)pTask->pOutData); break; #endif 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, uOutSize, pTask->pInData, 0); } } int evp_add_crypto_task(CRYPTO_TYPE type, unsigned char *pInBuf, unsigned int iSize, unsigned char *pOutBuf, char *pKey, on_evp_crypto onEvpCryptCb) { uv_work_t *puvWork = NULL; PCRYPT_TASK_PARAMS pTask = NULL; if (!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(get_task_manager(), &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 = (int)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((char *)pTask->pKey, pKey, EVP_MAX_KEY_LENGTH); } memcpy(pTask->pInData, pInBuf, iSize); uv_queue_work(get_task_manager(), puvWork, onEVPWorkCb, freeEVPWorkCb); return 0; } static void evpLockCb(int mode, int n, const char *UNUSED(pFile), int UNUSED(line)) { if (n >= CRYPTO_num_locks()) { return; } if (mode & CRYPTO_LOCK) { uv_mutex_lock(&pEvpMutex[n]); } else { uv_mutex_unlock(&pEvpMutex[n]); } } #if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_0_0 void evpIdCb(CRYPTO_THREADID *tid) { CRYPTO_THREADID_set_numeric(tid, (unsigned long)pthread_self()); } #else static unsigned long evpIdCb(void) { return ((unsigned long)uv_thread_self()); } #endif void evp_system_init(void) { int i; 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]); } #if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_0_0 CRYPTO_THREADID_set_callback(evpIdCb); #else CRYPTO_set_id_callback(evpIdCb); #endif CRYPTO_set_locking_callback(evpLockCb); }