crypto/ecdsa: reject empty hashes

It's an API misuse and it's unreachable from other standard library
packages, but since it produces/accepts trivially forged signatures,
reject it explicitly.

Change-Id: If7a56d18d6ec445a4d2620a71d85ab7d6a6a6964
Reviewed-on: https://go-review.googlesource.com/c/go/+/765640
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
Filippo Valsorda 2026-04-11 14:39:52 +02:00 committed by Gopher Robot
parent 1debc9f0ce
commit 2f9a9642e1
2 changed files with 17 additions and 0 deletions

View file

@ -380,6 +380,10 @@ func generateFIPS[P ecdsa.Point[P]](curve elliptic.Curve, c *ecdsa.Curve[P], ran
// is set. This setting will be removed in a future Go release. Instead, use
// [testing/cryptotest.SetGlobalRandom].
func SignASN1(r io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) {
if len(hash) == 0 {
return nil, errors.New("ecdsa: hash cannot be empty")
}
if boring.Enabled && rand.IsDefaultReader(r) {
b, err := boringPrivateKey(priv)
if err != nil {
@ -497,6 +501,10 @@ func addASN1IntBytes(b *cryptobyte.Builder, bytes []byte) {
// The inputs are not considered confidential, and may leak through timing side
// channels, or if an attacker has control of part of the inputs.
func VerifyASN1(pub *PublicKey, hash, sig []byte) bool {
if len(hash) == 0 {
return false
}
if boring.Enabled {
key, err := boringPublicKey(pub)
if err != nil {

View file

@ -282,6 +282,9 @@ func Sign[P Point[P], H hash.Hash](c *Curve[P], h func() H, priv *PrivateKey, ra
if priv.pub.curve != c.curve {
return nil, errors.New("ecdsa: private key does not match curve")
}
if len(hash) == 0 {
return nil, errors.New("ecdsa: hash cannot be empty")
}
fips140.RecordApproved()
fipsSelfTest()
@ -315,6 +318,9 @@ func SignDeterministic[P Point[P], H hash.Hash](c *Curve[P], h func() H, priv *P
if priv.pub.curve != c.curve {
return nil, errors.New("ecdsa: private key does not match curve")
}
if len(hash) == 0 {
return nil, errors.New("ecdsa: hash cannot be empty")
}
fips140.RecordApproved()
fipsSelfTestDeterministic()
drbg := newDRBG(h, priv.d, bits2octets(c, hash), nil) // RFC 6979, Section 3.3
@ -447,6 +453,9 @@ func Verify[P Point[P]](c *Curve[P], pub *PublicKey, hash []byte, sig *Signature
if pub.curve != c.curve {
return errors.New("ecdsa: public key does not match curve")
}
if len(hash) == 0 {
return errors.New("ecdsa: hash cannot be empty")
}
fips140.RecordApproved()
fipsSelfTest()
return verify(c, pub, hash, sig)