golang/go · error

crypto/rsa: invalid PSS salt length

Error message

crypto/rsa: invalid PSS salt length

What it means

invalidSaltLenErr is returned by SignRSAPSS (and VerifyRSAPSS) when saltLen <= -2. BoringSSL treats -2 as 'maximal salt length', but Go's crypto/rsa uses 0 for that and reserves -1 for hash-length; values <= -2 are not part of crypto/rsa's contract, so they are rejected before conversion to BoringSSL sentinels.

Source

Thrown at src/crypto/internal/boring/rsa.go:255

// These dumb wrappers work around the fact that cgo functions cannot be used as values directly.

func decryptInit(ctx *C.GO_EVP_PKEY_CTX) C.int {
	return C._goboringcrypto_EVP_PKEY_decrypt_init(ctx)
}

func decrypt(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.size_t, in *C.uint8_t, inLen C.size_t) C.int {
	return C._goboringcrypto_EVP_PKEY_decrypt(ctx, out, outLen, in, inLen)
}

func encryptInit(ctx *C.GO_EVP_PKEY_CTX) C.int {
	return C._goboringcrypto_EVP_PKEY_encrypt_init(ctx)
}

func encrypt(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.size_t, in *C.uint8_t, inLen C.size_t) C.int {
	return C._goboringcrypto_EVP_PKEY_encrypt(ctx, out, outLen, in, inLen)
}

var invalidSaltLenErr = errors.New("crypto/rsa: invalid PSS salt length")

func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) {
	md := cryptoHashToMD(h)
	if md == nil {
		return nil, errors.New("crypto/rsa: unsupported hash function")
	}

	// A salt length of -2 is valid in BoringSSL, but not in crypto/rsa, so reject
	// it, and lengths < -2, before we convert to the BoringSSL sentinel values.
	if saltLen <= -2 {
		return nil, invalidSaltLenErr
	}

	// BoringSSL uses sentinel salt length values like we do, but the values don't
	// fully match what we use. We both use -1 for salt length equal to hash length,
	// but BoringSSL uses -2 to mean maximal size where we use 0. In the latter
	// case convert to the BoringSSL version.
	if saltLen == 0 {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Use crypto/rsa sentinels: rsa.PSSSaltLengthAuto (-1-ish semantics) or rsa.PSSSaltLengthEqualsHash, or a non-negative explicit salt length.
  2. For maximal salt length pass 0 (Go's sentinel), not -2.
  3. Validate saltLen is >= -1 before calling Sign/Verify PSS.

Example fix

// before
sig, err := boring.SignRSAPSS(priv, crypto.SHA256, digest, -2) // invalid

// after
sig, err := boring.SignRSAPSS(priv, crypto.SHA256, digest, rsa.PSSSaltLengthEqualsHash)
Defensive patterns

Strategy: validation

Validate before calling

func validatePSSSaltLen(saltLen int) error {
    if saltLen <= -2 {
        return errors.New("crypto/rsa: invalid PSS salt length")
    }
    return nil
}

Prevention

When it happens

Trigger: Calling SignRSAPSS/VerifyRSAPSS with saltLen of -2 or lower. This typically arises when callers pass BoringSSL-style sentinels into the Go API, or compute saltLen incorrectly (e.g. negative overflow).

Common situations: Porting code that uses BoringSSL/OpenSSL sentinel salt lengths directly; arithmetic that produces unexpectedly negative saltLen; interop with libraries that emit -2 for maximal salt.

Related errors


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