xref: /aosp_15_r20/external/tink/go/signature/subtle/ecdsa_test.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1// Copyright 2020 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15////////////////////////////////////////////////////////////////////////////////
16
17package subtle_test
18
19import (
20	"encoding/asn1"
21	"encoding/hex"
22	"math/big"
23	"testing"
24
25	"github.com/google/tink/go/signature/subtle"
26	"github.com/google/tink/go/subtle/random"
27)
28
29type paramsTestECDSA struct {
30	hash     string
31	curve    string
32	encoding string
33}
34
35func TestECDSAEncodeDecodeDER(t *testing.T) {
36	nTest := 1000
37	for i := 0; i < nTest; i++ {
38		sig := newECDSARandomSignature()
39		encoding := "DER"
40		encoded, err := sig.EncodeECDSASignature(encoding, "P-256")
41		if err != nil {
42			t.Errorf("unexpected error during encoding: %s", err)
43		}
44		// first byte is 0x30
45		if encoded[0] != byte(0x30) {
46			t.Errorf("first byte is incorrect, expected 48, got %v", encoded[0])
47		}
48		// tag is 2
49		if encoded[2] != byte(2) || encoded[4+encoded[3]] != byte(2) {
50			t.Errorf("expect tag to be 2 (integer), got %d and %d", encoded[2], encoded[4+encoded[3]])
51		}
52		// length
53		if len(encoded) != int(encoded[1])+2 {
54			t.Errorf("incorrect length, expected %d, got %d", len(encoded), encoded[1]+2)
55		}
56		decodedSig, err := subtle.DecodeECDSASignature(encoded, encoding)
57		if err != nil {
58			t.Errorf("unexpected error during decoding: %s", err)
59		}
60		if decodedSig.R.Cmp(sig.R) != 0 || decodedSig.S.Cmp(sig.S) != 0 {
61			t.Errorf("decoded signature doesn't match original value")
62		}
63	}
64}
65
66func TestECDSAEncodeDecodeIEEEP1363(t *testing.T) {
67	nTest := 1000
68	for i := 0; i < nTest; i++ {
69		sig := newECDSARandomSignature()
70		encoding := "IEEE_P1363"
71		encoded, err := sig.EncodeECDSASignature(encoding, "P-256")
72		if err != nil {
73			t.Errorf("unexpected error during encoding: %s", err)
74		}
75		if len(encoded) != 64 {
76			t.Errorf("incorrect length, expected %d, got %d", 64, len(encoded))
77		}
78		if len(sig.R.Bytes()) < 32 {
79			expectedZeros := 32 - len(sig.R.Bytes())
80			for i := 0; i < expectedZeros; i++ {
81				if encoded[i] != 0 {
82					t.Errorf("expect byte %d to be 0, got %d. encoded data = %s", i, encoded[i], hex.Dump(encoded))
83				}
84			}
85		}
86		if len(sig.S.Bytes()) < 32 {
87			expectedZeros := 32 - len(sig.S.Bytes())
88			for i := 32; i < (32 + expectedZeros); i++ {
89				if encoded[i] != 0 {
90					t.Errorf("expect byte %d to be 0, got %d. encoded data = %s", i, encoded[i], hex.Dump(encoded))
91				}
92			}
93		}
94		decodedSig, err := subtle.DecodeECDSASignature(encoded, encoding)
95		if err != nil {
96			t.Errorf("unexpected error during decoding: %s", err)
97		}
98		if decodedSig.R.Cmp(sig.R) != 0 || decodedSig.S.Cmp(sig.S) != 0 {
99			t.Errorf("decoded signature doesn't match original value")
100		}
101	}
102}
103
104func TestECDSAEncodeWithInvalidInput(t *testing.T) {
105	sig := newECDSARandomSignature()
106	_, err := sig.EncodeECDSASignature("UNKNOWN_ENCODING", "P-256")
107	if err == nil {
108		t.Errorf("expect an error when encoding is invalid")
109	}
110}
111
112func TestECDSADecodeWithInvalidInput(t *testing.T) {
113	var sig *subtle.ECDSASignature
114	var encoded []byte
115	encoding := "DER"
116
117	// modified first byte
118	sig = newECDSARandomSignature()
119	encoded, _ = sig.EncodeECDSASignature(encoding, "P-256")
120	encoded[0] = 0x31
121	if _, err := subtle.DecodeECDSASignature(encoded, encoding); err == nil {
122		t.Errorf("expect an error when first byte is not 0x30")
123	}
124	// modified tag
125	sig = newECDSARandomSignature()
126	encoded, _ = sig.EncodeECDSASignature(encoding, "P-256")
127	encoded[2] = encoded[2] + 1
128	if _, err := subtle.DecodeECDSASignature(encoded, encoding); err == nil {
129		t.Errorf("expect an error when tag is modified")
130	}
131	// modified length
132	sig = newECDSARandomSignature()
133	encoded, _ = sig.EncodeECDSASignature(encoding, "P-256")
134	encoded[1] = encoded[1] + 1
135	if _, err := subtle.DecodeECDSASignature(encoded, encoding); err == nil {
136		t.Errorf("expect an error when length is modified")
137	}
138	// append unused 0s
139	sig = newECDSARandomSignature()
140	encoded, _ = sig.EncodeECDSASignature(encoding, "P-256")
141	tmp := make([]byte, len(encoded)+4)
142	copy(tmp, encoded)
143	if _, err := subtle.DecodeECDSASignature(tmp, encoding); err == nil {
144		t.Errorf("expect an error when unused 0s are appended to signature")
145	}
146	// a struct with three numbers
147	randomStruct := struct{ X, Y, Z *big.Int }{
148		X: new(big.Int).SetBytes(random.GetRandomBytes(32)),
149		Y: new(big.Int).SetBytes(random.GetRandomBytes(32)),
150		Z: new(big.Int).SetBytes(random.GetRandomBytes(32)),
151	}
152	encoded, _ = asn1.Marshal(randomStruct)
153	if _, err := subtle.DecodeECDSASignature(encoded, encoding); err == nil {
154		t.Errorf("expect an error when input is not an ECDSASignature")
155	}
156}
157
158func TestECDSAValidateParams(t *testing.T) {
159	params := genECDSAValidParams()
160	for i := 0; i < len(params); i++ {
161		if err := subtle.ValidateECDSAParams(params[i].hash, params[i].curve, params[i].encoding); err != nil {
162			t.Errorf("unexpected error for valid params: %s, i = %d", err, i)
163		}
164	}
165	params = genECDSAInvalidParams()
166	for i := 0; i < len(params); i++ {
167		if err := subtle.ValidateECDSAParams(params[i].hash, params[i].curve, params[i].encoding); err == nil {
168			t.Errorf("expect an error when params are invalid, i = %d", i)
169		}
170	}
171}
172
173func genECDSAInvalidParams() []paramsTestECDSA {
174	encodings := []string{"DER", "IEEE_P1363"}
175	testCases := []paramsTestECDSA{
176		// invalid encoding
177		{hash: "SHA256", curve: "NIST_P256", encoding: "UNKNOWN_ENCODING"},
178		// invalid hash
179		{hash: "SHA1", curve: "NIST_P256", encoding: "IEEE_P1363"},
180		// invalid curve
181		{hash: "SHA1", curve: "UNKNOWN_CURVE", encoding: "IEEE_P1363"},
182	}
183	for _, encoding := range encodings {
184		testCases = append(testCases,
185			// invalid curve
186			paramsTestECDSA{hash: "SHA256", curve: "UNKNOWN_CURVE", encoding: encoding},
187			// invalid hash: P256 and SHA-512
188			paramsTestECDSA{hash: "SHA512", curve: "NIST_P256", encoding: encoding},
189			// invalid hash: P521 and SHA-256
190			paramsTestECDSA{hash: "SHA256", curve: "NIST_P521", encoding: encoding},
191			// invalid hash: P384 and SHA-256
192			paramsTestECDSA{hash: "SHA256", curve: "NIST_P384", encoding: encoding},
193		)
194	}
195	return testCases
196}
197
198func genECDSAValidParams() []paramsTestECDSA {
199	return []paramsTestECDSA{
200		{hash: "SHA256", curve: "NIST_P256", encoding: "DER"},
201		{hash: "SHA256", curve: "NIST_P256", encoding: "IEEE_P1363"},
202		{hash: "SHA384", curve: "NIST_P384", encoding: "DER"},
203		{hash: "SHA384", curve: "NIST_P384", encoding: "IEEE_P1363"},
204		{hash: "SHA512", curve: "NIST_P384", encoding: "DER"},
205		{hash: "SHA512", curve: "NIST_P384", encoding: "IEEE_P1363"},
206		{hash: "SHA512", curve: "NIST_P521", encoding: "DER"},
207		{hash: "SHA512", curve: "NIST_P521", encoding: "IEEE_P1363"},
208	}
209}
210
211func newECDSARandomSignature() *subtle.ECDSASignature {
212	r := new(big.Int).SetBytes(random.GetRandomBytes(32))
213	s := new(big.Int).SetBytes(random.GetRandomBytes(32))
214	return subtle.NewECDSASignature(r, s)
215}
216