| File: System\Security\Cryptography\ChaCha20Poly1305.cs | Web Access |
| Project: src\runtime\src\libraries\System.Security.Cryptography\src\System.Security.Cryptography.csproj (System.Security.Cryptography) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.Versioning; using Internal.Cryptography; namespace System.Security.Cryptography { [UnsupportedOSPlatform("browser")] [UnsupportedOSPlatform("ios")] [UnsupportedOSPlatform("tvos")] [SupportedOSPlatform("ios13.0")] [SupportedOSPlatform("tvos13.0")] public sealed partial class ChaCha20Poly1305 : IDisposable { // Per https://tools.ietf.org/html/rfc7539, ChaCha20Poly1305 AEAD requires a 256-bit key and 96-bit nonce, // and it produces a 128-bit tag. We don't expose NonceByteSizes / TagByteSizes properties because callers // are expected to know this. private const int KeySizeInBytes = 256 / 8; private const int NonceSizeInBytes = 96 / 8; private const int TagSizeInBytes = 128 / 8; public ChaCha20Poly1305(ReadOnlySpan<byte> key) { ThrowIfNotSupported(); CheckKeySize(key.Length); ImportKey(key); } public ChaCha20Poly1305(byte[] key) { ArgumentNullException.ThrowIfNull(key); ThrowIfNotSupported(); CheckKeySize(key.Length); ImportKey(key); } private static void CheckKeySize(int keySizeInBytes) { if (keySizeInBytes != KeySizeInBytes) { throw new CryptographicException(SR.Cryptography_InvalidKeySize); } } public void Encrypt(byte[] nonce, byte[] plaintext, byte[] ciphertext, byte[] tag, byte[]? associatedData = null) { ArgumentNullException.ThrowIfNull(nonce); ArgumentNullException.ThrowIfNull(plaintext); ArgumentNullException.ThrowIfNull(ciphertext); ArgumentNullException.ThrowIfNull(tag); Encrypt((ReadOnlySpan<byte>)nonce, plaintext, ciphertext, tag, associatedData); } public void Encrypt( ReadOnlySpan<byte> nonce, ReadOnlySpan<byte> plaintext, Span<byte> ciphertext, Span<byte> tag, ReadOnlySpan<byte> associatedData = default) { CheckParameters(plaintext, ciphertext, nonce, tag); EncryptCore(nonce, plaintext, ciphertext, tag, associatedData); } public void Decrypt(byte[] nonce, byte[] ciphertext, byte[] tag, byte[] plaintext, byte[]? associatedData = null) { ArgumentNullException.ThrowIfNull(nonce); ArgumentNullException.ThrowIfNull(ciphertext); ArgumentNullException.ThrowIfNull(tag); ArgumentNullException.ThrowIfNull(plaintext); Decrypt((ReadOnlySpan<byte>)nonce, ciphertext, tag, plaintext, associatedData); } public void Decrypt( ReadOnlySpan<byte> nonce, ReadOnlySpan<byte> ciphertext, ReadOnlySpan<byte> tag, Span<byte> plaintext, ReadOnlySpan<byte> associatedData = default) { CheckParameters(plaintext, ciphertext, nonce, tag); DecryptCore(nonce, ciphertext, tag, plaintext, associatedData); } private static void CheckParameters( ReadOnlySpan<byte> plaintext, ReadOnlySpan<byte> ciphertext, ReadOnlySpan<byte> nonce, ReadOnlySpan<byte> tag) { if (plaintext.Length != ciphertext.Length) throw new ArgumentException(SR.Cryptography_PlaintextCiphertextLengthMismatch); if (nonce.Length != NonceSizeInBytes) throw new ArgumentException(SR.Cryptography_InvalidNonceLength, nameof(nonce)); if (tag.Length != TagSizeInBytes) throw new ArgumentException(SR.Cryptography_InvalidTagLength, nameof(tag)); } private static void ThrowIfNotSupported() { if (!IsSupported) { throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(ChaCha20Poly1305))); } } } }