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
- Set PSSOptions.SaltLength to rsa.PSSSaltLengthEqualsHash (-1) so the salt always equals h.Size(), which is always FIPS-legal.
- Set PSSOptions.SaltLength to rsa.PSSSaltLengthAuto (0); in FIPS mode this is capped at the hash size automatically.
- If you must set an explicit byte count, clamp it: saltLength = min(saltLength, hash.Size()).
- 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
- Default PSSOptions.SaltLength to rsa.PSSSaltLengthEqualsHash in all signing code.
- If FIPS-only mode is a deployment target, run the crypto/rsa test suite under GOFIPS-only to catch salt-length issues early.
- Document the hash:salt relationship in the signing config so operators understand the cap.
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
- crypto/rsa: invalid PSS salt length
- crypto/rsa: invalid PSS salt length
- crypto/rsa: verification error
- crypto/ecdsa: use of hash functions other than SHA-2 or SHA-
- crypto/rsa: unsupported hash function
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/d51cb2e1eec702f5.
Report an issue: GitHub.