Working with FIPS in .NET C#

A user of the Windows Installer XML Toolset (WiX) created a bug asking if the we could support FIPS (SFBUG:2545539). FIPS 140 is a U.S. government standard of security for cryptography. Having worked with DHS before at several locations I know that 1) they are strict about security and 2) I would like to see Windows Installer XML Toolset (WiX) more heavily used by our government (and everyone else). The one thing I did hear while working for the fed was that all software that is executed needs to be looked at extensively in order for it to be approved. The good thing about Windows Installer XML Toolset (WiX) is that it is open source and can easily be evaluated in order to adopt.

So, why am I writing this blog? Well, when looking for information on what algorithms are and are not supported I didn’t find much documentation on MSDN. This lead me to look in other locations to find information. I finally stumbled on a good blog called FIPS validated cryptographic algorithms in .NET (it also shows you how to turn FIPS on in Windows there is also KB811833 which describes this in some more detail between Windows 2003/XP and 2008/Vista). Although I figured the information given was correct, I knew there were a few more algorithms available that weren’t listed. So, I went about writing one of my little test apps to see what did and did not work.

The other thing you can derive from this is that we are looking to make the Windows Installer XML Toolset (WiX) FIPS compliant. It currently is not due to the way we generate our identifiers. The toolset itself is not highly worried about security implications as the use of hashes are just for uniqueness. I hope to write more about making the toolset FIPS compliant in the near future.

Before running this on your machine make sure to ENABLE FIPS. Otherwise, you will get all ‘Y’ for ‘Compliant’.

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Reflection;

namespace FIPS
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly core = Assembly.Load(
                "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
            Assembly mscorlib = Assembly.Load(
                "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");

            Type[] subclasses = new Type[]
            {
                typeof(SymmetricAlgorithm),
                typeof(HashAlgorithm),
                typeof(AsymmetricAlgorithm)
            };

            Print(mscorlib, subclasses);
            Console.WriteLine();
            Console.WriteLine();
            Print(core, subclasses);
            
            Console.Read();
        }

        private static void Print(Assembly asm, Type[] subclasses)
        {
            string columnFormat = "{0,-35}{1,-15}{2}";
            Console.WriteLine("FIPS Compliant in {0}", asm.GetName());
            Console.WriteLine(columnFormat, "Name", "Compliant", "Subclass");

            foreach (Type type in asm.GetTypes())
            {
                foreach (Type subclass in subclasses)
                {
                    if (type.IsSubclassOf(subclass))
                    {
                        if (!type.IsAbstract)
                        {
                            string isCompliant = null;
                            try
                            {
                                Activator.CreateInstance(type);
                                isCompliant = "Y";
                            }
                            catch (TargetInvocationException)
                            {
                                isCompliant = "N";
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e.Message);
                            }
                            finally
                            {
                                Console.WriteLine(
                                    columnFormat, type.Name, isCompliant, subclass.Name);
                            }
                        }
                    }
                }
            }
        }
    }
}

The result can be seen below.

 FIPS Compliant in mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Name                               Compliant      Subclass
DESCryptoServiceProvider           Y              SymmetricAlgorithm
DSACryptoServiceProvider           Y              AsymmetricAlgorithm
HMACMD5                            N              HashAlgorithm
HMACRIPEMD160                      N              HashAlgorithm
HMACSHA1                           Y              HashAlgorithm
HMACSHA256                         N              HashAlgorithm
HMACSHA384                         N              HashAlgorithm
HMACSHA512                         N              HashAlgorithm
MACTripleDES                       Y              HashAlgorithm
MD5CryptoServiceProvider           N              HashAlgorithm
RC2CryptoServiceProvider           N              SymmetricAlgorithm
RIPEMD160Managed                   N              HashAlgorithm
RSACryptoServiceProvider           Y              AsymmetricAlgorithm
RijndaelManaged                    N              SymmetricAlgorithm
SHA1CryptoServiceProvider          Y              HashAlgorithm
SHA1Managed                        N              HashAlgorithm
SHA256Managed                      N              HashAlgorithm
SHA384Managed                      N              HashAlgorithm
SHA512Managed                      N              HashAlgorithm
TripleDESCryptoServiceProvider     Y              SymmetricAlgorithm


FIPS Compliant in System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Name                               Compliant      Subclass
AesCryptoServiceProvider           Y              SymmetricAlgorithm
AesManaged                         N              SymmetricAlgorithm
ECDiffieHellmanCng                 Y              AsymmetricAlgorithm
ECDsaCng                           Y              AsymmetricAlgorithm
MD5Cng                             N              HashAlgorithm
SHA1Cng                            Y              HashAlgorithm
SHA256Cng                          Y              HashAlgorithm
SHA256CryptoServiceProvider        Y              HashAlgorithm
SHA384Cng                          Y              HashAlgorithm
SHA384CryptoServiceProvider        Y              HashAlgorithm
SHA512Cng                          Y              HashAlgorithm
SHA512CryptoServiceProvider        Y              HashAlgorithm

As a side note, I would like to add that Windows Live Writer does not log into spaces when FIPS is enabled on your machine. You get an exception message, something similar to this. “An unexpected exception has occurred … please check your proxy server or firewall configuration.” Obviously this is incorrect and should probably be fixed.