Merge pull request #2513 from hardening/license_and_security_retValues

License and security ret values
This commit is contained in:
Bernhard Miklautz 2015-04-08 11:33:57 +02:00
commit 879ed36a3c
11 changed files with 319 additions and 174 deletions

View File

@ -103,15 +103,15 @@ 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 void crypto_des3_encrypt(CryptoDes3 des3, UINT32 length, const BYTE *in_data, BYTE *out_data);
FREERDP_API void crypto_des3_decrypt(CryptoDes3 des3, UINT32 length, const BYTE *in_data, BYTE* out_data);
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_hmac_struct* CryptoHmac;
FREERDP_API CryptoHmac crypto_hmac_new(void);
FREERDP_API void crypto_hmac_sha1_init(CryptoHmac hmac, const BYTE *data, UINT32 length);
FREERDP_API void crypto_hmac_md5_init(CryptoHmac hmac, const BYTE *data, UINT32 length);
FREERDP_API BOOL crypto_hmac_sha1_init(CryptoHmac hmac, const BYTE *data, UINT32 length);
FREERDP_API BOOL crypto_hmac_md5_init(CryptoHmac hmac, const BYTE *data, UINT32 length);
FREERDP_API void crypto_hmac_update(CryptoHmac hmac, const BYTE *data, UINT32 length);
FREERDP_API void crypto_hmac_final(CryptoHmac hmac, BYTE *out_data, UINT32 length);
FREERDP_API void crypto_hmac_free(CryptoHmac hmac);

View File

@ -817,23 +817,28 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNu
Stream_Write_UINT8(s, 0x1); /* TSFIPS_VERSION 1*/
Stream_Write_UINT8(s, pad); /* padding */
security_hmac_signature(fpInputEvents, fpInputEvents_length, Stream_Pointer(s), rdp);
if (!security_hmac_signature(fpInputEvents, fpInputEvents_length, Stream_Pointer(s), rdp))
return FALSE;
if (pad)
memset(fpInputEvents + fpInputEvents_length, 0, pad);
security_fips_encrypt(fpInputEvents, fpInputEvents_length + pad, rdp);
if (!security_fips_encrypt(fpInputEvents, fpInputEvents_length + pad, rdp))
return FALSE;
length += pad;
}
else
{
if (rdp->sec_flags & SEC_SECURE_CHECKSUM)
security_salted_mac_signature(rdp, fpInputEvents, fpInputEvents_length, TRUE, Stream_Pointer(s));
else
security_mac_signature(rdp, fpInputEvents, fpInputEvents_length, Stream_Pointer(s));
BOOL status;
security_encrypt(fpInputEvents, fpInputEvents_length, rdp);
if (rdp->sec_flags & SEC_SECURE_CHECKSUM)
status = security_salted_mac_signature(rdp, fpInputEvents, fpInputEvents_length, TRUE, Stream_Pointer(s));
else
status = security_mac_signature(rdp, fpInputEvents, fpInputEvents_length, Stream_Pointer(s));
if (!status || !security_encrypt(fpInputEvents, fpInputEvents_length, rdp))
return FALSE;
}
}
@ -1021,17 +1026,19 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
{
security_hmac_signature(data, dataSize - pad, pSignature, rdp);
if (!security_hmac_signature(data, dataSize - pad, pSignature, rdp))
return FALSE;
security_fips_encrypt(data, dataSize, rdp);
}
else
{
if (rdp->sec_flags & SEC_SECURE_CHECKSUM)
security_salted_mac_signature(rdp, data, dataSize, TRUE, pSignature);
status = security_salted_mac_signature(rdp, data, dataSize, TRUE, pSignature);
else
security_mac_signature(rdp, data, dataSize, pSignature);
status = security_mac_signature(rdp, data, dataSize, pSignature);
security_encrypt(data, dataSize, rdp);
if (!status || !security_encrypt(data, dataSize, rdp))
return FALSE;
}
}

View File

@ -72,7 +72,8 @@ BOOL rdp_compute_client_auto_reconnect_cookie(rdpRdp* rdp)
/* SecurityVerifier = HMAC_MD5(AutoReconnectRandom, ClientRandom) */
crypto_hmac_md5_init(hmac, AutoReconnectRandom, 16);
if (!crypto_hmac_md5_init(hmac, AutoReconnectRandom, 16))
return FALSE;
crypto_hmac_update(hmac, ClientRandom, 32);
crypto_hmac_final(hmac, clientCookie->securityVerifier, 16);
crypto_hmac_free(hmac);

View File

