protected override bool ReleaseHandle()
        {
            // PreSharp 
#pragma warning suppress 56523 // We are not interested in throwing an exception here if CloseHandle fails.
            bool ret = NativeMethods.CryptDestroyKey(handle);
            if (this.provHandle != null)
            {
                this.provHandle.DangerousRelease();
                this.provHandle = null;
            }
            return ret;
        }
        protected override bool ReleaseHandle()
        {
            // PreSharp Bug: Call 'Marshal.GetLastWin32Error' or 'Marshal.GetHRForLastWin32Error' before any other interop call. 
#pragma warning suppress 56523 // We are not interested in throwing an exception here if CloseHandle fails.
            bool ret = NativeMethods.CryptDestroyKey(handle);
            if (this.provHandle != null)
            {
                this.provHandle.DangerousRelease();
                this.provHandle = null;
            }
            return ret;
        }
        internal static unsafe SafeKeyHandle SafeCryptImportKey(SafeProvHandle provHandle, void* pbDataPtr, int cbData)
        {
            bool b = false;
            int err = 0;
            SafeKeyHandle keyHandle = null;
            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                provHandle.DangerousAddRef(ref b);
            }
            catch (Exception e)
            {
                if (System.Runtime.Fx.IsFatal(e))
                    throw;
                
                if (b)
                {
                    provHandle.DangerousRelease();
                    b = false;
                }
                if (!(e is ObjectDisposedException))
                    throw;
            }
            finally
            {
                if (b)
                {
                    b = NativeMethods.CryptImportKey(provHandle, pbDataPtr, (uint)cbData, IntPtr.Zero, 0, out keyHandle);
                    if (!b)
                    {
                        err = Marshal.GetLastWin32Error();
                        provHandle.DangerousRelease();
                    }
                    else
                    {
                        // Take ownership of AddRef.  Will Release at Close.
                        keyHandle.provHandle = provHandle;
                    }
                }
            }

            if (!b)
            {
                Utility.CloseInvalidOutSafeHandle(keyHandle);
                string reason = (err != 0) ? new Win32Exception(err).Message : String.Empty;
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.GetString(SR.AESCryptImportKeyFailed, reason)));
            }
            return keyHandle;
        }
Beispiel #4
0
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                SafeKeyHandle hKey = _hKey;
                _hKey = null !;
                if (hKey != null)
                {
                    hKey.Dispose();
                }

                SafeProvHandle hProvider = _hProvider;
                _hProvider = null !;
                if (hProvider != null)
                {
                    hProvider.Dispose();
                }
            }

            base.Dispose(disposing);
        }
Beispiel #5
0
        public BasicSymmetricCipherCsp(int algId, CipherMode cipherMode, int blockSizeInBytes, byte[] key, int effectiveKeyLength, bool addNoSaltFlag, byte[]?iv, bool encrypting)
            : base(cipherMode.GetCipherIv(iv), blockSizeInBytes)
        {
            _encrypting = encrypting;

            _hProvider = AcquireSafeProviderHandle();
            _hKey      = ImportCspBlob(_hProvider, algId, key, addNoSaltFlag);

            SetKeyParameter(_hKey, CryptGetKeyParamQueryType.KP_MODE, (int)cipherMode);

            byte[]? currentIv = cipherMode.GetCipherIv(iv);
            if (currentIv != null)
            {
                SetKeyParameter(_hKey, CryptGetKeyParamQueryType.KP_IV, currentIv);
            }

            if (effectiveKeyLength != 0)
            {
                SetKeyParameter(_hKey, CryptGetKeyParamQueryType.KP_EFFECTIVE_KEYLEN, effectiveKeyLength);
            }
        }
