Example #1
0
        internal BCryptHMAC(CngAlgorithm algorithm,
                            CngProvider algorithmProvider,
                            string hashName,
                            int blockSize,
                            byte[] key)
        {
            Debug.Assert(algorithm != null, "algorithm != null");
            Debug.Assert(algorithmProvider != null, "algorithmProvider != null");
            Debug.Assert(!String.IsNullOrEmpty(hashName), "!String.IsNullOrEmpty(hashName)");
            Debug.Assert(blockSize > 0, "blockSize > 0");
            Debug.Assert(key != null, "key != null");

            BlockSizeValue = blockSize;

            // We set the HashName up to be the CNG version of the hash, since the base type will instantiate
            // the algorithm, and the CNG versions have different FIPS characteristics than the standard implementations.
            HashName = String.Format(CultureInfo.InvariantCulture,
                                     "System.Security.Cryptography.{0}Cng, {1}",
                                     hashName,
                                     typeof(SHA256Cng).Assembly.FullName);

            m_implementation = algorithmProvider;

            m_algorithm = BCryptNative.OpenAlgorithm(algorithm.Algorithm,
                                                     algorithmProvider.Provider,
                                                     BCryptNative.AlgorithmProviderOptions.HmacAlgorithm);

            // Resetting the key will call Initialize for us, and get us setup with a hash handle,
            // so we don't need to create the hash handle ourselves
            Key = key;

            HashSizeValue = BCryptNative.GetInt32Property(m_hash, BCryptNative.HashPropertyName.HashLength) * 8;
        }
Example #2
0
            public static unsafe int HashData(string hashAlgorithmId, ReadOnlySpan <byte> source, Span <byte> destination)
            {
                int hashSize; // in bytes

                // Try using a pseudo-handle if available.
                if (!s_useCompatOneShot)
                {
                    if (HashDataUsingPseudoHandle(hashAlgorithmId, source, destination, out hashSize))
                    {
                        return(hashSize);
                    }
                }

                // Pseudo-handle not available or a precondition check failed.
                // Fall back to a shared handle with no using or dispose.
                SafeBCryptAlgorithmHandle cachedAlgorithmHandle = BCryptAlgorithmCache.GetCachedBCryptAlgorithmHandle(
                    hashAlgorithmId,
                    BCryptOpenAlgorithmProviderFlags.None,
                    out hashSize);

                if (destination.Length < hashSize)
                {
                    throw new CryptographicException();
                }

                HashUpdateAndFinish(cachedAlgorithmHandle, hashSize, source, destination);

                return(hashSize);
            }
Example #3
0
 public Entry(string hashAlgorithmId, BCryptOpenAlgorithmProviderFlags flags, SafeBCryptAlgorithmHandle handle)
     : this()
 {
     HashAlgorithmId = hashAlgorithmId;
     Flags           = flags;
     Handle          = handle;
 }
Example #4
0
        internal BCryptHMAC(CngAlgorithm algorithm,
                            CngProvider algorithmProvider,
                            string hashName,
                            int blockSize,
                            byte[] key)
        {
            Debug.Assert(algorithm != null, "algorithm != null");
            Debug.Assert(algorithmProvider != null, "algorithmProvider != null");
            Debug.Assert(!String.IsNullOrEmpty(hashName), "!String.IsNullOrEmpty(hashName)");
            Debug.Assert(blockSize > 0, "blockSize > 0");
            Debug.Assert(key != null, "key != null");

            BlockSizeValue = blockSize;
            HashName = hashName;

            m_algorithm = BCryptNative.OpenAlgorithm(algorithm.Algorithm,
                                                     algorithmProvider.Provider,
                                                     BCryptNative.AlgorithmProviderOptions.HmacAlgorithm);

            // Resetting the key will call Initialize for us, and get us setup with a hash handle,
            // so we don't need to create the hash handle ourselves
            Key = key;

            HashSizeValue = BCryptNative.GetInt32Property(m_hash, BCryptNative.HashPropertyName.HashLength) * 8;
        }
        private static unsafe void FillDeriveKeyPBKDF2(
            ReadOnlySpan <byte> password,
            ReadOnlySpan <byte> salt,
            int iterations,
            string hashAlgorithmName,
            Span <byte> destination)
        {
            const BCryptOpenAlgorithmProviderFlags OpenAlgorithmFlags = BCryptOpenAlgorithmProviderFlags.BCRYPT_ALG_HANDLE_HMAC_FLAG;

            // This code path will only be taken on Windows 7, so we can assume pseudo handles are not supported.
            // Do not dispose handle since it is shared and cached.
            SafeBCryptAlgorithmHandle handle =
                Interop.BCrypt.BCryptAlgorithmCache.GetCachedBCryptAlgorithmHandle(hashAlgorithmName, OpenAlgorithmFlags, out _);

            fixed(byte *pPassword = password)
            fixed(byte *pSalt        = salt)
            fixed(byte *pDestination = destination)
            {
                NTSTATUS status = Interop.BCrypt.BCryptDeriveKeyPBKDF2(
                    handle,
                    pPassword,
                    password.Length,
                    pSalt,
                    salt.Length,
                    (ulong)iterations,
                    pDestination,
                    destination.Length,
                    dwFlags: 0);

                if (status != NTSTATUS.STATUS_SUCCESS)
                {
                    throw Interop.BCrypt.CreateCryptographicException(status);
                }
            }
        }
