Conditionally run CNG tests only on supported platforms.

This commit is contained in:
Levi B 2014-12-18 12:05:20 -08:00
parent 47c870c871
commit e9c4a8c9de
7 changed files with 245 additions and 20 deletions

View File

@ -6,13 +6,15 @@ using System.Linq;
using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNet.Security.DataProtection.Cng;
using Microsoft.AspNet.Testing.xunit;
using Xunit;
namespace Microsoft.AspNet.Security.DataProtection.Test.Cng
{
public class CbcAuthenticatedEncryptorTests
{
[Fact]
[ConditionalFact]
[ConditionalRunTestOnlyIfBcryptAvailable]
public void Encrypt_Decrypt_RoundTrips()
{
// Arrange
@ -32,7 +34,8 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.Cng
Assert.Equal(plaintext, decipheredtext);
}
[Fact]
[ConditionalFact]
[ConditionalRunTestOnlyIfBcryptAvailable]
public void Encrypt_Decrypt_Tampering_Fails()
{
// Arrange
@ -78,7 +81,8 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.Cng
});
}
[Fact]
[ConditionalFact]
[ConditionalRunTestOnlyIfBcryptAvailable]
public void Encrypt_KnownKey()
{
// Arrange

View File

@ -3,6 +3,7 @@
using System;
using Microsoft.AspNet.Security.DataProtection.Cng;
using Microsoft.AspNet.Testing.xunit;
using Moq;
using Xunit;
@ -10,7 +11,8 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.Cng
{
public unsafe class CngAuthenticatedEncryptorBaseTests
{
[Fact]
[ConditionalFact]
[ConditionalRunTestOnlyIfBcryptAvailable]
public void Decrypt_ForwardsArraySegment()
{
// Arrange
@ -35,7 +37,8 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.Cng
Assert.Equal(new byte[] { 0x20, 0x21, 0x22 }, retVal);
}
[Fact]
[ConditionalFact]
[ConditionalRunTestOnlyIfBcryptAvailable]
public void Decrypt_HandlesEmptyAADPointerFixup()
{
// Arrange
@ -60,7 +63,8 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.Cng
Assert.Equal(new byte[] { 0x20, 0x21, 0x22 }, retVal);
}
[Fact]
[ConditionalFact]
[ConditionalRunTestOnlyIfBcryptAvailable]
public void Decrypt_HandlesEmptyCiphertextPointerFixup()
{
// Arrange

View File

@ -6,13 +6,15 @@ using System.Linq;
using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNet.Security.DataProtection.Cng;
using Microsoft.AspNet.Testing.xunit;
using Xunit;
namespace Microsoft.AspNet.Security.DataProtection.Test.Cng
{
public class GcmAuthenticatedEncryptorTests
{
[Fact]
[ConditionalFact]
[ConditionalRunTestOnlyIfBcryptAvailable]
public void Encrypt_Decrypt_RoundTrips()
{
// Arrange
@ -29,7 +31,8 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.Cng
Assert.Equal(plaintext, decipheredtext);
}
[Fact]
[ConditionalFact]
[ConditionalRunTestOnlyIfBcryptAvailable]
public void Encrypt_Decrypt_Tampering_Fails()
{
// Arrange
@ -72,7 +75,8 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.Cng
});
}
[Fact]
[ConditionalFact]
[ConditionalRunTestOnlyIfBcryptAvailable]
public void Encrypt_KnownKey()
{
// Arrange

View File

@ -0,0 +1,58 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Globalization;
using Microsoft.AspNet.Security.DataProtection.SafeHandles;
using Microsoft.AspNet.Testing.xunit;
namespace Microsoft.AspNet.Security.DataProtection.Test
{
public class ConditionalRunTestOnlyIfBcryptAvailableAttribute : Attribute, ITestCondition
{
private static readonly SafeLibraryHandle _bcryptLibHandle = GetBcryptLibHandle();
private readonly string _requiredExportFunction;
public ConditionalRunTestOnlyIfBcryptAvailableAttribute(string requiredExportFunction = null)
{
_requiredExportFunction = requiredExportFunction;
}
public bool IsMet
{
get
{
if (_bcryptLibHandle == null)
{
return false; // no bcrypt.dll available
}
return (_requiredExportFunction == null || _bcryptLibHandle.DoesProcExist(_requiredExportFunction));
}
}
public string SkipReason
{
get
{
return (_bcryptLibHandle != null)
? String.Format(CultureInfo.InvariantCulture, "Export {0} not found in bcrypt.dll", _requiredExportFunction)
: "bcrypt.dll not found on this platform.";
}
}
private static SafeLibraryHandle GetBcryptLibHandle()
{
try
{
return SafeLibraryHandle.Open("bcrypt.dll");
}
catch
{
// If we're not on an OS with BCRYPT.DLL, just bail.
return null;
}
}
}
}

View File

@ -4,6 +4,7 @@
using System;
using System.Text;
using Microsoft.AspNet.Security.DataProtection.PBKDF2;
using Microsoft.AspNet.Testing.xunit;
using Xunit;
namespace Microsoft.AspNet.Security.DataProtection.Test.PBKDF2
@ -23,7 +24,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.PBKDF2
[InlineData("my-password", KeyDerivationPrf.Sha512, 5, 512 / 8 - 1, "ZTallQJrFn0279xIzaiA1XqatVTGei+ZjKngA7bIMtKMDUw6YJeGUQpFG8iGTgN+ri3LNDktNbzwfcSyZmm9")]
[InlineData("my-password", KeyDerivationPrf.Sha512, 5, 512 / 8 + 0, "ZTallQJrFn0279xIzaiA1XqatVTGei+ZjKngA7bIMtKMDUw6YJeGUQpFG8iGTgN+ri3LNDktNbzwfcSyZmm90Q==")]
[InlineData("my-password", KeyDerivationPrf.Sha512, 5, 512 / 8 + 1, "ZTallQJrFn0279xIzaiA1XqatVTGei+ZjKngA7bIMtKMDUw6YJeGUQpFG8iGTgN+ri3LNDktNbzwfcSyZmm90Wk=")]
public void RunTest_Normal(string password, KeyDerivationPrf prf, int iterationCount, int numBytesRequested, string expectedValueAsBase64)
public void RunTest_Normal_Managed(string password, KeyDerivationPrf prf, int iterationCount, int numBytesRequested, string expectedValueAsBase64)
{
// Arrange
byte[] salt = new byte[256];
@ -32,14 +33,86 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.PBKDF2
salt[i] = (byte)i;
}
// Act & assert - fully managed, Win7, and Win8
// Act & assert
TestProvider<ManagedPbkdf2Provider>(password, salt, prf, iterationCount, numBytesRequested, expectedValueAsBase64);
}
// The 'numBytesRequested' parameters below are chosen to exercise code paths where
// this value straddles the digest length of the PRF. We only use 5 iterations so
// that our unit tests are fast.
[ConditionalTheory]
[ConditionalRunTestOnlyIfBcryptAvailable("BCryptDeriveKeyPBKDF2")]
[InlineData("my-password", KeyDerivationPrf.Sha1, 5, 160 / 8 - 1, "efmxNcKD/U1urTEDGvsThlPnHA==")]
[InlineData("my-password", KeyDerivationPrf.Sha1, 5, 160 / 8 + 0, "efmxNcKD/U1urTEDGvsThlPnHDI=")]
[InlineData("my-password", KeyDerivationPrf.Sha1, 5, 160 / 8 + 1, "efmxNcKD/U1urTEDGvsThlPnHDLk")]
[InlineData("my-password", KeyDerivationPrf.Sha256, 5, 256 / 8 - 1, "JRNz8bPKS02EG1vf7eWjA64IeeI+TI8gBEwb1oVvRA==")]
[InlineData("my-password", KeyDerivationPrf.Sha256, 5, 256 / 8 + 0, "JRNz8bPKS02EG1vf7eWjA64IeeI+TI8gBEwb1oVvRLo=")]
[InlineData("my-password", KeyDerivationPrf.Sha256, 5, 256 / 8 + 1, "JRNz8bPKS02EG1vf7eWjA64IeeI+TI8gBEwb1oVvRLpk")]
[InlineData("my-password", KeyDerivationPrf.Sha512, 5, 512 / 8 - 1, "ZTallQJrFn0279xIzaiA1XqatVTGei+ZjKngA7bIMtKMDUw6YJeGUQpFG8iGTgN+ri3LNDktNbzwfcSyZmm9")]
[InlineData("my-password", KeyDerivationPrf.Sha512, 5, 512 / 8 + 0, "ZTallQJrFn0279xIzaiA1XqatVTGei+ZjKngA7bIMtKMDUw6YJeGUQpFG8iGTgN+ri3LNDktNbzwfcSyZmm90Q==")]
[InlineData("my-password", KeyDerivationPrf.Sha512, 5, 512 / 8 + 1, "ZTallQJrFn0279xIzaiA1XqatVTGei+ZjKngA7bIMtKMDUw6YJeGUQpFG8iGTgN+ri3LNDktNbzwfcSyZmm90Wk=")]
public void RunTest_Normal_Win7(string password, KeyDerivationPrf prf, int iterationCount, int numBytesRequested, string expectedValueAsBase64)
{
// Arrange
byte[] salt = new byte[256];
for (int i = 0; i < salt.Length; i++)
{
salt[i] = (byte)i;
}
// Act & assert
TestProvider<Win7Pbkdf2Provider>(password, salt, prf, iterationCount, numBytesRequested, expectedValueAsBase64);
}
// The 'numBytesRequested' parameters below are chosen to exercise code paths where
// this value straddles the digest length of the PRF. We only use 5 iterations so
// that our unit tests are fast.
[ConditionalTheory]
[ConditionalRunTestOnlyIfBcryptAvailable("BCryptKeyDerivation")]
[InlineData("my-password", KeyDerivationPrf.Sha1, 5, 160 / 8 - 1, "efmxNcKD/U1urTEDGvsThlPnHA==")]
[InlineData("my-password", KeyDerivationPrf.Sha1, 5, 160 / 8 + 0, "efmxNcKD/U1urTEDGvsThlPnHDI=")]
[InlineData("my-password", KeyDerivationPrf.Sha1, 5, 160 / 8 + 1, "efmxNcKD/U1urTEDGvsThlPnHDLk")]
[InlineData("my-password", KeyDerivationPrf.Sha256, 5, 256 / 8 - 1, "JRNz8bPKS02EG1vf7eWjA64IeeI+TI8gBEwb1oVvRA==")]
[InlineData("my-password", KeyDerivationPrf.Sha256, 5, 256 / 8 + 0, "JRNz8bPKS02EG1vf7eWjA64IeeI+TI8gBEwb1oVvRLo=")]
[InlineData("my-password", KeyDerivationPrf.Sha256, 5, 256 / 8 + 1, "JRNz8bPKS02EG1vf7eWjA64IeeI+TI8gBEwb1oVvRLpk")]
[InlineData("my-password", KeyDerivationPrf.Sha512, 5, 512 / 8 - 1, "ZTallQJrFn0279xIzaiA1XqatVTGei+ZjKngA7bIMtKMDUw6YJeGUQpFG8iGTgN+ri3LNDktNbzwfcSyZmm9")]
[InlineData("my-password", KeyDerivationPrf.Sha512, 5, 512 / 8 + 0, "ZTallQJrFn0279xIzaiA1XqatVTGei+ZjKngA7bIMtKMDUw6YJeGUQpFG8iGTgN+ri3LNDktNbzwfcSyZmm90Q==")]
[InlineData("my-password", KeyDerivationPrf.Sha512, 5, 512 / 8 + 1, "ZTallQJrFn0279xIzaiA1XqatVTGei+ZjKngA7bIMtKMDUw6YJeGUQpFG8iGTgN+ri3LNDktNbzwfcSyZmm90Wk=")]
public void RunTest_Normal_Win8(string password, KeyDerivationPrf prf, int iterationCount, int numBytesRequested, string expectedValueAsBase64)
{
// Arrange
byte[] salt = new byte[256];
for (int i = 0; i < salt.Length; i++)
{
salt[i] = (byte)i;
}
// Act & assert
TestProvider<Win8Pbkdf2Provider>(password, salt, prf, iterationCount, numBytesRequested, expectedValueAsBase64);
}
[Fact]
public void RunTest_WithLongPassword()
public void RunTest_WithLongPassword_Managed()
{
RunTest_WithLongPassword_Impl<ManagedPbkdf2Provider>();
}
[ConditionalFact]
[ConditionalRunTestOnlyIfBcryptAvailable("BCryptDeriveKeyPBKDF2")]
public void RunTest_WithLongPassword_Win7()
{
RunTest_WithLongPassword_Impl<Win7Pbkdf2Provider>();
}
[ConditionalFact]
[ConditionalRunTestOnlyIfBcryptAvailable("BCryptKeyDerivation")]
public void RunTest_WithLongPassword_Win8()
{
RunTest_WithLongPassword_Impl<Win8Pbkdf2Provider>();
}
private static void RunTest_WithLongPassword_Impl<TProvider>()
where TProvider : IPbkdf2Provider, new()
{
// Arrange
string password = new String('x', 50000); // 50,000 char password
@ -49,10 +122,8 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.PBKDF2
const int iterationCount = 5;
const int numBytesRequested = 128;
// Act & assert - fully managed, Win7, and Win8
TestProvider<ManagedPbkdf2Provider>(password, salt, prf, iterationCount, numBytesRequested, expectedDerivedKeyBase64);
TestProvider<Win7Pbkdf2Provider>(password, salt, prf, iterationCount, numBytesRequested, expectedDerivedKeyBase64);
TestProvider<Win8Pbkdf2Provider>(password, salt, prf, iterationCount, numBytesRequested, expectedDerivedKeyBase64);
// Act & assert
TestProvider<TProvider>(password, salt, prf, iterationCount, numBytesRequested, expectedDerivedKeyBase64);
}
private static void TestProvider<TProvider>(string password, byte[] salt, KeyDerivationPrf prf, int iterationCount, int numBytesRequested, string expectedDerivedKeyAsBase64)

View File

@ -5,6 +5,7 @@ using System;
using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNet.Security.DataProtection.SP800_108;
using Microsoft.AspNet.Testing.xunit;
using Xunit;
namespace Microsoft.AspNet.Security.DataProtection.Test.SP800_108
@ -19,7 +20,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.SP800_108
[InlineData(512 / 8 - 1, "V47WmHzPSkdC2vkLAomIjCzZlDOAetll3yJLcSvon7LJFjJpEN+KnSNp+gIpeydKMsENkflbrIZ/3s6GkEaH")]
[InlineData(512 / 8 + 0, "mVaFM4deXLl610CmnCteNzxgbM/VkmKznAlPauHcDBn0le06uOjAKLHx0LfoU2/Ttq9nd78Y6Nk6wArmdwJgJg==")]
[InlineData(512 / 8 + 1, "GaHPeqdUxriFpjRtkYQYWr5/iqneD/+hPhVJQt4rXblxSpB1UUqGqL00DMU/FJkX0iMCfqUjQXtXyfks+p++Ev4=")]
public void DeriveKeyWithContextHeader_Normal(int numDerivedBytes, string expectedDerivedSubkeyAsBase64)
public void DeriveKeyWithContextHeader_Normal_Managed(int numDerivedBytes, string expectedDerivedSubkeyAsBase64)
{
// Arrange
byte[] kdk = Encoding.UTF8.GetBytes("kdk");
@ -27,9 +28,45 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.SP800_108
byte[] contextHeader = Encoding.UTF8.GetBytes("contextHeader");
byte[] context = Encoding.UTF8.GetBytes("context");
// Act & assert - managed, Win7, Win8
// Act & assert
TestManagedKeyDerivation(kdk, label, contextHeader, context, numDerivedBytes, expectedDerivedSubkeyAsBase64);
}
// The 'numBytesRequested' parameters below are chosen to exercise code paths where
// this value straddles the digest length of the PRF (which is hardcoded to HMACSHA512).
[ConditionalTheory]
[ConditionalRunTestOnlyIfBcryptAvailable]
[InlineData(512 / 8 - 1, "V47WmHzPSkdC2vkLAomIjCzZlDOAetll3yJLcSvon7LJFjJpEN+KnSNp+gIpeydKMsENkflbrIZ/3s6GkEaH")]
[InlineData(512 / 8 + 0, "mVaFM4deXLl610CmnCteNzxgbM/VkmKznAlPauHcDBn0le06uOjAKLHx0LfoU2/Ttq9nd78Y6Nk6wArmdwJgJg==")]
[InlineData(512 / 8 + 1, "GaHPeqdUxriFpjRtkYQYWr5/iqneD/+hPhVJQt4rXblxSpB1UUqGqL00DMU/FJkX0iMCfqUjQXtXyfks+p++Ev4=")]
public void DeriveKeyWithContextHeader_Normal_Win7(int numDerivedBytes, string expectedDerivedSubkeyAsBase64)
{
// Arrange
byte[] kdk = Encoding.UTF8.GetBytes("kdk");
byte[] label = Encoding.UTF8.GetBytes("label");
byte[] contextHeader = Encoding.UTF8.GetBytes("contextHeader");
byte[] context = Encoding.UTF8.GetBytes("context");
// Act & assert
TestCngKeyDerivation((pbKdk, cbKdk) => new Win7SP800_108_CTR_HMACSHA512Provider(pbKdk, cbKdk), kdk, label, contextHeader, context, numDerivedBytes, expectedDerivedSubkeyAsBase64);
}
// The 'numBytesRequested' parameters below are chosen to exercise code paths where
// this value straddles the digest length of the PRF (which is hardcoded to HMACSHA512).
[ConditionalTheory]
[ConditionalRunTestOnlyIfBcryptAvailable("BCryptKeyDerivation")]
[InlineData(512 / 8 - 1, "V47WmHzPSkdC2vkLAomIjCzZlDOAetll3yJLcSvon7LJFjJpEN+KnSNp+gIpeydKMsENkflbrIZ/3s6GkEaH")]
[InlineData(512 / 8 + 0, "mVaFM4deXLl610CmnCteNzxgbM/VkmKznAlPauHcDBn0le06uOjAKLHx0LfoU2/Ttq9nd78Y6Nk6wArmdwJgJg==")]
[InlineData(512 / 8 + 1, "GaHPeqdUxriFpjRtkYQYWr5/iqneD/+hPhVJQt4rXblxSpB1UUqGqL00DMU/FJkX0iMCfqUjQXtXyfks+p++Ev4=")]
public void DeriveKeyWithContextHeader_Normal_Win8(int numDerivedBytes, string expectedDerivedSubkeyAsBase64)
{
// Arrange
byte[] kdk = Encoding.UTF8.GetBytes("kdk");
byte[] label = Encoding.UTF8.GetBytes("label");
byte[] contextHeader = Encoding.UTF8.GetBytes("contextHeader");
byte[] context = Encoding.UTF8.GetBytes("context");
// Act & assert
TestCngKeyDerivation((pbKdk, cbKdk) => new Win8SP800_108_CTR_HMACSHA512Provider(pbKdk, cbKdk), kdk, label, contextHeader, context, numDerivedBytes, expectedDerivedSubkeyAsBase64);
}
@ -39,7 +76,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.SP800_108
[InlineData(512 / 8 - 1, "rt2hM6kkQ8hAXmkHx0TU4o3Q+S7fie6b3S1LAq107k++P9v8uSYA2G+WX3pJf9ZkpYrTKD7WUIoLkgA1R9lk")]
[InlineData(512 / 8 + 0, "RKiXmHSrWq5gkiRSyNZWNJrMR0jDyYHJMt9odOayRAE5wLSX2caINpQmfzTH7voJQi3tbn5MmD//dcspghfBiw==")]
[InlineData(512 / 8 + 1, "KedXO0zAIZ3AfnPqY1NnXxpC3HDHIxefG4bwD3g6nWYEc5+q7pjbam71Yqj0zgHMNC9Z7BX3wS1/tajFocRWZUk=")]
public void DeriveKeyWithContextHeader_LongKey(int numDerivedBytes, string expectedDerivedSubkeyAsBase64)
public void DeriveKeyWithContextHeader_LongKey_Managed(int numDerivedBytes, string expectedDerivedSubkeyAsBase64)
{
// Arrange
byte[] kdk = new byte[50000]; // CNG can't normally handle a 50,000 byte KDK, but we coerce it into working :)
@ -52,9 +89,55 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.SP800_108
byte[] contextHeader = Encoding.UTF8.GetBytes("contextHeader");
byte[] context = Encoding.UTF8.GetBytes("context");
// Act & assert - managed, Win7, Win8
// Act & assert
TestManagedKeyDerivation(kdk, label, contextHeader, context, numDerivedBytes, expectedDerivedSubkeyAsBase64);
}
// The 'numBytesRequested' parameters below are chosen to exercise code paths where
// this value straddles the digest length of the PRF (which is hardcoded to HMACSHA512).
[ConditionalTheory]
[ConditionalRunTestOnlyIfBcryptAvailable]
[InlineData(512 / 8 - 1, "rt2hM6kkQ8hAXmkHx0TU4o3Q+S7fie6b3S1LAq107k++P9v8uSYA2G+WX3pJf9ZkpYrTKD7WUIoLkgA1R9lk")]
[InlineData(512 / 8 + 0, "RKiXmHSrWq5gkiRSyNZWNJrMR0jDyYHJMt9odOayRAE5wLSX2caINpQmfzTH7voJQi3tbn5MmD//dcspghfBiw==")]
[InlineData(512 / 8 + 1, "KedXO0zAIZ3AfnPqY1NnXxpC3HDHIxefG4bwD3g6nWYEc5+q7pjbam71Yqj0zgHMNC9Z7BX3wS1/tajFocRWZUk=")]
public void DeriveKeyWithContextHeader_LongKey_Win7(int numDerivedBytes, string expectedDerivedSubkeyAsBase64)
{
// Arrange
byte[] kdk = new byte[50000]; // CNG can't normally handle a 50,000 byte KDK, but we coerce it into working :)
for (int i = 0; i < kdk.Length; i++)
{
kdk[i] = (byte)i;
}
byte[] label = Encoding.UTF8.GetBytes("label");
byte[] contextHeader = Encoding.UTF8.GetBytes("contextHeader");
byte[] context = Encoding.UTF8.GetBytes("context");
// Act & assert
TestCngKeyDerivation((pbKdk, cbKdk) => new Win7SP800_108_CTR_HMACSHA512Provider(pbKdk, cbKdk), kdk, label, contextHeader, context, numDerivedBytes, expectedDerivedSubkeyAsBase64);
}
// The 'numBytesRequested' parameters below are chosen to exercise code paths where
// this value straddles the digest length of the PRF (which is hardcoded to HMACSHA512).
[ConditionalTheory]
[ConditionalRunTestOnlyIfBcryptAvailable("BCryptKeyDerivation")]
[InlineData(512 / 8 - 1, "rt2hM6kkQ8hAXmkHx0TU4o3Q+S7fie6b3S1LAq107k++P9v8uSYA2G+WX3pJf9ZkpYrTKD7WUIoLkgA1R9lk")]
[InlineData(512 / 8 + 0, "RKiXmHSrWq5gkiRSyNZWNJrMR0jDyYHJMt9odOayRAE5wLSX2caINpQmfzTH7voJQi3tbn5MmD//dcspghfBiw==")]
[InlineData(512 / 8 + 1, "KedXO0zAIZ3AfnPqY1NnXxpC3HDHIxefG4bwD3g6nWYEc5+q7pjbam71Yqj0zgHMNC9Z7BX3wS1/tajFocRWZUk=")]
public void DeriveKeyWithContextHeader_LongKey_Win8(int numDerivedBytes, string expectedDerivedSubkeyAsBase64)
{
// Arrange
byte[] kdk = new byte[50000]; // CNG can't normally handle a 50,000 byte KDK, but we coerce it into working :)
for (int i = 0; i < kdk.Length; i++)
{
kdk[i] = (byte)i;
}
byte[] label = Encoding.UTF8.GetBytes("label");
byte[] contextHeader = Encoding.UTF8.GetBytes("contextHeader");
byte[] context = Encoding.UTF8.GetBytes("context");
// Act & assert
TestCngKeyDerivation((pbKdk, cbKdk) => new Win8SP800_108_CTR_HMACSHA512Provider(pbKdk, cbKdk), kdk, label, contextHeader, context, numDerivedBytes, expectedDerivedSubkeyAsBase64);
}

View File

@ -1,6 +1,7 @@
{
"dependencies": {
"Microsoft.AspNet.Security.DataProtection": "1.0.0-*",
"Microsoft.AspNet.Testing": "1.0.0-*",
"Moq": "4.2.1312.1622",
"xunit.runner.kre": "1.0.0-*"
},