public byte[] ExpandSHA1(byte[] secret, byte[] seed, int length) { int hashLength = 20; int iterations = (int)(length / hashLength); if ((length % hashLength) > 0) { iterations++; } ByteBuffer resMacs = new ByteBuffer(); byte[] bAofi = seed; for (int i = 1; i <= iterations; i++) { ByteBuffer hcseed = new ByteBuffer(); HMACSHA1 sha = new HMACSHA1(secret); byte[] bNextAofi = sha.ComputeHash(bAofi); /// A(1) = HMAC_hash(secret, A(0)), /// A(2) = HMAC_hash(secret, A(1)), /// etc HMACSHA1 sha2 = new HMACSHA1(secret); byte[] bComputeNextHashOver = new byte[20 + seed.Length]; Array.Copy(bNextAofi, 0, bComputeNextHashOver, 0, 20); Array.Copy(seed, 0, bComputeNextHashOver, 20, seed.Length); byte[] bTotalHashThisIteration = sha2.ComputeHash(bComputeNextHashOver); resMacs.AppendData(bTotalHashThisIteration); /// Append it to our total buffer bAofi = bNextAofi; /// use next loop } byte[] res = resMacs.GetNSamples(length); return res; }
public void ComputeKeys(byte[] MasterSecret, byte[] ServerPlusClientRandomKeys) { // Create keyblock ByteBuffer keyBlock = new ByteBuffer(); byte[] bKEPRF = this.PRF(MasterSecret, "key expansion", ServerPlusClientRandomKeys, this.SecurityParameters.Cipher.KeyBlockSize); keyBlock.AppendData(bKEPRF); this.ClientWriteMACSecret = keyBlock.GetNSamples(this.SecurityParameters.Cipher.HashSize); this.ServerWriteMACSecret = keyBlock.GetNSamples(this.SecurityParameters.Cipher.HashSize); this.ClientWriteKey = keyBlock.GetNSamples(this.SecurityParameters.Cipher.KeyMaterialLength); this.ServerWriteKey = keyBlock.GetNSamples(this.SecurityParameters.Cipher.KeyMaterialLength); if (SocketClient.ShowDebug == true) { System.Diagnostics.Debug.WriteLine("ClientWriteMACSecret: +++++++++++\r\n{0}\r\n++++++++++++", ByteHelper.HexStringFromByte(this.ClientWriteMACSecret, true, 16)); System.Diagnostics.Debug.WriteLine("ServerWriteMACSecret: +++++++++++\r\n{0}\r\n++++++++++++", ByteHelper.HexStringFromByte(this.ServerWriteMACSecret, true, 16)); System.Diagnostics.Debug.WriteLine("ClientWriteKey: +++++++++++\r\n{0}\r\n++++++++++++", ByteHelper.HexStringFromByte(this.ClientWriteKey, true, 16)); System.Diagnostics.Debug.WriteLine("ServerWriteKey: +++++++++++\r\n{0}\r\n++++++++++++", ByteHelper.HexStringFromByte(this.ServerWriteKey, true, 16)); } //if (!this.IsExportable) //{ if (this.SecurityParameters.Cipher.IVSize != 0) { this.ClientWriteIV = keyBlock.GetNSamples(this.SecurityParameters.Cipher.IVSize); this.ServerWriteIV = keyBlock.GetNSamples(this.SecurityParameters.Cipher.IVSize); } else { this.ClientWriteIV = new byte[] { }; this.ServerWriteIV = new byte[] { }; } //} if (SocketClient.ShowDebug == true) { System.Diagnostics.Debug.WriteLine("ClientWriteIV: +++++++++++\r\n{0}\r\n++++++++++++", ByteHelper.HexStringFromByte(this.ClientWriteIV, true, 16)); System.Diagnostics.Debug.WriteLine("ServerWriteIV: +++++++++++\r\n{0}\r\n++++++++++++", ByteHelper.HexStringFromByte(this.ServerWriteIV, true, 16)); } //else //{ // // Generate final write keys // byte[] finalClientWriteKey = PRF(this.Context.ClientWriteKey, "client write key", this.Context.RandomCS, this.ExpandedKeyMaterialSize); // byte[] finalServerWriteKey = PRF(this.Context.ServerWriteKey, "server write key", this.Context.RandomCS, this.ExpandedKeyMaterialSize); // this.Context.ClientWriteKey = finalClientWriteKey; // this.Context.ServerWriteKey = finalServerWriteKey; // if (this.IvSize > 0) // { // // Generate IV block // byte[] ivBlock = PRF(CipherSuite.EmptyArray, "IV block", this.Context.RandomCS, this.IvSize * 2); // // Generate IV keys // this.Context.ClientWriteIV = new byte[this.IvSize]; // Buffer.BlockCopy(ivBlock, 0, this.Context.ClientWriteIV, 0, this.Context.ClientWriteIV.Length); // this.Context.ServerWriteIV = new byte[this.IvSize]; // Buffer.BlockCopy(ivBlock, this.IvSize, this.Context.ServerWriteIV, 0, this.Context.ServerWriteIV.Length); // } // else // { // this.Context.ClientWriteIV = CipherSuite.EmptyArray; // this.Context.ServerWriteIV = CipherSuite.EmptyArray; // } //} Initialize(); /// Initialize our cryptographic grind thingies on that thingy }