@ -179,6 +179,8 @@ wStream* license_send_stream_init(rdpLicense* license)
}
s = transport_send_stream_init(license->rdp->transport, 4096);
if (!s)
return NULL;
rdp_init_stream(license->rdp, s);
license->rdp->do_crypt = do_crypt;
@ -268,7 +270,6 @@ int license_recv(rdpLicense* license, wStream* s)
Stream_Rewind(s, RDP_SECURITY_HEADER_LENGTH);
status = rdp_recv_out_of_sequence_pdu(license->rdp, s);
if (status < 0)
{
WLog_ERR(TAG, "unexpected license packet.");
@ -286,31 +287,34 @@ int license_recv(rdpLicense* license, wStream* s)
switch (bMsgType)
{
case LICENSE_REQUEST:
if (!license_read_license_request_packet(license, s))
return -1;
license_send_new_license_request_packet(license);
if (!license_send_new_license_request_packet(license))
return -1;
break;
case PLATFORM_CHALLENGE:
case PLATFORM_CHALLENGE:
if (!license_read_platform_challenge_packet(license, s))
return -1;
license_send_platform_challenge_response_packet(license);
if (!license_send_platform_challenge_response_packet(license))
return -1;
break;
case NEW_LICENSE:
license_read_new_license_packet(license, s);
break;
case UPGRADE_LICENSE:
license_read_upgrade_license_packet(license, s);
break;
case ERROR_ALERT:
case ERROR_ALERT:
if (!license_read_error_alert_packet(license, s))
return -1;
break;
default:
WLog_ERR(TAG, "invalid bMsgType:%d", bMsgType);
return FALSE;
@ -336,15 +340,23 @@ void license_generate_randoms(rdpLicense* license)
* @param license license module
*/
void license_generate_keys(rdpLicense* license)
BOOL license_generate_keys(rdpLicense* license)
{
security_master_secret(license->PremasterSecret, license->ClientRandom,
license->ServerRandom, license->MasterSecret); /* MasterSecret */
security_session_key_blob(license->MasterSecret, license->ClientRandom,
license->ServerRandom, license->SessionKeyBlob); /* SessionKeyBlob */
BOOL ret;
if (
/* MasterSecret */
!security_master_secret(license->PremasterSecret, license->ClientRandom,
license->ServerRandom, license->MasterSecret) ||
/* SessionKeyBlob */
!security_session_key_blob(license->MasterSecret, license->ClientRandom,
license->ServerRandom, license->SessionKeyBlob))
{
return FALSE;
}
security_mac_salt_key(license->SessionKeyBlob, license->ClientRandom,
license->ServerRandom, license->MacSaltKey); /* MacSaltKey */
security_licensing_encryption_key(license->SessionKeyBlob, license->ClientRandom,
ret = security_licensing_encryption_key(license->SessionKeyBlob, license->ClientRandom,
license->ServerRandom, license->LicensingEncryptionKey); /* LicensingEncryptionKey */
#ifdef WITH_DEBUG_LICENSE
WLog_DBG(TAG, "ClientRandom:");
@ -362,6 +374,7 @@ void license_generate_keys(rdpLicense* license)
WLog_DBG(TAG, "LicensingEncryptionKey:");
winpr_HexDump(TAG, WLOG_DEBUG, license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
#endif
return ret;
}
/**
@ -369,7 +382,7 @@ void license_generate_keys(rdpLicense* license)
* @param license license module
*/
void license_generate_hwid(rdpLicense* license)
BOOL license_generate_hwid(rdpLicense* license)
{
CryptoMd5 md5;
BYTE macAddress[6];
@ -382,14 +395,15 @@ void license_generate_hwid(rdpLicense* license)
if (!md5)
{
WLog_ERR(TAG, "unable to allocate a md5");
return;
return FALSE;
}
crypto_md5_update(md5, macAddress, sizeof(macAddress));
crypto_md5_final(md5, &license->HardwareId[HWID_PLATFORM_ID_LENGTH]);
return TRUE;
}
void license_get_server_rsa_public_key(rdpLicense* license)
BOOL license_get_server_rsa_public_key(rdpLicense* license)
{
BYTE* Exponent;
BYTE* Modulus;
@ -398,8 +412,9 @@ void license_get_server_rsa_public_key(rdpLicense* license)
if (license->ServerCertificate->length < 1)
{
certificate_read_server_certificate(license->certificate,
settings->ServerCertificate, settings->ServerCertificateLength);
if (!certificate_read_server_certificate(license->certificate,
settings->ServerCertificate, settings->ServerCertificateLength))
return FALSE;
}
Exponent = license->certificate->cert_info.exponent;
@ -409,19 +424,26 @@ void license_get_server_rsa_public_key(rdpLicense* license)
license->ModulusLength = ModulusLength;
license->Modulus = (BYTE*) malloc(ModulusLength);
CopyMemory(license->Modulus, Modulus, ModulusLength);
return TRUE;
}
void license_encrypt_premaster_secret(rdpLicense* license)
BOOL license_encrypt_premaster_secret(rdpLicense* license)
{
BYTE* EncryptedPremasterSecret;
license_get_server_rsa_public_key(license);
if (!license_get_server_rsa_public_key(license))
return FALSE;
#ifdef WITH_DEBUG_LICENSE
WLog_DBG(TAG, "Modulus (%d bits):", license->ModulusLength * 8);
winpr_HexDump(TAG, WLOG_DEBUG, license->Modulus, license->ModulusLength);
WLog_DBG(TAG, "Exponent:");
winpr_HexDump(TAG, WLOG_DEBUG, license->Exponent, 4);
#endif
EncryptedPremasterSecret = (BYTE*) calloc(1, license->ModulusLength);
if (!EncryptedPremasterSecret)
return FALSE;
license->EncryptedPremasterSecret->type = BB_RANDOM_BLOB;
license->EncryptedPremasterSecret->length = PREMASTER_SECRET_LENGTH;
@ -431,21 +453,25 @@ void license_encrypt_premaster_secret(rdpLicense* license)
license->ModulusLength, license->Modulus, license->Exponent, EncryptedPremasterSecret);
#endif
license->EncryptedPremasterSecret->data = EncryptedPremasterSecret;
return TRUE;
}
void license_decrypt_platform_challenge(rdpLicense* license)
BOOL license_decrypt_platform_challenge(rdpLicense* license)
{
CryptoRc4 rc4;
license->PlatformChallenge->data = (BYTE*) malloc(license->EncryptedPlatformChallenge->length);
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");
return;
free(license->PlatformChallenge->data);
license->PlatformChallenge->data = NULL;
return FALSE;
}
crypto_rc4(rc4, license->EncryptedPlatformChallenge->length,
@ -453,6 +479,7 @@ void license_decrypt_platform_challenge(rdpLicense* license)
license->PlatformChallenge->data);
crypto_rc4_free(rc4);
return TRUE;
}
/**
@ -569,17 +596,20 @@ BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob)
* @param blob license binary blob
*/
void license_write_binary_blob(wStream* s, LICENSE_BLOB* blob)
BOOL license_write_binary_blob(wStream* s, LICENSE_BLOB* blob)
{
Stream_EnsureRemainingCapacity(s, blob->length + 4);
if (!Stream_EnsureRemainingCapacity(s, blob->length + 4))
return FALSE;
Stream_Write_UINT16(s, blob->type); /* wBlobType (2 bytes) */
Stream_Write_UINT16(s, blob->length); /* wBlobLen (2 bytes) */
if (blob->length > 0)
Stream_Write(s, blob->data, blob->length); /* blobData */
return TRUE;
}
void license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blob, UINT32 ModulusLength)
BOOL license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blob, UINT32 ModulusLength)
{
UINT32 length;
length = ModulusLength + 8;
@ -587,10 +617,11 @@ void license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blo
if (blob->length > ModulusLength)
{
WLog_ERR(TAG, "license_write_encrypted_premaster_secret_blob: invalid blob");
return;
return FALSE;
}
Stream_EnsureRemainingCapacity(s, length + 4);
if (!Stream_EnsureRemainingCapacity(s, length + 4))
return FALSE;
Stream_Write_UINT16(s, blob->type); /* wBlobType (2 bytes) */
Stream_Write_UINT16(s, length); /* wBlobLen (2 bytes) */
@ -598,6 +629,7 @@ void license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blo
Stream_Write(s, blob->data, blob->length); /* blobData */
Stream_Zero(s, length - blob->length);
return TRUE;
}
/**
@ -742,9 +774,10 @@ BOOL license_read_license_request_packet(rdpLicense* license, wStream* s)
license->ServerCertificate->data, license->ServerCertificate->length))
return FALSE;
license_generate_keys(license);
license_generate_hwid(license);
license_encrypt_premaster_secret(license);
if (!license_generate_keys(license) || !license_generate_hwid(license) ||
!license_encrypt_premaster_secret(license))
return FALSE;
#ifdef WITH_DEBUG_LICENSE
WLog_DBG(TAG, "ServerRandom:");
winpr_HexDump(TAG, WLOG_DEBUG, license->ServerRandom, 32);
@ -765,6 +798,7 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s)
{
BYTE MacData[16];
UINT32 ConnectFlags = 0;
DEBUG_LICENSE("Receiving Platform Challenge Packet");
if (Stream_GetRemainingLength(s) < 4)
@ -780,7 +814,8 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s)
return FALSE;
Stream_Read(s, MacData, 16); /* MACData (16 bytes) */
license_decrypt_platform_challenge(license);
if (!license_decrypt_platform_challenge(license))
return FALSE;
#ifdef WITH_DEBUG_LICENSE
WLog_DBG(TAG, "ConnectFlags: 0x%08X", ConnectFlags);
WLog_DBG(TAG, "EncryptedPlatformChallenge:");
@ -878,17 +913,26 @@ BOOL license_read_error_alert_packet(rdpLicense* license, wStream* s)
* @param s stream
*/
void license_write_new_license_request_packet(rdpLicense* license, wStream* s)
BOOL license_write_new_license_request_packet(rdpLicense* license, wStream* s)
{
UINT32 PlatformId;
UINT32 PreferredKeyExchangeAlg = KEY_EXCHANGE_ALG_RSA;
PlatformId = CLIENT_OS_ID_WINNT_POST_52 | CLIENT_IMAGE_ID_MICROSOFT;
Stream_Write_UINT32(s, PreferredKeyExchangeAlg); /* PreferredKeyExchangeAlg (4 bytes) */
Stream_Write_UINT32(s, PlatformId); /* PlatformId (4 bytes) */
Stream_Write(s, license->ClientRandom, 32); /* ClientRandom (32 bytes) */
license_write_encrypted_premaster_secret_blob(s, license->EncryptedPremasterSecret, license->ModulusLength); /* EncryptedPremasterSecret */
license_write_binary_blob(s, license->ClientUserName); /* ClientUserName */
license_write_binary_blob(s, license->ClientMachineName); /* ClientMachineName */
/* EncryptedPremasterSecret */
if (!license_write_encrypted_premaster_secret_blob(s, license->EncryptedPremasterSecret, license->ModulusLength) ||
/* ClientUserName */
!license_write_binary_blob(s, license->ClientUserName) ||
/* ClientMachineName */
!license_write_binary_blob(s, license->ClientMachineName))
{
return FALSE;
}
#ifdef WITH_DEBUG_LICENSE
WLog_DBG(TAG, "PreferredKeyExchangeAlg: 0x%08X", PreferredKeyExchangeAlg);
WLog_DBG(TAG, "ClientRandom:");
@ -898,6 +942,7 @@ void license_write_new_license_request_packet(rdpLicense* license, wStream* s)
WLog_DBG(TAG, "ClientUserName (%d): %s", license->ClientUserName->length, (char*) license->ClientUserName->data);
WLog_DBG(TAG, "ClientMachineName (%d): %s", license->ClientMachineName->length, (char*) license->ClientMachineName->data);
#endif
return TRUE;
}
/**
@ -906,12 +951,14 @@ void license_write_new_license_request_packet(rdpLicense* license, wStream* s)
* @param license license module
*/
void license_send_new_license_request_packet(rdpLicense* license)
BOOL license_send_new_license_request_packet(rdpLicense* license)
{
wStream* s;
char* username;
DEBUG_LICENSE("Sending New License Packet");
s = license_send_stream_init(license);
if (!s)
return FALSE;
if (license->rdp->settings->Username != NULL)
username = license->rdp->settings->Username;
@ -922,12 +969,17 @@ void license_send_new_license_request_packet(rdpLicense* license)
license->ClientUserName->length = strlen(username) + 1;
license->ClientMachineName->data = (BYTE*) license->rdp->settings->ClientHostname;
license->ClientMachineName->length = strlen(license->rdp->settings->ClientHostname) + 1;
license_write_new_license_request_packet(license, s);
license_send(license, s, NEW_LICENSE_REQUEST);
if (!license_write_new_license_request_packet(license, s) ||
!license_send(license, s, NEW_LICENSE_REQUEST))
{
return FALSE;
}
license->ClientUserName->data = NULL;
license->ClientUserName->length = 0;
license->ClientMachineName->data = NULL;
license->ClientMachineName->length = 0;
return TRUE;
}
/**
@ -938,12 +990,17 @@ void license_send_new_license_request_packet(rdpLicense* license)
* @param mac_data signature
*/
void license_write_platform_challenge_response_packet(rdpLicense* license, wStream* s, BYTE* macData)
BOOL license_write_platform_challenge_response_packet(rdpLicense* license, wStream* s, BYTE* macData)
{
license_write_binary_blob(s, license->EncryptedPlatformChallenge); /* EncryptedPlatformChallengeResponse */
license_write_binary_blob(s, license->EncryptedHardwareId); /* EncryptedHWID */
Stream_EnsureRemainingCapacity(s, 16);
if (!license_write_binary_blob(s, license->EncryptedPlatformChallenge) || /* EncryptedPlatformChallengeResponse */
!license_write_binary_blob(s, license->EncryptedHardwareId) || /* EncryptedHWID */
!Stream_EnsureRemainingCapacity(s, 16))
{
return FALSE;
}
Stream_Write(s, macData, 16); /* MACData */
return TRUE;
}
/**
@ -952,32 +1009,43 @@ void license_write_platform_challenge_response_packet(rdpLicense* license, wStre
* @param license license module
*/
void license_send_platform_challenge_response_packet(rdpLicense* license)
BOOL license_send_platform_challenge_response_packet(rdpLicense* license)
{
wStream* s;
int length;
BYTE* buffer;
CryptoRc4 rc4;
BYTE mac_data[16];
BOOL status;
DEBUG_LICENSE("Sending Platform Challenge Response Packet");
s = license_send_stream_init(license);
license->EncryptedPlatformChallenge->type = BB_DATA_BLOB;
length = license->PlatformChallenge->length + HWID_LENGTH;
buffer = (BYTE*) malloc(length);
if (!buffer)
return FALSE;
CopyMemory(buffer, license->PlatformChallenge->data, license->PlatformChallenge->length);
CopyMemory(&buffer[license->PlatformChallenge->length], license->HardwareId, HWID_LENGTH);
security_mac_data(license->MacSaltKey, buffer, length, mac_data);
status = security_mac_data(license->MacSaltKey, buffer, length, mac_data);
free(buffer);
buffer = (BYTE*) malloc(HWID_LENGTH);
rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
if (!status)
return FALSE;
rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
if (!rc4)
{
WLog_ERR(TAG, "unable to allocate a rc4");
free(buffer);
return;
return FALSE;
}
buffer = (BYTE*) malloc(HWID_LENGTH);
if (!buffer)
return FALSE;
crypto_rc4(rc4, HWID_LENGTH, license->HardwareId, buffer);
crypto_rc4_free(rc4);
license->EncryptedHardwareId->type = BB_DATA_BLOB;
@ -991,8 +1059,8 @@ void license_send_platform_challenge_response_packet(rdpLicense* license)
WLog_DBG(TAG, "EncryptedHardwareId:");
winpr_HexDump(TAG, WLOG_DEBUG, license->EncryptedHardwareId->data, HWID_LENGTH);
#endif
license_write_platform_challenge_response_packet(license, s, mac_data);
license_send(license, s, PLATFORM_CHALLENGE_RESPONSE);
return license_write_platform_challenge_response_packet(license, s, mac_data) &&
license_send(license, s, PLATFORM_CHALLENGE_RESPONSE);
}
/**
@ -1005,11 +1073,15 @@ BOOL license_send_valid_client_error_packet(rdpLicense* license)
{
wStream* s;
s = license_send_stream_init(license);
if (!s)
return FALSE;
DEBUG_LICENSE("Sending Error Alert Packet");
Stream_Write_UINT32(s, STATUS_VALID_CLIENT); /* dwErrorCode */
Stream_Write_UINT32(s, ST_NO_TRANSITION); /* dwStateTransition */
license_write_binary_blob(s, license->ErrorInfo);
return license_send(license, s, ERROR_ALERT);
return license_write_binary_blob(s, license->ErrorInfo) &&
license_send(license, s, ERROR_ALERT);
}
/**

View File

@ -205,10 +205,10 @@ BOOL license_send(rdpLicense* license, wStream* s, BYTE type);
wStream* license_send_stream_init(rdpLicense* license);
void license_generate_randoms(rdpLicense* license);
void license_generate_keys(rdpLicense* license);
void license_generate_hwid(rdpLicense* license);
void license_encrypt_premaster_secret(rdpLicense* license);
void license_decrypt_platform_challenge(rdpLicense* license);
BOOL license_generate_keys(rdpLicense* license);
BOOL license_generate_hwid(rdpLicense* license);
BOOL license_encrypt_premaster_secret(rdpLicense* license);
BOOL license_decrypt_platform_challenge(rdpLicense* license);
LICENSE_PRODUCT_INFO* license_new_product_info(void);
void license_free_product_info(LICENSE_PRODUCT_INFO* productInfo);
@ -217,7 +217,7 @@ BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo);
LICENSE_BLOB* license_new_binary_blob(UINT16 type);
void license_free_binary_blob(LICENSE_BLOB* blob);
BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob);
void license_write_binary_blob(wStream* s, LICENSE_BLOB* blob);
BOOL license_write_binary_blob(wStream* s, LICENSE_BLOB* blob);
SCOPE_LIST* license_new_scope_list(void);
void license_free_scope_list(SCOPE_LIST* scopeList);
@ -229,11 +229,11 @@ void license_read_new_license_packet(rdpLicense* license, wStream* s);
void license_read_upgrade_license_packet(rdpLicense* license, wStream* s);
BOOL license_read_error_alert_packet(rdpLicense* license, wStream* s);
void license_write_new_license_request_packet(rdpLicense* license, wStream* s);
void license_send_new_license_request_packet(rdpLicense* license);
BOOL license_write_new_license_request_packet(rdpLicense* license, wStream* s);
BOOL license_send_new_license_request_packet(rdpLicense* license);
void license_write_platform_challenge_response_packet(rdpLicense* license, wStream* s, BYTE* mac_data);
void license_send_platform_challenge_response_packet(rdpLicense* license);
BOOL license_write_platform_challenge_response_packet(rdpLicense* license, wStream* s, BYTE* mac_data);
BOOL license_send_platform_challenge_response_packet(rdpLicense* license);
BOOL license_send_valid_client_error_packet(rdpLicense* license);

View File

@ -429,12 +429,13 @@ void rdp_write_header(rdpRdp* rdp, wStream* s, UINT16 length, UINT16 channelId)
Stream_Write_UINT16_BE(s, length); /* userData (OCTET_STRING) */
}
static UINT32 rdp_security_stream_out(rdpRdp* rdp, wStream* s, int length, UINT32 sec_flags)
static BOOL rdp_security_stream_out(rdpRdp* rdp, wStream* s, int length, UINT32 sec_flags, UINT32 *pad)
{
BYTE* data;
UINT32 pad = 0;
BOOL status;
sec_flags |= rdp->sec_flags;
*pad = 0;
if (sec_flags != 0)
{
@ -451,17 +452,18 @@ static UINT32 rdp_security_stream_out(rdpRdp* rdp, wStream* s, int length, UINT3
Stream_Write_UINT8(s, 0x1); /* TSFIPS_VERSION 1*/
/* handle padding */
pad = 8 - (length % 8);
*pad = 8 - (length % 8);
if (pad == 8)
if (*pad == 8)
pad = 0;
if (pad)
memset(data+length, 0, pad);
if (*pad)
memset(data+length, 0, *pad);
Stream_Write_UINT8(s, pad);
security_hmac_signature(data, length, Stream_Pointer(s), rdp);
Stream_Write_UINT8(s, *pad);
if (!security_hmac_signature(data, length, Stream_Pointer(s), rdp))
return FALSE;
Stream_Seek(s, 8);
security_fips_encrypt(data, length + pad, rdp);
security_fips_encrypt(data, length + *pad, rdp);
}
else
{
@ -469,19 +471,24 @@ static UINT32 rdp_security_stream_out(rdpRdp* rdp, wStream* s, int length, UINT3
length = length - (data - Stream_Buffer(s));
if (sec_flags & SEC_SECURE_CHECKSUM)
security_salted_mac_signature(rdp, data, length, TRUE, Stream_Pointer(s));
status = security_salted_mac_signature(rdp, data, length, TRUE, Stream_Pointer(s));
else
security_mac_signature(rdp, data, length, Stream_Pointer(s));
status = security_mac_signature(rdp, data, length, Stream_Pointer(s));
if (!status)
return FALSE;
Stream_Seek(s, 8);
security_encrypt(Stream_Pointer(s), length, rdp);
if (!security_encrypt(Stream_Pointer(s), length, rdp))
return FALSE;
}
}
rdp->sec_flags = 0;
}
return pad;
return TRUE;
}
static UINT32 rdp_get_sec_bytes(rdpRdp* rdp, UINT16 sec_flags)
@ -516,11 +523,15 @@ static UINT32 rdp_get_sec_bytes(rdpRdp* rdp, UINT16 sec_flags)
BOOL rdp_send(rdpRdp* rdp, wStream* s, UINT16 channel_id)
{
UINT32 pad;
UINT16 length;
length = Stream_GetPosition(s);
Stream_SetPosition(s, 0);
rdp_write_header(rdp, s, length, channel_id);
length += rdp_security_stream_out(rdp, s, length, 0);
if (!rdp_security_stream_out(rdp, s, length, 0, &pad))
return FALSE;
length += pad;
Stream_SetPosition(s, length);
Stream_SealLength(s);
@ -535,6 +546,8 @@ BOOL rdp_send_pdu(rdpRdp* rdp, wStream* s, UINT16 type, UINT16 channel_id)
UINT16 length;
UINT32 sec_bytes;
int sec_hold;
UINT32 pad;
length = Stream_GetPosition(s);
Stream_SetPosition(s, 0);
rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID);
@ -543,7 +556,11 @@ BOOL rdp_send_pdu(rdpRdp* rdp, wStream* s, UINT16 type, UINT16 channel_id)
Stream_Seek(s, sec_bytes);
rdp_write_share_control_header(s, length - sec_bytes, type, channel_id);
Stream_SetPosition(s, sec_hold);
length += rdp_security_stream_out(rdp, s, length, 0);
if (!rdp_security_stream_out(rdp, s, length, 0, &pad))
return FALSE;
length += pad;
Stream_SetPosition(s, length);
Stream_SealLength(s);
@ -558,6 +575,8 @@ BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type, UINT16 channel_id)
UINT16 length;
UINT32 sec_bytes;
int sec_hold;
UINT32 pad;
length = Stream_GetPosition(s);
Stream_SetPosition(s, 0);
rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID);
@ -567,7 +586,9 @@ BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type, UINT16 channel_id)
rdp_write_share_control_header(s, length - sec_bytes, PDU_TYPE_DATA, channel_id);
rdp_write_share_data_header(s, length - sec_bytes, type, rdp->settings->ShareId);
Stream_SetPosition(s, sec_hold);
length += rdp_security_stream_out(rdp, s, length, 0);
if (!rdp_security_stream_out(rdp, s, length, 0, &pad))
return FALSE;
length += pad;
Stream_SetPosition(s, length);
Stream_SealLength(s);
@ -582,6 +603,8 @@ BOOL rdp_send_message_channel_pdu(rdpRdp* rdp, wStream* s, UINT16 sec_flags)
UINT16 length;
UINT32 sec_bytes;
int sec_hold;
UINT32 pad;
length = Stream_GetPosition(s);
Stream_SetPosition(s, 0);
rdp_write_header(rdp, s, length, rdp->mcs->messageChannelId);
@ -589,7 +612,11 @@ BOOL rdp_send_message_channel_pdu(rdpRdp* rdp, wStream* s, UINT16 sec_flags)
sec_hold = Stream_GetPosition(s);
Stream_Seek(s, sec_bytes);
Stream_SetPosition(s, sec_hold);
length += rdp_security_stream_out(rdp, s, length, sec_flags);
if (!rdp_security_stream_out(rdp, s, length, sec_flags, &pad))
return FALSE;
length += pad;
Stream_SetPosition(s, length);
Stream_SealLength(s);
@ -956,6 +983,7 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags)
{
BYTE cmac[8];
BYTE wmac[8];
BOOL status;
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
{
@ -1001,9 +1029,12 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags)
return FALSE;
if (securityFlags & SEC_SECURE_CHECKSUM)
security_salted_mac_signature(rdp, Stream_Pointer(s), length, FALSE, cmac);
status = security_salted_mac_signature(rdp, Stream_Pointer(s), length, FALSE, cmac);
else
security_mac_signature(rdp, Stream_Pointer(s), length, cmac);
status = security_mac_signature(rdp, Stream_Pointer(s), length, cmac);
if (!status)
return FALSE;
if (memcmp(wmac, cmac, sizeof(wmac)) != 0)
{

View File

@ -123,7 +123,7 @@ fips_oddparity_table[256] =
0xf8, 0xf8, 0xfb, 0xfb, 0xfd, 0xfd, 0xfe, 0xfe
};
static void security_salted_hash(const BYTE* salt, const BYTE* input, int length,
static BOOL security_salted_hash(const BYTE* salt, const BYTE* input, int length,
const BYTE* salt1, const BYTE* salt2, BYTE* output)
{
CryptoMd5 md5;
@ -137,7 +137,7 @@ static void security_salted_hash(const BYTE* salt, const BYTE* input, int length
if (!sha1)
{
WLog_ERR(TAG, "unable to allocate a sha1");
return;
return FALSE;
}
crypto_sha1_update(sha1, input, length); /* Input */
crypto_sha1_update(sha1, salt, 48); /* Salt (48 bytes) */
@ -150,42 +150,44 @@ static void security_salted_hash(const BYTE* salt, const BYTE* input, int length
if (!md5)
{
WLog_ERR(TAG, "unable to allocate a md5");
return;
return FALSE;
}
crypto_md5_update(md5, salt, 48); /* Salt (48 bytes) */
crypto_md5_update(md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */
crypto_md5_final(md5, output);
return TRUE;
}
static void security_premaster_hash(const char* input, int length, const BYTE* premaster_secret, const BYTE* client_random, const BYTE* server_random, BYTE* output)
static BOOL security_premaster_hash(const char* input, int length, const BYTE* premaster_secret,
const BYTE* client_random, const BYTE* server_random, BYTE* output)
{
/* PremasterHash(Input) = SaltedHash(PremasterSecret, Input, ClientRandom, ServerRandom) */
security_salted_hash(premaster_secret, (BYTE*)input, length, client_random, server_random, output);
return security_salted_hash(premaster_secret, (BYTE*)input, length, client_random, server_random, output);
}
void security_master_secret(const BYTE* premaster_secret, const BYTE* client_random,
BOOL security_master_secret(const BYTE* premaster_secret, const BYTE* client_random,
const BYTE* server_random, BYTE* output)
{
/* MasterSecret = PremasterHash('A') + PremasterHash('BB') + PremasterHash('CCC') */
security_premaster_hash("A", 1, premaster_secret, client_random, server_random, &output[0]);
security_premaster_hash("BB", 2, premaster_secret, client_random, server_random, &output[16]);
security_premaster_hash("CCC", 3, premaster_secret, client_random, server_random, &output[32]);
return security_premaster_hash("A", 1, premaster_secret, client_random, server_random, &output[0]) &&
security_premaster_hash("BB", 2, premaster_secret, client_random, server_random, &output[16]) &&
security_premaster_hash("CCC", 3, premaster_secret, client_random, server_random, &output[32]);
}
static void security_master_hash(const char* input, int length, const BYTE* master_secret,
static BOOL security_master_hash(const char* input, int length, const BYTE* master_secret,
const BYTE* client_random, const BYTE* server_random, BYTE* output)
{
/* MasterHash(Input) = SaltedHash(MasterSecret, Input, ServerRandom, ClientRandom) */
security_salted_hash(master_secret, (const BYTE*)input, length, server_random, client_random, output);
return security_salted_hash(master_secret, (const BYTE*)input, length, server_random, client_random, output);
}
void security_session_key_blob(const BYTE* master_secret, const BYTE* client_random,
BOOL security_session_key_blob(const BYTE* master_secret, const BYTE* client_random,
const BYTE* server_random, BYTE* output)
{
/* MasterHash = MasterHash('A') + MasterHash('BB') + MasterHash('CCC') */
security_master_hash("A", 1, master_secret, client_random, server_random, &output[0]);
security_master_hash("BB", 2, master_secret, client_random, server_random, &output[16]);
security_master_hash("CCC", 3, master_secret, client_random, server_random, &output[32]);
return security_master_hash("A", 1, master_secret, client_random, server_random, &output[0]) &&
security_master_hash("BB", 2, master_secret, client_random, server_random, &output[16]) &&
security_master_hash("CCC", 3, master_secret, client_random, server_random, &output[32]);
}
void security_mac_salt_key(const BYTE* session_key_blob, const BYTE* client_random,
@ -195,7 +197,7 @@ void security_mac_salt_key(const BYTE* session_key_blob, const BYTE* client_rand
memcpy(output, session_key_blob, 16);
}
void security_md5_16_32_32(const BYTE* in0, const BYTE* in1, const BYTE* in2, BYTE* output)
BOOL security_md5_16_32_32(const BYTE* in0, const BYTE* in1, const BYTE* in2, BYTE* output)
{
CryptoMd5 md5;
@ -203,19 +205,20 @@ void security_md5_16_32_32(const BYTE* in0, const BYTE* in1, const BYTE* in2, BY
if (!md5)
{
WLog_ERR(TAG, "unable to allocate a md5");
return;
return FALSE;
}
crypto_md5_update(md5, in0, 16);
crypto_md5_update(md5, in1, 32);
crypto_md5_update(md5, in2, 32);
crypto_md5_final(md5, output);
return TRUE;
}
void security_licensing_encryption_key(const BYTE* session_key_blob, const BYTE* client_random,
BOOL security_licensing_encryption_key(const BYTE* session_key_blob, const BYTE* client_random,
const BYTE* server_random, BYTE* output)
{
/* LicensingEncryptionKey = MD5(Second128Bits(SessionKeyBlob) + ClientRandom + ServerRandom)) */
security_md5_16_32_32(&session_key_blob[16], client_random, server_random, output);
return security_md5_16_32_32(&session_key_blob[16], client_random, server_random, output);
}
void security_UINT32_le(BYTE* output, UINT32 value)
@ -226,7 +229,7 @@ void security_UINT32_le(BYTE* output, UINT32 value)
output[3] = (value >> 24) & 0xFF;
}
void security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length,
BOOL security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length,
BYTE* output)
{
CryptoMd5 md5;
@ -242,8 +245,8 @@ void security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length
sha1 = crypto_sha1_init();
if (!sha1)
{
WLog_ERR(TAG, "unable to allocate a sha1");
return;
WLog_ERR(TAG, "unable to allocate a sha1");
return FALSE;
}
crypto_sha1_update(sha1, mac_salt_key, 16); /* MacSaltKey */
crypto_sha1_update(sha1, pad1, sizeof(pad1)); /* pad1 */
@ -255,16 +258,17 @@ void security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length
md5 = crypto_md5_init();
if (!md5)
{
WLog_ERR(TAG, "unable to allocate a md5");
return;
WLog_ERR(TAG, "unable to allocate a md5");
return FALSE;
}
crypto_md5_update(md5, mac_salt_key, 16); /* MacSaltKey */
crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */
crypto_md5_update(md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */
crypto_md5_final(md5, output);
return TRUE;
}
void security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE* output)
BOOL security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE* output)
{
CryptoMd5 md5;
CryptoSha1 sha1;
@ -278,8 +282,8 @@ void security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE*
sha1 = crypto_sha1_init();
if (!sha1)
{
WLog_ERR(TAG, "unable to allocate a sha1");
return;
WLog_ERR(TAG, "unable to allocate a sha1");
return FALSE;
}
crypto_sha1_update(sha1, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
crypto_sha1_update(sha1, pad1, sizeof(pad1)); /* pad1 */
@ -291,8 +295,8 @@ void security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE*
md5 = crypto_md5_init();
if (!md5)
{
WLog_ERR(TAG, "unable to allocate a md5");
return;
WLog_ERR(TAG, "unable to allocate a md5");
return FALSE;
}
crypto_md5_update(md5, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */
@ -300,9 +304,10 @@ void security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE*
crypto_md5_final(md5, md5_digest);
memcpy(output, md5_digest, 8);
return TRUE;
}
void security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length,
BOOL security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length,
BOOL encryption, BYTE* output)
{
CryptoMd5 md5;
@ -331,8 +336,8 @@ void security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length,
sha1 = crypto_sha1_init();
if (!sha1)
{
WLog_ERR(TAG, "unable to allocate a sha1");
return;
WLog_ERR(TAG, "unable to allocate a sha1");
return FALSE;
}
crypto_sha1_update(sha1, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
crypto_sha1_update(sha1, pad1, sizeof(pad1)); /* pad1 */
@ -345,8 +350,8 @@ void security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length,
md5 = crypto_md5_init();
if (!md5)
{
WLog_ERR(TAG, "unable to allocate a md5");
return;
WLog_ERR(TAG, "unable to allocate a md5");
return FALSE;
}
crypto_md5_update(md5, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */
@ -354,22 +359,25 @@ void security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length,
crypto_md5_final(md5, md5_digest);
memcpy(output, md5_digest, 8);
return TRUE;
}
static void security_A(BYTE* master_secret, const BYTE* client_random, BYTE* server_random,
static BOOL security_A(BYTE* master_secret, const BYTE* client_random, BYTE* server_random,
BYTE* output)
{
security_premaster_hash("A", 1, master_secret, client_random, server_random, &output[0]);
security_premaster_hash("BB", 2, master_secret, client_random, server_random, &output[16]);
security_premaster_hash("CCC", 3, master_secret, client_random, server_random, &output[32]);
return
security_premaster_hash("A", 1, master_secret, client_random, server_random, &output[0]) &&
security_premaster_hash("BB", 2, master_secret, client_random, server_random, &output[16]) &&
security_premaster_hash("CCC", 3, master_secret, client_random, server_random, &output[32]);
}
static void security_X(BYTE* master_secret, const BYTE* client_random, BYTE* server_random,
static BOOL security_X(BYTE* master_secret, const BYTE* client_random, BYTE* server_random,
BYTE* output)
{
security_premaster_hash("X", 1, master_secret, client_random, server_random, &output[0]);
security_premaster_hash("YY", 2, master_secret, client_random, server_random, &output[16]);
security_premaster_hash("ZZZ", 3, master_secret, client_random, server_random, &output[32]);
return
security_premaster_hash("X", 1, master_secret, client_random, server_random, &output[0]) &&
security_premaster_hash("YY", 2, master_secret, client_random, server_random, &output[16]) &&
security_premaster_hash("ZZZ", 3, master_secret, client_random, server_random, &output[32]);
}
static void fips_expand_key_bits(BYTE* in, BYTE* out)
@ -413,6 +421,7 @@ BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp)
BYTE* server_random;
BYTE salt[] = { 0xD1, 0x26, 0x9E }; /* 40 bits: 3 bytes, 56 bits: 1 byte */
rdpSettings* settings;
BOOL status;
settings = rdp->settings;
server_random = settings->ServerRandom;
@ -469,26 +478,29 @@ BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp)
memcpy(pre_master_secret, client_random, 24);
memcpy(pre_master_secret + 24, server_random, 24);
security_A(pre_master_secret, client_random, server_random, master_secret);
security_X(master_secret, client_random, server_random, session_key_blob);
if (!security_A(pre_master_secret, client_random, server_random, master_secret) ||
!security_X(master_secret, client_random, server_random, session_key_blob))
{
return FALSE;
}
memcpy(rdp->sign_key, session_key_blob, 16);
if (rdp->settings->ServerMode)
{
security_md5_16_32_32(&session_key_blob[16], client_random,
server_random, rdp->encrypt_key);
security_md5_16_32_32(&session_key_blob[32], client_random,
server_random, rdp->decrypt_key);
status = security_md5_16_32_32(&session_key_blob[16], client_random, server_random, rdp->encrypt_key);
status &= security_md5_16_32_32(&session_key_blob[32], client_random, server_random, rdp->decrypt_key);
}
else
{
security_md5_16_32_32(&session_key_blob[16], client_random,
server_random, rdp->decrypt_key);
security_md5_16_32_32(&session_key_blob[32], client_random,
server_random, rdp->encrypt_key);
status = security_md5_16_32_32(&session_key_blob[16], client_random, server_random, rdp->decrypt_key);
status &= security_md5_16_32_32(&session_key_blob[32], client_random, server_random, rdp->encrypt_key);
}
if (!status)
return FALSE;
if (settings->EncryptionMethods == ENCRYPTION_METHOD_40BIT)
{
memcpy(rdp->sign_key, salt, 3);
@ -540,7 +552,7 @@ BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp)
md5 = crypto_md5_init();
if (!md5)
{
WLog_ERR(TAG, "unable to allocate a md5");
WLog_ERR(TAG, "unable to allocate a md5");
return FALSE;
}
crypto_md5_update(md5, update_key, key_len);
@ -551,7 +563,7 @@ BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp)
rc4 = crypto_rc4_init(key, key_len);
if (!rc4)
{
WLog_ERR(TAG, "unable to allocate a rc4");
WLog_ERR(TAG, "unable to allocate a rc4");
return FALSE;
}
crypto_rc4(rc4, key_len, key, key);
@ -569,16 +581,19 @@ BOOL security_encrypt(BYTE* data, int length, rdpRdp* rdp)
{
if (rdp->encrypt_use_count >= 4096)
{
security_key_update(rdp->encrypt_key, rdp->encrypt_update_key, rdp->rc4_key_len, 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");
WLog_ERR(TAG, "unable to allocate rc4 encrypt key");
return FALSE;
}
rdp->encrypt_use_count = 0;
}
crypto_rc4(rdp->rc4_encrypt_key, length, data, data);
rdp->encrypt_use_count++;
rdp->encrypt_checksum_use_count++;
@ -589,9 +604,11 @@ BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp)
{
if (rdp->rc4_decrypt_key == NULL)
return FALSE;
if (rdp->decrypt_use_count >= 4096)
{
security_key_update(rdp->decrypt_key, rdp->decrypt_update_key, rdp->rc4_key_len, 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)
@ -608,32 +625,35 @@ BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp)
return TRUE;
}
void security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp* rdp)
BOOL security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp* rdp)
{
BYTE buf[20];
BYTE use_count_le[4];
security_UINT32_le(use_count_le, rdp->encrypt_use_count);
crypto_hmac_sha1_init(rdp->fips_hmac, rdp->fips_sign_key, 20);
if (!crypto_hmac_sha1_init(rdp->fips_hmac, rdp->fips_sign_key, 20))
return FALSE;
crypto_hmac_update(rdp->fips_hmac, data, length);
crypto_hmac_update(rdp->fips_hmac, use_count_le, 4);
crypto_hmac_final(rdp->fips_hmac, buf, 20);
memmove(output, buf, 8);
return TRUE;
}
BOOL security_fips_encrypt(BYTE* data, int length, rdpRdp* rdp)
{
crypto_des3_encrypt(rdp->fips_encrypt, length, data, data);
if (!crypto_des3_encrypt(rdp->fips_encrypt, length, data, data))
return FALSE;
rdp->encrypt_use_count++;
return TRUE;
}
BOOL security_fips_decrypt(BYTE* data, int length, rdpRdp* rdp)
{
crypto_des3_decrypt(rdp->fips_decrypt, length, data, data);
return TRUE;
return crypto_des3_decrypt(rdp->fips_decrypt, length, data, data);
}
BOOL security_fips_check_signature(const BYTE* data, int length, const BYTE* sig, rdpRdp* rdp)
@ -643,7 +663,8 @@ BOOL security_fips_check_signature(const BYTE* data, int length, const BYTE* sig
security_UINT32_le(use_count_le, rdp->decrypt_use_count);
crypto_hmac_sha1_init(rdp->fips_hmac, rdp->fips_sign_key, 20);
if (!crypto_hmac_sha1_init(rdp->fips_hmac, rdp->fips_sign_key, 20))
return FALSE;
crypto_hmac_update(rdp->fips_hmac, data, length);
crypto_hmac_update(rdp->fips_hmac, use_count_le, 4);
crypto_hmac_final(rdp->fips_hmac, buf, 20);

View File

@ -27,20 +27,20 @@
#include <winpr/stream.h>
void security_master_secret(const BYTE* premaster_secret, const BYTE* client_random, const BYTE* server_random, BYTE* output);
void security_session_key_blob(const BYTE* master_secret, const BYTE* client_random, const BYTE* server_random, BYTE* output);
BOOL security_master_secret(const BYTE* premaster_secret, const BYTE* client_random, const BYTE* server_random, BYTE* output);
BOOL security_session_key_blob(const BYTE* master_secret, const BYTE* client_random, const BYTE* server_random, BYTE* output);
void security_mac_salt_key(const BYTE* session_key_blob, const BYTE* client_random, const BYTE* server_random, BYTE* output);
void security_licensing_encryption_key(const BYTE* session_key_blob, const BYTE* client_random, const BYTE* server_random, BYTE* output);
void security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length, BYTE* output);
BOOL security_licensing_encryption_key(const BYTE* session_key_blob, const BYTE* client_random, const BYTE* server_random, BYTE* output);
BOOL security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length, BYTE* output);
void security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE* output);
void security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BOOL encryption, BYTE* output);
BOOL security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE* output);
BOOL security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BOOL encryption, BYTE* output);
BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp);
BOOL security_encrypt(BYTE* data, int length, rdpRdp* rdp);
BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp);
void security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp* rdp);
BOOL security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp* rdp);
BOOL security_fips_encrypt(BYTE* data, int length, rdpRdp* rdp);
BOOL security_fips_decrypt(BYTE* data, int length, rdpRdp* rdp);
BOOL security_fips_check_signature(const BYTE* data, int length, const BYTE* sig, rdpRdp* rdp);

