-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Background and Motivation
We've received requests to add more cryptographic primitives to the BCL. Among these requests is support for ChaCha20-Poly1305 (see #16010), an AEAD algorithm standardized in RFC 7539. This algorithm is beginning to see widespread use in networking protocols - notably, for TLS.
We're not considering shipping APIs for standalone ChaCha20 and Poly1305 primitives. This proposal is only for the combined ChaCha20Poly1305 AEAD construction.
Proposed API
Since this is an AEAD algorithm, the proposed API surface exactly mirrors the API surface of System.Security.Cryptography.AesGcm. We're not using the existing SymmetricAlgorithm class, as it's not well-suited for AEAD algorithms.
namespace System.Security.Cryptography
{
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
public sealed partial class ChaCha20Poly1305 : System.IDisposable
{
public ChaCha20Poly1305(byte[] key) { }
public ChaCha20Poly1305(System.ReadOnlySpan<byte> key) { }
// public static System.Security.Cryptography.KeySizes NonceByteSizes { get { throw null; } } // (removed - see discussion)
// public static System.Security.Cryptography.KeySizes TagByteSizes { get { throw null; } } // (removed - see discussion)
public void Decrypt(byte[] nonce, byte[] ciphertext, byte[] tag, byte[] plaintext, byte[]? associatedData = null) { }
public void Decrypt(System.ReadOnlySpan<byte> nonce, System.ReadOnlySpan<byte> ciphertext, System.ReadOnlySpan<byte> tag, System.Span<byte> plaintext, System.ReadOnlySpan<byte> associatedData = default(System.ReadOnlySpan<byte>)) { }
public void Dispose() { }
public void Encrypt(byte[] nonce, byte[] plaintext, byte[] ciphertext, byte[] tag, byte[]? associatedData = null) { }
public void Encrypt(System.ReadOnlySpan<byte> nonce, System.ReadOnlySpan<byte> plaintext, System.Span<byte> ciphertext, System.Span<byte> tag, System.ReadOnlySpan<byte> associatedData = default(System.ReadOnlySpan<byte>)) { }
}
}The key, nonce, and tag lengths are fixed at 256, 96, and 128 bits, respectively. Callers are expected to know this information. We could consider getting rid of the NonceByteSizes and TagByteSizes properties here, which were copied over from the AesGcm approved API surface.
Implementation and usage notes
We are not shipping an implementation of this algorithm. We rely on the underlying OS or a third-party crypto library to provide the implementation on our behalf. The support matrix is then:
- Windows 10: Build 20142 or later.
- OpenSSL: Version 1.1 or later.
- Mac OSX: Unsupported unless the OpenSSL shim is enabled, same as AES-GCM.
- Browser: Unsupported.
Open questions
Do we need to attribute the type with "if on Windows, supported in 20142+ only"? I don't know how useful this would be, since normally some high-level orchestration layer or config dictates what algorithms to use, and the low-level code which would be using this proposed type would be far-removed from any orchestration code. That low-level code normally wouldn't be responsible for checking support, as any PNSE that's thrown would indicate a failure on the part of the orchestration layer, not the component that attempted to create a ChaCha20Poly1305 instance.