-
Notifications
You must be signed in to change notification settings - Fork 771
Description
Feature Description
Some Linux distros like RHEL / Rocky Linux and Ubuntu can run in FIPS mode which will ensure that the system OpenSSL only provides/enables NIST approved algorithms.
On Linux, /proc/sys/crypto/fips_enabled is the standard Linux kernel interface to check, the behavior is:
- In FIPS mode, the value in the file
/proc/sys/crypto/fips_enabledwill be set to1. - If the kernel parameter was
fips=0then still the file would be created but with value0. - If no kernel parameter was given, the "file doesn't exist" = "not in FIPS mode"
NIST/FIPS algorithm approval vs module validation
These are genuinely different things:
- Algorithm approval (FIPS 186-5, SP 800-56A, etc.): "This cryptographic primitive is sound and approved for use."
- Module validation (FIPS 140-3 CMVP): "This specific compiled binary, on these specific platforms, has passed our audit for correct implementation, self-tests, key zeroization, entropy handling, etc."
Cybersecurity and Compliance posture
Definition: An organization's overall security standing and regulatory adherence, encompassing the policies, controls, technologies, and practices that collectively determine its ability to protect assets, detect threats, respond to incidents, and demonstrate compliance with applicable standards and regulations.
A strong posture answers these questions clearly:
- What cryptographic algorithms does our software use, and which are NIST-approved?
- What happens when a user configures a non-compliant feature?
- Can we demonstrate compliance to an auditor with documentation and logs?
- How do we detect and respond to a compromise?
A user might have a compliance posture which requires to only use NIST/FIPS approved ciphers and cryptographic primitives.
WAMP cryptographic primitives
Autobahn|Python and Crossbar.io support all advanced cryptographic features of WAMP.
The NIST/FIPS approval status of the cryptographic primitives ("algorithms") used for these features is as follows:
| Category | Algorithm | Usage in WAMP | NIST/FIPS Compatible |
|---|---|---|---|
| Elliptic Curves | |||
| secp256r1 (P-256) | Transport Encryption | ✅ Yes (SP 800-186) | |
| curve25519 | Session Authentication (WAMP-Cryptosign) | ✅ Yes (SP 800-186) | |
| secp256k1 | Data Signatures (Certificates, E2E) | ❌ No | |
| Hash Functions | |||
| SHA-256 | Session Authentication (WAMP-Cryptosign) | ✅ Yes (FIPS 180-4) | |
| Keccak-256 | Data Signatures (Certificates, E2E) | ❌ No (differs from SHA3-256) | |
| Signature Schemes | |||
| Ed25519 | Session Authentication (WAMP-Cryptosign) | ✅ Yes (FIPS 186-5) | |
| ECDSA | Data Signatures (Ethereum, Certificates, E2E) |
Notes on ECDSA:
- ECDSA + secp256r1 (P-256): ✅ FIPS compatible
- ECDSA + secp256k1: ❌ Not FIPS compatible (Ethereum uses this)
For background references and intro reading, here are some good ones:
Run-time detection
To detect NIST/FIPS mode on Linux, here is a Python code draft:
import os
from pathlib import Path
from typing import NamedTuple
class FIPSStatus(NamedTuple):
"""System FIPS mode status."""
enabled: bool
kernel_fips: bool | None # None if file doesn't exist
openssl_fips: bool | None # None if we can't determine
def get_kernel_fips_mode() -> bool | None:
"""
Check Linux kernel FIPS mode via /proc/sys/crypto/fips_enabled.
Returns:
True: FIPS mode enabled (file contains "1")
False: FIPS mode disabled (file contains "0")
None: Cannot determine (file doesn't exist, not Linux, etc.)
"""
fips_path = Path("/proc/sys/crypto/fips_enabled")
try:
content = fips_path.read_text().strip()
return content == "1"
except FileNotFoundError:
# Kernel not booted with fips= parameter
return None
except (OSError, PermissionError):
# Some other issue reading the file
return None
def get_openssl_fips_mode() -> bool | None:
"""
Check if OpenSSL is operating in FIPS mode.
Returns:
True: OpenSSL FIPS provider is active
False: OpenSSL not in FIPS mode
None: Cannot determine (OpenSSL not available, etc.)
"""
try:
# Python 3.9+ with OpenSSL 3.x
import ssl
# This is a bit of a hack - check if MD5 is available
# In FIPS mode, MD5 should fail
import hashlib
try:
# usedforsecurity=True is the default and will fail in FIPS mode
hashlib.md5(b"test", usedforsecurity=True)
return False # MD5 worked, not in FIPS mode
except ValueError:
return True # MD5 rejected, likely FIPS mode
except Exception:
return None
def get_fips_status() -> FIPSStatus:
"""
Get comprehensive FIPS mode status.
Returns a FIPSStatus with:
- enabled: True if system appears to be in FIPS mode
- kernel_fips: Kernel FIPS flag status
- openssl_fips: OpenSSL FIPS mode status
"""
kernel = get_kernel_fips_mode()
openssl = get_openssl_fips_mode()
# Consider FIPS enabled if kernel says so
# (OpenSSL check is supplementary)
enabled = kernel is True
return FIPSStatus(
enabled=enabled,
kernel_fips=kernel,
openssl_fips=openssl,
)
def os_fips_enabled() -> bool:
"""Simple check: is the OS in FIPS mode?"""
return get_fips_status().enabledRun-time enforcement
We should add an environment variable to Autobahn:
# defaults to unrestricted
AUTOBAHN_CRYPTO_POLICY=nist-algorithms | unrestrictedand a CLI option to Crossbar.io:
--crypto-policy=nist-algorithms
--crypto-policy=unrestricted # defaultwhich makes it actively fail rather than just log or even silently run and thus break the user's compliance posture.
=> Fail-fast is better than fail-audit!
What it should do
At startup, when this flag is set:
- Reject configurations that enable:
secp256k1andkeccak-256(Ethereum integration) - Log clearly:
[WARN] NIST-algorithms crypto policy active. The following features are disabled:
- Ethereum integration (requires secp256k1, keccak-256)
- [any others non-NIST algorithms for cryptographic use]
- Fail hard if a config file specifies disabled features:
[ERROR] Configuration error: Ethereum integration requires secp256k1 which is
not permitted under AUTOBAHN_CRYPTO_POLICY=nist-algorithms / --crypto-policy=nist-algorithms. Remove this flag or remove the Ethereum integration configuration.
WAMP Application Error URIs
We will also need to define a WAMP application error URI - as a WAMP client with Ethereum integration enabled might try to talk to a WAMP router without Ethereum integration enabled due to --crypto-policy=nist-algorithms!
Documentation framing
Be precise in our docs:
NIST-Algorithms Mode (AUTOBAHN_CRYPTO_POLICY=nist-algorithms / --crypto-policy=nist-algorithms)
When enabled, Autobahn|Python / Crossbar.io restricts cryptographic operations to algorithms
approved by NIST (FIPS 186-5, SP 800-56A, etc.).
This is a necessary but not sufficient condition for FIPS 140-3 compliance—full compliance also
requires using a FIPS-validated cryptographic module at the OS level.
This mode disables Ethereum integration, see https://wamp-proto.org/spec.html: Data Signatures (Ethereum, WAMP-Cryptosign Certificates, WAMP-E2E encryption).
Crypto Policy Summary
Summary for crypto policy:
| Feature | NIST-algorithms Mode |
|---|---|
| TLS transport (secp256r1) | ✅ Allowed |
| WAMP-Cryptosign auth (Ed25519/curve25519/SHA-256) | ✅ Allowed |
| WAMP-Cryptosign certificates with secp256k1 | ❌ Blocked |
| WAMP E2E encryption (secp256k1/keccak256) | ❌ Blocked |
| Ethereum integration | ❌ Blocked |
So core WAMP-Cryptosign authentication is actually NIST-algorithms compatible.
It's specifically the Ethereum-interop features (certificates with secp256k1 signatures, E2E using keccak256) that break compliance.
In Crossbar.io during startup, here is some draft code:
def check_fips_compatibility(config: Config) -> None:
"""Check FIPS mode compatibility at startup."""
fips = get_fips_status()
uses_non_nist = config.has_ethereum_bridge() or config.has_bitcoin_integration()
if fips.enabled and uses_non_nist and not config.nist_only:
log.warn(
"System is in FIPS mode (kernel={kernel}, openssl={openssl}) "
"but configuration uses non-NIST algorithms (Ethereum/secp256k1). "
"Cryptographic operations may fail at runtime. "
"Consider using --nist-only to catch this at startup.",
kernel=fips.kernel_fips,
openssl=fips.openssl_fips,
)
if config.nist_only and uses_non_nist:
raise ConfigurationError(
"Configuration error: Ethereum integration requires secp256k1 "
"which is not permitted under --nist-only mode. "
"Remove --nist-only or disable Ethereum features."
)Checklist
- I have searched existing issues to avoid duplicates
- I have described the problem clearly
- I have provided use cases
- I have considered alternatives
- I have assessed impact and breaking changes