# PRD — Cross-OS FIPS 140-3 Cryptographic Posture

## Table of Contents

<!-- generated by `cypilot toc` -->

## 1. Overview

### 1.1 Purpose

Gears MUST be deployable into environments that require a FIPS 140-3 cryptographic claim (US federal procurement,
regulated industries, large enterprise security baselines). This PRD defines what the FIPS-mode build of Gears
claims, what it does not claim, and the verification gates that make the claim defensible.

The scope is the TLS data plane (outbound HTTPS, inbound HTTPS / mTLS termination, internal service mesh) on Linux,
macOS, and Windows under a single `--features fips` build flag.

### 1.2 Background / Problem Statement

FIPS 140-3 is the only crypto-compliance regime accepted by US federal procurement, several large enterprise customers,
and a growing set of regulated industries. When a deployment requires FIPS, three independent claims must all be true at
once: (1) every TLS-relevant primitive is performed by a CMVP-validated module, (2) the running OS version is inside
that module's Operational Environment, (3) the application uses only Approved algorithms with approved parameters.
Vendors often advertise "FIPS-enabled" builds while quietly violating one of the three.

The Rust ecosystem has no single cross-platform CMVP-validated crypto module equivalent to Go 1.25's `crypto/fips140`.
The OpenSSL FIPS Provider 3.1.2 (cert #4985) has cross-platform OE but requires giving up `rustls` (the TLS state
machine moves into `libssl` C code, surrendering memory-safety guarantees). Gears already have `rustls` in
production; the cost of replacing it with `libssl` outweighs the cost of maintaining three rustls `CryptoProvider`
integrations.

The architectural answer is a single `rustls 0.23` TLS state machine with three pluggable CMVP-validated backends:
AWS-LC FIPS on Linux, Apple corecrypto on macOS, Microsoft Windows CNG on Windows. Decision rationale per backend is in
the ADRs in [`adrs/`](adrs/).

### 1.3 Goals (Business Outcomes)

- A single `--features fips` build flag produces a binary whose TLS data plane routes every cryptographic primitive
  through a CMVP-validated module on Linux, macOS, and Windows.
- The wire-level cipher-suite, key-exchange, and signature-algorithm profile observable from `ClientHello` contains only
  FIPS-Approved algorithms — no ChaCha20-Poly1305, no X25519, no Ed25519, no MD5, no SHA-1 outside the legacy
  signature-verify allowance.
- A defensible FIPS-claim audit trail exists end-to-end: linkage smoke, dep-graph regression, runtime OE check (macOS),
  wire-level probe, CMVP cert search per release.
- The dep graph contains no non-FIPS-validated crypto primitive crate that could be reached at build-time under
  `--features fips` (Phase A enforced via `cargo-deny`).

### 1.4 Glossary

| Term        | Definition                                                                                                                                                            |
|-------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| CMVP        | Cryptographic Module Validation Program (NIST) — the validation regime that produces FIPS 140-3 certificates.                                                         |
| OE          | Operational Environment — the specific OS version + hardware combination listed on a CMVP certificate. A binary running outside the OE has no valid FIPS claim.       |
| CAVS        | Cryptographic Algorithm Validation System — NIST's per-algorithm test program. CAVS validation is one prerequisite for the composite CMVP module certification.       |
| corecrypto  | Apple's user-space cryptographic module, CMVP-validated per macOS release. Accessed via `Security.framework` / `CommonCrypto`.                                        |
| AWS-LC FIPS | The FIPS-validated build of AWS Labs Cryptography library, CMVP cert #4816. Used as the Linux backend via `rustls/fips`.                                              |
| CNG         | Cryptography Next Generation — Microsoft Windows' OS-supplied crypto framework (`bcrypt.dll` / `ncrypt.dll`), CMVP-validated per Windows build.                       |
| FIPS-mode   | OS-level configuration that restricts the system crypto to FIPS-Approved algorithms. On Windows: `HKLM\System\CurrentControlSet\Control\Lsa\FipsAlgorithmPolicy = 1`. |
| HKDF        | HMAC-based Extract-and-Expand Key Derivation Function (RFC 5869). Approved KDF per NIST SP 800-56C.                                                                   |
| EMS         | Extended Master Secret (RFC 7627). NIST SP 800-52 Rev. 2 §3.5 requires it for TLS 1.2 FIPS claims.                                                                    |
| PRF         | Pseudorandom Function. In TLS 1.2 this is the HMAC-based P_hash construction (RFC 5246 §5).                                                                           |

## 2. Actors

### 2.1 Human Actors

#### Security / Compliance Reviewer

**ID**: `cpt-toolkit-fips-actor-compliance-reviewer`

- **Role**: Reviews a Gears deployment's FIPS posture before procurement sign-off or audit. Reads ADRs and PRD,
  runs verification gates, checks CMVP cert OE coverage against the targeted OS version.
- **Needs**: Defensible audit trail (linkage smoke, dep-graph regression, wire-level probe, cert-OE cross-check);
  honest "does NOT claim" list; release checklist artefacts.

#### Operations / Deployment Engineer

**ID**: `cpt-toolkit-fips-actor-ops`

- **Role**: Builds, ships, and operates Gears under `--features fips`. Configures OS-level FIPS-mode flags where
  required (Windows registry), installs the binary on hosts inside the cert's OE.