Example #6
0
 private void UpdateLegalTagSizes()
 {
     using (SafeBCryptAlgorithmHandle algorithm = SetupAlgorithm())
     {
         UpdateLegalTagSizes(algorithm);
     }
 }
Example #7
0
        internal BCryptAuthenticatedSymmetricAlgorithm(CngAlgorithm algorithm,
                                                       CngProvider implementation,
                                                       KeySizes[] legalBlockSizes,
                                                       KeySizes[] legalKeySizes)
        {
            Debug.Assert(algorithm != null, "algorithm != null");
            Debug.Assert(implementation != null, "implementation != null");
            Debug.Assert(legalBlockSizes != null, "legalBlockSizes != null");
            Debug.Assert(legalKeySizes != null, "legalKeySizes != null");

            m_algorithm      = algorithm;
            m_implementation = implementation;
            m_chainingMode   = CngChainingMode.Gcm;

            LegalBlockSizesValue = legalBlockSizes;
            LegalKeySizesValue   = legalKeySizes;

            // Create a temporary algorithm handle so that we can query it for some properties - such as the
            // block and tag sizes.
            using (SafeBCryptAlgorithmHandle algorithmHandle = SetupAlgorithm())
            {
                // Get block size in bits
                BlockSize = BCryptNative.GetInt32Property(algorithmHandle, BCryptNative.ObjectPropertyName.BlockLength) * 8;

                UpdateLegalTagSizes(algorithmHandle);
            }
        }
Example #8
0
        internal unsafe AeadBulkCipherInstance(SafeBCryptAlgorithmHandle algo, EphemeralBufferPoolWindows bufferPool, BulkCipherType cipherType)
        {
            _bufferPool = bufferPool;
            _algo       = algo;
            switch (cipherType)
            {
            case BulkCipherType.AES_128_GCM:
                _chainingMode = BCRYPT_CHAIN_MODE_GCM;
                _keyLength    = 16;
                _iVLength     = 16;
                _overhead     = 16;
                break;

            case BulkCipherType.AES_256_GCM:
                _chainingMode = BCRYPT_CHAIN_MODE_GCM;
                _keyLength    = 32;
                _iVLength     = 16;
                _overhead     = 16;
                break;

            default:
                Internal.ExceptionHelper.ThrowException(new InvalidOperationException());
                return;
            }
            _keyStore = bufferPool.Rent(0);
            void *tmpPointer;

            if (!_keyStore.Memory.TryGetPointer(out tmpPointer))
            {
                throw new InvalidOperationException("Could not get keystore pointer");
            }
            _ivPointer = (IntPtr)tmpPointer;
        }
Example #9
0
        public IHashInstance GetHashInstance(HashType hashType)
        {
            int size = HashSize(hashType);
            SafeBCryptAlgorithmHandle algo = null;

            switch (hashType)
            {
            case HashType.SHA256:
                algo = _sha256.Item1;
                break;

            case HashType.SHA384:
                algo = _sha384.Item1;
                break;

            case HashType.SHA512:
                algo = _sha512.Item1;
                break;

            default:
                ExceptionHelper.ThrowException(new ArgumentOutOfRangeException(nameof(hashType)));
                break;
            }
            return(new HashInstance(size, algo));
        }
            public static unsafe int HashData(string hashAlgorithmId, ReadOnlySpan <byte> source, Span <byte> destination)
            {
                int hashSize; // in bytes

                // Try using a pseudo-handle if available.
                if (Interop.BCrypt.PseudoHandlesSupported)
                {
                    HashDataUsingPseudoHandle(hashAlgorithmId, source, destination, out hashSize);
                    return(hashSize);
                }
                else
                {
                    // Pseudo-handle not available. Fall back to a shared handle with no using or dispose.
                    SafeBCryptAlgorithmHandle cachedAlgorithmHandle = BCryptAlgorithmCache.GetCachedBCryptAlgorithmHandle(
                        hashAlgorithmId,
                        BCryptOpenAlgorithmProviderFlags.None,
                        out hashSize);

                    if (destination.Length < hashSize)
                    {
                        Debug.Fail("Caller should have checked length.");
                        throw new CryptographicException();
                    }

                    HashUpdateAndFinish(cachedAlgorithmHandle, hashSize, source, destination);

                    return(hashSize);
                }
            }
