// This function is defined as follow : // Func (S, i) = HMAC(S || i) | HMAC2(S || i) | ... | HMAC(iterations) (S || i) // where i is the block number. private byte[] Func() { byte[] INT_block = Utils.Int(m_block); m_hmac.TransformBlock(m_salt, 0, m_salt.Length, null, 0); m_hmac.TransformBlock(INT_block, 0, INT_block.Length, null, 0); m_hmac.TransformFinalBlock(EmptyArray <Byte> .Value, 0, 0); byte[] temp = m_hmac.HashValue; m_hmac.Initialize(); byte[] ret = temp; for (int i = 2; i <= m_iterations; i++) { m_hmac.TransformBlock(temp, 0, temp.Length, null, 0); m_hmac.TransformFinalBlock(EmptyArray <Byte> .Value, 0, 0); temp = m_hmac.HashValue; for (int j = 0; j < m_blockSize; j++) { ret[j] ^= temp[j]; } m_hmac.Initialize(); } // increment the block count. m_block++; return(ret); }
static readonly byte[] emptyArray64 = new byte[64]; // for SHA-512 public HKDF(Func<HMAC> hmacFactory, byte[] ikm, byte[] salt = null, byte[] context = null) { hmac = hmacFactory(); hmac2 = hmac as HMAC2; hashLength = hmac.HashSize >> 3; // a malicious implementation of HMAC could conceivably mess up the shared static empty byte arrays, which are still writeable... hmac.Key = salt ?? (hashLength == 48 ? emptyArray48 : hashLength == 64 ? emptyArray64 : hashLength == 32 ? emptyArray32 : hashLength == 20 ? emptyArray20 : new byte[hashLength]); // re-keying hmac with PRK hmac.TransformBlock(ikm, 0, ikm.Length, null, 0); hmac.TransformFinalBlock(ikm, 0, 0); hmac.Key = (hmac2 != null) ? hmac2.HashInner : hmac.Hash; hmac.Initialize(); this.context = context; Reset(); }
// iterative hash function private byte[] Func() { byte[] INT_block = Utils.GetBigEndianBytes(_block); _hmac.TransformBlock(_salt, 0, _salt.Length, _salt, 0); _hmac.TransformFinalBlock(INT_block, 0, INT_block.Length); byte[] temp = _hmac.Hash; _hmac.Initialize(); byte[] ret = temp; for (int i = 2; i <= _iterationCount; i++) { temp = _hmac.ComputeHash(temp); for (int j = 0; j < _blockSize; j++) { ret[j] ^= temp[j]; } } _block++; return(ret); }
public void CheckE (string testName, HMAC algo, byte[] data, byte[] result) { byte[] copy = new byte[data.Length]; for (int i = 0; i < data.Length - 1; i++) algo.TransformBlock (data, i, 1, copy, i); algo.TransformFinalBlock (data, data.Length - 1, 1); Compare (result, algo.Hash, testName + "e"); algo.Initialize (); }
public void CheckD (string testName, HMAC algo, byte[] data, byte[] result) { algo.TransformFinalBlock (data, 0, data.Length); Compare (result, algo.Hash, testName + "d"); algo.Initialize (); }
static byte[] Compute_PHash(int bytes, byte[][] seeds, HMAC hmac, int blockSize) { int blocks = (bytes / blockSize) + (bytes % blockSize == 0 ? 0 : 1); byte[] ret = new byte[blockSize * blocks]; byte[] prev = null; for (int i = 0; i < blocks; i++) { hmac.Initialize (); if (prev == null) { for (int q = 0; q < seeds.Length; q ++) hmac.TransformBlock (seeds[q], 0, seeds[q].Length, seeds[q], 0); } else { hmac.TransformBlock (prev, 0, prev.Length, prev, 0); } hmac.TransformFinalBlock (Utility.EmptyByteArray, 0, 0); prev = hmac.Hash; hmac.Initialize (); hmac.TransformBlock (prev, 0, prev.Length, prev, 0); for (int q = 0; q < seeds.Length; q++) hmac.TransformBlock (seeds[q], 0, seeds[q].Length, seeds[q], 0); hmac.TransformFinalBlock (Utility.EmptyByteArray, 0, 0); for (int q = 0; q < blockSize; q++) ret[i * blockSize + q] = hmac.Hash[q]; } return ret; }