---
title: "FIPS 140-3 Compliance Tutorial"
---

# FIPS 140-3 Compliance Tutorial

**Build:** `cargo build --release --no-default-features --features "fips,encryption,vector-search,ha-tier1"`
**Crypto provider:** AWS-LC FIPS — NIST CMVP Certificate **#4816**

---

## UVP

Most embedded databases either ship a single crypto stack you can't swap, or punt FIPS compliance to a wrapper layer. HeliosDB Nano builds **the same source tree** in two modes via Cargo features: the default `ring-crypto` (BLAKE3 + Argon2id) for performance, or `fips` (AWS-LC FIPS Certificate #4816 + SHA-256 + PBKDF2-HMAC-SHA256) for regulated environments. **No code change. Same SQL. Same wire protocol. Same data files.** Toggle the feature flag and you have a binary that satisfies FedRAMP / DoD / FIPS 140-3 requirements out of the box — no third-party HSM required.

---

## When You Need This

| You are | Use |
|---------|-----|
| Building for US Federal civilian / DoD / IC | FIPS mode (mandatory under FIPS 140-3 / FedRAMP) |
| State / municipal government with NIST mandate | FIPS mode |
| HIPAA + Defense contractor (e.g., DHA) | FIPS mode |
| PCI / SOC 2 / GDPR commercial | Default `ring-crypto` is sufficient |
| Pure performance benchmark | Default `ring-crypto` (BLAKE3 is ~3× faster than SHA-256) |

---

## Prerequisites

- Rust 1.85+ toolchain
- A C/C++ toolchain (AWS-LC builds native FIPS-validated assembly)
- ~5 minutes

```bash
rustc --version          # 1.85+
cc --version             # any modern gcc/clang
```

---

## 1. Build the FIPS Binary

The `fips` feature is mutually exclusive with the default `ring-crypto`. You must opt out of defaults:

```bash
git clone https://github.com/HeliosDatabase/HeliosDB-Nano.git
cd HDB-HeliosDB-Nano

cargo build --release \
    --no-default-features \
    --features "fips,encryption,vector-search,ha-tier1"
```

The build pulls `aws-lc-rs = { version = "1.12", features = ["fips"] }`, which compiles the FIPS-validated AWS-LC C library with the same source as Certificate #4816.

Verify:

```bash
./target/release/heliosdb-nano --version
# heliosdb-nano <version>
```

---

## 2. What Changes in FIPS Mode

The crypto provider is a trait (`src/crypto/provider.rs`); the `fips` feature swaps which implementation gets compiled in. Three primitives differ:

| Operation | Default (`ring-crypto`) | FIPS (`fips`) |
|-----------|------------------------|---------------|
| Content hashing (CAS, dump checksums) | BLAKE3 | SHA-256 (NIST FIPS 180-4) |
| KDF for password / TDE keys | Argon2id (memory-hard) | PBKDF2-HMAC-SHA256 (NIST SP 800-132) |
| Random bytes (TDE keys, IVs) | `ring::rand::SystemRandom` | AWS-LC FIPS DRBG (SP 800-90A CTR_DRBG) |
| Symmetric encryption | AES-256-GCM (ring) | AES-256-GCM (AWS-LC FIPS) |
| TLS provider | rustls + ring | rustls + AWS-LC FIPS |

Argon2id is **not on the FIPS-approved list**, which is why HeliosDB swaps in PBKDF2 in this mode. PBKDF2 is computationally cheaper than Argon2id — log in attempts will be marginally faster, but the security guarantee shifts from memory-hardness to iteration count.

---

## 3. Confirm You're Running FIPS

Start the server and check the startup banner:

```bash
./target/release/heliosdb-nano start \
    --memory \
    --auth scram-sha-256 \
    --password s3cret
```

The banner names the active crypto provider:

```
[2/4] Initializing in-memory database...
      Crypto provider: aws-lc-rs (SHA-256 + PBKDF2-HMAC-SHA256, FIPS Cert #4816)
```

You can also check from SQL:

