Document differences between RDP encryption and SSLv3, and bring some

of the terminology in line with the SSLv3 specification.


git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@698 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
Matt Chapman 2004-05-16 11:18:20 +00:00
parent fbd632d425
commit 80ef1df3b3
2 changed files with 40 additions and 32 deletions

View File

@ -36,20 +36,20 @@ BOOL g_licence_issued = False;
/* Generate a session key and RC4 keys, given client and server randoms */ /* Generate a session key and RC4 keys, given client and server randoms */
static void static void
licence_generate_keys(uint8 * client_key, uint8 * server_key, uint8 * client_rsa) licence_generate_keys(uint8 * client_random, uint8 * server_random, uint8 * pre_master_secret)
{ {
uint8 session_key[48]; uint8 master_secret[48];
uint8 temp_hash[48]; uint8 key_block[48];
/* Generate session key - two rounds of sec_hash_48 */ /* Generate master secret and then key material */
sec_hash_48(temp_hash, client_rsa, client_key, server_key, 65); sec_hash_48(master_secret, pre_master_secret, client_random, server_random, 'A');
sec_hash_48(session_key, temp_hash, server_key, client_key, 65); sec_hash_48(key_block, master_secret, server_random, client_random, 'A');
/* Store first 16 bytes of session key, for generating signatures */ /* Store first 16 bytes of session key as MAC secret */
memcpy(g_licence_sign_key, session_key, 16); memcpy(g_licence_sign_key, key_block, 16);
/* Generate RC4 key */ /* Generate RC4 key from next 16 bytes */
sec_hash_16(g_licence_key, &session_key[16], client_key, server_key); sec_hash_16(g_licence_key, &key_block[16], client_random, server_random);
} }
static void static void

View File

@ -61,8 +61,17 @@ static uint8 sec_crypted_random[SEC_MODULUS_SIZE];
uint16 g_server_rdp_version = 0; uint16 g_server_rdp_version = 0;
/* /*
* General purpose 48-byte transformation, using two 32-byte salts (generally, * I believe this is based on SSLv3 with the following differences:
* a client and server salt) and a global salt value used for padding. * MAC algorithm (5.2.3.1) uses only 32-bit length in place of seq_num/type/length fields
* MAC algorithm uses SHA1 and MD5 for the two hash functions instead of one or other
* key_block algorithm (6.2.2) uses 'X', 'YY', 'ZZZ' instead of 'A', 'BB', 'CCC'
* key_block partitioning is different (16 bytes each: MAC secret, decrypt key, encrypt key)
* encryption/decryption keys updated every 4096 packets
* See http://wp.netscape.com/eng/ssl3/draft302.txt
*/
/*
* 48-byte transformation used to generate master secret (6.1) and key material (6.2.2).
* Both SHA1 and MD5 algorithms are used. * Both SHA1 and MD5 algorithms are used.
*/ */
void void
@ -93,8 +102,7 @@ sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
} }
/* /*
* Weaker 16-byte transformation, also using two 32-byte salts, but * 16-byte transformation used to generate export keys (6.2.2).
* only using a single round of MD5.
*/ */
void void
sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2) sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2)
@ -117,28 +125,28 @@ sec_make_40bit(uint8 * key)
key[2] = 0x9e; key[2] = 0x9e;
} }
/* Generate a session key and RC4 keys, given client and server randoms */ /* Generate encryption keys given client and server randoms */
static void static void
sec_generate_keys(uint8 * client_key, uint8 * server_key, int rc4_key_size) sec_generate_keys(uint8 * client_random, uint8 * server_random, int rc4_key_size)
{ {
uint8 session_key[48]; uint8 pre_master_secret[48];
uint8 temp_hash[48]; uint8 master_secret[48];
uint8 input[48]; uint8 key_block[48];
/* Construct input data to hash */ /* Construct pre-master secret */
memcpy(input, client_key, 24); memcpy(pre_master_secret, client_random, 24);
memcpy(input + 24, server_key, 24); memcpy(pre_master_secret + 24, server_random, 24);
/* Generate session key - two rounds of sec_hash_48 */ /* Generate master secret and then key material */
sec_hash_48(temp_hash, input, client_key, server_key, 65); sec_hash_48(master_secret, pre_master_secret, client_random, server_random, 'A');
sec_hash_48(session_key, temp_hash, client_key, server_key, 88); sec_hash_48(key_block, master_secret, client_random, server_random, 'X');
/* Store first 16 bytes of session key, for generating signatures */ /* First 16 bytes of key material is MAC secret */
memcpy(sec_sign_key, session_key, 16); memcpy(sec_sign_key, key_block, 16);
/* Generate RC4 keys */ /* Generate export keys from next two blocks of 16 bytes */
sec_hash_16(sec_decrypt_key, &session_key[16], client_key, server_key); sec_hash_16(sec_decrypt_key, &key_block[16], client_random, server_random);
sec_hash_16(sec_encrypt_key, &session_key[32], client_key, server_key); sec_hash_16(sec_encrypt_key, &key_block[32], client_random, server_random);
if (rc4_key_size == 1) if (rc4_key_size == 1)
{ {
@ -187,7 +195,7 @@ buf_out_uint32(uint8 * buffer, uint32 value)
buffer[3] = (value >> 24) & 0xff; buffer[3] = (value >> 24) & 0xff;
} }
/* Generate a signature hash, using a combination of SHA1 and MD5 */ /* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */
void void
sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data, int datalen) sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data, int datalen)
{ {
@ -215,7 +223,7 @@ sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 *
memcpy(signature, md5sig, siglen); memcpy(signature, md5sig, siglen);
} }
/* Update an encryption key - similar to the signing process */ /* Update an encryption key */
static void static void
sec_update(uint8 * key, uint8 * update_key) sec_update(uint8 * key, uint8 * update_key)
{ {