From 1268252b91effa180843f0a192029ceca2288f91 Mon Sep 17 00:00:00 2001 From: Jeremy Barton Date: Thu, 30 Aug 2018 22:20:57 -0700 Subject: [PATCH] Erase temporary copies of plaintext during de/padding operations When symmetric block padding is added, or removed, the UniversalCryptoDecryptor and UniversalCryptoEncryptor classes make a temporary buffer to hold the padded result (for encryption this is the input to the cryptographic transform, for decryption it is the output before calling DepadBlock). While these buffers are usually marked as unused by the GC in short order, and overwritten by new objects in short order, some applications are more sensitive to having plaintext residuals in memory; and we should clear these out before abandoning them to the garbage collector. Commit migrated from https://github.com/dotnet/corefx/commit/bb54ed5540d19a1595443bab0233e3c985da9dad --- .../Internal/Cryptography/UniversalCryptoDecryptor.cs | 13 ++++++++++++- .../Internal/Cryptography/UniversalCryptoEncryptor.cs | 16 +++++++++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoDecryptor.cs b/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoDecryptor.cs index 6415ec6..5b44d44 100644 --- a/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoDecryptor.cs +++ b/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoDecryptor.cs @@ -97,7 +97,18 @@ namespace Internal.Cryptography byte[] outputData; if (ciphertext.Length > 0) { - outputData = DepadBlock(decryptedBytes, 0, decryptedBytes.Length); + unsafe + { + fixed (byte* decryptedBytesPtr = decryptedBytes) + { + outputData = DepadBlock(decryptedBytes, 0, decryptedBytes.Length); + + if (outputData != decryptedBytes) + { + CryptographicOperations.ZeroMemory(decryptedBytes); + } + } + } } else { diff --git a/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoEncryptor.cs b/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoEncryptor.cs index bfe4430..937d6e5 100644 --- a/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoEncryptor.cs +++ b/src/libraries/Common/src/Internal/Cryptography/UniversalCryptoEncryptor.cs @@ -30,11 +30,21 @@ namespace Internal.Cryptography return BasicSymmetricCipher.Transform(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset); } - protected sealed override byte[] UncheckedTransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) + protected sealed override unsafe byte[] UncheckedTransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) { byte[] paddedBlock = PadBlock(inputBuffer, inputOffset, inputCount); - byte[] output = BasicSymmetricCipher.TransformFinal(paddedBlock, 0, paddedBlock.Length); - return output; + + fixed (byte* paddedBlockPtr = paddedBlock) + { + byte[] output = BasicSymmetricCipher.TransformFinal(paddedBlock, 0, paddedBlock.Length); + + if (paddedBlock != inputBuffer) + { + CryptographicOperations.ZeroMemory(paddedBlock); + } + + return output; + } } private byte[] PadBlock(byte[] block, int offset, int count) -- 2.7.4