golang/go · error

crypto/rsa: use of keys with odd size is not allowed in FIPS

Error message

crypto/rsa: use of keys with odd size is not allowed in FIPS 140-only mode

What it means

Thrown by checkFIPS140OnlyPublicKey when fips140only.Enforced() and pub.N.BitLen() is odd. An RSA modulus is the product of two primes; FIPS requires the two primes to be of equal bit length, which yields an even modulus bit length. An odd bit length implies primes of unequal size (e.g. a 1025-bit modulus), which is non-compliant and a sign of a malformed or non-standard key.

Source

Thrown at src/crypto/rsa/fips.go:447

	return err
}

func fipsError2[T any](x T, err error) (T, error) {
	return x, fipsError(err)
}

func checkFIPS140OnlyPublicKey(pub *PublicKey) error {
	if !fips140only.Enforced() {
		return nil
	}
	if pub.N == nil {
		return errors.New("crypto/rsa: public key missing N")
	}
	if pub.N.BitLen() < 2048 {
		return errors.New("crypto/rsa: use of keys smaller than 2048 bits is not allowed in FIPS 140-only mode")
	}
	if pub.N.BitLen()%2 == 1 {
		return errors.New("crypto/rsa: use of keys with odd size is not allowed in FIPS 140-only mode")
	}
	if pub.E <= 1<<16 {
		return errors.New("crypto/rsa: use of public exponent <= 2¹⁶ is not allowed in FIPS 140-only mode")
	}
	if pub.E&1 == 0 {
		return errors.New("crypto/rsa: use of even public exponent is not allowed in FIPS 140-only mode")
	}
	return nil
}

func checkFIPS140OnlyPrivateKey(priv *PrivateKey) error {
	if !fips140only.Enforced() {
		return nil
	}
	if err := checkFIPS140OnlyPublicKey(&priv.PublicKey); err != nil {
		return err
	}
	if len(priv.Primes) != 2 {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Regenerate the key with rsa.GenerateKey(rand.Reader, 2048) which always produces balanced primes and an even bit length.
  2. Reject keys at load time: if pub.N.BitLen()%2 == 1 { return error }.
  3. If parsing external keys, validate bit-length parity before use.

Example fix

// before
// externally-supplied key with odd bit length
sig, err := rsa.SignPSS(rand.Reader, oddKey, crypto.SHA256, digest, opts)

// after
priv, _ := rsa.GenerateKey(rand.Reader, 2048) // guaranteed even bit length
sig, err := rsa.SignPSS(rand.Reader, priv, crypto.SHA256, digest, opts)
Defensive patterns

Strategy: validation

Validate before calling

if pub.N.BitLen()%2 == 1 {
    return fmt.Errorf("RSA modulus has odd bit length %d; FIPS requires even (balanced primes)", pub.N.BitLen())
}
// proceed

Type guard

func keyHasEvenBitLength(pub *rsa.PublicKey) bool {
    return pub != nil && pub.N != nil && pub.N.BitLen()%2 == 0
}

Prevention

When it happens

Trigger: Loading a key whose N has an odd bit length — typically the result of a buggy/malicious key generator, a manually-constructed key, or a parser that produced an off-by-one modulus.

Common situations: Keys generated by non-Go libraries with unbalanced primes. Adversarially-crafted keys. Rare: a key with a leading zero byte stripped during encoding shifting the effective bit length.

Related errors


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