```bash
psql "postgresql://postgres:s3cret@127.0.0.1:5432/postgres" -c \
    "SELECT current_setting('helios.crypto_provider');"
#  current_setting
# ----------------------------------------------------------------
#  aws-lc-rs (SHA-256 + PBKDF2-HMAC-SHA256, FIPS Cert #4816)
```

---

## 4. Programmatic Self-Test

The `CryptoProvider` trait exposes `run_self_test()` which exercises the FIPS power-on self-tests (KAT vectors for AES-GCM, SHA-256, HMAC, DRBG):

```rust
use heliosdb_nano::crypto::provider::default_provider;

fn main() -> heliosdb_nano::Result<()> {
    let crypto = default_provider();
    println!("Provider: {}", crypto.name());
    println!("FIPS:     {}", crypto.is_fips());
    crypto.run_self_test()?;
    println!("Self-test: PASS");
    Ok(())
}
```

When built with `--features fips`, `is_fips()` returns `true` and `run_self_test()` runs the KATs that AWS-LC requires before any cryptographic operation.

---

## 5. Encryption At Rest — Same SQL, FIPS Cipher Suite

TDE (Transparent Data Encryption) reads its key material through the active provider. The DDL is unchanged from the default build:

```sql
-- Wrap an entire tablespace in TDE
CREATE ENCRYPTED TABLESPACE classified
WITH (algorithm = 'AES-256-GCM', key_source = 'master_key');

CREATE TABLE classified.documents (
  id    SERIAL PRIMARY KEY,
  title TEXT,
  body  BYTEA      -- on-disk pages encrypted under FIPS-derived key
);
```

In FIPS mode the master key is derived via PBKDF2-HMAC-SHA256 (600 000 iterations by default — meets NIST SP 800-132 § 5.1) and the page-level cipher is AES-256-GCM from AWS-LC.

---

## 6. TLS / wire encryption

```bash
./target/release/heliosdb-nano start \
    --data-dir ./data \
    --tls-cert /etc/heliosdb/server.pem \
    --tls-key  /etc/heliosdb/server.key \
    --auth scram-sha-256 --password s3cret
```

The TLS handshake is performed by `rustls` backed by the AWS-LC FIPS provider — no separate OpenSSL FIPS module required.

---

## 7. Audit Trail

The audit log (see [AUDIT_LOGGING_TUTORIAL](https://www.heliosdb.com/docs/nano/guides/tutorials/audit_logging_tutorial/)) chains every event with SHA-256 checksums in FIPS mode (BLAKE3 in the default build). The chain hash is verifiable post-incident:

```sql
SELECT pg_audit_verify_chain();
-- t   (chain intact)
```

---

## Troubleshooting

| Symptom | Cause | Fix |
|---------|-------|-----|
| `error: feature 'fips' and 'ring-crypto' are mutually exclusive` | Forgot `--no-default-features` | Re-run with `--no-default-features --features "fips,encryption,vector-search,ha-tier1"` |
| Build fails with `aws-lc-sys` link error | Missing C toolchain | Install `gcc`/`clang` and `cmake` |
| `is_fips()` returns `false` at runtime | Default build, not FIPS build | Rebuild with the `fips` feature; verify via the startup banner |
| Self-test panic on first crypto op | A KAT failed (corrupted binary, mismatched AWS-LC version) | Reproduce on a clean checkout; report with `cargo --version` |
| Slower password hashing than expected | PBKDF2 with 600k iterations is the FIPS minimum | This is intentional — FIPS prefers iteration count over memory hardness |

---

## Where Next

- [ENCRYPTION_TUTORIAL](https://www.heliosdb.com/docs/nano/guides/tutorials/encryption_tutorial/) — full TDE walkthrough and an overview of zero-knowledge encryption.
- [AUDIT_LOGGING_TUTORIAL](https://www.heliosdb.com/docs/nano/guides/tutorials/audit_logging_tutorial/) — tamper-evident chain (SHA-256 in FIPS mode).
- [BACKUP_RESTORE_TUTORIAL](https://www.heliosdb.com/docs/nano/guides/tutorials/backup_restore_tutorial/) — dumps include FIPS-derived integrity checksums.
- [HIGH_AVAILABILITY](https://www.heliosdb.com/docs/nano/features/high-availability/) — running FIPS in HA topologies.
