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(); } } }
public unsafe RijndaelCryptoTransform(byte[] rgbKey, byte[] rgbIV, PaddingMode paddingMode, int blockSizeBits, bool encrypt) { if (((rgbKey.Length != 0x10) && (rgbKey.Length != 0x18)) && (rgbKey.Length != 0x20)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(System.IdentityModel.SR.GetString("AESKeyLengthNotSupported", new object[] { rgbKey.Length * 8 }))); } if (rgbIV.Length != 0x10) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(System.IdentityModel.SR.GetString("AESIVLengthNotSupported", new object[] { rgbIV.Length * 8 }))); } if ((paddingMode != PaddingMode.PKCS7) && (paddingMode != PaddingMode.ISO10126)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(System.IdentityModel.SR.GetString("AESPaddingModeNotSupported", new object[] { paddingMode }))); } this.paddingMode = paddingMode; this.blockSize = blockSizeBits / 8; this.encrypt = encrypt; System.IdentityModel.SafeProvHandle phProv = null; System.IdentityModel.SafeKeyHandle phKey = null; try { ThrowIfFalse("AESCryptAcquireContextFailed", System.IdentityModel.NativeMethods.CryptAcquireContextW(out phProv, null, null, 0x18, 0xf0000000)); int cbData = PLAINTEXTKEYBLOBHEADER.SizeOf + rgbKey.Length; byte[] dst = new byte[cbData]; Buffer.BlockCopy(rgbKey, 0, dst, PLAINTEXTKEYBLOBHEADER.SizeOf, rgbKey.Length); fixed(IntPtr *ptrRef = dst) { PLAINTEXTKEYBLOBHEADER *plaintextkeyblobheaderPtr = (PLAINTEXTKEYBLOBHEADER *)ptrRef; plaintextkeyblobheaderPtr->bType = 8; plaintextkeyblobheaderPtr->bVersion = 2; plaintextkeyblobheaderPtr->reserved = 0; if (rgbKey.Length == 0x10) { plaintextkeyblobheaderPtr->aiKeyAlg = 0x660e; } else if (rgbKey.Length == 0x18) { plaintextkeyblobheaderPtr->aiKeyAlg = 0x660f; } else { plaintextkeyblobheaderPtr->aiKeyAlg = 0x6610; } plaintextkeyblobheaderPtr->keyLength = rgbKey.Length; phKey = System.IdentityModel.SafeKeyHandle.SafeCryptImportKey(phProv, (void *)ptrRef, cbData); } fixed(IntPtr *ptrRef2 = rgbIV) { ThrowIfFalse("AESCryptSetKeyParamFailed", System.IdentityModel.NativeMethods.CryptSetKeyParam(phKey, 1, (void *)ptrRef2, 0)); } this.keyHandle = phKey; this.provHandle = phProv; phKey = null; phProv = null; } finally { if (phKey != null) { phKey.Close(); } if (phProv != null) { phProv.Close(); } } }