- **Needs**: One build flag, no special runtime config beyond OS-native FIPS-mode flags; clear error message when the
  deployment host is outside the cert's OE; documented per-OS toolchain requirements.

#### CF/Gear Developer

**ID**: `cpt-toolkit-fips-actor-internal-dev`

- **Role**: Writes Rust code inside Gears. Must not introduce non-FIPS-validated crypto primitives (
  intentionally or transitively) into the FIPS-build dep graph.
- **Needs**: `cargo-deny` policy that rejects forbidden crates at PR time before they merge; clear list of supported
  algorithms.

### 2.2 System Actors

#### CMVP Module (Apple corecrypto / AWS-LC FIPS / Windows CNG)

**ID**: `cpt-toolkit-fips-actor-cmvp-module`

- **Role**: External CMVP-validated cryptographic module. Performs every TLS-relevant primitive (RNG, hash, HMAC, AEAD,
  HKDF, ECDHE, ECDSA, RSA sign/verify) on behalf of `rustls`. Validated and shipped by Apple / AWS Labs / Microsoft
  respectively.

#### TLS Peer

**ID**: `cpt-toolkit-fips-actor-tls-peer`

- **Role**: Any external HTTPS server (outbound case) or HTTPS client (inbound / mTLS case) that completes a TLS 1.2 or
  1.3 handshake with Gears. Must offer an Approved cipher suite + curve + signature scheme for the handshake to
  succeed.

## 3. Operational Concept & Environment

### 3.1 Gear-Specific Environment Constraints

These constraints derive from the CMVP ecosystem and Cargo's resolution model; they cannot be relaxed by Gears-side
engineering.

- **Apple corecrypto is the only path to macOS FIPS.** Apple's `Security.framework` only exposes RSA and NIST P-curves;
  Apple does not submit any third-party module under their OE. Macos FIPS deployments MUST route through corecrypto via
  the in-tree `cf-gears-rustls-corecrypto-provider`.
  See [ADR 0001](adrs/0001-macos-fips-via-corecrypto-provider.md), [ADR 0004](adrs/0004-macos-server-side-tls-via-corecrypto.md).
- **Windows CNG is the only path to Windows FIPS.** Microsoft does not submit third-party modules; `rustls-symcrypt` is
  not currently CMVP-validated. Windows FIPS deployments MUST route through CNG via `rustls-cng-crypto`.
  See [ADR 0003](adrs/0003-windows-fips-via-rustls-cng-crypto.md).
- **TLS 1.2 PRF is not separately CAVS-listed on macOS.** Apple corecrypto exposes only generic HMAC primitives, not a
  CAVS-listed TLS-PRF primitive (unlike AWS-LC FIPS). Consequence: macOS+FIPS deployments MUST restrict to TLS 1.3.
- **Cargo has no target-conditional feature activation.** `[features] fips = ["rustls/fips"]` would activate
  `rustls/fips` on every target, including the macOS and Windows targets where `aws-lc-fips-sys` is dead code.
  Workaround: empty shim crate `cf-gears-rustls-fips-shim` with `[target.cfg(...)]`-gated deps.
  See [ADR 0002](adrs/0002-fips-feature-target-conditional-shim.md).
- **Windows requires OS-level FIPS-mode.** CNG only enforces Approved-only algorithm restrictions when
  `HKLM\System\CurrentControlSet\Control\Lsa\FipsAlgorithmPolicy = 1`. Gears refuse to start on Windows without
  this; `rustls_cng_crypto::fips_provider()` returns an empty provider when the flag is off, and the bootstrap detects
  the empty-provider shape and fails closed.

## 4. Scope

### 4.1 In Scope

