Skip to content

Merge System.Security.Cryptography.Algorithms to System.Security.Cryptography #61543

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

Merged
merged 7 commits into from
Nov 17, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public void AppendHashData(byte[] data, int offset, int count)
// an invalid number of bytes read. Since our implementations of AppendHashDataCore
// end up using unsafe code, we want to be sure the arguments are valid.
if (data == null)
throw new ArgumentNullException(nameof(data), SR.ArgumentNull_Buffer);
throw new ArgumentNullException(nameof(data));
if (offset < 0)
throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
Expand Down
17 changes: 17 additions & 0 deletions src/libraries/Common/src/Internal/Cryptography/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@ namespace Internal.Cryptography
{
internal static partial class Helpers
{
[UnsupportedOSPlatformGuard("browser")]
internal static bool HasSymmetricEncryption { get; } =
#if NET5_0_OR_GREATER
!OperatingSystem.IsBrowser();
#else
true;
#endif

[UnsupportedOSPlatformGuard("browser")]
internal static bool HasHMAC { get; } =
#if NET5_0_OR_GREATER
!OperatingSystem.IsBrowser();
#else
true;
#endif

#if NET5_0_OR_GREATER
[UnsupportedOSPlatformGuard("ios")]
[UnsupportedOSPlatformGuard("tvos")]
Expand All @@ -20,6 +36,7 @@ internal static partial class Helpers

#if NET5_0_OR_GREATER
[UnsupportedOSPlatformGuard("android")]
[UnsupportedOSPlatformGuard("browser")]
public static bool IsRC2Supported => !OperatingSystem.IsAndroid();
#else
public static bool IsRC2Supported => true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, b
if (inputCount % InputBlockSize != 0)
throw new ArgumentOutOfRangeException(nameof(inputCount), SR.Cryptography_MustTransformWholeBlock);
if (inputCount > inputBuffer.Length - inputOffset)
throw new ArgumentOutOfRangeException(nameof(inputCount), SR.Cryptography_TransformBeyondEndOfBuffer);
throw new ArgumentOutOfRangeException(nameof(inputCount), SR.Argument_InvalidOffLen);
if (outputBuffer == null)
throw new ArgumentNullException(nameof(outputBuffer));
if (outputOffset > outputBuffer.Length)
throw new ArgumentOutOfRangeException(nameof(outputOffset));
if (inputCount > outputBuffer.Length - outputOffset)
throw new ArgumentOutOfRangeException(nameof(outputOffset), SR.Cryptography_TransformBeyondEndOfBuffer);
throw new ArgumentOutOfRangeException(nameof(outputOffset), SR.Argument_InvalidOffLen);

int numBytesWritten = UncheckedTransformBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
Debug.Assert(numBytesWritten >= 0 && numBytesWritten <= inputCount);
Expand All @@ -102,7 +102,7 @@ public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int input
if (inputOffset > inputBuffer.Length)
throw new ArgumentOutOfRangeException(nameof(inputOffset));
if (inputCount > inputBuffer.Length - inputOffset)
throw new ArgumentOutOfRangeException(nameof(inputCount), SR.Cryptography_TransformBeyondEndOfBuffer);
throw new ArgumentOutOfRangeException(nameof(inputCount), SR.Argument_InvalidOffLen);

byte[] output = UncheckedTransformFinalBlock(inputBuffer, inputOffset, inputCount);
return output;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public partial class ECDsa : AsymmetricAlgorithm
/// <summary>
/// Creates an instance of the platform specific implementation of the cref="ECDsa" algorithm.
/// </summary>
public static new ECDsa Create()
public static new partial ECDsa Create()
{
return new ECDsaImplementation.ECDsaSecurityTransforms();
}
Expand All @@ -24,7 +24,7 @@ public partial class ECDsa : AsymmetricAlgorithm
/// <param name="curve">
/// The <see cref="ECCurve"/> representing the elliptic curve.
/// </param>
public static ECDsa Create(ECCurve curve)
public static partial ECDsa Create(ECCurve curve)
{
ECDsa ecdsa = Create();
ecdsa.GenerateKey(curve);
Expand All @@ -37,7 +37,7 @@ public static ECDsa Create(ECCurve curve)
/// <param name="parameters">
/// The <see cref="ECParameters"/> representing the elliptic curve parameters.
/// </param>
public static ECDsa Create(ECParameters parameters)
public static partial ECDsa Create(ECParameters parameters)
{
ECDsa ecdsa = Create();
ecdsa.ImportParameters(parameters);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// 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 Internal.Cryptography;

namespace System.Security.Cryptography
{
Expand All @@ -15,25 +15,28 @@ public static int MacData(
ReadOnlySpan<byte> source,
Span<byte> destination)
{
if (hashAlgorithm == HashAlgorithmName.SHA256)
if (Helpers.HasHMAC)
{
return HMACSHA256.HashData(key, source, destination);
}
else if (hashAlgorithm == HashAlgorithmName.SHA1)
{
return HMACSHA1.HashData(key, source, destination);
}
else if (hashAlgorithm == HashAlgorithmName.SHA512)
{
return HMACSHA512.HashData(key, source, destination);
}
else if (hashAlgorithm == HashAlgorithmName.SHA384)
{
return HMACSHA384.HashData(key, source, destination);
}
else if (hashAlgorithm == HashAlgorithmName.MD5)
{
return HMACMD5.HashData(key, source, destination);
if (hashAlgorithm == HashAlgorithmName.SHA256)
{
return HMACSHA256.HashData(key, source, destination);
}
else if (hashAlgorithm == HashAlgorithmName.SHA1)
{
return HMACSHA1.HashData(key, source, destination);
}
else if (hashAlgorithm == HashAlgorithmName.SHA512)
{
return HMACSHA512.HashData(key, source, destination);
}
else if (hashAlgorithm == HashAlgorithmName.SHA384)
{
return HMACSHA384.HashData(key, source, destination);
}
else if (hashAlgorithm == HashAlgorithmName.MD5)
{
return HMACMD5.HashData(key, source, destination);
}
}

throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ internal static unsafe int Decrypt(
{
Debug.Assert(destination.Length >= encryptedData.Length);

if (!Helpers.HasSymmetricEncryption)
{
throw new CryptographicException(
SR.Format(
SR.Cryptography_UnknownAlgorithmIdentifier,
algorithmIdentifier.Algorithm));
}

// Don't check that algorithmIdentifier.Parameters is set here.
// Maybe some future PBES3 will have one with a default.

Expand Down Expand Up @@ -229,6 +237,14 @@ internal static void InitiateEncryption(
{
Debug.Assert(pbeParameters != null);

if (!Helpers.HasSymmetricEncryption)
{
throw new CryptographicException(
SR.Format(
SR.Cryptography_UnknownAlgorithmIdentifier,
pbeParameters.EncryptionAlgorithm));
}

isPkcs12 = false;

switch (pbeParameters.EncryptionAlgorithm)
Expand Down Expand Up @@ -258,7 +274,7 @@ internal static void InitiateEncryption(
throw new CryptographicException(
SR.Format(
SR.Cryptography_UnknownAlgorithmIdentifier,
pbeParameters.HashAlgorithm.Name));
pbeParameters.EncryptionAlgorithm));
}

HashAlgorithmName prf = pbeParameters.HashAlgorithm;
Expand Down Expand Up @@ -377,6 +393,12 @@ internal static unsafe int Encrypt(
Debug.Assert(pwdTmpBytes!.Length == 0);
}

if (!Helpers.HasHMAC)
{
throw new CryptographicException(
SR.Format(SR.Cryptography_AlgorithmNotSupported, "HMAC" + prf.Name));
}

using (var pbkdf2 = new Rfc2898DeriveBytes(pwdTmpBytes, salt.ToArray(), iterationCount, prf))
{
derivedKey = pbkdf2.GetBytes(keySizeBytes);
Expand Down Expand Up @@ -518,6 +540,8 @@ private static unsafe int Pbes2Decrypt(
Rfc2898DeriveBytes pbkdf2 =
OpenPbkdf2(password, pbes2Params.KeyDerivationFunc.Parameters, out int? requestedKeyLength);

Debug.Assert(Helpers.HasHMAC);

using (pbkdf2)
{
// The biggest block size (for IV) we support is AES (128-bit / 16 byte)
Expand Down Expand Up @@ -556,6 +580,12 @@ private static SymmetricAlgorithm OpenCipher(
{
string? algId = encryptionScheme.Algorithm;

if (!Helpers.HasSymmetricEncryption)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This (+ HasHMAC below) are becoming something of a common pattern. Would it make sense to refactor the "check + throw an appropriate exception" logic into its own helper method?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

M...aybe? They're here because of the UnsupportedOS flow analyzer, to show it that there's no way for Browser to make it to the annotated-as-failing Creates. I don't know how much flexibility we have with what it understands.

{
throw new CryptographicException(
SR.Format(SR.Cryptography_AlgorithmNotSupported, algId));
}

if (algId == Oids.Aes128Cbc ||
algId == Oids.Aes192Cbc ||
algId == Oids.Aes256Cbc)
Expand Down Expand Up @@ -747,6 +777,12 @@ private static unsafe Rfc2898DeriveBytes OpenPbkdf2(
throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
}

if (!Helpers.HasHMAC)
{
throw new CryptographicException(
SR.Format(SR.Cryptography_AlgorithmNotSupported, "HMAC" + prf.Name));
}

int iterationCount = NormalizeIterationCount(pbkdf2Params.IterationCount);
ReadOnlyMemory<byte> saltMemory = pbkdf2Params.Salt.Specified.Value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace System.Security.Cryptography
#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
public partial class RSA : AsymmetricAlgorithm
{
public static new RSA Create() => new RSAImplementation.RSAOpenSsl();
public static new partial RSA Create() => new RSAImplementation.RSAOpenSsl();
}

internal static partial class RSAImplementation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace System.Security.Cryptography
#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
public partial class RSA : AsymmetricAlgorithm
{
public static new RSA Create()
public static new partial RSA Create()
{
return new RSAImplementation.RSASecurityTransforms();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@ System.DirectoryServices.ActiveDirectory.DomainController</PackageDescription>
<Reference Include="System.Threading" />
<Reference Include="System.Threading.Thread" />
</ItemGroup>
<ItemGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">
<Reference Include="System.Security.Cryptography" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' != '.NETCoreApp'">
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="$(SystemIOFileSystemAccessControlVersion)" />
<PackageReference Include="System.Security.AccessControl" Version="$(SystemSecurityAccessControlVersion)" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
<Reference Include="System.Runtime.CompilerServices.Unsafe" />
<Reference Include="System.Runtime.Extensions" />
<Reference Include="System.Runtime.InteropServices" />
<Reference Include="System.Security.Cryptography.Algorithms" />
<Reference Include="System.Security.Cryptography" />
<Reference Include="System.Security.Principal" />
<Reference Include="System.Text.Encoding.Extensions" />
<Reference Include="System.Threading" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,63 @@
// Changes to this file must follow the https://aka.ms/api-review process.
// ------------------------------------------------------------------------------

[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.Aes))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.AesCcm))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.AesGcm))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.AesManaged))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.AsymmetricKeyExchangeDeformatter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.AsymmetricKeyExchangeFormatter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.AsymmetricSignatureDeformatter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.AsymmetricSignatureFormatter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.ChaCha20Poly1305))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CryptoConfig))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.DES))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.DSA))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.DSAParameters))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.DSASignatureDeformatter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.DSASignatureFormat))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.DSASignatureFormatter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.DeriveBytes))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.ECCurve))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.ECDiffieHellman))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.ECDiffieHellmanPublicKey))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.ECDsa))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.ECParameters))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.ECPoint))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.HKDF))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.HMACMD5))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.HMACSHA1))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.HMACSHA256))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.HMACSHA384))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.HMACSHA512))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.IncrementalHash))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.MD5))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.MaskGenerationMethod))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.PKCS1MaskGenerationMethod))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RC2))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RSA))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RSAEncryptionPadding))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RSAEncryptionPaddingMode))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RSAOAEPKeyExchangeDeformatter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RSAOAEPKeyExchangeFormatter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RSAPKCS1KeyExchangeDeformatter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RSAPKCS1KeyExchangeFormatter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RSAPKCS1SignatureDeformatter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RSAPKCS1SignatureFormatter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RSAParameters))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RSASignaturePadding))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RSASignaturePaddingMode))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RandomNumberGenerator))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.Rfc2898DeriveBytes))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.Rijndael))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RijndaelManaged))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.SHA1))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.SHA1Managed))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.SHA256))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.SHA256Managed))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.SHA384))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.SHA384Managed))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.SHA512))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.SHA512Managed))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.SignatureDescription))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.TripleDES))]
Loading