Skip to content
This repository has been archived by the owner on Oct 27, 2023. It is now read-only.

Commit

Permalink
[reflect] use SHA1.Create() to support FIPS (#13)
Browse files Browse the repository at this point in the history
Context: dotnet/android#3728 (comment)

On Windows 10 machines with the [Use FIPS compliant algorithms][0] group
policy enabled, `mkbundle` fails with:

    C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\mkbundle.exe --dos2unix=false --nomain --i18n none --bundled-header --mono-api-struct-path "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\\mkbundle-api.h" --style linux -c -o obj\Release\bundles\x86_64\temp.c -oo obj\Release\bundles\x86_64\assemblies.o -z obj\Release\android\assets\UnnamedProject.dll obj\Release\android\assets\shrunk\Java.Interop.dll obj\Release\android\assets\shrunk\Mono.Android.dll obj\Release\android\assets\shrunk\mscorlib.dll obj\Release\android\assets\shrunk\System.Core.dll obj\Release\android\assets\shrunk\System.dll obj\Release\android\assets\shrunk\System.Runtime.Serialization.dll (TaskId:215)
    Unhandled Exception: System.InvalidOperationException: This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms. (TaskId:215)
       at System.Security.Cryptography.SHA1Managed..ctor() (TaskId:215)
       at IKVM.Reflection.AssemblyName.ComputePublicKeyToken(Byte[] publicKey) (TaskId:215)
       at IKVM.Reflection.AssemblyName.get_FullName() (TaskId:215)
       at IKVM.Reflection.Universe.LoadAssembly(RawModule module) (TaskId:215)
       at IKVM.Reflection.Universe.LoadFile(String path) (TaskId:215)
       at MakeBundle.LoadAssemblyFile(String assembly) (TaskId:215)
       at MakeBundle.LoadAssemblies(List`1 sources) (TaskId:215)
       at MakeBundle.Main(String[] args) (TaskId:215)

On a FIPS-enabled machine, these code examples:

    var sha1 = new SHA1Managed();

Will throw:

    System.InvalidOperationException:
        This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.

But these three options work:

    var sha1 = SHA1.Create();
    var sha1 = new SHA1CryptoServiceProvider();
    var sha1 = new SHA1Cng();

We should use `SHA1.Create()` which will use the appropriate
implementation if FIPS is enabled or not.

Since the `PublicKeyToken` of a .NET assembly is a SHA1 value, there
is not really another option--we have to make this change for
`mkbundle.exe` to work.

[0]: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/system-cryptography-use-fips-compliant-algorithms-for-encryption-hashing-and-signing
  • Loading branch information
jonathanpeppers authored and akoeplinger committed Oct 3, 2019
1 parent caa8e7f commit e994668
Showing 1 changed file with 8 additions and 5 deletions.
13 changes: 8 additions & 5 deletions reflect/AssemblyName.cs
Original file line number Diff line number Diff line change
Expand Up @@ -402,13 +402,16 @@ internal static byte[] ComputePublicKeyToken(byte[] publicKey)
{
return publicKey;
}
byte[] hash = new SHA1Managed().ComputeHash(publicKey);
byte[] token = new byte[8];
for (int i = 0; i < token.Length; i++)
using (var sha1 = SHA1.Create())
{
token[i] = hash[hash.Length - 1 - i];
byte[] hash = sha1.ComputeHash(publicKey);
byte[] token = new byte[8];
for (int i = 0; i < token.Length; i++)
{
token[i] = hash[hash.Length - 1 - i];
}
return token;
}
return token;
}

internal static string ComputePublicKeyToken(string publicKey)
Expand Down

0 comments on commit e994668

Please sign in to comment.