FIPS 140-3 support

February 12, 2026 ยท View on GitHub

libspdm 3.0.0 starts adding FIPS 140-3 support.

NOTE: The SPDM WG does not plan to obtain FIPS 140-3 Cryptographic Module Validation Program (CMVP) or Cryptographic Algorithm Validation Program (CAVP) certification for libspdm.

libspdm integrator is expected to choose crypto module and support CMVP.

Design

Cryptographic Algorithm Self-Test

SPDM AlgorithmSpecificationTypeTest Attributes
SHA-256/384/512NIST.FIPS.180-4KATSHA-256/384/512
SHA3-256/384/512NIST.FIPS.202KATSHA3-256/384/512
RSA-SSANIST.FIPS.186-5, rfc8017KATRSA-SSA2048 + SHA256
RSA-PSSNIST.FIPS.186-5, rfc8017KATRSA-PSS2048 + SHA256
ECDSANIST.FIPS.186-5, NIST.SP.800-186KAT with fixed randomECDSA-P256+SHA256
EdDSANIST.FIPS.186-5, NIST.SP.800-186, rfc8032KATEdDSA-25519,EdDSA-448
HMACNIST.FIPS.198-1, rfc2104KATHMAC-SHA-256/384/512
AES-GCMNIST.FIPS.197, NIST.SP.800-38DKATAES-GCM-256
FFDHENIST.SP.800-56Ar3, rfc7919PCTFFDHE-2048
ECDHENIST.SP.800-56Ar3, rfc8446KATECDHE-P256
HKDFNIST.SP.800-56Cr2, rfc5869KATHKDF-HMAC-SHA-256
ChaCha-Poly (*)rfc8439KATnot FIPS approved yet
SM3 (*)GB/T 32905-2016, GM/T 0004-2012, ISO/IEC 10118-3:2018KATnot FIPS approved yet
SM4-GCM (*)GB/T 32907-2016, GM/T 0002-2012, ISO/IEC 18033-3:2010/Amd 1:2021, rfc8998KATnot FIPS approved yet
SM2-digital-signature (*)
SM2-key-exchange (*)
GB/T 32918-2016, GM/T 0003-2012, ISO/IEC 14888-3:2018KATnot FIPS approved yet
SPDM-Key-Schedule (*)DMTF-DSP0274KATnot FIPS approved yet
ML-KEMNIST.FIPS.203KATML-KEM-1024
ML-DSANIST.FIPS.204KATML-DSA-87
SLH-DSANIST.FIPS.205KATSLH-DSA-SHA2-128s

The test maybe Known Answer Test (KAT) or Pairwise Consistency Test (PCT).

The Test Vector (KAT) can be found at CAVP-Testing and Cryptographic Standards and Guidelines.

The latest test code and test case can be found at Automated Cryptographic Validation Protocol (ACVP) Server.

Reference:

Software Integrity Self-Test

Not implemented in the libspdm. The integrator may build libspdm as a binary and do self test.

Implementation

Please refer to FIPS discussion for detail.

FIPS configuration

The integrator can define LIBSPDM_FIPS_MODE=1 according to spdm_lib_config.h to enable FIPS mode.

libspdm_get_fips_mode() in spdm_common_lib can return FIPS mode.

