-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Like AES-GCM and AES-CCM, the macOS build uses OpenSSL for the implementation. Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com>
- Loading branch information
Showing
10 changed files
with
255 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,4 @@ | |
|
||
#cmakedefine01 HAVE_OPENSSL_EC2M | ||
#cmakedefine01 HAVE_OPENSSL_ALPN | ||
#cmakedefine01 HAVE_OPENSSL_CHACHA20POLY1305 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
136 changes: 136 additions & 0 deletions
136
...ecurity.Cryptography.Algorithms/src/System/Security/Cryptography/ChaCha20Poly1305.Unix.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
// 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; | ||
using Microsoft.Win32.SafeHandles; | ||
|
||
namespace System.Security.Cryptography | ||
{ | ||
public sealed partial class ChaCha20Poly1305 | ||
{ | ||
public static bool IsSupported { get; } = Interop.Crypto.EvpChaCha20Poly1305() != IntPtr.Zero; | ||
|
||
private SafeEvpCipherCtxHandle _ctxHandle; | ||
|
||
[MemberNotNull(nameof(_ctxHandle))] | ||
private void ImportKey(ReadOnlySpan<byte> key) | ||
{ | ||
_ctxHandle = Interop.Crypto.EvpCipherCreatePartial(GetCipher(key.Length * 8)); | ||
|
||
Interop.Crypto.CheckValidOpenSslHandle(_ctxHandle); | ||
Interop.Crypto.EvpCipherSetKeyAndIV( | ||
_ctxHandle, | ||
key, | ||
Span<byte>.Empty, | ||
Interop.Crypto.EvpCipherDirection.NoChange); | ||
} | ||
|
||
private void EncryptCore( | ||
ReadOnlySpan<byte> nonce, | ||
ReadOnlySpan<byte> plaintext, | ||
Span<byte> ciphertext, | ||
Span<byte> tag, | ||
ReadOnlySpan<byte> associatedData = default) | ||
{ | ||
Interop.Crypto.EvpCipherSetKeyAndIV( | ||
_ctxHandle, | ||
Span<byte>.Empty, | ||
nonce, | ||
Interop.Crypto.EvpCipherDirection.Encrypt); | ||
|
||
if (associatedData.Length != 0) | ||
{ | ||
if (!Interop.Crypto.EvpCipherUpdate(_ctxHandle, Span<byte>.Empty, out _, associatedData)) | ||
{ | ||
throw Interop.Crypto.CreateOpenSslCryptographicException(); | ||
} | ||
} | ||
|
||
if (!Interop.Crypto.EvpCipherUpdate(_ctxHandle, ciphertext, out int ciphertextBytesWritten, plaintext)) | ||
{ | ||
throw Interop.Crypto.CreateOpenSslCryptographicException(); | ||
} | ||
|
||
if (!Interop.Crypto.EvpCipherFinalEx( | ||
_ctxHandle, | ||
ciphertext.Slice(ciphertextBytesWritten), | ||
out int bytesWritten)) | ||
{ | ||
throw Interop.Crypto.CreateOpenSslCryptographicException(); | ||
} | ||
|
||
ciphertextBytesWritten += bytesWritten; | ||
|
||
if (ciphertextBytesWritten != ciphertext.Length) | ||
{ | ||
Debug.Fail($"ChaCha20Poly1305 encrypt wrote {ciphertextBytesWritten} of {ciphertext.Length} bytes."); | ||
throw new CryptographicException(); | ||
} | ||
|
||
Interop.Crypto.EvpCipherGetAeadTag(_ctxHandle, tag); | ||
} | ||
|
||
private void DecryptCore( | ||
ReadOnlySpan<byte> nonce, | ||
ReadOnlySpan<byte> ciphertext, | ||
ReadOnlySpan<byte> tag, | ||
Span<byte> plaintext, | ||
ReadOnlySpan<byte> associatedData) | ||
{ | ||
Interop.Crypto.EvpCipherSetKeyAndIV( | ||
_ctxHandle, | ||
ReadOnlySpan<byte>.Empty, | ||
nonce, | ||
Interop.Crypto.EvpCipherDirection.Decrypt); | ||
|
||
if (associatedData.Length != 0) | ||
{ | ||
if (!Interop.Crypto.EvpCipherUpdate(_ctxHandle, Span<byte>.Empty, out _, associatedData)) | ||
{ | ||
throw Interop.Crypto.CreateOpenSslCryptographicException(); | ||
} | ||
} | ||
|
||
if (!Interop.Crypto.EvpCipherUpdate(_ctxHandle, plaintext, out int plaintextBytesWritten, ciphertext)) | ||
{ | ||
throw Interop.Crypto.CreateOpenSslCryptographicException(); | ||
} | ||
|
||
Interop.Crypto.EvpCipherSetAeadTag(_ctxHandle, tag); | ||
|
||
if (!Interop.Crypto.EvpCipherFinalEx( | ||
_ctxHandle, | ||
plaintext.Slice(plaintextBytesWritten), | ||
out int bytesWritten)) | ||
{ | ||
CryptographicOperations.ZeroMemory(plaintext); | ||
throw new CryptographicException(SR.Cryptography_AuthTagMismatch); | ||
} | ||
|
||
plaintextBytesWritten += bytesWritten; | ||
|
||
if (plaintextBytesWritten != plaintext.Length) | ||
{ | ||
Debug.Fail($"ChaCha20Poly1305 decrypt wrote {plaintextBytesWritten} of {plaintext.Length} bytes."); | ||
throw new CryptographicException(); | ||
} | ||
} | ||
|
||
private static IntPtr GetCipher(int keySizeInBits) | ||
{ | ||
switch (keySizeInBits) | ||
{ | ||
case 256: return Interop.Crypto.EvpChaCha20Poly1305(); | ||
default: | ||
Debug.Fail("Key size should already be validated"); | ||
return IntPtr.Zero; | ||
} | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
_ctxHandle.Dispose(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters