public ManagedAuthenticatedEncryptor(Secret keyDerivationKey, Func <SymmetricAlgorithm> symmetricAlgorithmFactory, int symmetricAlgorithmKeySizeInBytes, Func <KeyedHashAlgorithm> validationAlgorithmFactory, IManagedGenRandom genRandom = null)
        {
            _genRandom        = genRandom ?? ManagedGenRandomImpl.Instance;
            _keyDerivationKey = keyDerivationKey;

            // Validate that the symmetric algorithm has the properties we require
            using (var symmetricAlgorithm = symmetricAlgorithmFactory())
            {
                _symmetricAlgorithmFactory             = symmetricAlgorithmFactory;
                _symmetricAlgorithmBlockSizeInBytes    = symmetricAlgorithm.GetBlockSizeInBytes();
                _symmetricAlgorithmSubkeyLengthInBytes = symmetricAlgorithmKeySizeInBytes;
            }

            // Validate that the MAC algorithm has the properties we require
            using (var validationAlgorithm = validationAlgorithmFactory())
            {
                _validationAlgorithmFactory             = validationAlgorithmFactory;
                _validationAlgorithmDigestLengthInBytes = validationAlgorithm.GetDigestSizeInBytes();
                _validationAlgorithmSubkeyLengthInBytes = _validationAlgorithmDigestLengthInBytes; // for simplicity we'll generate MAC subkeys with a length equal to the digest length
            }

            // Argument checking on the algorithms and lengths passed in to us
            AlgorithmAssert.IsAllowableSymmetricAlgorithmBlockSize(checked ((uint)_symmetricAlgorithmBlockSizeInBytes * 8));
            AlgorithmAssert.IsAllowableSymmetricAlgorithmKeySize(checked ((uint)_symmetricAlgorithmSubkeyLengthInBytes * 8));
            AlgorithmAssert.IsAllowableValidationAlgorithmDigestSize(checked ((uint)_validationAlgorithmDigestLengthInBytes * 8));

            _contextHeader = CreateContextHeader();
        }
예제 #2
0
    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;
        _symmetricAlgorithmSubkeyLengthInBytes = symmetricAlgorithmKeySizeInBytes;
        _contextHeader = CreateContextHeader();
    }
예제 #3
0
        public CbcAuthenticatedEncryptor(Secret keyDerivationKey, BCryptAlgorithmHandle symmetricAlgorithmHandle, uint symmetricAlgorithmKeySizeInBytes, BCryptAlgorithmHandle hmacAlgorithmHandle, IBCryptGenRandom?genRandom = null)
        {
            _genRandom = genRandom ?? BCryptGenRandomImpl.Instance;
            _sp800_108_ctr_hmac_provider           = SP800_108_CTR_HMACSHA512Util.CreateProvider(keyDerivationKey);
            _symmetricAlgorithmHandle              = symmetricAlgorithmHandle;
            _symmetricAlgorithmBlockSizeInBytes    = symmetricAlgorithmHandle.GetCipherBlockLength();
            _symmetricAlgorithmSubkeyLengthInBytes = symmetricAlgorithmKeySizeInBytes;
            _hmacAlgorithmHandle = hmacAlgorithmHandle;
            _hmacAlgorithmDigestLengthInBytes = hmacAlgorithmHandle.GetHashDigestLength();
            _hmacAlgorithmSubkeyLengthInBytes = _hmacAlgorithmDigestLengthInBytes; // for simplicity we'll generate HMAC subkeys with a length equal to the digest length

            // Argument checking on the algorithms and lengths passed in to us
            AlgorithmAssert.IsAllowableSymmetricAlgorithmBlockSize(checked (_symmetricAlgorithmBlockSizeInBytes * 8));
            AlgorithmAssert.IsAllowableSymmetricAlgorithmKeySize(checked (_symmetricAlgorithmSubkeyLengthInBytes * 8));
            AlgorithmAssert.IsAllowableValidationAlgorithmDigestSize(checked (_hmacAlgorithmDigestLengthInBytes * 8));

            _contextHeader = CreateContextHeader();
        }
예제 #4
0
    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);
    }
예제 #5
0
    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);
    }