diff --git a/patches/015-add-hash-sign-verify.patch b/patches/015-add-hash-sign-verify.patch index b73bc92885..a8c1a72fbb 100644 --- a/patches/015-add-hash-sign-verify.patch +++ b/patches/015-add-hash-sign-verify.patch @@ -1,20 +1,54 @@ diff --git a/src/crypto/ecdsa/ecdsa_hash_sign_verify.go b/src/crypto/ecdsa/ecdsa_hash_sign_verify.go new file mode 100644 -index 0000000000..50a39f5d0a +index 0000000000..977b21958f --- /dev/null +++ b/src/crypto/ecdsa/ecdsa_hash_sign_verify.go -@@ -0,0 +1,45 @@ +@@ -0,0 +1,96 @@ +package ecdsa + +import ( + "crypto" + "crypto/internal/randutil" ++ "errors" + "io" ++ "math/big" + + boring "crypto/internal/backend" ++ ++ "golang.org/x/crypto/cryptobyte" ++ "golang.org/x/crypto/cryptobyte/asn1" +) + -+func HashSign(rand io.Reader, priv *PrivateKey, msg []byte, h crypto.Hash) ([]byte, error) { ++func HashSign(rand io.Reader, priv *PrivateKey, msg []byte, h crypto.Hash) (*big.Int, *big.Int, error) { ++ randutil.MaybeReadByte(rand) ++ ++ if boring.Enabled() { ++ sig, err := HashSignASN1(rand, priv, msg, h) ++ if err != nil { ++ return nil, nil, err ++ } ++ r, s := new(big.Int), new(big.Int) ++ var inner cryptobyte.String ++ input := cryptobyte.String(sig) ++ if !input.ReadASN1(&inner, asn1.SEQUENCE) || ++ !input.Empty() || ++ !inner.ReadASN1Integer(r) || ++ !inner.ReadASN1Integer(s) || ++ !inner.Empty() { ++ return nil, nil, errors.New("invalid ASN.1 from HashSignECDSA") ++ } ++ return r, s, nil ++ } ++ boring.UnreachableExceptTests() ++ ++ hash := h.New() ++ hash.Write(msg) ++ d := hash.Sum(nil) ++ ++ return Sign(rand, priv, d) ++} ++ ++func HashSignASN1(rand io.Reader, priv *PrivateKey, msg []byte, h crypto.Hash) ([]byte, error) { + randutil.MaybeReadByte(rand) + + if boring.Enabled() { @@ -33,7 +67,24 @@ index 0000000000..50a39f5d0a + return SignASN1(rand, priv, d) +} + -+func HashVerify(pub *PublicKey, msg, sig []byte, h crypto.Hash) bool { ++func HashVerify(pub *PublicKey, msg []byte, r, s *big.Int, h crypto.Hash) bool { ++ if boring.Enabled() { ++ sig, err := encodeSignature(r.Bytes(), s.Bytes()) ++ if err != nil { ++ return false ++ } ++ return HashVerifyASN1(pub, h, msg, sig) ++ } ++ boring.UnreachableExceptTests() ++ ++ hash := h.New() ++ hash.Write(msg) ++ d := hash.Sum(nil) ++ ++ return Verify(pub, d, r, s) ++} ++ ++func HashVerifyASN1(pub *PublicKey, h crypto.Hash, msg, sig []byte) bool { + if boring.Enabled() { + bpk, err := boringPublicKey(pub) + if err != nil { @@ -51,7 +102,7 @@ index 0000000000..50a39f5d0a +} diff --git a/src/crypto/ecdsa/ecdsa_hashsignverify_test.go b/src/crypto/ecdsa/ecdsa_hashsignverify_test.go new file mode 100644 -index 0000000000..65ca8a4b77 +index 0000000000..b73b03e975 --- /dev/null +++ b/src/crypto/ecdsa/ecdsa_hashsignverify_test.go @@ -0,0 +1,43 @@ @@ -73,23 +124,23 @@ index 0000000000..65ca8a4b77 + + msg := []byte("testing") + h := crypto.SHA256 -+ hsm, err := HashSign(rand.Reader, priv, msg, h) ++ hsm, err := HashSignASN1(rand.Reader, priv, msg, h) + if err != nil { + t.Errorf("%s: error signing: %s", tag, err) + return + } + -+ if !HashVerify(&priv.PublicKey, msg, hsm, h) { ++ if !HashVerifyASN1(&priv.PublicKey, h, msg, hsm) { + t.Errorf("%s: Verify failed", tag) + } + + msg[0] ^= 0xff -+ if HashVerify(&priv.PublicKey, msg, hsm, h) { ++ if HashVerifyASN1(&priv.PublicKey, h, msg, hsm) { + t.Errorf("%s: Verify should not have succeeded", tag) + } +} + -+func TestHashSignAndHashVerify(t *testing.T) { ++func TestHashSignAndHashVerifyASN1(t *testing.T) { + testHashSignAndHashVerify(t, elliptic.P256(), "p256") + + if testing.Short() && !boring.Enabled() {