From: Jeremy Barton Date: Tue, 8 Oct 2019 20:37:58 +0000 (-0700) Subject: Handle "too small" success from CNG and clear out decryption residuals X-Git-Tag: submit/tizen/20210909.063632~11031^2~331 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c518055310888674f820f4198e4ef9d41e046f03;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Handle "too small" success from CNG and clear out decryption residuals * When NCryptEncrypt or NCryptDecrypt reports success with a cbResult value that doesn't make sense, normalize the error to NTE_BUFFER_TOO_SMALL. * When resizing arrays for the array-returning implementation, clear out the temporary arrays to reduce the amount of time they're sitting in memory before the GC clears the memory for reissuance. Commit migrated from https://github.com/dotnet/corefx/commit/7c586d32edce94c910fc8b402f4adedaa3cf05fd --- diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSACng.EncryptDecrypt.cs b/src/libraries/Common/src/System/Security/Cryptography/RSACng.EncryptDecrypt.cs index 66b636c..30f92d4 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSACng.EncryptDecrypt.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSACng.EncryptDecrypt.cs @@ -241,6 +241,7 @@ namespace System.Security.Cryptography if (errorCode == ErrorCode.NTE_BUFFER_TOO_SMALL) { + CryptographicOperations.ZeroMemory(output); output = new byte[numBytesNeeded]; for (int i = 0; i <= StatusUnsuccessfulRetryCount; i++) @@ -260,7 +261,13 @@ namespace System.Security.Cryptography throw errorCode.ToCryptographicException(); } - Array.Resize(ref output, numBytesNeeded); + if (numBytesNeeded != output.Length) + { + byte[] ret = output.AsSpan(0, numBytesNeeded).ToArray(); + CryptographicOperations.ZeroMemory(output); + output = ret; + } + return output; } @@ -300,9 +307,17 @@ namespace System.Security.Cryptography bool encrypt, out int bytesNeeded) { - return encrypt ? + ErrorCode errorCode = encrypt ? Interop.NCrypt.NCryptEncrypt(key, input, input.Length, paddingInfo, output, output.Length, out bytesNeeded, paddingMode) : Interop.NCrypt.NCryptDecrypt(key, input, input.Length, paddingInfo, output, output.Length, out bytesNeeded, paddingMode); + + // Windows 10.1903 can return success when it meant NTE_BUFFER_TOO_SMALL. + if (errorCode == ErrorCode.ERROR_SUCCESS && bytesNeeded > output.Length) + { + errorCode = ErrorCode.NTE_BUFFER_TOO_SMALL; + } + + return errorCode; } } #if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS