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
- Use crypto/rsa sentinels: rsa.PSSSaltLengthAuto (-1-ish semantics) or rsa.PSSSaltLengthEqualsHash, or a non-negative explicit salt length.
- For maximal salt length pass 0 (Go's sentinel), not -2.
- 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
- Use crypto/rsa sentinels: PSSSaltLengthAuto, PSSSaltLengthEqualsHash, or a non-negative length.
- Pass 0 for maximal salt (Go's sentinel), never -2.
- Validate saltLen >= -1 before sign/verify.
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
- crypto/aes: GCM tag and nonce sizes can't be non-standard at
- NewPublicKeyECDH: wrong key length
- point not on curve
- NewPrivateKeyECDH: wrong key length
- boringcrypto: unknown elliptic curve
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/e03469cfb1e6b451.
Report an issue: GitHub.