public void ResolvePolicy_CngGcmEncryption_WithExplicitSettings() { IServiceCollection serviceCollection = new ServiceCollection(); RunTestWithRegValues(serviceCollection, new Dictionary <string, object>() { ["EncryptionType"] = "cng-gcm", ["EncryptionAlgorithm"] = "enc-alg", ["EncryptionAlgorithmKeySize"] = 2048, ["EncryptionAlgorithmProvider"] = "my-enc-alg-provider" }); var services = serviceCollection.BuildServiceProvider(); var expectedConfiguration = new CngGcmAuthenticatedEncryptorConfiguration(new CngGcmAuthenticatedEncryptionOptions() { EncryptionAlgorithm = "enc-alg", EncryptionAlgorithmKeySize = 2048, EncryptionAlgorithmProvider = "my-enc-alg-provider" }); var actualConfiguration = (CngGcmAuthenticatedEncryptorConfiguration)services.GetService <IAuthenticatedEncryptorConfiguration>(); Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithm, actualConfiguration.Options.EncryptionAlgorithm); Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithmKeySize, actualConfiguration.Options.EncryptionAlgorithmKeySize); Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithmProvider, actualConfiguration.Options.EncryptionAlgorithmProvider); }
/// <summary> /// Imports the <see cref="CngCbcAuthenticatedEncryptorDescriptor"/> from serialized XML. /// </summary> public IAuthenticatedEncryptorDescriptor ImportFromXml(XElement element) { if (element == null) { throw new ArgumentNullException(nameof(element)); } // <descriptor> // <!-- Windows CNG-GCM --> // <encryption algorithm="..." keyLength="..." [provider="..."] /> // <masterKey>...</masterKey> // </descriptor> var configuration = new CngGcmAuthenticatedEncryptorConfiguration(); var encryptionElement = element.Element("encryption") !; configuration.EncryptionAlgorithm = (string)encryptionElement.Attribute("algorithm") !; configuration.EncryptionAlgorithmKeySize = (int)encryptionElement.Attribute("keyLength") !; configuration.EncryptionAlgorithmProvider = (string?)encryptionElement.Attribute("provider"); // could be null Secret masterKey = ((string)element.Element("masterKey") !).ToSecret(); return(new CngGcmAuthenticatedEncryptorDescriptor(configuration, masterKey)); }
public void ResolvePolicy_CngGcmEncryption_WithExplicitSettings() { // Arrange var registryEntries = new Dictionary <string, object>() { ["EncryptionType"] = "cng-gcm", ["EncryptionAlgorithm"] = "enc-alg", ["EncryptionAlgorithmKeySize"] = 2048, ["EncryptionAlgorithmProvider"] = "my-enc-alg-provider" }; var expectedConfiguration = new CngGcmAuthenticatedEncryptorConfiguration() { EncryptionAlgorithm = "enc-alg", EncryptionAlgorithmKeySize = 2048, EncryptionAlgorithmProvider = "my-enc-alg-provider" }; // Act var context = RunTestWithRegValues(registryEntries); // Assert var actualConfiguration = (CngGcmAuthenticatedEncryptorConfiguration)context.EncryptorConfiguration; Assert.Equal(expectedConfiguration.EncryptionAlgorithm, actualConfiguration.EncryptionAlgorithm); Assert.Equal(expectedConfiguration.EncryptionAlgorithmKeySize, actualConfiguration.EncryptionAlgorithmKeySize); Assert.Equal(expectedConfiguration.EncryptionAlgorithmProvider, actualConfiguration.EncryptionAlgorithmProvider); }
internal IAuthenticatedEncryptor?CreateAuthenticatedEncryptorInstance( ISecret secret, AuthenticatedEncryptorConfiguration?authenticatedConfiguration) { if (authenticatedConfiguration == null) { return(null); } 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()) { throw new PlatformNotSupportedException(Resources.Platform_WindowsRequiredForGcm); } Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); var configuration = new CngGcmAuthenticatedEncryptorConfiguration() { EncryptionAlgorithm = GetBCryptAlgorithmNameFromEncryptionAlgorithm(authenticatedConfiguration.EncryptionAlgorithm), EncryptionAlgorithmKeySize = GetAlgorithmKeySizeInBits(authenticatedConfiguration.EncryptionAlgorithm) }; return(new CngGcmAuthenticatedEncryptorFactory(_loggerFactory).CreateAuthenticatedEncryptorInstance(secret, configuration)); #endif } else { if (OSVersionUtil.IsWindows()) { Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); // CNG preferred over managed implementations if running on Windows var configuration = new CngCbcAuthenticatedEncryptorConfiguration() { EncryptionAlgorithm = GetBCryptAlgorithmNameFromEncryptionAlgorithm(authenticatedConfiguration.EncryptionAlgorithm), EncryptionAlgorithmKeySize = GetAlgorithmKeySizeInBits(authenticatedConfiguration.EncryptionAlgorithm), HashAlgorithm = GetBCryptAlgorithmNameFromValidationAlgorithm(authenticatedConfiguration.ValidationAlgorithm) }; return(new CngCbcAuthenticatedEncryptorFactory(_loggerFactory).CreateAuthenticatedEncryptorInstance(secret, configuration)); } else { // Use managed implementations as a fallback var configuration = new ManagedAuthenticatedEncryptorConfiguration() { EncryptionAlgorithmType = GetManagedTypeFromEncryptionAlgorithm(authenticatedConfiguration.EncryptionAlgorithm), EncryptionAlgorithmKeySize = GetAlgorithmKeySizeInBits(authenticatedConfiguration.EncryptionAlgorithm), ValidationAlgorithmType = GetManagedTypeFromValidationAlgorithm(authenticatedConfiguration.ValidationAlgorithm) }; return(new ManagedAuthenticatedEncryptorFactory(_loggerFactory).CreateAuthenticatedEncryptorInstance(secret, configuration)); } } }
public void CreateNewDescriptor_PropagatesOptions() { // Arrange var configuration = new CngGcmAuthenticatedEncryptorConfiguration(); // Act var descriptor = (CngGcmAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor(); // Assert Assert.Equal(configuration, descriptor.Configuration); }
internal IAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance( ISecret secret, AuthenticatedEncryptorConfiguration authenticatedConfiguration) { if (authenticatedConfiguration == null) { return(null); } if (IsGcmAlgorithm(authenticatedConfiguration.EncryptionAlgorithm)) { // GCM requires CNG, and CNG is only supported on Windows. if (!OSVersionUtil.IsWindows()) { throw new PlatformNotSupportedException("GCM algorithms require the Windows platform."); } var configuration = new CngGcmAuthenticatedEncryptorConfiguration() { EncryptionAlgorithm = GetBCryptAlgorithmNameFromEncryptionAlgorithm(authenticatedConfiguration.EncryptionAlgorithm), EncryptionAlgorithmKeySize = GetAlgorithmKeySizeInBits(authenticatedConfiguration.EncryptionAlgorithm) }; return(new CngGcmAuthenticatedEncryptorFactory(_loggerFactory).CreateAuthenticatedEncryptorInstance(secret, configuration)); } else { if (OSVersionUtil.IsWindows()) { // CNG preferred over managed implementations if running on Windows var configuration = new CngCbcAuthenticatedEncryptorConfiguration() { EncryptionAlgorithm = GetBCryptAlgorithmNameFromEncryptionAlgorithm(authenticatedConfiguration.EncryptionAlgorithm), EncryptionAlgorithmKeySize = GetAlgorithmKeySizeInBits(authenticatedConfiguration.EncryptionAlgorithm), HashAlgorithm = GetBCryptAlgorithmNameFromValidationAlgorithm(authenticatedConfiguration.ValidationAlgorithm) }; return(new CngCbcAuthenticatedEncryptorFactory(_loggerFactory).CreateAuthenticatedEncryptorInstance(secret, configuration)); } else { // Use managed implementations as a fallback var configuration = new ManagedAuthenticatedEncryptorConfiguration() { EncryptionAlgorithmType = GetManagedTypeFromEncryptionAlgorithm(authenticatedConfiguration.EncryptionAlgorithm), EncryptionAlgorithmKeySize = GetAlgorithmKeySizeInBits(authenticatedConfiguration.EncryptionAlgorithm), ValidationAlgorithmType = GetManagedTypeFromValidationAlgorithm(authenticatedConfiguration.ValidationAlgorithm) }; return(new ManagedAuthenticatedEncryptorFactory(_loggerFactory).CreateAuthenticatedEncryptorInstance(secret, configuration)); } } }
internal CngGcmAuthenticatedEncryptor?CreateAuthenticatedEncryptorInstance( ISecret secret, CngGcmAuthenticatedEncryptorConfiguration configuration) { if (configuration == null) { return(null); } return(new CngGcmAuthenticatedEncryptor( keyDerivationKey: new Secret(secret), symmetricAlgorithmHandle: GetSymmetricBlockCipherAlgorithmHandle(configuration), symmetricAlgorithmKeySizeInBytes: (uint)(configuration.EncryptionAlgorithmKeySize / 8))); }
public void CreateNewDescriptor_CreatesUniqueCorrectlySizedMasterKey() { // Arrange var configuration = new CngGcmAuthenticatedEncryptorConfiguration(); // Act var masterKey1 = ((CngGcmAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor()).MasterKey; var masterKey2 = ((CngGcmAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor()).MasterKey; // Assert SecretAssert.NotEqual(masterKey1, masterKey2); SecretAssert.LengthIs(512 /* bits */, masterKey1); SecretAssert.LengthIs(512 /* bits */, masterKey2); }
/// <summary> /// Initializes a new instance of <see cref="CngGcmAuthenticatedEncryptorDescriptor"/>. /// </summary> /// <param name="configuration">The <see cref="CngCbcAuthenticatedEncryptorConfiguration"/>.</param> /// <param name="masterKey">The master key.</param> public CngGcmAuthenticatedEncryptorDescriptor(CngGcmAuthenticatedEncryptorConfiguration configuration, ISecret masterKey) { if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } if (masterKey == null) { throw new ArgumentNullException(nameof(masterKey)); } Configuration = configuration; MasterKey = masterKey; }
public void CreateEncrptorInstance_ExpectedDescriptorType_ReturnsEncryptor() { // Arrange var descriptor = new CngGcmAuthenticatedEncryptorConfiguration().CreateNewDescriptor(); var key = new Mock <IKey>(); key.Setup(k => k.Descriptor).Returns(descriptor); var factory = new CngGcmAuthenticatedEncryptorFactory(NullLoggerFactory.Instance); // Act var encryptor = factory.CreateEncryptorInstance(key.Object); // Assert Assert.NotNull(encryptor); Assert.IsType <CngGcmAuthenticatedEncryptor>(encryptor); }
private BCryptAlgorithmHandle GetSymmetricBlockCipherAlgorithmHandle(CngGcmAuthenticatedEncryptorConfiguration configuration) { // basic argument checking if (String.IsNullOrEmpty(configuration.EncryptionAlgorithm)) { throw Error.Common_PropertyCannotBeNullOrEmpty(nameof(EncryptionAlgorithm)); } if (configuration.EncryptionAlgorithmKeySize < 0) { throw Error.Common_PropertyMustBeNonNegative(nameof(configuration.EncryptionAlgorithmKeySize)); } BCryptAlgorithmHandle?algorithmHandle = null; _logger.OpeningCNGAlgorithmFromProviderWithChainingModeGCM(configuration.EncryptionAlgorithm, configuration.EncryptionAlgorithmProvider); // Special-case cached providers if (configuration.EncryptionAlgorithmProvider == null) { if (configuration.EncryptionAlgorithm == Constants.BCRYPT_AES_ALGORITHM) { algorithmHandle = CachedAlgorithmHandles.AES_GCM; } } // Look up the provider dynamically if we couldn't fetch a cached instance if (algorithmHandle == null) { algorithmHandle = BCryptAlgorithmHandle.OpenAlgorithmHandle(configuration.EncryptionAlgorithm, configuration.EncryptionAlgorithmProvider); algorithmHandle.SetChainingMode(Constants.BCRYPT_CHAIN_MODE_GCM); } // make sure we're using a block cipher with an appropriate key size & block size CryptoUtil.Assert(algorithmHandle.GetCipherBlockLength() == 128 / 8, "GCM requires a block cipher algorithm with a 128-bit block size."); AlgorithmAssert.IsAllowableSymmetricAlgorithmKeySize(checked ((uint)configuration.EncryptionAlgorithmKeySize)); // make sure the provided key length is valid algorithmHandle.GetSupportedKeyLengths().EnsureValidKeyLength((uint)configuration.EncryptionAlgorithmKeySize); // all good! return(algorithmHandle); }
private RegistryPolicy?ResolvePolicyCore(RegistryKey?policyRegKey) { if (policyRegKey == null) { return(null); } // Read the encryption options type: CNG-CBC, CNG-GCM, Managed AlgorithmConfiguration?configuration = null; var encryptionType = (string?)policyRegKey.GetValue("EncryptionType"); if (String.Equals(encryptionType, "CNG-CBC", StringComparison.OrdinalIgnoreCase)) { configuration = new CngCbcAuthenticatedEncryptorConfiguration(); } else if (String.Equals(encryptionType, "CNG-GCM", StringComparison.OrdinalIgnoreCase)) { configuration = new CngGcmAuthenticatedEncryptorConfiguration(); } else if (String.Equals(encryptionType, "Managed", StringComparison.OrdinalIgnoreCase)) { configuration = new ManagedAuthenticatedEncryptorConfiguration(); } else if (!String.IsNullOrEmpty(encryptionType)) { throw CryptoUtil.Fail("Unrecognized EncryptionType: " + encryptionType); } if (configuration != null) { PopulateOptions(configuration, policyRegKey); } // Read ancillary data var defaultKeyLifetime = (int?)policyRegKey.GetValue("DefaultKeyLifetime"); var keyEscrowSinks = ReadKeyEscrowSinks(policyRegKey).Select(item => _activator.CreateInstance <IKeyEscrowSink>(item)); return(new RegistryPolicy(configuration, keyEscrowSinks, defaultKeyLifetime)); }
private static CngGcmAuthenticatedEncryptorConfiguration GetCngGcmAuthenticatedEncryptorConfiguration(RegistryKey key) { var options = new CngGcmAuthenticatedEncryptorConfiguration(); var valueFromRegistry = key.GetValue(nameof(CngGcmAuthenticatedEncryptorConfiguration.EncryptionAlgorithm)); if (valueFromRegistry != null) { options.EncryptionAlgorithm = Convert.ToString(valueFromRegistry, CultureInfo.InvariantCulture) !; } valueFromRegistry = key.GetValue(nameof(CngGcmAuthenticatedEncryptorConfiguration.EncryptionAlgorithmProvider)); if (valueFromRegistry != null) { options.EncryptionAlgorithmProvider = Convert.ToString(valueFromRegistry, CultureInfo.InvariantCulture) !; } valueFromRegistry = key.GetValue(nameof(CngGcmAuthenticatedEncryptorConfiguration.EncryptionAlgorithmKeySize)); if (valueFromRegistry != null) { options.EncryptionAlgorithmKeySize = Convert.ToInt32(valueFromRegistry, CultureInfo.InvariantCulture); } return(options); }
public static IDataProtectionBuilder UseCustomCryptographicAlgorithms(this IDataProtectionBuilder builder, CngGcmAuthenticatedEncryptorConfiguration configuration) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } return(UseCryptographicAlgorithmsCore(builder, configuration)); }