{"record":{"id":"596045adf3f8eb71","repo":"golang/go","slug":"crypto-ecdsa-only-crypto-rand-reader-is-allowed-i","errorCode":null,"errorMessage":"crypto/ecdsa: only crypto/rand.Reader is allowed in FIPS 140-only mode","messagePattern":"crypto/ecdsa: only crypto/rand\\.Reader is allowed in FIPS 140-only mode","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/ecdsa/ecdsa.go","lineNumber":373,"sourceCode":"\tr = rand.CustomReader(r)\n\n\tswitch c.Params() {\n\tcase elliptic.P224().Params():\n\t\treturn generateFIPS(c, ecdsa.P224(), r)\n\tcase elliptic.P256().Params():\n\t\treturn generateFIPS(c, ecdsa.P256(), r)\n\tcase elliptic.P384().Params():\n\t\treturn generateFIPS(c, ecdsa.P384(), r)\n\tcase elliptic.P521().Params():\n\t\treturn generateFIPS(c, ecdsa.P521(), r)\n\tdefault:\n\t\treturn generateLegacy(c, r)\n\t}\n}\n\nfunc generateFIPS[P ecdsa.Point[P]](curve elliptic.Curve, c *ecdsa.Curve[P], rand io.Reader) (*PrivateKey, error) {\n\tif fips140only.Enforced() && !fips140only.ApprovedRandomReader(rand) {\n\t\treturn nil, errors.New(\"crypto/ecdsa: only crypto/rand.Reader is allowed in FIPS 140-only mode\")\n\t}\n\tprivateKey, err := ecdsa.GenerateKey(c, rand)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn privateKeyFromFIPS(curve, privateKey)\n}\n\n// SignASN1 signs a hash (which should be the result of hashing a larger message)\n// using the private key, priv. If the hash is longer than the bit-length of the\n// private key's curve order, the hash will be truncated to that length. It\n// returns the ASN.1 encoded signature.\n//\n// The signature is randomized. Since Go 1.26, a secure source of random bytes\n// is always used, and the Reader is ignored unless GODEBUG=cryptocustomrand=1\n// is set. This setting will be removed in a future Go release. Instead, use\n// [testing/cryptotest.SetGlobalRandom].\nfunc SignASN1(r io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) {","sourceCodeStart":355,"sourceCodeEnd":391,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/ecdsa/ecdsa.go#L355-L391","documentation":"Thrown by generateFIPS during key generation when FIPS 140-only mode is enforced (GOEXPERIMENT or system FIPS policy) and the provided random reader is not crypto/rand.Reader. FIPS 140 requires that all randomness for key generation come from an approved CSPRNG, which in Go is exclusively crypto/rand.Reader.","triggerScenarios":"Calling ecdsa.GenerateKey with a custom io.Reader for randomness while the process is running in FIPS 140-only mode (fips140only.Enforced() == true). The fips140only.ApprovedRandomReader check rejects any reader that isn't crypto/rand.Reader.","commonSituations":"Deploying in a FIPS-compliant environment (e.g., US government or regulated industries) with code that passes a custom or mock random reader; testing code that injects deterministic randomness; upgrading a system to FIPS mode where existing code used non-standard readers.","solutions":["Pass nil or crypto/rand.Reader as the random source when FIPS mode is active — the library always uses a secure source internally regardless.","Since Go 1.26, the Reader parameter is ignored unless GODEBUG=cryptocustomrand=1 is set, so simply pass crypto/rand.Reader and the FIPS check passes.","For testing, use testing/cryptotest.SetGlobalRandom instead of a custom reader to avoid FIPS violations."],"exampleFix":"// before\npriv, err := ecdsa.GenerateKey(curve, customReader) // fails in FIPS mode\n\n// after\npriv, err := ecdsa.GenerateKey(curve, rand.Reader) // or nil, both pass FIPS check","handlingStrategy":"validation","validationCode":"func isFIPSEnforced() bool {\n    return fips140only.Enforced() // or check GOEXPERIMENT/system FIPS flag\n}\n// before GenerateKey: use crypto/rand.Reader if FIPS is active","typeGuard":null,"tryCatchPattern":"priv, err := ecdsa.GenerateKey(curve, r)\nif err != nil && strings.Contains(err.Error(), \"FIPS\") {\n    // retry with rand.Reader, or notify user of FIPS requirement\n    priv, err = ecdsa.GenerateKey(curve, cryptoRand.Reader)\n}","preventionTips":["Always pass crypto/rand.Reader (or nil) to GenerateKey — custom readers are ignored since Go 1.26 anyway.","Use testing/cryptotest.SetGlobalRandom for test randomness injection in FIPS environments."],"tags":["crypto","ecdsa","fips","key-generation","compliance","random"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}