Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use crypto.subtle for AES on Browser WASM #71501

Merged
merged 5 commits into from
Jul 6, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ internal enum SimpleDigest
Sha512,
};

internal static readonly bool CanUseSubtleCrypto = CanUseSubtleCryptoImpl() == 1;

[LibraryImport(Libraries.CryptoNative, EntryPoint = "SystemCryptoNativeBrowser_CanUseSubtleCryptoImpl")]
internal static partial int CanUseSubtleCryptoImpl();
private static partial int CanUseSubtleCryptoImpl();

[LibraryImport(Libraries.CryptoNative, EntryPoint = "SystemCryptoNativeBrowser_SimpleDigestHash")]
internal static unsafe partial int SimpleDigestHash(
Expand All @@ -28,5 +30,27 @@ internal static unsafe partial int SimpleDigestHash(
int input_len,
byte* output_buffer,
int output_len);

[LibraryImport(Libraries.CryptoNative, EntryPoint = "SystemCryptoNativeBrowser_Sign")]
internal static unsafe partial int Sign(
SimpleDigest hashAlgorithm,
byte* key_buffer,
int key_len,
byte* input_buffer,
int input_len,
byte* output_buffer,
int output_len);

[LibraryImport(Libraries.CryptoNative, EntryPoint = "SystemCryptoNativeBrowser_EncryptDecrypt")]
internal static unsafe partial int EncryptDecrypt(
int encrypting,
byte* key_buffer,
int key_len,
byte* iv_buffer,
int iv_len,
byte* input_buffer,
int input_len,
byte* output_buffer,
int output_len);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public static void RandomKeyRoundtrip_128()
}

[Fact]
[SkipOnPlatform(TestPlatforms.Browser, "AES-192 is not supported on Browser")]
public static void RandomKeyRoundtrip_192()
{
using (Aes aes = AesFactory.Create())
Expand Down Expand Up @@ -485,6 +486,7 @@ public static void VerifyKnownTransform_CFB128_128_NoPadding_3()
}

[Fact]
[SkipOnPlatform(TestPlatforms.Browser, "AES-192 is not supported on Browser")]
public static void VerifyKnownTransform_CBC192_NoPadding()
{
TestAesTransformDirectKey(
Expand Down Expand Up @@ -525,6 +527,7 @@ public static void VerifyKnownTransform_CFB8_192_NoPadding()
}

[Fact]
[SkipOnPlatform(TestPlatforms.Browser, "AES-192 is not supported on Browser")]
public static void VerifyKnownTransform_CBC192_NoPadding_2()
{
TestAesTransformDirectKey(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ public static void LegalKeySizes()

Assert.Equal(128, keySizeLimits.MinSize);
Assert.Equal(256, keySizeLimits.MaxSize);
Assert.Equal(64, keySizeLimits.SkipSize);

// Browser's SubtleCrypto doesn't support AES-192
int expectedKeySkipSize = PlatformDetection.IsBrowser ? 128 : 64;
Assert.Equal(expectedKeySkipSize, keySizeLimits.SkipSize);
}
}

Expand Down Expand Up @@ -214,6 +217,7 @@ public static void VerifyKeyGeneration_128()
}