LIBSPDM_FIPS_MODE will only allow below algorithms in spdm_lib_config.h:

  • LIBSPDM_RSA_SSA_2048_SUPPORT, LIBSPDM_RSA_SSA_3072_SUPPORT, LIBSPDM_RSA_SSA_4096_SUPPORT
  • LIBSPDM_RSA_PSS_2048_SUPPORT, LIBSPDM_RSA_PSS_3072_SUPPORT, LIBSPDM_RSA_PSS_4096_SUPPORT
  • LIBSPDM_ECDSA_P256_SUPPORT, LIBSPDM_ECDSA_P384_SUPPORT, LIBSPDM_ECDSA_P521_SUPPORT
  • LIBSPDM_EDDSA_ED25519_SUPPORT, LIBSPDM_EDDSA_ED448_SUPPORT
  • LIBSPDM_FFDHE_2048_SUPPORT, LIBSPDM_FFDHE_3072_SUPPORT, LIBSPDM_FFDHE_4096_SUPPORT
  • LIBSPDM_ECDHE_P256_SUPPORT, LIBSPDM_ECDHE_P384_SUPPORT, LIBSPDM_ECDHE_P521_SUPPORT
  • LIBSPDM_AEAD_AES_128_GCM_SUPPORT, LIBSPDM_AEAD_AES_256_GCM_SUPPORT
  • LIBSPDM_SHA256_SUPPORT, LIBSPDM_SHA384_SUPPORT, LIBSPDM_SHA512_SUPPORT
  • LIBSPDM_SHA3_256_SUPPORT, LIBSPDM_SHA3_384_SUPPORT, LIBSPDM_SHA3_512_SUPPORT
  • LIBSPDM_ML_KEM_512_SUPPORT, LIBSPDM_ML_KEM_768_SUPPORT, LIBSPDM_ML_KEM_1024_SUPPORT
  • LIBSPDM_ML_DSA_44_SUPPORT, LIBSPDM_ML_DSA_65_SUPPORT, LIBSPDM_ML_DSA_87_SUPPORT
  • LIBSPDM_SLH_DSA_SHA2_128S_SUPPORT, LIBSPDM_SLH_DSA_SHAKE_128S_SUPPORT, LIBSPDM_SLH_DSA_SHA2_128F_SUPPORT, LIBSPDM_SLH_DSA_SHAKE_128F_SUPPORT, LIBSPDM_SLH_DSA_SHA2_192S_SUPPORT, LIBSPDM_SLH_DSA_SHAKE_192S_SUPPORT, LIBSPDM_SLH_DSA_SHA2_192F_SUPPORT, LIBSPDM_SLH_DSA_SHAKE_192F_SUPPORT, LIBSPDM_SLH_DSA_SHA2_256S_SUPPORT, LIBSPDM_SLH_DSA_SHAKE_256S_SUPPORT, LIBSPDM_SLH_DSA_SHA2_256F_SUPPORT, LIBSPDM_SLH_DSA_SHAKE_256F_SUPPORT

Below algorithms will be disabled:

  • LIBSPDM_SM2_DSA_P256_SUPPORT
  • LIBSPDM_SM2_KEY_EXCHANGE_P256_SUPPORT
  • LIBSPDM_AEAD_CHACHA20_POLY1305_SUPPORT
  • LIBSPDM_AEAD_SM4_128_GCM_SUPPORT
  • LIBSPDM_SM3_256_SUPPORT

FIPS approved algorithm

If FIPS mode is enabled, then only FIPS-approved algorithms will be enabled, which is listed in NIST.SP.800-140C and NIST.SP.800-140D.

Key zeroization

If a key is not used, then the variable to hold the key must be explicitly zeroized. This is done in the libspdm.

The private key for signing is managed by the requester-asymsignlib and responder-asymlib. The library provider shall guarantee the key is zeroized after use.

The pre-shared key (PSK) is managed by the requester-psklib and responder-psklib. The library provider shall guarantee the key is zeroized after use.

module version API

libspdm_module_version() in spdm_common_lib can return libspdm version information.

self-test API

libspdm_fips_run_selftest() in spdm_crypt_lib can be used to run FIPS selftest, including

  • libspdm_fips_selftest_hmac_sha256()
  • libspdm_fips_selftest_hmac_sha384()
  • libspdm_fips_selftest_hmac_sha512()
  • libspdm_fips_selftest_aes_gcm()
  • libspdm_fips_selftest_rsa_ssa()
  • libspdm_fips_selftest_rsa_pss()
  • libspdm_fips_selftest_hkdf()
  • libspdm_fips_selftest_ecdh()
  • libspdm_fips_selftest_sha256()
  • libspdm_fips_selftest_sha384()
  • libspdm_fips_selftest_sha512()
  • libspdm_fips_selftest_sha3_256()
  • libspdm_fips_selftest_sha3_384()
  • libspdm_fips_selftest_sha3_512()
  • libspdm_fips_selftest_ffdh()
  • libspdm_fips_selftest_ecdsa()
  • libspdm_fips_selftest_eddsa()
  • libspdm_fips_selftest_mlkem()
  • libspdm_fips_selftest_mldsa()
  • libspdm_fips_selftest_slhdsa()