Beispiel #6
0
            private void ImportShortKeyToCSP(SafeProvHandle hProv, int keyCalg, int keyHashCalg, out SafeKeyHandle hMacKey)
            {
                SafeHashHandle hTmpHash;

                if (!Interop.Advapi32.CryptCreateHash(hProv, keyHashCalg, SafeKeyHandle.InvalidHandle, Interop.Advapi32.CryptCreateHashFlags.None, out hTmpHash))
                {
                    int hr = Interop.CPError.GetHRForLastWin32Error();
                    throw new CryptographicException(hr);
                }
                if (!Interop.Advapi32.CryptSetHashParam(hTmpHash, Interop.Advapi32.CryptHashProperty.HP_HASHVAL, _key, 0))
                {
                    int hr = Interop.CPError.GetHRForLastWin32Error();
                    throw new CryptographicException(hr);
                }
                if (!Interop.Advapi32.CryptDeriveKey(hProv, keyCalg, hTmpHash, _key.Length << 19, out hMacKey))
                {
                    int hr = Interop.CPError.GetHRForLastWin32Error();
                    throw new CryptographicException(hr);
                }
                hTmpHash.Dispose();
            }
Beispiel #7
0
            internal CryptoApiHashProvider(int providerType, int calgHash)
            {
                SafeProvHandle hProv;

                if (!Interop.Advapi32.CryptAcquireContext(out hProv, null, null, providerType, (uint)Interop.Advapi32.CryptAcquireContextFlags.CRYPT_VERIFYCONTEXT))
                {
                    int hr = Interop.CPError.GetHRForLastWin32Error();
                    throw new CryptographicException(hr);
                }
                SafeHashHandle hHash;

                if (!Interop.Advapi32.CryptCreateHash(hProv, calgHash, SafeKeyHandle.InvalidHandle, (int)Interop.Advapi32.CryptCreateHashFlags.None, out hHash))
                {
                    int hr = Interop.CPError.GetHRForLastWin32Error();
                    throw new CryptographicException(hr);
                }

                int dwHashSize = 0;
                int cbHashSize = sizeof(int);

                if (!Interop.Advapi32.CryptGetHashParam(hHash, Interop.Advapi32.CryptHashProperty.HP_HASHSIZE, out dwHashSize, ref cbHashSize, 0))
                {
                    int hr = Interop.CPError.GetHRForLastWin32Error();
                    throw new CryptographicException(hr);
                }
                if (dwHashSize < 0)
                {
                    throw new PlatformNotSupportedException(
                              SR.Format(
                                  SR.Cryptography_UnknownHashAlgorithm, providerType, calgHash));
                }
                HashSizeInBytes = dwHashSize;
                _calgHash       = calgHash;
                _hHash          = hHash;
                _hProv          = hProv;
                _hHash.SetParent(_hProv);
            }
        internal static int EncryptDataCp(SafeProvHandle hProv, SafeKeyHandle hKey, byte[] data,
                                          int ib, int cb, ref byte[] outputBuffer, int outputOffset,
                                          PaddingMode paddingMode, bool fDone, bool isStream)
        {
            int dwDataLen = (int)cb; // ebp+0x58
            int bufLength = cb;      // ebp+0x34

            if (fDone)
            {
                // Мы не используем в отличии от MS реализации Final
                // поэтому на 8 байт CAPI Padding меньше
                bufLength += 8;
            }
            int remainder = cb & 7; // ebp+0x30

            if (cb < 0)
            {
                throw new ArgumentOutOfRangeException("cb", SR.ArgumentOutOfRange_NeedNonNegNum);
            }
            if (ib < 0)
            {
                throw new ArgumentOutOfRangeException("ib", SR.ArgumentOutOfRange_NeedNonNegNum);
            }
            if (ib > data.Length)
            {
                throw new ArgumentException(SR.Argument_InvalidValue, "ib");
            }
            byte[] tmpBuffer = new byte[bufLength]; // ebp + 0x4c
            Array.Clear(tmpBuffer, 0, bufLength);
            Array.Copy(data, ib, tmpBuffer, 0, cb);
            if (fDone)
            {
                byte fill = (byte)(8 - remainder); // ebp - 0x28;
                switch (paddingMode)
                {
                case PaddingMode.None:     // [data]
                    if (remainder == 0)
                    {
                        break;
                    }
                    if (isStream)
                    {
                        break;
                    }
                    throw new CryptographicException(
                              SR.Cryptography_InvalidPaddingMode);

                case PaddingMode.PKCS7: // [data] [length..length]
                {
                    int c = cb;         // ebp+0x44;
                    dwDataLen += fill;
                    while (c < dwDataLen)
                    {
                        tmpBuffer[c++] = fill;
                    }
                }
                break;

                case PaddingMode.Zeros:     // [data] [0..0]
                    if (remainder == 0)
                    {
                        break;
                    }
                    dwDataLen += fill;
                    break;

                case PaddingMode.ANSIX923: // [data] [0..0] [length]
                {
                    int c = cb;            // ebp+0x48;
                    dwDataLen += fill;
                    // без while: итак 0.
                    tmpBuffer[dwDataLen - 1] = fill;
                    break;
                }

                case PaddingMode.ISO10126:     // [data] [random] [length]
                {
                    byte[] tmpBuf = new byte[fill - 1];
                    if (hProv == null || hProv.IsInvalid)
                    {
                        CspParameters gostParameters = new CspParameters(GostConstants.PROV_GOST_2001_DH);
                        using (var rng = new GostRngCryptoServiceProvider(gostParameters))
                        {
                            rng.GetBytes(tmpBuf);
                        }
                    }
                    else
                    {
                        using (var rng = new GostRngCryptoServiceProvider(hProv))
                        {
                            rng.GetBytes(tmpBuf);
                        }
                    }
                    tmpBuf.CopyTo(tmpBuffer, cb);
                    dwDataLen += fill;
                    tmpBuffer[dwDataLen - 1] = fill;
                    break;
                }

                default:
                    throw new ArgumentException(
                              SR.Cryptography_InvalidPaddingMode
                              );
                }
            }
            // Утверждалось, что "Это похоже ошибка CSP. Не дает шифровать 0 байт в конце."
            // if (dwDataLen != 0)
            //
            // Не используем CAPI Padding!
            bool ret = Interop.Advapi32.CryptEncrypt(hKey, SafeHashHandle.InvalidHandle,
                                                     false, 0, tmpBuffer,
                                                     ref dwDataLen, (int)bufLength);

            if (!ret)
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }
            if (outputBuffer == null)
            {
                outputBuffer = new byte[dwDataLen];
                Array.Copy(tmpBuffer, 0, outputBuffer, 0, dwDataLen);
            }
            else
            {
                if (outputOffset < 0)
                {
                    throw new ArgumentOutOfRangeException("outputOffset", SR.ArgumentOutOfRange_NeedNonNegNum);
                }
                if (outputBuffer.Length < dwDataLen)
                {
                    throw new ArgumentException(SR.Argument_InvalidValue);
                }
                if (outputBuffer.Length - dwDataLen < outputOffset)
                {
                    throw new ArgumentException(SR.Argument_InvalidValue);
                }
                Array.Copy(tmpBuffer, 0, outputBuffer, outputOffset, dwDataLen);
            }
            return((int)dwDataLen);
        }
