From 8238f2369dd62da7c10ca4cbdaeb136468810033 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Thu, 19 Jan 2012 05:07:30 +0100 Subject: [PATCH] - Simplify security_mac_signature() API. - Introduce implementation of security_salted_mac_signature() that would be used to handle packets with SEC_SECURE_CHECKSUM flag. --- libfreerdp-core/rdp.c | 13 ++----------- libfreerdp-core/security.c | 40 +++++++++++++++++++++++++++++++++++--- libfreerdp-core/security.h | 3 ++- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/libfreerdp-core/rdp.c b/libfreerdp-core/rdp.c index 723f15c53..83a87b539 100644 --- a/libfreerdp-core/rdp.c +++ b/libfreerdp-core/rdp.c @@ -274,8 +274,6 @@ void rdp_write_header(rdpRdp* rdp, STREAM* s, uint16 length, uint16 channel_id) static uint32 rdp_security_stream_out(rdpRdp* rdp, STREAM* s, int length) { - uint32 ml; - uint8* mk; uint8* data; uint32 sec_flags; uint32 pad = 0; @@ -314,10 +312,7 @@ static uint32 rdp_security_stream_out(rdpRdp* rdp, STREAM* s, int length) { data = s->p + 8; length = length - (data - s->data); - - mk = rdp->sign_key; - ml = rdp->rc4_key_len; - security_mac_signature(mk, ml, data, length, s->p); + security_mac_signature(rdp, data, length, s->p); stream_seek(s, 8); security_encrypt(s->p, length, rdp); } @@ -583,8 +578,6 @@ boolean rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, STREAM* s) boolean rdp_decrypt(rdpRdp* rdp, STREAM* s, int length) { uint8 cmac[8], wmac[8]; - uint32 ml; - uint8* mk; if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) { @@ -621,9 +614,7 @@ boolean rdp_decrypt(rdpRdp* rdp, STREAM* s, int length) stream_read(s, wmac, sizeof(wmac)); length -= sizeof(wmac); security_decrypt(s->p, length, rdp); - mk = rdp->sign_key; - ml = rdp->rc4_key_len; - security_mac_signature(mk, ml, s->p, length, cmac); + security_mac_signature(rdp, s->p, length, cmac); if (memcmp(wmac, cmac, sizeof(wmac)) != 0) { printf("FATAL: invalid packet signature\n"); return false; diff --git a/libfreerdp-core/security.c b/libfreerdp-core/security.c index 223173281..e003b213b 100644 --- a/libfreerdp-core/security.c +++ b/libfreerdp-core/security.c @@ -223,7 +223,7 @@ void security_mac_data(uint8* mac_salt_key, uint8* data, uint32 length, uint8* o crypto_md5_final(md5, output); } -void security_mac_signature(uint8* mac_key, int mac_key_length, uint8* data, uint32 length, uint8* output) +void security_mac_signature(rdpRdp *rdp, uint8* data, uint32 length, uint8* output) { CryptoMd5 md5; CryptoSha1 sha1; @@ -235,7 +235,7 @@ void security_mac_signature(uint8* mac_key, int mac_key_length, uint8* data, uin /* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */ sha1 = crypto_sha1_init(); - crypto_sha1_update(sha1, mac_key, mac_key_length); /* MacKeyN */ + crypto_sha1_update(sha1, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */ crypto_sha1_update(sha1, pad1, sizeof(pad1)); /* pad1 */ crypto_sha1_update(sha1, length_le, sizeof(length_le)); /* length */ crypto_sha1_update(sha1, data, length); /* data */ @@ -243,7 +243,41 @@ void security_mac_signature(uint8* mac_key, int mac_key_length, uint8* data, uin /* MACSignature = First64Bits(MD5(MACKeyN + pad2 + SHA1_Digest)) */ md5 = crypto_md5_init(); - crypto_md5_update(md5, mac_key, mac_key_length); /* MacKeyN */ + crypto_md5_update(md5, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */ + crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */ + crypto_md5_update(md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */ + crypto_md5_final(md5, md5_digest); + + memcpy(output, md5_digest, 8); +} + +void security_salted_mac_signature(rdpRdp *rdp, uint8* data, uint32 length, boolean encryption, uint8* output) +{ + CryptoMd5 md5; + CryptoSha1 sha1; + uint8 length_le[4]; + uint8 use_count_le[4]; + uint8 md5_digest[CRYPTO_MD5_DIGEST_LENGTH]; + uint8 sha1_digest[CRYPTO_SHA1_DIGEST_LENGTH]; + + security_uint32_le(length_le, length); /* length must be little-endian */ + if (encryption) + security_uint32_le(use_count_le, rdp->encrypt_use_count); + else + security_uint32_le(use_count_le, rdp->decrypt_use_count); + + /* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */ + sha1 = crypto_sha1_init(); + crypto_sha1_update(sha1, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */ + crypto_sha1_update(sha1, pad1, sizeof(pad1)); /* pad1 */ + crypto_sha1_update(sha1, length_le, sizeof(length_le)); /* length */ + crypto_sha1_update(sha1, data, length); /* data */ + crypto_sha1_update(sha1, use_count_le, sizeof(use_count_le)); /* encryptionCount */ + crypto_sha1_final(sha1, sha1_digest); + + /* MACSignature = First64Bits(MD5(MACKeyN + pad2 + SHA1_Digest)) */ + md5 = crypto_md5_init(); + crypto_md5_update(md5, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */ crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */ crypto_md5_update(md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */ crypto_md5_final(md5, md5_digest); diff --git a/libfreerdp-core/security.h b/libfreerdp-core/security.h index 6d4b0f5d4..7f338d3fa 100644 --- a/libfreerdp-core/security.h +++ b/libfreerdp-core/security.h @@ -32,7 +32,8 @@ void security_mac_salt_key(uint8* session_key_blob, uint8* client_random, uint8* void security_licensing_encryption_key(uint8* session_key_blob, uint8* client_random, uint8* server_random, uint8* output); void security_mac_data(uint8* mac_salt_key, uint8* data, uint32 length, uint8* output); -void security_mac_signature(uint8* mac_key, int mac_key_length, uint8* data, uint32 length, uint8* output); +void security_mac_signature(rdpRdp *rdp, uint8* data, uint32 length, uint8* output); +void security_salted_mac_signature(rdpRdp *rdp, uint8* data, uint32 length, boolean encryption, uint8* output); boolean security_establish_keys(uint8* client_random, rdpRdp* rdp); boolean security_encrypt(uint8* data, int length, rdpRdp* rdp);