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; }
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); }
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); } }
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(); }
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); }
public static extern bool CryptSetProvParam( #endif SafeProvHandle hProv, CryptProvParam dwParam, ref IntPtr pbData, int dwFlags);
internal static extern bool CryptGenRandom(SafeProvHandle hProv, int dwLen, byte[] pbBuffer);
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(); } }
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);
public static extern bool CryptContextAddRef( SafeProvHandle hProv, byte[] pdwReserved, uint dwFlags);
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);