1
1
diff --git a/src/crypto/ecdsa/ecdsa_hash_sign_verify.go b/src/crypto/ecdsa/ecdsa_hash_sign_verify.go
2
2
new file mode 100644
3
- index 0000000000..50a39f5d0a
3
+ index 0000000000..977b21958f
4
4
--- /dev/null
5
5
+++ b/src/crypto/ecdsa/ecdsa_hash_sign_verify.go
6
- @@ -0,0 +1,45 @@
6
+ @@ -0,0 +1,96 @@
7
7
+ package ecdsa
8
8
+
9
9
+ import (
10
10
+ "crypto"
11
11
+ "crypto/internal/randutil"
12
+ + "errors"
12
13
+ "io"
14
+ + "math/big"
13
15
+
14
16
+ boring "crypto/internal/backend"
17
+ +
18
+ + "golang.org/x/crypto/cryptobyte"
19
+ + "golang.org/x/crypto/cryptobyte/asn1"
15
20
+ )
16
21
+
17
- + func HashSign(rand io.Reader, priv *PrivateKey, msg []byte, h crypto.Hash) ([]byte, error) {
22
+ + func HashSign(rand io.Reader, priv *PrivateKey, msg []byte, h crypto.Hash) (*big.Int, *big.Int, error) {
23
+ + randutil.MaybeReadByte(rand)
24
+ +
25
+ + if boring.Enabled() {
26
+ + sig, err := HashSignASN1(rand, priv, msg, h)
27
+ + if err != nil {
28
+ + return nil, nil, err
29
+ + }
30
+ + r, s := new(big.Int), new(big.Int)
31
+ + var inner cryptobyte.String
32
+ + input := cryptobyte.String(sig)
33
+ + if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
34
+ + !input.Empty() ||
35
+ + !inner.ReadASN1Integer(r) ||
36
+ + !inner.ReadASN1Integer(s) ||
37
+ + !inner.Empty() {
38
+ + return nil, nil, errors.New("invalid ASN.1 from HashSignECDSA")
39
+ + }
40
+ + return r, s, nil
41
+ + }
42
+ + boring.UnreachableExceptTests()
43
+ +
44
+ + hash := h.New()
45
+ + hash.Write(msg)
46
+ + d := hash.Sum(nil)
47
+ +
48
+ + return Sign(rand, priv, d)
49
+ + }
50
+ +
51
+ + func HashSignASN1(rand io.Reader, priv *PrivateKey, msg []byte, h crypto.Hash) ([]byte, error) {
18
52
+ randutil.MaybeReadByte(rand)
19
53
+
20
54
+ if boring.Enabled() {
@@ -33,7 +67,24 @@ index 0000000000..50a39f5d0a
33
67
+ return SignASN1(rand, priv, d)
34
68
+ }
35
69
+
36
- + func HashVerify(pub *PublicKey, msg, sig []byte, h crypto.Hash) bool {
70
+ + func HashVerify(pub *PublicKey, msg []byte, r, s *big.Int, h crypto.Hash) bool {
71
+ + if boring.Enabled() {
72
+ + sig, err := encodeSignature(r.Bytes(), s.Bytes())
73
+ + if err != nil {
74
+ + return false
75
+ + }
76
+ + return HashVerifyASN1(pub, h, msg, sig)
77
+ + }
78
+ + boring.UnreachableExceptTests()
79
+ +
80
+ + hash := h.New()
81
+ + hash.Write(msg)
82
+ + d := hash.Sum(nil)
83
+ +
84
+ + return Verify(pub, d, r, s)
85
+ + }
86
+ +
87
+ + func HashVerifyASN1(pub *PublicKey, h crypto.Hash, msg, sig []byte) bool {
37
88
+ if boring.Enabled() {
38
89
+ bpk, err := boringPublicKey(pub)
39
90
+ if err != nil {
@@ -51,7 +102,7 @@ index 0000000000..50a39f5d0a
51
102
+ }
52
103
diff --git a/src/crypto/ecdsa/ecdsa_hashsignverify_test.go b/src/crypto/ecdsa/ecdsa_hashsignverify_test.go
53
104
new file mode 100644
54
- index 0000000000..65ca8a4b77
105
+ index 0000000000..b73b03e975
55
106
--- /dev/null
56
107
+++ b/src/crypto/ecdsa/ecdsa_hashsignverify_test.go
57
108
@@ -0,0 +1,43 @@
@@ -73,23 +124,23 @@ index 0000000000..65ca8a4b77
73
124
+
74
125
+ msg := []byte("testing")
75
126
+ h := crypto.SHA256
76
- + hsm, err := HashSign (rand.Reader, priv, msg, h)
127
+ + hsm, err := HashSignASN1 (rand.Reader, priv, msg, h)
77
128
+ if err != nil {
78
129
+ t.Errorf("%s: error signing: %s", tag, err)
79
130
+ return
80
131
+ }
81
132
+
82
- + if !HashVerify (&priv.PublicKey, msg, hsm, h ) {
133
+ + if !HashVerifyASN1 (&priv.PublicKey, h, msg, hsm ) {
83
134
+ t.Errorf("%s: Verify failed", tag)
84
135
+ }
85
136
+
86
137
+ msg[0] ^= 0xff
87
- + if HashVerify (&priv.PublicKey, msg, hsm, h ) {
138
+ + if HashVerifyASN1 (&priv.PublicKey, h, msg, hsm ) {
88
139
+ t.Errorf("%s: Verify should not have succeeded", tag)
89
140
+ }
90
141
+ }
91
142
+
92
- + func TestHashSignAndHashVerify (t *testing.T) {
143
+ + func TestHashSignAndHashVerifyASN1 (t *testing.T) {
93
144
+ testHashSignAndHashVerify(t, elliptic.P256(), "p256")
94
145
+
95
146
+ if testing.Short() && !boring.Enabled() {
0 commit comments