Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 02a6f1c

Browse files
committed
Merge pull request #2213 from bartonjs/DeriveBytes1956
Properly reset HashAlgorithm objects using OpenSSL.
2 parents 2c4cac4 + 9ff8bc0 commit 02a6f1c

File tree

6 files changed

+63
-4
lines changed

6 files changed

+63
-4
lines changed

src/Common/src/Interop/OSX/libcrypto/Interop.HMAC.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ internal static unsafe int HMAC_Init(out HMAC_CTX ctx, byte* key, int key_len, I
2020
return Success;
2121
}
2222

23+
internal static int HMAC_Init_ex(ref HMAC_CTX ctx, byte[] key, int key_len, IntPtr md, IntPtr zero)
24+
{
25+
HMAC_Init_exNative(ref ctx, key, key_len, md, zero);
26+
return Success;
27+
}
28+
2329
internal static unsafe int HMAC_Update(ref HMAC_CTX ctx, byte* data, int len)
2430
{
2531
HMAC_UpdateNative(ref ctx, data, len);
@@ -35,6 +41,9 @@ internal static unsafe int HMAC_Final(ref HMAC_CTX ctx, byte* md, ref uint len)
3541
[DllImport(Libraries.LibCrypto, EntryPoint = "HMAC_Init", ExactSpelling = true)]
3642
private extern static unsafe int HMAC_InitNative(out HMAC_CTX ctx, byte* key, int key_len, IntPtr md);
3743

44+
[DllImport(Libraries.LibCrypto, EntryPoint = "HMAC_Init_ex", ExactSpelling = true)]
45+
private extern static void HMAC_Init_exNative(ref HMAC_CTX ctx, byte[] key, int key_len, IntPtr md, IntPtr zero);
46+
3847
[DllImport(Libraries.LibCrypto, EntryPoint = "HMAC_Update", ExactSpelling = true)]
3948
private extern static unsafe int HMAC_UpdateNative(ref HMAC_CTX ctx, byte* data, int len);
4049

src/Common/src/Interop/Unix/libcrypto/Interop.HMAC.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ internal static partial class libcrypto
1111
[DllImport(Libraries.LibCrypto)]
1212
internal extern static unsafe int HMAC_Init(out HMAC_CTX ctx, byte* key, int key_len, IntPtr md);
1313

14+
[DllImport(Libraries.LibCrypto)]
15+
internal extern static int HMAC_Init_ex(ref HMAC_CTX ctx, byte[] key, int key_len, IntPtr md, IntPtr zero);
16+
1417
[DllImport(Libraries.LibCrypto)]
1518
internal extern static unsafe int HMAC_Update(ref HMAC_CTX ctx, byte* data, int len);
1619

src/System.Security.Cryptography.DeriveBytes/tests/Rfc2898Tests.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,6 @@ public static void GetBytes_StreamLike()
207207
}
208208

