Skip to content

Instantly share code, notes, and snippets.

@Metaluim
Created October 8, 2015 13:27
Show Gist options
  • Save Metaluim/fcf9a4f1012fdeb2a44f to your computer and use it in GitHub Desktop.
Save Metaluim/fcf9a4f1012fdeb2a44f to your computer and use it in GitHub Desktop.
[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