For 2026, The Move Towards FIPS 140–3

If your company is serious about cybersecurity and in protecting data, there’s a good chance that it will support FIPS (Federal Information…

For 2026, The Move Towards FIPS 140–3

If your company is serious about cybersecurity and in protecting data, there’s a good chance that it will support FIPS (Federal Information Processing Standards Publications) 140–2. Currently, there are 946 certified modules for FIPS 140–2 [here]:

While still acceptable, FIPS 140–2 will be replaced by FIPS 140–3 by 2026, and which involves much more rigorous testing and validation.

Just doing it, but doing it right!

Doing cryptography right is not an easy task, and companies who are serious about it, will invest a considerable amount of resources to make sure everything works well. And we have to be careful in the libraries that we use and how we implement our methods. So, how do we make sure we are using the right code integration for our applications? Well, one way is to make sure the cryptography functions that we integrate are Federal Information Processing Standard (FIPS)-140 compliant. The two main standards are FIPS 140–2 [here] and FIPS 140–3 [here] (which is superseding FIPS 140–2). These tests design and implementation of a cryptographic module, such as for [1]:

specifications; ports and interfaces; roles, services, and authentication; finite state model; physical security; operational environment; cryptographic key management; electromagnetic interference/electromagnetic compatibility (EMI/EMC); self-tests; design assurance; and mitigation of other attacks.

At the current time, this is these are the FIPS-140 compliance integrations for common cryptography libraries:

We can see that OpenSSL, Bouncy Castle and BSAFE are all approved for FIPS 140–2 and in process for FIP 140–3 validation. It is thus unlikely that we would see a library such as NaCL or libsodium used in an serious application within the finance industry or in critical infrastructure applications, as they have not been rigously tested against FIPS 140–2. It should be noted that BSAFE is a closed-source library, while OpenSSL and Bouncy Castle are open source implementations (and where their code can be reviewed in an open and transparent way).

FIPS 140

The US government defines a number of standards that many companies comply with, and one of the strongest is FIPS (Federal Information Processing Standard) 140. This standard defines a number of levels that define the security level of a product/system and includes modules tested within the Cryptography Module Validation Program (CMVP).

In 2019, FIPS 140–3 replaced FIPS 140–2. It defines 11 areas of design involved in designing and implementing modules [here][docs]. This includes four security levels for the cryptographic module specification; cryptographic module interfaces; roles, services, and authentication; software/firmware security; operating environment; physical security; non-invasive security; sensitive security parameter management; self-tests; life-cycle assurance; and mitigation of other attacks. Each layer builds on the previous level, and where Level 1 is the lowest level, and Level 4 provides the highest level. For those working in finance and in high-risk areas, Level 3 is often the benchmark, while in defence-related areas, Level 4 would often be applied. Table 1 outlines the differences between the levels.

Table 1: FIPS 140–3 overview

For physical security, the tamper-proof nature of the target system is key, and where tamper detection becomes important at the higher levels of security.

As Figure 1 illustrates, Level 1 provides a minimum security level, while Level 2 implements methods around role-based authentication, and also integrate physical tamper-evidence. As we move up to Level 3, we integrate identity-based authentication and also has an isolation barrier between the identity system and the place that the keys are stored. This would integrate a secure enclave (such as with the Apple T2 chip), or a hardware security module (HSM). For Level 4, we see formal models, detailed explanations, and pre/post conditions. It also contains a great integration of tamper detection, with EFP (Environmental Failure Protection) and EFT (Environmental Failure Testing). This would involve testing where other components around the target system were to fail, and for the target to not be compromised. A typical focus is around side channels, such as for radio frequency (RF) or electromagnetic (EM) radiation from devices.

Figure 1: FIP 140 levels

For isolation, a method often used is key wrapping, and where a key is protected outside a trusted environment. Within the Cloud, AWS CloudHSM (hardware security module) supports AES key wrapping with the default initialization vector — 0xA6A6A6A6A6A6A6A6- or a user-defined value. This provides a FIPS 140–2 Level 3 environment and where the keys in their raw form are only handled within a trusted cloud instance. The wrapped keys can then exist outside this but only converted into their actual form within the CloudHSM. A key generated within the CloudHSM can then be wrapped for export from the environment, or imported from an external wrapped key. The AWS CLI is on the form which defines a key handle (with -k) and the wrapping key handle (with -w):

> wrapKey -k 7 -w 14 -out mykey.key -m 5Key Wrapped.Wrapped Key written to file "mykey.key: length 612
Cfm2WrapKey returned: 0x00 : HSM Return: SUCCESS

Within FIP140–3, the approved methods are:

  • Symmetric key: AES-128, AES-192 and AES-256. Acceptable modes are ECB, CBC, CBC with ciphertext stealing, OFB, CTR, CCM, GCM, XTS, and AES Keywrap. AES is the only approved method, but Triple DES can be used in existing applications (but requires a key length of at least 192 bits).
  • Digital Signatures: This requires a security level of 112 bits or more. For RSA signatures, we require the keys to be 2,048 bits or more. For DSA: (2048-bit keys, 224-bit hash); (2048-bit keys, 256-bit hash) and (3072-bit keys, 256-bit hash). For ECDSA and EdDSA we require a key size of 224 bits or more, such as the NIST P-256 curve. Approved curves include NIST P-224, P-256, P-384 and P-521 curves.
  • Hashing: For hashing, the SHA-1 is not recommended, as it has been broken. The approved ones are SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512, SHA512/224, and SHA-512/256), and SHA-3 (SHA3–224, SHA3–256, SHA3–384, SHA3–512, SHAKE128, and SHAKE256).
  • MAC (Message Authentication Code): HMAC methods must have 112 bits or more, and for the approved AES and hashing ciphers.
  • Key exchange. For Diffie-Hellman (DH) we require at least a 2,048-bit prime number, and some of the acceptable methods are MODP-2048, MODP-3072, MODP-4096, MODP-6144, and MODP-8192.