Example #11
0
 public KeyshareProvider()
 {
     _x25519    = GetECProvider("curve25519");
     _secp256r1 = GetECProvider("secP256r1");
     _secp384r1 = GetECProvider("secP384r1");
     _secp521r1 = GetECProvider("secP521r1");
 }
Example #12
0
 private static extern ErrorCode BCryptCreateHash(SafeBCryptAlgorithmHandle hAlgorithm,
                                                  [Out] out SafeBCryptHashHandle phHash,
                                                  [MarshalAs(UnmanagedType.LPArray), In, Out] byte[] pbHashObject,
                                                  int cbHashObject,
                                                  IntPtr pbSecret,
                                                  int cbSecret,
                                                  BCryptAlgorithmFlags dwFlags);
Example #13
0
        public RNGCng(CngProvider algorithmProvider)
        {
            if (algorithmProvider == null)
                throw new ArgumentNullException("algorithmProvider");

            m_algorithm = BCryptNative.OpenAlgorithm(BCryptNative.AlgorithmName.Rng,
                                                     algorithmProvider.Provider);
        }
Example #14
0
 internal static unsafe partial NTSTATUS BCryptGenerateSymmetricKey(
     SafeBCryptAlgorithmHandle hAlgorithm,
     out SafeBCryptKeyHandle phKey,
     IntPtr pbKeyObject,
     int cbKeyObject,
     byte *pbSecret,
     int cbSecret,
     uint dwFlags);
Example #15
0
 internal BCryptAuthenticatedSymmetricCryptoTransform(SafeBCryptAlgorithmHandle algorithm,
                                                      byte[] key,
                                                      byte[] nonce,
                                                      byte[] authenticatedData,
                                                      bool chainingSupported,
                                                      int tagSize) :
     this(algorithm, key, nonce, authenticatedData, new byte[tagSize / 8], chainingSupported)
 {
     m_encrypting = true;
 }
 internal static extern int BCryptDeriveKeyPBKDF2(
     SafeBCryptAlgorithmHandle hPrf,
     byte[] pbPassword,
     int cbPassword,
     byte[] pbSalt,
     int cbSalt,
     long cIterations,
     byte[] derivedKey,
     int cbDerivedKey,
     int dwFlags);
Example #17
0
 internal static extern unsafe NTSTATUS BCryptDeriveKeyPBKDF2(
     SafeBCryptAlgorithmHandle hPrf,
     byte *pbPassword,
     int cbPassword,
     byte *pbSalt,
     int cbSalt,
     ulong cIterations,
     byte *pbDerivedKey,
     int cbDerivedKey,
     uint dwFlags);
Example #18
0
            public static unsafe int HashData(string hashAlgorithmId, ReadOnlySpan <byte> source, Span <byte> destination)
            {
                // Shared handle, no using or dispose.
                SafeBCryptAlgorithmHandle cachedAlgorithmHandle = BCryptAlgorithmCache.GetCachedBCryptAlgorithmHandle(
                    hashAlgorithmId,
                    BCryptOpenAlgorithmProviderFlags.None);

                int hashSize;

                NTSTATUS ntStatus = Interop.BCrypt.BCryptGetProperty(
                    cachedAlgorithmHandle,
                    Interop.BCrypt.BCryptPropertyStrings.BCRYPT_HASH_LENGTH,
                    &hashSize,
                    sizeof(int),
                    out _,
                    0);

                if (ntStatus != NTSTATUS.STATUS_SUCCESS)
                {
                    throw Interop.BCrypt.CreateCryptographicException(ntStatus);
                }

                if (destination.Length < hashSize)
                {
                    throw new CryptographicException();
                }

                if (!s_useCompatOneShot)
                {
                    try
                    {
                        fixed(byte *pSource = source)
                        fixed(byte *pDestination = destination)
                        {
                            ntStatus = Interop.BCrypt.BCryptHash(cachedAlgorithmHandle, null, 0, pSource, source.Length, pDestination, hashSize);

                            if (ntStatus != NTSTATUS.STATUS_SUCCESS)
                            {
                                throw Interop.BCrypt.CreateCryptographicException(ntStatus);
                            }
                        }

                        return(hashSize);
                    }
                    catch (EntryPointNotFoundException)
                    {
                        s_useCompatOneShot = true;
                    }
                }

                Debug.Assert(s_useCompatOneShot);
                HashUpdateAndFinish(cachedAlgorithmHandle, hashSize, source, destination);

                return(hashSize);
            }
