M12 / Discovery, inventory and CBOM

Crypto-agility: provider models and testability

PractitionerAdvisor

After this lesson you can

  • Explain, with concrete examples, the common idea behind the OpenSSL providers, JCE and PKCS#11 provider models (separating algorithm choice from code)
  • Explain what policy-driven algorithm selection and testable agility mean, pointing in one sentence to why the HAWK case (M14) makes this concrete

Before thisCBOM and CycloneDX: the real release history

Mental model

In M12’s previous two lessons you saw how to build a crypto inventory (discovery) and how to document it (CBOM). This last lesson goes beyond the inventory and focuses on “how quickly and safely can we switch when an algorithm changes”, that is, crypto-agility.

Three provider models, the same basic idea

OpenSSL providers: as you actually tested in your own environment in M0, the default provider of OpenSSL 3.5+ supports ML-KEM, ML-DSA and SLH-DSA natively (M0’s own RockyLinux 9 test showed exactly this: the base image’s 3.0.7 had no PQC support at all, and after updating to 3.5.5 it did; the general phrase “OpenSSL 3.x” is misleading, the version threshold matters). Application code binds not to a particular algorithm implementation but to OpenSSL’s abstract interface (the EVP API), and which provider (default, legacy, fips, or third party) supplies which algorithm is decided in configuration.

JCE (Java Cryptography Extension): Java’s own provider architecture applies the same idea. Bouncy Castle (a standard JCE/JCA provider) has fully supported ML-KEM and ML-DSA since 30 October 2024SOURCED; but its FIPS-certified module (BC-FJA 3.0.0) has early access, under test, not yet FIPS-certifiedSOURCED status, as a separate product. This is a distinction parallel to M5’s OpenSSL FIPS provider example (CAVP passed, CMVP pending): a JCE provider supporting an algorithm and that provider being FIPS certified are different claims.

PKCS#11: as you saw in depth in M9, the abstract interface for talking to an HSM; functions such as C_EncapsulateKey/C_DecapsulateKey provide a common call pattern regardless of which HSM vendor supports which algorithm.

The common pattern of all three: application code binds to an abstraction layer instead of directly to a concrete algorithm implementation; the real implementation behind that layer can be changed without changing the code. This is the architectural foundation of crypto-agility.

Policy-driven selection and testability: architecture is not enough

Using the provider model is a necessary but not sufficient condition for agility. Two more elements are needed: policy-driven algorithm selection (which algorithm to use is not hardcoded but read from a configuration or policy file, so an algorithm change does not require a code change) and testable agility (an algorithm change can really be verified with an automated test suite; being able to say not “we changed it, it seems to work” but “we changed it, the tests passed”).

You will see exactly why this distinction matters in M14: the HAWK case (a NIST round 3 candidate withdrawn before reaching production because of a cryptanalysis finding) is concrete evidence that crypto-agility is not an abstract principle but a real need. An algorithm considered “secure” today may have to change tomorrow because of such a finding; without a provider model, policy-driven selection and testability, that change becomes a crisis that can take months, instead of a routine operation that takes days.

Update, October 2026

On 29 September 2026 Germany’s BSI advised against using Classic McEliece in new developments, after several 2026 cryptanalysis papers lowered its key-recovery cost estimates. Hybrid deployments still keep at least classical security, and ML-KEM and HQC are not affected. It is a second, live example of the point above: a scheme that was recommended for years can be downgraded quickly, and only systems that can switch algorithms through policy, and test the switch, absorb that calmly. Details on the news desk.

Numbers to know

  • Three provider models, one idea: OpenSSL providers (seen in M0; OpenSSL 3.5+'s default provider supports ML-KEM/ML-DSA/SLH-DSA natively), JCE (Java Cryptography Extension; Bouncy Castle fully supports ML-KEM/ML-DSA since 1.79, but its FIPS-certified module is separate and in early access), PKCS#11 (seen in M9; the C_EncapsulateKey/C_DecapsulateKey mechanism abstraction)
  • Testable agility: the ability to verify that an algorithm change really works with an automated test suite rather than trial in production; the difference between saying 'we have agility' and 'we can prove our agility'

Lab: Move algorithm selection out of the code in your own system

[not run] This is an architecture assessment exercise, not a runnable command

Requires: . Check your setup

shell
# Find a cryptography call in your own code base (e.g. a signing function). Is the algorithm name hardcoded, or read from a configuration or policy file?
Recorded output
If it is hardcoded, that is an agility gap: changing the algorithm requires a code change and a rebuild. If it is read from configuration, there is agility, but check separately that it is really tested (that a test suite switches the algorithm and verifies the result)

At the table

How to say this in a bank meeting.

To an executive
Crypto-agility is a more important question than 'which algorithm do we use': 'how quickly and safely can we switch when an algorithm changes.' While PQC standards are still maturing (some are still drafts, as you saw in M2-M4), this agility is a more valuable investment than which algorithm we choose today.
To an architect
The common pattern of the three provider models (OpenSSL, JCE, PKCS#11): application code binds not to a concrete algorithm implementation but to an abstract interface (a provider); which provider supplies which algorithm is decided at run time or in configuration. These are the OpenSSL and Java counterparts of the PKCS#11 mechanism abstraction you saw in M9.
Objection
“"Our code base already uses the provider model. Doesn't that mean we have agility?"”
Answer
Using the provider model is a necessary but not sufficient condition for agility. The real question: when an algorithm changes (for example when a vulnerability is found, as in the HAWK case you will see in M14), how do you prove the change really works? Without a provider model agility is impossible, but a provider model alone does not guarantee that an untested switch won't blow up in production.

Sources

  • OpenSSL Project, 2025. The normative source for OpenSSL's provider architecture, the structure that separates algorithm implementations from code

    overview / 10 min

  • Legion of the Bouncy Castle Inc., 2024. The source for the JCE/JCA provider's ML-KEM/ML-DSA/SLH-DSA support and the early-access status of its separate FIPS module (BC-FJA)

    1.79 release notes / 10 min

Checkpoint

Answer first, then compare with the model answer and score yourself against the rubric. Saved in this browser only.

  1. 01Recall

    What is the common idea of OpenSSL providers, JCE and PKCS#11?

  2. 02Recall

    What is the difference between 'testable agility' and 'using the provider model'?

  3. 03Scenario

    A team claims it is agile because its code base uses the provider model. What extra question do you ask, and how do you test the claim?

  4. 04Hostile

    An auditor asks 'How quickly can you adapt to an algorithm change, and can you prove it?' Answer using the difference between the provider model and testability.

Project linkContributes to the crypto-agility sections of Projects 3 and 4 (capstone), as a template for the common architecture of the three provider models and the testability requirement.