Unified encryption functions.
This commit is contained in:
parent
5805ba8e52
commit
238ff3b315
@ -38,11 +38,7 @@
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
|
||||
struct crypto_des3_struct
|
||||
{
|
||||
EVP_CIPHER_CTX des3_ctx;
|
||||
};
|
||||
#include <freerdp/crypto/certificate.h>
|
||||
|
||||
struct crypto_cert_struct
|
||||
{
|
||||
@ -54,18 +50,8 @@ struct crypto_cert_struct
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct crypto_des3_struct* CryptoDes3;
|
||||
|
||||
FREERDP_API CryptoDes3 crypto_des3_encrypt_init(const BYTE* key, const BYTE* ivec);
|
||||
FREERDP_API CryptoDes3 crypto_des3_decrypt_init(const BYTE* key, const BYTE* ivec);
|
||||
FREERDP_API BOOL crypto_des3_encrypt(CryptoDes3 des3, UINT32 length, const BYTE *in_data, BYTE *out_data);
|
||||
FREERDP_API BOOL crypto_des3_decrypt(CryptoDes3 des3, UINT32 length, const BYTE *in_data, BYTE* out_data);
|
||||
FREERDP_API void crypto_des3_free(CryptoDes3 des3);
|
||||
|
||||
typedef struct crypto_cert_struct* CryptoCert;
|
||||
|
||||
#include <freerdp/crypto/certificate.h>
|
||||
|
||||
FREERDP_API CryptoCert crypto_cert_read(BYTE* data, UINT32 length);
|
||||
FREERDP_API char* crypto_cert_fingerprint(X509* xcert);
|
||||
FREERDP_API char* crypto_cert_subject(X509* xcert);
|
||||
|
@ -490,14 +490,14 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp)
|
||||
|
||||
if (settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec);
|
||||
if (!rdp->fips_encrypt)
|
||||
if (!winpr_Cipher_New(&rdp->fips_encrypt, WINPR_CIPHER_DES_EDE3_CBC,
|
||||
WINPR_ENCRYPT, rdp->fips_encrypt_key, fips_ivec))
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate des3 encrypt key");
|
||||
goto end;
|
||||
}
|
||||
rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec);
|
||||
if (!rdp->fips_decrypt)
|
||||
if (!winpr_Cipher_New(&rdp->fips_decrypt, WINPR_CIPHER_DES_EDE3_CBC,
|
||||
WINPR_DECRYPT, rdp->fips_decrypt_key, fips_ivec))
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate des3 decrypt key");
|
||||
goto end;
|
||||
@ -597,15 +597,15 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s)
|
||||
|
||||
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec);
|
||||
if (!rdp->fips_encrypt)
|
||||
if (!winpr_Cipher_New(&rdp->fips_encrypt, WINPR_CIPHER_DES_EDE3_CBC,
|
||||
WINPR_ENCRYPT, rdp->fips_encrypt_key, fips_ivec))
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate des3 encrypt key");
|
||||
goto end;
|
||||
}
|
||||
|
||||
rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec);
|
||||
if (!rdp->fips_decrypt)
|
||||
if (!winpr_Cipher_New(&rdp->fips_decrypt, WINPR_CIPHER_DES_EDE3_CBC,
|
||||
WINPR_DECRYPT, rdp->fips_decrypt_key, fips_ivec))
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate des3 decrypt key");
|
||||
goto end;
|
||||
|
@ -1602,13 +1602,13 @@ void rdp_reset(rdpRdp* rdp)
|
||||
|
||||
if (rdp->fips_encrypt)
|
||||
{
|
||||
crypto_des3_free(rdp->fips_encrypt);
|
||||
winpr_Cipher_Free(rdp->fips_encrypt);
|
||||
rdp->fips_encrypt = NULL;
|
||||
}
|
||||
|
||||
if (rdp->fips_decrypt)
|
||||
{
|
||||
crypto_des3_free(rdp->fips_decrypt);
|
||||
winpr_Cipher_Free(rdp->fips_decrypt);
|
||||
rdp->fips_decrypt = NULL;
|
||||
}
|
||||
|
||||
@ -1663,8 +1663,8 @@ void rdp_free(rdpRdp* rdp)
|
||||
{
|
||||
winpr_RC4_Final(rdp->rc4_decrypt_key);
|
||||
winpr_RC4_Final(rdp->rc4_encrypt_key);
|
||||
crypto_des3_free(rdp->fips_encrypt);
|
||||
crypto_des3_free(rdp->fips_decrypt);
|
||||
winpr_Cipher_Free(rdp->fips_encrypt);
|
||||
winpr_Cipher_Free(rdp->fips_decrypt);
|
||||
free(rdp->fips_hmac);
|
||||
freerdp_settings_free(rdp->settings);
|
||||
freerdp_settings_free(rdp->settingsCopy);
|
||||
|
@ -154,8 +154,8 @@ struct rdp_rdp
|
||||
WINPR_RC4_CTX* rc4_encrypt_key;
|
||||
int encrypt_use_count;
|
||||
int encrypt_checksum_use_count;
|
||||
struct crypto_des3_struct* fips_encrypt;
|
||||
struct crypto_des3_struct* fips_decrypt;
|
||||
WINPR_CIPHER_CTX* fips_encrypt;
|
||||
WINPR_CIPHER_CTX* fips_decrypt;
|
||||
WINPR_HMAC_CTX* fips_hmac;
|
||||
UINT32 sec_flags;
|
||||
BOOL do_crypt;
|
||||
|
@ -646,7 +646,9 @@ BOOL security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp*
|
||||
|
||||
BOOL security_fips_encrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
{
|
||||
if (!crypto_des3_encrypt(rdp->fips_encrypt, length, data, data))
|
||||
size_t olen;
|
||||
|
||||
if (!winpr_Cipher_Update(rdp->fips_encrypt, data, length, data, &olen))
|
||||
return FALSE;
|
||||
rdp->encrypt_use_count++;
|
||||
return TRUE;
|
||||
@ -654,7 +656,11 @@ BOOL security_fips_encrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
|
||||
BOOL security_fips_decrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
{
|
||||
return crypto_des3_decrypt(rdp->fips_decrypt, length, data, data);
|
||||
size_t olen;
|
||||
|
||||
if (!winpr_Cipher_Update(rdp->fips_decrypt, data, length, data, &olen))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL security_fips_check_signature(const BYTE* data, int length, const BYTE* sig, rdpRdp* rdp)
|
||||
|
@ -29,54 +29,6 @@
|
||||
|
||||
#define TAG FREERDP_TAG("crypto")
|
||||
|
||||
CryptoDes3 crypto_des3_encrypt_init(const BYTE* key, const BYTE* ivec)
|
||||
{
|
||||
CryptoDes3 des3 = malloc(sizeof(*des3));
|
||||
if (!des3)
|
||||
return NULL;
|
||||
|
||||
EVP_CIPHER_CTX_init(&des3->des3_ctx);
|
||||
EVP_EncryptInit_ex(&des3->des3_ctx, EVP_des_ede3_cbc(), NULL, key, ivec);
|
||||
EVP_CIPHER_CTX_set_padding(&des3->des3_ctx, 0);
|
||||
return des3;
|
||||
}
|
||||
|
||||
CryptoDes3 crypto_des3_decrypt_init(const BYTE* key, const BYTE* ivec)
|
||||
{
|
||||
CryptoDes3 des3 = malloc(sizeof(*des3));
|
||||
if (!des3)
|
||||
return NULL;
|
||||
|
||||
EVP_CIPHER_CTX_init(&des3->des3_ctx);
|
||||
EVP_DecryptInit_ex(&des3->des3_ctx, EVP_des_ede3_cbc(), NULL, key, ivec);
|
||||
EVP_CIPHER_CTX_set_padding(&des3->des3_ctx, 0);
|
||||
return des3;
|
||||
}
|
||||
|
||||
BOOL crypto_des3_encrypt(CryptoDes3 des3, UINT32 length, const BYTE* in_data, BYTE* out_data)
|
||||
{
|
||||
int len;
|
||||
return EVP_EncryptUpdate(&des3->des3_ctx, out_data, &len, in_data, length) == 1;
|
||||
}
|
||||
|
||||
BOOL crypto_des3_decrypt(CryptoDes3 des3, UINT32 length, const BYTE* in_data, BYTE* out_data)
|
||||
{
|
||||
int len;
|
||||
int ret = EVP_DecryptUpdate(&des3->des3_ctx, out_data, &len, in_data, length);
|
||||
|
||||
if (length != len)
|
||||
abort(); /* TODO */
|
||||
return ret == 1;
|
||||
}
|
||||
|
||||
void crypto_des3_free(CryptoDes3 des3)
|
||||
{
|
||||
if (des3 == NULL)
|
||||
return;
|
||||
EVP_CIPHER_CTX_cleanup(&des3->des3_ctx);
|
||||
free(des3);
|
||||
}
|
||||
|
||||
CryptoCert crypto_cert_read(BYTE* data, UINT32 length)
|
||||
{
|
||||
CryptoCert cert = malloc(sizeof(*cert));
|
||||
|
@ -1016,9 +1016,10 @@ typedef union _WINPR_CIPHER_CTX WINPR_CIPHER_CTX;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
WINPR_API BOOL winpr_Cipher_Init(WINPR_CIPHER_CTX* ctx, int cipher, int op, const BYTE* key, const BYTE* iv);
|
||||
WINPR_API BOOL winpr_Cipher_New(WINPR_CIPHER_CTX** ctx, int cipher, int op, const BYTE* key, const BYTE* iv);
|
||||
WINPR_API BOOL winpr_Cipher_Update(WINPR_CIPHER_CTX* ctx, const BYTE* input, size_t ilen, BYTE* output, size_t* olen);
|
||||
WINPR_API BOOL winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx, BYTE* output, size_t* olen);
|
||||
WINPR_API void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -500,26 +500,39 @@ mbedtls_cipher_type_t winpr_mbedtls_get_cipher_type(int cipher)
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOL winpr_Cipher_Init(WINPR_CIPHER_CTX* ctx, int cipher, int op, const BYTE* key, const BYTE* iv)
|
||||
BOOL winpr_Cipher_New(WINPR_CIPHER_CTX** cctx, int cipher, int op, const BYTE* key, const BYTE* iv)
|
||||
{
|
||||
WINPR_CIPHER_CTX* ctx;
|
||||
#if defined(WITH_OPENSSL)
|
||||
int operation;
|
||||
const EVP_CIPHER* evp;
|
||||
EVP_CIPHER_CTX* octx;
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
int key_bitlen;
|
||||
mbedtls_operation_t operation;
|
||||
mbedtls_cipher_type_t cipher_type;
|
||||
const mbedtls_cipher_info_t* cipher_info;
|
||||
#endif
|
||||
|
||||
ctx = calloc(1, sizeof(WINPR_CIPHER_CTX));
|
||||
if (!ctx)
|
||||
return FALSE;
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
octx = (EVP_CIPHER_CTX*)ctx;
|
||||
evp = winpr_openssl_get_evp_cipher(cipher);
|
||||
|
||||
if (!evp)
|
||||
return FALSE;
|
||||
|
||||
operation = (op == WINPR_ENCRYPT) ? 1 : 0;
|
||||
EVP_CIPHER_CTX_init((EVP_CIPHER_CTX*) ctx);
|
||||
EVP_CIPHER_CTX_init(octx);
|
||||
|
||||
if (EVP_CipherInit_ex((EVP_CIPHER_CTX*) ctx, evp, NULL, key, iv, operation) != 1)
|
||||
if (EVP_CipherInit_ex(octx, evp, NULL, key, iv, operation) != 1)
|
||||
return FALSE;
|
||||
|
||||
EVP_CIPHER_CTX_set_padding(octx, 0);
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
int key_bitlen;
|
||||
mbedtls_operation_t operation;
|
||||
mbedtls_cipher_type_t cipher_type;
|
||||
const mbedtls_cipher_info_t* cipher_info;
|
||||
cipher_type = winpr_mbedtls_get_cipher_type(cipher);
|
||||
cipher_info = mbedtls_cipher_info_from_type(cipher_type);
|
||||
|
||||
@ -537,6 +550,8 @@ BOOL winpr_Cipher_Init(WINPR_CIPHER_CTX* ctx, int cipher, int op, const BYTE* ke
|
||||
if (mbedtls_cipher_setkey((mbedtls_cipher_context_t*) ctx, key, key_bitlen, operation) != 0)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
*cctx = ctx;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -564,17 +579,27 @@ BOOL winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx, BYTE* output, size_t* olen)
|
||||
if (EVP_CipherFinal_ex((EVP_CIPHER_CTX*) ctx, output, &outl) != 1)
|
||||
return FALSE;
|
||||
|
||||
EVP_CIPHER_CTX_cleanup((EVP_CIPHER_CTX*) ctx);
|
||||
*olen = (size_t) outl;
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
if (mbedtls_cipher_finish((mbedtls_cipher_context_t*) ctx, output, olen) != 0)
|
||||
return FALSE;
|
||||
|
||||
mbedtls_cipher_free((mbedtls_cipher_context_t*) ctx);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx)
|
||||
{
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
#if defined(WITH_OPENSSL)
|
||||
EVP_CIPHER_CTX_cleanup((EVP_CIPHER_CTX*) ctx);
|
||||
#elif defined(WITH_MBEDTLS)
|
||||
mbedtls_cipher_free((mbedtls_cipher_context_t*) ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Key Generation
|
||||
*/
|
||||
|
@ -150,7 +150,7 @@ BOOL CryptProtectMemory(LPVOID pData, DWORD cbData, DWORD dwFlags)
|
||||
{
|
||||
BYTE* pCipherText;
|
||||
size_t cbOut, cbFinal;
|
||||
WINPR_CIPHER_CTX enc;
|
||||
WINPR_CIPHER_CTX* enc;
|
||||
BYTE randomKey[256];
|
||||
WINPR_PROTECTED_MEMORY_BLOCK* pMemBlock;
|
||||
|
||||
@ -186,27 +186,34 @@ BOOL CryptProtectMemory(LPVOID pData, DWORD cbData, DWORD dwFlags)
|
||||
pCipherText = (BYTE*) malloc(cbOut);
|
||||
|
||||
if (!pCipherText)
|
||||
{
|
||||
free(pMemBlock);
|
||||
return FALSE;
|
||||
}
|
||||
goto out;
|
||||
|
||||
winpr_Cipher_Init(&enc, WINPR_CIPHER_AES_256_CBC, WINPR_ENCRYPT, pMemBlock->key, pMemBlock->iv);
|
||||
winpr_Cipher_Update(&enc, pMemBlock->pData, pMemBlock->cbData, pCipherText, &cbOut);
|
||||
winpr_Cipher_Final(&enc, pCipherText + cbOut, &cbFinal);
|
||||
if (!winpr_Cipher_New(&enc, WINPR_CIPHER_AES_256_CBC, WINPR_ENCRYPT, pMemBlock->key, pMemBlock->iv))
|
||||
goto out;
|
||||
if (!winpr_Cipher_Update(enc, pMemBlock->pData, pMemBlock->cbData, pCipherText, &cbOut))
|
||||
goto out;
|
||||
if (!winpr_Cipher_Final(enc, pCipherText + cbOut, &cbFinal))
|
||||
goto out;
|
||||
winpr_Cipher_Free(enc);
|
||||
|
||||
CopyMemory(pMemBlock->pData, pCipherText, pMemBlock->cbData);
|
||||
free(pCipherText);
|
||||
|
||||
return ListDictionary_Add(g_ProtectedMemoryBlocks, pData, pMemBlock);
|
||||
out:
|
||||
free (pMemBlock);
|
||||
free (pCipherText);
|
||||
winpr_Cipher_Free(enc);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CryptUnprotectMemory(LPVOID pData, DWORD cbData, DWORD dwFlags)
|
||||
{
|
||||
BYTE* pPlainText;
|
||||
BYTE* pPlainText = NULL;
|
||||
size_t cbOut, cbFinal;
|
||||
WINPR_CIPHER_CTX dec;
|
||||
WINPR_PROTECTED_MEMORY_BLOCK* pMemBlock;
|
||||
WINPR_CIPHER_CTX* dec = NULL;
|
||||
WINPR_PROTECTED_MEMORY_BLOCK* pMemBlock = NULL;
|
||||
|
||||
if (dwFlags != CRYPTPROTECTMEMORY_SAME_PROCESS)
|
||||
return FALSE;
|
||||
@ -217,18 +224,22 @@ BOOL CryptUnprotectMemory(LPVOID pData, DWORD cbData, DWORD dwFlags)
|
||||
pMemBlock = (WINPR_PROTECTED_MEMORY_BLOCK*) ListDictionary_GetItemValue(g_ProtectedMemoryBlocks, pData);
|
||||
|
||||
if (!pMemBlock)
|
||||
return FALSE;
|
||||
goto out;
|
||||
|
||||
cbOut = pMemBlock->cbData + 16 - 1;
|
||||
|
||||
pPlainText = (BYTE*) malloc(cbOut);
|
||||
|
||||
if (!pPlainText)
|
||||
return FALSE;
|
||||
goto out;
|
||||
|
||||
winpr_Cipher_Init(&dec, WINPR_CIPHER_AES_256_CBC, WINPR_DECRYPT, pMemBlock->key, pMemBlock->iv);
|
||||
winpr_Cipher_Update(&dec, pMemBlock->pData, pMemBlock->cbData, pPlainText, &cbOut);
|
||||
winpr_Cipher_Final(&dec, pPlainText + cbOut, &cbFinal);
|
||||
if (!winpr_Cipher_New(&dec, WINPR_CIPHER_AES_256_CBC, WINPR_DECRYPT, pMemBlock->key, pMemBlock->iv))
|
||||
goto out;
|
||||
if (!winpr_Cipher_Update(dec, pMemBlock->pData, pMemBlock->cbData, pPlainText, &cbOut))
|
||||
goto out;
|
||||
if (!winpr_Cipher_Final(dec, pPlainText + cbOut, &cbFinal))
|
||||
goto out;
|
||||
winpr_Cipher_Free(dec);
|
||||
|
||||
CopyMemory(pMemBlock->pData, pPlainText, pMemBlock->cbData);
|
||||
SecureZeroMemory(pPlainText, pMemBlock->cbData);
|
||||
@ -239,6 +250,12 @@ BOOL CryptUnprotectMemory(LPVOID pData, DWORD cbData, DWORD dwFlags)
|
||||
free(pMemBlock);
|
||||
|
||||
return TRUE;
|
||||
|
||||
out:
|
||||
free(pPlainText);
|
||||
free(pMemBlock);
|
||||
winpr_Cipher_Free(dec);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CryptProtectData(DATA_BLOB* pDataIn, LPCWSTR szDataDescr, DATA_BLOB* pOptionalEntropy,
|
||||
|
Loading…
Reference in New Issue
Block a user