ModernKeePassLib implements HMAC correctly

Blake2b also implemented, but not tested
ModernKeePass app better implements focus on database password box (but still not working correctly)
This commit is contained in:
2017-10-26 12:38:34 +02:00
committed by BONNEVILLE Geoffroy
parent 5cf4ff3012
commit 1b439a4960
18 changed files with 317 additions and 213 deletions

View File

@@ -4,10 +4,12 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
xmlns:actions="using:ModernKeePass.Actions"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="60" d:DesignHeight="60"
d:DesignWidth="550" d:DesignWidth="550" >
Loaded="UserControl_Loaded">
<UserControl.Resources> <UserControl.Resources>
<SolidColorBrush x:Key="ErrorColorBrush" Color="Red"/> <SolidColorBrush x:Key="ErrorColorBrush" Color="Red"/>
<Style TargetType="PasswordBox" x:Name="PasswordBoxWithButtonStyle"> <Style TargetType="PasswordBox" x:Name="PasswordBoxWithButtonStyle">
@@ -335,7 +337,13 @@
</Style> </Style>
</UserControl.Resources> </UserControl.Resources>
<StackPanel> <StackPanel>
<PasswordBox x:Name="PasswordBox" Password="{Binding Password, ElementName=UserControl, Mode=TwoWay}" Width="500" IsPasswordRevealButtonEnabled="True" KeyDown="PasswordBox_KeyDown" PlaceholderText="Password" Style="{StaticResource PasswordBoxWithButtonStyle}"/> <PasswordBox x:Name="PasswordBox" Password="{Binding Password, ElementName=UserControl, Mode=TwoWay}" Width="500" IsPasswordRevealButtonEnabled="True" KeyDown="PasswordBox_KeyDown" PlaceholderText="Password" Style="{StaticResource PasswordBoxWithButtonStyle}">
<interactivity:Interaction.Behaviors>
<core:DataTriggerBehavior Binding="{Binding Visibility, ElementName=UserControl}" Value="Visible">
<actions:SetupFocusAction TargetObject="{Binding ElementName=PasswordBox}" />
</core:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</PasswordBox>
<TextBlock x:Name="StatusTextBlock" Height="28" Foreground="{ThemeResource ErrorColorBrush}" FontSize="14" FontWeight="SemiBold" TextWrapping="WrapWholeWords" /> <TextBlock x:Name="StatusTextBlock" Height="28" Foreground="{ThemeResource ErrorColorBrush}" FontSize="14" FontWeight="SemiBold" TextWrapping="WrapWholeWords" />
</StackPanel> </StackPanel>
</UserControl> </UserControl>

View File

@@ -1,7 +1,5 @@
using System; using System;
using System.Threading.Tasks;
using Windows.System; using Windows.System;
using Windows.UI.Core;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Input;
using ModernKeePass.Common; using ModernKeePass.Common;
@@ -71,12 +69,5 @@ namespace ModernKeePass.Controls
StatusTextBlock.Text = string.Empty; StatusTextBlock.Text = string.Empty;
} }
} }
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(
() => Dispatcher.RunAsync(CoreDispatcherPriority.Low,
() => PasswordBox.Focus(FocusState.Programmatic)));
}
} }
} }

View File

@@ -254,10 +254,6 @@
<HintPath>..\packages\Microsoft.Toolkit.Uwp.Notifications.2.0.0\lib\dotnet\Microsoft.Toolkit.Uwp.Notifications.dll</HintPath> <HintPath>..\packages\Microsoft.Toolkit.Uwp.Notifications.2.0.0\lib\dotnet\Microsoft.Toolkit.Uwp.Notifications.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="ModernKeePassLib, Version=2.37.0.2000, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ModernKeePassLib.2.37.4000\lib\netstandard1.2\ModernKeePassLib.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Splat, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="Splat, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Splat.2.0.0\lib\Portable-Win81+Wpa81\Splat.dll</HintPath> <HintPath>..\packages\Splat.2.0.0\lib\Portable-Win81+Wpa81\Splat.dll</HintPath>
<Private>True</Private> <Private>True</Private>
@@ -318,6 +314,12 @@
<Content Include="Assets\Wide310x150Logo.scale-180.png" /> <Content Include="Assets\Wide310x150Logo.scale-180.png" />
<Content Include="Assets\Wide310x150Logo.scale-80.png" /> <Content Include="Assets\Wide310x150Logo.scale-80.png" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ModernKeePassLib\ModernKeePassLib.csproj">
<Project>{2e710089-9559-4967-846c-e763dd1f3acb}</Project>
<Name>ModernKeePassLib</Name>
</ProjectReference>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '12.0' "> <PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '12.0' ">
<VisualStudioVersion>12.0</VisualStudioVersion> <VisualStudioVersion>12.0</VisualStudioVersion>
</PropertyGroup> </PropertyGroup>

