Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Jones <kevin@vcsjones.com>2022-10-01 19:02:03 +0300
committerGitHub <noreply@github.com>2022-10-01 19:02:03 +0300
commit72ac50cef091a46d9c02b43f6f4f1785011afe4a (patch)
treed61bea911ea2f6f7ec017456b6f2c06ba382d0d8 /src/libraries
parent65a15783e334039dfc303fa62b22dcc872029257 (diff)
Implement ChaCha20Poly1305 with CryptoKit on macOS
Co-authored-by: Filip Navara <filip.navara@gmail.com>
Diffstat (limited to 'src/libraries')
-rw-r--r--src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Aead.cs120
-rw-r--r--src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj5
-rw-r--r--src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ChaCha20Poly1305.macOS.cs72
-rw-r--r--src/libraries/System.Security.Cryptography/tests/ChaCha20Poly1305Tests.cs8
4 files changed, 202 insertions, 3 deletions
diff --git a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Aead.cs b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Aead.cs
new file mode 100644
index 00000000000..62102ac0a59
--- /dev/null
+++ b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Aead.cs
@@ -0,0 +1,120 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Security.Cryptography;
+using System.Security.Cryptography.Apple;
+
+internal static partial class Interop
+{
+ internal static partial class AppleCrypto
+ {
+ internal static unsafe void ChaCha20Poly1305Encrypt(
+ ReadOnlySpan<byte> key,
+ ReadOnlySpan<byte> nonce,
+ ReadOnlySpan<byte> plaintext,
+ Span<byte> ciphertext,
+ Span<byte> tag,
+ ReadOnlySpan<byte> aad)
+ {
+ fixed (byte* keyPtr = key)
+ fixed (byte* noncePtr = nonce)
+ fixed (byte* plaintextPtr = plaintext)
+ fixed (byte* ciphertextPtr = ciphertext)
+ fixed (byte* tagPtr = tag)
+ fixed (byte* aadPtr = aad)
+ {
+ const int Success = 1;
+ int result = AppleCryptoNative_ChaCha20Poly1305Encrypt(
+ keyPtr, key.Length,
+ noncePtr, nonce.Length,
+ plaintextPtr, plaintext.Length,
+ ciphertextPtr, ciphertext.Length,
+ tagPtr, tag.Length,
+ aadPtr, aad.Length);
+
+ if (result != Success)
+ {
+ Debug.Assert(result == 0);
+ CryptographicOperations.ZeroMemory(ciphertext);
+ CryptographicOperations.ZeroMemory(tag);
+ throw new CryptographicException();
+ }
+ }
+ }
+
+ internal static unsafe void ChaCha20Poly1305Decrypt(
+ ReadOnlySpan<byte> key,
+ ReadOnlySpan<byte> nonce,
+ ReadOnlySpan<byte> ciphertext,
+ ReadOnlySpan<byte> tag,
+ Span<byte> plaintext,
+ ReadOnlySpan<byte> aad)
+ {
+ fixed (byte* keyPtr = key)
+ fixed (byte* noncePtr = nonce)
+ fixed (byte* ciphertextPtr = ciphertext)
+ fixed (byte* tagPtr = tag)
+ fixed (byte* plaintextPtr = plaintext)
+ fixed (byte* aadPtr = aad)
+ {
+ const int Success = 1;
+ const int AuthTagMismatch = -1;
+ int result = AppleCryptoNative_ChaCha20Poly1305Decrypt(
+ keyPtr, key.Length,
+ noncePtr, nonce.Length,
+ ciphertextPtr, ciphertext.Length,
+ tagPtr, tag.Length,
+ plaintextPtr, plaintext.Length,
+ aadPtr, aad.Length);
+
+ if (result != Success)
+ {
+ CryptographicOperations.ZeroMemory(plaintext);
+
+ if (result == AuthTagMismatch)
+ {
+ throw new AuthenticationTagMismatchException();
+ }
+ else
+ {
+ Debug.Assert(result == 0);
+ throw new CryptographicException();
+ }
+ }
+ }
+ }
+
+ [LibraryImport(Libraries.AppleCryptoNative)]
+ private static unsafe partial int AppleCryptoNative_ChaCha20Poly1305Encrypt(
+ byte* keyPtr,
+ int keyLength,
+ byte* noncePtr,
+ int nonceLength,
+ byte* plaintextPtr,
+ int plaintextLength,
+ byte* ciphertextPtr,
+ int ciphertextLength,
+ byte* tagPtr,
+ int tagLength,
+ byte* aadPtr,
+ int aadLength);
+
+ [LibraryImport(Libraries.AppleCryptoNative)]
+ private static unsafe partial int AppleCryptoNative_ChaCha20Poly1305Decrypt(
+ byte* keyPtr,
+ int keyLength,
+ byte* noncePtr,
+ int nonceLength,
+ byte* ciphertextPtr,
+ int ciphertextLength,
+ byte* tagPtr,
+ int tagLength,
+ byte* plaintextPtr,
+ int plaintextLength,
+ byte* aadPtr,
+ int aadLength);
+ }
+}
diff --git a/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj b/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj
index 0840f45a3ae..b8d2342e227 100644
--- a/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj
+++ b/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj
@@ -788,6 +788,7 @@
<Compile Include="System\Security\Cryptography\CapiHelper.DSA.Shared.cs" />
<Compile Include="System\Security\Cryptography\CapiHelper.Shared.cs" />
<Compile Include="System\Security\Cryptography\CapiHelper.Unix.cs" />
+ <Compile Include="System\Security\Cryptography\ChaCha20Poly1305.OpenSsl.cs" />
<Compile Include="System\Security\Cryptography\Cng.NotSupported.cs" />
<Compile Include="System\Security\Cryptography\CspKeyContainerInfo.NotSupported.cs" />
<Compile Include="System\Security\Cryptography\DESCryptoServiceProvider.Unix.cs" />
@@ -868,7 +869,6 @@
Link="Common\Interop\Unix\System.Security.Cryptography.Native\Interop.EVP.Cipher.cs" />
<Compile Include="$(CommonPath)Microsoft\Win32\SafeHandles\SafeEvpCipherCtxHandle.Unix.cs"
Link="Common\Microsoft\Win32\SafeHandles\SafeEvpCipherCtxHandle.Unix.cs" />
- <Compile Include="System\Security\Cryptography\ChaCha20Poly1305.OpenSsl.cs" />
<Compile Include="System\Security\Cryptography\AesCcm.OpenSsl.cs" />
<Compile Include="System\Security\Cryptography\AesGcm.OpenSsl.cs" />
</ItemGroup>
@@ -1257,6 +1257,8 @@
Link="Common\Interop\Unix\System.Security.Cryptography.Native\Interop.EvpPkey.Rsa.cs" />
<Compile Include="$(CommonPath)Interop\Unix\System.Security.Cryptography.Native\Interop.OpenSslVersion.cs"
Link="Common\Interop\Unix\System.Security.Cryptography.Native\Interop.OpenSslVersion.cs" />
+ <Compile Include="$(CommonPath)Interop\OSX\System.Security.Cryptography.Native.Apple\Interop.Aead.cs"
+ Link="Common\Interop\OSX\System.Security.Cryptography.Native.Apple\Interop.Aead.cs" />
<Compile Include="$(CommonPath)Interop\OSX\System.Security.Cryptography.Native.Apple\Interop.Keychain.macOS.cs"
Link="Common\Interop\OSX\System.Security.Cryptography.Native.Apple\Interop.Keychain.macOS.cs" />
<Compile Include="$(CommonPath)Interop\OSX\System.Security.Cryptography.Native.Apple\Interop.Pbkdf2.cs"
@@ -1289,6 +1291,7 @@
Link="Common\System\Security\Cryptography\RSASecurityTransforms.macOS.cs" />
<Compile Include="$(CommonPath)System\Security\Cryptography\RSAOpenSsl.cs"
Link="Common\System\Security\Cryptography\RSAOpenSsl.cs" />
+ <Compile Include="System\Security\Cryptography\ChaCha20Poly1305.macOS.cs" />
<Compile Include="System\Security\Cryptography\DSA.Create.SecurityTransforms.cs" />
<Compile Include="System\Security\Cryptography\DSACryptoServiceProvider.Unix.cs" />
<Compile Include="System\Security\Cryptography\DSAOpenSsl.cs" />
diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ChaCha20Poly1305.macOS.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ChaCha20Poly1305.macOS.cs
new file mode 100644
index 00000000000..82f1633c188
--- /dev/null
+++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ChaCha20Poly1305.macOS.cs
@@ -0,0 +1,72 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+
+namespace System.Security.Cryptography
+{
+ public sealed partial class ChaCha20Poly1305
+ {
+ // CryptoKit added ChaCha20Poly1305 in macOS 10.15, which is our minimum target for macOS.
+ public static bool IsSupported => true;
+ private byte[]? _key;
+
+ [MemberNotNull(nameof(_key))]
+ private void ImportKey(ReadOnlySpan<byte> key)
+ {
+ // We should only be calling this in the constructor, so there shouldn't be a previous key.
+ Debug.Assert(_key is null);
+
+ // Pin the array on the POH so that the GC doesn't move it around to allow zeroing to be more effective.
+ _key = GC.AllocateArray<byte>(key.Length, pinned: true);
+ key.CopyTo(_key);
+ }
+
+ private void EncryptCore(
+ ReadOnlySpan<byte> nonce,
+ ReadOnlySpan<byte> plaintext,
+ Span<byte> ciphertext,
+ Span<byte> tag,
+ ReadOnlySpan<byte> associatedData = default)
+ {
+ CheckDisposed();
+ Interop.AppleCrypto.ChaCha20Poly1305Encrypt(
+ _key,
+ nonce,
+ plaintext,
+ ciphertext,
+ tag,
+ associatedData);
+ }
+
+ private void DecryptCore(
+ ReadOnlySpan<byte> nonce,
+ ReadOnlySpan<byte> ciphertext,
+ ReadOnlySpan<byte> tag,
+ Span<byte> plaintext,
+ ReadOnlySpan<byte> associatedData = default)
+ {
+ CheckDisposed();
+ Interop.AppleCrypto.ChaCha20Poly1305Decrypt(
+ _key,
+ nonce,
+ ciphertext,
+ tag,
+ plaintext,
+ associatedData);
+ }
+
+ public void Dispose()
+ {
+ CryptographicOperations.ZeroMemory(_key);
+ _key = null;
+ }
+
+ [MemberNotNull(nameof(_key))]
+ private void CheckDisposed()
+ {
+ ObjectDisposedException.ThrowIf(_key is null, this);
+ }
+ }
+}
diff --git a/src/libraries/System.Security.Cryptography/tests/ChaCha20Poly1305Tests.cs b/src/libraries/System.Security.Cryptography/tests/ChaCha20Poly1305Tests.cs
index f381e17e73d..40f17690cdf 100644
--- a/src/libraries/System.Security.Cryptography/tests/ChaCha20Poly1305Tests.cs
+++ b/src/libraries/System.Security.Cryptography/tests/ChaCha20Poly1305Tests.cs
@@ -457,8 +457,12 @@ namespace System.Security.Cryptography.Tests
// OpenSSL is present, and a high enough version,
// but the distro build options turned off ChaCha/Poly.
}
- else if (PlatformDetection.OpenSslPresentOnSystem &&
- (PlatformDetection.IsOSX || PlatformDetection.IsOpenSslSupported))
+ else if (PlatformDetection.IsOSX)
+ {
+ // CryptoKit is supported on macOS 10.15+, which is our minimum target.
+ expectedIsSupported = true;
+ }
+ else if (PlatformDetection.OpenSslPresentOnSystem && PlatformDetection.IsOpenSslSupported)
{
const int OpenSslChaChaMinimumVersion = 0x1_01_00_00_F; //major_minor_fix_patch_status
expectedIsSupported = SafeEvpPKeyHandle.OpenSslVersion >= OpenSslChaChaMinimumVersion;