1 // Copyright 2025 The BoringSSL Authors
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 // https://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 #include <stdio.h>
16
17 #include <vector>
18
19 #include <gtest/gtest.h>
20
21 #include <openssl/crypto.h>
22 #include <openssl/ec.h>
23 #include <openssl/ec_key.h>
24 #include <openssl/ecdsa.h>
25 #include <openssl/evp.h>
26 #include <openssl/rand.h>
27
28 #include "../test/file_test.h"
29 #include "../test/wycheproof_util.h"
30
31
RunWycheproofTest(const char * path)32 static void RunWycheproofTest(const char *path) {
33 SCOPED_TRACE(path);
34 FileTestGTest(path, [](FileTest *t) {
35 t->IgnoreAllUnusedInstructions();
36
37 const EC_GROUP *group = GetWycheproofCurve(t, "key.curve", true);
38 ASSERT_TRUE(group);
39 std::vector<uint8_t> uncompressed;
40 ASSERT_TRUE(t->GetInstructionBytes(&uncompressed, "key.uncompressed"));
41 bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
42 ASSERT_TRUE(key);
43 ASSERT_TRUE(EC_KEY_set_group(key.get(), group));
44 ASSERT_TRUE(EC_KEY_oct2key(key.get(), uncompressed.data(),
45 uncompressed.size(), nullptr));
46
47 const EVP_MD *md = GetWycheproofDigest(t, "sha", true);
48 ASSERT_TRUE(md);
49
50 std::vector<uint8_t> msg;
51 ASSERT_TRUE(t->GetBytes(&msg, "msg"));
52 std::vector<uint8_t> sig;
53 ASSERT_TRUE(t->GetBytes(&sig, "sig"));
54 WycheproofResult result;
55 ASSERT_TRUE(GetWycheproofResult(t, &result));
56
57 uint8_t digest[EVP_MAX_MD_SIZE];
58 unsigned int digest_len;
59 ASSERT_TRUE(
60 EVP_Digest(msg.data(), msg.size(), digest, &digest_len, md, nullptr));
61
62 int ret = ECDSA_verify_p1363(digest, digest_len, sig.data(), sig.size(),
63 key.get());
64 EXPECT_EQ(ret, result.IsValid() ? 1 : 0);
65 });
66 }
67
TEST(ECDSAP1363Test,WycheproofP224)68 TEST(ECDSAP1363Test, WycheproofP224) {
69 RunWycheproofTest(
70 "third_party/wycheproof_testvectors/"
71 "ecdsa_secp224r1_sha224_p1363_test.txt");
72 RunWycheproofTest(
73 "third_party/wycheproof_testvectors/"
74 "ecdsa_secp224r1_sha256_p1363_test.txt");
75 RunWycheproofTest(
76 "third_party/wycheproof_testvectors/"
77 "ecdsa_secp224r1_sha512_p1363_test.txt");
78 }
79
TEST(ECDSAP1363Test,WycheproofP256)80 TEST(ECDSAP1363Test, WycheproofP256) {
81 RunWycheproofTest(
82 "third_party/wycheproof_testvectors/"
83 "ecdsa_secp256r1_sha256_p1363_test.txt");
84 RunWycheproofTest(
85 "third_party/wycheproof_testvectors/"
86 "ecdsa_secp256r1_sha512_p1363_test.txt");
87 }
88
TEST(ECDSAP1363Test,WycheproofP384)89 TEST(ECDSAP1363Test, WycheproofP384) {
90 RunWycheproofTest(
91 "third_party/wycheproof_testvectors/"
92 "ecdsa_secp384r1_sha384_p1363_test.txt");
93 RunWycheproofTest(
94 "third_party/wycheproof_testvectors/"
95 "ecdsa_secp384r1_sha512_p1363_test.txt");
96 }
97
TEST(ECDSAP1363Test,WycheproofP521)98 TEST(ECDSAP1363Test, WycheproofP521) {
99 RunWycheproofTest(
100 "third_party/wycheproof_testvectors/"
101 "ecdsa_secp521r1_sha512_p1363_test.txt");
102 }
103
104
RunSignTest(const EC_GROUP * group)105 static void RunSignTest(const EC_GROUP *group) {
106 // Fill digest values with some random data.
107 uint8_t digest[20];
108 ASSERT_TRUE(RAND_bytes(digest, sizeof(digest)));
109
110 bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
111 ASSERT_TRUE(key);
112 ASSERT_TRUE(EC_KEY_set_group(key.get(), group));
113 ASSERT_TRUE(EC_KEY_generate_key(key.get()));
114
115 size_t sig_len = ECDSA_size_p1363(key.get());
116 ASSERT_GT(sig_len, 0u);
117 std::vector<uint8_t> sig(sig_len);
118
119 size_t out_sig_len;
120 ASSERT_TRUE(ECDSA_sign_p1363(digest, sizeof(digest), sig.data(), &out_sig_len,
121 sig.size(), key.get()));
122 ASSERT_EQ(out_sig_len, sig_len);
123
124 ASSERT_TRUE(ECDSA_verify_p1363(digest, sizeof(digest), sig.data(), sig.size(),
125 key.get()));
126 }
127
TEST(ECDSAP1363Test,SignP224)128 TEST(ECDSAP1363Test, SignP224) {
129 RunSignTest(EC_group_p224());
130 }
131
TEST(ECDSAP1363Test,SignP256)132 TEST(ECDSAP1363Test, SignP256) {
133 RunSignTest(EC_group_p256());
134 }
135
TEST(ECDSAP1363Test,SignP384)136 TEST(ECDSAP1363Test, SignP384) {
137 RunSignTest(EC_group_p384());
138 }
139
TEST(ECDSAP1363Test,SignP521)140 TEST(ECDSAP1363Test, SignP521) {
141 RunSignTest(EC_group_p521());
142 }
143
TEST(ECDSAP1363Test,SignFailsWithSmallBuffer)144 TEST(ECDSAP1363Test, SignFailsWithSmallBuffer) {
145 // Fill digest values with some random data.
146 uint8_t digest[20];
147 ASSERT_TRUE(RAND_bytes(digest, sizeof(digest)));
148
149 bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
150 ASSERT_TRUE(key);
151 ASSERT_TRUE(EC_KEY_set_group(key.get(), EC_group_p256()));
152 ASSERT_TRUE(EC_KEY_generate_key(key.get()));
153
154 size_t sig_len = ECDSA_size_p1363(key.get());
155 ASSERT_GT(sig_len, 0u);
156 std::vector<uint8_t> sig(sig_len - 1);
157
158 size_t out_sig_len;
159 ASSERT_FALSE(ECDSA_sign_p1363(digest, sizeof(digest), sig.data(),
160 &out_sig_len, sig.size(), key.get()));
161 }
162
TEST(ECDSAP1363Test,SignSucceedsWithLargeBuffer)163 TEST(ECDSAP1363Test, SignSucceedsWithLargeBuffer) {
164 // Fill digest values with some random data.
165 uint8_t digest[20];
166 ASSERT_TRUE(RAND_bytes(digest, sizeof(digest)));
167
168 bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
169 ASSERT_TRUE(key);
170 ASSERT_TRUE(EC_KEY_set_group(key.get(), EC_group_p256()));
171 ASSERT_TRUE(EC_KEY_generate_key(key.get()));
172
173 size_t sig_len = ECDSA_size_p1363(key.get());
174 ASSERT_GT(sig_len, 0u);
175 std::vector<uint8_t> sig(sig_len + 1, 'x');
176
177 size_t out_sig_len;
178 ASSERT_TRUE(ECDSA_sign_p1363(digest, sizeof(digest), sig.data(),
179 &out_sig_len, sig.size(), key.get()));
180 ASSERT_EQ(out_sig_len, sig_len);
181 // The extra byte should be untouched.
182 EXPECT_EQ(sig.back(), 'x');
183
184 ASSERT_TRUE(ECDSA_verify_p1363(digest, sizeof(digest), sig.data(),
185 out_sig_len, key.get()));
186 }
187
TEST(ECDSAP1363Test,SizeWithoutGroup)188 TEST(ECDSAP1363Test, SizeWithoutGroup) {
189 EXPECT_EQ(ECDSA_size_p1363(nullptr), 0u);
190
191 bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
192 EXPECT_EQ(ECDSA_size_p1363(key.get()), 0u);
193 }
194