- TLS data plane (handshake + record layer) on Linux, macOS, Windows under `--features fips`.
- Outbound HTTPS via `toolkit-http`.
- Inbound HTTPS termination and mTLS client-cert authentication via `rustls::ServerConfig` built on the FIPS provider.
- Server-side TLS signing (RSA-PSS, RSA-PKCS#1 v1.5, ECDSA P-256/P-384/P-521) routed through the CMVP module.
- Wire-level cipher-suite restriction to AES-GCM + ECDHE on NIST P-curves + Approved signature schemes.
- Build-time dep-graph policy refusing non-FIPS-validated crypto crates (`make fips-policy`, Phase A
  in [ADR 0005](adrs/0005-fips-dependency-policy.md)).
- Runtime Operational Environment check on macOS (sysctl-based, fail-closed under `--features fips`).
- Release-time CMVP cert search per targeted OS version.

### 4.2 Out of Scope

- **Gears themselves on the CMVP Validated Modules list.** Gears are consumers of validated modules; the validated
  modules are Apple corecrypto, AWS-LC FIPS Provider, and Microsoft Windows CNG.
- **Non-TLS crypto in the binary.** JWT signature validation (`jsonwebtoken`) uses `ring` / non-FIPS
  `aws-lc-rs`. `ring`, non-FIPS `aws-lc-rs`, and `chacha20` are linked into the macOS+fips binary via transitive deps
  from `pingora-pool`, `ureq`, and rustls's default feature set; they are dead-at-runtime on the TLS path but
  physically present. Dependency policy Phase B (see [ADR 0005](adrs/0005-fips-dependency-policy.md)) tracks the
  cleanup.
- **TLS 1.2 FIPS claim on macOS.** Apple does not expose a CAVS-listed TLS-PRF primitive; `fips_provider()` on macOS is
  TLS-1.3-only.
- **Runtime OE-validation on Linux + Windows.** Today only macOS performs a runtime sysctl-based OE check. Linux +
  Windows OE coverage is verified manually via the release checklist (CMVP cert search per OS version). Tracked as
  TODO-8 in [§13 Open Questions](#13-open-questions).
- **Keychain / NCrypt / HSM-stored private keys.** Server-side TLS keys are loaded from PEM/DER bytes at startup. The
  bytes transit user-space memory before reaching the CMVP module. Strict-FIPS auditors operating under "no plaintext
  CSPs outside the boundary" require a Keychain / NCrypt / HSM flow; tracked as TODO-1.
- **Cross-implementation interop testing.** Today every provider's `handshake_smoke` uses the same provider on both
  sides; cross-provider interop (corecrypto ↔ aws-lc-rs ↔ rustls-cng-crypto) is not in CI. Tracked as TODO-2.
- **Native rustls-symcrypt migration on Windows.** SymCrypt is not currently CMVP-validated; migration is conditional on
  Microsoft obtaining a CMVP certificate. Tracked as TODO-3.
- **`fips140=only`-style source-level enforcement.** A custom `dylint` rule that refuses `use md5;` / `use sha1;` at
  module scope is deferred to Phase C of the dependency policy ([ADR 0005](adrs/0005-fips-dependency-policy.md)).

## 5. Functional Requirements

### 5.1 TLS Cryptographic Routing

#### Outbound HTTPS routes through a CMVP-validated module

- [ ] `p1` - **ID**: `cpt-toolkit-fips-fr-outbound-tls`

The system **MUST** route every TLS-relevant cryptographic primitive (random, hash, HMAC, AEAD encrypt/decrypt, HKDF,
ECDHE, ECDSA sign/verify, RSA-PSS/PKCS#1 sign/verify) performed during outbound HTTPS through the CMVP-validated module
appropriate for the running OS (AWS-LC FIPS on Linux, Apple corecrypto on macOS, Windows CNG on Windows).

- **Rationale**: A FIPS 140-3 claim is only valid when every primitive terminates inside the CMVP boundary; any
  primitive performed in non-validated Rust code or in a different C library voids the claim.
- **Actors**: `cpt-toolkit-fips-actor-cmvp-module`, `cpt-toolkit-fips-actor-tls-peer`
- **Acceptance Evidence**: Linkage smoke per [§9](#9-acceptance-criteria) (e.g. `otool -L` shows only
  `Security.framework` on macOS+fips); wire-level probe at `https://www.howsmyssl.com/a/check` reports AES-GCM-only
  `given_cipher_suites`.

#### Inbound HTTPS / mTLS routes through a CMVP-validated module

- [ ] `p1` - **ID**: `cpt-toolkit-fips-fr-inbound-tls`

The system **MUST** support `rustls::ServerConfig` construction over the FIPS provider so that inbound HTTPS termination
and mTLS client-certificate authentication route every cryptographic primitive — including server-side / client-cert
signing — through the CMVP-validated module.

- **Rationale**: Deployments without a reverse-proxy edge layer (single-process edge, on-prem, mTLS) need server-side TLS in Gears libraries; the FIPS claim must extend to those code paths.
- **Actors**: `cpt-toolkit-fips-actor-cmvp-module`, `cpt-toolkit-fips-actor-tls-peer`
- **Acceptance Evidence**: `tests/handshake_smoke.rs::server_handshake_*` covers TLS 1.3 × {P-256, P-384, P-521,
  RSA-2048} and TLS 1.2 × {ECDHE_ECDSA, ECDHE_RSA}; `server_config_on_fips_provider_advertises_fips` asserts
  `ServerConfig::fips() == true` under `fips_provider()` + EMS.

### 5.2 Approved-Algorithm Surface

#### Wire profile contains only Approved algorithms

- [ ] `p1` - **ID**: `cpt-toolkit-fips-fr-wire-profile`

The system **MUST** restrict the wire-level cipher-suite list, key-exchange group list, and signature scheme list under
`--features fips` to FIPS-Approved algorithms: AES-128/256-GCM, ECDHE on NIST P-256/P-384, ECDSA on P-256/P-384/P-521,
RSA-PSS and RSA-PKCS#1 v1.5 with SHA-256/384/512, HKDF over SHA-256/384, SHA-2 family hash, HMAC-SHA-2 family.

- **Rationale**: A `ClientHello` that offers a non-Approved algorithm (ChaCha20-Poly1305, X25519, MLKEM, Ed25519) is a
  wire-level FIPS claim violation even if the negotiated suite is Approved.
- **Actors**: `cpt-toolkit-fips-actor-tls-peer`
- **Acceptance Evidence**: `tests/fips_provider_invariants.rs` (G-6 regression:
  `fips_provider_has_only_aes_gcm_cipher_suites`, `fips_provider_has_only_nist_kx_groups`,
  `fips_provider_has_only_tls13_protocol`).

#### RSA modulus minimum enforced at key load

- [ ] `p1` - **ID**: `cpt-toolkit-fips-fr-rsa-modulus`

The system **MUST** reject RSA private keys with modulus < 2048 bits at load time, per NIST FIPS 186-5 §5.1.

- **Rationale**: Apple's `SecKeyCreateWithData` accepts 1024-bit RSA keys silently. Without the check, a weak server key
  would pass through to `SecKeyCreateSignature` and produce technically-valid but FIPS-invalid signatures.
- **Acceptance Evidence**: `libs/rustls-corecrypto-provider/src/signer/rsa.rs::rsa_1024_key_is_rejected`.

#### TLS 1.2 EMS required under FIPS claim

- [ ] `p1` - **ID**: `cpt-toolkit-fips-fr-tls12-ems`

The system **MUST** set `require_ems = true` on every TLS 1.2 `ClientConfig` / `ServerConfig` constructed under
`--features fips`, per NIST SP 800-52 Rev. 2 §3.5.

- **Rationale**: Without EMS, a TLS 1.2 master-secret can be derived from session state that does not bind to the
  handshake's full transcript, breaking the FIPS claim's session-key derivation chain.
- **Acceptance Evidence**: `libs/toolkit-http/src/tls.rs::build_client_config` sets the flag and asserts
  `config.fips() == true` under `feature = "fips"`.

### 5.3 EC Key Boundary Preservation

#### EC public point read from SEC1, never derived

- [ ] `p1` - **ID**: `cpt-toolkit-fips-fr-ec-publickey-read`

The system **MUST NOT** derive an EC public point `Q = d · G` from a private scalar `d` in non-CMVP-validated Rust code
on macOS. EC keys imported via `cf-gears-rustls-corecrypto-provider` MUST read the public point from the SEC1
`EcPrivateKey.publicKey` OPTIONAL field; SEC1 inputs without `publicKey`, or with `publicKey` in compressed form, MUST
be rejected fail-closed.

- **Rationale**: EC scalar multiplication is itself a cryptographic primitive. Performing it outside Apple corecrypto
  violates the FIPS 140-3 cryptographic boundary; auditors will flag the claim as void.
- **Acceptance Evidence**: `libs/rustls-corecrypto-provider/src/signer/ec.rs::sec1_without_public_key_is_rejected`,
  `sec1_with_compressed_public_key_is_rejected`.

### 5.4 Build-Time Dependency Discipline

#### Dep-graph bans non-FIPS crypto crates

- [ ] `p1` - **ID**: `cpt-toolkit-fips-fr-dep-graph-policy`

The system **MUST** refuse to compile under `--features fips` if the resolved dependency graph contains any crate from
the Phase A ban list in [`deny-fips.toml`](../../../deny-fips.toml). Phase A covers non-Approved hashes (`md2`, `md4`,
`ripemd`, …), non-Approved AEAD / stream ciphers (`chacha20poly1305`, `salsa20`, …), Curve25519 family (`x25519-dalek`,
`ed25519-dalek`, …), alternative TLS frameworks (`openssl`, `boring`, `native-tls`, …), and alternative rustls
CryptoProviders (`rustls-symcrypt`, `rustls-mbedcrypto-provider`, …).

- **Rationale**: The TLS-routing requirement (FR-outbound-tls) does not prevent application-level or transitive crypto
  calls from bypassing the validated module. The build-time policy is the Rust-ecosystem analogue of Go 1.25's
  `fips140=only` runtime enforcement.
- **Acceptance Evidence**: `make fips-policy` (see [ADR 0005](adrs/0005-fips-dependency-policy.md)).

### 5.5 Runtime Operational Environment Validation

#### macOS OE validation at provider construction

- [ ] `p1` - **ID**: `cpt-toolkit-fips-fr-macos-oe-check`

The system **MUST** verify the running macOS major version against the active Apple corecrypto CMVP cert OE table at
`fips_provider()` construction time on macOS. Mismatch under `--features fips` MUST fail closed by panicking the
process; the env-var `CF_GEARS_FIPS_OE_OVERRIDE=1` downgrades fail-closed to a `tracing::warn!` for CI use on
pre-release macOS.

- **Rationale**: A binary built with `--features fips` that runs on a macOS version outside the cert's OE has no valid
  FIPS claim. Panic is the only signal that cannot be silently caught and downgraded by an intermediate `Result`
  -handling caller.
- **Verification Method**: Inspection of `libs/rustls-corecrypto-provider/src/oe.rs::validate_oe` + unit tests.
- **Acceptance Evidence**: `libs/rustls-corecrypto-provider/src/oe.rs::tests::*`.

#### Windows OS-level FIPS-mode required

- [ ] `p1` - **ID**: `cpt-toolkit-fips-fr-windows-fips-mode`

The system **MUST** refuse to install the CNG-backed crypto provider on Windows when the OS-level FIPS-mode flag (
`HKLM\System\CurrentControlSet\Control\Lsa\FipsAlgorithmPolicy`) is not `1`. The bootstrap MUST detect
`rustls_cng_crypto::fips_provider()`'s empty-provider shape (returned when FIPS-mode is off) and fail closed rather than
installing a non-handshakeable provider.

- **Rationale**: CNG only enforces Approved-only algorithm restrictions when FIPS-mode is enabled; without the flag the
  CMVP cert's claim does not apply to runtime crypto operations.
- **Acceptance Evidence**: Manual smoke per `examples/cf-gears-fips-probe/README.md` "Verify on Windows" — negative case (
  FIPS-mode off → refusal).

## 6. Non-Functional Requirements

### 6.1 Gear-Specific NFRs

#### Toolchain-availability for cross-compile

- [ ] `p2` - **ID**: `cpt-toolkit-fips-nfr-cross-compile-toolchain`

The system **MUST** support cross-compile of the Windows `--features fips` build from a developer Linux or macOS host
using `cargo install cargo-xwin` plus `ninja` for the cmake-driven C deps. No Visual Studio, Xcode, or third-party
closed-source SDK MUST be required for the cross-compile gate to run in CI.

- **Threshold**: `make check-windows-fips` succeeds on Linux and macOS CI hosts.
- **Rationale**: Catching cross-OS regressions in CI requires Windows builds to be reachable from non-Windows hosts.

#### Binary-linkage exclusivity per OS

- [ ] `p1` - **ID**: `cpt-toolkit-fips-nfr-binary-linkage`

The system **MUST NOT** link the AWS-LC FIPS dylib into macOS or Windows `--features fips` builds. Linkage smoke
per [§9](#9-acceptance-criteria) MUST show only Apple `Security.framework` on macOS and only `bcrypt.dll` on Windows (no
`aws-lc-fips*.so` / `*.dylib` / `*.dll`).

- **Threshold**: `otool -L target/release/cf-gears-fips-probe | grep -E 'aws|ssl|crypto'` returns only `Security.framework` on
  macOS; `dumpbin /imports cf-gears-fips-probe.exe | findstr /i "bcrypt aws"` returns only `bcrypt.dll` on Windows.
- **Rationale**: A FIPS claim asserted while a non-OE module is linked into the binary is questionable even if the
  non-OE module is never called; cleaner to exclude it from the link entirely.

#### Memory-safety preservation under FIPS-build

- [ ] `p1` - **ID**: `cpt-toolkit-fips-nfr-memory-safety`

The TLS state machine MUST remain implemented in memory-safe Rust (`rustls`) under `--features fips`. Heartbleed-class
C-TLS-state-machine vulnerabilities MUST NOT enter Gears' threat model via the FIPS toolchain.

- **Rationale**: The OpenSSL FIPS Provider 3.1.2 (CMVP cert #4985) is the only cross-platform CMVP-validated option in
  the ecosystem; using it requires `openssl::ssl::SslStream`, which moves the TLS state machine into `libssl` C code. We
  deliberately reject that path.

#### Cross-OS architectural uniformity

- [ ] `p2` - **ID**: `cpt-toolkit-fips-nfr-cross-os-uniformity`

Adding a new supported OS, or upgrading an existing supported OS to a new major version, MUST NOT require rewriting the
TLS state machine. Only the crypto-primitive backend behind a `cfg` branch MUST change.

- **Rationale**: Customer-visible behaviour drift across OS targets is a support and audit burden; one rustls state
  machine on three backends is materially cheaper to maintain than three native-TLS implementations.

## 7. Public Library Interfaces

### 7.1 Public API Surface

#### `--features fips` build flag

- [ ] `p1` - **ID**: `cpt-toolkit-fips-interface-cargo-feature`

- **Type**: Cargo feature on `cf-gears-toolkit`, `cf-gears-toolkit-http`, and `cf-gears-fips-probe`.
- **Stability**: stable.
- **Description**: Single user-facing API for selecting the FIPS-conformant build. Enables `cf-gears-rustls-fips-shim` on
  Linux (which pulls `rustls/fips` + `hyper-rustls/fips`), `cf-gears-rustls-corecrypto-provider/fips` on macOS, and
  `rustls-cng-crypto/fips` on Windows.
- **Breaking Change Policy**: Removal or renaming requires a major version bump and a documented migration path per ADR.

#### `toolkit::bootstrap::init_crypto_provider`

- [ ] `p1` - **ID**: `cpt-toolkit-fips-interface-init-crypto-provider`

- **Type**: Rust public function on `cf-gears-toolkit`.
- **Stability**: stable.
- **Description**: One-shot installer of the process-wide rustls `CryptoProvider`. Behaviour gated by
  `cfg(feature = "fips")` + `cfg(target_os = ...)`. Documented to be safe to call multiple times — only the first
  invocation has effect; cached result returned on subsequent calls.
- **Breaking Change Policy**: Adding new `CryptoProviderError` variants is a non-breaking change (enum is
  `#[non_exhaustive]`); removing variants is breaking.

#### `cf_gears_rustls_corecrypto_provider::{default_provider, fips_provider}`

- [ ] `p1` - **ID**: `cpt-toolkit-fips-interface-corecrypto-provider`

- **Type**: Rust public functions on `cf-gears-rustls-corecrypto-provider`.
- **Stability**: unstable (`0.1.x`).
- **Description**: Factory functions returning `rustls::crypto::CryptoProvider`. `default_provider()` returns TLS 1.2 +
  1.3 with `fips() = false`; `fips_provider()` returns TLS 1.3 only with `fips() = true`. Under the crate's own `fips`
  feature, `default_provider()` is aliased to `fips_provider()` for single-entry-point compatibility with the
  `rustls-cng-crypto` pattern.
- **Breaking Change Policy**: Caret-pinned to `0.1.x`; semver bumps require dep-graph regression review.

### 7.2 External Integration Contracts

#### CMVP-validated module ABI

- [ ] `p1` - **ID**: `cpt-toolkit-fips-contract-cmvp-module-abi`

- **Direction**: required from external system.
- **Protocol/Format**: Apple `Security.framework` / `CommonCrypto` (macOS), `bcrypt.dll` / `ncrypt.dll` (Windows),
  AWS-LC C ABI (Linux).
- **Compatibility**: Each module's ABI is stable per OS major version; Apple, Microsoft, and AWS Labs publish a new CMVP
  cert per OS major release. The Gears code adapts via the per-target `CryptoProvider` integration; binary
  compatibility is maintained by re-linking against the OS-supplied module at run time.

#### TLS 1.2 / 1.3 peer wire compatibility

- [ ] `p1` - **ID**: `cpt-toolkit-fips-contract-tls-peer-wire`

- **Direction**: provided to external systems (TLS peers).
- **Protocol/Format**: RFC 5246 (TLS 1.2), RFC 8446 (TLS 1.3), RFC 5288 (TLS 1.2 GCM), RFC 7627 (TLS 1.2 EMS).
- **Compatibility**: Backward-compatible with TLS 1.2 peers offering AES-GCM + ECDHE on P-256 / P-384 + ECDSA /
  RSA-PSS / RSA-PKCS#1 with SHA-2; forward-compatible with TLS 1.3 peers offering the same algorithm families. Not
  interoperable with peers that mandate ChaCha20-Poly1305 or X25519 only.

## 8. Use Cases

### 8.1 Outbound HTTPS to a FIPS-required backend

- [ ] `p1` - **ID**: `cpt-toolkit-fips-usecase-outbound-https`

**Actor**: `cpt-toolkit-fips-actor-tls-peer`

**Preconditions**:

- Gears are built with `--features fips`.
- The deployment host's OS is inside the active CMVP cert's OE for the relevant module.

**Main Flow**:

1. CF/Gear calls `toolkit_http::HttpClientBuilder::new().build()`.
2. The HTTP client invokes `tls::get_crypto_provider()`, which returns the installed default rustls `CryptoProvider` (
   corecrypto on macOS, AWS-LC FIPS on Linux, CNG on Windows).
3. The HTTP client constructs a `rustls::ClientConfig` with `require_ems = true` (TLS 1.2) and
   `protocol_versions = &[TLS13]` available.
4. On `GET https://api.partner.example/`, rustls negotiates an AES-GCM cipher suite, P-256 or P-384 kx group, and
   ECDSA / RSA-PSS / RSA-PKCS#1 signature scheme; every primitive routes through the CMVP-validated module.

**Postconditions**:

- The HTTPS connection is established; `ClientConfig::fips()` is `true`.
- No non-FIPS crypto crate is reached on the TLS code path.

**Alternative Flows**:

- **Peer offers only non-Approved algorithms** (ChaCha20-Poly1305, X25519): rustls's handshake fails; Gears return a `handshake_failure` to the caller. No silent downgrade.

### 8.2 Inbound HTTPS termination with mTLS

- [ ] `p1` - **ID**: `cpt-toolkit-fips-usecase-inbound-mtls`

**Actor**: `cpt-toolkit-fips-actor-tls-peer` (TLS client)

**Preconditions**:

- Gears are built with `--features fips`.
- Server certificate + private key are available on disk (PEM/DER, RSA ≥ 2048 or NIST P-curve).
- Server-cert is signed by a CA that the client trusts.
- Client cert is signed by a CA that Gears libraries trust (for mTLS).

**Main Flow**:

1. Gears construct a `rustls::ServerConfig::builder_with_provider(fips_provider().into())` and calls `.with_single_cert(chain, key)`.

2. Server-side `KeyProvider::load_private_key` parses the PEM/DER, performs structural unwrap (PKCS#8 → PKCS#1 for RSA, PKCS#8/SEC1 → X9.63 for EC), and hands the bytes to `SecKeyCreateWithData` (macOS) / `BCryptImportKeyPair` (Windows) / `EVP_PKEY_new` (Linux).

3. For RSA, the loader rejects keys with modulus < 2048 bits.

4. For EC, the loader reads `publicKey` from SEC1; if absent or compressed, rejects.

5. On TLS handshake, the client's certificate is verified against the trust roots, and the server's signature in `CertificateVerify` is produced via the CMVP module.

**Postconditions**:

- `ServerConfig::fips()` is `true`.
- Handshake completes; the client's identity is established by the mTLS cert.

**Alternative Flows**:

- **SEC1 EC key without `publicKey`**: loader rejects with a marker error referencing the FIPS boundary. Operator must
  re-export with `publicKey` embedded.
- **RSA-1024 key**: loader rejects with the FIPS 186-5 minimum error. Operator must regenerate the key at ≥ 2048 bits.

## 9. Acceptance Criteria

- [ ] `make fips-policy` exits clean on the workspace; no Phase A crate from [`deny-fips.toml`](../../../deny-fips.toml)
  appears in the `--features fips` resolved dep graph.
- [ ] `cargo tree --target aarch64-apple-darwin -p cf-gears-example-server --features fips` shows
  `cf-gears-rustls-corecrypto-provider` present and `aws-lc-fips-sys` absent.
- [ ] `cargo tree --target x86_64-unknown-linux-gnu -p cf-gears-example-server --features fips` shows `aws-lc-fips-sys`
  present.
- [ ] `cargo tree --target x86_64-pc-windows-msvc -p cf-gears-example-server --features fips` shows `rustls-cng-crypto`
  present and `aws-lc-fips-sys` absent.
- [ ] `otool -L target/release/cf-gears-fips-probe | grep -E 'aws|ssl|crypto|Security'` on macOS+fips shows only
  `Security.framework`.
- [ ] `dumpbin /imports target/release/cf-gears-fips-probe.exe | findstr /i "bcrypt aws"` on Windows+fips shows only
  `bcrypt.dll`.
- [ ] `cargo test -p cf-gears-rustls-corecrypto-provider --features fips --test fips_provider_invariants` passes.
- [ ] `cargo run -p cf-gears-fips-probe --features fips -- --url https://www.howsmyssl.com/a/check` reports
  `given_cipher_suites` containing only AES-GCM, `given_named_groups` only `secp256r1` / `secp384r1`,
  `post_quantum_key_agreement: false`.
- [ ] Apple corecrypto CMVP cert search
  at <https://csrc.nist.gov/projects/cryptographic-module-validation-program/validated-modules/search> confirms that the
  macOS version targeted by this release is inside the OE of an active corecrypto cert.
- [ ] Microsoft Windows CNG CMVP cert search confirms the same for the targeted Windows build.
- [ ] AWS-LC FIPS Provider CMVP cert (#4816) confirms the targeted Linux distribution and kernel are in OE.
- [ ] Manual smoke on a Windows host: positive case (FIPS-mode on → AES-GCM-only `ClientHello`); negative case (
  FIPS-mode off → bootstrap refusal).

## 10. Dependencies

| Dependency                                               | Description                                                                                                                                          | Criticality |
|----------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|-------------|
| `rustls` 0.23                                            | TLS state machine (handshake, record layer, alerts). Memory-safe Rust.                                                                               | `p1`        |
| `aws-lc-fips-sys`                                        | Linux FIPS-validated crypto module (CMVP cert #4816). Activated via `rustls/fips`.                                                                   | `p1`        |
| Apple corecrypto / `Security.framework` / `CommonCrypto` | macOS OS-supplied CMVP-validated module. Routed via in-tree `cf-gears-rustls-corecrypto-provider`.                                                         | `p1`        |
| Microsoft Windows CNG (`bcrypt.dll`)                     | Windows OS-supplied CMVP-validated module. Routed via `rustls-cng-crypto` (community crate, caret-pinned `0.1.x`).                                   | `p1`        |
| `cf-gears-rustls-fips-shim` (in-tree)                          | Target-conditional feature shim activating `rustls/fips` only on non-macOS, non-Windows targets.                                                     | `p1`        |
| `cargo-deny`                                             | Dep-graph policy enforcement for [`deny-fips.toml`](../../../deny-fips.toml).                                                                        | `p2`        |
| `cargo-xwin` + `ninja`                                   | Cross-compile toolchain for Windows from Linux/macOS hosts. CI only.                                                                                 | `p3`        |
| `pkcs8` + `sec1`                                         | Pure-Rust DER parsing for PKCS#8 / SEC1 EC key envelope unwrap. **No curve arithmetic** — keys pass to corecrypto without crypto operations in Rust. | `p2`        |

## 11. Assumptions

- The deployment host runs an OS version inside the CMVP cert's OE for the relevant module (verified per release via §9
  release-checklist).
- Windows deployments enable system-wide FIPS-mode via Group Policy or registry before installing Gears.
- Operators configure server-side TLS keys at ≥ 2048-bit modulus for RSA or NIST P-curve for EC; legacy 1024-bit RSA
  keys are rejected at load.
- Standard key-generation tooling (`rcgen`, `openssl`, GnuTLS) emits SEC1 EC keys with the `publicKey` OPTIONAL field;
  SEC1 keys produced by `openssl ec -no_public` are rejected.
- Apple, Microsoft, and AWS Labs each publish a fresh CMVP submission per major OS release within an acceptable time
  window (typically 3–6 months); during the gap window between an OS release and its CMVP cert, the release-checklist
  gate may temporarily exclude that OS version from the supported list.
- JWT validation paths (`jsonwebtoken`) and miscellaneous transitive crypto (`ring`, non-FIPS
  `aws-lc-rs`, `chacha20`) are out of scope for the FIPS claim; Phase B of `deny-fips.toml` tracks cleanup.

## 12. Risks

| Risk                                                                                         | Impact                                                                                                       | Mitigation                                                                                                                                                    |
|----------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Apple publishes a new corecrypto CMVP cert later than expected after a macOS major release   | New macOS deployments cannot pass §9 release-checklist; field deployments on the older OS major remain valid | `CF_GEARS_FIPS_OE_OVERRIDE=1` env-var for CI on pre-release macOS; release-checklist documents which macOS majors are currently covered                      |
| `rustls-cng-crypto` is a single-maintainer young crate; upstream may stagnate                | Windows FIPS posture loses upstream maintenance                                                              | Caret-pin to `0.1.x`; migration path to `rustls-symcrypt` documented in [ADR 0003](adrs/0003-windows-fips-via-rustls-cng-crypto.md) as a trigger-based switch |
| Apple SDK silently changes RSA-PSS salt-length default                                       | TLS 1.3 interop breaks with RFC-compliant peers; FIPS-claim becomes ambiguous                                | Cross-impl regression test `rsa_pss_apple_salt_length_matches_rfc8017` runs on every CI build                                                                 |
| Transitive dep pulls a banned Phase A crate into a future PR                                 | Build-time FIPS regression                                                                                   | `make fips-policy` is a required CI gate via `make security`; pre-merge `cargo-deny` rejection                                                                |
| Non-TLS crypto paths (JWT, password hashing) drift further from the validated module surface | Audit finding: "FIPS claim is not what it says on the tin"                                                   | Phase B of `deny-fips.toml` tracks each non-validated crypto crate currently in graph; TODO-7 tracks the broader audit                                        |
| OE-validation cert table goes stale                                                          | Production deployments accept an OS version that has dropped out of the cert's OE                            | Release-checklist explicitly searches the CMVP database per release; TODO-6 tracks automation                                                                 |

## 13. Open Questions

- [ ] **TODO-1**: Keychain / NCrypt / HSM-stored private keys for server-side TLS — owner TBD, target post-1.0 of
  `cf-gears-rustls-corecrypto-provider`. Today's PEM/DER load is acceptable for development and most production deployments
  where filesystem permissions guard the key, but the strict-FIPS posture requires the key never to materialize outside
  the validated module.
- [ ] **TODO-2**: Cross-implementation interop tests (our corecrypto provider ↔ `aws-lc-rs` ↔ `rustls-cng-crypto` over
  real TLS). Acceptance: 6 cases (TLS 1.2 + 1.3 × {RSA, ECDSA-P256, ECDSA-P384}) green with cross-provider
  client/server.
- [ ] **TODO-3**: `rustls-symcrypt` migration on Windows once Microsoft obtains a CMVP cert for SymCrypt. Architecture
  is ready — swap is a two-file change.
- [ ] **TODO-4**: PSS salt-length regression watch for macOS corecrypto. Already covered by
  `rsa_pss_apple_salt_length_matches_rfc8017` cross-impl test; standing regression test, no further action unless it
  fails.
- [ ] **TODO-5**: Dedicated CAVS-listed TLS PRF primitive on macOS. Apple corecrypto does not currently expose
  `CC_TLSPrf`; if it ever does, TLS 1.2 cipher suites can move into `fips_provider()`.
- [ ] **TODO-6**: CMVP-cert-version pinning automation. Today the release checklist asks the engineer to manually verify
  CMVP cert OE coverage. Automate by scraping the CMVP search results into the CI gate.
- [ ] **TODO-7**: Non-TLS crypto outside the FIPS path. `jsonwebtoken` (JWT verification) calls into
  `ring` / non-FIPS `aws-lc-rs`. Audit the dependency surface; evaluate forking `jsonwebtoken` onto a FIPS-friendly
  backend, or restrict JWT validation to symmetric HMAC tokens. Build-time floor enforced
  via [ADR 0005](adrs/0005-fips-dependency-policy.md) `deny-fips.toml` Phase B.
- [ ] **TODO-8**: Runtime OE-validation on Linux + Windows. The macOS branch reads `kern.osproductversion` and panics
  fail-closed on a CMVP-cert OE mismatch. Linux (`/etc/os-release` against the AWS-LC FIPS Provider OE table) and
  Windows (`CurrentBuild` against the CNG CMVP cert table) need an equivalent gate.

## 14. Traceability

- **Design / per-OS rationale**: encoded in the ADRs in [`adrs/`](adrs/).
    - [ADR 0001 — macOS FIPS via custom corecrypto CryptoProvider](adrs/0001-macos-fips-via-corecrypto-provider.md)
    - [ADR 0002 — FIPS feature flag via target-conditional shim crate](adrs/0002-fips-feature-target-conditional-shim.md)
    - [ADR 0003 — Windows FIPS via `rustls-cng-crypto`](adrs/0003-windows-fips-via-rustls-cng-crypto.md)
    - [ADR 0004 — macOS server-side TLS via corecrypto](adrs/0004-macos-server-side-tls-via-corecrypto.md)
    - [ADR 0005 — Workspace-level FIPS dependency policy via cargo-deny](adrs/0005-fips-dependency-policy.md)
- **Implementation pointers**:
    - [`libs/toolkit/src/bootstrap/crypto.rs`](../../../libs/toolkit/src/bootstrap/crypto.rs) — provider dispatch +
      install.
    - [`libs/toolkit-http/src/tls.rs`](../../../libs/toolkit-http/src/tls.rs) — TLS config wiring + EMS enforcement.
    - [`libs/rustls-corecrypto-provider/`](../../../libs/rustls-corecrypto-provider/) — macOS provider crate.
    - [`libs/rustls-fips-shim/`](../../../libs/rustls-fips-shim/) — target-conditional shim.
    - [`deny-fips.toml`](../../../deny-fips.toml) — dep-graph deny list.
    - [`Makefile`](../../../Makefile) `fips-policy` target.
