{"record":{"id":"acbbf6c3b09735f7","repo":"golang/go","slug":"crypto-mlkem-mlkemtest-use-of-derandomized-encaps","errorCode":null,"errorMessage":"crypto/mlkem/mlkemtest: use of derandomized encapsulation is not allowed in FIPS 140-only mode","messagePattern":"crypto/mlkem/mlkemtest: use of derandomized encapsulation is not allowed in FIPS 140-only mode","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/mlkem/mlkemtest/mlkemtest.go","lineNumber":25,"sourceCode":"\nimport (\n\tfips140mlkem \"crypto/internal/fips140/mlkem\"\n\t\"crypto/internal/fips140only\"\n\t\"crypto/mlkem\"\n\t\"errors\"\n)\n\n// Encapsulate768 implements derandomized ML-KEM-768 encapsulation\n// (ML-KEM.Encaps_internal from FIPS 203) using the provided encapsulation key\n// ek and 32 bytes of randomness.\n//\n// It must only be used for known-answer tests.\nfunc Encapsulate768(ek *mlkem.EncapsulationKey768, random []byte) (sharedKey, ciphertext []byte, err error) {\n\tif len(random) != 32 {\n\t\treturn nil, nil, errors.New(\"mlkemtest: Encapsulate768: random must be 32 bytes\")\n\t}\n\tif fips140only.Enforced() {\n\t\treturn nil, nil, errors.New(\"crypto/mlkem/mlkemtest: use of derandomized encapsulation is not allowed in FIPS 140-only mode\")\n\t}\n\tk, err := fips140mlkem.NewEncapsulationKey768(ek.Bytes())\n\tif err != nil {\n\t\treturn nil, nil, errors.New(\"mlkemtest: Encapsulate768: failed to reconstruct key: \" + err.Error())\n\t}\n\tsharedKey, ciphertext = k.EncapsulateInternal((*[32]byte)(random))\n\treturn sharedKey, ciphertext, nil\n}\n\n// Encapsulate1024 implements derandomized ML-KEM-1024 encapsulation\n// (ML-KEM.Encaps_internal from FIPS 203) using the provided encapsulation key\n// ek and 32 bytes of randomness.\n//\n// It must only be used for known-answer tests.\nfunc Encapsulate1024(ek *mlkem.EncapsulationKey1024, random []byte) (sharedKey, ciphertext []byte, err error) {\n\tif len(random) != 32 {\n\t\treturn nil, nil, errors.New(\"mlkemtest: Encapsulate1024: random must be 32 bytes\")\n\t}","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/mlkem/mlkemtest/mlkemtest.go#L7-L43","documentation":"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.","triggerScenarios":"Building with GOEXPERIMENT=boringcrypto / FIPS-only settings (so fips140only.Enforced() returns true) and calling mlkemtest.Encapsulate768. Running KAT tests inside a FIPS-enforced binary.","commonSituations":"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.","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."],"exampleFix":"// before (in FIPS-only build)\nshared, ct, err := mlkemtest.Encapsulate768(ek, z) // blocked\n\n// after\nshared, ct, err := ek.Encapsulate() // approved RNG path","handlingStrategy":"validation","validationCode":"if fips140only.Enforced() {\n    return ek.Encapsulate() // approved path\n}\nreturn mlkemtest.Encapsulate768(ek, random)","typeGuard":"func isFipsOnly() bool { return fips140only.Enforced() }","tryCatchPattern":"shared, ct, err := mlkemtest.Encapsulate768(ek, random)\nif err != nil && strings.Contains(err.Error(), \"FIPS 140-only mode\") {\n    shared, ct, err = ek.Encapsulate()\n}\nreturn shared, ct, err","preventionTips":["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."],"tags":["cryptography","go","post-quantum","mlkem","fips140","compliance","test-utility"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}