Skip to content

Commit 5f578ba

Browse files
committed
Implement AuthenticationTagMismatchException
1 parent 6e3ba36 commit 5f578ba

File tree

3 files changed

+58
-52
lines changed

3 files changed

+58
-52
lines changed

src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Aead.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using System.Diagnostics;
56
using System.Runtime.InteropServices;
67
using System.Security.Cryptography;
78
using System.Security.Cryptography.Apple;
@@ -36,6 +37,7 @@ internal static unsafe void ChaCha20Poly1305Encrypt(
3637

3738
if (result != Success)
3839
{
40+
Debug.Assert(result == 0);
3941
CryptographicOperations.ZeroMemory(ciphertext);
4042
CryptographicOperations.ZeroMemory(tag);
4143
throw new CryptographicException();
@@ -59,6 +61,7 @@ internal static unsafe void ChaCha20Poly1305Decrypt(
5961
fixed (byte* aadPtr = aad)
6062
{
6163
const int Success = 1;
64+
const int AuthTagMismatch = -1;
6265
int result = AppleCryptoNative_ChaCha20Poly1305Decrypt(
6366
keyPtr, key.Length,
6467
noncePtr, nonce.Length,
@@ -67,12 +70,19 @@ internal static unsafe void ChaCha20Poly1305Decrypt(
6770
plaintextPtr, plaintext.Length,
6871
aadPtr, aad.Length);
6972

70-
// TODO: Need to throw the AuthenticationTagMismatchException when it gets merged.
71-
// When there is an auth tag mismatch, -2 is returned.
7273
if (result != Success)
7374
{
7475
CryptographicOperations.ZeroMemory(plaintext);
75-
throw new CryptographicException();
76+
77+
if (result == AuthTagMismatch)
78+
{
79+
throw new AuthenticationTagMismatchException();
80+
}
81+
else
82+
{
83+
Debug.Assert(result == 0);
84+
throw new CryptographicException();
85+
}
7686
}
7787
}
7888
}

src/libraries/System.Security.Cryptography/tests/ChaCha20Poly1305Tests.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,12 @@ public static void CheckIsSupported()
457457
// OpenSSL is present, and a high enough version,
458458
// but the distro build options turned off ChaCha/Poly.
459459
}
460-
else if (PlatformDetection.OpenSslPresentOnSystem &&
461-
(PlatformDetection.IsOSX || PlatformDetection.IsOpenSslSupported))
460+
else if (PlatformDetection.IsOSX)
461+
{
462+
// CryptoKit is supported on macOS 10.15+, which is our minimum target.
463+
expectedIsSupported = true;
464+
}
465+
else if (PlatformDetection.OpenSslPresentOnSystem && PlatformDetection.IsOpenSslSupported)
462466
{
463467
const int OpenSslChaChaMinimumVersion = 0x1_01_00_00_F; //major_minor_fix_patch_status
464468
expectedIsSupported = SafeEvpPKeyHandle.OpenSslVersion >= OpenSslChaChaMinimumVersion;

src/native/libs/System.Security.Cryptography.Native.Apple/pal_swiftbindings.swift

Lines changed: 39 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,26 @@ public func AppleCryptoNative_ChaCha20Poly1305Encrypt(
1919
aadPtr: UnsafeMutableRawPointer,
2020
aadLength: Int32
2121
) -> Int32 {
22-
if #available(macOS 10.15, *) {
23-
let nonceData = Data(bytesNoCopy: noncePtr, count: Int(nonceLength), deallocator: Data.Deallocator.none)
24-
let key = Data(bytesNoCopy: keyPtr, count: Int(keyLength), deallocator: Data.Deallocator.none)
25-
let plaintext = Data(bytesNoCopy: plaintextPtr, count: Int(plaintextLength), deallocator: Data.Deallocator.none)
26-
let aad = Data(bytesNoCopy: aadPtr, count: Int(aadLength), deallocator: Data.Deallocator.none)
27-
let symmetricKey = SymmetricKey(data: key)
22+
let nonceData = Data(bytesNoCopy: noncePtr, count: Int(nonceLength), deallocator: Data.Deallocator.none)
23+
let key = Data(bytesNoCopy: keyPtr, count: Int(keyLength), deallocator: Data.Deallocator.none)
24+
let plaintext = Data(bytesNoCopy: plaintextPtr, count: Int(plaintextLength), deallocator: Data.Deallocator.none)
25+
let aad = Data(bytesNoCopy: aadPtr, count: Int(aadLength), deallocator: Data.Deallocator.none)
26+
let symmetricKey = SymmetricKey(data: key)
2827

29-
guard let nonce = try? ChaChaPoly.Nonce(data: nonceData) else {
30-
return 0
31-
}
32-
33-
guard let result = try? ChaChaPoly.seal(plaintext, using: symmetricKey, nonce: nonce, authenticating: aad) else {
34-
return 0
35-
}
36-
37-
assert(ciphertextBufferLength >= result.ciphertext.count)
38-
assert(tagBufferLength >= result.tag.count)
28+
guard let nonce = try? ChaChaPoly.Nonce(data: nonceData) else {
29+
return 0
30+
}
3931

40-
result.ciphertext.copyBytes(to: ciphertextBuffer, count: result.ciphertext.count)
41-
result.tag.copyBytes(to: tagBuffer, count: result.tag.count)
42-
return 1
32+
guard let result = try? ChaChaPoly.seal(plaintext, using: symmetricKey, nonce: nonce, authenticating: aad) else {
33+
return 0
4334
}
4435

45-
return -1
36+
assert(ciphertextBufferLength >= result.ciphertext.count)
37+
assert(tagBufferLength >= result.tag.count)
38+
39+
result.ciphertext.copyBytes(to: ciphertextBuffer, count: result.ciphertext.count)
40+
result.tag.copyBytes(to: tagBuffer, count: result.tag.count)
41+
return 1
4642
}
4743

4844
@_cdecl("AppleCryptoNative_ChaCha20Poly1305Decrypt")
@@ -61,36 +57,32 @@ public func AppleCryptoNative_ChaCha20Poly1305Decrypt(
6157
aadLength: Int32
6258
) -> Int32
6359
{
64-
if #available(macOS 10.15, *) {
65-
let nonceData = Data(bytesNoCopy: noncePtr, count: Int(nonceLength), deallocator: Data.Deallocator.none)
66-
let key = Data(bytesNoCopy: keyPtr, count: Int(keyLength), deallocator: Data.Deallocator.none)
67-
let ciphertext = Data(bytesNoCopy: ciphertextPtr, count: Int(ciphertextLength), deallocator: Data.Deallocator.none)
68-
let aad = Data(bytesNoCopy: aadPtr, count: Int(aadLength), deallocator: Data.Deallocator.none)
69-
let tag = Data(bytesNoCopy: tagPtr, count: Int(tagLength), deallocator: Data.Deallocator.none)
70-
let symmetricKey = SymmetricKey(data: key)
60+
let nonceData = Data(bytesNoCopy: noncePtr, count: Int(nonceLength), deallocator: Data.Deallocator.none)
61+
let key = Data(bytesNoCopy: keyPtr, count: Int(keyLength), deallocator: Data.Deallocator.none)
62+
let ciphertext = Data(bytesNoCopy: ciphertextPtr, count: Int(ciphertextLength), deallocator: Data.Deallocator.none)
63+
let aad = Data(bytesNoCopy: aadPtr, count: Int(aadLength), deallocator: Data.Deallocator.none)
64+
let tag = Data(bytesNoCopy: tagPtr, count: Int(tagLength), deallocator: Data.Deallocator.none)
65+
let symmetricKey = SymmetricKey(data: key)
7166

72-
guard let nonce = try? ChaChaPoly.Nonce(data: nonceData) else {
73-
return 0
74-
}
67+
guard let nonce = try? ChaChaPoly.Nonce(data: nonceData) else {
68+
return 0
69+
}
7570

76-
guard let sealedBoxRestored = try? ChaChaPoly.SealedBox(nonce: nonce, ciphertext: ciphertext, tag: tag) else {
77-
return 0
78-
}
71+
guard let sealedBoxRestored = try? ChaChaPoly.SealedBox(nonce: nonce, ciphertext: ciphertext, tag: tag) else {
72+
return 0
73+
}
7974

80-
do {
81-
let result = try ChaChaPoly.open(sealedBoxRestored, using: symmetricKey, authenticating: aad)
75+
do {
76+
let result = try ChaChaPoly.open(sealedBoxRestored, using: symmetricKey, authenticating: aad)
8277

83-
assert(plaintextBufferLength >= result.count)
84-
result.copyBytes(to: plaintextBuffer, count: result.count)
85-
return 1
86-
}
87-
catch CryptoKitError.authenticationFailure {
88-
return -2
89-
}
90-
catch {
91-
return 0
92-
}
78+
assert(plaintextBufferLength >= result.count)
79+
result.copyBytes(to: plaintextBuffer, count: result.count)
80+
return 1
81+
}
82+
catch CryptoKitError.authenticationFailure {
83+
return -1
84+
}
85+
catch {
86+
return 0
9387
}
94-
95-
return -1
9688
}

0 commit comments

Comments
 (0)