From e95e62f184510a12f9a53db8ade6e047ebad0288 Mon Sep 17 00:00:00 2001 From: bg45 Date: Sun, 22 Oct 2017 16:44:17 -0400 Subject: [PATCH] WIP 2.37 - ter --- ModernKeePassLib/Cryptography/CryptoUtil.cs | 12 ++--- .../Cryptography/Hash/DigestManaged.cs | 26 +++++++++ .../Cryptography/Hash/HMACSHA256.cs | 54 +++++++++++++------ .../Cryptography/Hash/SHA256Managed.cs | 13 +++++ .../Cryptography/Hash/SHA512Managed.cs | 13 +++++ ModernKeePassLib/Cryptography/SelfTest.cs | 28 +++++----- ModernKeePassLib/ModernKeePassLib.csproj | 3 ++ .../Serialization/HmacBlockStream.cs | 39 +++++++------- 8 files changed, 134 insertions(+), 54 deletions(-) create mode 100644 ModernKeePassLib/Cryptography/Hash/DigestManaged.cs create mode 100644 ModernKeePassLib/Cryptography/Hash/SHA256Managed.cs create mode 100644 ModernKeePassLib/Cryptography/Hash/SHA512Managed.cs diff --git a/ModernKeePassLib/Cryptography/CryptoUtil.cs b/ModernKeePassLib/Cryptography/CryptoUtil.cs index 62b5eed..333ec54 100644 --- a/ModernKeePassLib/Cryptography/CryptoUtil.cs +++ b/ModernKeePassLib/Cryptography/CryptoUtil.cs @@ -52,15 +52,15 @@ namespace ModernKeePassLib.Cryptography byte[] pbHash; -#if ModernKeePassLib +/*#if ModernKeePassLib var h = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256).CreateHash(); CryptographicBuffer.CopyToByteArray(h.GetValueAndReset(), out pbHash); -#else +#else*/ using(SHA256Managed h = new SHA256Managed()) { pbHash = h.ComputeHash(pbData, iOffset, cbCount); } -#endif +//#endif #if DEBUG // Ensure the data has not been modified @@ -90,15 +90,15 @@ namespace ModernKeePassLib.Cryptography if(cbOut <= 32) pbHash = HashSha256(pbIn, iInOffset, cbIn); else { -#if ModernKeePassLib +/*#if ModernKeePassLib var h = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha512).CreateHash(); CryptographicBuffer.CopyToByteArray(h.GetValueAndReset(), out pbHash); -#else +#else*/ using(SHA512Managed h = new SHA512Managed()) { pbHash = h.ComputeHash(pbIn, iInOffset, cbIn); } -#endif +//#endif } if(cbOut == pbHash.Length) return pbHash; diff --git a/ModernKeePassLib/Cryptography/Hash/DigestManaged.cs b/ModernKeePassLib/Cryptography/Hash/DigestManaged.cs new file mode 100644 index 0000000..bfff5dc --- /dev/null +++ b/ModernKeePassLib/Cryptography/Hash/DigestManaged.cs @@ -0,0 +1,26 @@ +using System; +using Org.BouncyCastle.Crypto; + +namespace ModernKeePassLib.Cryptography.Hash +{ + public abstract class DigestManaged : IDisposable + { + protected IDigest _hash; + + public byte[] ComputeHash(byte[] value, int offset, int length) + { + if (value == null) throw new ArgumentNullException(nameof(value)); + + byte[] resBuf = new byte[_hash.GetDigestSize()]; + _hash.BlockUpdate(value, offset, length); + _hash.DoFinal(resBuf, 0); + + return resBuf; + } + + public void Dispose() + { + _hash.Reset(); + } + } +} diff --git a/ModernKeePassLib/Cryptography/Hash/HMACSHA256.cs b/ModernKeePassLib/Cryptography/Hash/HMACSHA256.cs index cfc3ff5..9cc9b9d 100644 --- a/ModernKeePassLib/Cryptography/Hash/HMACSHA256.cs +++ b/ModernKeePassLib/Cryptography/Hash/HMACSHA256.cs @@ -6,30 +6,54 @@ using Org.BouncyCastle.Crypto.Parameters; namespace ModernKeePassLib.Cryptography.Hash { public class HMACSHA256: IDisposable - { - private readonly HMac _hmac; + private readonly HMac _hmac; - public HMACSHA256(byte[] key) - { - _hmac = new HMac(new Sha256Digest()); - _hmac.Init(new KeyParameter(key)); - } + public byte[] Hash + { + get + { + byte[] resBuf = new byte[_hmac.GetMacSize()]; + _hmac.DoFinal(resBuf, 0); + return resBuf; + } + } - public byte[] ComputeHash(byte[] value) - { - if (value == null) throw new ArgumentNullException("value"); + public HMACSHA256(byte[] key) + { + _hmac = new HMac(new Sha256Digest()); + _hmac.Init(new KeyParameter(key)); + } - byte[] resBuf = new byte[_hmac.GetMacSize()]; - _hmac.BlockUpdate(value, 0, value.Length); - _hmac.DoFinal(resBuf, 0); + public byte[] ComputeHash(byte[] value) + { + if (value == null) throw new ArgumentNullException(nameof(value)); - return resBuf; - } + byte[] resBuf = new byte[_hmac.GetMacSize()]; + _hmac.BlockUpdate(value, 0, value.Length); + _hmac.DoFinal(resBuf, 0); + + return resBuf; + } public void Dispose() { _hmac.Reset(); } + + internal void TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset ) + { + _hmac.BlockUpdate(inputBuffer, inputOffset, inputCount); + } + + internal void TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) + { + _hmac.DoFinal(inputBuffer, inputOffset); + } + + internal void Initialize() + { + _hmac.Reset(); + } } } diff --git a/ModernKeePassLib/Cryptography/Hash/SHA256Managed.cs b/ModernKeePassLib/Cryptography/Hash/SHA256Managed.cs new file mode 100644 index 0000000..1ad2659 --- /dev/null +++ b/ModernKeePassLib/Cryptography/Hash/SHA256Managed.cs @@ -0,0 +1,13 @@ +using System; +using Org.BouncyCastle.Crypto.Digests; + +namespace ModernKeePassLib.Cryptography.Hash +{ + public class SHA256Managed : DigestManaged + { + public SHA256Managed() + { + _hash = new Sha256Digest(); + } + } +} diff --git a/ModernKeePassLib/Cryptography/Hash/SHA512Managed.cs b/ModernKeePassLib/Cryptography/Hash/SHA512Managed.cs new file mode 100644 index 0000000..e293192 --- /dev/null +++ b/ModernKeePassLib/Cryptography/Hash/SHA512Managed.cs @@ -0,0 +1,13 @@ +using System; +using Org.BouncyCastle.Crypto.Digests; + +namespace ModernKeePassLib.Cryptography.Hash +{ + public class SHA512Managed : DigestManaged + { + public SHA512Managed() + { + _hash = new Sha512Digest(); + } + } +} diff --git a/ModernKeePassLib/Cryptography/SelfTest.cs b/ModernKeePassLib/Cryptography/SelfTest.cs index c0a7b3c..03916da 100644 --- a/ModernKeePassLib/Cryptography/SelfTest.cs +++ b/ModernKeePassLib/Cryptography/SelfTest.cs @@ -687,7 +687,7 @@ namespace ModernKeePassLib.Cryptography private static void HmacEval(byte[] pbKey, byte[] pbMsg, byte[] pbExpc, string strID) { -#if ModernKeePassLib +/*#if ModernKeePassLib // WinRT var h = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha256).CreateHash(CryptographicBuffer.CreateFromByteArray(pbKey)); h.Append(CryptographicBuffer.CreateFromByteArray(pbMsg)); @@ -701,19 +701,19 @@ namespace ModernKeePassLib.Cryptography throw new SecurityException("HMAC-SHA-256-" + strID + "-R"); // BouncyCastle - /*var h = new HMac(new Sha256Digest()); - h.BlockUpdate(pbMsg, 0, pbMsg.Length); - byte[] pbHash = MemUtil.EmptyByteArray; - h.DoFinal(pbHash, 0); - if (!MemUtil.ArraysEqual(pbHash, pbExpc)) - throw new SecurityException("HMAC-SHA-256-" + strID); + // var h = new HMac(new Sha256Digest()); + //h.BlockUpdate(pbMsg, 0, pbMsg.Length); + //byte[] pbHash = MemUtil.EmptyByteArray; + //h.DoFinal(pbHash, 0); + //if (!MemUtil.ArraysEqual(pbHash, pbExpc)) + // throw new SecurityException("HMAC-SHA-256-" + strID); - h.Reset(); - h.BlockUpdate(pbMsg, 0, pbMsg.Length); - h.DoFinal(pbHash, 0); - if (!MemUtil.ArraysEqual(pbHash, pbExpc)) - throw new SecurityException("HMAC-SHA-256-" + strID + "-R");*/ -#else + // h.Reset(); + //h.BlockUpdate(pbMsg, 0, pbMsg.Length); + //h.DoFinal(pbHash, 0); + //if (!MemUtil.ArraysEqual(pbHash, pbExpc)) + // throw new SecurityException("HMAC-SHA-256-" + strID + "-R"); +#else*/ // Original using(HMACSHA256 h = new HMACSHA256(pbKey)) { @@ -733,7 +733,7 @@ namespace ModernKeePassLib.Cryptography if(!MemUtil.ArraysEqual(pbHash, pbExpc)) throw new SecurityException("HMAC-SHA-256-" + strID + "-R"); } -#endif +//#endif } #endif diff --git a/ModernKeePassLib/ModernKeePassLib.csproj b/ModernKeePassLib/ModernKeePassLib.csproj index 4137d30..fbaa27d 100644 --- a/ModernKeePassLib/ModernKeePassLib.csproj +++ b/ModernKeePassLib/ModernKeePassLib.csproj @@ -61,7 +61,10 @@ + + + diff --git a/ModernKeePassLib/Serialization/HmacBlockStream.cs b/ModernKeePassLib/Serialization/HmacBlockStream.cs index 154933a..ff80b41 100644 --- a/ModernKeePassLib/Serialization/HmacBlockStream.cs +++ b/ModernKeePassLib/Serialization/HmacBlockStream.cs @@ -24,6 +24,7 @@ using System.IO; using System.Text; using Windows.Security.Cryptography; using Windows.Security.Cryptography.Core; +using ModernKeePassLib.Cryptography.Hash; using ModernKeePassLib.Resources; using ModernKeePassLib.Utility; using Org.BouncyCastle.Crypto.Digests; @@ -114,7 +115,7 @@ namespace ModernKeePassLib.Serialization Flush(); } - //m_sBase.Close(); + m_sBase.Dispose(); m_sBase = null; } @@ -144,10 +145,10 @@ namespace ModernKeePassLib.Serialization if(pbKey == null) throw new ArgumentNullException("pbKey"); Debug.Assert(pbKey.Length == 64); - // We are computing the HMAC using SHA-256, whose internal - // block size is 512 bits; thus create a key that is 512 - // bits long (using SHA-512) - + // We are computing the HMAC using SHA-256, whose internal + // block size is 512 bits; thus create a key that is 512 + // bits long (using SHA-512) +#if ModernKeePassLib byte[] pbBlockKey = MemUtil.EmptyByteArray; byte[] pbIndex = MemUtil.UInt64ToBytes(uBlockIndex); var h = new Sha512Digest(); @@ -155,8 +156,8 @@ namespace ModernKeePassLib.Serialization h.BlockUpdate(pbKey, 0, pbKey.Length); h.DoFinal(pbBlockKey, 0); h.Reset(); - - /*byte[] pbBlockKey; +#else + byte[] pbBlockKey; using(SHA512Managed h = new SHA512Managed()) { byte[] pbIndex = MemUtil.UInt64ToBytes(uBlockIndex); @@ -167,7 +168,7 @@ namespace ModernKeePassLib.Serialization pbBlockKey = h.Hash; } - */ +#endif #if DEBUG byte[] pbZero = new byte[64]; @@ -240,10 +241,10 @@ namespace ModernKeePassLib.Serialization if(m_bVerify) { - byte[] pbCmpHmac = MemUtil.EmptyByteArray; + byte[] pbCmpHmac; byte[] pbBlockKey = GetHmacKey64(m_pbKey, m_uBlockIndex); -#if ModernKeePassLib +/*#if ModernKeePassLib var h = new HMac(new Sha256Digest()); h.BlockUpdate(pbBlockIndex, 0, pbBlockIndex.Length); h.BlockUpdate(pbBlockSize, 0, pbBlockSize.Length); @@ -252,7 +253,7 @@ namespace ModernKeePassLib.Serialization h.DoFinal(pbCmpHmac, 0); h.Reset(); -#else +#else*/ using(HMACSHA256 h = new HMACSHA256(pbBlockKey)) { h.TransformBlock(pbBlockIndex, 0, pbBlockIndex.Length, @@ -268,8 +269,8 @@ namespace ModernKeePassLib.Serialization pbCmpHmac = h.Hash; } -#endif - MemUtil.ZeroByteArray(pbBlockKey); +//#endif + MemUtil.ZeroByteArray(pbBlockKey); if(!MemUtil.ArraysEqual(pbCmpHmac, pbStoredHmac)) throw new InvalidDataException(KLRes.FileCorrupted); @@ -313,10 +314,10 @@ namespace ModernKeePassLib.Serialization int cbBlockSize = m_iBufferPos; byte[] pbBlockSize = MemUtil.Int32ToBytes(cbBlockSize); - byte[] pbBlockHmac = MemUtil.EmptyByteArray; + byte[] pbBlockHmac; byte[] pbBlockKey = GetHmacKey64(m_pbKey, m_uBlockIndex); -#if ModernKeePassLib +/*#if ModernKeePassLib var h = new HMac(new Sha256Digest()); h.BlockUpdate(pbBlockIndex, 0, pbBlockIndex.Length); h.BlockUpdate(pbBlockSize, 0, pbBlockSize.Length); @@ -325,8 +326,8 @@ namespace ModernKeePassLib.Serialization h.DoFinal(pbBlockHmac, 0); h.Reset(); -#else - using(HMACSHA256 h = new HMACSHA256(pbBlockKey)) +#else*/ + using(HMACSHA256 h = new HMACSHA256(pbBlockKey)) { h.TransformBlock(pbBlockIndex, 0, pbBlockIndex.Length, pbBlockIndex, 0); @@ -340,8 +341,8 @@ namespace ModernKeePassLib.Serialization pbBlockHmac = h.Hash; } -#endif - MemUtil.ZeroByteArray(pbBlockKey); +//#endif + MemUtil.ZeroByteArray(pbBlockKey); MemUtil.Write(m_sBase, pbBlockHmac); // MemUtil.Write(m_sBase, pbBlockIndex); // Implicit