Example #19
0
 private static void HashUpdateAndFinish(
     SafeBCryptAlgorithmHandle algHandle,
     int hashSize,
     ReadOnlySpan <byte> source,
     Span <byte> destination)
 {
     NTSTATUS ntStatus = Interop.BCrypt.BCryptCreateHash(
         algHandle,
         out SafeBCryptHashHandle hHash,
         IntPtr.Zero,
         0,
Example #20
0
 internal static void DisposeMD5Handles()
 {
     lock (syncObject)
     {
         if (algorithmHandle != null)
         {
             algorithmHandle.Dispose();
             algorithmHandle = null;
         }
     }
 }
Example #21
0
        public RNGCng(CngProvider algorithmProvider)
        {
            if (algorithmProvider == null)
            {
                throw new ArgumentNullException("algorithmProvider");
            }

            m_algorithm = BCryptNative.OpenAlgorithm(BCryptNative.AlgorithmName.Rng,
                                                     algorithmProvider.Provider);

            m_implementation = algorithmProvider;
        }
Example #22
0
        private SafeBCryptAlgorithmHandle SetupAlgorithm()
        {
            // Open the algorithm handle
            SafeBCryptAlgorithmHandle algorithm =
                BCryptNative.OpenAlgorithm(m_algorithm.Algorithm, m_implementation.Provider);

            // Set the chaining mode
            BCryptNative.SetStringProperty(algorithm,
                                           BCryptNative.ObjectPropertyName.ChainingMode,
                                           m_chainingMode.ChainingMode);

            return(algorithm);
        }
        private SafeBCryptAlgorithmHandle SetupAlgorithm()
        {
            SafeBCryptAlgorithmHandle algorithmHandle = BCryptNative.OpenAlgorithm(m_algorithm.Algorithm, m_algorithmProvider.Provider);

            // If we've selected a different block size than the default, set that now
            if (BlockSize / 8 != BCryptNative.GetInt32Property(algorithmHandle, BCryptNative.ObjectPropertyName.BlockLength))
            {
                BCryptNative.SetInt32Property(algorithmHandle, BCryptNative.ObjectPropertyName.BlockLength, BlockSize / 8);
            }

            BCryptNative.SetStringProperty(algorithmHandle, BCryptNative.ObjectPropertyName.ChainingMode, m_chainingMode.ChainingMode);

            return(algorithmHandle);
        }
        private ICryptoTransform CreateEphemeralCryptoTransformCore(byte[] key, byte[] iv, bool encrypting)
        {
            int blockSizeInBytes = _outer.BlockSize.BitSizeToByteSize();
            SafeBCryptAlgorithmHandle algorithmModeHandle = _outer.GetEphemeralModeHandle();

            BasicSymmetricCipher cipher = new BasicSymmetricCipherBCrypt(
                algorithmModeHandle,
                _outer.Mode,
                blockSizeInBytes,
                key,
                iv,
                encrypting);

            return(UniversalCryptoTransform.Create(_outer.Padding, cipher, encrypting));
        }
        public BasicSymmetricCipherBCrypt(SafeBCryptAlgorithmHandle algorithm, CipherMode cipherMode, int blockSizeInBytes, byte[] key, byte[] iv, bool encrypting)
            : base(cipherMode.GetCipherIv(iv), blockSizeInBytes)
        {
            Debug.Assert(algorithm != null);

            _encrypting = encrypting;

            if (IV != null)
            {
                _currentIv = new byte[IV.Length];
            }

            _hKey = BCryptNative.BCryptImportKey(algorithm, key);

            Reset();
        }
Example #26
0
        internal BCryptSymmetricCryptoTransform(SafeBCryptAlgorithmHandle algorithm,
                                                byte[] key,
                                                byte[] iv,
                                                PaddingMode paddingMode,
                                                bool encrypting)
        {
            Debug.Assert(algorithm != null, "algorithm != null");
            Debug.Assert(!algorithm.IsClosed && !algorithm.IsInvalid, "!algorithm.IsClosed && !algorithm.IsInvalid");
            Debug.Assert(key != null, "key != null");

            m_algorithm  = algorithm;
            m_encrypting = encrypting;

            m_paddingMode = BlockPaddingMethod.Create(paddingMode,
                                                      BCryptNative.GetInt32Property(algorithm, BCryptNative.ObjectPropertyName.BlockLength));
            m_iv = ProcessIV(iv, BCryptNative.GetInt32Property(algorithm,
                                                               BCryptNative.ObjectPropertyName.BlockLength),
                             BCryptNative.MapChainingMode(BCryptNative.GetStringProperty(algorithm, BCryptNative.ObjectPropertyName.ChainingMode)));
            m_key = BCryptNative.ImportSymmetricKey(algorithm, key);
        }
        internal BCryptSymmetricCryptoTransform(SafeBCryptAlgorithmHandle algorithm,
                                                byte[] key,
                                                byte[] iv,
                                                PaddingMode paddingMode,
                                                bool encrypting)
        {
            Debug.Assert(algorithm != null, "algorithm != null");
            Debug.Assert(!algorithm.IsClosed && !algorithm.IsInvalid, "!algorithm.IsClosed && !algorithm.IsInvalid");
            Debug.Assert(key != null, "key != null");

            m_algorithm = algorithm;
            m_encrypting = encrypting;

            m_paddingMode = BlockPaddingMethod.Create(paddingMode,
                                                      BCryptNative.GetInt32Property(algorithm, BCryptNative.ObjectPropertyName.BlockLength));
            m_iv = ProcessIV(iv, BCryptNative.GetInt32Property(algorithm,
                                                               BCryptNative.ObjectPropertyName.BlockLength),
                                                               BCryptNative.MapChainingMode(BCryptNative.GetStringProperty(algorithm, BCryptNative.ObjectPropertyName.ChainingMode)));
            m_key = BCryptNative.ImportSymmetricKey(algorithm, key);
        }
Example #28
0
        private void UpdateLegalTagSizes(SafeBCryptAlgorithmHandle algorithm)
        {
            Debug.Assert(algorithm != null, "algorithm != null");
            Debug.Assert(!algorithm.IsClosed && !algorithm.IsInvalid, "!algorithm.IsClosed && !algorithm.IsInvalid");

            // Get the authentication tag length structure.
            BCryptNative.BCRYPT_KEY_LENGTHS_STRUCT tagLengths =
                BCryptNative.GetValueTypeProperty <SafeBCryptAlgorithmHandle, BCryptNative.BCRYPT_KEY_LENGTHS_STRUCT>(
                    algorithm,
                    BCryptNative.ObjectPropertyName.AuthTagLength);

            // BCrypt returns the tag sizes in bytes, convert them to bits for the LegalTagSizes property
            LegalTagSizesValue = new KeySizes[]
            {
                new KeySizes(tagLengths.dwMinLength * 8, tagLengths.dwMaxLength * 8, tagLengths.dwIncrement * 8)
            };

            // By default, generate the maximum authentication tag length possible for this algorithm
            TagSize = tagLengths.dwMaxLength * 8;
        }
 internal static extern NTSTATUS BCryptOpenAlgorithmProvider(out SafeBCryptAlgorithmHandle phAlgorithm, string pszAlgId, string pszImplementation, BCryptOpenAlgorithmProviderFlags dwFlags);
Example #30
0
 internal static extern int BCryptCreateHash(SafeBCryptAlgorithmHandle algorithmHandle, out SafeBCryptHashHandle hashHandle, IntPtr hashObject, int hashObjectByteLength, [In, Out] byte[] secretBuffer, int secretByteLength, BCryptCreateHashFlags flags);
Example #31
0
 internal static extern int BCryptOpenAlgorithmProvider(out SafeBCryptAlgorithmHandle algorithmHandle, string algIdString, string implementationString, BCryptOpenAlgorithmProviderFlags flags);
 internal static extern NTSTATUS BCryptCreateHash(SafeBCryptAlgorithmHandle hAlgorithm, out SafeBCryptHashHandle phHash, IntPtr pbHashObject, int cbHashObject, [In, Out] byte[] pbSecret, int cbSecret, BCryptCreateHashFlags dwFlags);
Example #33
0
 public static extern NTStatus BCryptGetProperty(SafeBCryptAlgorithmHandle hObject, [MarshalAs(UnmanagedType.LPWStr)] string pszProperty, byte[] pbOutput, int cbOutput, out uint pcbResult, int dwFlags = 0);