Unified encryption functions.

This commit is contained in:
Armin Novak 2016-02-27 23:28:49 +01:00
parent 5805ba8e52
commit 238ff3b315
9 changed files with 93 additions and 106 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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));

View File

@ -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
}

View File

@ -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
*/

View File

@ -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,