private static BCryptAlgorithmHandle GetAesAlgorithm(string chainingMode)
        {
            var algHandle = BCryptAlgorithmHandle.OpenAlgorithmHandle(Constants.BCRYPT_AES_ALGORITHM);

            algHandle.SetChainingMode(chainingMode);
            return(algHandle);
        }
Beispiel #2
0
        private static BCryptAlgorithmHandle GetEncryptionAlgorithmHandleAndCheckKeySize(string encryptionAlgorithm, string encryptionAlgorithmProvider, uint keyLengthInBits)
        {
            BCryptAlgorithmHandle algorithmHandle = null;

            // Special-case cached providers
            if (encryptionAlgorithmProvider == null)
            {
                if (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(encryptionAlgorithm, encryptionAlgorithmProvider);
                algorithmHandle.SetChainingMode(Constants.BCRYPT_CHAIN_MODE_GCM);
            }

            // make sure we're using a block cipher with an appropriate block size
            uint cipherBlockSizeInBytes = algorithmHandle.GetCipherBlockLength();

            CryptoUtil.Assert(cipherBlockSizeInBytes == 128 / 8, "cipherBlockSizeInBytes == 128 / 8");

            // make sure the provided key length is valid
            algorithmHandle.GetSupportedKeyLengths().EnsureValidKeyLength(keyLengthInBits);

            // all good!
            return(algorithmHandle);
        }
        private BCryptAlgorithmHandle GetHmacAlgorithmHandle(ILogger logger)
        {
            // basic argument checking
            if (String.IsNullOrEmpty(HashAlgorithm))
            {
                throw Error.Common_PropertyCannotBeNullOrEmpty(nameof(HashAlgorithm));
            }

            if (logger.IsVerboseLevelEnabled())
            {
                logger.LogVerboseF($"Opening CNG algorithm '{HashAlgorithm}' from provider '{HashAlgorithmProvider}' with HMAC.");
            }

            BCryptAlgorithmHandle algorithmHandle = null;

            // Special-case cached providers
            if (HashAlgorithmProvider == null)
            {
                if (HashAlgorithm == Constants.BCRYPT_SHA1_ALGORITHM)
                {
                    algorithmHandle = CachedAlgorithmHandles.HMAC_SHA1;
                }
                else if (HashAlgorithm == Constants.BCRYPT_SHA256_ALGORITHM)
                {
                    algorithmHandle = CachedAlgorithmHandles.HMAC_SHA256;
                }
                else if (HashAlgorithm == Constants.BCRYPT_SHA512_ALGORITHM)
                {
                    algorithmHandle = CachedAlgorithmHandles.HMAC_SHA512;
                }
            }

            // Look up the provider dynamically if we couldn't fetch a cached instance
            if (algorithmHandle == null)
            {
                algorithmHandle = BCryptAlgorithmHandle.OpenAlgorithmHandle(HashAlgorithm, HashAlgorithmProvider, hmac: true);
            }

            // Make sure we're using a hash algorithm. We require a minimum 128-bit digest.
            uint digestSize = algorithmHandle.GetHashDigestLength();

            AlgorithmAssert.IsAllowableValidationAlgorithmDigestSize(checked (digestSize * 8));

            // all good!
            return(algorithmHandle);
        }
Beispiel #4
0
        private BCryptAlgorithmHandle GetSymmetricBlockCipherAlgorithmHandle(ILogger logger)
        {
            // basic argument checking
            if (String.IsNullOrEmpty(EncryptionAlgorithm))
            {
                throw Error.Common_PropertyCannotBeNullOrEmpty(nameof(EncryptionAlgorithm));
            }
            if (EncryptionAlgorithmKeySize < 0)
            {
                throw Error.Common_PropertyMustBeNonNegative(nameof(EncryptionAlgorithmKeySize));
            }

            BCryptAlgorithmHandle algorithmHandle = null;

            if (logger.IsVerboseLevelEnabled())
            {
                logger.LogVerboseF($"Opening CNG algorithm '{EncryptionAlgorithm}' from provider '{EncryptionAlgorithmProvider}' with chaining mode GCM.");
            }

            // Special-case cached providers
            if (EncryptionAlgorithmProvider == null)
            {
                if (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(EncryptionAlgorithm, 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)EncryptionAlgorithmKeySize));

            // make sure the provided key length is valid
            algorithmHandle.GetSupportedKeyLengths().EnsureValidKeyLength((uint)EncryptionAlgorithmKeySize);

            // all good!
            return(algorithmHandle);
        }
        private BCryptAlgorithmHandle GetHmacAlgorithmHandle(CngCbcAuthenticatedEncryptorConfiguration configuration)
        {
            // basic argument checking
            if (String.IsNullOrEmpty(configuration.HashAlgorithm))
            {
                throw Error.Common_PropertyCannotBeNullOrEmpty(nameof(configuration.HashAlgorithm));
            }

            _logger.OpeningCNGAlgorithmFromProviderWithHMAC(configuration.HashAlgorithm, configuration.HashAlgorithmProvider);
            BCryptAlgorithmHandle?algorithmHandle = null;

            // Special-case cached providers
            if (configuration.HashAlgorithmProvider == null)
            {
                if (configuration.HashAlgorithm == Constants.BCRYPT_SHA1_ALGORITHM)
                {
                    algorithmHandle = CachedAlgorithmHandles.HMAC_SHA1;
                }
                else if (configuration.HashAlgorithm == Constants.BCRYPT_SHA256_ALGORITHM)
                {
                    algorithmHandle = CachedAlgorithmHandles.HMAC_SHA256;
                }
                else if (configuration.HashAlgorithm == Constants.BCRYPT_SHA512_ALGORITHM)
                {
                    algorithmHandle = CachedAlgorithmHandles.HMAC_SHA512;
                }
            }

            // Look up the provider dynamically if we couldn't fetch a cached instance
            if (algorithmHandle == null)
            {
                algorithmHandle = BCryptAlgorithmHandle.OpenAlgorithmHandle(configuration.HashAlgorithm, configuration.HashAlgorithmProvider, hmac: true);
            }

            // Make sure we're using a hash algorithm. We require a minimum 128-bit digest.
            uint digestSize = algorithmHandle.GetHashDigestLength();

            AlgorithmAssert.IsAllowableValidationAlgorithmDigestSize(checked (digestSize * 8));

            // all good!
            return(algorithmHandle);
        }
        private BCryptAlgorithmHandle GetSymmetricBlockCipherAlgorithmHandle(CngCbcAuthenticatedEncryptorConfiguration 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));
            }

            _logger.OpeningCNGAlgorithmFromProviderWithChainingModeCBC(configuration.EncryptionAlgorithm, configuration.EncryptionAlgorithmProvider);

            BCryptAlgorithmHandle?algorithmHandle = null;

            // Special-case cached providers
            if (configuration.EncryptionAlgorithmProvider == null)
            {
                if (configuration.EncryptionAlgorithm == Constants.BCRYPT_AES_ALGORITHM)
                {
                    algorithmHandle = CachedAlgorithmHandles.AES_CBC;
                }
            }

            // 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_CBC);
            }

            // make sure we're using a block cipher with an appropriate key size & block size
            AlgorithmAssert.IsAllowableSymmetricAlgorithmBlockSize(checked (algorithmHandle.GetCipherBlockLength() * 8));
            AlgorithmAssert.IsAllowableSymmetricAlgorithmKeySize(checked ((uint)configuration.EncryptionAlgorithmKeySize));

            // make sure the provided key length is valid
            algorithmHandle.GetSupportedKeyLengths().EnsureValidKeyLength((uint)configuration.EncryptionAlgorithmKeySize);

            // all good!
            return(algorithmHandle);
        }
