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 asView on GitHub (pinned to b6b368adc5)
Solutions
- 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).
- Audit all deterministic signing call sites when entering FIPS mode and replace non-compliant hashes.
- 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
- In FIPS environments, only use SHA-2 or SHA-3 hashes for signing.
- Audit all crypto.Hash constants in signing code paths when enabling FIPS mode.
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
- ecdsa: requested hash function unavailable:
- ecdsa: Sign must be called with a hash, not with crypto.Hash
- ecdsa: hash length does not match hash function
- crypto/ecdsa: only crypto/rand.Reader is allowed in FIPS 140
- ecdsa: hash cannot be empty
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/d2727a523e540466.
Report an issue: GitHub.