{"record":{"id":"7eed8a5797f26e1d","repo":"golang/go","slug":"crypto-rsa-use-of-keys-with-odd-size-is-not-allow-7eed8a","errorCode":null,"errorMessage":"crypto/rsa: use of keys with odd size is not allowed in FIPS 140-only mode","messagePattern":"crypto/rsa: use of keys with odd size is not allowed in FIPS 140-only mode","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/rsa/rsa.go","lineNumber":365,"sourceCode":"\t\t\tD:      D,\n\t\t\tPrimes: []*big.Int{P, Q},\n\t\t\tPrecomputed: PrecomputedValues{\n\t\t\t\tDp:        Dp,\n\t\t\t\tDq:        Dq,\n\t\t\t\tQinv:      Qinv,\n\t\t\t\tCRTValues: make([]CRTValue, 0), // non-nil, to match Precompute\n\t\t\t},\n\t\t}\n\t\treturn key, nil\n\t}\n\n\trandom = rand.CustomReader(random)\n\n\tif fips140only.Enforced() && bits < 2048 {\n\t\treturn nil, errors.New(\"crypto/rsa: use of keys smaller than 2048 bits is not allowed in FIPS 140-only mode\")\n\t}\n\tif fips140only.Enforced() && bits%2 == 1 {\n\t\treturn nil, errors.New(\"crypto/rsa: use of keys with odd size is not allowed in FIPS 140-only mode\")\n\t}\n\tif fips140only.Enforced() && !fips140only.ApprovedRandomReader(random) {\n\t\treturn nil, errors.New(\"crypto/rsa: only crypto/rand.Reader is allowed in FIPS 140-only mode\")\n\t}\n\n\tk, err := rsa.GenerateKey(random, bits)\n\tif bits < 256 && err != nil {\n\t\t// Toy-sized keys have a non-negligible chance of hitting two hard\n\t\t// failure cases: p == q and d <= 2^(nlen / 2).\n\t\t//\n\t\t// Since these are impossible to hit for real keys, we don't want to\n\t\t// make the production code path more complex and harder to think about\n\t\t// to handle them.\n\t\t//\n\t\t// Instead, just rerun the whole process a total of 8 times, which\n\t\t// brings the chance of failure for 32-bit keys down to the same as for\n\t\t// 256-bit keys.\n\t\tfor i := 1; i < 8 && err != nil; i++ {","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/rsa/rsa.go#L347-L383","documentation":"Returned by GenerateKey when FIPS 140-only mode is active and bits is odd (bits%2 == 1). The standard mandates that the two primes each have equal bit length, which requires an even modulus bit length; an odd bits value cannot be split symmetrically, so FIPS-only mode rejects it. This check sits immediately after the 2048-bit floor and applies only when fips140only.Enforced() is true.","triggerScenarios":"Call rsa.GenerateKey(rand.Reader, 2049) or 3000 under GODEBUG=fips140=only; compute bits dynamically from a configuration value that is off-by-one.","commonSituations":"Off-by-one in a configuration field (e.g. policy that says 2048 ± 1); user-supplied key size from a CLI flag without validation.","solutions":["Round down to the nearest even size that is also ≥2048 (2048, 3072, 4096).","Validate the configured size before calling GenerateKey: if bits%2 != 0 { return err }.","Prefer the standard sizes (2048/3072/4096) so the BoringCrypto fast path also applies."],"exampleFix":"// before (under GODEBUG=fips140=only)\npriv, err := rsa.GenerateKey(rand.Reader, 2049) // err: odd size\n\n// after\nif bits%2 != 0 { bits-- }\npriv, err := rsa.GenerateKey(rand.Reader, bits)","handlingStrategy":"validation","validationCode":"if bits%2 != 0 {\n    return errors.New(\"RSA key size must be even\")\n}\nreturn rsa.GenerateKey(rand.Reader, bits)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Bound user-supplied sizes to a fixed allowlist: {2048, 3072, 4096}.","Add a parity check wherever key size is configured.","Document the even-size requirement in CLI --help text."],"tags":["fips","rsa","key-generation","fips140-only","validation","crypto"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}