/// <summary> /// Update session key according to section 5.3.7 Session Key Updates. /// </summary> internal void UpdateSessionKey() { if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT || encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_56BIT || encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_128BIT) { currentClientEncryptKey = UpdateKey(initialClientEncryptKey, currentClientEncryptKey, encryptionMethod); currentClientDecryptKey = UpdateKey(initialClientDecryptKey, currentClientDecryptKey, encryptionMethod); currentServerEncryptKey = UpdateKey(initialServerEncryptKey, currentServerEncryptKey, encryptionMethod); currentServerDecryptKey = UpdateKey(initialServerDecryptKey, currentServerDecryptKey, encryptionMethod); RC4CryptoServiceProvider rc4Enc = new RC4CryptoServiceProvider(); rc4Encrypt = rc4Enc.CreateEncryptor(currentClientEncryptKey, null); rc4EncryptServer = rc4Enc.CreateEncryptor(currentServerEncryptKey, null); RC4CryptoServiceProvider rc4Dec = new RC4CryptoServiceProvider(); rc4Decrypt = rc4Dec.CreateDecryptor(currentClientDecryptKey, null); rc4DecryptServer = rc4Dec.CreateDecryptor(currentServerDecryptKey, null); } // else in other cases we don't need to update session key }
internal void GenerateSessionKey(byte[] clientRandom, byte[] serverRandom) { if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT || encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_56BIT || encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_128BIT) { byte[] mackey = null; byte[] clientEncKey = null; byte[] clientDecKey = null; GenerateNonFIPSSessionKey(clientRandom, serverRandom, out mackey, out clientEncKey, out clientDecKey); if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_40BIT) { // MACKey40 = 0xD1269E + Last40Bits(First64Bits(MACKey128)) byte[] salt = ConstValue.NON_FIPS_SALT_40BIT; byte[] first = GetFirstNBits(64, mackey); byte[] last = GetLastNBits(40, first); macKey = RdpbcgrUtility.ConcatenateArrays(salt, last); // InitialClientEncryptKey40 = 0xD1269E + Last40Bits(First64Bits(InitialClientEncryptKey128)) first = GetFirstNBits(64, clientEncKey); last = GetLastNBits(40, first); currentClientEncryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); currentServerDecryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); // InitialClientDecryptKey40 = 0xD1269E + Last40Bits(First64Bits(InitialClientDecryptKey128)) first = GetFirstNBits(64, clientDecKey); last = GetLastNBits(40, first); currentClientDecryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); currentServerEncryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); } else if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_56BIT) { // MACKey56 = 0xD1 + Last56Bits(First64Bits(MACKey128)) byte[] salt = ConstValue.NON_FIPS_SALT_56BIT; byte[] first = GetFirstNBits(64, mackey); byte[] last = GetLastNBits(56, first); macKey = RdpbcgrUtility.ConcatenateArrays(salt, last); // InitialClientEncryptKey56 = 0xD1 + Last56Bits(First64Bits(InitialClientEncryptKey128)) first = GetFirstNBits(64, clientEncKey); last = GetLastNBits(56, first); currentClientEncryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); currentServerDecryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); // InitialClientDecryptKey56 = 0xD1 + Last56Bits(First64Bits(InitialClientDecryptKey128)) first = GetFirstNBits(64, clientDecKey); last = GetLastNBits(56, first); currentClientDecryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); currentServerEncryptKey = RdpbcgrUtility.ConcatenateArrays(salt, last); } else // encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_128BIT { macKey = mackey; currentClientEncryptKey = clientEncKey; currentServerDecryptKey = clientEncKey; currentClientDecryptKey = clientDecKey; currentServerEncryptKey = clientDecKey; } initialClientDecryptKey = currentClientDecryptKey; initialClientEncryptKey = currentClientEncryptKey; initialServerEncryptKey = currentServerEncryptKey; initialServerDecryptKey = currentServerDecryptKey; RC4CryptoServiceProvider rc4Enc = new RC4CryptoServiceProvider(); rc4Encrypt = rc4Enc.CreateEncryptor(currentClientEncryptKey, null); rc4EncryptServer = rc4Enc.CreateEncryptor(currentServerEncryptKey, null); RC4CryptoServiceProvider rc4Dec = new RC4CryptoServiceProvider(); rc4Decrypt = rc4Dec.CreateDecryptor(currentClientDecryptKey, null); rc4DecryptServer = rc4Dec.CreateDecryptor(currentServerDecryptKey, null); } else if (encryptionMethod == EncryptionMethods.ENCRYPTION_METHOD_FIPS) { GenerateFIPSSessionKey(clientRandom, serverRandom, out macKey, out currentClientEncryptKey, out currentClientDecryptKey, out currentServerEncryptKey, out currentServerDecryptKey); initialClientDecryptKey = currentClientDecryptKey; initialClientEncryptKey = currentClientEncryptKey; initialServerDecryptKey = currentServerDecryptKey; initialServerEncryptKey = currentServerEncryptKey; // suppress "CA5353:TripleDESCannotBeUsed" message, since TripleDES is used according protocol definition in MS-RDPBCGR desEncrypt = new TripleDESCryptoServiceProvider(); desEncrypt.IV = ConstValue.TRPLE_DES_IV; desEncrypt.Key = currentClientEncryptKey; desEncrypt.Mode = CipherMode.CBC; desDecrypt = new TripleDESCryptoServiceProvider(); desDecrypt.IV = ConstValue.TRPLE_DES_IV; desDecrypt.Key = currentClientDecryptKey; desDecrypt.Mode = CipherMode.CBC; desEncryptServer = new TripleDESCryptoServiceProvider(); desEncryptServer.IV = ConstValue.TRPLE_DES_IV; desEncryptServer.Key = currentServerEncryptKey; desEncryptServer.Mode = CipherMode.CBC; desDecryptServer = new TripleDESCryptoServiceProvider(); desDecryptServer.IV = ConstValue.TRPLE_DES_IV; desDecryptServer.Key = currentServerDecryptKey; desDecryptServer.Mode = CipherMode.CBC; } else // the encryption method is ENCRYPTION_METHOD_NONE or error { macKey = null; initialClientEncryptKey = null; initialClientDecryptKey = null; currentClientEncryptKey = null; currentClientDecryptKey = null; initialServerEncryptKey = null; initialServerDecryptKey = null; currentServerEncryptKey = null; currentServerDecryptKey = null; rc4Encrypt = null; rc4Decrypt = null; rc4EncryptServer = null; rc4DecryptServer = null; desEncrypt = null; desDecrypt = null; desEncryptServer = null; desDecryptServer = null; } // the cumulative encryption/decryption count // indicating how many encryptions/decryptions have been carried out. encryptionCount = 0; // the first encryption start with 0 decryptionCount = -1; // after the first decryption, decryptionCount++ up to 0 }