Created
October 8, 2015 13:27
-
-
Save Metaluim/fcf9a4f1012fdeb2a44f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[System.Security.SecuritySafeCritical] // auto-generated | |
private unsafe int DecryptData(byte[] inputBuffer, | |
int inputOffset, | |
int inputCount, | |
ref byte[] outputBuffer, | |
int outputOffset, | |
PaddingMode paddingMode, | |
bool fLast) { | |
if (inputBuffer.Length < inputOffset + inputCount) | |
throw new CryptographicException(Environment.GetResourceString("Cryptography_InsufficientBuffer")); | |
if (outputBuffer == null) { | |
outputBuffer = new byte[inputCount]; | |
outputOffset = 0; | |
} else { | |
if ((outputBuffer.Length - outputOffset) < inputCount) | |
throw new CryptographicException(Environment.GetResourceString("Cryptography_InsufficientBuffer")); | |
} | |
fixed (int* encryptindex = m_encryptindex) { | |
fixed (int* encryptKeyExpansion = m_encryptKeyExpansion) { | |
fixed (int* decryptindex = m_decryptindex) { | |
fixed (int* decryptKeyExpansion = m_decryptKeyExpansion) { | |
fixed (int *T = s_T) { | |
fixed (int *TF = s_TF) { | |
fixed (int *iT = s_iT) { | |
fixed (int *iTF = s_iTF) { | |
int* work = stackalloc int[m_Nb]; | |
int* temp = stackalloc int[m_Nb]; | |
int iNumBlocks = inputCount / m_inputBlockSize; | |
int workBaseIndex = inputOffset, index = 0, transformCount = outputOffset; | |
for (int blockNum = 0; blockNum < iNumBlocks; ++blockNum) { | |
#if FEATURE_CRYPTO // see code:System.Security.Cryptography.RijndaelManaged#CoreCLRRijndaelModes | |
if (m_cipherMode == CipherMode.CFB) { | |
index = 0; | |
for (int i = 0; i < m_Nb; ++i) { | |
int i0 = m_shiftRegister[index++]; | |
int i1 = m_shiftRegister[index++]; | |
int i2 = m_shiftRegister[index++]; | |
int i3 = m_shiftRegister[index++]; | |
work[i] = i3 << 24 | i2 << 16 | i1 << 8 | i0; | |
} | |
} else { | |
#endif // FEATURE_CRYPTO | |
index = workBaseIndex; | |
for (int i = 0; i < m_Nb; ++i) { | |
int i0 = inputBuffer[index++]; | |
int i1 = inputBuffer[index++]; | |
int i2 = inputBuffer[index++]; | |
int i3 = inputBuffer[index++]; | |
work[i] = i3 << 24 | i2 << 16 | i1 << 8 | i0; | |
} | |
#if FEATURE_CRYPTO | |
} | |
#endif // FEATURE_CRYPTO | |
#if FEATURE_CRYPTO | |
if (m_cipherMode == CipherMode.CFB) { | |
// We use the encryption function in both encryption and decryption in CFB mode. | |
Enc(encryptindex, encryptKeyExpansion, T, TF, work, temp); | |
index = workBaseIndex; | |
for (int i = 0; i < m_Nb; ++i) { | |
if (index >= workBaseIndex + m_inputBlockSize) break; | |
outputBuffer[transformCount++] = (byte)((temp[i] & 0xFF) ^ inputBuffer[index++]); | |
if (index >= workBaseIndex + m_inputBlockSize) break; | |
outputBuffer[transformCount++] = (byte)((temp[i] >> 8 & 0xFF) ^ inputBuffer[index++]); | |
if (index >= workBaseIndex + m_inputBlockSize) break; | |
outputBuffer[transformCount++] = (byte)((temp[i] >> 16 & 0xFF) ^ inputBuffer[index++]); | |
if (index >= workBaseIndex + m_inputBlockSize) break; | |
outputBuffer[transformCount++] = (byte)((temp[i] >> 24 & 0xFF) ^ inputBuffer[index++]); | |
} | |
// shift m_lastBlockBuffer to the left by m_inputBlockSize bytes. | |
index = 0; | |
while (index < m_blockSizeBytes - m_inputBlockSize) { | |
m_shiftRegister[index] = m_shiftRegister[index + m_inputBlockSize]; | |
index++; | |
} | |
Buffer.InternalBlockCopy(inputBuffer, workBaseIndex, m_shiftRegister, m_blockSizeBytes - m_inputBlockSize, m_inputBlockSize); | |
} else { | |
#endif // FEATURE_CRYPTO | |
Dec(decryptindex, decryptKeyExpansion, iT, iTF, work, temp); | |
#if FEATURE_CRYPTO | |
if (m_cipherMode == CipherMode.CBC) { | |
#endif // FEATURE_CRYPTO | |
index = workBaseIndex; | |
for (int i = 0; i < m_Nb; ++i) { | |
temp[i] ^= m_lastBlockBuffer[i]; | |
// save the input buffer | |
int i0 = inputBuffer[index++]; | |
int i1 = inputBuffer[index++]; | |
int i2 = inputBuffer[index++]; | |
int i3 = inputBuffer[index++]; | |
m_lastBlockBuffer[i] = i3 << 24 | i2 << 16 | i1 << 8 | i0; | |
} | |
#if FEATURE_CRYPTO | |
} | |
#endif // FEATURE_CRYPTO | |
for (int i = 0; i < m_Nb; ++i) { | |
outputBuffer[transformCount++] = (byte)(temp[i] & 0xFF); | |
outputBuffer[transformCount++] = (byte)(temp[i] >> 8 & 0xFF); | |
outputBuffer[transformCount++] = (byte)(temp[i] >> 16 & 0xFF); | |
outputBuffer[transformCount++] = (byte)(temp[i] >> 24 & 0xFF); | |
} | |
#if FEATURE_CRYPTO | |
} | |
#endif // FEATURE_CRYPTO | |
workBaseIndex += m_inputBlockSize; | |
} | |
if (fLast == false) | |
return inputCount; | |
// this is the last block, remove the padding. | |
byte[] outputBuffer1 = outputBuffer; | |
int padSize = 0; | |
#if FEATURE_CRYPTO // see code:System.Security.Cryptography.RijndaelManaged#CoreCLRRijndaelModes | |
switch (paddingMode) { | |
case PaddingMode.None: | |
break; | |
case PaddingMode.Zeros: | |
break; | |
case PaddingMode.PKCS7: | |
#endif // FEATURE_CRYPTO | |
if (inputCount == 0) | |
throw new CryptographicException(Environment.GetResourceString("Cryptography_PKCS7_InvalidPadding")); | |
padSize = outputBuffer[inputCount - 1]; | |
if (padSize > outputBuffer.Length || padSize > InputBlockSize || padSize <= 0) | |
throw new CryptographicException(Environment.GetResourceString("Cryptography_PKCS7_InvalidPadding")); | |
for (index = 1; index <= padSize; index++) | |
if (outputBuffer[inputCount - index] != padSize) | |
throw new CryptographicException(Environment.GetResourceString("Cryptography_PKCS7_InvalidPadding")); | |
outputBuffer1 = new byte[outputBuffer.Length - padSize]; | |
Buffer.InternalBlockCopy(outputBuffer, 0, outputBuffer1, 0, outputBuffer.Length - padSize); | |
#if FEATURE_CRYPTO | |
break; | |
case PaddingMode.ANSIX923: | |
if (inputCount == 0) | |
throw new CryptographicException(Environment.GetResourceString("Cryptography_PKCS7_InvalidPadding")); | |
padSize = outputBuffer[inputCount - 1]; | |
if (padSize > outputBuffer.Length || padSize > InputBlockSize || padSize <= 0) | |
throw new CryptographicException(Environment.GetResourceString("Cryptography_PKCS7_InvalidPadding")); | |
// check the validity of the padding | |
for (index = 2; index <= padSize; index++) | |
if (outputBuffer[inputCount - index] != 0) | |
throw new CryptographicException(Environment.GetResourceString("Cryptography_PKCS7_InvalidPadding")); | |
outputBuffer1 = new byte[outputBuffer.Length - padSize]; | |
Buffer.InternalBlockCopy(outputBuffer, 0, outputBuffer1, 0, outputBuffer.Length - padSize); | |
break; | |
case PaddingMode.ISO10126: | |
if (inputCount == 0) | |
throw new CryptographicException(Environment.GetResourceString("Cryptography_PKCS7_InvalidPadding")); | |
padSize = outputBuffer[inputCount - 1]; | |
if (padSize > outputBuffer.Length || padSize > InputBlockSize || padSize <= 0) | |
throw new CryptographicException(Environment.GetResourceString("Cryptography_PKCS7_InvalidPadding")); | |
// Just ignore the random bytes | |
outputBuffer1 = new byte[outputBuffer.Length - padSize]; | |
Buffer.InternalBlockCopy(outputBuffer, 0, outputBuffer1, 0, outputBuffer.Length - padSize); | |
break; | |
} | |
#endif // FEATURE_CRYPTO | |
outputBuffer = outputBuffer1; | |
return outputBuffer1.Length; | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment