golang/go · error

crypto/rsa: salt length cannot be negative

Error message

crypto/rsa: salt length cannot be negative

What it means

rsa.SignPSS requires saltLength >= 0. A negative salt length is meaningless — it would imply a negative-length salt allocation. FIPS 186-5 further requires 0 <= sLen <= hLen; values exceeding hLen are recorded as non-approved but still processed. Only strictly negative values trigger this hard error.

Source

Thrown at src/crypto/internal/fips140/rsa/pkcs1v22.go:281

		return hash.Size(), nil
	}
	return saltLength, nil
}

// SignPSS calculates the signature of hashed using RSASSA-PSS.
func SignPSS(rand io.Reader, priv *PrivateKey, hash hash.Hash, hashed []byte, saltLength int) ([]byte, error) {
	fipsSelfTest()
	fips140.RecordApproved()
	checkApprovedHash(hash)

	// Note that while we don't commit to deterministic execution with respect
	// to the rand stream, we also never applied MaybeReadByte, so per Hyrum's
	// Law it's probably relied upon by some. It's a tolerable promise because a
	// well-specified number of random bytes is included in the signature, in a
	// well-specified way.

	if saltLength < 0 {
		return nil, errors.New("crypto/rsa: salt length cannot be negative")
	}
	// FIPS 186-5, Section 5.4(g): "the length (in bytes) of the salt (sLen)
	// shall satisfy 0 ≤ sLen ≤ hLen".
	if saltLength > hash.Size() {
		fips140.RecordNonApproved()
	}
	salt := make([]byte, saltLength)
	if err := drbg.ReadWithReader(rand, salt); err != nil {
		return nil, err
	}

	emBits := priv.pub.N.BitLen() - 1
	em, err := emsaPSSEncode(hashed, emBits, salt, hash)
	if err != nil {
		return nil, err
	}

	// RFC 8017: "Note that the octet length of EM will be one less than k if

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Use a non-negative saltLength: 0 for no salt, hash.Size() for hash-length salt, or a specific byte count
  2. If you intended PSSSaltLengthEqualsHash or PSSSaltLengthAuto, use the higher-level crypto/rsa.SignPSS which interprets those constants
  3. Validate saltLength >= 0 before calling the function

Example fix

// before
sig, err := fipsrsa.SignPSS(rand, key, hash, digest, -1) // negative

// after
sig, err := fipsrsa.SignPSS(rand, key, hash, digest, hash.Size()) // explicit hash-length salt
Defensive patterns

Strategy: validation

Validate before calling

func validatePSSSaltLength(saltLen int) error {
    if saltLen < 0 {
        return fmt.Errorf("PSS salt length cannot be negative: %d", saltLen)
    }
    return nil
}

if err := validatePSSSaltLength(saltLen); err != nil { return err }
sig, err := rsa.SignPSS(rand, key, hash, digest, &rsa.PSSOptions{SaltLength: saltLen})

Try / catch

sig, err := rsa.SignPSS(rand, key, hash, digest, opts)
if err != nil {
    return fmt.Errorf("PSS signing failed: %w", err)
}

Prevention

When it happens

Trigger: Calling SignPSS with a negative saltLength argument.

Common situations: Using rsa.PSSSaltLengthEqualsHash (-1) or rsa.PSSSaltLengthAuto (-2) constants with the internal SignPSS instead of the public API that interprets them; computing saltLength from a subtraction that underflows; an uninitialized int field defaulting to a sentinel negative value.

Related errors


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