golang/go · error

crypto/rsa: use of even public exponent is not allowed in FI

Error message

crypto/rsa: use of even public exponent is not allowed in FIPS 140-only mode

What it means

Thrown by checkFIPS140OnlyPublicKey when fips140only.Enforced() and pub.E is even (pub.E & 1 == 0). An even public exponent is mathematically invalid for RSA (gcd(e, phi) != 1 is possible and e must be coprime to (p-1)(q-1)) and FIPS mandates an odd exponent. This check follows the > 2^16 check, so a large even exponent also trips 497 first.

Source

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

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 {
		return errors.New("crypto/rsa: use of multi-prime keys is not allowed in FIPS 140-only mode")
	}
	if priv.Primes[0] == nil || priv.Primes[1] == nil || priv.Primes[0].BitLen() != priv.Primes[1].BitLen() {
		return errors.New("crypto/rsa: use of primes of different sizes is not allowed in FIPS 140-only mode")
	}
	return nil

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Regenerate the key with rsa.GenerateKey (E = 65537, which is odd).
  2. Validate at load: if pub.E & 1 == 0 { reject }.
  3. Inspect the key-serialization round-trip if E was correct at generation but even at load.

Example fix

// before
pub := &rsa.PublicKey{N: n, E: 65536} // even, invalid
err := rsa.VerifyPSS(pub, crypto.SHA256, digest, sig, opts)

// after
pub := &rsa.PublicKey{N: n, E: 65537} // odd, FIPS-approved
err := rsa.VerifyPSS(pub, crypto.SHA256, digest, sig, opts)
Defensive patterns

Strategy: validation

Validate before calling

if pub.E&1 == 0 {
    return fmt.Errorf("public exponent E=%d is even; FIPS requires an odd exponent (use 65537)", pub.E)
}
// proceed

Type guard

func exponentIsOdd(e int) bool { return e&1 == 1 }

Prevention

When it happens

Trigger: A key with E set to an even value (e.g. 65536, 131072) — usually a bug in key generation or a corrupted/round-tripped key where E was modified. Constructing a PublicKey literal with an even E.

Common situations: Deserialization bug that altered E. Test fixtures with placeholder E values. Manually-built keys from a non-standard generator.

Related errors


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