Example #1
0
        public static unsafe void Decrypt(
            SafeAlgorithmHandle algorithm,
            SafeKeyHandleBCrypt keyHandle,
            ReadOnlySpan <byte> nonce,
            ReadOnlySpan <byte> associatedData,
            ReadOnlySpan <byte> ciphertext,
            ReadOnlySpan <byte> tag,
            Span <byte> plaintext,
            bool clearPlaintextOnFailure)
        {
            fixed(byte *plaintextBytes = plaintext)
            fixed(byte *nonceBytes          = nonce)
            fixed(byte *ciphertextBytes     = ciphertext)
            fixed(byte *tagBytes            = tag)
            fixed(byte *associatedDataBytes = associatedData)
            {
                BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO authInfo = BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO.Create();

                authInfo.pbNonce    = nonceBytes;
                authInfo.cbNonce    = nonce.Length;
                authInfo.pbTag      = tagBytes;
                authInfo.cbTag      = tag.Length;
                authInfo.pbAuthData = associatedDataBytes;
                authInfo.cbAuthData = associatedData.Length;

                NTSTATUS ntStatus = Cng.Interop.BCryptDecrypt(
                    keyHandle,
                    ciphertextBytes,
                    ciphertext.Length,
                    new IntPtr(&authInfo),
                    null,
                    0,
                    plaintextBytes,
                    plaintext.Length,
                    out int plaintextBytesWritten,
                    0);

                Debug.Assert(ciphertext.Length == plaintextBytesWritten);

                switch (ntStatus)
                {
                case NTSTATUS.STATUS_SUCCESS:
                    return;

                case NTSTATUS.STATUS_AUTH_TAG_MISMATCH:
                    if (clearPlaintextOnFailure)
                    {
                        CryptographicOperations.ZeroMemory(plaintext);
                    }

                    throw new CryptographicException(SR.Cryptography_AuthTagMismatch);

                default:
                    throw CreateCryptographicException(ntStatus);
                }
            }
        }
Example #2
0
        public static unsafe void Encrypt(
            SafeAlgorithmHandle algorithm,
            SafeKeyHandleBCrypt keyHandle,
            ReadOnlySpan <byte> nonce,
            ReadOnlySpan <byte> associatedData,
            ReadOnlySpan <byte> plaintext,
            Span <byte> ciphertext,
            Span <byte> tag)
        {
            fixed(byte *plaintextBytes = plaintext)
            fixed(byte *nonceBytes          = nonce)
            fixed(byte *ciphertextBytes     = ciphertext)
            fixed(byte *tagBytes            = tag)
            fixed(byte *associatedDataBytes = associatedData)
            {
                BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO authInfo = BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO.Create();

                authInfo.pbNonce    = nonceBytes;
                authInfo.cbNonce    = nonce.Length;
                authInfo.pbTag      = tagBytes;
                authInfo.cbTag      = tag.Length;
                authInfo.pbAuthData = associatedDataBytes;
                authInfo.cbAuthData = associatedData.Length;

                NTSTATUS ntStatus = Cng.Interop.BCryptEncrypt(
                    keyHandle,
                    plaintextBytes,
                    plaintext.Length,
                    new IntPtr(&authInfo),
                    null,
                    0,
                    ciphertextBytes,
                    ciphertext.Length,
                    out int ciphertextBytesWritten,
                    0);

                Debug.Assert(plaintext.Length == ciphertextBytesWritten);

                if (ntStatus != NTSTATUS.STATUS_SUCCESS)
                {
                    throw CreateCryptographicException(ntStatus);
                }
            }
        }
Example #3
0
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                SafeKeyHandleBCrypt hKey = _hKey;
                _hKey = null;
                if (hKey != null)
                {
                    hKey.Dispose();
                }

                byte[] currentIv = _currentIv;
                _currentIv = null;
                if (currentIv != null)
                {
                    Array.Clear(currentIv, 0, currentIv.Length);
                }
            }

            base.Dispose(disposing);
        }
Example #4
0
        private byte[] _currentIv;  // CNG mutates this with the updated IV for the next stage on each Encrypt/Decrypt call.
                                    // The base IV holds a copy of the original IV for Reset(), until it is cleared by Dispose().

        public BasicSymmetricCipherBCrypt(SafeAlgorithmHandle algorithm, CipherMode cipherMode, int blockSizeInBytes, byte[] key, bool ownsParentHandle, byte[] iv, bool encrypting)
            : base(cipherMode.GetCipherIv(iv), blockSizeInBytes)
        {
            Debug.Assert(algorithm != null);

            _encrypting = encrypting;

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

            _hKey = algorithm.BCryptImportKey(key);

            if (ownsParentHandle)
            {
                _hKey.SetParentHandle(algorithm);
            }

            Reset();
        }
Example #5
0
 private void ImportKey(ReadOnlySpan <byte> key)
 {
     _keyHandle = s_aesCcm.BCryptImportKey(key);
 }