Unified RC4 functions.

This commit is contained in:
Armin Novak
2016-02-24 17:04:03 +01:00
parent 06da644007
commit ada2b16c50
8 changed files with 34 additions and 108 deletions

View File

@@ -25,7 +25,6 @@
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rc4.h>
#include <openssl/hmac.h>
#include <openssl/bn.h>
#include <openssl/x509v3.h>
@@ -42,11 +41,6 @@
#include <freerdp/api.h>
#include <freerdp/freerdp.h>
struct crypto_rc4_struct
{
RC4_KEY rc4_key;
};
struct crypto_des3_struct
{
EVP_CIPHER_CTX des3_ctx;
@@ -67,12 +61,6 @@ struct crypto_cert_struct
extern "C" {
#endif
typedef struct crypto_rc4_struct* CryptoRc4;
FREERDP_API CryptoRc4 crypto_rc4_init(const BYTE* key, UINT32 length);
FREERDP_API void crypto_rc4(CryptoRc4 rc4, UINT32 length, const BYTE* in_data, BYTE* out_data);
FREERDP_API void crypto_rc4_free(CryptoRc4 rc4);
typedef struct crypto_des3_struct* CryptoDes3;
FREERDP_API CryptoDes3 crypto_des3_encrypt_init(const BYTE* key, const BYTE* ivec);

View File

@@ -31,6 +31,7 @@
#include "transport.h"
#include <winpr/crt.h>
#include <winpr/crypto.h>
#include <freerdp/log.h>
#include <freerdp/error.h>
@@ -512,19 +513,9 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp)
goto end;
}
rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len);
if (!rdp->rc4_decrypt_key)
{
WLog_ERR(TAG, "unable to allocate rc4 decrypt key");
goto end;
}
winpr_RC4_Init(rdp->rc4_decrypt_key, rdp->decrypt_key, rdp->rc4_key_len);
winpr_RC4_Init(rdp->rc4_encrypt_key, rdp->encrypt_key, rdp->rc4_key_len);
rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len);
if (!rdp->rc4_encrypt_key)
{
WLog_ERR(TAG, "unable to allocate rc4 encrypt key");
goto end;
}
ret = TRUE;
end:
free(crypt_client_random);
@@ -630,19 +621,9 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s)
goto end;
}
rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len);
if (!rdp->rc4_decrypt_key)
{
WLog_ERR(TAG, "unable to allocate rc4 decrypt key");
goto end;
}
winpr_RC4_Init(rdp->rc4_decrypt_key, rdp->decrypt_key, rdp->rc4_key_len);
winpr_RC4_Init(rdp->rc4_encrypt_key, rdp->encrypt_key, rdp->rc4_key_len);
rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len);
if (!rdp->rc4_encrypt_key)
{
WLog_ERR(TAG, "unable to allocate rc4 encrypt key");
goto end;
}
ret = TRUE;
end:
free(crypt_client_random);

View File

