FIPS Mode

sgcCrypto has an optional compile time switch, SGC_CRYPTO_FIPS, that leaves only FIPS-approved algorithms in the library. It is meant for projects that must not use algorithms outside the FIPS and NIST SP publications. This page explains what the switch does, how to turn it on, what it keeps, what it removes, and what it does not cover.

What FIPS means here

FIPS 140-3 is a certification of a cryptographic module, not of an algorithm. An accredited laboratory tests one specific build of a product under NIST's Cryptographic Module Validation Program (CMVP), and NIST publishes a certificate for that build. Using an approved algorithm such as AES does not make a program validated.

sgcCrypto is not a FIPS 140-3 validated module, and turning on the switch is not a validation claim. What the switch does is narrower:

The algorithms that stay follow the FIPS and NIST SP publications listed in the table below.

If your project has a formal FIPS 140-3 requirement, its cryptography must go through a validated module, for example Windows CNG with the system running in FIPS mode. The switch helps keep algorithms that are not approved out of your code. It does not replace a validated module.

Turning it on

The switch is off by default. Without it nothing changes, and every algorithm listed on the Cryptography page is available. To turn it on, do one of the following:


  {.$DEFINE SGC_CRYPTO_FIPS}   { off, the default }
  {$DEFINE SGC_CRYPTO_FIPS}    { on }

Then rebuild. The switch only affects code compiled with the define, so precompiled packages that were built without it are not affected.

With the switch on, the removed functions no longer exist. Code that still calls one of them fails to compile with an "Undeclared identifier" error. This is intentional: nothing that is not approved can end up in the binary by accident, and the compiler points at every place that needs a different algorithm.

What stays

Certificates, one time passwords and the encoding helpers stay as well, because they are built only from the approved algorithms or are not cryptographic algorithms at all.

Family Kept Standard
AES AES-128/192/256 in ECB, CBC, CFB, OFB, CTR, CTS, GCM and CCM mode, AES Key Wrap (KW and KWP), AES-CMAC and AES-GMAC FIPS 197, SP 800-38A/B/C/D/F
Hashing SHA-1 (only where still allowed, never for new signatures), SHA-224, SHA-256, SHA-384, SHA-512, SHA3-224/256/384/512, SHAKE128, SHAKE256, cSHAKE and KMAC FIPS 180-4, FIPS 202, SP 800-185
Message authentication HMAC-SHA1, HMAC-SHA256, HMAC-SHA384 and HMAC-SHA512 FIPS 198-1
Key derivation PBKDF2, HKDF and the ANSI X9.63 KDF SP 800-132 (PBKDF2), SP 800-56C (HKDF), SP 800-135 (ANSI X9.63 KDF)
RSA RSA key generation, PKCS#1 v1.5 and PSS signatures, RSA-OAEP encryption FIPS 186-5, SP 800-56B
ECDSA and ECDH Signatures and key agreement on NIST P-256, P-384 and P-521 (P-224 is not implemented by sgcCrypto) FIPS 186-5, SP 800-56A
EdDSA Ed25519 and Ed448 signatures FIPS 186-5
Post-quantum cryptography ML-KEM, ML-DSA and SLH-DSA FIPS 203, FIPS 204, FIPS 205
Certificates & PKI X.509 certificate parsing, chain verification and CRL checks, and certificate or CSR generation signed with the algorithms above RFC 5280, RFC 2986
One time passwords HOTP and TOTP, built on HMAC RFC 4226, RFC 6238
Encoding & utilities Hex, Base32 and Base64 encoding, constant time compare, secure zero RFC 4648

What is removed

Removed Why
ChaCha20, XChaCha20, Salsa20, XSalsa20, Poly1305, ChaCha20-Poly1305 and XChaCha20-Poly1305 Not NIST algorithms.
X25519 and X448 key exchange Not approved for key agreement in SP 800-56A.
The X25519 + ML-KEM-768 hybrid, and ECIES Both are built on X25519.
secp256k1 and the Brainpool curves, and BIP-340 Schnorr signatures Not NIST recommended curves, and BIP-340 is not a FIPS 186-5 signature scheme. FIPS mode keeps only the NIST P curves.
Argon2 and scrypt Not NIST password key derivation functions.
BLAKE2b, BLAKE2s, SipHash and TLSH Not NIST algorithms.
MD4, MD5, HMAC-MD5, RIPEMD-160 and DES (the sgcCrypto_Legacy unit) Obsolete, or never approved by NIST.
KDF1 and KDF2 Defined in ISO 18033-2, not in a NIST publication. The ANSI X9.63 KDF stays.
RSA PKCS#1 v1.5 encryption Disallowed by SP 800-131A. PKCS#1 v1.5 signatures stay.
WinZip AES (AE-1 and AE-2) Not a NIST format.

For most removed algorithms an approved replacement is in the first table: AES-GCM instead of ChaCha20-Poly1305, ECDH on P-256 or P-384 instead of X25519, PBKDF2 instead of Argon2 or scrypt, SHA-256 or SHA-3 instead of BLAKE2, and RSA-OAEP instead of PKCS#1 v1.5 encryption.

Rules checked at run time

Some rules depend on the values passed to a function, so the compiler cannot enforce them. With the switch on, sgcCrypto checks them when the function runs, and each one raises an exception whose message starts with sgcCrypto FIPS:

Where the random bytes come from

Keys, nonces and salts need random bytes. sgcRandomBytes always reads them from the operating system, in both modes, and never runs a generator of its own on top. The switch only changes which system source is used:

Platform With SGC_CRYPTO_FIPS Without SGC_CRYPTO_FIPS
Windows BCryptGenRandom (CNG, system preferred RNG), with no fallback BCryptGenRandom, falling back to RtlGenRandom and then CryptGenRandom when BCryptGenRandom is not available
Linux and Android The getrandom system call /dev/urandom
macOS and iOS SecRandomCopyBytes from the Security framework /dev/urandom

In both modes, if no source can be read, an exception is raised instead of returning weak bytes. Whether the operating system generator counts as FIPS depends on the operating system and its configuration, not on sgcCrypto.

What the switch does not cover

The switch applies to the sgcCrypto units only. Other parts of sgcWebSockets can still use algorithms that are not approved:

If the whole application must stay within approved algorithms, review these areas as well.

See also