[Fact]
[SkipOnPlatform(TestPlatforms.Browser, "AES-192 is not supported on Browser")]
public static void VerifyKeyGeneration_192()
{
using (Aes aes = AesFactory.Create())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -541,14 +541,13 @@
Link="Common\Interop\Browser\Interop.Libraries.cs" />
<Compile Include="$(CommonPath)System\Sha1ForNonSecretPurposes.cs"
Link="Common\System\Sha1ForNonSecretPurposes.cs" />
<Compile Include="$(CommonPath)Interop\Browser\System.Security.Cryptography.Native.Browser\Interop.SimpleDigestHash.cs"
Link="Common\Interop\Browser\System.Security.Cryptography.Native.Browser\Interop.SimpleDigestHash.cs" />
<Compile Include="$(CommonPath)Interop\Browser\System.Security.Cryptography.Native.Browser\Interop.Sign.cs"
Link="Common\Interop\Browser\System.Security.Cryptography.Native.Browser\Interop.Sign.cs" />
<Compile Include="$(CommonPath)Interop\Browser\System.Security.Cryptography.Native.Browser\Interop.SubtleCrypto.cs"
Link="Common\Interop\Browser\System.Security.Cryptography.Native.Browser\Interop.SubtleCrypto.cs" />
<Compile Include="System\Security\Cryptography\AesCcm.NotSupported.cs" />
<Compile Include="System\Security\Cryptography\AesGcm.NotSupported.cs" />
<Compile Include="System\Security\Cryptography\AesImplementation.Browser.cs" />
<Compile Include="System\Security\Cryptography\AesManagedTransform.Browser.cs" />
<Compile Include="System\Security\Cryptography\AesSubtleCryptoTransform.Browser.cs" />
<Compile Include="System\Security\Cryptography\AsnFormatter.Managed.cs" />
<Compile Include="System\Security\Cryptography\CapiHelper.Browser.cs" />
<Compile Include="System\Security\Cryptography\ChaCha20Poly1305.NotSupported.cs" />
Expand Down Expand Up @@ -583,6 +582,9 @@
<Compile Include="System\Security\Cryptography\X509Certificates\StorePal.NotSupported.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\X509Pal.NotSupported.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetPlatformIdentifier)' != 'Browser'">
<Compile Include="System\Security\Cryptography\AesImplementation.NonBrowser.cs" />
</ItemGroup>
<ItemGroup Condition="'$(NeedOpenSslInitializer)' == 'true'">
<Compile Include="$(CommonPath)Interop\Unix\Interop.Libraries.cs"
Link="Common\Interop\Unix\Interop.Libraries.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public abstract class Aes : SymmetricAlgorithm
protected Aes()
{
LegalBlockSizesValue = s_legalBlockSizes.CloneKeySizesArray();
LegalKeySizesValue = s_legalKeySizes.CloneKeySizesArray();
LegalKeySizesValue = AesImplementation.s_legalKeySizes.CloneKeySizesArray();

BlockSizeValue = 128;
FeedbackSizeValue = 8;
Expand All @@ -31,6 +31,5 @@ protected Aes()
}

private static readonly KeySizes[] s_legalBlockSizes = { new KeySizes(128, 128, 0) };
private static readonly KeySizes[] s_legalKeySizes = { new KeySizes(128, 256, 64) };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using Internal.Cryptography;

namespace System.Security.Cryptography
{
internal sealed partial class AesImplementation
{
internal const int BlockSizeBytes = 16; // 128 bits

// SubtleCrypto doesn't support AES-192. http://crbug.com/533699
internal static readonly KeySizes[] s_legalKeySizes = { new KeySizes(128, 256, 128) };
vcsjones marked this conversation as resolved.
Show resolved Hide resolved

private static UniversalCryptoTransform CreateTransformCore(
CipherMode cipherMode,
PaddingMode paddingMode,
Expand All @@ -19,11 +23,17 @@ private static UniversalCryptoTransform CreateTransformCore(
bool encrypting)
{
ValidateCipherMode(cipherMode);
if (iv is null)
throw new CryptographicException(SR.Cryptography_MissingIV);

Debug.Assert(blockSize == AesManagedTransform.BlockSizeBytes);
Debug.Assert(blockSize == BlockSizeBytes);
Debug.Assert(paddingSize == blockSize);

return UniversalCryptoTransform.Create(paddingMode, new AesManagedTransform(key, iv, encrypting), encrypting);
BasicSymmetricCipher cipher = Interop.BrowserCrypto.CanUseSubtleCrypto ?
new AesSubtleCryptoTransform(key, iv, encrypting) :
new AesManagedTransform(key, iv, encrypting);

return UniversalCryptoTransform.Create(paddingMode, cipher, encrypting);
}

private static ILiteSymmetricCipher CreateLiteCipher(
Expand All @@ -37,10 +47,12 @@ private static ILiteSymmetricCipher CreateLiteCipher(
{
ValidateCipherMode(cipherMode);

Debug.Assert(blockSize == AesManagedTransform.BlockSizeBytes);
Debug.Assert(blockSize == BlockSizeBytes);
Debug.Assert(paddingSize == blockSize);

return new AesManagedTransform(key, iv, encrypting);
return Interop.BrowserCrypto.CanUseSubtleCrypto ?
new AesSubtleCryptoTransform(key, iv, encrypting) :
new AesManagedTransform(key, iv, encrypting);
}

private static void ValidateCipherMode(CipherMode cipherMode)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// 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
{
internal sealed partial class AesImplementation
{
internal static readonly KeySizes[] s_legalKeySizes = { new KeySizes(128, 256, 64) };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace System.Security.Cryptography
{
internal sealed class AesManagedTransform : BasicSymmetricCipher, ILiteSymmetricCipher
{
public const int BlockSizeBytes = 16; // 128 bits
private const int BlockSizeBytes = AesImplementation.BlockSizeBytes;
private const int BlockSizeInts = BlockSizeBytes / 4;

private readonly bool _encrypting;
Expand All @@ -30,13 +30,7 @@ public AesManagedTransform(ReadOnlySpan<byte> key,
: base(iv: null, BlockSizeBytes, BlockSizeBytes)
{
Debug.Assert(BitConverter.IsLittleEndian, "The logic of casting Span<int> to Span<byte> below assumes little endian");

if (iv.IsEmpty)
throw new CryptographicException(SR.Cryptography_MissingIV);

// we only support the standard AES block size
if (iv.Length != BlockSizeBytes)
throw new CryptographicException(SR.Cryptography_InvalidIVSize);
Debug.Assert(iv.Length == BlockSizeBytes);

_encrypting = encrypting;
_Nr = GetNumberOfRounds(key);
Expand Down Expand Up @@ -331,7 +325,7 @@ private static int GetNumberOfRounds(ReadOnlySpan<byte> key)
return (BlockSizeBytes > key.Length ? BlockSizeBytes : key.Length) switch
{
16 => 10, // 128 bits
24 => 12, // 192 bits
// 24 => 12, // 192 bits is not supported by SubtleCrypto, so the managed implementation doesn't support it either
32 => 14, // 256 bits
_ => throw new CryptographicException(SR.Cryptography_InvalidKeySize)
};
Expand Down
Loading