private byte[] ComputeHeaderHmac(byte[] pbHeader, byte[] pbKey) { byte[] pbHeaderHmac; byte[] pbBlockKey = HmacBlockStream.GetHmacKey64( pbKey, ulong.MaxValue); using(HMACSHA256 h = new HMACSHA256(pbBlockKey)) { pbHeaderHmac = h.ComputeHash(pbHeader); } MemUtil.ZeroByteArray(pbBlockKey); return pbHeaderHmac; }
/// <summary> /// Create a cryptographic key of length <paramref name="cbOut" /> /// (in bytes) from <paramref name="pbIn" />. /// </summary> public static byte[] ResizeKey(byte[] pbIn, int iInOffset, int cbIn, int cbOut) { if (pbIn == null) { throw new ArgumentNullException("pbIn"); } if (cbOut < 0) { throw new ArgumentOutOfRangeException("cbOut"); } if (cbOut == 0) { return(MemUtil.EmptyByteArray); } byte[] pbHash; if (cbOut <= 32) { pbHash = HashSha256(pbIn, iInOffset, cbIn); } else { using (SHA512Managed h = new SHA512Managed()) { pbHash = h.ComputeHash(pbIn, iInOffset, cbIn); } } if (cbOut == pbHash.Length) { return(pbHash); } byte[] pbRet = new byte[cbOut]; if (cbOut < pbHash.Length) { Array.Copy(pbHash, pbRet, cbOut); } else { int iPos = 0; ulong r = 0; while (iPos < cbOut) { Debug.Assert(pbHash.Length == 64); using (HMACSHA256 h = new HMACSHA256(pbHash)) { byte[] pbR = MemUtil.UInt64ToBytes(r); byte[] pbPart = h.ComputeHash(pbR); int cbCopy = Math.Min(cbOut - iPos, pbPart.Length); Debug.Assert(cbCopy > 0); Array.Copy(pbPart, 0, pbRet, iPos, cbCopy); iPos += cbCopy; ++r; MemUtil.ZeroByteArray(pbPart); } } Debug.Assert(iPos == cbOut); } #if DEBUG byte[] pbZero = new byte[pbHash.Length]; Debug.Assert(!MemUtil.ArraysEqual(pbHash, pbZero)); #endif MemUtil.ZeroByteArray(pbHash); return(pbRet); }