808bits

FIPS 140-2 vs 140-3: what actually changed

2026-09-10 · 6 min

Certificate #5458 is a FIPS 140-2 validation that NIST issued on 31 July 2026. On 21 September it moves to the historical list along with every other 140-2 certificate, so it will have been on the active list for 52 days. NIST stopped accepting 140-2 submissions for new certificates in April 2022. Both facts are true, and the way they fit together says more about what changed between 140-2 and 140-3 than the two standards do.

I run a tracker that pulls the CMVP lists every night and diffs them, 5,506 certificates as of 8 September, and for this I read FIPS 140-2, the implementation guidance on both sides and the SP 800-140 documents.

The date

FIPS 140-3 was approved in March 2019, took effect that September, and testing against it began a year later. From September 2021 the programme stopped taking 140-2 submissions for new certificates, bar vendors already under contract with a lab, and from 1 April 2022 the exception closed too. On 21 September 2026 the transition page puts all remaining 140-2 certificates on the historical list. Historical means a US or Canadian agency may keep using the module in a system it already has, and may not buy it for a new one. Nobody outside those two governments is bound by that directly, but a contract that says “FIPS 140 validated” usually means the active list.

The July 2026 certificate comes through Implementation Guidance G.8, which kept accepting the revalidation scenarios that do not change a sunset date. Under scenario 1A a vendor takes a module another vendor already validated, puts its own name on it with the original vendor’s written permission, and receives a new certificate number that “will inherit the sunset date of the original certificate.” Tintri’s security policy says so plainly: the validation is a rebranding of Red Hat’s RHEL 8 OpenSSL module, certificate 4642, itself validated in October 2023. Of the 75 FIPS 140-2 certificates numbered since January 2024, 60 are software and 14 have OpenSSL in the name.

Of the 485 certificates still active on 140-2, 364 carry numbers issued after the April 2022 cut-off. Most of those were submissions already in the queue, which kept producing 140-2 certificates at fifteen to forty a month until the end of 2023. The 63 active certificates numbered since January 2024 are the other thing, rebrands and minor revisions of modules validated years earlier, and each goes historical on the 21st with its parent.

The text

FIPS 140-3 is ISO/IEC 19790:2012 adopted as a US federal standard, with the test method from ISO/IEC 24759 and NIST’s modifications published as SP 800-140A through F. The eleven requirement areas were recut. The finite state model and EMI/EMC disappear as areas of their own, software/firmware security and non-invasive security appear, “cryptographic key management” becomes “sensitive security parameter management” and “design assurance” becomes “life-cycle assurance”. The level requirements moved in a few places, environmental protection at Level 3 and multi-factor authentication at Level 4 among them, and I have covered those separately.

The change that touches code is the self-test. FIPS 140-2 section 4.9.1 is blunt:

Power-up tests shall be performed by a cryptographic module when the module is powered up … All data output via the data output interface shall be inhibited when the power-up tests are performed.

Every algorithm’s known-answer test runs at boot. Under 19790 the algorithm test is a conditional test instead, and the 140-3 guidance at 10.3.A says when: “prior to the first operational use of the cryptographic algorithm.” Before the module comes up, the required tests shrink to the integrity check and the self-test of the algorithm behind it.

Go’s validated module does both. The AES self-test runs in init():

// crypto/internal/fips140/aes/cast.go
func init() {
	fips140.CAST("AES-CBC", func() error {

The ECDSA self-test waits for the first signature:

// crypto/internal/fips140/ecdsa/cast.go
var fipsSelfTest = sync.OnceFunc(func() {
	fips140.CAST("ECDSA P-256 SHA2-512 sign and verify", func() error {

Both are compliant, and both are in the module NIST validated, as the source still shows. The 2019 YubiKey FIPS flaw was predictable bits left in the RNG buffer by the mandatory power-up self-tests. A 140-3 module may not have run most of those tests yet when it generates its first key, which is either the fix or a different bug, depending on how the deferred tests are written.

The area nobody tests

Non-invasive security is the area 140-3 added, and the one the side-channel flaws of the last decade lived in. The test metrics live in SP 800-140F, section 6.2, “Approved non-invasive attack mitigation test metrics”. The entire body of the section reads: “No additional requirements at this time.” The document is dated March 2020 and I could not find a revision.

Of 778 FIPS 140-3 certificates, 766 list non-invasive security as not applicable. The dozen that do not are mostly NXP secure elements and applets running on them. The area is on every certificate and tested on almost none.

What the certificates say

The module population did not move. The overall levels on the active 140-2 list run 67, 24, 8 and 1 percent for Levels 1 to 4. On 140-3 they run 73, 19, 8 and 0. Of the 485 active 140-2 certificates, 104 have a 140-3 certificate with the same module name, and 95 of those came back at the same level.

What moved is the queue. The CMVP issued six 140-3 certificates in 2022, seven in 2023, 204 in 2024, 167 in 2025 and 394 in the first 36 weeks of this year. It got there with an interim validation scheme. A submission received before January 2024 could take a two-year certificate to clear the backlog, extendable to five with a follow-up report. Red Hat’s RHEL 9 kernel module is certificate 4796, validated September 2024 with the caveat “Interim validation” and a sunset date of 10 September 2026. NIST moved it to the historical list this week, eleven days ahead of the 140-2 list it was supposed to replace.

And then there is the gap. 114 vendors hold active 140-2 certificates and have never held a 140-3 one. That is 166 certificates, 83 of them hardware, 20 of them at Level 3, including two Futurex HSMs, a Marvell NITROX family and the Fortanix appliance. Thirteen of those vendors, Futurex, Marvell and Fortanix among them, have something in the 185-entry modules-in-process queue. The other 101 do not, and the queue is not a date anyway. I have the cross-tab, vendor by vendor, with what each has in the queue. It is a shorter list than 485 makes it sound.

The obvious objection is that none of this is news, because 140-3 was an alignment exercise. The rest of the world has evaluated against 19790 since 2012, and the point was to stop maintaining a separate American standard, not to raise the bar. That is right, and it is the finding. The alignment moved the vocabulary, the paperwork and the timing of a self-test. The security properties of a module validated on 21 September are the ones it had on the 20th.

What changes on the 21st is which certificates a contract will accept. The modules behind them mostly did not change at all. The standard moved less than the date did.