mirror of
https://github.com/golang/go
synced 2024-09-15 22:20:06 +00:00
crypto/rsa, crypto/ecdsa: fail earlier on zero parameters
Change-Id: Ia6ed49d5ef3a256a55e6d4eaa1b4d9f0fc447013 Reviewed-on: https://go-review.googlesource.com/21560 Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
7e0d66020c
commit
d7c699d993
|
@ -23,6 +23,7 @@ import (
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"crypto/sha512"
|
"crypto/sha512"
|
||||||
"encoding/asn1"
|
"encoding/asn1"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
@ -140,6 +141,8 @@ func fermatInverse(k, N *big.Int) *big.Int {
|
||||||
return new(big.Int).Exp(k, nMinus2, N)
|
return new(big.Int).Exp(k, nMinus2, N)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var errZeroParam = errors.New("zero parameter")
|
||||||
|
|
||||||
// Sign signs an arbitrary length hash (which should be the result of hashing a
|
// Sign signs an arbitrary length hash (which should be the result of hashing a
|
||||||
// larger message) using the private key, priv. It returns the signature as a
|
// larger message) using the private key, priv. It returns the signature as a
|
||||||
// pair of integers. The security of the private key depends on the entropy of
|
// pair of integers. The security of the private key depends on the entropy of
|
||||||
|
@ -180,7 +183,9 @@ func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err err
|
||||||
// See [NSA] 3.4.1
|
// See [NSA] 3.4.1
|
||||||
c := priv.PublicKey.Curve
|
c := priv.PublicKey.Curve
|
||||||
N := c.Params().N
|
N := c.Params().N
|
||||||
|
if N.Sign() == 0 {
|
||||||
|
return nil, nil, errZeroParam
|
||||||
|
}
|
||||||
var k, kInv *big.Int
|
var k, kInv *big.Int
|
||||||
for {
|
for {
|
||||||
for {
|
for {
|
||||||
|
@ -193,7 +198,7 @@ func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err err
|
||||||
if in, ok := priv.Curve.(invertible); ok {
|
if in, ok := priv.Curve.(invertible); ok {
|
||||||
kInv = in.Inverse(k)
|
kInv = in.Inverse(k)
|
||||||
} else {
|
} else {
|
||||||
kInv = fermatInverse(k, N)
|
kInv = fermatInverse(k, N) // N != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
r, _ = priv.Curve.ScalarBaseMult(k.Bytes())
|
r, _ = priv.Curve.ScalarBaseMult(k.Bytes())
|
||||||
|
@ -207,7 +212,7 @@ func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err err
|
||||||
s = new(big.Int).Mul(priv.D, r)
|
s = new(big.Int).Mul(priv.D, r)
|
||||||
s.Add(s, e)
|
s.Add(s, e)
|
||||||
s.Mul(s, kInv)
|
s.Mul(s, kInv)
|
||||||
s.Mod(s, N)
|
s.Mod(s, N) // N != 0
|
||||||
if s.Sign() != 0 {
|
if s.Sign() != 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -465,6 +465,9 @@ func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err er
|
||||||
err = ErrDecryption
|
err = ErrDecryption
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if priv.N.Sign() == 0 {
|
||||||
|
return nil, ErrDecryption
|
||||||
|
}
|
||||||
|
|
||||||
var ir *big.Int
|
var ir *big.Int
|
||||||
if random != nil {
|
if random != nil {
|
||||||
|
@ -490,7 +493,7 @@ func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err er
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bigE := big.NewInt(int64(priv.E))
|
bigE := big.NewInt(int64(priv.E))
|
||||||
rpowe := new(big.Int).Exp(r, bigE, priv.N)
|
rpowe := new(big.Int).Exp(r, bigE, priv.N) // N != 0
|
||||||
cCopy := new(big.Int).Set(c)
|
cCopy := new(big.Int).Set(c)
|
||||||
cCopy.Mul(cCopy, rpowe)
|
cCopy.Mul(cCopy, rpowe)
|
||||||
cCopy.Mod(cCopy, priv.N)
|
cCopy.Mod(cCopy, priv.N)
|
||||||
|
|
Loading…
Reference in a new issue