If any test failed, then libspdm_fips_run_selftest() will return false.

libspdm_fips_run_selftest() requires fips_selftest_context parameter, which is initialized by libspdm_get_fips_selftest_context_size(), libspdm_init_fips_selftest_context() in spdm_common_lib.

The expected step is as follows:

  1. The integrator invokes libspdm_get_fips_selftest_context_size(), libspdm_get_fips_selftest_buffer_size() and libspdm_init_fips_selftest_context() to create the FIPS selftest context and required buffer to hold intermediate result.
  2. The integrator invokes libspdm_fips_run_selftest() to trigger self-test.
  3. If fail, then return.
#if LIBSPDM_FIPS_MODE
    m_fips_selftest_context = (void *)malloc(libspdm_get_fips_selftest_context_size());
    if (m_fips_selftest_context == NULL) {
        return NULL;
    }
    fips_selftest_context = m_fips_selftest_context;
    fips_selftest_buffer_size = libspdm_get_fips_selftest_buffer_size();
    fips_selftest_buffer = (void *)malloc(fips_selftest_buffer_size);
    if (fips_selftest_buffer == NULL) {
        return NULL;
    }
    libspdm_init_fips_selftest_context(fips_selftest_context, fips_selftest_buffer_size, fips_selftest_buffer);
    result = libspdm_fips_run_selftest(fips_selftest_context);
    free(fips_selftest_buffer);
    if (!result) {
        return NULL;
    }
#endif

NOTE: If a crypto library does not support a FIPS algorithm, then the algorithm must be disabled explicitly. Otherwise libspdm_fips_run_selftest() will fail. For example, if the integrator links libspdm with mbedtls, then SHA3, EdDSA, ML-KEM, ML-DSA and SLH-DSA related algorithms must be disabled via LIBSPDM_SHA3_256_SUPPORT=0, LIBSPDM_SHA3_384_SUPPORT=0, LIBSPDM_SHA3_512_SUPPORT=0, LIBSPDM_EDDSA_ED25519_SUPPORT=0, LIBSPDM_EDDSA_ED448_SUPPORT=0,LIBSPDM_ML_KEM_512_SUPPORT=0, LIBSPDM_ML_KEM_768_SUPPORT=0, LIBSPDM_ML_KEM_1024_SUPPORT=0, LIBSPDM_ML_DSA_44_SUPPORT=0, LIBSPDM_ML_DSA_65_SUPPORT=0, LIBSPDM_ML_DSA_87_SUPPORT=0, LIBSPDM_SLH_DSA_SHA2_128S_SUPPORT=0, LIBSPDM_SLH_DSA_SHAKE_128S_SUPPORT=0, LIBSPDM_SLH_DSA_SHA2_128F_SUPPORT=0, LIBSPDM_SLH_DSA_SHAKE_128F_SUPPORT=0, LIBSPDM_SLH_DSA_SHA2_192S_SUPPORT=0, LIBSPDM_SLH_DSA_SHAKE_192S_SUPPORT=0, LIBSPDM_SLH_DSA_SHA2_192F_SUPPORT=0, LIBSPDM_SLH_DSA_SHAKE_192F_SUPPORT=0, LIBSPDM_SLH_DSA_SHA2_256S_SUPPORT=0, LIBSPDM_SLH_DSA_SHAKE_256S_SUPPORT=0, LIBSPDM_SLH_DSA_SHA2_256F_SUPPORT=0, LIBSPDM_SLH_DSA_SHAKE_256F_SUPPORT=0, because they are not supported by mbedtls yet.