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
path: root/src
diff options
context:
space:
mode:
authorKevin Jones <kevin@vcsjones.com>2022-09-30 15:56:57 +0300
committerGitHub <noreply@github.com>2022-09-30 15:56:57 +0300
commit60b40c38eb06106164a125b0ec6521024f62e46f (patch)
treedc4f396bef667506744db989ca31b0b85299f4e8 /src
parenta70adac8b46cf67d2366f219c14b5212ad2857a0 (diff)
Implement AuthenticationTagMismatchException exception
Co-authored-by: Filip Navara <filip.navara@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Cipher.cs28
-rw-r--r--src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs6
-rw-r--r--src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj1
-rw-r--r--src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AeadCommon.Windows.cs2
-rw-r--r--src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesCcm.Android.cs19
-rw-r--r--src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesCcm.OpenSsl.cs2
-rw-r--r--src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesGcm.Android.cs19
-rw-r--r--src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesGcm.OpenSsl.cs2
-rw-r--r--src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AuthenticationTagMismatchException.cs47
-rw-r--r--src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ChaCha20Poly1305.Android.cs19
-rw-r--r--src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ChaCha20Poly1305.OpenSsl.cs2
-rw-r--r--src/libraries/System.Security.Cryptography/tests/AesCcmTests.cs8
-rw-r--r--src/libraries/System.Security.Cryptography/tests/AesGcmTests.cs8
-rw-r--r--src/libraries/System.Security.Cryptography/tests/ChaCha20Poly1305Tests.cs6
-rw-r--r--src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.c42
-rw-r--r--src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.h1
-rw-r--r--src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c5
-rw-r--r--src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h3
18 files changed, 190 insertions, 30 deletions
diff --git a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Cipher.cs b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Cipher.cs
index 8b987ce31ea..8cc861a948c 100644
--- a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Cipher.cs
+++ b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Cipher.cs
@@ -136,6 +136,34 @@ internal static partial class Interop
return EvpCipherFinalEx(ctx, ref MemoryMarshal.GetReference(output), out bytesWritten);
}
+ [LibraryImport(Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_AeadCipherFinalEx")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ private static unsafe partial bool EvpAeadCipherFinalEx(
+ SafeEvpCipherCtxHandle ctx,
+ byte* outm,
+ out int outl,
+ [MarshalAs(UnmanagedType.Bool)] out bool authTagMismatch);
+
+ internal static unsafe bool EvpAeadCipherFinalEx(
+ SafeEvpCipherCtxHandle ctx,
+ Span<byte> output,
+ out int bytesWritten,
+ out bool authTagMismatch)
+ {
+ scoped Span<byte> notNullOutput = output;
+
+ // We can't pass null down to the native shim, so create a valid pointer if we have an empty span.
+ if (notNullOutput.IsEmpty)
+ {
+ notNullOutput = (stackalloc byte[1]).Slice(1);
+ }
+
+ fixed (byte* pOutput = &MemoryMarshal.GetReference(notNullOutput))
+ {
+ return EvpAeadCipherFinalEx(ctx, pOutput, out bytesWritten, out authTagMismatch);
+ }
+ }
+
[LibraryImport(Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_CipherSetTagLength")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool CipherSetTagLength(
diff --git a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs
index 99e9063d8ec..a90b8977d5b 100644
--- a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs
+++ b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs
@@ -270,6 +270,12 @@ namespace System.Security.Cryptography
public abstract void SetHashAlgorithm(string strName);
public abstract void SetKey(System.Security.Cryptography.AsymmetricAlgorithm key);
}
+ public sealed partial class AuthenticationTagMismatchException : System.Security.Cryptography.CryptographicException
+ {
+ public AuthenticationTagMismatchException() { }
+ public AuthenticationTagMismatchException(string? message) { }
+ public AuthenticationTagMismatchException(string? message, System.Exception? inner) { }
+ }
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")]
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 996f80f6687..ed68d33a835 100644
--- a/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj
+++ b/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj
@@ -283,6 +283,7 @@
<Compile Include="System\Security\Cryptography\AsymmetricKeyExchangeFormatter.cs" />
<Compile Include="System\Security\Cryptography\AsymmetricSignatureDeformatter.cs" />
<Compile Include="System\Security\Cryptography\AsymmetricSignatureFormatter.cs" />
+ <Compile Include="System\Security\Cryptography\AuthenticationTagMismatchException.cs" />
<Compile Include="System\Security\Cryptography\Base64Transforms.cs" />
<Compile Include="System\Security\Cryptography\BasicSymmetricCipher.cs" />
<Compile Include="System\Security\Cryptography\ChaCha20Poly1305.cs" />
diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AeadCommon.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AeadCommon.Windows.cs
index fe10a0ed2ca..909f650a7aa 100644
--- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AeadCommon.Windows.cs
+++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AeadCommon.Windows.cs
@@ -104,7 +104,7 @@ namespace System.Security.Cryptography
CryptographicOperations.ZeroMemory(plaintext);
}
- throw new CryptographicException(SR.Cryptography_AuthTagMismatch);
+ throw new AuthenticationTagMismatchException();
default:
throw CreateCryptographicException(ntStatus);
}
diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesCcm.Android.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesCcm.Android.cs
index 39247bed98e..b7089bd3d10 100644
--- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesCcm.Android.cs
+++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesCcm.Android.cs
@@ -69,11 +69,13 @@ namespace System.Security.Cryptography
throw new CryptographicException();
}
- if (!Interop.Crypto.EvpCipherFinalEx(
+ if (!Interop.Crypto.EvpAeadCipherFinalEx(
ctx,
ciphertextAndTag.Slice(ciphertextBytesWritten),
- out int bytesWritten))
+ out int bytesWritten,
+ out bool authTagMismatch))
{
+ Debug.Assert(!authTagMismatch);
throw new CryptographicException();
}
@@ -141,13 +143,20 @@ namespace System.Security.Cryptography
plaintextBytesWritten += bytesWritten;
- if (!Interop.Crypto.EvpCipherFinalEx(
+ if (!Interop.Crypto.EvpAeadCipherFinalEx(
ctx,
plaintext.Slice(plaintextBytesWritten),
- out bytesWritten))
+ out bytesWritten,
+ out bool authTagMismatch))
{
CryptographicOperations.ZeroMemory(plaintext);
- throw new CryptographicException(SR.Cryptography_AuthTagMismatch);
+
+ if (authTagMismatch)
+ {
+ throw new AuthenticationTagMismatchException();
+ }
+
+ throw new CryptographicException(SR.Arg_CryptographyException);
}
plaintextBytesWritten += bytesWritten;
diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesCcm.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesCcm.OpenSsl.cs
index 6c78bee075e..0aedd34fe2d 100644
--- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesCcm.OpenSsl.cs
+++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesCcm.OpenSsl.cs
@@ -104,7 +104,7 @@ namespace System.Security.Cryptography
if (!Interop.Crypto.EvpCipherUpdate(ctx, plaintext, out int plaintextBytesWritten, ciphertext))
{
plaintext.Clear();
- throw new CryptographicException(SR.Cryptography_AuthTagMismatch);
+ throw new AuthenticationTagMismatchException();
}
if (plaintextBytesWritten != plaintext.Length)
diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesGcm.Android.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesGcm.Android.cs
index 3e36ef16d38..471338a8e8a 100644
--- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesGcm.Android.cs
+++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesGcm.Android.cs
@@ -74,11 +74,13 @@ namespace System.Security.Cryptography
throw new CryptographicException();
}
- if (!Interop.Crypto.EvpCipherFinalEx(
+ if (!Interop.Crypto.EvpAeadCipherFinalEx(
_ctxHandle,
ciphertextAndTag.Slice(ciphertextBytesWritten),
- out int bytesWritten))
+ out int bytesWritten,
+ out bool authTagMismatch))
{
+ Debug.Assert(!authTagMismatch);
throw new CryptographicException();
}
@@ -141,13 +143,20 @@ namespace System.Security.Cryptography
plaintextBytesWritten += bytesWritten;
- if (!Interop.Crypto.EvpCipherFinalEx(
+ if (!Interop.Crypto.EvpAeadCipherFinalEx(
_ctxHandle,
plaintext.Slice(plaintextBytesWritten),
- out bytesWritten))
+ out bytesWritten,
+ out bool authTagMismatch))
{
CryptographicOperations.ZeroMemory(plaintext);
- throw new CryptographicException(SR.Cryptography_AuthTagMismatch);
+
+ if (authTagMismatch)
+ {
+ throw new AuthenticationTagMismatchException();
+ }
+
+ throw new CryptographicException(SR.Arg_CryptographyException);
}
plaintextBytesWritten += bytesWritten;
diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesGcm.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesGcm.OpenSsl.cs
index 1691f3357db..f11936951bc 100644
--- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesGcm.OpenSsl.cs
+++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesGcm.OpenSsl.cs
@@ -106,7 +106,7 @@ namespace System.Security.Cryptography
out int bytesWritten))
{
CryptographicOperations.ZeroMemory(plaintext);
- throw new CryptographicException(SR.Cryptography_AuthTagMismatch);
+ throw new AuthenticationTagMismatchException();
}
plaintextBytesWritten += bytesWritten;
diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AuthenticationTagMismatchException.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AuthenticationTagMismatchException.cs
new file mode 100644
index 00000000000..6c63045da0f
--- /dev/null
+++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AuthenticationTagMismatchException.cs
@@ -0,0 +1,47 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace System.Security.Cryptography
+{
+ /// <summary>
+ /// The exception that is thrown when a decryption operation with an authenticated cipher
+ /// has an authentication tag mismatch.
+ /// </summary>
+ public sealed class AuthenticationTagMismatchException : CryptographicException
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AuthenticationTagMismatchException" /> class with default
+ /// properties.
+ /// </summary>
+ public AuthenticationTagMismatchException() : base(SR.Cryptography_AuthTagMismatch)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AuthenticationTagMismatchException" /> class with a specified
+ /// error message.
+ /// </summary>
+ /// <param name="message">
+ /// The error message that explains the reason for the exception.
+ /// </param>
+ public AuthenticationTagMismatchException(string? message) : base(message)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AuthenticationTagMismatchException" /> class with a specified
+ /// error message and a reference to the inner exception that is the cause of this exception.
+ /// </summary>
+ /// <param name="message">
+ /// The error message that explains the reason for the exception.
+ /// </param>
+ /// <param name="inner">
+ /// The exception that is the cause of the current exception. If the parameter is not
+ /// <see langword="null" />, the current exception is raised in a catch block that handles the inner exception.
+ /// </param>
+ public AuthenticationTagMismatchException(string? message, Exception? inner)
+ : base(message, inner)
+ {
+ }
+ }
+}
diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ChaCha20Poly1305.Android.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ChaCha20Poly1305.Android.cs
index a36599202e3..3c6f78d5425 100644
--- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ChaCha20Poly1305.Android.cs
+++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ChaCha20Poly1305.Android.cs
@@ -71,11 +71,13 @@ namespace System.Security.Cryptography
throw new CryptographicException();
}
- if (!Interop.Crypto.EvpCipherFinalEx(
+ if (!Interop.Crypto.EvpAeadCipherFinalEx(
_ctxHandle,
ciphertextAndTag.Slice(ciphertextBytesWritten),
- out int bytesWritten))
+ out int bytesWritten,
+ out bool authTagMismatch))
{
+ Debug.Assert(!authTagMismatch);
throw new CryptographicException();
}
@@ -133,13 +135,20 @@ namespace System.Security.Cryptography
plaintextBytesWritten += bytesWritten;
- if (!Interop.Crypto.EvpCipherFinalEx(
+ if (!Interop.Crypto.EvpAeadCipherFinalEx(
_ctxHandle,
plaintext.Slice(plaintextBytesWritten),
- out bytesWritten))
+ out bytesWritten,
+ out bool authTagMismatch))
{
CryptographicOperations.ZeroMemory(plaintext);
- throw new CryptographicException(SR.Cryptography_AuthTagMismatch);
+
+ if (authTagMismatch)
+ {
+ throw new AuthenticationTagMismatchException();
+ }
+
+ throw new CryptographicException(SR.Arg_CryptographyException);
}
plaintextBytesWritten += bytesWritten;
diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ChaCha20Poly1305.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ChaCha20Poly1305.OpenSsl.cs
index 6fd211689ae..353f7429403 100644
--- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ChaCha20Poly1305.OpenSsl.cs
+++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ChaCha20Poly1305.OpenSsl.cs
@@ -106,7 +106,7 @@ namespace System.Security.Cryptography
out int bytesWritten))
{
CryptographicOperations.ZeroMemory(plaintext);
- throw new CryptographicException(SR.Cryptography_AuthTagMismatch);
+ throw new AuthenticationTagMismatchException();
}
plaintextBytesWritten += bytesWritten;
diff --git a/src/libraries/System.Security.Cryptography/tests/AesCcmTests.cs b/src/libraries/System.Security.Cryptography/tests/AesCcmTests.cs
index 1d662f9a085..8b68d7f1d61 100644
--- a/src/libraries/System.Security.Cryptography/tests/AesCcmTests.cs
+++ b/src/libraries/System.Security.Cryptography/tests/AesCcmTests.cs
@@ -34,7 +34,7 @@ namespace System.Security.Cryptography.Tests
additionalData[0] ^= 1;
byte[] decrypted = new byte[dataLength];
- Assert.Throws<CryptographicException>(
+ Assert.Throws<AuthenticationTagMismatchException>(
() => aesCcm.Decrypt(nonce, ciphertext, tag, decrypted, additionalData));
}
}
@@ -305,7 +305,7 @@ namespace System.Security.Cryptography.Tests
tag[0] ^= 1;
- Assert.Throws<CryptographicException>(
+ Assert.Throws<AuthenticationTagMismatchException>(
() => aesCcm.Decrypt(nonce, data, tag, data));
Assert.Equal(new byte[data.Length], data);
}
@@ -347,7 +347,7 @@ namespace System.Security.Cryptography.Tests
byte[] plaintext = new byte[testCase.Plaintext.Length];
RandomNumberGenerator.Fill(plaintext);
- Assert.Throws<CryptographicException>(
+ Assert.Throws<AuthenticationTagMismatchException>(
() => aesCcm.Decrypt(testCase.Nonce, ciphertext, tag, plaintext, testCase.AssociatedData));
Assert.Equal(new byte[plaintext.Length], plaintext);
}
@@ -370,7 +370,7 @@ namespace System.Security.Cryptography.Tests
byte[] plaintext = new byte[testCase.Plaintext.Length];
RandomNumberGenerator.Fill(plaintext);
- Assert.Throws<CryptographicException>(
+ Assert.Throws<AuthenticationTagMismatchException>(
() => aesCcm.Decrypt(testCase.Nonce, ciphertext, tag, plaintext, testCase.AssociatedData));
Assert.Equal(new byte[plaintext.Length], plaintext);
}
diff --git a/src/libraries/System.Security.Cryptography/tests/AesGcmTests.cs b/src/libraries/System.Security.Cryptography/tests/AesGcmTests.cs
index 1a41a2beb3f..6ef5391e40e 100644
--- a/src/libraries/System.Security.Cryptography/tests/AesGcmTests.cs
+++ b/src/libraries/System.Security.Cryptography/tests/AesGcmTests.cs
@@ -34,7 +34,7 @@ namespace System.Security.Cryptography.Tests
additionalData[0] ^= 1;
byte[] decrypted = new byte[dataLength];
- Assert.Throws<CryptographicException>(
+ Assert.Throws<AuthenticationTagMismatchException>(
() => aesGcm.Decrypt(nonce, ciphertext, tag, decrypted, additionalData));
}
}
@@ -312,7 +312,7 @@ namespace System.Security.Cryptography.Tests
tag[0] ^= 1;
- Assert.Throws<CryptographicException>(
+ Assert.Throws<AuthenticationTagMismatchException>(
() => aesGcm.Decrypt(nonce, data, tag, data));
Assert.Equal(new byte[data.Length], data);
}
@@ -354,7 +354,7 @@ namespace System.Security.Cryptography.Tests
byte[] plaintext = new byte[testCase.Plaintext.Length];
RandomNumberGenerator.Fill(plaintext);
- Assert.Throws<CryptographicException>(
+ Assert.Throws<AuthenticationTagMismatchException>(
() => aesGcm.Decrypt(testCase.Nonce, ciphertext, tag, plaintext, testCase.AssociatedData));
Assert.Equal(new byte[plaintext.Length], plaintext);
}
@@ -377,7 +377,7 @@ namespace System.Security.Cryptography.Tests
byte[] plaintext = new byte[testCase.Plaintext.Length];
RandomNumberGenerator.Fill(plaintext);
- Assert.Throws<CryptographicException>(
+ Assert.Throws<AuthenticationTagMismatchException>(
() => aesGcm.Decrypt(testCase.Nonce, ciphertext, tag, plaintext, testCase.AssociatedData));
Assert.Equal(new byte[plaintext.Length], plaintext);
}
diff --git a/src/libraries/System.Security.Cryptography/tests/ChaCha20Poly1305Tests.cs b/src/libraries/System.Security.Cryptography/tests/ChaCha20Poly1305Tests.cs
index 7d39b45922f..f381e17e73d 100644
--- a/src/libraries/System.Security.Cryptography/tests/ChaCha20Poly1305Tests.cs
+++ b/src/libraries/System.Security.Cryptography/tests/ChaCha20Poly1305Tests.cs
@@ -35,7 +35,7 @@ namespace System.Security.Cryptography.Tests
additionalData[0] ^= 1;
byte[] decrypted = new byte[dataLength];
- Assert.Throws<CryptographicException>(
+ Assert.Throws<AuthenticationTagMismatchException>(
() => chaChaPoly.Decrypt(nonce, ciphertext, tag, decrypted, additionalData));
}
}
@@ -271,7 +271,7 @@ namespace System.Security.Cryptography.Tests
tag[0] ^= 1;
- Assert.Throws<CryptographicException>(
+ Assert.Throws<AuthenticationTagMismatchException>(
() => chaChaPoly.Decrypt(nonce, data, tag, data));
Assert.Equal(new byte[data.Length], data);
}
@@ -310,7 +310,7 @@ namespace System.Security.Cryptography.Tests
tag[0] ^= 1;
byte[] plaintext = RandomNumberGenerator.GetBytes(testCase.Plaintext.Length);
- Assert.Throws<CryptographicException>(
+ Assert.Throws<AuthenticationTagMismatchException>(
() => chaChaPoly.Decrypt(testCase.Nonce, ciphertext, tag, plaintext, testCase.AssociatedData));
Assert.Equal(new byte[plaintext.Length], plaintext);
}
diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.c
index 0b52b0a100a..b09932392ee 100644
--- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.c
+++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.c
@@ -299,6 +299,48 @@ int32_t AndroidCryptoNative_CipherFinalEx(CipherCtx* ctx, uint8_t* outm, int32_t
return CheckJNIExceptions(env) ? FAIL : SUCCESS;
}
+
+int32_t AndroidCryptoNative_AeadCipherFinalEx(CipherCtx* ctx, uint8_t* outm, int32_t* outl, int32_t* authTagMismatch)
+{
+ if (!ctx)
+ return FAIL;
+
+ abort_if_invalid_pointer_argument(outm);
+ abort_if_invalid_pointer_argument(outl);
+ abort_if_invalid_pointer_argument(authTagMismatch);
+
+ JNIEnv* env = GetJNIEnv();
+
+ *outl = 0;
+ *authTagMismatch = 0;
+
+ jbyteArray outBytes = (jbyteArray)(*env)->CallObjectMethod(env, ctx->cipher, g_cipherDoFinalMethod);
+ jthrowable ex = NULL;
+
+ if (TryGetJNIException(env, &ex, false))
+ {
+ if (ex == NULL)
+ {
+ return FAIL;
+ }
+
+ if ((*env)->IsInstanceOf(env, ex, g_AEADBadTagExceptionClass))
+ {
+ *authTagMismatch = 1;
+ }
+
+ (*env)->DeleteLocalRef(env, ex);
+ return FAIL;
+ }
+
+ jsize outBytesLen = (*env)->GetArrayLength(env, outBytes);
+ *outl = outBytesLen;
+ (*env)->GetByteArrayRegion(env, outBytes, 0, outBytesLen, (jbyte*) outm);
+
+ (*env)->DeleteLocalRef(env, outBytes);
+ return CheckJNIExceptions(env) ? FAIL : SUCCESS;
+}
+
int32_t AndroidCryptoNative_CipherCtxSetPadding(CipherCtx* ctx, int32_t padding)
{
if (!ctx)
diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.h b/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.h
index 6b9555967a5..dc1bbe2211d 100644
--- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.h
+++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.h
@@ -36,6 +36,7 @@ PALEXPORT int32_t AndroidCryptoNative_CipherCtxSetPadding(CipherCtx* ctx, int32_
PALEXPORT int32_t AndroidCryptoNative_CipherUpdateAAD(CipherCtx* ctx, uint8_t* in, int32_t inl);
PALEXPORT int32_t AndroidCryptoNative_CipherUpdate(CipherCtx* ctx, uint8_t* out, int32_t* outl, uint8_t* in, int32_t inl);
PALEXPORT int32_t AndroidCryptoNative_CipherFinalEx(CipherCtx* ctx, uint8_t* outm, int32_t* outl);
+PALEXPORT int32_t AndroidCryptoNative_AeadCipherFinalEx(CipherCtx* ctx, uint8_t* outm, int32_t* outl, int32_t* authTagMismatch);
PALEXPORT CipherInfo* AndroidCryptoNative_Aes128Ecb(void);
PALEXPORT CipherInfo* AndroidCryptoNative_Aes128Cbc(void);
PALEXPORT CipherInfo* AndroidCryptoNative_Aes128Cfb8(void);
diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c
index 7aa8b45768b..0c4c732b44e 100644
--- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c
+++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c
@@ -88,6 +88,9 @@ jclass g_sslCtxClass;
jmethodID g_sslCtxGetDefaultMethod;
jmethodID g_sslCtxGetDefaultSslParamsMethod;
+// javax/crypto/spec/AEADBadTagException
+jclass g_AEADBadTagExceptionClass;
+
// javax/crypto/spec/GCMParameterSpec
jclass g_GCMParameterSpecClass;
jmethodID g_GCMParameterSpecCtor;
@@ -704,6 +707,8 @@ JNI_OnLoad(JavaVM *vm, void *reserved)
g_ivPsClass = GetClassGRef(env, "javax/crypto/spec/IvParameterSpec");
g_ivPsCtor = GetMethod(env, false, g_ivPsClass, "<init>", "([B)V");
+ g_AEADBadTagExceptionClass = GetClassGRef(env, "javax/crypto/AEADBadTagException");
+
g_GCMParameterSpecClass = GetClassGRef(env, "javax/crypto/spec/GCMParameterSpec");
g_GCMParameterSpecCtor = GetMethod(env, false, g_GCMParameterSpecClass, "<init>", "(I[B)V");
diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h
index f8d89e25131..9294c0e13cb 100644
--- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h
+++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h
@@ -71,6 +71,9 @@ extern jmethodID g_cipherInitMethod;
extern jmethodID g_cipherInit2Method;
extern jmethodID g_getBlockSizeMethod;
+// javax/crypto/spec/AEADBadTagException
+extern jclass g_AEADBadTagExceptionClass;
+
// javax/crypto/spec/IvParameterSpec
extern jclass g_ivPsClass;
extern jmethodID g_ivPsCtor;