View File

@@ -122,7 +122,7 @@ namespace ModernKeePassLib.Cryptography.Cipher
m_c.Dispose(); m_c.Dispose();
m_c = null; m_c = null;
//m_sBase.Close(); m_sBase.Dispose();
m_sBase = null; m_sBase = null;
} }

View File

@@ -22,7 +22,6 @@ using System.Collections.Generic;
using System.Text; using System.Text;
using System.IO; using System.IO;
using System.Diagnostics; using System.Diagnostics;
using System.Security;
namespace ModernKeePassLib.Cryptography.Cipher namespace ModernKeePassLib.Cryptography.Cipher
{ {

View File

@@ -18,7 +18,10 @@
*/ */
using System; using System;
using System.Collections.Generic;
using System.Text;
using System.IO; using System.IO;
using System.Security;
using System.Diagnostics; using System.Diagnostics;
#if ModernKeePassLib #if ModernKeePassLib
using ModernKeePassLib.Resources; using ModernKeePassLib.Resources;

View File

@@ -23,12 +23,12 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
#if ModernKeePassLib #if ModernKeePassLib
using ModernKeePassLib.Cryptography.Hash;
using Windows.Security.Cryptography; using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
#else #else
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Windows.Forms;
#endif #endif
using ModernKeePassLib.Native; using ModernKeePassLib.Native;
@@ -120,12 +120,6 @@ namespace ModernKeePassLib.Cryptography
byte[] pbNewData = pbEntropy; byte[] pbNewData = pbEntropy;
if(pbEntropy.Length > 64) if(pbEntropy.Length > 64)
{ {
#if ModernKeePassLib
var h = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256)
.HashData(CryptographicBuffer.CreateFromByteArray(pbEntropy));
CryptographicBuffer.CopyToByteArray(h, out pbNewData);
#else
#if KeePassLibSD #if KeePassLibSD
using(SHA256Managed shaNew = new SHA256Managed()) using(SHA256Managed shaNew = new SHA256Managed())
#else #else
@@ -134,7 +128,6 @@ namespace ModernKeePassLib.Cryptography
{ {
pbNewData = shaNew.ComputeHash(pbEntropy); pbNewData = shaNew.ComputeHash(pbEntropy);
} }
#endif
} }
lock(m_oSyncRoot) lock(m_oSyncRoot)
@@ -148,11 +141,6 @@ namespace ModernKeePassLib.Cryptography
MemUtil.ZeroByteArray(m_pbEntropyPool); MemUtil.ZeroByteArray(m_pbEntropyPool);
#if ModernKeePassLib
var h = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256)
.HashData(CryptographicBuffer.CreateFromByteArray(pbCmp));
CryptographicBuffer.CopyToByteArray(h, out m_pbEntropyPool);
#else
#if KeePassLibSD #if KeePassLibSD
using(SHA256Managed shaPool = new SHA256Managed()) using(SHA256Managed shaPool = new SHA256Managed())
#else #else
@@ -161,7 +149,7 @@ namespace ModernKeePassLib.Cryptography
{ {
m_pbEntropyPool = shaPool.ComputeHash(pbCmp); m_pbEntropyPool = shaPool.ComputeHash(pbCmp);
} }
#endif
MemUtil.ZeroByteArray(pbCmp); MemUtil.ZeroByteArray(pbCmp);
} }
} }

View File

