diff --git a/src/DataProtection/Cryptography.Internal/src/CryptoUtil.cs b/src/DataProtection/Cryptography.Internal/src/CryptoUtil.cs index 9fad4bdc46fb..b51699912e0d 100644 --- a/src/DataProtection/Cryptography.Internal/src/CryptoUtil.cs +++ b/src/DataProtection/Cryptography.Internal/src/CryptoUtil.cs @@ -76,12 +76,19 @@ public static T Fail(string message) where T : class #endif public static bool TimeConstantBuffersAreEqual(byte* bufA, byte* bufB, uint count) { +#if NETCOREAPP + var byteCount = Convert.ToInt32(count); + var bytesA = new ReadOnlySpan(bufA, byteCount); + var bytesB = new ReadOnlySpan(bufB, byteCount); + return CryptographicOperations.FixedTimeEquals(bytesA, bytesB); +#else bool areEqual = true; for (uint i = 0; i < count; i++) { areEqual &= (bufA[i] == bufB[i]); } return areEqual; +#endif } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] @@ -91,12 +98,21 @@ public static bool TimeConstantBuffersAreEqual(byte[] bufA, int offsetA, int cou // An error at the call site isn't usable for timing attacks. Assert(countA == countB, "countA == countB"); +#if NETCOREAPP + unsafe + { + return CryptographicOperations.FixedTimeEquals( + bufA.AsSpan(start: offsetA, length: countA), + bufB.AsSpan(start: offsetB, length: countB)); + } +#else bool areEqual = true; for (int i = 0; i < countA; i++) { areEqual &= (bufA[offsetA + i] == bufB[offsetB + i]); } return areEqual; +#endif } } } diff --git a/src/DataProtection/DataProtection/src/AuthenticatedEncryption/AuthenticatedEncryptorFactory.cs b/src/DataProtection/DataProtection/src/AuthenticatedEncryption/AuthenticatedEncryptorFactory.cs index 151074ed205e..64d7712a638d 100644 --- a/src/DataProtection/DataProtection/src/AuthenticatedEncryption/AuthenticatedEncryptorFactory.cs +++ b/src/DataProtection/DataProtection/src/AuthenticatedEncryption/AuthenticatedEncryptorFactory.cs @@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Cryptography.Cng; using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel; using Microsoft.AspNetCore.DataProtection.KeyManagement; +using Microsoft.AspNetCore.DataProtection.Managed; using Microsoft.Extensions.Logging; namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption @@ -54,6 +55,9 @@ public AuthenticatedEncryptorFactory(ILoggerFactory loggerFactory) if (IsGcmAlgorithm(authenticatedConfiguration.EncryptionAlgorithm)) { +#if NETCOREAPP + return new AesGcmAuthenticatedEncryptor(secret, GetAlgorithmKeySizeInBits(authenticatedConfiguration.EncryptionAlgorithm) / 8); +#else // GCM requires CNG, and CNG is only supported on Windows. if (!OSVersionUtil.IsWindows()) { @@ -69,6 +73,7 @@ public AuthenticatedEncryptorFactory(ILoggerFactory loggerFactory) }; return new CngGcmAuthenticatedEncryptorFactory(_loggerFactory).CreateAuthenticatedEncryptorInstance(secret, configuration); +#endif } else { diff --git a/src/DataProtection/DataProtection/src/AuthenticatedEncryption/CngGcmAuthenticatedEncryptorFactory.cs b/src/DataProtection/DataProtection/src/AuthenticatedEncryption/CngGcmAuthenticatedEncryptorFactory.cs index f666b074c24d..ef291eaf708d 100644 --- a/src/DataProtection/DataProtection/src/AuthenticatedEncryption/CngGcmAuthenticatedEncryptorFactory.cs +++ b/src/DataProtection/DataProtection/src/AuthenticatedEncryption/CngGcmAuthenticatedEncryptorFactory.cs @@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption { /// - /// An for . + /// An for . /// public sealed class CngGcmAuthenticatedEncryptorFactory : IAuthenticatedEncryptorFactory { @@ -48,7 +48,7 @@ public CngGcmAuthenticatedEncryptorFactory(ILoggerFactory loggerFactory) [SupportedOSPlatform("windows")] [return: NotNullIfNotNull("configuration")] - internal GcmAuthenticatedEncryptor? CreateAuthenticatedEncryptorInstance( + internal CngGcmAuthenticatedEncryptor? CreateAuthenticatedEncryptorInstance( ISecret secret, CngGcmAuthenticatedEncryptorConfiguration configuration) { @@ -57,7 +57,7 @@ public CngGcmAuthenticatedEncryptorFactory(ILoggerFactory loggerFactory) return null; } - return new GcmAuthenticatedEncryptor( + return new CngGcmAuthenticatedEncryptor( keyDerivationKey: new Secret(secret), symmetricAlgorithmHandle: GetSymmetricBlockCipherAlgorithmHandle(configuration), symmetricAlgorithmKeySizeInBytes: (uint)(configuration.EncryptionAlgorithmKeySize / 8)); diff --git a/src/DataProtection/DataProtection/src/Cng/GcmAuthenticatedEncryptor.cs b/src/DataProtection/DataProtection/src/Cng/CngGcmAuthenticatedEncryptor.cs similarity index 98% rename from src/DataProtection/DataProtection/src/Cng/GcmAuthenticatedEncryptor.cs rename to src/DataProtection/DataProtection/src/Cng/CngGcmAuthenticatedEncryptor.cs index 6e47ee069481..1566fabba4f4 100644 --- a/src/DataProtection/DataProtection/src/Cng/GcmAuthenticatedEncryptor.cs +++ b/src/DataProtection/DataProtection/src/Cng/CngGcmAuthenticatedEncryptor.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using Microsoft.AspNetCore.Cryptography; using Microsoft.AspNetCore.Cryptography.Cng; using Microsoft.AspNetCore.Cryptography.SafeHandles; @@ -21,7 +20,7 @@ namespace Microsoft.AspNetCore.DataProtection.Cng // going to the IV. This means that we'll only hit the 2^-32 probability limit after 2^96 encryption // operations, which will realistically never happen. (At the absurd rate of one encryption operation // per nanosecond, it would still take 180 times the age of the universe to hit 2^96 operations.) - internal unsafe sealed class GcmAuthenticatedEncryptor : CngAuthenticatedEncryptorBase + internal unsafe sealed class CngGcmAuthenticatedEncryptor : CngAuthenticatedEncryptorBase { // Having a key modifier ensures with overwhelming probability that no two encryption operations // will ever derive the same (encryption subkey, MAC subkey) pair. This limits an attacker's @@ -38,12 +37,12 @@ internal unsafe sealed class GcmAuthenticatedEncryptor : CngAuthenticatedEncrypt private readonly BCryptAlgorithmHandle _symmetricAlgorithmHandle; private readonly uint _symmetricAlgorithmSubkeyLengthInBytes; - public GcmAuthenticatedEncryptor(Secret keyDerivationKey, BCryptAlgorithmHandle symmetricAlgorithmHandle, uint symmetricAlgorithmKeySizeInBytes, IBCryptGenRandom? genRandom = null) + public CngGcmAuthenticatedEncryptor(Secret keyDerivationKey, BCryptAlgorithmHandle symmetricAlgorithmHandle, uint symmetricAlgorithmKeySizeInBytes, IBCryptGenRandom? genRandom = null) { // Is the key size appropriate? AlgorithmAssert.IsAllowableSymmetricAlgorithmKeySize(checked(symmetricAlgorithmKeySizeInBytes * 8)); CryptoUtil.Assert(symmetricAlgorithmHandle.GetCipherBlockLength() == 128 / 8, "GCM requires a block cipher algorithm with a 128-bit block size."); - + _genRandom = genRandom ?? BCryptGenRandomImpl.Instance; _sp800_108_ctr_hmac_provider = SP800_108_CTR_HMACSHA512Util.CreateProvider(keyDerivationKey); _symmetricAlgorithmHandle = symmetricAlgorithmHandle; @@ -151,7 +150,6 @@ protected override byte[] DecryptImpl(byte* pbCiphertext, uint cbCiphertext, byt cbDerivedKey: _symmetricAlgorithmSubkeyLengthInBytes); // Perform the decryption operation - using (var decryptionSubkeyHandle = _symmetricAlgorithmHandle.GenerateSymmetricKey(pbSymmetricDecryptionSubkey, _symmetricAlgorithmSubkeyLengthInBytes)) { byte dummy; diff --git a/src/DataProtection/DataProtection/src/Managed/AesGcmAuthenticatedEncryptor.cs b/src/DataProtection/DataProtection/src/Managed/AesGcmAuthenticatedEncryptor.cs new file mode 100644 index 000000000000..d883dfeaaaed --- /dev/null +++ b/src/DataProtection/DataProtection/src/Managed/AesGcmAuthenticatedEncryptor.cs @@ -0,0 +1,231 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +#if NETCOREAPP +using System; +using System.IO; +using System.Security.Cryptography; +using Microsoft.AspNetCore.Cryptography; +using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption; +using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel; +using Microsoft.AspNetCore.DataProtection.SP800_108; + +namespace Microsoft.AspNetCore.DataProtection.Managed +{ + // An encryptor that uses AesGcm to do encryption + internal unsafe sealed class AesGcmAuthenticatedEncryptor : IOptimizedAuthenticatedEncryptor, IDisposable + { + // Having a key modifier ensures with overwhelming probability that no two encryption operations + // will ever derive the same (encryption subkey, MAC subkey) pair. This limits an attacker's + // ability to mount a key-dependent chosen ciphertext attack. See also the class-level comment + // on CngGcmAuthenticatedEncryptor for how this is used to overcome GCM's IV limitations. + private const int KEY_MODIFIER_SIZE_IN_BYTES = 128 / 8; + + private const int NONCE_SIZE_IN_BYTES = 96 / 8; // GCM has a fixed 96-bit IV + private const int TAG_SIZE_IN_BYTES = 128 / 8; // we're hardcoding a 128-bit authentication tag size + + // See CngGcmAuthenticatedEncryptor.CreateContextHeader for how these were precomputed + + // 128 "00-01-00-00-00-10-00-00-00-0C-00-00-00-10-00-00-00-10-95-7C-50-FF-69-2E-38-8B-9A-D5-C7-68-9E-4B-9E-2B" + private static readonly byte[] AES_128_GCM_Header = new byte[] { 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x95, 0x7C, 0x50, 0xFF, 0x69, 0x2E, 0x38, 0x8B, 0x9A, 0xD5, 0xC7, 0x68, 0x9E, 0x4B, 0x9E, 0x2B }; + + // 192 "00-01-00-00-00-18-00-00-00-0C-00-00-00-10-00-00-00-10-0D-AA-01-3A-95-0A-DA-2B-79-8F-5F-F2-72-FA-D3-63" + private static readonly byte[] AES_192_GCM_Header = new byte[] { 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x0D, 0xAA, 0x01, 0x3A, 0x95, 0x0A, 0xDA, 0x2B, 0x79, 0x8F, 0x5F, 0xF2, 0x72, 0xFA, 0xD3, 0x63 }; + + // 256 00-01-00-00-00-20-00-00-00-0C-00-00-00-10-00-00-00-10-E7-DC-CE-66-DF-85-5A-32-3A-6B-B7-BD-7A-59-BE-45 + private static readonly byte[] AES_256_GCM_Header = new byte[] { 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0xE7, 0xDC, 0xCE, 0x66, 0xDF, 0x85, 0x5A, 0x32, 0x3A, 0x6B, 0xB7, 0xBD, 0x7A, 0x59, 0xBE, 0x45 }; + + private static readonly Func _kdkPrfFactory = key => new HMACSHA512(key); // currently hardcoded to SHA512 + + private readonly byte[] _contextHeader; + + private readonly Secret _keyDerivationKey; + private readonly int _derivedkeySizeInBytes; + private readonly IManagedGenRandom _genRandom; + + public AesGcmAuthenticatedEncryptor(ISecret keyDerivationKey, int derivedKeySizeInBytes, IManagedGenRandom? genRandom = null) + { + _keyDerivationKey = new Secret(keyDerivationKey); + _derivedkeySizeInBytes = derivedKeySizeInBytes; + + switch (_derivedkeySizeInBytes) + { + case 16: + _contextHeader = AES_128_GCM_Header; + break; + case 24: + _contextHeader = AES_192_GCM_Header; + break; + case 32: + _contextHeader = AES_256_GCM_Header; + break; + default: + throw CryptoUtil.Fail("Unexpected AES key size in bytes only support 16, 24, 32."); // should never happen + } + + _genRandom = genRandom ?? ManagedGenRandomImpl.Instance; + } + + public byte[] Decrypt(ArraySegment ciphertext, ArraySegment additionalAuthenticatedData) + { + ciphertext.Validate(); + additionalAuthenticatedData.Validate(); + + // Argument checking: input must at the absolute minimum contain a key modifier, nonce, and tag + if (ciphertext.Count < KEY_MODIFIER_SIZE_IN_BYTES + NONCE_SIZE_IN_BYTES + TAG_SIZE_IN_BYTES) + { + throw Error.CryptCommon_PayloadInvalid(); + } + + // Assumption: pbCipherText := { keyModifier || nonce || encryptedData || authenticationTag } + var plaintextBytes = ciphertext.Count - (KEY_MODIFIER_SIZE_IN_BYTES + NONCE_SIZE_IN_BYTES + TAG_SIZE_IN_BYTES); + var plaintext = new byte[plaintextBytes]; + + try + { + // Step 1: Extract the key modifier from the payload. + + int keyModifierOffset; // position in ciphertext.Array where key modifier begins + int nonceOffset; // position in ciphertext.Array where key modifier ends / nonce begins + int encryptedDataOffset; // position in ciphertext.Array where nonce ends / encryptedData begins + int tagOffset; // position in ciphertext.Array where encrypted data ends + + checked + { + keyModifierOffset = ciphertext.Offset; + nonceOffset = keyModifierOffset + KEY_MODIFIER_SIZE_IN_BYTES; + encryptedDataOffset = nonceOffset + NONCE_SIZE_IN_BYTES; + tagOffset = encryptedDataOffset + plaintextBytes; + } + + var keyModifier = new ArraySegment(ciphertext.Array!, keyModifierOffset, KEY_MODIFIER_SIZE_IN_BYTES); + + // Step 2: Decrypt the KDK and use it to restore the original encryption and MAC keys. + // We pin all unencrypted keys to limit their exposure via GC relocation. + + var decryptedKdk = new byte[_keyDerivationKey.Length]; + var derivedKey = new byte[_derivedkeySizeInBytes]; + + fixed (byte* __unused__1 = decryptedKdk) + fixed (byte* __unused__2 = derivedKey) + { + try + { + _keyDerivationKey.WriteSecretIntoBuffer(new ArraySegment(decryptedKdk)); + ManagedSP800_108_CTR_HMACSHA512.DeriveKeysWithContextHeader( + kdk: decryptedKdk, + label: additionalAuthenticatedData, + contextHeader: _contextHeader, + context: keyModifier, + prfFactory: _kdkPrfFactory, + output: new ArraySegment(derivedKey)); + + // Perform the decryption operation + var nonce = new Span(ciphertext.Array, nonceOffset, NONCE_SIZE_IN_BYTES); + var tag = new Span(ciphertext.Array, tagOffset, TAG_SIZE_IN_BYTES); + var encrypted = new Span(ciphertext.Array, encryptedDataOffset, plaintextBytes); + using var aes = new AesGcm(derivedKey); + aes.Decrypt(nonce, encrypted, tag, plaintext); + return plaintext; + } + finally + { + // delete since these contain secret material + Array.Clear(decryptedKdk, 0, decryptedKdk.Length); + Array.Clear(derivedKey, 0, derivedKey.Length); + } + } + } + catch (Exception ex) when (ex.RequiresHomogenization()) + { + // Homogenize all exceptions to CryptographicException. + throw Error.CryptCommon_GenericError(ex); + } + } + + public byte[] Encrypt(ArraySegment plaintext, ArraySegment additionalAuthenticatedData, uint preBufferSize, uint postBufferSize) + { + plaintext.Validate(); + additionalAuthenticatedData.Validate(); + + try + { + // Allocate a buffer to hold the key modifier, nonce, encrypted data, and tag. + // In GCM, the encrypted output will be the same length as the plaintext input. + var retVal = new byte[checked(preBufferSize + KEY_MODIFIER_SIZE_IN_BYTES + NONCE_SIZE_IN_BYTES + plaintext.Count + TAG_SIZE_IN_BYTES + postBufferSize)]; + int keyModifierOffset; // position in ciphertext.Array where key modifier begins + int nonceOffset; // position in ciphertext.Array where key modifier ends / nonce begins + int encryptedDataOffset; // position in ciphertext.Array where nonce ends / encryptedData begins + int tagOffset; // position in ciphertext.Array where encrypted data ends + + checked + { + keyModifierOffset = plaintext.Offset + (int)preBufferSize; + nonceOffset = keyModifierOffset + KEY_MODIFIER_SIZE_IN_BYTES; + encryptedDataOffset = nonceOffset + NONCE_SIZE_IN_BYTES; + tagOffset = encryptedDataOffset + plaintext.Count; + } + + // Randomly generate the key modifier and nonce + var keyModifier = _genRandom.GenRandom(KEY_MODIFIER_SIZE_IN_BYTES); + var nonceBytes = _genRandom.GenRandom(NONCE_SIZE_IN_BYTES); + + Buffer.BlockCopy(keyModifier, 0, retVal, (int)preBufferSize, keyModifier.Length); + Buffer.BlockCopy(nonceBytes, 0, retVal, (int)preBufferSize + keyModifier.Length, nonceBytes.Length); + + // At this point, retVal := { preBuffer | keyModifier | nonce | _____ | _____ | postBuffer } + + // Use the KDF to generate a new symmetric block cipher key + // We'll need a temporary buffer to hold the symmetric encryption subkey + var decryptedKdk = new byte[_keyDerivationKey.Length]; + var derivedKey = new byte[_derivedkeySizeInBytes]; + fixed (byte* __unused__1 = decryptedKdk) + fixed (byte* __unused__2 = derivedKey) + { + try + { + _keyDerivationKey.WriteSecretIntoBuffer(new ArraySegment(decryptedKdk)); + ManagedSP800_108_CTR_HMACSHA512.DeriveKeysWithContextHeader( + kdk: decryptedKdk, + label: additionalAuthenticatedData, + contextHeader: _contextHeader, + context: keyModifier, + prfFactory: _kdkPrfFactory, + output: new ArraySegment(derivedKey)); + + // do gcm + var nonce = new Span(retVal, nonceOffset, NONCE_SIZE_IN_BYTES); + var tag = new Span(retVal, tagOffset, TAG_SIZE_IN_BYTES); + var encrypted = new Span(retVal, encryptedDataOffset, plaintext.Count); + using var aes = new AesGcm(derivedKey); + aes.Encrypt(nonce, plaintext, encrypted, tag); + + // At this point, retVal := { preBuffer | keyModifier | nonce | encryptedData | authenticationTag | postBuffer } + // And we're done! + return retVal; + } + finally + { + // delete since these contain secret material + Array.Clear(decryptedKdk, 0, decryptedKdk.Length); + Array.Clear(derivedKey, 0, derivedKey.Length); + } + } + } + catch (Exception ex) when (ex.RequiresHomogenization()) + { + // Homogenize all exceptions to CryptographicException. + throw Error.CryptCommon_GenericError(ex); + } + } + + public byte[] Encrypt(ArraySegment plaintext, ArraySegment additionalAuthenticatedData) + => Encrypt(plaintext, additionalAuthenticatedData, 0, 0); + + public void Dispose() + { + _keyDerivationKey.Dispose(); + } + } +} +#endif diff --git a/src/DataProtection/DataProtection/test/AuthenticatedEncryption/CngGcmAuthenticatedEncryptorFactoryTest.cs b/src/DataProtection/DataProtection/test/AuthenticatedEncryption/CngGcmAuthenticatedEncryptorFactoryTest.cs index 2a6fbcf307fe..ef6b3fa5663c 100644 --- a/src/DataProtection/DataProtection/test/AuthenticatedEncryption/CngGcmAuthenticatedEncryptorFactoryTest.cs +++ b/src/DataProtection/DataProtection/test/AuthenticatedEncryption/CngGcmAuthenticatedEncryptorFactoryTest.cs @@ -46,7 +46,7 @@ public void CreateEncrptorInstance_ExpectedDescriptorType_ReturnsEncryptor() // Assert Assert.NotNull(encryptor); - Assert.IsType(encryptor); + Assert.IsType(encryptor); } } } diff --git a/src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorDescriptorTests.cs b/src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorDescriptorTests.cs index c268589b27ac..e7dac35da21d 100644 --- a/src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorDescriptorTests.cs +++ b/src/DataProtection/DataProtection/test/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorDescriptorTests.cs @@ -62,7 +62,33 @@ public void CreateAuthenticatedEncryptor_RoundTripsData_CngGcmImplementation(Enc // Arrange var masterKey = Secret.Random(512 / 8); - var control = new GcmAuthenticatedEncryptor( + var control = new CngGcmAuthenticatedEncryptor( + keyDerivationKey: masterKey, + symmetricAlgorithmHandle: CachedAlgorithmHandles.AES_GCM, + symmetricAlgorithmKeySizeInBytes: (uint)(keyLengthInBits / 8)); + var test = CreateEncryptorInstanceFromDescriptor(CreateDescriptor(encryptionAlgorithm, ValidationAlgorithm.HMACSHA256 /* unused */, masterKey)); + + // Act & assert - data round trips properly from control to test + byte[] plaintext = new byte[] { 1, 2, 3, 4, 5 }; + byte[] aad = new byte[] { 2, 4, 6, 8, 0 }; + byte[] ciphertext = control.Encrypt(new ArraySegment(plaintext), new ArraySegment(aad)); + byte[] roundTripPlaintext = test.Decrypt(new ArraySegment(ciphertext), new ArraySegment(aad)); + Assert.Equal(plaintext, roundTripPlaintext); + } + + [ConditionalTheory] + [ConditionalRunTestOnlyOnWindows] + [InlineData(EncryptionAlgorithm.AES_128_GCM)] + [InlineData(EncryptionAlgorithm.AES_192_GCM)] + [InlineData(EncryptionAlgorithm.AES_256_GCM)] + public void CreateAuthenticatedEncryptor_RoundTripsData_AesGcmImplementation(EncryptionAlgorithm encryptionAlgorithm) + { + // Parse test input + int keyLengthInBits = Int32.Parse(Regex.Match(encryptionAlgorithm.ToString(), @"^AES_(?\d{3})_GCM$").Groups["keyLength"].Value, CultureInfo.InvariantCulture); + + // Arrange + var masterKey = Secret.Random(512 / 8); + var control = new CngGcmAuthenticatedEncryptor( keyDerivationKey: masterKey, symmetricAlgorithmHandle: CachedAlgorithmHandles.AES_GCM, symmetricAlgorithmKeySizeInBytes: (uint)(keyLengthInBits / 8)); diff --git a/src/DataProtection/DataProtection/test/Cng/GcmAuthenticatedEncryptorTests.cs b/src/DataProtection/DataProtection/test/Cng/GcmAuthenticatedEncryptorTests.cs index 2a5b3d465f9a..fa245d72cb47 100644 --- a/src/DataProtection/DataProtection/test/Cng/GcmAuthenticatedEncryptorTests.cs +++ b/src/DataProtection/DataProtection/test/Cng/GcmAuthenticatedEncryptorTests.cs @@ -20,7 +20,7 @@ public void Encrypt_Decrypt_RoundTrips() { // Arrange Secret kdk = new Secret(new byte[512 / 8]); - GcmAuthenticatedEncryptor encryptor = new GcmAuthenticatedEncryptor(kdk, CachedAlgorithmHandles.AES_GCM, symmetricAlgorithmKeySizeInBytes: 256 / 8); + CngGcmAuthenticatedEncryptor encryptor = new CngGcmAuthenticatedEncryptor(kdk, CachedAlgorithmHandles.AES_GCM, symmetricAlgorithmKeySizeInBytes: 256 / 8); ArraySegment plaintext = new ArraySegment(Encoding.UTF8.GetBytes("plaintext")); ArraySegment aad = new ArraySegment(Encoding.UTF8.GetBytes("aad")); @@ -38,7 +38,7 @@ public void Encrypt_Decrypt_Tampering_Fails() { // Arrange Secret kdk = new Secret(new byte[512 / 8]); - GcmAuthenticatedEncryptor encryptor = new GcmAuthenticatedEncryptor(kdk, CachedAlgorithmHandles.AES_GCM, symmetricAlgorithmKeySizeInBytes: 256 / 8); + CngGcmAuthenticatedEncryptor encryptor = new CngGcmAuthenticatedEncryptor(kdk, CachedAlgorithmHandles.AES_GCM, symmetricAlgorithmKeySizeInBytes: 256 / 8); ArraySegment plaintext = new ArraySegment(Encoding.UTF8.GetBytes("plaintext")); ArraySegment aad = new ArraySegment(Encoding.UTF8.GetBytes("aad")); byte[] validCiphertext = encryptor.Encrypt(plaintext, aad); @@ -82,7 +82,7 @@ public void Encrypt_KnownKey() { // Arrange Secret kdk = new Secret(Encoding.UTF8.GetBytes("master key")); - GcmAuthenticatedEncryptor encryptor = new GcmAuthenticatedEncryptor(kdk, CachedAlgorithmHandles.AES_GCM, symmetricAlgorithmKeySizeInBytes: 128 / 8, genRandom: new SequentialGenRandom()); + CngGcmAuthenticatedEncryptor encryptor = new CngGcmAuthenticatedEncryptor(kdk, CachedAlgorithmHandles.AES_GCM, symmetricAlgorithmKeySizeInBytes: 128 / 8, genRandom: new SequentialGenRandom()); ArraySegment plaintext = new ArraySegment(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }, 2, 3); ArraySegment aad = new ArraySegment(new byte[] { 7, 6, 5, 4, 3, 2, 1, 0 }, 1, 4);