]> Cypherpunks.ru repositories - gostls13.git/commitdiff
crypto/ecdsa: properly truncate P-521 hashes
authorFilippo Valsorda <filippo@golang.org>
Mon, 12 Jun 2023 16:58:50 +0000 (18:58 +0200)
committerGopher Robot <gobot@golang.org>
Tue, 13 Jun 2023 16:14:23 +0000 (16:14 +0000)
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 #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>
src/crypto/ecdsa/ecdsa.go
src/crypto/ecdsa/ecdsa_test.go

index 1b04b2cb99b4da8c9865522dfcad11396b1a4e28..1c93cefdbf247e4c85d93c768d0de8408682ed7f 100644 (file)
@@ -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)
index 95c78c8e32403f636d7eb2089c2b4311b377c763..08a0903eb1ae2b9e60f4cb4a2faeb4722057e611 100644 (file)
@@ -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)
 }