{"record":{"id":"1f74777ee0535c9d","repo":"golang/go","slug":"crypto-rsa-use-of-multi-prime-keys-is-not-allowed","errorCode":null,"errorMessage":"crypto/rsa: use of multi-prime keys is not allowed in FIPS 140-only mode","messagePattern":"crypto/rsa: use of multi-prime keys is not allowed in FIPS 140-only mode","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/rsa/fips.go","lineNumber":466,"sourceCode":"\t}\n\tif pub.E <= 1<<16 {\n\t\treturn errors.New(\"crypto/rsa: use of public exponent <= 2¹⁶ is not allowed in FIPS 140-only mode\")\n\t}\n\tif pub.E&1 == 0 {\n\t\treturn errors.New(\"crypto/rsa: use of even public exponent is not allowed in FIPS 140-only mode\")\n\t}\n\treturn nil\n}\n\nfunc checkFIPS140OnlyPrivateKey(priv *PrivateKey) error {\n\tif !fips140only.Enforced() {\n\t\treturn nil\n\t}\n\tif err := checkFIPS140OnlyPublicKey(&priv.PublicKey); err != nil {\n\t\treturn err\n\t}\n\tif len(priv.Primes) != 2 {\n\t\treturn errors.New(\"crypto/rsa: use of multi-prime keys is not allowed in FIPS 140-only mode\")\n\t}\n\tif priv.Primes[0] == nil || priv.Primes[1] == nil || priv.Primes[0].BitLen() != priv.Primes[1].BitLen() {\n\t\treturn errors.New(\"crypto/rsa: use of primes of different sizes is not allowed in FIPS 140-only mode\")\n\t}\n\treturn nil\n}\n","sourceCodeStart":448,"sourceCodeEnd":473,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/rsa/fips.go#L448-L473","documentation":"Thrown by checkFIPS140OnlyPrivateKey when fips140only.Enforced() and len(priv.Primes) != 2. Standard RSA uses exactly two primes; multi-prime RSA (3+ primes) is faster but explicitly disallowed by FIPS 140-only mode. This also catches the degenerate case of fewer than 2 primes (malformed key). The check runs after the public-key checks pass.","triggerScenarios":"Using a private key generated with rsa.GenerateMultiPrimeKey (3+ primes) in a FIPS-only build. Loading a key parsed from a multi-prime PKCS#1 structure. A malformed key with 0 or 1 primes.","commonSituations":"Performance-optimized multi-prime keys (common in some Java/old systems) migrated to a Go FIPS-only service. Test keys generated with GenerateMultiPrimeKey for speed.","solutions":["Regenerate the key with rsa.GenerateKey(rand.Reader, 2048) which produces exactly 2 primes.","Validate at load: if len(priv.Primes) != 2 { reject }.","Avoid rsa.GenerateMultiPrimeKey entirely in FIPS-compliant code paths."],"exampleFix":"// before\npriv, _ := rsa.GenerateMultiPrimeKey(rand.Reader, 3, 2048)\nsig, err := rsa.SignPSS(rand.Reader, priv, crypto.SHA256, digest, opts)\n\n// after\npriv, _ := rsa.GenerateKey(rand.Reader, 2048)\nsig, err := rsa.SignPSS(rand.Reader, priv, crypto.SHA256, digest, opts)","handlingStrategy":"validation","validationCode":"if len(priv.Primes) != 2 {\n    return fmt.Errorf(\"private key has %d primes; FIPS-only mode requires exactly 2\", len(priv.Primes))\n}\n// proceed","typeGuard":"func isTwoPrimeKey(priv *rsa.PrivateKey) bool {\n    return priv != nil && len(priv.Primes) == 2\n}","tryCatchPattern":null,"preventionTips":["Never use rsa.GenerateMultiPrimeKey in FIPS-compliant code — always rsa.GenerateKey.","Reject keys with != 2 primes at the load/parse layer.","Audit imported keys (e.g. from PKCS#1 multi-prime format) for prime count."],"tags":["crypto","rsa","fips","key-validation","multi-prime"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}