Beispiel #9
0
        public static extern bool CryptSetProvParam(
#endif
            SafeProvHandle hProv,
            CryptProvParam dwParam,
            ref IntPtr pbData,
            int dwFlags);
Beispiel #10
0
 internal static extern bool CryptGenRandom(SafeProvHandle hProv, int dwLen, byte[] pbBuffer);
Beispiel #11
0
 internal static partial bool CryptCreateHash(
     SafeProvHandle hProv,
     int Algid,
     SafeCapiKeyHandle hKey,
     CryptCreateHashFlags dwFlags,
     out SafeHashHandle phHash);
            public unsafe RijndaelCryptoTransform(byte[] rgbKey, byte[] rgbIV, PaddingMode paddingMode, int blockSizeBits, bool encrypt)
            {
                if (rgbKey.Length != 16 && rgbKey.Length != 24 && rgbKey.Length != 32)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.AESKeyLengthNotSupported, rgbKey.Length * 8)));
                if (rgbIV.Length != 16)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.AESIVLengthNotSupported, rgbIV.Length * 8)));
                if (paddingMode != PaddingMode.PKCS7 && paddingMode != PaddingMode.ISO10126)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.AESPaddingModeNotSupported, paddingMode)));

                this.paddingMode = paddingMode;
                DiagnosticUtility.DebugAssert((blockSizeBits % 8) == 0, "Bits must be byte aligned.");
                this.blockSize = blockSizeBits / 8;
                this.encrypt = encrypt;

                SafeProvHandle provHandle = null;
                SafeKeyHandle keyHandle = null;
                try
                {
#pragma warning suppress 56523
                    ThrowIfFalse(SR.AESCryptAcquireContextFailed, NativeMethods.CryptAcquireContextW(out provHandle, null, null, NativeMethods.PROV_RSA_AES, NativeMethods.CRYPT_VERIFYCONTEXT));

                    // (BLOBHEADER + keyLen) + Key
                    int cbData = PLAINTEXTKEYBLOBHEADER.SizeOf + rgbKey.Length;
                    byte[] pbData = new byte[cbData];
                    Buffer.BlockCopy(rgbKey, 0, pbData, PLAINTEXTKEYBLOBHEADER.SizeOf, rgbKey.Length);
                    fixed (void* pbDataPtr = &pbData[0])
                    {
                        PLAINTEXTKEYBLOBHEADER* pbhdr = (PLAINTEXTKEYBLOBHEADER*)pbDataPtr;
                        pbhdr->bType = NativeMethods.PLAINTEXTKEYBLOB;
                        pbhdr->bVersion = NativeMethods.CUR_BLOB_VERSION;
                        pbhdr->reserved = 0;
                        if (rgbKey.Length == 16)
                            pbhdr->aiKeyAlg = NativeMethods.CALG_AES_128;
                        else if (rgbKey.Length == 24)
                            pbhdr->aiKeyAlg = NativeMethods.CALG_AES_192;
                        else
                            pbhdr->aiKeyAlg = NativeMethods.CALG_AES_256;
                        pbhdr->keyLength = rgbKey.Length;

                        keyHandle = SafeKeyHandle.SafeCryptImportKey(provHandle, pbDataPtr, cbData);
                    }
#if DEBUG
                    uint ivLen = 0;
#pragma warning suppress 56523 // win32 error checked in ThrowIfFalse() method
                    ThrowIfFalse(SR.AESCryptGetKeyParamFailed, NativeMethods.CryptGetKeyParam(keyHandle, NativeMethods.KP_IV, IntPtr.Zero, ref ivLen, 0));
                    DiagnosticUtility.DebugAssert(rgbIV.Length == ivLen, "Mismatch iv size");
#endif
                    fixed (void* pbIVPtr = &rgbIV[0])
                    {
#pragma warning suppress 56523
                        ThrowIfFalse(SR.AESCryptSetKeyParamFailed, NativeMethods.CryptSetKeyParam(keyHandle, NativeMethods.KP_IV, pbIVPtr, 0));
                    }

                    // Save
                    this.keyHandle = keyHandle;
                    this.provHandle = provHandle;
                    keyHandle = null;
                    provHandle = null;
                }
                finally
                {
                    if (keyHandle != null)
                        keyHandle.Close();
                    if (provHandle != null)
                        provHandle.Close();
                }
            }
