Code cleanup

Rename IAuthenticatedEncryptor2 -> IOptimizedAuthenticatedEncryptor
Rename ProtectedMemoryBlob -> Secret
Add some missing doc comments explaining
This commit is contained in:
Levi B 2015-02-20 11:36:12 -08:00
parent 71a2712c5a
commit 8ec6dc3712
35 changed files with 200 additions and 109 deletions

View File

@ -12,7 +12,7 @@ namespace Microsoft.AspNet.Security.DataProtection.AuthenticatedEncryption
public static byte[] Encrypt(this IAuthenticatedEncryptor encryptor, ArraySegment<byte> plaintext, ArraySegment<byte> additionalAuthenticatedData, uint preBufferSize, uint postBufferSize) public static byte[] Encrypt(this IAuthenticatedEncryptor encryptor, ArraySegment<byte> plaintext, ArraySegment<byte> additionalAuthenticatedData, uint preBufferSize, uint postBufferSize)
{ {
// Can we call the optimized version? // Can we call the optimized version?
IAuthenticatedEncryptor2 optimizedEncryptor = encryptor as IAuthenticatedEncryptor2; IOptimizedAuthenticatedEncryptor optimizedEncryptor = encryptor as IOptimizedAuthenticatedEncryptor;
if (optimizedEncryptor != null) if (optimizedEncryptor != null)
{ {
return optimizedEncryptor.Encrypt(plaintext, additionalAuthenticatedData, preBufferSize, postBufferSize); return optimizedEncryptor.Encrypt(plaintext, additionalAuthenticatedData, preBufferSize, postBufferSize);

View File

@ -23,7 +23,7 @@ namespace Microsoft.AspNet.Security.DataProtection.AuthenticatedEncryption
{ {
// generate a 512-bit secret randomly // generate a 512-bit secret randomly
const int KDK_SIZE_IN_BYTES = 512 / 8; const int KDK_SIZE_IN_BYTES = 512 / 8;
var secret = ProtectedMemoryBlob.Random(KDK_SIZE_IN_BYTES); var secret = Secret.Random(KDK_SIZE_IN_BYTES);
return new CngCbcAuthenticatedEncryptorConfiguration(_options, secret); return new CngCbcAuthenticatedEncryptorConfiguration(_options, secret);
} }
} }

View File

@ -96,7 +96,7 @@ namespace Microsoft.AspNet.Security.DataProtection.AuthenticatedEncryption
// and we're good to go! // and we're good to go!
return new CbcAuthenticatedEncryptor( return new CbcAuthenticatedEncryptor(
keyDerivationKey: new ProtectedMemoryBlob(secret), keyDerivationKey: new Secret(secret),
symmetricAlgorithmHandle: encryptionAlgorithmHandle, symmetricAlgorithmHandle: encryptionAlgorithmHandle,
symmetricAlgorithmKeySizeInBytes: encryptionAlgorithmKeySizeInBits / 8, symmetricAlgorithmKeySizeInBytes: encryptionAlgorithmKeySizeInBits / 8,
hmacAlgorithmHandle: hashAlgorithmHandle); hmacAlgorithmHandle: hashAlgorithmHandle);

View File

@ -58,8 +58,8 @@ namespace Microsoft.AspNet.Security.DataProtection.AuthenticatedEncryption
byte[] decryptedSecretBytes = Convert.FromBase64String((string)decryptedSecretElement); byte[] decryptedSecretBytes = Convert.FromBase64String((string)decryptedSecretElement);
try try
{ {
var protectedMemoryBlob = new ProtectedMemoryBlob(decryptedSecretBytes); var secret = new Secret(decryptedSecretBytes);
return new CngCbcAuthenticatedEncryptorConfiguration(options, protectedMemoryBlob); return new CngCbcAuthenticatedEncryptorConfiguration(options, secret);
} }
finally finally
{ {

View File

@ -23,7 +23,7 @@ namespace Microsoft.AspNet.Security.DataProtection.AuthenticatedEncryption
{ {
// generate a 512-bit secret randomly // generate a 512-bit secret randomly
const int KDK_SIZE_IN_BYTES = 512 / 8; const int KDK_SIZE_IN_BYTES = 512 / 8;
var secret = ProtectedMemoryBlob.Random(KDK_SIZE_IN_BYTES); var secret = Secret.Random(KDK_SIZE_IN_BYTES);
return new CngGcmAuthenticatedEncryptorConfiguration(_options, secret); return new CngGcmAuthenticatedEncryptorConfiguration(_options, secret);
} }
} }

View File

@ -67,7 +67,7 @@ namespace Microsoft.AspNet.Security.DataProtection.AuthenticatedEncryption
// and we're good to go! // and we're good to go!
return new GcmAuthenticatedEncryptor( return new GcmAuthenticatedEncryptor(
keyDerivationKey: new ProtectedMemoryBlob(secret), keyDerivationKey: new Secret(secret),
symmetricAlgorithmHandle: encryptionAlgorithmHandle, symmetricAlgorithmHandle: encryptionAlgorithmHandle,
symmetricAlgorithmKeySizeInBytes: encryptionAlgorithmKeySizeInBits / 8); symmetricAlgorithmKeySizeInBytes: encryptionAlgorithmKeySizeInBits / 8);
} }

View File