209209
[Fact]
210-
[ActiveIssue(1956, PlatformID.AnyUnix)]
211210
public static void GetBytes_KnownValues_1()
212211
{
213212
TestKnownValue(
@@ -224,7 +223,6 @@ public static void GetBytes_KnownValues_1()
224223
}
225224

226225
[Fact]
227-
[ActiveIssue(1956, PlatformID.AnyUnix)]
228226
public static void GetBytes_KnownValues_2()
229227
{
230228
TestKnownValue(
@@ -241,7 +239,6 @@ public static void GetBytes_KnownValues_2()
241239
}
242240

243241
[Fact]
244-
[ActiveIssue(1956, PlatformID.AnyUnix)]
245242
public static void GetBytes_KnownValues_3()
246243
{
247244
TestKnownValue(
@@ -258,7 +255,6 @@ public static void GetBytes_KnownValues_3()
258255
}
259256

260257
[Fact]
261-
[ActiveIssue(1956, PlatformID.AnyUnix)]
262258
public static void GetBytes_KnownValues_4()
263259
{
264260
TestKnownValue(

src/System.Security.Cryptography.Hashing.Algorithms/src/Internal/Cryptography/HashProviderDispenser.Unix.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,13 @@ public static unsafe HashProvider CreateMacProvider(string hashAlgorithmId, byte
5353

5454
private sealed class EvpHashProvider : HashProvider
5555
{
56+
private readonly IntPtr _algorithmEvp;
5657
private readonly int _hashSize;
5758
private readonly SafeEvpMdCtxHandle _ctx;
5859

5960
public EvpHashProvider(IntPtr algorithmEvp)
6061
{
62+
_algorithmEvp = algorithmEvp;
6163
Debug.Assert(algorithmEvp != IntPtr.Zero);
6264

6365
_hashSize = Interop.libcrypto.EVP_MD_size(algorithmEvp);
@@ -90,6 +92,9 @@ public sealed override unsafe byte[] FinalizeHashAndReset()
9092
Check(Interop.libcrypto.EVP_DigestFinal_ex(_ctx, md, ref length));
9193
Debug.Assert(length == _hashSize);
9294

95+
// Reset the algorithm provider.
96+
Check(Interop.libcrypto.EVP_DigestInit_ex(_ctx, _algorithmEvp, IntPtr.Zero));
97+
9398
byte[] result = new byte[(int)length];
9499
Marshal.Copy((IntPtr)md, result, 0, (int)length);
95100
return result;
@@ -146,6 +151,10 @@ public sealed override unsafe byte[] FinalizeHashAndReset()
146151
Check(Interop.libcrypto.HMAC_Final(ref _hmacCtx, md, ref length));
147152
Debug.Assert(length == _hashSize);
148153

154+
// HMAC_Init_ex with all NULL values keeps the key and algorithm (and engine) intact,
155+
// but resets the values for another computation.
156+
Check(Interop.libcrypto.HMAC_Init_ex(ref _hmacCtx, null, 0, IntPtr.Zero, IntPtr.Zero));
157+
149158
byte[] result = new byte[(int)length];
150159
Marshal.Copy((IntPtr)md, result, 0, (int)length);
151160
return result;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System.Collections.Generic;
5+
using Xunit;
6+
7+
namespace System.Security.Cryptography.Hashing.Algorithms.Tests
8+
{
9+
public class ReusabilityTests
10+
{
11+
[Theory]
12+
[MemberData("ReusabilityHashAlgorithms")]
13+
public void TestReusability(HashAlgorithm hashAlgorithm)
14+
{
15+
using (hashAlgorithm)
16+
{
17+
byte[] input = { 8, 6, 7, 5, 3, 0, 9, };
18+
byte[] hash1 = hashAlgorithm.ComputeHash(input);
19+
byte[] hash2 = hashAlgorithm.ComputeHash(input);
20+
21+
Assert.Equal(hash1, hash2);
22+
}
23+
}
24+
25+
public static IEnumerable<object[]> ReusabilityHashAlgorithms()
26+
{
27+
return new[]
28+
{
29+
new object[] { MD5.Create(), },
30+
new object[] { SHA1.Create(), },
31+
new object[] { SHA256.Create(), },
32+
new object[] { SHA384.Create(), },
33+
new object[] { SHA512.Create(), },
34+
new object[] { new HMACSHA1(), },
35+
new object[] { new HMACSHA256(), },
36+
new object[] { new HMACSHA384(), },
37+
new object[] { new HMACSHA512(), },
38+
};
39+
}
40+
}
41+
}

src/System.Security.Cryptography.Hashing.Algorithms/tests/System.Security.Cryptography.Hashing.Algorithms.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
<Compile Include="HmacSha512Tests.cs" />
3030
<Compile Include="HmacTests.cs" />
3131
<Compile Include="MD5Tests.cs" />
32+
<Compile Include="ReusabilityTests.cs" />
3233
<Compile Include="Rfc2202HmacTests.cs" />
3334
<Compile Include="Rfc4231HmacTests.cs" />
3435
<Compile Include="Sha1Tests.cs" />

0 commit comments

Comments
 (0)