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