/* * This function computes Phash with the specified HMAC * engine, XORing the output with the current contents of * the outBuf[] buffer. */ static void Phash(HMAC hm, byte[] s, int soff, int slen, byte[] bufa, byte[] bufb, byte[] label, byte[] seed, byte[] outBuf, int outOff, int outLen) { /* * Set the key for HMAC. */ hm.SetKey(s, soff, slen); /* * Compute A(1) = HMAC(secret, seed). */ hm.Update(label); hm.Update(seed); hm.DoFinal(bufa, 0); while (outLen > 0) { /* * Next chunk: HMAC(secret, A(i) + label + seed) */ hm.Update(bufa); hm.Update(label); hm.Update(seed); hm.DoFinal(bufb, 0); int clen = Math.Min(hm.MACSize, outLen); for (int i = 0; i < clen; i++) { outBuf[outOff++] ^= bufb[i]; } outLen -= clen; /* * If we are not finished, then compute: * A(i+1) = HMAC(secret, A(i)) */ if (outLen > 0) { hm.Update(bufa); hm.DoFinal(bufa, 0); } } }
private void HMACTest(IDigest Digest, String[] Expected, byte[] TruncExpected) { HMAC mac = new HMAC(Digest); byte[] macV2 = new byte[mac.MacSize]; for (int i = 0; i != _macKeys.Length; i++) { mac.Initialize(_macKeys[i]); byte[] mData = HexConverter.Decode(_macData[i]); byte[] macV = new byte[mac.MacSize]; mac.BlockUpdate(mData, 0, mData.Length); mac.DoFinal(macV, 0); if (Evaluate.AreEqual(HexConverter.Decode(Expected[i]), macV) == false) { throw new Exception("Keccak HMAC: Expected hash is not equal! Expected: " + Expected[i] + " Received: " + HexConverter.ToString(macV)); } } // test truncated keys mac = new HMAC(Digest); mac.Initialize(_truncKey); mac.BlockUpdate(_truncData, 0, _truncData.Length); mac.DoFinal(macV2, 0); for (int i = 0; i != TruncExpected.Length; i++) { if (macV2[i] != TruncExpected[i]) { throw new Exception("Keccak HMAC: Expected hash is not equal!"); } } }
private void CompareBlocks(HmacAlg Algorithm) { if (Algorithm == HmacAlg.Sha256Hmac) { byte[] hashKey = new byte[32]; byte[] buffer = new byte[640]; byte[] hash1 = new byte[32]; byte[] hash2 = new byte[32]; using (System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider()) { rng.GetBytes(hashKey); rng.GetBytes(buffer); } using (System.Security.Cryptography.HMACSHA256 hmac = new System.Security.Cryptography.HMACSHA256(hashKey)) hash1 = hmac.ComputeHash(buffer); // test 1: HMAC interface HMAC hmac1 = new HMAC(new SHA256Digest()); hmac1.Init(hashKey); hmac1.BlockUpdate(buffer, 0, buffer.Length); hmac1.DoFinal(hash2, 0); if (!Compare.AreEqual(hash2, hash1)) throw new Exception("hmac is not equal!"); // test 2: class with dofinal using (SHA256HMAC hmac = new SHA256HMAC()) { hmac.Init(hashKey); hmac.BlockUpdate(buffer, 0, buffer.Length); hmac.DoFinal(hash2, 0); } if (!Compare.AreEqual(hash2, hash1)) throw new Exception("hmac1 is not equal!"); // test 3: class with computemac using (SHA256HMAC hmac = new SHA256HMAC(hashKey)) hash2 = hmac.ComputeMac(buffer); if (!Compare.AreEqual(hash2, hash1)) throw new Exception("hmac2 is not equal!"); } else { // SHA512 // byte[] hash1 = new byte[64]; byte[] hash2 = new byte[64]; byte[] hashKey = new byte[64]; byte[] buffer = new byte[128]; using (System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider()) { rng.GetBytes(hashKey); rng.GetBytes(buffer); } using (System.Security.Cryptography.HMACSHA512 hmac = new System.Security.Cryptography.HMACSHA512(hashKey)) hash1 = hmac.ComputeHash(buffer); // test 1: HMAC interface HMAC hmac1 = new HMAC(new SHA512Digest()); hmac1.Init(hashKey); hmac1.BlockUpdate(buffer, 0, buffer.Length); hmac1.DoFinal(hash2, 0); if (!Compare.AreEqual(hash2, hash1)) throw new Exception("hmac1 is not equal!"); // test 2: class with dofinal using (SHA512HMAC hmac = new SHA512HMAC()) { hmac.Init(hashKey); hmac.BlockUpdate(buffer, 0, buffer.Length); hmac.DoFinal(hash2, 0); } if (!Compare.AreEqual(hash2, hash1)) throw new Exception("hmac1 is not equal!"); // test 3: class with computemac using (SHA512HMAC hmac = new SHA512HMAC(hashKey)) hash2 = hmac.ComputeMac(buffer); if (!Compare.AreEqual(hash2, hash1)) throw new Exception("hmac2 is not equal!"); } }
void DecryptStream(Stream encryptedStream, Stream output) { using (BinaryReader reader = new BinaryReader(encryptedStream)) using (BinaryWriter writer = new BinaryWriter(output)) { //Read file header byte[] headerNonce; byte[] ciphertextPayload; byte[] mac; byte[] contentKey; byte[] cleartextPayload; headerNonce = reader.ReadBytes(16); ciphertextPayload = reader.ReadBytes(40); mac = reader.ReadBytes(32); HMAC headerHmac = new HMAC(macKey); headerHmac.Update(headerNonce); headerHmac.DoFinal(ciphertextPayload); if (!headerHmac.Hash.SequenceEqual(mac)) { throw new IOException("Encrypted file fails integrity check."); } cleartextPayload = AesCtr(ciphertextPayload, masterKey, headerNonce); contentKey = Slice(cleartextPayload, 8, 32); HMAC chunkHmac = new HMAC(macKey); //Process all chunks for (int blocknum = 0; ; ++blocknum) { //read file content payload byte[] chunk; chunk = reader.ReadBytes(32768 + 48); if (chunk.Length == 0) { break; } var chunkNonce = Slice(chunk, 0, 16); var chunkpayload = Slice(chunk, chunkNonce.Length, chunk.Length - 48); var chunkmac = Slice(chunk, chunkNonce.Length + chunkpayload.Length, 32); byte[] beBlockNum = BitConverter.GetBytes((long)blocknum); if (BitConverter.IsLittleEndian) { Array.Reverse(beBlockNum); } chunkHmac.Initialize(); chunkHmac.Update(headerNonce); chunkHmac.Update(beBlockNum); chunkHmac.Update(chunkNonce); chunkHmac.DoFinal(chunkpayload); if (!chunkHmac.Hash.SequenceEqual(chunkmac)) { throw new IOException("Encrypted file fails integrity check."); } var decryptedContent = AesCtr(chunkpayload, contentKey, chunkNonce); writer.Write(decryptedContent); } } }
private void CompareBlocks(HmacAlg Algorithm) { if (Algorithm == HmacAlg.Sha256Hmac) { byte[] hashKey = new byte[32]; byte[] buffer = new byte[640]; byte[] hash1 = new byte[32]; byte[] hash2 = new byte[32]; using (System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider()) { rng.GetBytes(hashKey); rng.GetBytes(buffer); } using (System.Security.Cryptography.HMACSHA256 hmac = new System.Security.Cryptography.HMACSHA256(hashKey)) hash1 = hmac.ComputeHash(buffer); // test 1: HMAC interface HMAC hmac1 = new HMAC(new SHA256Digest()); hmac1.Init(hashKey); hmac1.BlockUpdate(buffer, 0, buffer.Length); hmac1.DoFinal(hash2, 0); if (!Compare.AreEqual(hash2, hash1)) { throw new Exception("hmac is not equal!"); } // test 2: class with dofinal using (SHA256HMAC hmac = new SHA256HMAC()) { hmac.Init(hashKey); hmac.BlockUpdate(buffer, 0, buffer.Length); hmac.DoFinal(hash2, 0); } if (!Compare.AreEqual(hash2, hash1)) { throw new Exception("hmac1 is not equal!"); } // test 3: class with computemac using (SHA256HMAC hmac = new SHA256HMAC(hashKey)) hash2 = hmac.ComputeMac(buffer); if (!Compare.AreEqual(hash2, hash1)) { throw new Exception("hmac2 is not equal!"); } } else { // SHA512 // byte[] hash1 = new byte[64]; byte[] hash2 = new byte[64]; byte[] hashKey = new byte[64]; byte[] buffer = new byte[128]; using (System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider()) { rng.GetBytes(hashKey); rng.GetBytes(buffer); } using (System.Security.Cryptography.HMACSHA512 hmac = new System.Security.Cryptography.HMACSHA512(hashKey)) hash1 = hmac.ComputeHash(buffer); // test 1: HMAC interface HMAC hmac1 = new HMAC(new SHA512Digest()); hmac1.Init(hashKey); hmac1.BlockUpdate(buffer, 0, buffer.Length); hmac1.DoFinal(hash2, 0); if (!Compare.AreEqual(hash2, hash1)) { throw new Exception("hmac1 is not equal!"); } // test 2: class with dofinal using (SHA512HMAC hmac = new SHA512HMAC()) { hmac.Init(hashKey); hmac.BlockUpdate(buffer, 0, buffer.Length); hmac.DoFinal(hash2, 0); } if (!Compare.AreEqual(hash2, hash1)) { throw new Exception("hmac1 is not equal!"); } // test 3: class with computemac using (SHA512HMAC hmac = new SHA512HMAC(hashKey)) hash2 = hmac.ComputeMac(buffer); if (!Compare.AreEqual(hash2, hash1)) { throw new Exception("hmac2 is not equal!"); } } }
void EncryptInner(int recordType, int version, byte[] data, ref int off, ref int len) { int blen = bc.BlockSize; int mlen = hm.MACSize; int doff = off; int dlen = len; if (explicitIV) { /* * To make pseudorandom IV, we reuse HMAC, computed * over the encoded sequence number. Since this * input is distinct from all other HMAC inputs with * the same key, this should be randomish enough * (assuming HMAC is a good imitation of a random * oracle). */ IO.Enc64be(seq, tmp, 0); hm.Update(tmp, 0, 8); hm.DoFinal(tmp, 0); Array.Copy(tmp, 0, data, off - blen, blen); off -= blen; len += blen; } /* * Compute HMAC. */ IO.Enc64be(seq, tmp, 0); IO.WriteHeader(recordType, version, dlen, tmp, 8); hm.Update(tmp, 0, 13); hm.Update(data, doff, dlen); hm.DoFinal(data, off + len); len += mlen; seq++; /* * Add padding. */ int plen = blen - (len & (blen - 1)); for (int i = 0; i < plen; i++) { data[off + len + i] = (byte)(plen - 1); } len += plen; /* * Perform CBC encryption. We use our saved IV. If there is * an explicit IV, then it gets encrypted, which is fine * (CBC encryption of randomness is equally good randomness). */ bc.CBCEncrypt(iv, data, off, len); Array.Copy(data, off + len - blen, iv, 0, blen); /* * Add the header. */ off -= 5; IO.WriteHeader(recordType, version, len, data, off); len += 5; }