@@ -23,16 +23,26 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO;
using System.Text; using System.Text;
#if ModernKeePassLib
#elif !KeePassUAP
using System.Security.Cryptography;
#endif
using ModernKeePassLib.Utility; using ModernKeePassLib.Utility;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Tls;
namespace ModernKeePassLib.Cryptography.Hash namespace ModernKeePassLib.Cryptography.Hash
{ {
public sealed class Blake2b : IDigest public sealed class Blake2b : IDisposable
{ {
protected int HashSizeValue;
protected internal byte[] HashValue;
protected int State = 0;
private bool m_bDisposed = false;
private const int NbRounds = 12; private const int NbRounds = 12;
private const int NbBlockBytes = 128; private const int NbBlockBytes = 128;
private const int NbMaxOutBytes = 64; private const int NbMaxOutBytes = 64;
@@ -70,13 +80,27 @@ namespace ModernKeePassLib.Cryptography.Hash
private ulong[] m_m = new ulong[16]; private ulong[] m_m = new ulong[16];
private ulong[] m_v = new ulong[16]; private ulong[] m_v = new ulong[16];
public string AlgorithmName { get; } = "Blake2b"; public int HashSize
public int HashSize { get; internal set; } {
get { return HashSizeValue; }
}
public Blake2b() public byte[] Hash
{
get
{
if (m_bDisposed)
throw new ObjectDisposedException(null);
if (State != 0)
throw new InvalidOperationException("Blak2B Cryptography Hash Not Yet Finalized");
return (byte[])HashValue.Clone();
}
}
public Blake2b()
{ {
m_cbHashLength = NbMaxOutBytes; m_cbHashLength = NbMaxOutBytes;
this.HashSize = NbMaxOutBytes * 8; // Bits this.HashSizeValue = NbMaxOutBytes * 8; // Bits
Initialize(); Initialize();
} }
@@ -87,7 +111,7 @@ namespace ModernKeePassLib.Cryptography.Hash
throw new ArgumentOutOfRangeException("cbHashLength"); throw new ArgumentOutOfRangeException("cbHashLength");
m_cbHashLength = cbHashLength; m_cbHashLength = cbHashLength;
this.HashSize = cbHashLength * 8; // Bits this.HashSizeValue = cbHashLength * 8; // Bits
Initialize(); Initialize();
} }
@@ -166,119 +190,205 @@ namespace ModernKeePassLib.Cryptography.Hash
m_t[0] += cb; m_t[0] += cb;
if(m_t[0] < cb) ++m_t[1]; if(m_t[0] < cb) ++m_t[1];
} }
public int GetDigestSize()
{
return HashSize;
}
public int GetByteLength() private void HashCore(byte[] array, int ibStart, int cbSize)
{ {
return m_buf.Length; Debug.Assert(m_f[0] == 0);
}
public void Update(byte input) if((m_cbBuf + cbSize) > NbBlockBytes) // Not '>=' (buffer must not be empty)
{ {
throw new NotImplementedException(); int cbFill = NbBlockBytes - m_cbBuf;
} if(cbFill > 0) Array.Copy(array, ibStart, m_buf, m_cbBuf, cbFill);
public void BlockUpdate(byte[] array, int ibStart, int cbSize) IncrementCounter((ulong)NbBlockBytes);
{ Compress(m_buf, 0);
Debug.Assert(m_f[0] == 0);
if ((m_cbBuf + cbSize) > NbBlockBytes) // Not '>=' (buffer must not be empty) m_cbBuf = 0;
{ cbSize -= cbFill;
int cbFill = NbBlockBytes - m_cbBuf; ibStart += cbFill;
if (cbFill > 0) Array.Copy(array, ibStart, m_buf, m_cbBuf, cbFill);
IncrementCounter((ulong)NbBlockBytes); while(cbSize > NbBlockBytes) // Not '>=' (buffer must not be empty)
Compress(m_buf, 0); {
IncrementCounter((ulong)NbBlockBytes);
Compress(array, ibStart);
m_cbBuf = 0; cbSize -= NbBlockBytes;
cbSize -= cbFill; ibStart += NbBlockBytes;
ibStart += cbFill; }
}
while (cbSize > NbBlockBytes) // Not '>=' (buffer must not be empty) if(cbSize > 0)
{ {
IncrementCounter((ulong)NbBlockBytes); Debug.Assert((m_cbBuf + cbSize) <= NbBlockBytes);
Compress(array, ibStart);
cbSize -= NbBlockBytes; Array.Copy(array, ibStart, m_buf, m_cbBuf, cbSize);
ibStart += NbBlockBytes; m_cbBuf += cbSize;
} }
} }
if (cbSize > 0) private byte[] HashFinal()
{ {
Debug.Assert((m_cbBuf + cbSize) <= NbBlockBytes); if(m_f[0] != 0) { Debug.Assert(false); throw new InvalidOperationException(); }
Debug.Assert(((m_t[1] == 0) && (m_t[0] == 0)) ||
(m_cbBuf > 0)); // Buffer must not be empty for last block processing
Array.Copy(array, ibStart, m_buf, m_cbBuf, cbSize); m_f[0] = ulong.MaxValue; // Indicate last block
m_cbBuf += cbSize;
}
}
public int DoFinal(byte[] output, int outOff) int cbFill = NbBlockBytes - m_cbBuf;
{ if(cbFill > 0) Array.Clear(m_buf, m_cbBuf, cbFill);
if (m_f[0] != 0) { Debug.Assert(false); throw new InvalidOperationException(); }
Debug.Assert(((m_t[1] == 0) && (m_t[0] == 0)) ||
(m_cbBuf > 0)); // Buffer must not be empty for last block processing
m_f[0] = ulong.MaxValue; // Indicate last block IncrementCounter((ulong)m_cbBuf);
Compress(m_buf, 0);
int cbFill = NbBlockBytes - m_cbBuf; byte[] pbHash = new byte[NbMaxOutBytes];
if (cbFill > 0) Array.Clear(m_buf, m_cbBuf, cbFill); for(int i = 0; i < m_h.Length; ++i)
MemUtil.UInt64ToBytesEx(m_h[i], pbHash, i << 3);
IncrementCounter((ulong)m_cbBuf); if(m_cbHashLength == NbMaxOutBytes) return pbHash;
Compress(m_buf, 0); Debug.Assert(m_cbHashLength < NbMaxOutBytes);
byte[] pbHash = new byte[NbMaxOutBytes]; byte[] pbShort = new byte[m_cbHashLength];
for (int i = 0; i < m_h.Length; ++i) if(m_cbHashLength > 0)
MemUtil.UInt64ToBytesEx(m_h[i], pbHash, i << 3); Array.Copy(pbHash, pbShort, m_cbHashLength);
MemUtil.ZeroByteArray(pbHash);
return pbShort;
}
if (m_cbHashLength == NbMaxOutBytes) public byte[] ComputeHash(Stream inputStream)
{
output = pbHash;
return output.Length;
}
Debug.Assert(m_cbHashLength < NbMaxOutBytes);
byte[] pbShort = new byte[m_cbHashLength];
if (m_cbHashLength > 0)
Array.Copy(pbHash, pbShort, m_cbHashLength);
MemUtil.ZeroByteArray(pbHash);
output = pbShort;
return output.Length;
}
public void Reset()
{
MemUtil.ZeroByteArray(m_buf);
}
public void TransformBlock(byte[] pbBuf, int p1, int pbBufLength, byte[] p3, int p4)
{ {
BlockUpdate(pbBuf, p1, pbBufLength); if (m_bDisposed)
throw new ObjectDisposedException(null);
// Default the buffer size to 4K.
byte[] buffer = new byte[4096];
int bytesRead;
do
{
bytesRead = inputStream.Read(buffer, 0, 4096);
if (bytesRead > 0)
{
HashCore(buffer, 0, bytesRead);
}
} while (bytesRead > 0);
HashValue = HashFinal();
byte[] Tmp = (byte[])HashValue.Clone();
Initialize();
return (Tmp);
} }
public void TransformFinalBlock(byte[] emptyByteArray, int i, int i1) public byte[] ComputeHash(byte[] buffer)
{ {
DoFinal(emptyByteArray, i); if (m_bDisposed)
throw new ObjectDisposedException(null);
// Do some validation
if (buffer == null) throw new ArgumentNullException("buffer");
HashCore(buffer, 0, buffer.Length);
HashValue = HashFinal();
byte[] Tmp = (byte[])HashValue.Clone();
Initialize();
return (Tmp);
}
public byte[] ComputeHash(byte[] buffer, int offset, int count)
{
// Do some validation
if (buffer == null)
throw new ArgumentNullException("buffer");
if (offset < 0)
throw new ArgumentOutOfRangeException("offset", "ArgumentOutOfRange_NeedNonNegNum");
if (count < 0 || (count > buffer.Length))
throw new ArgumentException("Argument_InvalidValue");
if ((buffer.Length - count) < offset)
throw new ArgumentException("Argument_InvalidOffLen");
if (m_bDisposed)
throw new ObjectDisposedException(null);
HashCore(buffer, offset, count);
HashValue = HashFinal();
byte[] Tmp = (byte[])HashValue.Clone();
Initialize();
return (Tmp);
}
public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
{
// Do some validation, we let BlockCopy do the destination array validation
if (inputBuffer == null)
throw new ArgumentNullException("inputBuffer");
if (inputOffset < 0)
throw new ArgumentOutOfRangeException("inputOffset", "ArgumentOutOfRange_NeedNonNegNum");
if (inputCount < 0 || (inputCount > inputBuffer.Length))
throw new ArgumentException("Argument_InvalidValue");
if ((inputBuffer.Length - inputCount) < inputOffset)
throw new ArgumentException("Argument_InvalidOffLen");
if (m_bDisposed)
throw new ObjectDisposedException(null);
// Change the State value
State = 1;
HashCore(inputBuffer, inputOffset, inputCount);
if ((outputBuffer != null) && ((inputBuffer != outputBuffer) || (inputOffset != outputOffset)))
Buffer.BlockCopy(inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
return inputCount;
}
public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
{
// Do some validation
if (inputBuffer == null)
throw new ArgumentNullException("inputBuffer");
if (inputOffset < 0)
throw new ArgumentOutOfRangeException("inputOffset", "ArgumentOutOfRange_NeedNonNegNum");
if (inputCount < 0 || (inputCount > inputBuffer.Length))
throw new ArgumentException("Argument_InvalidValue");
if ((inputBuffer.Length - inputCount) < inputOffset)
throw new ArgumentException("Argument_InvalidOffLen");
if (m_bDisposed)
throw new ObjectDisposedException(null);
HashCore(inputBuffer, inputOffset, inputCount);
HashValue = HashFinal();
byte[] outputBytes;
if (inputCount != 0)
{
outputBytes = new byte[inputCount];
Array.Copy(inputBuffer, inputOffset, outputBytes, 0, inputCount);
}
else
{
outputBytes = MemUtil.EmptyByteArray;
}
// reset the State value
State = 0;
return outputBytes;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} }
public void Clear() public void Clear()
{ {
Reset(); (this as IDisposable).Dispose();
} }
internal byte[] ComputeHash(byte[] value) private void Dispose(bool disposing)
{ {
if (value == null) throw new ArgumentNullException(nameof(value)); if (disposing)
{
byte[] resBuf = new byte[m_cbHashLength]; if (HashValue != null)
BlockUpdate(value, 0, value.Length); Array.Clear(HashValue, 0, HashValue.Length);
DoFinal(resBuf, 0); HashValue = null;
m_bDisposed = true;
return resBuf; }
} }
} }
} }

