golang/go · error
crypto/mlkem/mlkemtest: use of derandomized encapsulation is
Error message
crypto/mlkem/mlkemtest: use of derandomized encapsulation is not allowed in FIPS 140-only mode
What it means
Returned by mlkemtest.Encapsulate768 when fips140only.Enforced() is true. Derandomized (fixed-randomness) encapsulation is a test-only operation that violates FIPS 140's approved-mode requirements because it bypasses the approved RNG; therefore the Go crypto module blocks it whenever the binary is built in FIPS 140-only mode. The same message appears in Encapsulate1024.
Source
Thrown at src/crypto/mlkem/mlkemtest/mlkemtest.go:25
import (
fips140mlkem "crypto/internal/fips140/mlkem"
"crypto/internal/fips140only"
"crypto/mlkem"
"errors"
)
// Encapsulate768 implements derandomized ML-KEM-768 encapsulation
// (ML-KEM.Encaps_internal from FIPS 203) using the provided encapsulation key
// ek and 32 bytes of randomness.
//
// It must only be used for known-answer tests.
func Encapsulate768(ek *mlkem.EncapsulationKey768, random []byte) (sharedKey, ciphertext []byte, err error) {
if len(random) != 32 {
return nil, nil, errors.New("mlkemtest: Encapsulate768: random must be 32 bytes")
}
if fips140only.Enforced() {
return nil, nil, errors.New("crypto/mlkem/mlkemtest: use of derandomized encapsulation is not allowed in FIPS 140-only mode")
}
k, err := fips140mlkem.NewEncapsulationKey768(ek.Bytes())
if err != nil {
return nil, nil, errors.New("mlkemtest: Encapsulate768: failed to reconstruct key: " + err.Error())
}
sharedKey, ciphertext = k.EncapsulateInternal((*[32]byte)(random))
return sharedKey, ciphertext, nil
}
// Encapsulate1024 implements derandomized ML-KEM-1024 encapsulation
// (ML-KEM.Encaps_internal from FIPS 203) using the provided encapsulation key
// ek and 32 bytes of randomness.
//
// It must only be used for known-answer tests.
func Encapsulate1024(ek *mlkem.EncapsulationKey1024, random []byte) (sharedKey, ciphertext []byte, err error) {
if len(random) != 32 {
return nil, nil, errors.New("mlkemtest: Encapsulate1024: random must be 32 bytes")
}View on GitHub (pinned to b6b368adc5)
Solutions
- Do not call mlkemtest functions in FIPS-only builds; gate them behind a non-FIPS build tag or test-only import.
- Use the standard mlkem.EncapsulationKey768.Encapsulate() which uses the approved RNG and is allowed in FIPS mode.
- If you need KATs, run them in a separate non-FIPS test binary.
Example fix
// before (in FIPS-only build) shared, ct, err := mlkemtest.Encapsulate768(ek, z) // blocked // after shared, ct, err := ek.Encapsulate() // approved RNG path
Defensive patterns
Strategy: validation
Validate before calling
if fips140only.Enforced() {
return ek.Encapsulate() // approved path
}
return mlkemtest.Encapsulate768(ek, random) Type guard
func isFipsOnly() bool { return fips140only.Enforced() } Try / catch
shared, ct, err := mlkemtest.Encapsulate768(ek, random)
if err != nil && strings.Contains(err.Error(), "FIPS 140-only mode") {
shared, ct, err = ek.Encapsulate()
}
return shared, ct, err Prevention
- Confine mlkemtest imports to test-only build tags.
- Detect FIPS-only mode at startup and route to approved APIs.
- Audit production binaries for mlkemtest linkage.
When it happens
Trigger: Building with GOEXPERIMENT=boringcrypto / FIPS-only settings (so fips140only.Enforced() returns true) and calling mlkemtest.Encapsulate768. Running KAT tests inside a FIPS-enforced binary.
Common situations: Shipping a FIPS-validated build and accidentally including KAT helper calls. CI that runs the full test matrix under FIPS mode. Importing mlkemtest in non-test code that must be FIPS-compliant.
Related errors
- mlkemtest: Encapsulate768: random must be 32 bytes
- mlkemtest: Encapsulate768: failed to reconstruct key:
- mlkemtest: Encapsulate1024: random must be 32 bytes
- mlkemtest: Encapsulate1024: failed to reconstruct key:
- crypto/pbkdf2: use of keys shorter than 112 bits is not allo
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/acbbf6c3b09735f7.
Report an issue: GitHub.