Commit b30fcbc9 authored by Adam Langley's avatar Adam Langley Committed by Russ Cox

crypto/ecdsa: reject negative inputs.

The fact that crypto/ecdsa.Verify didn't reject negative inputs was a
mistake on my part: I had unsigned numbers on the brain. However, it
doesn't generally cause problems. (ModInverse results in zero, which
results in x being zero, which is rejected.)

The amd64 P-256 code will crash when given a large, negative input.

This fixes both crypto/ecdsa to reject these values and also the P-256
code to ignore the sign of inputs.

Change-Id: I6370ed7ca8125e53225866f55b616a4022b818f8
Reviewed-on: https://go-review.googlesource.com/22093
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 2ba8fc5b
...@@ -228,7 +228,7 @@ func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool { ...@@ -228,7 +228,7 @@ func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
c := pub.Curve c := pub.Curve
N := c.Params().N N := c.Params().N
if r.Sign() == 0 || s.Sign() == 0 { if r.Sign() <= 0 || s.Sign() <= 0 {
return false return false
} }
if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 { if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 {
......
...@@ -296,3 +296,26 @@ func TestVectors(t *testing.T) { ...@@ -296,3 +296,26 @@ func TestVectors(t *testing.T) {
} }
} }
} }
func testNegativeInputs(t *testing.T, curve elliptic.Curve, tag string) {
key, err := GenerateKey(curve, rand.Reader)
if err != nil {
t.Errorf("failed to generate key for %q", tag)
}
var hash [32]byte
r := new(big.Int).SetInt64(1)
r.Lsh(r, 550 /* larger than any supported curve */)
r.Neg(r)
if Verify(&key.PublicKey, hash[:], r, r) {
t.Errorf("bogus signature accepted for %q", tag)
}
}
func TestNegativeInputs(t *testing.T) {
testNegativeInputs(t, elliptic.P224(), "p224")
testNegativeInputs(t, elliptic.P256(), "p256")
testNegativeInputs(t, elliptic.P384(), "p384")
testNegativeInputs(t, elliptic.P521(), "p521")
}
...@@ -93,10 +93,14 @@ func p256PointAddAsm(res, in1, in2 []uint64) ...@@ -93,10 +93,14 @@ func p256PointAddAsm(res, in1, in2 []uint64)
func p256PointDoubleAsm(res, in []uint64) func p256PointDoubleAsm(res, in []uint64)
func (curve p256Curve) Inverse(k *big.Int) *big.Int { func (curve p256Curve) Inverse(k *big.Int) *big.Int {
if k.Sign() < 0 {
// This should never happen.
k = new(big.Int).Neg(k)
}
if k.Cmp(p256.N) >= 0 { if k.Cmp(p256.N) >= 0 {
// This should never happen. // This should never happen.
reducedK := new(big.Int).Mod(k, p256.N) k = new(big.Int).Mod(k, p256.N)
k = reducedK
} }
// table will store precomputed powers of x. The four words at index // table will store precomputed powers of x. The four words at index
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment