golang/go · error

crypto/rsa: use of hash functions other than SHA-2 or SHA-3

Error message

crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode

What it means

Returned during RSA PSS signing in FIPS 140-only mode when the hash used for signing is not an approved SHA-2 or SHA-3 variant. FIPS-approved RSA PSS requires SHA-2/SHA-3; hashes like SHA-1 are rejected. The check (fips140only.ApprovedHash) runs after the availability check and after private-key FIPS validation.

Source

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

		if err != nil {
			return nil, err
		}
		return boring.SignRSAPSS(bkey, hash, digest, opts.saltLength())
	}
	if priv.N.BitLen() >= 1024 {
		boring.UnreachableExceptTests()
	}

	if !hash.Available() {
		return nil, errors.New("crypto/rsa: requested hash function unavailable: " + hash.String())
	}
	h := fips140hash.Unwrap(hash.New())

	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 {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Switch to SHA-256 or stronger: use crypto.SHA256 with rsa.SignPSS.
  2. Update peer systems/certificates to SHA-2 signatures.
  3. If SHA-1 is unavoidable, run outside FIPS-only mode and document the compliance gap.

Example fix

// before (FIPS-only build)
sig, err := rsa.SignPSS(rand.Reader, priv, crypto.SHA1, digest, opts) // error

// after
sig, err := rsa.SignPSS(rand.Reader, priv, crypto.SHA256, digest, opts)
Defensive patterns

Strategy: validation

Validate before calling

if fips140only.Enforced() && !fips140only.ApprovedHash(h) {
    h = crypto.SHA256 // fall back to approved hash
}
return rsa.SignPSS(rand.Reader, priv, h, digest, opts)

Type guard

func isApprovedHash(h hash.Hash) bool { return fips140only.ApprovedHash(h) }

Try / catch

sig, err := rsa.SignPSS(rand.Reader, priv, hash, digest, opts)
if err != nil && strings.Contains(err.Error(), "other than SHA-2 or SHA-3") {
    sig, err = rsa.SignPSS(rand.Reader, priv, crypto.SHA256, digest, opts)
}
return sig, err

Prevention

When it happens

Trigger: Calling rsa.SignPSS with crypto.SHA1 (or another non-approved hash) in a FIPS-only build. Using a SignerOpts that resolves to SHA-1.

Common situations: Legacy protocols that mandate SHA-1 with RSA (e.g., old TLS cipher suites, legacy cert signatures) migrated into FIPS mode. Interop with systems that only support SHA-1.

Related errors


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