-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clarify thread safety of crypto one-shots #53320
Comments
Tagging subscribers to this area: @bartonjs, @vcsjones, @krwq, @GrabYourPitchforks Issue Details.NET has recently introduced several crypto one-shot methods, including: // Static one-shots on SHA and HMAC classes
public static byte[] HashData(byte[] source) { throw null; }
// Instance one-shots on AesGcm / AesCcm / ChaCha20Poly1305
public void Encrypt(byte[] nonce, byte[] plaintext, byte[] ciphertext, byte[] tag, byte[]? associatedData = null) { }
public void Decrypt(byte[] nonce, byte[] ciphertext, byte[] tag, byte[] plaintext, byte[]? associatedData = null) { }
// Instance one-shots on SymmetricAlgorithm
public byte[] EncryptEcb(byte[] plaintext, PaddingMode paddingMode) { throw null; } Following our normal threading principles, static one-shot methods are thread-safe, but instance one-shot methods are not guaranteed to be thread-safe. For instance, as of this writing, public class MyClass
{
private static readonly AesGcm _aes = new AesGcm(GetGlobalKey());
public void MethodCalledByMultipleThreads(/* ... */)
{
_aes.Encrypt(plaintext, nonce, /* ... */);
}
} The failure mode could be corruption of the managed buffer, corruption of the underlying native handle, or even nonce reuse (which would destroy GHASH). Considering that keeping singleton Given this, how do we want to proceed here? Three options immediately come to mind.
|
@GrabYourPitchforks I assume this may have an impact on #49511? Unsure if these APIs will make it to WASM but figured I would link to another thread concern in the crypto space. |
The static one-shots should be thread-safe, since they're static. For the instance members, I think my preferences are 3/2/1. |
I'm indifferent between 2 and 3... documentation makes sense, but then again if we document every single instance API that is not thread safe, throughout the stack - that is a lot of documentation to add. But then yet again, maybe crypto APIs are a bit special and calling out their thread safety is a worthy task. I don't think the hashing one-shots being thread safe has much bearing on the thread safety of the encryption ones. I largely don't even think of the encryption ones as one-shots since you need to construct an object. Is |
Any pushback on explicitly deciding on "do nothing", @GrabYourPitchforks? |
"Do nothing" is fine. It means that we're mixing thread-safe ( |
Alrighty, then. Closing as no action required 😄. |
.NET has recently introduced several crypto one-shot methods, including:
Following our normal threading principles, static one-shot methods are thread-safe, but instance one-shot methods are not guaranteed to be thread-safe. For instance, as of this writing,
AesGcm.Encrypt
is thread-safe on Windows but not on other operating systems. Which means that the code below could work on a Windows test box but fail in a Linux prod environment.The failure mode could be corruption of the managed buffer, corruption of the underlying native handle, or even nonce reuse (which would destroy GHASH). Considering that keeping singleton
SymmetricAlgorithm
instances around and usingCreateEncryptor
/CreateDecryptor
as thread-safeICryptoTransform
factories is a well-established pattern, I believe that customers may incorrectly believe that the new crypto one-shots behave similarly.Given this, how do we want to proceed here? Three options immediately come to mind.
Change
AesGcm
/AesCcm
/ChaCha20Poly1305
to be thread-safe on all platforms. The benefit to this is that it makes the pattern above work correctly on all platforms. However, it may complicate the documentation because we would have to say "it's only thread-safe on .NET 6+." And it doesn't addressEncryptCbc
and friends.Explicitly document these APIs as not thread-safe. This wouldn't change our default stance that static APIs are generally thread-safe and instance APIs are generally not thread-safe. But it would remove ambiguity for these APIs in particular.
Do nothing. Assume devs know the default threading behaviors without needing to be told explicitly, and assume that devs won't make the leap from
CreateEncryptor
being historically thread-safe toEncryptCbc
also being thread-safe.The text was updated successfully, but these errors were encountered: