Skip to content

ffi: FIPS-compliant mode foundation (#06) - #2427

Closed
ronaldtse wants to merge 5 commits into
mainfrom
fips-mode-foundation
Closed

ffi: FIPS-compliant mode foundation (#06)#2427
ronaldtse wants to merge 5 commits into
mainfrom
fips-mode-foundation

Conversation

@ronaldtse

Copy link
Copy Markdown
Contributor

Summary

Foundation for FIPS-compliant mode (roadmap item #6). Adds the build switch, runtime query, and default algorithm policy. The full FIPS effort is a multi-PR initiative; this PR lays the groundwork only.

What's in this PR

  • CMakeLists.txt: new option ENABLE_FIPS_MODE (default Off). When On, forces CRYPTO_BACKEND=openssl (Botan rejected with helpful error) and requires OpenSSL 3.x.
  • src/lib/CMakeLists.txt: defines RNP_FIPS_MODE on librnp-obj (PUBLIC). Propagates to librnp and librnp-static via INTERFACE_COMPILE_DEFINITIONS (added to the existing foreach that copies interface properties).
  • src/lib/sec_profile.cpp: when RNP_FIPS_MODE is defined, the SecurityContext constructor adds Disabled-level rules for non-FIPS-approved algorithms:
    • Symmetric: Twofish, CAST5, IDEA, Blowfish, SM4
    • Hash: MD5, SHA1, RIPEMD160
    • Public key: EdDSA, SM2, ElGamal, ElGamal-Encrypt-Or-Sign
  • include/rnp/rnp.h + src/lib/rnp.cpp: new FFI function rnp_is_fips_mode_enabled() returning whether the library was built with ENABLE_FIPS_MODE=On.
  • docs/security.adoc (new): documents the certification boundary, required OpenSSL version, how to enable, how to query, and current limitations. Makes clear that rnp is a consumer of OpenSSL's validated FIPS provider module, not a validated module itself.
  • src/tests/ffi.cpp: new test test_ffi_fips_mode_query verifying the FFI query.
  • .github/workflows/fips-mode.yml (new): CI leg building and testing under -DENABLE_FIPS_MODE=On.

Why

FIPS 140-3 certification (or its successors) is required for OpenPGP libraries used in US federal, Canadian federal, and many regulated industries. Without a FIPS mode, rnp is invisible to that procurement channel. This PR doesn't get us to certification, but it puts the right bones in place: a clean compile-time switch, an algorithm policy expressed through the existing security-rule registry (not scattered #ifdefs), and a clear certification-boundary statement.

Out of scope (follow-up PRs)

  • Constant-time primitive audit
  • Secret zeroisation audit
  • Argon2 → PBKDF2 S2K migration
  • FIPS provider load/unload ceremony
  • Test-suite adaptation (many existing tests use non-FIPS algorithms and will fail under FIPS mode — see Test Plan below)
  • Real FIPS validation effort

Test plan

  • Local build under -DCRYPTO_BACKEND=openssl -DENABLE_FIPS_MODE=On succeeds (Botan correctly rejected, OpenSSL 1.1.1 would be rejected)
  • test_ffi_fips_mode_query passes (returns 1 in FIPS build, 0 in default build via #if defined(RNP_FIPS_MODE))
  • CI green on the new fips-mode workflow
  • Known: full rnp_tests under FIPS mode currently fails ~37 tests because they use disabled algorithms (DSA, EdDSA, MD5, SHA1, etc.). Adapting these tests is follow-up work; the foundation PR deliberately lands the policy first so we can see what breaks.

@ronaldtse
ronaldtse requested review from antonsviridenko and ni4 July 31, 2026 16:20
@ronaldtse
ronaldtse force-pushed the fips-mode-foundation branch from e60d483 to 5d27b9d Compare August 10, 2026 02:09
Allows callers to enumerate the security profile's rule list, including
the built-in defaults (SHA-1, MD5, CAST5/3DES/IDEA/BLOWFISH, RIPEMD).
Useful for diagnostics, tooling, and letting downstream consumers report
which features rnp considers insecure.
Extends test_ffi_security_rule_enumeration to also add a public-key
rule (EdDSA, PROHIBITED) so the case rnp::FeatureType::PublicKey
branch in rnp_get_security_rule_at and the SecurityLevel::Disabled →
RNP_SECURITY_PROHIBITED mapping are exercised.

Adds the same RNP_FEATURE_PK_ALG handling to get_feature_sec_value()
that hash and cipher types already enjoy, so rnp_add_security_rule,
rnp_get_security_rule, and rnp_remove_security_rule accept public-key
features symmetrically with the other two types.
@ronaldtse
ronaldtse force-pushed the fips-mode-foundation branch from 5d27b9d to 1a7bb99 Compare August 20, 2026 10:11
…#6)

Foundation for FIPS-compliant mode. Adds a cmake build switch
ENABLE_FIPS_MODE that:
- forces CRYPTO_BACKEND=openssl (Botan has no validated FIPS provider)
- requires OpenSSL 3.x (FIPS provider is a 3.x feature)
- defines RNP_FIPS_MODE throughout the library
- adds Disabled-level default security rules for non-FIPS algorithms
  (Twofish, CAST5, IDEA, Blowfish, SM4, MD5, SHA1, RIPEMD160, EdDSA,
  SM2, ElGamal)

Adds the FFI query rnp_is_fips_mode_enabled() so callers can detect
the compile-time setting at runtime. Documents the certification
boundary in docs/security.adoc: rnp is a consumer of OpenSSL's
validated FIPS provider module, not a validated module itself.

Adds a CI leg that builds and tests under -DENABLE_FIPS_MODE=On.

This is foundation only. Constant-time audit, zeroization, Argon2 →
PBKDF2 S2K migration, and FIPS provider loading ceremony are
intentionally out of scope and will land in follow-up PRs.
Adds test_ffi_fips_mode_default_rules which is compiled in only when
RNP_FIPS_MODE is defined. It queries each algorithm the FIPS default
profile marks Disabled (CAST5, IDEA, BLOWFISH, MD5, SHA1, RIPEMD160,
EDDSA, ELGAMAL) via rnp_get_security_rule and asserts the level is
RNP_SECURITY_PROHIBITED. AES-256 is sanity-checked to remain
DEFAULT.

Extends get_feature_sec_value() in the FFI to also accept
RNP_FEATURE_PK_ALG so the Disabled public-key rules can be queried
through the same API as hash and cipher rules.
@ronaldtse
ronaldtse force-pushed the fips-mode-foundation branch from 1a7bb99 to cd67f7d Compare August 20, 2026 10:43
@ronaldtse ronaldtse closed this Aug 20, 2026
@ronaldtse

Copy link
Copy Markdown
Contributor Author

Consolidated into #2424: the FIPS-mode commits have been fast-forward merged into the weak-cipher-reporting branch, combining the security-rule enumeration API and the FIPS foundation into one review. CI for the combined change runs on #2424.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant