golang/go · error

crypto/rsa: use of PSS salt longer than the hash is not allo

Error message

crypto/rsa: use of PSS salt longer than the hash is not allowed in FIPS 140-only mode

What it means

Thrown by SignPSS in FIPS 140-only mode when opts.SaltLength (after resolving sentinels) is strictly greater than the hash function's output size (h.Size()). FIPS 186-5 caps the PSS salt at the hash output length, so an explicit saltLength larger than h.Size() is rejected before signing proceeds. This guard only fires when fips140only.Enforced() returns true (the binary was built/run in FIPS-only mode).

Source

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

	if err := checkFIPS140OnlyPrivateKey(priv); err != nil {
		return nil, err
	}
	if fips140only.Enforced() && !fips140only.ApprovedHash(h) {
		return nil, errors.New("crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode")
	}
	if fips140only.Enforced() && !fips140only.ApprovedRandomReader(random) {
		return nil, errors.New("crypto/rsa: only crypto/rand.Reader is allowed in FIPS 140-only mode")
	}

	k, err := fipsPrivateKey(priv)
	if err != nil {
		return nil, err
	}

	saltLength := opts.saltLength()
	if fips140only.Enforced() && saltLength > h.Size() {
		return nil, errors.New("crypto/rsa: use of PSS salt longer than the hash is not allowed in FIPS 140-only mode")
	}
	switch saltLength {
	case PSSSaltLengthAuto:
		saltLength, err = rsa.PSSMaxSaltLength(k.PublicKey(), h)
		if err != nil {
			return nil, fipsError(err)
		}
	case PSSSaltLengthEqualsHash:
		saltLength = h.Size()
	default:
		// If we get here saltLength is either > 0 or < -1, in the
		// latter case we fail out.
		if saltLength <= 0 {
			return nil, errors.New("crypto/rsa: invalid PSS salt length")
		}
	}

	return fipsError2(rsa.SignPSS(random, k, h, digest, saltLength))

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Set PSSOptions.SaltLength to rsa.PSSSaltLengthEqualsHash (-1) so the salt always equals h.Size(), which is always FIPS-legal.
  2. Set PSSOptions.SaltLength to rsa.PSSSaltLengthAuto (0); in FIPS mode this is capped at the hash size automatically.
  3. If you must set an explicit byte count, clamp it: saltLength = min(saltLength, hash.Size()).
  4. If the oversized salt is an unavoidable protocol requirement, you cannot use FIPS-only mode — remove the enforcement setting for this operation.

Example fix

// before
opts := &rsa.PSSOptions{SaltLength: 64, Hash: crypto.SHA256}
sig, err := rsa.SignPSS(rand.Reader, priv, crypto.SHA256, digest, opts)

// after
opts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: crypto.SHA256}
sig, err := rsa.SignPSS(rand.Reader, priv, crypto.SHA256, digest, opts)
Defensive patterns

Strategy: validation

Validate before calling

// Before calling SignPSS, ensure the salt length is FIPS-legal.
func safeSaltLength(hash crypto.Hash, opts *rsa.PSSOptions) int {
    sl := rsa.PSSSaltLengthAuto
    if opts != nil {
        sl = opts.SaltLength
    }
    switch sl {
    case rsa.PSSSaltLengthAuto, rsa.PSSSaltLengthEqualsHash:
        return sl
    default:
        if sl > hash.Size() {
            return rsa.PSSSaltLengthEqualsHash // clamp to hash size
        }
        return sl
    }
}
opts.SaltLength = safeSaltLength(crypto.SHA256, opts)

Type guard

func isFIPSCompliantSaltLength(hash crypto.Hash, sl int) bool {
    return sl == rsa.PSSSaltLengthAuto ||
        sl == rsa.PSSSaltLengthEqualsHash ||
        (sl > 0 && sl <= hash.Size())
}

Prevention

When it happens

Trigger: Calling rsa.SignPSS (or PrivateKey.Sign with *PSSOptions) where opts.SaltLength is a positive int larger than hash.Size() — e.g. SaltLength: 64 with crypto.SHA256 (Size()==32) — while GOFIPS-only enforcement is active. The sentinel PSSSaltLengthEqualsHash and PSSSaltLengthAuto do NOT trip this (they are resolved before the comparison).

Common situations: Migrating an app from a non-FIPS Go build to a FIPS-only toolchain where the original code set an oversized explicit salt. Porting PSS parameters from another library (OpenSSL default salt = key size, often > hash size). Hardcoding a salt length chosen for maximum entropy without considering the hash.

Related errors


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