aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippo Valsorda <filippo@golang.org>2023-06-12 18:58:50 +0200
committerGopher Robot <gobot@golang.org>2023-06-19 16:08:25 +0000
commita7a48fad7ef67033f3662bcc659e92848040d3d6 (patch)
tree1ef8966ffd3910f40369386cb2db924baf7d7220
parentf5172dcd38f42829d145afd47c293afab934ccbc (diff)
downloadgo-a7a48fad7ef67033f3662bcc659e92848040d3d6.tar.gz
go-a7a48fad7ef67033f3662bcc659e92848040d3d6.zip
[release-branch.go1.20] crypto/ecdsa: properly truncate P-521 hashes
Before, if a hash was exactly 66 bytes long, we weren't truncating it for use with P-521, because the byte length was not overflowing. However, the bit length could still overflow. Fixes #60744 Updates #60741 Change-Id: I37a0ee210add0eb566e6dc1c141e83e992983eb6 Reviewed-on: https://go-review.googlesource.com/c/go/+/502478 Auto-Submit: Filippo Valsorda <filippo@golang.org> Reviewed-by: Roland Shoemaker <roland@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Filippo Valsorda <filippo@golang.org> Reviewed-by: Damien Neil <dneil@google.com> (cherry picked from commit 886fba5871268c2dccba2675fea5aafacab59189) Reviewed-on: https://go-review.googlesource.com/c/go/+/502915 Auto-Submit: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Run-TryBot: Damien Neil <dneil@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
-rw-r--r--src/crypto/ecdsa/ecdsa.go2
-rw-r--r--src/crypto/ecdsa/ecdsa_test.go15
2 files changed, 16 insertions, 1 deletions
diff --git a/src/crypto/ecdsa/ecdsa.go b/src/crypto/ecdsa/ecdsa.go
index 68272af41f..03a9a72ddd 100644
--- a/src/crypto/ecdsa/ecdsa.go
+++ b/src/crypto/ecdsa/ecdsa.go
@@ -380,7 +380,7 @@ func hashToNat[Point nistPoint[Point]](c *nistCurve[Point], e *bigmod.Nat, hash
// an integer modulo N. This is the absolute worst of all worlds: we still
// have to reduce, because the result might still overflow N, but to take
// the left-most bits for P-521 we have to do a right shift.
- if size := c.N.Size(); len(hash) > size {
+ if size := c.N.Size(); len(hash) >= size {
hash = hash[:size]
if excess := len(hash)*8 - c.N.BitLen(); excess > 0 {
hash = bytes.Clone(hash)
diff --git a/src/crypto/ecdsa/ecdsa_test.go b/src/crypto/ecdsa/ecdsa_test.go
index 95c78c8e32..08a0903eb1 100644
--- a/src/crypto/ecdsa/ecdsa_test.go
+++ b/src/crypto/ecdsa/ecdsa_test.go
@@ -9,6 +9,7 @@ import (
"bytes"
"compress/bzip2"
"crypto/elliptic"
+ "crypto/internal/bigmod"
"crypto/rand"
"crypto/sha1"
"crypto/sha256"
@@ -398,6 +399,20 @@ func testRandomPoint[Point nistPoint[Point]](t *testing.T, c *nistCurve[Point])
}
}
+func TestHashToNat(t *testing.T) {
+ t.Run("P-224", func(t *testing.T) { testHashToNat(t, p224()) })
+ t.Run("P-256", func(t *testing.T) { testHashToNat(t, p256()) })
+ t.Run("P-384", func(t *testing.T) { testHashToNat(t, p384()) })
+ t.Run("P-521", func(t *testing.T) { testHashToNat(t, p521()) })
+}
+
+func testHashToNat[Point nistPoint[Point]](t *testing.T, c *nistCurve[Point]) {
+ for l := 0; l < 600; l++ {
+ h := bytes.Repeat([]byte{0xff}, l)
+ hashToNat(c, bigmod.NewNat(), h)
+ }
+}
+
func TestZeroSignature(t *testing.T) {
testAllCurves(t, testZeroSignature)
}