1
libfreerdp/core/test/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
TestCore.c

View File

@ -112,19 +112,20 @@ CryptoDes3 crypto_des3_decrypt_init(const BYTE* key, const BYTE* ivec)
return des3;
}
void crypto_des3_encrypt(CryptoDes3 des3, UINT32 length, const BYTE* in_data, BYTE* out_data)
BOOL crypto_des3_encrypt(CryptoDes3 des3, UINT32 length, const BYTE* in_data, BYTE* out_data)
{
int len;
EVP_EncryptUpdate(&des3->des3_ctx, out_data, &len, in_data, length);
return EVP_EncryptUpdate(&des3->des3_ctx, out_data, &len, in_data, length) == 1;
}
void crypto_des3_decrypt(CryptoDes3 des3, UINT32 length, const BYTE* in_data, BYTE* out_data)
BOOL crypto_des3_decrypt(CryptoDes3 des3, UINT32 length, const BYTE* in_data, BYTE* out_data)
{
int len;
EVP_DecryptUpdate(&des3->des3_ctx, out_data, &len, in_data, length);
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)
@ -145,14 +146,24 @@ CryptoHmac crypto_hmac_new(void)
return hmac;
}
void crypto_hmac_sha1_init(CryptoHmac hmac, const BYTE* data, UINT32 length)
BOOL crypto_hmac_sha1_init(CryptoHmac hmac, const BYTE* data, UINT32 length)
{
#if (OPENSSL_VERSION_NUMBER >= 0x00909000)
return HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_sha1(), NULL) == 1;
#else
HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_sha1(), NULL);
return TRUE;
#endif
}
void crypto_hmac_md5_init(CryptoHmac hmac, const BYTE* data, UINT32 length)
BOOL crypto_hmac_md5_init(CryptoHmac hmac, const BYTE* data, UINT32 length)
{
#if (OPENSSL_VERSION_NUMBER >= 0x00909000)
return HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_md5(), NULL) == 1;
#else
HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_md5(), NULL);
return TRUE;
#endif
}
void crypto_hmac_update(CryptoHmac hmac, const BYTE* data, UINT32 length)

1
winpr/include/winpr/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
version.h