View File

@@ -0,0 +1,31 @@
using System;
using Org.BouncyCastle.Crypto.Macs;
namespace ModernKeePassLib.Cryptography.Hash
{
public class HMAC : IDisposable
{
protected HMac _hmac;
public byte[] ComputeHash(byte[] value)
{
return ComputeHash(value, 0, value.Length);
}
public byte[] ComputeHash(byte[] value, int offset, int length)
{
if (value == null) throw new ArgumentNullException(nameof(value));
byte[] resBuf = new byte[_hmac.GetMacSize()];
_hmac.BlockUpdate(value, 0, length);
_hmac.DoFinal(resBuf, 0);
return resBuf;
}
public void Dispose()
{
_hmac.Reset();
}
}
}

View File

@@ -0,0 +1,15 @@
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Macs;
using Org.BouncyCastle.Crypto.Parameters;
namespace ModernKeePassLib.Cryptography.Hash
{
public class HMACSHA1: HMAC
{
public HMACSHA1(byte[] key)
{
_hmac = new HMac(new Sha1Digest());
_hmac.Init(new KeyParameter(key));
}
}
}

View File

@@ -1,47 +1,18 @@
using System; using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Macs; using Org.BouncyCastle.Crypto.Macs;
using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Parameters;
namespace ModernKeePassLib.Cryptography.Hash namespace ModernKeePassLib.Cryptography.Hash
{ {
public class HMACSHA256: IDisposable public class HMACSHA256: HMAC
{ {
private readonly HMac _hmac;
public byte[] Hash
{
get
{
byte[] resBuf = new byte[_hmac.GetMacSize()];
_hmac.DoFinal(resBuf, 0);
return resBuf;
}
}
public HMACSHA256(byte[] key) public HMACSHA256(byte[] key)
{ {
_hmac = new HMac(new Sha256Digest()); _hmac = new HMac(new Sha256Digest());
_hmac.Init(new KeyParameter(key)); _hmac.Init(new KeyParameter(key));
} }
public byte[] ComputeHash(byte[] value) /*internal void TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
{
if (value == null) throw new ArgumentNullException(nameof(value));
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); _hmac.BlockUpdate(inputBuffer, inputOffset, inputCount);
} }
@@ -54,6 +25,6 @@ namespace ModernKeePassLib.Cryptography.Hash
internal void Initialize() internal void Initialize()
{ {
_hmac.Reset(); _hmac.Reset();
} }*/
} }
} }

