golang/go · error

crypto/rsa: multi-prime RSA is not allowed in FIPS 140-only

Error message

crypto/rsa: multi-prime RSA is not allowed in FIPS 140-only mode

What it means

Returned by GenerateMultiPrimeKey when FIPS 140-only mode is active and nprimes != 2. Multi-prime RSA (more than two primes) is not in the FIPS 140-3 approved algorithm set, and even the nprimes==2 case is redirected to GenerateKey at the top of the function, so any call that actually reaches the multi-prime code path is rejected. The function is also Deprecated for general use.

Source

Thrown at src/crypto/rsa/rsa.go:440

//
// This package does not implement CRT optimizations for multi-prime RSA, so the
// keys with more than two primes will have worse performance.
//
// Since Go 1.26, a secure source of random bytes is always used, and the Reader is
// ignored unless GODEBUG=cryptocustomrand=1 is set. This setting will be removed
// in a future Go release. Instead, use [testing/cryptotest.SetGlobalRandom].
//
// Deprecated: The use of this function with a number of primes different from
// two is not recommended for the above security, compatibility, and performance
// reasons. Use [GenerateKey] instead.
//
// [On the Security of Multi-prime RSA]: http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf
func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey, error) {
	if nprimes == 2 {
		return GenerateKey(random, bits)
	}
	if fips140only.Enforced() {
		return nil, errors.New("crypto/rsa: multi-prime RSA is not allowed in FIPS 140-only mode")
	}

	random = rand.CustomReader(random)

	priv := new(PrivateKey)
	priv.E = 65537

	if nprimes < 2 {
		return nil, errors.New("crypto/rsa: GenerateMultiPrimeKey: nprimes must be >= 2")
	}

	if bits < 64 {
		primeLimit := float64(uint64(1) << uint(bits/nprimes))
		// pi approximates the number of primes less than primeLimit
		pi := primeLimit / (math.Log(primeLimit) - 1)
		// Generated primes start with 11 (in binary) so we can only
		// use a quarter of them.
		pi /= 4

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Replace with rsa.GenerateKey(rand.Reader, bits) (which is 2-prime and FIPS-eligible).
  2. If multi-prime RSA is mandated by a peer, you cannot comply with FIPS-only — escalate the protocol choice.
  3. Stop using GenerateMultiPrimeKey entirely; it is Deprecated.

Example fix

// before (under GODEBUG=fips140=only)
priv, err := rsa.GenerateMultiPrimeKey(rand.Reader, 3, 2048) // err: multi-prime RSA is not allowed

// after
priv, err := rsa.GenerateKey(rand.Reader, 2048)
Defensive patterns

Strategy: fallback

Validate before calling

// Always prefer GenerateKey; multi-prime is deprecated and FIPS-incompatible.
func generate(bits int) (*rsa.PrivateKey, error) {
    return rsa.GenerateKey(rand.Reader, bits)
}

Prevention

When it happens

Trigger: Call rsa.GenerateMultiPrimeKey(rand.Reader, 3, 2048) under GODEBUG=fips140=only; legacy library (e.g. some BouncyCastle interop) that requests 3- or 4-prime keys.

Common situations: Migrating an existing multi-prime-RSA workload into a FIPS-only Go service; test fixtures originally designed to exercise multi-prime paths.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/9dceefb9a8d07f7a. Report an issue: GitHub.