@ -52,8 +52,8 @@ namespace Microsoft.AspNet.Security.DataProtection.AuthenticatedEncryption
byte[] decryptedSecretBytes = Convert.FromBase64String((string)decryptedSecretElement); byte[] decryptedSecretBytes = Convert.FromBase64String((string)decryptedSecretElement);
try try
{ {
var protectedMemoryBlob = new ProtectedMemoryBlob(decryptedSecretBytes); var secret = new Secret(decryptedSecretBytes);
return new CngGcmAuthenticatedEncryptorConfiguration(options, protectedMemoryBlob); return new CngGcmAuthenticatedEncryptorConfiguration(options, secret);
} }
finally finally
{ {

View File

@ -1,12 +0,0 @@
// 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;
namespace Microsoft.AspNet.Security.DataProtection.AuthenticatedEncryption
{
internal interface IAuthenticatedEncryptor2 : IAuthenticatedEncryptor
{
byte[] Encrypt(ArraySegment<byte> plaintext, ArraySegment<byte> additionalAuthenticatedData, uint preBufferSize, uint postBufferSize);
}
}

View File

@ -0,0 +1,35 @@
// 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;
namespace Microsoft.AspNet.Security.DataProtection.AuthenticatedEncryption
{
/// <summary>
/// An optimized encryptor that can avoid buffer allocations in common code paths.
/// </summary>
internal interface IOptimizedAuthenticatedEncryptor : IAuthenticatedEncryptor
{
/// <summary>
/// Encrypts and tamper-proofs a piece of data.
/// </summary>
/// <param name="plaintext">The plaintext to encrypt. This input may be zero bytes in length.</param>
/// <param name="additionalAuthenticatedData">A piece of data which will not be included in
/// the returned ciphertext but which will still be covered by the authentication tag.
/// This input may be zero bytes in length. The same AAD must be specified in the corresponding
/// call to Decrypt.</param>
/// <param name="preBufferSize">The number of bytes to include before the ciphertext in the return value.</param>
/// <param name="postBufferSize">The number of bytes to include after the ciphertext in the return value.</param>
/// <returns>
/// A buffer containing the ciphertext and authentication tag.
/// If a non-zero pre-buffer or post-buffer size is specified, the returned buffer will contain appropriate padding
/// on either side of the ciphertext and authentication tag. For instance, if a pre-buffer size of 4 and a post-buffer
/// size of 7 are specified, and if the ciphertext and tag are a combined 48 bytes, then the returned buffer will
/// be a total 59 bytes in length. The first four bytes will be undefined, the next 48 bytes will contain the
/// ciphertext and tag, and the last seven bytes will be undefined. The intent is that the caller can overwrite the
/// pre-buffer or post-buffer with a header or footer without needing to allocate an additional buffer object.
/// </returns>
/// <remarks>All cryptography-related exceptions should be homogenized to CryptographicException.</remarks>
byte[] Encrypt(ArraySegment<byte> plaintext, ArraySegment<byte> additionalAuthenticatedData, uint preBufferSize, uint postBufferSize);
}
}

View File

@ -21,10 +21,10 @@ namespace Microsoft.AspNet.Security.DataProtection.AuthenticatedEncryption
// generate a 512-bit secret randomly // generate a 512-bit secret randomly
const int KDK_SIZE_IN_BYTES = 512 / 8; const int KDK_SIZE_IN_BYTES = 512 / 8;
byte[] kdk = ManagedGenRandomImpl.Instance.GenRandom(KDK_SIZE_IN_BYTES); byte[] kdk = ManagedGenRandomImpl.Instance.GenRandom(KDK_SIZE_IN_BYTES);
ProtectedMemoryBlob secret; Secret secret;
try try
{ {
secret = new ProtectedMemoryBlob(kdk); secret = new Secret(kdk);
} }
finally finally
{ {

View File

@ -70,7 +70,7 @@ namespace Microsoft.AspNet.Security.DataProtection.AuthenticatedEncryption
// We're good to go! // We're good to go!
return new ManagedAuthenticatedEncryptor( return new ManagedAuthenticatedEncryptor(
keyDerivationKey: new ProtectedMemoryBlob(secret), keyDerivationKey: new Secret(secret),
symmetricAlgorithmFactory: encryptorFactory, symmetricAlgorithmFactory: encryptorFactory,
symmetricAlgorithmKeySizeInBytes: keySizeInBytes, symmetricAlgorithmKeySizeInBytes: keySizeInBytes,
validationAlgorithmFactory: validatorFactory); validationAlgorithmFactory: validatorFactory);

View File

@ -56,8 +56,8 @@ namespace Microsoft.AspNet.Security.DataProtection.AuthenticatedEncryption
byte[] decryptedSecretBytes = Convert.FromBase64String((string)decryptedSecretElement); byte[] decryptedSecretBytes = Convert.FromBase64String((string)decryptedSecretElement);
try try
{ {
var protectedMemoryBlob = new ProtectedMemoryBlob(decryptedSecretBytes); var secret = new Secret(decryptedSecretBytes);
return new ManagedAuthenticatedEncryptorConfiguration(options, protectedMemoryBlob); return new ManagedAuthenticatedEncryptorConfiguration(options, secret);
} }
finally finally
{ {

View File

@ -21,6 +21,20 @@ namespace Microsoft.AspNet.Security.DataProtection
bytePtr[3] = (byte)(value); bytePtr[3] = (byte)(value);
} }
/// <summary>
/// Writes an unsigned 32-bit value to a memory address, big-endian.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteTo(ref byte* ptr, uint value)
{
byte* pTemp = ptr;
pTemp[0] = (byte)(value >> 24);
pTemp[1] = (byte)(value >> 16);
pTemp[2] = (byte)(value >> 8);
pTemp[3] = (byte)(value);
ptr = &pTemp[4];
}
/// <summary> /// <summary>
/// Writes a signed 32-bit value to a memory address, big-endian. /// Writes a signed 32-bit value to a memory address, big-endian.
/// </summary> /// </summary>

View File

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Security.Cryptography;
using Microsoft.AspNet.Security.DataProtection.SafeHandles; using Microsoft.AspNet.Security.DataProtection.SafeHandles;
using Microsoft.AspNet.Security.DataProtection.SP800_108; using Microsoft.AspNet.Security.DataProtection.SP800_108;
@ -41,7 +40,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Cng
private readonly uint _symmetricAlgorithmBlockSizeInBytes; private readonly uint _symmetricAlgorithmBlockSizeInBytes;
private readonly uint _symmetricAlgorithmSubkeyLengthInBytes; private readonly uint _symmetricAlgorithmSubkeyLengthInBytes;
public CbcAuthenticatedEncryptor(ProtectedMemoryBlob keyDerivationKey, BCryptAlgorithmHandle symmetricAlgorithmHandle, uint symmetricAlgorithmKeySizeInBytes, BCryptAlgorithmHandle hmacAlgorithmHandle, IBCryptGenRandom genRandom = null) public CbcAuthenticatedEncryptor(Secret keyDerivationKey, BCryptAlgorithmHandle symmetricAlgorithmHandle, uint symmetricAlgorithmKeySizeInBytes, BCryptAlgorithmHandle hmacAlgorithmHandle, IBCryptGenRandom genRandom = null)
{ {
CryptoUtil.Assert(KEY_MODIFIER_SIZE_IN_BYTES <= symmetricAlgorithmKeySizeInBytes && symmetricAlgorithmKeySizeInBytes <= Constants.MAX_STACKALLOC_BYTES, CryptoUtil.Assert(KEY_MODIFIER_SIZE_IN_BYTES <= symmetricAlgorithmKeySizeInBytes && symmetricAlgorithmKeySizeInBytes <= Constants.MAX_STACKALLOC_BYTES,
"KEY_MODIFIER_SIZE_IN_BYTES <= symmetricAlgorithmKeySizeInBytes && symmetricAlgorithmKeySizeInBytes <= Constants.MAX_STACKALLOC_BYTES"); "KEY_MODIFIER_SIZE_IN_BYTES <= symmetricAlgorithmKeySizeInBytes && symmetricAlgorithmKeySizeInBytes <= Constants.MAX_STACKALLOC_BYTES");
@ -88,16 +87,12 @@ namespace Microsoft.AspNet.Security.DataProtection.Cng
*(ptr++) = 0; // 0x00 = CBC encryption + HMAC authentication *(ptr++) = 0; // 0x00 = CBC encryption + HMAC authentication
// Next is information about the symmetric algorithm (key size followed by block size) // Next is information about the symmetric algorithm (key size followed by block size)
BitHelpers.WriteTo(ptr, _symmetricAlgorithmSubkeyLengthInBytes); BitHelpers.WriteTo(ref ptr, _symmetricAlgorithmSubkeyLengthInBytes);
ptr += sizeof(uint); BitHelpers.WriteTo(ref ptr, _symmetricAlgorithmBlockSizeInBytes);
BitHelpers.WriteTo(ptr, _symmetricAlgorithmBlockSizeInBytes);
ptr += sizeof(uint);
// Next is information about the HMAC algorithm (key size followed by digest size) // Next is information about the HMAC algorithm (key size followed by digest size)
BitHelpers.WriteTo(ptr, _hmacAlgorithmSubkeyLengthInBytes); BitHelpers.WriteTo(ref ptr, _hmacAlgorithmSubkeyLengthInBytes);
ptr += sizeof(uint); BitHelpers.WriteTo(ref ptr, _hmacAlgorithmDigestLengthInBytes);
BitHelpers.WriteTo(ptr, _hmacAlgorithmDigestLengthInBytes);
ptr += sizeof(uint);
// See the design document for an explanation of the following code. // See the design document for an explanation of the following code.
byte[] tempKeys = new byte[_symmetricAlgorithmSubkeyLengthInBytes + _hmacAlgorithmSubkeyLengthInBytes]; byte[] tempKeys = new byte[_symmetricAlgorithmSubkeyLengthInBytes + _hmacAlgorithmSubkeyLengthInBytes];
@ -348,7 +343,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Cng
using (var symmetricKeyHandle = _symmetricAlgorithmHandle.GenerateSymmetricKey(pbSymmetricEncryptionSubkey, _symmetricAlgorithmSubkeyLengthInBytes)) using (var symmetricKeyHandle = _symmetricAlgorithmHandle.GenerateSymmetricKey(pbSymmetricEncryptionSubkey, _symmetricAlgorithmSubkeyLengthInBytes))
{ {
// We can't assume PKCS#7 padding (maybe the underlying provided is using CTS), // We can't assume PKCS#7 padding (maybe the underlying provider is really using CTS),
// so we need to query the padded output size before we can allocate the return value array. // so we need to query the padded output size before we can allocate the return value array.
uint cbOutputCiphertext = GetCbcEncryptedOutputSizeWithPadding(symmetricKeyHandle, pbPlaintext, cbPlaintext); uint cbOutputCiphertext = GetCbcEncryptedOutputSizeWithPadding(symmetricKeyHandle, pbPlaintext, cbPlaintext);

View File

@ -2,12 +2,14 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Security.Cryptography;
using Microsoft.AspNet.Security.DataProtection.AuthenticatedEncryption; using Microsoft.AspNet.Security.DataProtection.AuthenticatedEncryption;
namespace Microsoft.AspNet.Security.DataProtection.Cng namespace Microsoft.AspNet.Security.DataProtection.Cng
{ {
internal unsafe abstract class CngAuthenticatedEncryptorBase : IAuthenticatedEncryptor, IDisposable /// <summary>
/// Base class used for all CNG-related authentication encryption operations.
/// </summary>
internal unsafe abstract class CngAuthenticatedEncryptorBase : IOptimizedAuthenticatedEncryptor, IDisposable
{ {
public byte[] Decrypt(ArraySegment<byte> ciphertext, ArraySegment<byte> additionalAuthenticatedData) public byte[] Decrypt(ArraySegment<byte> ciphertext, ArraySegment<byte> additionalAuthenticatedData)
{ {
@ -30,7 +32,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Cng
pbAdditionalAuthenticatedData: (pbAdditionalAuthenticatedDataArray != null) ? &pbAdditionalAuthenticatedDataArray[additionalAuthenticatedData.Offset] : &dummy, pbAdditionalAuthenticatedData: (pbAdditionalAuthenticatedDataArray != null) ? &pbAdditionalAuthenticatedDataArray[additionalAuthenticatedData.Offset] : &dummy,
cbAdditionalAuthenticatedData: (uint)additionalAuthenticatedData.Count); cbAdditionalAuthenticatedData: (uint)additionalAuthenticatedData.Count);
} }
catch (Exception ex) when (!(ex is CryptographicException)) catch (Exception ex) when (ex.RequiresHomogenization())
{ {
// Homogenize to CryptographicException. // Homogenize to CryptographicException.
throw Error.CryptCommon_GenericError(ex); throw Error.CryptCommon_GenericError(ex);
@ -71,7 +73,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Cng
cbPreBuffer: preBufferSize, cbPreBuffer: preBufferSize,
cbPostBuffer: postBufferSize); cbPostBuffer: postBufferSize);
} }
catch (Exception ex) when (!(ex is CryptographicException)) catch (Exception ex) when (ex.RequiresHomogenization())
{ {
// Homogenize to CryptographicException. // Homogenize to CryptographicException.
throw Error.CryptCommon_GenericError(ex); throw Error.CryptCommon_GenericError(ex);

View File

@ -172,7 +172,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Cng
} }
} }
public static ProtectedMemoryBlob UnprotectWithDpapi(byte[] protectedSecret) public static Secret UnprotectWithDpapi(byte[] protectedSecret)
{ {
Debug.Assert(protectedSecret != null); Debug.Assert(protectedSecret != null);
@ -185,7 +185,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Cng
} }
} }
internal static ProtectedMemoryBlob UnprotectWithDpapiImpl(byte* pbProtectedData, uint cbProtectedData, byte* pbOptionalEntropy, uint cbOptionalEntropy) internal static Secret UnprotectWithDpapiImpl(byte* pbProtectedData, uint cbProtectedData, byte* pbOptionalEntropy, uint cbOptionalEntropy)
{ {
byte dummy; // provides a valid memory address if the secret or entropy has zero length byte dummy; // provides a valid memory address if the secret or entropy has zero length
@ -220,7 +220,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Cng
throw new CryptographicException(errorCode); throw new CryptographicException(errorCode);
} }
return new ProtectedMemoryBlob(dataOut.pbData, checked((int)dataOut.cbData)); return new Secret(dataOut.pbData, checked((int)dataOut.cbData));
} }
finally finally
{ {
@ -234,7 +234,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Cng
} }
} }
public static ProtectedMemoryBlob UnprotectWithDpapiNG(byte[] protectedData) public static Secret UnprotectWithDpapiNG(byte[] protectedData)
{ {
Debug.Assert(protectedData != null); Debug.Assert(protectedData != null);
@ -247,7 +247,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Cng
} }
} }
private static ProtectedMemoryBlob UnprotectWithDpapiNGImpl(byte* pbData, uint cbData) private static Secret UnprotectWithDpapiNGImpl(byte* pbData, uint cbData)
{ {
Debug.Assert(pbData != null); Debug.Assert(pbData != null);
@ -280,7 +280,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Cng
try try
{ {
unencryptedPayloadHandle.DangerousAddRef(ref handleAcquired); unencryptedPayloadHandle.DangerousAddRef(ref handleAcquired);
return new ProtectedMemoryBlob((byte*)unencryptedPayloadHandle.DangerousGetHandle(), checked((int)cbUnencryptedPayload)); return new Secret((byte*)unencryptedPayloadHandle.DangerousGetHandle(), checked((int)cbUnencryptedPayload));
} }
finally finally
{ {

View File

@ -35,7 +35,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Cng
private readonly BCryptAlgorithmHandle _symmetricAlgorithmHandle; private readonly BCryptAlgorithmHandle _symmetricAlgorithmHandle;
private readonly uint _symmetricAlgorithmSubkeyLengthInBytes; private readonly uint _symmetricAlgorithmSubkeyLengthInBytes;
public GcmAuthenticatedEncryptor(ProtectedMemoryBlob keyDerivationKey, BCryptAlgorithmHandle symmetricAlgorithmHandle, uint symmetricAlgorithmKeySizeInBytes, IBCryptGenRandom genRandom = null) public GcmAuthenticatedEncryptor(Secret keyDerivationKey, BCryptAlgorithmHandle symmetricAlgorithmHandle, uint symmetricAlgorithmKeySizeInBytes, IBCryptGenRandom genRandom = null)
{ {
CryptoUtil.Assert(KEY_MODIFIER_SIZE_IN_BYTES <= symmetricAlgorithmKeySizeInBytes && symmetricAlgorithmKeySizeInBytes <= Constants.MAX_STACKALLOC_BYTES, CryptoUtil.Assert(KEY_MODIFIER_SIZE_IN_BYTES <= symmetricAlgorithmKeySizeInBytes && symmetricAlgorithmKeySizeInBytes <= Constants.MAX_STACKALLOC_BYTES,
"KEY_MODIFIER_SIZE_IN_BYTES <= symmetricAlgorithmKeySizeInBytes && symmetricAlgorithmKeySizeInBytes <= Constants.MAX_STACKALLOC_BYTES"); "KEY_MODIFIER_SIZE_IN_BYTES <= symmetricAlgorithmKeySizeInBytes && symmetricAlgorithmKeySizeInBytes <= Constants.MAX_STACKALLOC_BYTES");
@ -67,14 +67,10 @@ namespace Microsoft.AspNet.Security.DataProtection.Cng
*(ptr++) = 1; // 0x01 = GCM encryption + authentication *(ptr++) = 1; // 0x01 = GCM encryption + authentication
// Next is information about the symmetric algorithm (key size, nonce size, block size, tag size) // Next is information about the symmetric algorithm (key size, nonce size, block size, tag size)
BitHelpers.WriteTo(ptr, _symmetricAlgorithmSubkeyLengthInBytes); BitHelpers.WriteTo(ref ptr, _symmetricAlgorithmSubkeyLengthInBytes);
ptr += sizeof(uint); BitHelpers.WriteTo(ref ptr, NONCE_SIZE_IN_BYTES);
BitHelpers.WriteTo(ptr, NONCE_SIZE_IN_BYTES); BitHelpers.WriteTo(ref ptr, TAG_SIZE_IN_BYTES); // block size = tag size
ptr += sizeof(uint); BitHelpers.WriteTo(ref ptr, TAG_SIZE_IN_BYTES);
BitHelpers.WriteTo(ptr, TAG_SIZE_IN_BYTES); // block size
ptr += sizeof(uint);
BitHelpers.WriteTo(ptr, TAG_SIZE_IN_BYTES);
ptr += sizeof(uint);
// See the design document for an explanation of the following code. // See the design document for an explanation of the following code.
byte[] tempKeys = new byte[_symmetricAlgorithmSubkeyLengthInBytes]; byte[] tempKeys = new byte[_symmetricAlgorithmSubkeyLengthInBytes];

View File

@ -48,6 +48,8 @@ namespace Microsoft.AspNet.Security.DataProtection
throw new CryptographicException("Assertion failed: " + message); throw new CryptographicException("Assertion failed: " + message);
} }
// Allows callers to write "var x = Method() ?? Fail<T>(message);" as a convenience to guard
// against a method returning null unexpectedly.
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
public static T Fail<T>(string message) where T : class public static T Fail<T>(string message) where T : class
{ {

View File

@ -36,7 +36,7 @@ namespace Microsoft.AspNet.Security.DataProtection
byte[] protectedDataAsBytes = protector.Protect(unprotectedDataAsBytes); byte[] protectedDataAsBytes = protector.Protect(unprotectedDataAsBytes);
return WebEncoders.Base64UrlEncode(protectedDataAsBytes); return WebEncoders.Base64UrlEncode(protectedDataAsBytes);
} }
catch (Exception ex) when (!(ex is CryptographicException)) catch (Exception ex) when (ex.RequiresHomogenization())
{ {
// Homogenize exceptions to CryptographicException // Homogenize exceptions to CryptographicException
throw Error.CryptCommon_GenericError(ex); throw Error.CryptCommon_GenericError(ex);
@ -60,7 +60,7 @@ namespace Microsoft.AspNet.Security.DataProtection
byte[] unprotectedDataAsBytes = protector.Unprotect(protectedDataAsBytes); byte[] unprotectedDataAsBytes = protector.Unprotect(protectedDataAsBytes);
return CryptoUtil.SecureUtf8Encoding.GetString(unprotectedDataAsBytes); return CryptoUtil.SecureUtf8Encoding.GetString(unprotectedDataAsBytes);
} }
catch (Exception ex) when (!(ex is CryptographicException)) catch (Exception ex) when (ex.RequiresHomogenization())
{ {
// Homogenize exceptions to CryptographicException // Homogenize exceptions to CryptographicException
throw Error.CryptCommon_GenericError(ex); throw Error.CryptCommon_GenericError(ex);

View File

@ -43,7 +43,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Dpapi
return _shim.Protect(unprotectedData, _combinedPurposes, _scope) return _shim.Protect(unprotectedData, _combinedPurposes, _scope)
?? CryptoUtil.Fail<byte[]>("Null return value."); ?? CryptoUtil.Fail<byte[]>("Null return value.");
} }
catch (Exception ex) when (!(ex is CryptographicException)) catch (Exception ex) when (ex.RequiresHomogenization())
{ {
// Homogenize to CryptographicException // Homogenize to CryptographicException
throw Error.CryptCommon_GenericError(ex); throw Error.CryptCommon_GenericError(ex);
@ -57,7 +57,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Dpapi
return _shim.Unprotect(protectedData, _combinedPurposes, _scope) return _shim.Unprotect(protectedData, _combinedPurposes, _scope)
?? CryptoUtil.Fail<byte[]>("Null return value."); ?? CryptoUtil.Fail<byte[]>("Null return value.");
} }
catch (Exception ex) when (!(ex is CryptographicException)) catch (Exception ex) when (ex.RequiresHomogenization())
{ {
// Homogenize to CryptographicException // Homogenize to CryptographicException
throw Error.CryptCommon_GenericError(ex); throw Error.CryptCommon_GenericError(ex);

View File

@ -32,7 +32,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Dpapi
public byte[] Unprotect(byte[] encryptedData, byte[] optionalEntropy, DataProtectionScope scope) public byte[] Unprotect(byte[] encryptedData, byte[] optionalEntropy, DataProtectionScope scope)
{ {
#if ASPNETCORE50 #if ASPNETCORE50
ProtectedMemoryBlob blob; Secret blob;
fixed (byte* pbEncryptedData = encryptedData) fixed (byte* pbEncryptedData = encryptedData)
{ {
fixed (byte* pbOptionalEntropy = optionalEntropy) fixed (byte* pbOptionalEntropy = optionalEntropy)

View File

@ -50,7 +50,7 @@ namespace Microsoft.AspNet.Security.DataProtection
// Currently hardcoded to a 512-bit KDK. // Currently hardcoded to a 512-bit KDK.
private const int NUM_BYTES_IN_KDK = 512 / 8; private const int NUM_BYTES_IN_KDK = 512 / 8;
public IAuthenticatedEncryptor DefaultAuthenticatedEncryptor { get; } = new T().CreateAuthenticatedEncryptor(ProtectedMemoryBlob.Random(NUM_BYTES_IN_KDK)); public IAuthenticatedEncryptor DefaultAuthenticatedEncryptor { get; } = new T().CreateAuthenticatedEncryptor(Secret.Random(NUM_BYTES_IN_KDK));
public Guid DefaultKeyId { get; } = default(Guid); public Guid DefaultKeyId { get; } = default(Guid);

View File

@ -0,0 +1,20 @@
// 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.Security.Cryptography;
namespace Microsoft.AspNet.Security.DataProtection
{
internal static class ExceptionExtensions
{
/// <summary>
/// Determines whether an exception must be homogenized by being wrapped inside a
/// CryptographicException before being rethrown.
/// </summary>
public static bool RequiresHomogenization(this Exception ex)
{
return !(ex is CryptographicException);
}
}
}

View File

@ -11,7 +11,7 @@ namespace Microsoft.AspNet.Security.DataProtection
public interface ISecret : IDisposable public interface ISecret : IDisposable
{ {
/// <summary> /// <summary>
/// The length (in bytes) of the value. /// The length (in bytes) of the secret value.
/// </summary> /// </summary>
int Length { get; } int Length { get; }

View File

@ -131,7 +131,7 @@ namespace Microsoft.AspNet.Security.DataProtection.KeyManagement
postBufferSize: 0); postBufferSize: 0);
CryptoUtil.Assert(retVal != null && retVal.Length >= sizeof(uint) + sizeof(Guid), "retVal != null && retVal.Length >= sizeof(uint) + sizeof(Guid)"); CryptoUtil.Assert(retVal != null && retVal.Length >= sizeof(uint) + sizeof(Guid), "retVal != null && retVal.Length >= sizeof(uint) + sizeof(Guid)");
} }
catch (Exception ex) when (!(ex is CryptographicException)) catch (Exception ex) when (ex.RequiresHomogenization())
{ {
// homogenize all errors to CryptographicException // homogenize all errors to CryptographicException
throw Error.Common_EncryptionFailed(ex); throw Error.Common_EncryptionFailed(ex);
@ -247,7 +247,7 @@ namespace Microsoft.AspNet.Security.DataProtection.KeyManagement
CryptoUtil.Assert(retVal != null, "retVal != null"); CryptoUtil.Assert(retVal != null, "retVal != null");
return retVal; return retVal;
} }
catch (Exception ex) when (!(ex is CryptographicException)) catch (Exception ex) when (ex.RequiresHomogenization())
{ {
// homogenize all failures to CryptographicException // homogenize all failures to CryptographicException
throw Error.DecryptionFailed(ex); throw Error.DecryptionFailed(ex);

View File

@ -111,7 +111,7 @@ namespace Microsoft.AspNet.Security.DataProtection.KeyManagement
var thisKey = ParseKeyElement(element); var thisKey = ParseKeyElement(element);
if (idToKeyMap.ContainsKey(thisKey.KeyId)) if (idToKeyMap.ContainsKey(thisKey.KeyId))
{ {
CryptoUtil.Fail("TODO: Duplicate key."); throw CryptoUtil.Fail("TODO: Duplicate key.");
} }
idToKeyMap.Add(thisKey.KeyId, thisKey); idToKeyMap.Add(thisKey.KeyId, thisKey);
} }
@ -140,7 +140,7 @@ namespace Microsoft.AspNet.Security.DataProtection.KeyManagement
} }
else else
{ {
CryptoUtil.Fail("TODO: Unknown element."); throw CryptoUtil.Fail("TODO: Unknown element.");
} }
} }

View File

@ -36,7 +36,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Managed
private readonly byte[] _contextHeader; private readonly byte[] _contextHeader;
private readonly IManagedGenRandom _genRandom; private readonly IManagedGenRandom _genRandom;
private readonly ProtectedMemoryBlob _keyDerivationKey; private readonly Secret _keyDerivationKey;
private readonly Func<SymmetricAlgorithm> _symmetricAlgorithmFactory; private readonly Func<SymmetricAlgorithm> _symmetricAlgorithmFactory;
private readonly int _symmetricAlgorithmBlockSizeInBytes; private readonly int _symmetricAlgorithmBlockSizeInBytes;
private readonly int _symmetricAlgorithmSubkeyLengthInBytes; private readonly int _symmetricAlgorithmSubkeyLengthInBytes;
@ -44,7 +44,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Managed
private readonly int _validationAlgorithmSubkeyLengthInBytes; private readonly int _validationAlgorithmSubkeyLengthInBytes;
private readonly Func<KeyedHashAlgorithm> _validationAlgorithmFactory; private readonly Func<KeyedHashAlgorithm> _validationAlgorithmFactory;
public ManagedAuthenticatedEncryptor(ProtectedMemoryBlob keyDerivationKey, Func<SymmetricAlgorithm> symmetricAlgorithmFactory, int symmetricAlgorithmKeySizeInBytes, Func<KeyedHashAlgorithm> validationAlgorithmFactory, IManagedGenRandom genRandom = null) public ManagedAuthenticatedEncryptor(Secret keyDerivationKey, Func<SymmetricAlgorithm> symmetricAlgorithmFactory, int symmetricAlgorithmKeySizeInBytes, Func<KeyedHashAlgorithm> validationAlgorithmFactory, IManagedGenRandom genRandom = null)
{ {
CryptoUtil.Assert(KEY_MODIFIER_SIZE_IN_BYTES <= symmetricAlgorithmKeySizeInBytes && symmetricAlgorithmKeySizeInBytes <= Constants.MAX_STACKALLOC_BYTES, CryptoUtil.Assert(KEY_MODIFIER_SIZE_IN_BYTES <= symmetricAlgorithmKeySizeInBytes && symmetricAlgorithmKeySizeInBytes <= Constants.MAX_STACKALLOC_BYTES,
"KEY_MODIFIER_SIZE_IN_BYTES <= symmetricAlgorithmKeySizeInBytes && symmetricAlgorithmKeySizeInBytes <= Constants.MAX_STACKALLOC_BYTES"); "KEY_MODIFIER_SIZE_IN_BYTES <= symmetricAlgorithmKeySizeInBytes && symmetricAlgorithmKeySizeInBytes <= Constants.MAX_STACKALLOC_BYTES");
@ -278,7 +278,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Managed
} }
} }
} }
catch (Exception ex) when (!(ex is CryptographicException)) catch (Exception ex) when (ex.RequiresHomogenization())
{ {
// Homogenize all exceptions to CryptographicException. // Homogenize all exceptions to CryptographicException.
throw Error.CryptCommon_GenericError(ex); throw Error.CryptCommon_GenericError(ex);
@ -382,7 +382,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Managed
} }
} }
} }
catch (Exception ex) when (!(ex is CryptographicException)) catch (Exception ex) when (ex.RequiresHomogenization())
{ {
// Homogenize all exceptions to CryptographicException. // Homogenize all exceptions to CryptographicException.
throw Error.CryptCommon_GenericError(ex); throw Error.CryptCommon_GenericError(ex);

View File

@ -36,7 +36,7 @@ namespace Microsoft.AspNet.Security.DataProtection.SP800_108
} }
// Creates a provider from the given secret. // Creates a provider from the given secret.
public static ISP800_108_CTR_HMACSHA512Provider CreateProvider(ProtectedMemoryBlob kdk) public static ISP800_108_CTR_HMACSHA512Provider CreateProvider(Secret kdk)
{ {
uint secretLengthInBytes = checked((uint)kdk.Length); uint secretLengthInBytes = checked((uint)kdk.Length);
if (secretLengthInBytes == 0) if (secretLengthInBytes == 0)

View File

@ -8,7 +8,10 @@ using Microsoft.AspNet.Security.DataProtection.SafeHandles;
namespace Microsoft.AspNet.Security.DataProtection namespace Microsoft.AspNet.Security.DataProtection
{ {
public unsafe sealed class ProtectedMemoryBlob : IDisposable, ISecret /// <summary>
/// Represents a secret value stored in memory.
/// </summary>
public unsafe sealed class Secret : IDisposable, ISecret
{ {
// from wincrypt.h // from wincrypt.h
private const uint CRYPTPROTECTMEMORY_BLOCK_SIZE = 16; private const uint CRYPTPROTECTMEMORY_BLOCK_SIZE = 16;
@ -16,42 +19,57 @@ namespace Microsoft.AspNet.Security.DataProtection
private readonly SecureLocalAllocHandle _localAllocHandle; private readonly SecureLocalAllocHandle _localAllocHandle;
private readonly uint _plaintextLength; private readonly uint _plaintextLength;
public ProtectedMemoryBlob(ArraySegment<byte> plaintext) /// <summary>
/// Creates a new Secret from the provided input value, where the input value
/// is specified as an array segment.
/// </summary>
public Secret(ArraySegment<byte> value)
{ {
plaintext.Validate(); value.Validate();
_localAllocHandle = Protect(plaintext); _localAllocHandle = Protect(value);
_plaintextLength = (uint)plaintext.Count; _plaintextLength = (uint)value.Count;
} }
public ProtectedMemoryBlob(byte[] plaintext) /// <summary>
: this(new ArraySegment<byte>(plaintext)) /// Creates a new Secret from the provided input value, where the input value
/// is specified as an array.
/// </summary>
public Secret(byte[] value)
: this(new ArraySegment<byte>(value))
{ {
} }
public ProtectedMemoryBlob(byte* plaintext, int plaintextLength) /// <summary>
/// Creates a new Secret from the provided input value, where the input value
/// is specified as a pointer to unmanaged memory.
/// </summary>
public Secret(byte* secret, int secretLength)
{ {
if (plaintext == null) if (secret == null)
{ {
throw new ArgumentNullException("plaintext"); throw new ArgumentNullException("secret");
} }
if (plaintextLength < 0) if (secretLength < 0)
{ {
throw new ArgumentOutOfRangeException("plaintextLength"); throw new ArgumentOutOfRangeException("secretLength");
} }
_localAllocHandle = Protect(plaintext, (uint)plaintextLength); _localAllocHandle = Protect(secret, (uint)secretLength);
_plaintextLength = (uint)plaintextLength; _plaintextLength = (uint)secretLength;
} }
public ProtectedMemoryBlob(ISecret secret) /// <summary>
/// Creates a new Secret from another secret object.
/// </summary>
public Secret(ISecret secret)
{ {
if (secret == null) if (secret == null)
{ {
throw new ArgumentNullException("secret"); throw new ArgumentNullException("secret");
} }
ProtectedMemoryBlob other = secret as ProtectedMemoryBlob; Secret other = secret as Secret;
if (other != null) if (other != null)
{ {
// Fast-track: simple deep copy scenario. // Fast-track: simple deep copy scenario.
@ -79,6 +97,9 @@ namespace Microsoft.AspNet.Security.DataProtection
} }
} }
/// <summary>
/// The length (in bytes) of the secret value.
/// </summary>
public int Length public int Length
{ {
get get
@ -87,6 +108,9 @@ namespace Microsoft.AspNet.Security.DataProtection
} }
} }
/// <summary>
/// Wipes the secret from memory.
/// </summary>
public void Dispose() public void Dispose()
{ {
_localAllocHandle.Dispose(); _localAllocHandle.Dispose();
@ -134,21 +158,25 @@ namespace Microsoft.AspNet.Security.DataProtection
return encryptedMemoryHandle; return encryptedMemoryHandle;
} }
public static ProtectedMemoryBlob Random(int numBytes) /// <summary>
/// Returns a Secret comprised entirely of random bytes retrieved from
/// a cryptographically secure RNG.
/// </summary>
public static Secret Random(int numBytes)
{ {
CryptoUtil.Assert(numBytes >= 0, "numBytes >= 0"); CryptoUtil.Assert(numBytes >= 0, "numBytes >= 0");
if (numBytes == 0) if (numBytes == 0)
{ {
byte dummy; byte dummy;
return new ProtectedMemoryBlob(&dummy, 0); return new Secret(&dummy, 0);
} }
else else
{ {
// Don't use CNG if we're not on Windows. // Don't use CNG if we're not on Windows.
if (!OSVersionUtil.IsBCryptOnWin7OrLaterAvailable()) if (!OSVersionUtil.IsBCryptOnWin7OrLaterAvailable())
{ {
return new ProtectedMemoryBlob(ManagedGenRandomImpl.Instance.GenRandom(numBytes)); return new Secret(ManagedGenRandomImpl.Instance.GenRandom(numBytes));
} }
byte[] bytes = new byte[numBytes]; byte[] bytes = new byte[numBytes];
@ -157,7 +185,7 @@ namespace Microsoft.AspNet.Security.DataProtection
try try
{ {
BCryptUtil.GenRandom(pbBytes, (uint)numBytes); BCryptUtil.GenRandom(pbBytes, (uint)numBytes);
return new ProtectedMemoryBlob(pbBytes, numBytes); return new Secret(pbBytes, numBytes);
} }
finally finally
{ {
@ -196,6 +224,12 @@ namespace Microsoft.AspNet.Security.DataProtection
} }
} }
/// <summary>
/// Writes the secret value to the specified buffer.
/// </summary>
/// <remarks>
/// The buffer size must exactly match the length of the secret value.
/// </remarks>
public void WriteSecretIntoBuffer(ArraySegment<byte> buffer) public void WriteSecretIntoBuffer(ArraySegment<byte> buffer)
{ {
// Parameter checking // Parameter checking
@ -215,6 +249,12 @@ namespace Microsoft.AspNet.Security.DataProtection
} }
} }
/// <summary>
/// Writes the secret value to the specified buffer.
/// </summary>
/// <remarks>
/// The 'bufferLength' parameter must exactly match the length of the secret value.
/// </remarks>
public void WriteSecretIntoBuffer(byte* buffer, int bufferLength) public void WriteSecretIntoBuffer(byte* buffer, int bufferLength)
{ {
if (buffer == null) if (buffer == null)

View File

@ -86,7 +86,7 @@ namespace Microsoft.AspNet.Security.DataProtection
expiration = new DateTimeOffset((long)utcTicksExpiration, TimeSpan.Zero); expiration = new DateTimeOffset((long)utcTicksExpiration, TimeSpan.Zero);
return retVal; return retVal;
} }
catch (Exception ex) when (!(ex is CryptographicException)) catch (Exception ex) when (ex.RequiresHomogenization())
{ {
// Homogenize all failures to CryptographicException // Homogenize all failures to CryptographicException
throw Error.CryptCommon_GenericError(ex); throw Error.CryptCommon_GenericError(ex);

View File

@ -46,20 +46,19 @@ namespace Microsoft.AspNet.Security.DataProtection.XmlEncryption
public XElement Encrypt([NotNull] XElement plaintextElement) public XElement Encrypt([NotNull] XElement plaintextElement)
{ {
// First, convert the XML element to a byte[] so that it can be encrypted. // First, convert the XML element to a byte[] so that it can be encrypted.
ProtectedMemoryBlob secret; Secret secret;
using (var memoryStream = new MemoryStream()) using (var memoryStream = new MemoryStream())
{ {
plaintextElement.Save(memoryStream); plaintextElement.Save(memoryStream);
#if !ASPNETCORE50 #if !ASPNETCORE50
// If we're on full desktop CLR, utilize the underlying buffer directly as an optimization. // If we're on full desktop CLR, utilize the underlying buffer directly as an optimization.
byte[] underlyingBuffer = memoryStream.GetBuffer(); byte[] underlyingBuffer = memoryStream.GetBuffer();
secret = new ProtectedMemoryBlob(new ArraySegment<byte>(underlyingBuffer, 0, checked((int)memoryStream.Length))); secret = new Secret(new ArraySegment<byte>(underlyingBuffer, 0, checked((int)memoryStream.Length)));
Array.Clear(underlyingBuffer, 0, underlyingBuffer.Length); Array.Clear(underlyingBuffer, 0, underlyingBuffer.Length);
#else #else
// Otherwise, need to make a copy of the buffer. // Otherwise, need to make a copy of the buffer.
byte[] clonedBuffer = memoryStream.ToArray(); byte[] clonedBuffer = memoryStream.ToArray();
secret = new ProtectedMemoryBlob(clonedBuffer); secret = new Secret(clonedBuffer);
Array.Clear(clonedBuffer, 0, clonedBuffer.Length); Array.Clear(clonedBuffer, 0, clonedBuffer.Length);
#endif #endif
} }

View File

@ -31,7 +31,7 @@ namespace Microsoft.AspNet.Security.DataProtection.XmlEncryption
public XElement Encrypt([NotNull] XElement plaintextElement) public XElement Encrypt([NotNull] XElement plaintextElement)
{ {
// First, convert the XML element to a byte[] so that it can be encrypted. // First, convert the XML element to a byte[] so that it can be encrypted.
ProtectedMemoryBlob secret; Secret secret;
using (var memoryStream = new MemoryStream()) using (var memoryStream = new MemoryStream())
{ {
plaintextElement.Save(memoryStream); plaintextElement.Save(memoryStream);
@ -39,12 +39,12 @@ namespace Microsoft.AspNet.Security.DataProtection.XmlEncryption
#if !ASPNETCORE50 #if !ASPNETCORE50
// If we're on full desktop CLR, utilize the underlying buffer directly as an optimization. // If we're on full desktop CLR, utilize the underlying buffer directly as an optimization.
byte[] underlyingBuffer = memoryStream.GetBuffer(); byte[] underlyingBuffer = memoryStream.GetBuffer();
secret = new ProtectedMemoryBlob(new ArraySegment<byte>(underlyingBuffer, 0, checked((int)memoryStream.Length))); secret = new Secret(new ArraySegment<byte>(underlyingBuffer, 0, checked((int)memoryStream.Length)));
Array.Clear(underlyingBuffer, 0, underlyingBuffer.Length); Array.Clear(underlyingBuffer, 0, underlyingBuffer.Length);
#else #else
// Otherwise, need to make a copy of the buffer. // Otherwise, need to make a copy of the buffer.
byte[] clonedBuffer = memoryStream.ToArray(); byte[] clonedBuffer = memoryStream.ToArray();
secret = new ProtectedMemoryBlob(clonedBuffer); secret = new Secret(clonedBuffer);
Array.Clear(clonedBuffer, 0, clonedBuffer.Length); Array.Clear(clonedBuffer, 0, clonedBuffer.Length);
#endif #endif
} }

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.Cng
public void Encrypt_Decrypt_RoundTrips() public void Encrypt_Decrypt_RoundTrips()
{ {
// Arrange // Arrange
ProtectedMemoryBlob kdk = new ProtectedMemoryBlob(new byte[512 / 8]); Secret kdk = new Secret(new byte[512 / 8]);
CbcAuthenticatedEncryptor encryptor = new CbcAuthenticatedEncryptor(kdk, CbcAuthenticatedEncryptor encryptor = new CbcAuthenticatedEncryptor(kdk,
symmetricAlgorithmHandle: CachedAlgorithmHandles.AES_CBC, symmetricAlgorithmHandle: CachedAlgorithmHandles.AES_CBC,
symmetricAlgorithmKeySizeInBytes: 256 / 8, symmetricAlgorithmKeySizeInBytes: 256 / 8,
@ -39,7 +39,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.Cng
public void Encrypt_Decrypt_Tampering_Fails() public void Encrypt_Decrypt_Tampering_Fails()
{ {
// Arrange // Arrange
ProtectedMemoryBlob kdk = new ProtectedMemoryBlob(new byte[512 / 8]); Secret kdk = new Secret(new byte[512 / 8]);
CbcAuthenticatedEncryptor encryptor = new CbcAuthenticatedEncryptor(kdk, CbcAuthenticatedEncryptor encryptor = new CbcAuthenticatedEncryptor(kdk,
symmetricAlgorithmHandle: CachedAlgorithmHandles.AES_CBC, symmetricAlgorithmHandle: CachedAlgorithmHandles.AES_CBC,
symmetricAlgorithmKeySizeInBytes: 256 / 8, symmetricAlgorithmKeySizeInBytes: 256 / 8,
@ -86,7 +86,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.Cng
public void Encrypt_KnownKey() public void Encrypt_KnownKey()
{ {
// Arrange // Arrange
ProtectedMemoryBlob kdk = new ProtectedMemoryBlob(Encoding.UTF8.GetBytes("master key")); Secret kdk = new Secret(Encoding.UTF8.GetBytes("master key"));
CbcAuthenticatedEncryptor encryptor = new CbcAuthenticatedEncryptor(kdk, CbcAuthenticatedEncryptor encryptor = new CbcAuthenticatedEncryptor(kdk,
symmetricAlgorithmHandle: CachedAlgorithmHandles.AES_CBC, symmetricAlgorithmHandle: CachedAlgorithmHandles.AES_CBC,
symmetricAlgorithmKeySizeInBytes: 256 / 8, symmetricAlgorithmKeySizeInBytes: 256 / 8,

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.Cng
public void Encrypt_Decrypt_RoundTrips() public void Encrypt_Decrypt_RoundTrips()
{ {
// Arrange // Arrange
ProtectedMemoryBlob kdk = new ProtectedMemoryBlob(new byte[512 / 8]); Secret kdk = new Secret(new byte[512 / 8]);
GcmAuthenticatedEncryptor encryptor = new GcmAuthenticatedEncryptor(kdk, CachedAlgorithmHandles.AES_GCM, symmetricAlgorithmKeySizeInBytes: 256 / 8); GcmAuthenticatedEncryptor encryptor = new GcmAuthenticatedEncryptor(kdk, CachedAlgorithmHandles.AES_GCM, symmetricAlgorithmKeySizeInBytes: 256 / 8);
ArraySegment<byte> plaintext = new ArraySegment<byte>(Encoding.UTF8.GetBytes("plaintext")); ArraySegment<byte> plaintext = new ArraySegment<byte>(Encoding.UTF8.GetBytes("plaintext"));
ArraySegment<byte> aad = new ArraySegment<byte>(Encoding.UTF8.GetBytes("aad")); ArraySegment<byte> aad = new ArraySegment<byte>(Encoding.UTF8.GetBytes("aad"));
@ -36,7 +36,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.Cng
public void Encrypt_Decrypt_Tampering_Fails() public void Encrypt_Decrypt_Tampering_Fails()
{ {
// Arrange // Arrange
ProtectedMemoryBlob kdk = new ProtectedMemoryBlob(new byte[512 / 8]); Secret kdk = new Secret(new byte[512 / 8]);
GcmAuthenticatedEncryptor encryptor = new GcmAuthenticatedEncryptor(kdk, CachedAlgorithmHandles.AES_GCM, symmetricAlgorithmKeySizeInBytes: 256 / 8); GcmAuthenticatedEncryptor encryptor = new GcmAuthenticatedEncryptor(kdk, CachedAlgorithmHandles.AES_GCM, symmetricAlgorithmKeySizeInBytes: 256 / 8);
ArraySegment<byte> plaintext = new ArraySegment<byte>(Encoding.UTF8.GetBytes("plaintext")); ArraySegment<byte> plaintext = new ArraySegment<byte>(Encoding.UTF8.GetBytes("plaintext"));
ArraySegment<byte> aad = new ArraySegment<byte>(Encoding.UTF8.GetBytes("aad")); ArraySegment<byte> aad = new ArraySegment<byte>(Encoding.UTF8.GetBytes("aad"));
@ -80,7 +80,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.Cng
public void Encrypt_KnownKey() public void Encrypt_KnownKey()
{ {
// Arrange // Arrange
ProtectedMemoryBlob kdk = new ProtectedMemoryBlob(Encoding.UTF8.GetBytes("master key")); Secret kdk = new Secret(Encoding.UTF8.GetBytes("master key"));
GcmAuthenticatedEncryptor encryptor = new GcmAuthenticatedEncryptor(kdk, CachedAlgorithmHandles.AES_GCM, symmetricAlgorithmKeySizeInBytes: 128 / 8, genRandom: new SequentialGenRandom()); GcmAuthenticatedEncryptor encryptor = new GcmAuthenticatedEncryptor(kdk, CachedAlgorithmHandles.AES_GCM, symmetricAlgorithmKeySizeInBytes: 128 / 8, genRandom: new SequentialGenRandom());
ArraySegment<byte> plaintext = new ArraySegment<byte>(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }, 2, 3); ArraySegment<byte> plaintext = new ArraySegment<byte>(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }, 2, 3);
ArraySegment<byte> aad = new ArraySegment<byte>(new byte[] { 7, 6, 5, 4, 3, 2, 1, 0 }, 1, 4); ArraySegment<byte> aad = new ArraySegment<byte>(new byte[] { 7, 6, 5, 4, 3, 2, 1, 0 }, 1, 4);

View File

@ -16,7 +16,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.Managed
public void Encrypt_Decrypt_RoundTrips() public void Encrypt_Decrypt_RoundTrips()
{ {
// Arrange // Arrange
ProtectedMemoryBlob kdk = new ProtectedMemoryBlob(new byte[512 / 8]); Secret kdk = new Secret(new byte[512 / 8]);
ManagedAuthenticatedEncryptor encryptor = new ManagedAuthenticatedEncryptor(kdk, ManagedAuthenticatedEncryptor encryptor = new ManagedAuthenticatedEncryptor(kdk,
symmetricAlgorithmFactory: Aes.Create, symmetricAlgorithmFactory: Aes.Create,
symmetricAlgorithmKeySizeInBytes: 256 / 8, symmetricAlgorithmKeySizeInBytes: 256 / 8,
@ -36,7 +36,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.Managed
public void Encrypt_Decrypt_Tampering_Fails() public void Encrypt_Decrypt_Tampering_Fails()
{ {
// Arrange // Arrange
ProtectedMemoryBlob kdk = new ProtectedMemoryBlob(new byte[512 / 8]); Secret kdk = new Secret(new byte[512 / 8]);
ManagedAuthenticatedEncryptor encryptor = new ManagedAuthenticatedEncryptor(kdk, ManagedAuthenticatedEncryptor encryptor = new ManagedAuthenticatedEncryptor(kdk,
symmetricAlgorithmFactory: Aes.Create, symmetricAlgorithmFactory: Aes.Create,
symmetricAlgorithmKeySizeInBytes: 256 / 8, symmetricAlgorithmKeySizeInBytes: 256 / 8,
@ -82,7 +82,7 @@ namespace Microsoft.AspNet.Security.DataProtection.Test.Managed
public void Encrypt_KnownKey() public void Encrypt_KnownKey()
{ {
// Arrange // Arrange
ProtectedMemoryBlob kdk = new ProtectedMemoryBlob(Encoding.UTF8.GetBytes("master key")); Secret kdk = new Secret(Encoding.UTF8.GetBytes("master key"));
ManagedAuthenticatedEncryptor encryptor = new ManagedAuthenticatedEncryptor(kdk, ManagedAuthenticatedEncryptor encryptor = new ManagedAuthenticatedEncryptor(kdk,
symmetricAlgorithmFactory: Aes.Create, symmetricAlgorithmFactory: Aes.Create,
symmetricAlgorithmKeySizeInBytes: 256 / 8, symmetricAlgorithmKeySizeInBytes: 256 / 8,