View File

@@ -42,8 +42,6 @@ namespace ModernKeePassLib.Cryptography
private readonly Stream m_sBaseStream; private readonly Stream m_sBaseStream;
private readonly bool m_bWriting; private readonly bool m_bWriting;
#if ModernKeePassLib #if ModernKeePassLib
//private ICryptoTransform m_hash;
//private CryptographicHash m_hash;
private IDigest m_hash; private IDigest m_hash;
#else #else
private HashAlgorithm m_hash; private HashAlgorithm m_hash;
@@ -93,8 +91,6 @@ namespace ModernKeePassLib.Cryptography
m_sBaseStream = sBaseStream; m_sBaseStream = sBaseStream;
m_bWriting = bWriting; m_bWriting = bWriting;
#if ModernKeePassLib #if ModernKeePassLib
//m_hash = WinRTCrypto.HashAlgorithmProvider.OpenAlgorithm(hashAlgorithm ?? HashAlgorithm.Sha256).CreateHash();
//m_hash = HashAlgorithmProvider.OpenAlgorithm(hashAlgorithm ?? HashAlgorithmNames.Sha256).CreateHash();
m_hash = hashAlgorithm ?? new Sha256Digest(); m_hash = hashAlgorithm ?? new Sha256Digest();
#elif !KeePassLibSD #elif !KeePassLibSD
m_hash = (hashAlgorithm ?? new SHA256Managed()); m_hash = (hashAlgorithm ?? new SHA256Managed());
@@ -128,8 +124,6 @@ namespace ModernKeePassLib.Cryptography
try try
{ {
#if ModernKeePassLib #if ModernKeePassLib
//m_pbFinalHash = (m_hash as CryptographicHash).GetValueAndReset ();
//CryptographicBuffer.CopyToByteArray(m_hash.GetValueAndReset(), out m_pbFinalHash);
m_pbFinalHash = new byte[32]; m_pbFinalHash = new byte[32];
m_hash.DoFinal(m_pbFinalHash, 0); m_hash.DoFinal(m_pbFinalHash, 0);
m_hash.Reset(); m_hash.Reset();

View File

@@ -22,8 +22,7 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Text; using System.Text;
#if ModernKeePassLib #if ModernKeePassLib
using Windows.Security.Cryptography; using ModernKeePassLib.Cryptography.Hash;
using Windows.Security.Cryptography.Core;
#elif !KeePassUAP #elif !KeePassUAP
using System.Security.Cryptography; using System.Security.Cryptography;
#endif #endif
@@ -46,16 +45,10 @@ namespace ModernKeePassLib.Cryptography
{ {
byte[] pbText = MemUtil.UInt64ToBytes(uFactor); byte[] pbText = MemUtil.UInt64ToBytes(uFactor);
Array.Reverse(pbText); // To big-endian Array.Reverse(pbText); // To big-endian
#if ModernKeePassLib
var hsha1 = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha1).CreateHash(CryptographicBuffer.CreateFromByteArray(pbSecret));
hsha1.Append(CryptographicBuffer.CreateFromByteArray(pbText));
byte[] pbHash;
CryptographicBuffer.CopyToByteArray(hsha1.GetValueAndReset(), out pbHash);
#else
HMACSHA1 hsha1 = new HMACSHA1(pbSecret); HMACSHA1 hsha1 = new HMACSHA1(pbSecret);
byte[] pbHash = hsha1.ComputeHash(pbText); byte[] pbHash = hsha1.ComputeHash(pbText);
#endif
uint uOffset = (uint)(pbHash[pbHash.Length - 1] & 0xF); uint uOffset = (uint)(pbHash[pbHash.Length - 1] & 0xF);
if((iTruncationOffset >= 0) && (iTruncationOffset < (pbHash.Length - 4))) if((iTruncationOffset >= 0) && (iTruncationOffset < (pbHash.Length - 4)))
uOffset = (uint)iTruncationOffset; uOffset = (uint)iTruncationOffset;

View File

@@ -151,10 +151,8 @@ namespace ModernKeePassLib.Cryptography.KeyDerivation
MemUtil.UInt32ToBytesEx((uint)pbAssocData.Length, pbBuf, 0); MemUtil.UInt32ToBytesEx((uint)pbAssocData.Length, pbBuf, 0);
h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0); h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
h.TransformBlock(pbAssocData, 0, pbAssocData.Length, pbAssocData, 0); h.TransformBlock(pbAssocData, 0, pbAssocData.Length, pbAssocData, 0);
byte[] pbH0 = MemUtil.EmptyByteArray; h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);
h.TransformFinalBlock(pbH0, 0, 0); byte[] pbH0 = h.Hash;
/*h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);
byte[] pbH0 = h.Hash;*/
Debug.Assert(pbH0.Length == 64); Debug.Assert(pbH0.Length == 64);
byte[] pbBlockHash = new byte[NbPreHashSeedLength]; byte[] pbBlockHash = new byte[NbPreHashSeedLength];
@@ -202,9 +200,14 @@ namespace ModernKeePassLib.Cryptography.KeyDerivation
// int iSrcOffset = (int)uSrcOffset; // int iSrcOffset = (int)uSrcOffset;
// for(int i = 0; i < (int)NbBlockSizeInQW; ++i) // for(int i = 0; i < (int)NbBlockSizeInQW; ++i)
// vDst[iDstOffset + i] = vSrc[iSrcOffset + i]; // vDst[iDstOffset + i] = vSrc[iSrcOffset + i];
#if ModernKeePassLib || KeePassUAP
Array.Copy(vSrc, (int)uSrcOffset, vDst, (int)uDstOffset, Array.Copy(vSrc, (int)uSrcOffset, vDst, (int)uDstOffset,
(int)NbBlockSizeInQW); (int)NbBlockSizeInQW);
#else
Array.Copy(vSrc, (long)uSrcOffset, vDst, (long)uDstOffset,
(long)NbBlockSizeInQW);
#endif
} }
private static void XorBlock(ulong[] vDst, ulong uDstOffset, ulong[] vSrc, private static void XorBlock(ulong[] vDst, ulong uDstOffset, ulong[] vSrc,
@@ -236,26 +239,23 @@ namespace ModernKeePassLib.Cryptography.KeyDerivation
hOut.TransformBlock(pbOutLen, 0, pbOutLen.Length, pbOutLen, 0); hOut.TransformBlock(pbOutLen, 0, pbOutLen.Length, pbOutLen, 0);
hOut.TransformBlock(pbIn, 0, cbIn, pbIn, 0); hOut.TransformBlock(pbIn, 0, cbIn, pbIn, 0);
hOut.TransformFinalBlock(pbOut, 0, 0); hOut.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);
/*hOut.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);
Array.Copy(hOut.Hash, pbOut, cbOut);*/ Array.Copy(hOut.Hash, pbOut, cbOut);
if(cbOut < 64) hOut.Clear(); if(cbOut < 64) hOut.Clear();
return; return;
} }
byte[] pbOutBuffer = new byte[64];
h.Initialize(); h.Initialize();
h.TransformBlock(pbOutLen, 0, pbOutLen.Length, pbOutLen, 0); h.TransformBlock(pbOutLen, 0, pbOutLen.Length, pbOutLen, 0);
h.TransformBlock(pbIn, 0, cbIn, pbIn, 0); h.TransformBlock(pbIn, 0, cbIn, pbIn, 0);
h.TransformFinalBlock(pbOutBuffer, 0, 0); h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);
/*h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0); byte[] pbOutBuffer = new byte[64];
Array.Copy(h.Hash, pbOutBuffer, pbOutBuffer.Length);
Array.Copy(h.Hash, pbOutBuffer, pbOutBuffer.Length);*/ int ibOut = 64 / 2;
int ibOut = 64 / 2;
Array.Copy(pbOutBuffer, pbOut, ibOut); Array.Copy(pbOutBuffer, pbOut, ibOut);
int cbToProduce = cbOut - ibOut; int cbToProduce = cbOut - ibOut;
@@ -272,18 +272,15 @@ namespace ModernKeePassLib.Cryptography.KeyDerivation
MemUtil.ZeroByteArray(pbHash); MemUtil.ZeroByteArray(pbHash);
} }
/*using(*/ using(Blake2b hOut = new Blake2b(cbToProduce))
{ {
Blake2b hOut = new Blake2b(cbToProduce); /*) byte[] pbHash = hOut.ComputeHash(pbOutBuffer);
{*/ Array.Copy(pbHash, 0, pbOut, ibOut, cbToProduce);
byte[] pbHash = hOut.ComputeHash(pbOutBuffer);
Array.Copy(pbHash, 0, pbOut, ibOut, cbToProduce);
MemUtil.ZeroByteArray(pbHash); MemUtil.ZeroByteArray(pbHash);
//} }
}
MemUtil.ZeroByteArray(pbOutBuffer); MemUtil.ZeroByteArray(pbOutBuffer);
} }
#if !ARGON2_G_INLINED #if !ARGON2_G_INLINED
@@ -468,13 +465,13 @@ namespace ModernKeePassLib.Cryptography.KeyDerivation
ti.Pass = r; ti.Pass = r;
ti.Lane = (ulong)l; ti.Lane = (ulong)l;
ti.Slice = s; ti.Slice = s;
#if !ModernKeePassLib
/*if(!ThreadPool.QueueUserWorkItem(FillSegmentThr, ti)) if(!ThreadPool.QueueUserWorkItem(FillSegmentThr, ti))
{ {
Debug.Assert(false); Debug.Assert(false);
throw new OutOfMemoryException(); throw new OutOfMemoryException();
}*/ }
#endif
v[l] = ti; v[l] = ti;
} }