To be FIPS140–2 compliant, a Web server setup can be set up with a mixture of these:

Bouncy Castle in FIPS 140

The Bouncy Castle library is one that has been tested against FIPS140–2, and where the code used to create these programs must thus be free of flaws and often have to comply with the Federal Information Processing Standard (FIPS) standard. In this case, we will use the Bouncy Castle FIPS (FIPS) C# API. This needs the bc-fips-1.0.2.dll assembly and which integrates into the System.Security.Cryptography provider.

First we create a folder named “bc_fips01”, and then go into that folder.We can create a Dotnet console project for .NET 8.0 with:

dotnet new console --framework net8.0

Next we download the FIPS module (bc-fips-1.0.2.dll) from [here] and add it as a reference to the project:

This produces a Csproject file of:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Reference Include="Org.BouncyCastle.Crypto">
<HintPath>bc-fips-1.0.2.dll</HintPath>
</Reference>

</ItemGroup>
</Project>

The following are some examples of the code integration for C#:

  • Random generator (FIPS) and Bouncy Castle (with C#). Random generator and Bouncy Castle (with C#). The usage of random numbers is often critically important for the security of cryptography-focused applications. With this, the random oracle model defines that the security of the overall method is defined by the randomness of the oracle value that we use. The code used to create these programs must thus be free of flaws and often have to comply with the Federal Information Processing Standard (FIPS) standard. In this case, we will use the Bouncy Castle FIPS (FIPS) C# API. This needs the bc-fips-1.0.2.dll assembly and which integrates into the System.Security.Cryptography provider.
  • Random generator (FIPS) and Bouncy Castle (with C#). RSA Signatures (PKCS1v15) using Bouncy Castle (with C#). With RSA, we create a key pair — a public key and a private key. For a digital signature, we create a digital signature using the private key, and the verify with the public key. In this case, we will use the FIPS Bouncy Castle library to generate a random RSA key, and then sign a message.
  • PBKDF2 and Bouncy Castle (with C#). PBKDF2 and Bouncy Castle (with C#). PBKDF2 (Password-Based Key Derivation Function 2) is defined in RFC 2898 and generates a salted hash. Often this is used to create an encryption key from a defined password, and where it is not possible to reverse the password from the hashed value. It is used in TrueCrypt to generate the key required to read the header information of the encrypted drive and which stores the encryption keys. Also, it is used in WPA-2 in order to create a hashed version of the password.
  • HKDF Key Derivation and Bouncy Castle (with C#). HKDF Key Derivation and Bouncy Castle (with C#). HMAC Key Derivation function (HKDF) is used to derive an encryption key from a pass phrase. Initially HKDF creates a pseudorandom key (PRK) using a pass phrase and a salt value (and any other random functions which are relavent), in order to produce an HMAC hash function (such as HMAC-SHA256), andalong with a salt value.
  • FIPS Hashing and Bouncy Castle (with C#). FIPS Hashing and Bouncy Castle (with C#). The hashing method of MD5 should not be used these days, as it is possible to create a hash collision for a relatively low cost. Improved methods are SHA-1 (160 bits), SHA-256 (256 bits) and SHA-512 (512 bits). This page provides a Federal Information Processing Standard (FIPS) approved code for hashing methods and which integrates into the Bouncy Castle FIPS (FIPS) C# API. This needs the bc-fips-1.0.2.dll assembly and which integrates into the System.Security.Cryptography provider.
  • FIPS key wrapping and Bouncy Castle (with C#). FIPS Hashing and Bouncy Castle (with C#). With key wrapping we take a secret symmetric key and encrypted it. This typically happens when we want to take a back-up of a symmetric key. For this we can either encrypted it with symmetric key encryption or public key encryption. For public key encryption, we create a key pair, and then encrypt the key with our public key — and which will wrap the key. To reveal the key, we can decrypt with the associated public key.
  • FIPS CMAC and Bouncy Castle (with C#). FIPS CMAC and Bouncy Castle (with C#). CMACs (Cipher-based message authentication codes) create a message authentication codes (MACs) using a block cipher and a secret key. They differ from HMACs in that they use a symmetric key method for the MACs rather than a hashing method.
  • FIPS HMAC and Bouncy Castle (with C#). FIPS HMAC and Bouncy Castle (with C#). HMAC is a message authentication code (MAC) that can be used to verify the integrity and authentication of a message. It involves hashing the message with a secret key and thus differs from standard hashing, which is purely a one-way function.

An example of code integration for hashing methods is [here]:

namespace Hashing
{
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Fips;
class Program
{

static void Main(string[] args)
{


var hash="sha256";
var msg="Qwerty123";

if (args.Length >0) msg=args[0];
if (args.Length >1) hash=args[1];


try {
var hashmethod=FipsShs.Sha256;
if (hash=="SHA1") hashmethod=FipsShs.Sha1;
if (hash=="SHA224") hashmethod=FipsShs.Sha224;
if (hash=="SHA256") hashmethod=FipsShs.Sha256;
if (hash=="SHA384") hashmethod=FipsShs.Sha384;
if (hash=="SHA512") hashmethod=FipsShs.Sha512;
if (hash=="SHA3_224") hashmethod=FipsShs.Sha3_224;
if (hash=="SHA3_256") hashmethod=FipsShs.Sha3_256;
if (hash=="SHA3_384") hashmethod=FipsShs.Sha3_384;
if (hash=="SHA3_512") hashmethod=FipsShs.Sha3_512;


IDigestFactory<FipsShs.Parameters> factory = CryptoServicesRegistrar.CreateService(hashmethod);
IStreamCalculator<IBlockResult> calculator = factory.CreateCalculator();
Stream digestStream = calculator.Stream;
digestStream.Write(System.Text.Encoding.UTF8.GetBytes(msg), 0,System.Text.Encoding.UTF8.GetBytes(msg).Length);
digestStream.Close();
byte[] digest = calculator.GetResult().Collect();
Console.WriteLine("Message: {0}",msg);
Console.WriteLine("Hash method: {0}",hash);
Console.WriteLine("Hash: {0}",Convert.ToHexString(digest));
Console.WriteLine("Hash: {0}",Convert.ToBase64String(digest));

} catch (Exception e) {
Console.WriteLine("Error: {0}",e.Message);
}
}
}
}

Conclusions

Companies who are serious about security should be serious about FIPS 140.

References

[1] https://en.wikipedia.org/wiki/Comparison_of_cryptography_libraries