Treat return values for security.c

This patch make functions in security.c return values when they should instead of
beeing void. And it also fix the callers of these functions.
This commit is contained in:
David FORT 2015-04-01 11:11:37 +02:00
parent 121ea23595
commit 0eb399a717
9 changed files with 216 additions and 131 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

@ -767,6 +767,7 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNu
rdpRdp* rdp;
UINT16 length;
BYTE eventHeader;
BOOL status;
/*
* A maximum of 15 events are allowed per request
@ -817,7 +818,8 @@ 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);
@ -829,9 +831,12 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNu
else
{
if (rdp->sec_flags & SEC_SECURE_CHECKSUM)
security_salted_mac_signature(rdp, fpInputEvents, fpInputEvents_length, TRUE, Stream_Pointer(s));
status = security_salted_mac_signature(rdp, fpInputEvents, fpInputEvents_length, TRUE, Stream_Pointer(s));
else
security_mac_signature(rdp, fpInputEvents, fpInputEvents_length, Stream_Pointer(s));
status = security_mac_signature(rdp, fpInputEvents, fpInputEvents_length, Stream_Pointer(s));
if (!status)
return FALSE;
security_encrypt(fpInputEvents, fpInputEvents_length, rdp);
}
@ -1021,16 +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);
if (!status)
return FALSE;
security_encrypt(data, dataSize, rdp);
}
}

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

@ -297,7 +297,8 @@ int license_recv(rdpLicense* license, wStream* s)
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);
@ -336,15 +337,21 @@ 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 */
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,
return security_licensing_encryption_key(license->SessionKeyBlob, license->ClientRandom,
license->ServerRandom, license->LicensingEncryptionKey); /* LicensingEncryptionKey */
#ifdef WITH_DEBUG_LICENSE
WLog_DBG(TAG, "ClientRandom:");
@ -369,7 +376,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,11 +389,12 @@ 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)
@ -411,7 +419,7 @@ void license_get_server_rsa_public_key(rdpLicense* license)
CopyMemory(license->Modulus, Modulus, ModulusLength);
}
void license_encrypt_premaster_secret(rdpLicense* license)
BOOL license_encrypt_premaster_secret(rdpLicense* license)
{
BYTE* EncryptedPremasterSecret;
license_get_server_rsa_public_key(license);
@ -422,6 +430,8 @@ void license_encrypt_premaster_secret(rdpLicense* license)
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,6 +441,7 @@ 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)
@ -742,9 +753,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);
@ -952,30 +964,41 @@ 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;
buffer = (BYTE*) malloc(HWID_LENGTH);
if (!buffer)
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;
}
crypto_rc4(rc4, HWID_LENGTH, license->HardwareId, buffer);
@ -992,7 +1015,7 @@ void license_send_platform_challenge_response_packet(rdpLicense* license)
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_send(license, s, PLATFORM_CHALLENGE_RESPONSE);
}
/**

View File

@ -205,9 +205,9 @@ 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);
BOOL license_generate_keys(rdpLicense* license);
BOOL license_generate_hwid(rdpLicense* license);
BOOL license_encrypt_premaster_secret(rdpLicense* license);
void license_decrypt_platform_challenge(rdpLicense* license);
LICENSE_PRODUCT_INFO* license_new_product_info(void);
@ -233,7 +233,7 @@ void license_write_new_license_request_packet(rdpLicense* license, wStream* s);
void 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_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,9 +471,12 @@ 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);
@ -481,7 +486,7 @@ static UINT32 rdp_security_stream_out(rdpRdp* rdp, wStream* s, int length, UINT3
rdp->sec_flags = 0;
}
return pad;
return TRUE;
}
static UINT32 rdp_get_sec_bytes(rdpRdp* rdp, UINT16 sec_flags)
@ -516,11 +521,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 +544,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 +554,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 +573,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 +584,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 +601,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 +610,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 +981,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 +1027,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,46 @@ 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 +199,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 +207,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 +231,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 +247,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 +260,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 +284,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 +297,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 +306,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 +338,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 +352,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 +361,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 +423,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 +480,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 +554,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 +565,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 +583,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 +606,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 +627,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 +665,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);

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,14 @@ 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)
{
HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_sha1(), NULL);
return HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_sha1(), NULL) == 1;
}
void crypto_hmac_md5_init(CryptoHmac hmac, const BYTE* data, UINT32 length)
BOOL crypto_hmac_md5_init(CryptoHmac hmac, const BYTE* data, UINT32 length)
{
HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_md5(), NULL);
return HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_md5(), NULL) == 1;
}
void crypto_hmac_update(CryptoHmac hmac, const BYTE* data, UINT32 length)