View File

@@ -1,6 +1,6 @@
/* /*
KeePass Password Safe - The Open-Source Password Manager KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de> Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/* /*
KeePass Password Safe - The Open-Source Password Manager KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de> Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@@ -62,6 +62,8 @@
<Compile Include="Cryptography\CryptoUtil.cs" /> <Compile Include="Cryptography\CryptoUtil.cs" />
<Compile Include="Cryptography\Hash\Blake2b.cs" /> <Compile Include="Cryptography\Hash\Blake2b.cs" />
<Compile Include="Cryptography\Hash\DigestManaged.cs" /> <Compile Include="Cryptography\Hash\DigestManaged.cs" />
<Compile Include="Cryptography\Hash\HMAC.cs" />
<Compile Include="Cryptography\Hash\HMACSHA1.cs" />
<Compile Include="Cryptography\Hash\HMACSHA256.cs" /> <Compile Include="Cryptography\Hash\HMACSHA256.cs" />
<Compile Include="Cryptography\Hash\SHA256Managed.cs" /> <Compile Include="Cryptography\Hash\SHA256Managed.cs" />
<Compile Include="Cryptography\Hash\SHA512Managed.cs" /> <Compile Include="Cryptography\Hash\SHA512Managed.cs" />

View File

@@ -2,15 +2,15 @@
<package > <package >
<metadata> <metadata>
<id>ModernKeePassLib</id> <id>ModernKeePassLib</id>
<version>2.37.4000</version> <version>2.37.5000</version>
<title>ModernKeePassLib</title> <title>ModernKeePassLib</title>
<authors>Geoffroy Bonneville</authors> <authors>Geoffroy Bonneville</authors>
<owners>Geoffroy Bonneville</owners> <owners>Geoffroy Bonneville</owners>
<licenseUrl>https://www.gnu.org/licenses/gpl-3.0.en.html</licenseUrl> <licenseUrl>https://www.gnu.org/licenses/gpl-3.0.en.html</licenseUrl>
<projectUrl>https://github.com/wismna/ModernKeePass</projectUrl> <projectUrl>https://github.com/wismna/ModernKeePass</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance> <requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Portable KeePass Password Management Library that targets .Net Standard and WinRT</description> <description>Portable KeePass Password Management Library that targets .Net Standard and WinRT. Allows reading, editing and writing to KeePass 2.x databases.</description>
<releaseNotes>Opening and writing back to working order! There is still some untested stuff, mainly related to KDBX file format 4</releaseNotes> <releaseNotes>HMAC and Blake2B re-implemented.</releaseNotes>
<copyright>Copyright © 2017 Geoffroy Bonneville</copyright> <copyright>Copyright © 2017 Geoffroy Bonneville</copyright>
<tags>KeePass KeePassLib Portable PCL NetStandard</tags> <tags>KeePass KeePassLib Portable PCL NetStandard</tags>
<dependencies> <dependencies>