Skip to content

Commit cb6958c

Browse files
Copilotwestin-m
andauthored
Enable cross-platform AES-GCM support for .NET 6+ (#3396)
* Initial plan * Add System.Security.Cryptography.AesGcm support for .NET 6+ Co-authored-by: westin-m <127992899+westin-m@users.noreply.github.com> * Update tests to support AesGcm on .NET 6+ Co-authored-by: westin-m <127992899+westin-m@users.noreply.github.com> * Address code review feedback - use consistent null checking Co-authored-by: westin-m <127992899+westin-m@users.noreply.github.com> * move conditions for readability --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: westin-m <127992899+westin-m@users.noreply.github.com>
1 parent 1a55919 commit cb6958c

3 files changed

Lines changed: 32 additions & 6 deletions

File tree

src/Microsoft.IdentityModel.Tokens/opensource/AesGcm/AesGcm.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@ internal class AesGcm : IDisposable
1010
public const int NonceSize = 12;
1111
public const int TagSize = 16;
1212

13+
#if NET6_0_OR_GREATER
14+
private System.Security.Cryptography.AesGcm _aesGcm;
15+
#else
1316
private static readonly SafeAlgorithmHandle s_aesGcm = AesBCryptModes.OpenAesAlgorithm(Cng.BCRYPT_CHAIN_MODE_GCM).Value;
1417
private SafeKeyHandle _keyHandle;
18+
#endif
1519
private bool _disposed;
1620

1721
public AesGcm(byte[] key)
@@ -24,7 +28,17 @@ public AesGcm(byte[] key)
2428

2529
private void ImportKey(byte[] key)
2630
{
31+
32+
#if NET8_0_OR_GREATER
33+
_aesGcm = new System.Security.Cryptography.AesGcm(key, TagSize);
34+
#elif NET6_0_OR_GREATER
35+
// .NET 6 and .NET 7 use the obsolete constructor without tagSizeInBytes parameter
36+
#pragma warning disable SYSLIB0053 // Type or member is obsolete
37+
_aesGcm = new System.Security.Cryptography.AesGcm(key);
38+
#pragma warning restore SYSLIB0053 // Type or member is obsolete
39+
#else
2740
_keyHandle = Interop.BCrypt.BCryptImportKey(s_aesGcm, key);
41+
#endif
2842
}
2943

3044
public void Dispose()
@@ -38,21 +52,33 @@ protected virtual void Dispose(bool disposing)
3852
if (!_disposed && disposing)
3953
{
4054
_disposed = true;
55+
#if NET6_0_OR_GREATER
56+
_aesGcm?.Dispose();
57+
#else
4158
_keyHandle.Dispose();
59+
#endif
4260
}
4361
}
4462

4563
public void Decrypt(byte[] nonce, byte[] ciphertext, byte[] tag, byte[] plaintext, byte[] associatedData = null)
4664
{
4765
AesAead.CheckArgumentsForNull(nonce, plaintext, ciphertext, tag);
66+
#if NET6_0_OR_GREATER
67+
_aesGcm.Decrypt(nonce, ciphertext, tag, plaintext, associatedData);
68+
#else
4869
AesAead.Decrypt(_keyHandle, nonce, associatedData, ciphertext, tag, plaintext, clearPlaintextOnFailure: true);
70+
#endif
4971
}
5072

5173
#region FOR TESTING ONLY
5274
internal void Encrypt(byte[] nonce, byte[] plaintext, byte[] ciphertext, byte[] tag, byte[] associatedData = null)
5375
{
5476
AesAead.CheckArgumentsForNull(nonce, plaintext, ciphertext, tag);
77+
#if NET6_0_OR_GREATER
78+
_aesGcm.Encrypt(nonce, plaintext, ciphertext, tag, associatedData);
79+
#else
5580
AesAead.Encrypt(_keyHandle, nonce, associatedData, plaintext, ciphertext, tag);
81+
#endif
5682
}
5783
#endregion
5884
}

test/Microsoft.IdentityModel.Tokens.Tests/AuthenticatedEncryptionProviderTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ public class AuthenticatedEncryptionProviderTests
6767
[Fact]
6868
public void AesGcmEncryptionOnWindows()
6969
{
70-
#if NET10_0_OR_GREATER
71-
// AES-GCM is now supported on all platforms in .NET 10+
70+
#if NET6_0_OR_GREATER
71+
// AES-GCM is now supported on all platforms in .NET 6+
7272
var context = new CompareContext();
7373
try
7474
{
@@ -104,8 +104,8 @@ public void AesGcmEncryptionOnWindows()
104104
[Fact]
105105
public void AesGcm_Dispose()
106106
{
107-
#if !NET10_0_OR_GREATER
108-
// In .NET 9 and below, AES-GCM is only supported on Windows
107+
#if !NET6_0_OR_GREATER
108+
// In .NET versions below .NET 6, AES-GCM is only supported on Windows
109109
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
110110
Assert.Throws<PlatformNotSupportedException>(() => new AuthenticatedEncryptionProvider(Default.SymmetricEncryptionKey256, SecurityAlgorithms.Aes256Gcm));
111111
#endif

test/Microsoft.IdentityModel.Tokens.Tests/ReferenceTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ public void ECDH_ESReferenceTest()
5858
[Fact]
5959
public void AesGcmReferenceTest()
6060
{
61-
#if NET10_0_OR_GREATER
62-
// AES-GCM is now supported on all platforms in .NET 10+
61+
#if NET6_0_OR_GREATER
62+
// AES-GCM is now supported on all platforms in .NET 6+
6363
var context = new CompareContext();
6464
var providerForDecryption = CryptoProviderFactory.Default.CreateAuthenticatedEncryptionProvider(new SymmetricSecurityKey(RSAES_OAEP_KeyWrap.CEK), AES_256_GCM.Algorithm);
6565
var plaintext = providerForDecryption.Decrypt(AES_256_GCM.E, AES_256_GCM.A, AES_256_GCM.IV, AES_256_GCM.T);

0 commit comments

Comments
 (0)