golang/go · error

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

Error message

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

What it means

Thrown by signFIPSDeterministic when FIPS 140-only mode is enforced and the requested hash function is not a FIPS-approved SHA-2 or SHA-3 variant. FIPS 140 prohibits the use of non-approved hash functions (like MD5, SHA-1, BLAKE2) in cryptographic operations. The fips140only.ApprovedHash check validates the hash implementation against the approved list.

Source

Thrown at src/crypto/ecdsa/ecdsa.go:468

		return signFIPSDeterministic(ecdsa.P384(), h, priv, hash)
	case elliptic.P521().Params():
		return signFIPSDeterministic(ecdsa.P521(), h, priv, hash)
	default:
		return nil, errors.New("ecdsa: curve not supported by deterministic signatures")
	}
}

func signFIPSDeterministic[P ecdsa.Point[P]](c *ecdsa.Curve[P], hashFunc crypto.Hash, priv *PrivateKey, hash []byte) ([]byte, error) {
	k, err := privateKeyToFIPS(c, priv)
	if err != nil {
		return nil, err
	}
	if !hashFunc.Available() {
		return nil, errors.New("ecdsa: requested hash function unavailable: " + hashFunc.String())
	}
	h := fips140hash.UnwrapNew(hashFunc.New)
	if fips140only.Enforced() && !fips140only.ApprovedHash(h()) {
		return nil, errors.New("crypto/ecdsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode")
	}
	sig, err := ecdsa.SignDeterministic(c, h, k, hash)
	if err != nil {
		return nil, err
	}
	return encodeSignature(sig.R, sig.S)
}

func encodeSignature(r, s []byte) ([]byte, error) {
	var b cryptobyte.Builder
	b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
		addASN1IntBytes(b, r)
		addASN1IntBytes(b, s)
	})
	return b.Bytes()
}

// addASN1IntBytes encodes in ASN.1 a positive integer represented as

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Switch to a FIPS-approved hash: use SHA-224, SHA-256, SHA-384, SHA-512 (SHA-2 family) or SHA3-224/256/384/512 (SHA-3 family).
  2. Audit all deterministic signing call sites when entering FIPS mode and replace non-compliant hashes.
  3. If SHA-1 is required for backward compatibility, it cannot be used in FIPS 140-only mode — negotiate a protocol upgrade to SHA-256.

Example fix

// before
sig, err := priv.Sign(nil, digest, crypto.SHA1) // rejected in FIPS mode

// after
sig, err := priv.Sign(nil, digest, crypto.SHA256) // SHA-2 is FIPS-approved
Defensive patterns

Strategy: validation

Validate before calling

func isFIPSApprovedHash(h crypto.Hash) bool {
    switch h {
    case crypto.SHA224, crypto.SHA256, crypto.SHA384, crypto.SHA512,
         crypto.SHA3_224, crypto.SHA3_256, crypto.SHA3_384, crypto.SHA3_512:
        return true
    }
    return false
}
// call before deterministic Sign in FIPS mode

Try / catch

sig, err := priv.Sign(nil, digest, h)
if err != nil && strings.Contains(err.Error(), "SHA-2 or SHA-3") {
    // switch to an approved hash and re-hash the original message
    digest = sha256.Sum256(msg)
    sig, err = priv.Sign(nil, digest[:], crypto.SHA256)
}

Prevention

When it happens

Trigger: Calling deterministic Sign with opts.HashFunc() set to a non-approved hash (e.g., crypto.MD5, crypto.SHA1, crypto.BLAKE2b_256) while FIPS 140-only mode is active. Even if the hash is technically 'available' (linked), it fails the FIPS approval check.

Common situations: FIPS-compliant deployments where legacy code uses SHA-1 or MD5 for signing; migrating to FIPS mode without auditing hash usage; protocols that mandate non-FIPS hashes (some legacy TLS cipher suites use SHA-1).

Related errors


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