Beispiel #7
0
        public void CreateAuthenticatedEncryptor_RoundTripsData_CngCbcImplementation(EncryptionAlgorithm encryptionAlgorithm, ValidationAlgorithm validationAlgorithm)
        {
            // Parse test input
            int    keyLengthInBits = Int32.Parse(Regex.Match(encryptionAlgorithm.ToString(), @"^AES_(?<keyLength>\d{3})_CBC$").Groups["keyLength"].Value, CultureInfo.InvariantCulture);
            string hashAlgorithm   = Regex.Match(validationAlgorithm.ToString(), @"^HMAC(?<hashAlgorithm>.*)$").Groups["hashAlgorithm"].Value;

            // Arrange
            var masterKey = Secret.Random(512 / 8);
            var control   = new CbcAuthenticatedEncryptor(
                keyDerivationKey: masterKey,
                symmetricAlgorithmHandle: CachedAlgorithmHandles.AES_CBC,
                symmetricAlgorithmKeySizeInBytes: (uint)(keyLengthInBits / 8),
                hmacAlgorithmHandle: BCryptAlgorithmHandle.OpenAlgorithmHandle(hashAlgorithm, hmac: true));
            var test = CreateEncryptorInstanceFromDescriptor(CreateDescriptor(encryptionAlgorithm, validationAlgorithm, 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 <byte>(plaintext), new ArraySegment <byte>(aad));
            byte[] roundTripPlaintext = test.Decrypt(new ArraySegment <byte>(ciphertext), new ArraySegment <byte>(aad));
            Assert.Equal(plaintext, roundTripPlaintext);
        }
        private static BCryptAlgorithmHandle GetHashAlgorithmHandle(string hashAlgorithm, string hashAlgorithmProvider)
        {
            BCryptAlgorithmHandle algorithmHandle = null;

            // Special-case cached providers
            if (hashAlgorithmProvider == null)
            {
                if (hashAlgorithm == Constants.BCRYPT_SHA1_ALGORITHM)
                {
                    algorithmHandle = CachedAlgorithmHandles.HMAC_SHA1;
                }
                else if (hashAlgorithm == Constants.BCRYPT_SHA256_ALGORITHM)
                {
                    algorithmHandle = CachedAlgorithmHandles.HMAC_SHA256;
                }
                else if (hashAlgorithm == Constants.BCRYPT_SHA512_ALGORITHM)
                {
                    algorithmHandle = CachedAlgorithmHandles.HMAC_SHA512;
                }
            }

            // Look up the provider dynamically if we couldn't fetch a cached instance
            if (algorithmHandle == null)
            {
                algorithmHandle = BCryptAlgorithmHandle.OpenAlgorithmHandle(hashAlgorithm, hashAlgorithmProvider, hmac: true);
            }

            // Make sure we're using a hash algorithm. We require a minimum 128-bit digest.
            uint digestSize = algorithmHandle.GetHashDigestLength();

            CryptoUtil.Assert(digestSize >= CbcAuthenticatedEncryptor.HASH_ALG_MIN_DIGEST_LENGTH_IN_BYTES,
                              "digestSize >= CbcAuthenticatedEncryptor.HASH_ALG_MIN_DIGEST_LENGTH_IN_BYTES");

            // all good!
            return(algorithmHandle);
        }
 private static BCryptAlgorithmHandle GetSP800_108_CTR_HMACAlgorithm()
 {
     return(BCryptAlgorithmHandle.OpenAlgorithmHandle(Constants.BCRYPT_SP800108_CTR_HMAC_ALGORITHM, implementation: Constants.MS_PRIMITIVE_PROVIDER));
 }
 private static BCryptAlgorithmHandle GetPbkdf2Algorithm()
 {
     return(BCryptAlgorithmHandle.OpenAlgorithmHandle(Constants.BCRYPT_PBKDF2_ALGORITHM, implementation: Constants.MS_PRIMITIVE_PROVIDER));
 }
 private static BCryptAlgorithmHandle GetHmacAlgorithm(string algorithm)
 {
     return(BCryptAlgorithmHandle.OpenAlgorithmHandle(algorithm, hmac: true));
 }
 private static BCryptAlgorithmHandle GetHashAlgorithm(string algorithm)
 {
     return(BCryptAlgorithmHandle.OpenAlgorithmHandle(algorithm, hmac: false));
 }