@@ -455,27 +455,19 @@ BOOL license_encrypt_premaster_secret(rdpLicense* license)
BOOL license_decrypt_platform_challenge(rdpLicense* license)
{
CryptoRc4 rc4;
WINPR_RC4_CTX rc4;
license->PlatformChallenge->data = (BYTE *)malloc(license->EncryptedPlatformChallenge->length);
if (!license->PlatformChallenge->data)
return FALSE;
license->PlatformChallenge->length = license->EncryptedPlatformChallenge->length;
rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
if (!rc4)
{
WLog_ERR(TAG, "unable to allocate a rc4");
free(license->PlatformChallenge->data);
license->PlatformChallenge->data = NULL;
return FALSE;
}
crypto_rc4(rc4, license->EncryptedPlatformChallenge->length,
winpr_RC4_Init(&rc4, license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
winpr_RC4_Update(&rc4, license->EncryptedPlatformChallenge->length,
license->EncryptedPlatformChallenge->data,
license->PlatformChallenge->data);
crypto_rc4_free(rc4);
winpr_RC4_Final(&rc4);
return TRUE;
}
@@ -1020,7 +1012,7 @@ BOOL license_send_platform_challenge_response_packet(rdpLicense* license)
wStream* s;
int length;
BYTE* buffer;
CryptoRc4 rc4;
WINPR_RC4_CTX rc4;
BYTE mac_data[16];
BOOL status;
@@ -1041,19 +1033,15 @@ BOOL license_send_platform_challenge_response_packet(rdpLicense* license)
if (!status)
return FALSE;
rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
if (!rc4)
{
WLog_ERR(TAG, "unable to allocate a rc4");
return FALSE;
}
winpr_RC4_Init(&rc4, license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
buffer = (BYTE*) malloc(HWID_LENGTH);
if (!buffer)
return FALSE;
crypto_rc4(rc4, HWID_LENGTH, license->HardwareId, buffer);
crypto_rc4_free(rc4);
winpr_RC4_Update(&rc4, HWID_LENGTH, license->HardwareId, buffer);
winpr_RC4_Final(&rc4);
license->EncryptedHardwareId->type = BB_DATA_BLOB;
license->EncryptedHardwareId->data = buffer;
license->EncryptedHardwareId->length = HWID_LENGTH;

View File

@@ -27,6 +27,7 @@ typedef struct rdp_nla rdpNla;
#include <winpr/sspi.h>
#include <winpr/stream.h>
#include <winpr/crypto.h>
#include <freerdp/crypto/tls.h>
#include <freerdp/crypto/ber.h>
@@ -75,7 +76,7 @@ struct rdp_nla
SecBuffer authInfo;
SecBuffer PublicKey;
SecBuffer tsCredentials;
CryptoRc4 rc4SealState;
WINPR_RC4_CTX rc4SealState;
LPTSTR ServicePrincipalName;
SEC_WINNT_AUTH_IDENTITY* identity;
PSecurityFunctionTable table;

View File

@@ -1590,13 +1590,13 @@ void rdp_reset(rdpRdp* rdp)
if (rdp->rc4_decrypt_key)
{
crypto_rc4_free(rdp->rc4_decrypt_key);
winpr_RC4_Final(rdp->rc4_decrypt_key);
rdp->rc4_decrypt_key = NULL;
}
if (rdp->rc4_encrypt_key)
{
crypto_rc4_free(rdp->rc4_encrypt_key);
winpr_RC4_Final(rdp->rc4_encrypt_key);
rdp->rc4_encrypt_key = NULL;
}
@@ -1661,8 +1661,8 @@ void rdp_free(rdpRdp* rdp)
{
if (rdp)
{
crypto_rc4_free(rdp->rc4_decrypt_key);
crypto_rc4_free(rdp->rc4_encrypt_key);
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);
crypto_hmac_free(rdp->fips_hmac);

View File

@@ -51,6 +51,7 @@
#include <freerdp/log.h>
#include <winpr/stream.h>
#include <winpr/crypto.h>
/* Security Header Flags */
#define SEC_EXCHANGE_PKT 0x0001
@@ -147,10 +148,10 @@ struct rdp_rdp
rdpAutoDetect* autodetect;
rdpHeartbeat* heartbeat;
rdpMultitransport* multitransport;
struct crypto_rc4_struct* rc4_decrypt_key;
WINPR_RC4_CTX* rc4_decrypt_key;
int decrypt_use_count;
int decrypt_checksum_use_count;
struct crypto_rc4_struct* rc4_encrypt_key;
WINPR_RC4_CTX* rc4_encrypt_key;
int encrypt_use_count;
int encrypt_checksum_use_count;
struct crypto_des3_struct* fips_encrypt;

View File

@@ -477,7 +477,7 @@ BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp)
BYTE sha1h[WINPR_SHA1_DIGEST_LENGTH];
WINPR_MD5_CTX md5;
WINPR_SHA1_CTX sha1;
CryptoRc4 rc4;
WINPR_RC4_CTX rc4;
BYTE salt[] = { 0xD1, 0x26, 0x9E }; /* 40 bits: 3 bytes, 56 bits: 1 byte */
winpr_SHA1_Init(&sha1);
@@ -492,14 +492,9 @@ BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp)
winpr_MD5_Update(&md5, sha1h, sizeof(sha1h));
winpr_MD5_Final(&md5, key);
rc4 = crypto_rc4_init(key, key_len);
if (!rc4)
{
WLog_ERR(TAG, "unable to allocate a rc4");
return FALSE;
}
crypto_rc4(rc4, key_len, key, key);
crypto_rc4_free(rc4);
winpr_RC4_Init(&rc4, key, key_len);
winpr_RC4_Update(&rc4, key_len, key, key);
winpr_RC4_Final(&rc4);
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_40BIT)
memcpy(key, salt, 3);
@@ -516,17 +511,13 @@ BOOL security_encrypt(BYTE* data, int length, rdpRdp* rdp)
if (!security_key_update(rdp->encrypt_key, rdp->encrypt_update_key, rdp->rc4_key_len, rdp))
return FALSE;
crypto_rc4_free(rdp->rc4_encrypt_key);
rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len);
if (!rdp->rc4_encrypt_key)
{
WLog_ERR(TAG, "unable to allocate rc4 encrypt key");
return FALSE;
}
winpr_RC4_Final(rdp->rc4_encrypt_key);
winpr_RC4_Init(rdp->rc4_encrypt_key, rdp->encrypt_key, rdp->rc4_key_len);
rdp->encrypt_use_count = 0;
}
crypto_rc4(rdp->rc4_encrypt_key, length, data, data);
winpr_RC4_Update(rdp->rc4_encrypt_key, length, data, data);
rdp->encrypt_use_count++;
rdp->encrypt_checksum_use_count++;
return TRUE;
@@ -541,17 +532,12 @@ BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp)
{
if (!security_key_update(rdp->decrypt_key, rdp->decrypt_update_key, rdp->rc4_key_len, rdp))
return FALSE;
crypto_rc4_free(rdp->rc4_decrypt_key);
rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len);
if (!rdp->rc4_decrypt_key)
{
WLog_ERR(TAG, "unable to allocate rc4 decrypt key");
return FALSE;
}
winpr_RC4_Final(rdp->rc4_decrypt_key);
winpr_RC4_Init(rdp->rc4_decrypt_key, rdp->decrypt_key, rdp->rc4_key_len);
rdp->decrypt_use_count = 0;
}
crypto_rc4(rdp->rc4_decrypt_key, length, data, data);
winpr_RC4_Update(rdp->rc4_decrypt_key, length, data, data);
rdp->decrypt_use_count += 1;
rdp->decrypt_checksum_use_count++;
return TRUE;

View File

@@ -28,25 +28,6 @@
#define TAG FREERDP_TAG("crypto")
CryptoRc4 crypto_rc4_init(const BYTE* key, UINT32 length)
{
CryptoRc4 rc4 = malloc(sizeof(*rc4));
if (!rc4)
return NULL;
RC4_set_key(&rc4->rc4_key, length, key);
return rc4;
}
void crypto_rc4(CryptoRc4 rc4, UINT32 length, const BYTE* in_data, BYTE* out_data)
{
RC4(&rc4->rc4_key, length, in_data, out_data);
}
void crypto_rc4_free(CryptoRc4 rc4)
{
free(rc4);
}
CryptoDes3 crypto_des3_encrypt_init(const BYTE* key, const BYTE* ivec)
{
CryptoDes3 des3 = malloc(sizeof(*des3));