internal static extern unsafe bool CryptImportKey([In] SafeProvHandle hProv, [In] void *pbData, [In] uint dwDataLen, [In] IntPtr hPubKey, [In] uint dwFlags, out SafeKeyHandle phKey);
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 CryptAcquireContextW(out SafeProvHandle phProv, [In] string pszContainer, [In] string pszProvider, [In] uint dwProvType, [In] uint dwFlags);