public static CipherSuite InitializeCipherSuite(byte[] master, byte[] clientrnd, byte[] serverrnd, CipherDefinition definition, ConnectionEnd entity)
 {
     CipherSuite ret = new CipherSuite();
     SymmetricAlgorithm bulk = (SymmetricAlgorithm)Activator.CreateInstance(definition.BulkCipherAlgorithm);
     if (definition.BulkIVSize > 0)
         bulk.Mode = CipherMode.CBC;
     bulk.Padding = PaddingMode.None;
     bulk.BlockSize = definition.BulkIVSize * 8;
     // get the keys and IVs
     byte[] client_mac, server_mac, client_key, server_key, client_iv, server_iv;
     byte[] random = new byte[64];
     Array.Copy(serverrnd, 0, random, 0, 32);
     Array.Copy(clientrnd, 0, random, 32, 32);
     PseudoRandomDeriveBytes prf = new PseudoRandomDeriveBytes(master, "key expansion", random);
     client_mac = prf.GetBytes(definition.HashSize);
     server_mac = prf.GetBytes(definition.HashSize);
     client_key = prf.GetBytes(definition.BulkKeySize);
     server_key = prf.GetBytes(definition.BulkKeySize);
     client_iv = prf.GetBytes(definition.BulkIVSize);
     server_iv = prf.GetBytes(definition.BulkIVSize);
     prf.Dispose();
     if (definition.Exportable) { // make some extra modifications if the keys are exportable
         Array.Copy(clientrnd, 0, random, 0, 32);
         Array.Copy(serverrnd, 0, random, 32, 32);
         prf = new PseudoRandomDeriveBytes(client_key, "client write key", random);
         client_key = prf.GetBytes(definition.BulkExpandedSize);
         prf.Dispose();
         prf = new PseudoRandomDeriveBytes(server_key, "server write key", random);
         server_key = prf.GetBytes(definition.BulkExpandedSize);
         prf.Dispose();
         prf = new PseudoRandomDeriveBytes(new byte[0], "IV block", random);
         client_iv = prf.GetBytes(definition.BulkIVSize);
         server_iv = prf.GetBytes(definition.BulkIVSize);
         prf.Dispose();
     }
     // generate the cipher objects
     if (entity == ConnectionEnd.Client) {
         ret.Encryptor = bulk.CreateEncryptor(client_key, client_iv);
         ret.Decryptor = bulk.CreateDecryptor(server_key, server_iv);
         ret.LocalHasher = new HMAC((HashAlgorithm)Activator.CreateInstance(definition.HashAlgorithm), client_mac);
         ret.RemoteHasher = new HMAC((HashAlgorithm)Activator.CreateInstance(definition.HashAlgorithm), server_mac);
     } else {
         ret.Encryptor = bulk.CreateEncryptor(server_key, server_iv);
         ret.Decryptor = bulk.CreateDecryptor(client_key, client_iv);
         ret.LocalHasher = new HMAC((HashAlgorithm)Activator.CreateInstance(definition.HashAlgorithm), server_mac);
         ret.RemoteHasher = new HMAC((HashAlgorithm)Activator.CreateInstance(definition.HashAlgorithm), client_mac);
     }
     // clear sensitive data
     Array.Clear(client_mac, 0, client_mac.Length);
     Array.Clear(server_mac, 0, server_mac.Length);
     Array.Clear(client_key, 0, client_key.Length);
     Array.Clear(server_key, 0, server_key.Length);
     Array.Clear(client_iv, 0, client_iv.Length);
     Array.Clear(server_iv, 0, server_iv.Length);
     Array.Clear(random, 0, random.Length);
     return ret;
 }
 public static CipherSuite InitializeCipherSuite(byte[] master, byte[] clientrnd, byte[] serverrnd, CipherDefinition definition, ConnectionEnd entity)
 {
     CipherSuite ret = new CipherSuite();
     SymmetricAlgorithm bulk = (SymmetricAlgorithm)Activator.CreateInstance(definition.BulkCipherAlgorithm);
     if (definition.BulkIVSize > 0)
         bulk.Mode = CipherMode.CBC;
     bulk.Padding = PaddingMode.None;
     bulk.BlockSize = definition.BulkIVSize * 8;
     // get the keys and IVs
     byte[] client_mac, server_mac, client_key, server_key, client_iv, server_iv;
     Ssl3DeriveBytes prf = new Ssl3DeriveBytes(master, clientrnd, serverrnd, false);
     client_mac = prf.GetBytes(definition.HashSize);
     server_mac = prf.GetBytes(definition.HashSize);
     client_key = prf.GetBytes(definition.BulkKeySize);
     server_key = prf.GetBytes(definition.BulkKeySize);
     client_iv = prf.GetBytes(definition.BulkIVSize);
     server_iv = prf.GetBytes(definition.BulkIVSize);
     prf.Dispose();
     if (definition.Exportable) { // make some extra modifications if the keys are exportable
         MD5 md5 = new MD5CryptoServiceProvider();
         md5.TransformBlock(client_key, 0, client_key.Length, client_key, 0);
         md5.TransformBlock(clientrnd, 0, clientrnd.Length, clientrnd, 0);
         md5.TransformFinalBlock(serverrnd, 0, serverrnd.Length);
         client_key = new byte[definition.BulkExpandedSize];
         Buffer.BlockCopy(md5.Hash, 0, client_key, 0, client_key.Length);
         md5.Initialize();
         md5.TransformBlock(server_key, 0, server_key.Length, server_key, 0);
         md5.TransformBlock(serverrnd, 0, serverrnd.Length, serverrnd, 0);
         md5.TransformFinalBlock(clientrnd, 0, clientrnd.Length);
         server_key = new byte[definition.BulkExpandedSize];
         Buffer.BlockCopy(md5.Hash, 0, server_key, 0, server_key.Length);
         md5.Initialize();
         md5.TransformBlock(clientrnd, 0, clientrnd.Length, clientrnd, 0);
         md5.TransformFinalBlock(serverrnd, 0, serverrnd.Length);
         client_iv = new byte[definition.BulkIVSize];
         Buffer.BlockCopy(md5.Hash, 0, client_iv, 0, client_iv.Length);
         md5.Initialize();
         md5.TransformBlock(serverrnd, 0, serverrnd.Length, serverrnd, 0);
         md5.TransformFinalBlock(clientrnd, 0, clientrnd.Length);
         server_iv = new byte[definition.BulkIVSize];
         Buffer.BlockCopy(md5.Hash, 0, server_iv, 0, server_iv.Length);
         md5.Clear();
     }
     // generate the cipher objects
     if (entity == ConnectionEnd.Client) {
         ret.Encryptor = bulk.CreateEncryptor(client_key, client_iv);
         ret.Decryptor = bulk.CreateDecryptor(server_key, server_iv);
         ret.LocalHasher = new Ssl3RecordMAC(definition.HashAlgorithmType, client_mac);
         ret.RemoteHasher = new Ssl3RecordMAC(definition.HashAlgorithmType, server_mac);
     } else {
         ret.Encryptor = bulk.CreateEncryptor(server_key, server_iv);
         ret.Decryptor = bulk.CreateDecryptor(client_key, client_iv);
         ret.LocalHasher = new Ssl3RecordMAC(definition.HashAlgorithmType, server_mac);
         ret.RemoteHasher = new Ssl3RecordMAC(definition.HashAlgorithmType, client_mac);
     }
     // clear sensitive data
     Array.Clear(client_mac, 0, client_mac.Length);
     Array.Clear(server_mac, 0, server_mac.Length);
     Array.Clear(client_key, 0, client_key.Length);
     Array.Clear(server_key, 0, server_key.Length);
     Array.Clear(client_iv, 0, client_iv.Length);
     Array.Clear(server_iv, 0, server_iv.Length);
     return ret;
 }
 protected void GenerateCiphers(byte[] premaster)
 {
     byte[] clientrnd = new byte[32], serverrnd = new byte[32];
     Array.Copy(m_ClientTime, 0, clientrnd, 0, 4);
     Array.Copy(m_ClientRandom, 0, clientrnd, 4, 28);
     Array.Copy(m_ServerTime, 0, serverrnd, 0, 4);
     Array.Copy(m_ServerRandom, 0, serverrnd, 4, 28);
     m_MasterSecret = GenerateMasterSecret(premaster, clientrnd, serverrnd);
     m_CipherSuite = CipherSuites.GetCipherSuite(GetProtocol(), m_MasterSecret, clientrnd, serverrnd, m_EncryptionScheme, m_Options.Entity);
     Array.Clear(premaster, 0, premaster.Length);
 }