Beispiel #13
0
 internal static extern bool CryptDeriveKey(
     SafeProvHandle hProv,
     int Algid,
     SafeHashHandle hBaseData,
     int dwFlags,
     out SafeKeyHandle phKey);
 internal static partial bool CryptGenKey(SafeProvHandle hProv, int Algid, int dwFlags, out SafeKeyHandle phKey);
 internal static extern bool CryptCreateHash(
     SafeProvHandle hProv,
     int Algid,
     SafeKeyHandle hKey,
     CryptCreateHashFlags dwFlags,
     out SafeHashHandle phHash);
 internal static extern bool CryptGetUserKey(SafeProvHandle hProv, int dwKeySpec, out SafeKeyHandle phUserKey);
 public static partial bool CryptSetProvParam(
     SafeProvHandle hProv,
     CryptProvParam dwParam,
     ref IntPtr pbData,
     int dwFlags);
Beispiel #18
0
 public static extern bool CryptContextAddRef(
     SafeProvHandle hProv,
     byte[] pdwReserved,
     uint dwFlags);
Beispiel #19
0
 internal static partial bool CryptGetUserKey(SafeProvHandle hProv, int dwKeySpec, out SafeCapiKeyHandle phUserKey);
 public static extern bool CryptAcquireContext(
     out SafeProvHandle phProv,
     string szContainer,
     string szProvider,
     int dwProvType,
     uint dwFlags);