xref: /aosp_15_r20/external/tink/cc/subtle/ed25519_sign_boringssl_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2019 Google Inc.
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 
17 #include "tink/subtle/ed25519_sign_boringssl.h"
18 
19 #include <memory>
20 #include <string>
21 #include <utility>
22 
23 #include "gtest/gtest.h"
24 #include "absl/status/status.h"
25 #include "absl/strings/escaping.h"
26 #include "absl/strings/str_cat.h"
27 #include "tink/config/tink_fips.h"
28 #include "tink/internal/ec_util.h"
29 #include "tink/public_key_sign.h"
30 #include "tink/public_key_verify.h"
31 #include "tink/subtle/ed25519_verify_boringssl.h"
32 #include "tink/subtle/random.h"
33 #include "tink/util/secret_data.h"
34 #include "tink/util/status.h"
35 #include "tink/util/statusor.h"
36 #include "tink/util/test_matchers.h"
37 
38 namespace crypto {
39 namespace tink {
40 namespace subtle {
41 namespace {
42 
43 using ::crypto::tink::test::IsOk;
44 using ::crypto::tink::test::StatusIs;
45 
46 constexpr int kEd25519SignatureLenInBytes = 64;
47 
48 class Ed25519SignBoringSslTest : public ::testing::Test {};
49 
50 struct Ed25519KeyPair {
51   std::string public_key;
52   util::SecretData private_key;
53 };
54 
NewKeyPair()55 util::StatusOr<Ed25519KeyPair> NewKeyPair() {
56   util::StatusOr<std::unique_ptr<internal::Ed25519Key>> key =
57       internal::NewEd25519Key();
58   if (!key.ok()) {
59     return key.status();
60   }
61 
62   return {{(*key)->public_key, util::SecretDataFromStringView(absl::StrCat(
63                                    (*key)->private_key, (*key)->public_key))}};
64 }
65 
TEST_F(Ed25519SignBoringSslTest,testBasicSign)66 TEST_F(Ed25519SignBoringSslTest, testBasicSign) {
67   if (IsFipsModeEnabled()) {
68     GTEST_SKIP() << "Test assumes kOnlyUseFips is false.";
69   }
70 
71   // Generate a new key pair.
72   util::StatusOr<Ed25519KeyPair> key = NewKeyPair();
73   ASSERT_THAT(key, IsOk());
74 
75   // Create a new signer.
76   auto signer_result = Ed25519SignBoringSsl::New(key->private_key);
77   ASSERT_TRUE(signer_result.ok()) << signer_result.status();
78   auto signer = std::move(signer_result.value());
79 
80   // Create a new verifier.
81   auto verifier_result = Ed25519VerifyBoringSsl::New(key->public_key);
82   ASSERT_TRUE(verifier_result.ok()) << verifier_result.status();
83   auto verifier = std::move(verifier_result.value());
84 
85   // Sign a message.
86   std::string message = "some data to be signed";
87   std::string signature = signer->Sign(message).value();
88   EXPECT_NE(signature, message);
89   EXPECT_EQ(signature.size(), kEd25519SignatureLenInBytes);
90   auto status = verifier->Verify(signature, message);
91   EXPECT_TRUE(status.ok()) << status;
92 
93   status = verifier->Verify("some bad signature", message);
94   EXPECT_FALSE(status.ok());
95 
96   status = verifier->Verify(signature, "some bad message");
97   EXPECT_FALSE(status.ok());
98 
99   // Loop 100 times, sign a random message twice using the signer and verify
100   // that the signatures are the same.
101   for (size_t i = 0; i < 100; i++) {
102     message = subtle::Random::GetRandomBytes(i);
103     std::string signature1 = signer->Sign(message).value();
104     std::string signature2 = signer->Sign(message).value();
105     EXPECT_EQ(signature1, signature2);
106     // Verify that the signatures are valid.
107     status = verifier->Verify(signature1, message);
108     EXPECT_TRUE(status.ok()) << status;
109   }
110 }
111 
TEST_F(Ed25519SignBoringSslTest,testInvalidPrivateKeys)112 TEST_F(Ed25519SignBoringSslTest, testInvalidPrivateKeys) {
113   if (IsFipsModeEnabled()) {
114     GTEST_SKIP() << "Test assumes kOnlyUseFips is false.";
115   }
116 
117   for (int keysize = 0; keysize < 128; keysize++) {
118     // Ed25519SignBoringSsl::New expects a private key: private part || public
119     // part.
120     if (keysize ==
121         internal::Ed25519KeyPrivKeySize() + internal::Ed25519KeyPubKeySize()) {
122       // Valid key size.
123       continue;
124     }
125     util::SecretData key(keysize, 'x');
126     EXPECT_FALSE(Ed25519SignBoringSsl::New(key).ok());
127   }
128 }
129 
TEST_F(Ed25519SignBoringSslTest,testMessageEmptyVersusNullStringView)130 TEST_F(Ed25519SignBoringSslTest, testMessageEmptyVersusNullStringView) {
131   if (IsFipsModeEnabled()) {
132     GTEST_SKIP() << "Test assumes kOnlyUseFips is false.";
133   }
134 
135   // Generate a new key pair.
136   util::StatusOr<Ed25519KeyPair> key = NewKeyPair();
137   ASSERT_THAT(key, IsOk());
138 
139   // Create a new signer.
140   auto signer_result = Ed25519SignBoringSsl::New(key->private_key);
141   ASSERT_TRUE(signer_result.ok()) << signer_result.status();
142   auto signer = std::move(signer_result.value());
143 
144   // Create a new verifier.
145   auto verifier_result = Ed25519VerifyBoringSsl::New(key->public_key);
146   ASSERT_TRUE(verifier_result.ok()) << verifier_result.status();
147   auto verifier = std::move(verifier_result.value());
148 
149   // Message is a null string_view.
150   const absl::string_view empty_message;
151   auto signature = signer->Sign(empty_message).value();
152   EXPECT_NE(signature, empty_message);
153   EXPECT_EQ(signature.size(), kEd25519SignatureLenInBytes);
154   auto status = verifier->Verify(signature, empty_message);
155   EXPECT_TRUE(status.ok()) << status;
156 
157   // Message is an empty string.
158   const std::string message = "";
159   signature = signer->Sign(message).value();
160   EXPECT_EQ(signature.size(), kEd25519SignatureLenInBytes);
161   EXPECT_NE(signature, message);
162   status = verifier->Verify(signature, message);
163   EXPECT_TRUE(status.ok()) << status;
164 
165   // Message is a default constructed string_view.
166   signature = signer->Sign(absl::string_view()).value();
167   EXPECT_EQ(signature.size(), kEd25519SignatureLenInBytes);
168   status = verifier->Verify(signature, absl::string_view());
169   EXPECT_TRUE(status.ok()) << status;
170 }
171 
172 struct TestVector {
173   std::string public_key;
174   std::string private_key;
175   std::string expected_signature;
176   std::string message;
177 };
178 
TEST_F(Ed25519SignBoringSslTest,testWithTestVectors)179 TEST_F(Ed25519SignBoringSslTest, testWithTestVectors) {
180   if (IsFipsModeEnabled()) {
181     GTEST_SKIP() << "Test assumes kOnlyUseFips is false.";
182   }
183 
184   // These test vectors are taken from:
185   // https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-02#section-6.
186   TestVector ed25519_vectors[] = {
187       {
188           /*TEST 1*/
189           /*public_key= */ absl::HexStringToBytes(
190               "d75a980182b10ab7d54bfed3c964073a"
191               "0ee172f3daa62325af021a68f707511a"),
192           /*private_key=*/
193           absl::HexStringToBytes("9d61b19deffd5a60ba844af492ec2cc4"
194                                  "4449c5697b326919703bac031cae7f60"),
195           /*signature = */
196           absl::HexStringToBytes("e5564300c360ac729086e2cc806e828a"
197                                  "84877f1eb8e5d974d873e06522490155"
198                                  "5fb8821590a33bacc61e39701cf9b46b"
199                                  "d25bf5f0595bbe24655141438e7a100b"),
200           /*message = */ "",
201       },
202       {
203           /*TEST 2*/
204           /*public_key= */ absl::HexStringToBytes(
205               "3d4017c3e843895a92b70aa74d1b7ebc"
206               "9c982ccf2ec4968cc0cd55f12af4660c"),
207           /*private_key=*/
208           absl::HexStringToBytes("4ccd089b28ff96da9db6c346ec114e0f"
209                                  "5b8a319f35aba624da8cf6ed4fb8a6fb"),
210           /*signature = */
211           absl::HexStringToBytes("92a009a9f0d4cab8720e820b5f642540"
212                                  "a2b27b5416503f8fb3762223ebdb69da"
213                                  "085ac1e43e15996e458f3613d0f11d8c"
214                                  "387b2eaeb4302aeeb00d291612bb0c00"),
215           /*message = */ "\x72",
216       },
217       {
218           /*TEST 3*/
219           /*public_key= */ absl::HexStringToBytes(
220               "fc51cd8e6218a1a38da47ed00230f058"
221               "0816ed13ba3303ac5deb911548908025"),
222           /*private_key=*/
223           absl::HexStringToBytes("c5aa8df43f9f837bedb7442f31dcb7b1"
224                                  "66d38535076f094b85ce3a2e0b4458f7"),
225           /*signature = */
226           absl::HexStringToBytes("6291d657deec24024827e69c3abe01a3"
227                                  "0ce548a284743a445e3680d7db5ac3ac"
228                                  "18ff9b538d16f290ae67f760984dc659"
229                                  "4a7c15e9716ed28dc027beceea1ec40a"),
230           /*message = */ "\xaf\x82",
231       },
232       {
233           /*TEST 1024*/
234           /*public_key= */ absl::HexStringToBytes(
235               "278117fc144c72340f67d0f2316e8386"
236               "ceffbf2b2428c9c51fef7c597f1d426e"),
237           /*private_key=*/
238           absl::HexStringToBytes("f5e5767cf153319517630f226876b86c"
239                                  "8160cc583bc013744c6bf255f5cc0ee5"),
240           /*signature = */
241           absl::HexStringToBytes("0aab4c900501b3e24d7cdf4663326a3a"
242                                  "87df5e4843b2cbdb67cbf6e460fec350"
243                                  "aa5371b1508f9f4528ecea23c436d94b"
244                                  "5e8fcd4f681e30a6ac00a9704a188a03"),
245           /*message = */
246           absl::HexStringToBytes("08b8b2b733424243760fe426a4b54908"
247                                  "632110a66c2f6591eabd3345e3e4eb98"
248                                  "fa6e264bf09efe12ee50f8f54e9f77b1"
249                                  "e355f6c50544e23fb1433ddf73be84d8"
250                                  "79de7c0046dc4996d9e773f4bc9efe57"
251                                  "38829adb26c81b37c93a1b270b20329d"
252                                  "658675fc6ea534e0810a4432826bf58c"
253                                  "941efb65d57a338bbd2e26640f89ffbc"
254                                  "1a858efcb8550ee3a5e1998bd177e93a"
255                                  "7363c344fe6b199ee5d02e82d522c4fe"
256                                  "ba15452f80288a821a579116ec6dad2b"
257                                  "3b310da903401aa62100ab5d1a36553e"
258                                  "06203b33890cc9b832f79ef80560ccb9"
259                                  "a39ce767967ed628c6ad573cb116dbef"
260                                  "efd75499da96bd68a8a97b928a8bbc10"
261                                  "3b6621fcde2beca1231d206be6cd9ec7"
262                                  "aff6f6c94fcd7204ed3455c68c83f4a4"
263                                  "1da4af2b74ef5c53f1d8ac70bdcb7ed1"
264                                  "85ce81bd84359d44254d95629e9855a9"
265                                  "4a7c1958d1f8ada5d0532ed8a5aa3fb2"
266                                  "d17ba70eb6248e594e1a2297acbbb39d"
267                                  "502f1a8c6eb6f1ce22b3de1a1f40cc24"
268                                  "554119a831a9aad6079cad88425de6bd"
269                                  "e1a9187ebb6092cf67bf2b13fd65f270"
270                                  "88d78b7e883c8759d2c4f5c65adb7553"
271                                  "878ad575f9fad878e80a0c9ba63bcbcc"
272                                  "2732e69485bbc9c90bfbd62481d9089b"
273                                  "eccf80cfe2df16a2cf65bd92dd597b07"
274                                  "07e0917af48bbb75fed413d238f5555a"
275                                  "7a569d80c3414a8d0859dc65a46128ba"
276                                  "b27af87a71314f318c782b23ebfe808b"
277                                  "82b0ce26401d2e22f04d83d1255dc51a"
278                                  "ddd3b75a2b1ae0784504df543af8969b"
279                                  "e3ea7082ff7fc9888c144da2af58429e"
280                                  "c96031dbcad3dad9af0dcbaaaf268cb8"
281                                  "fcffead94f3c7ca495e056a9b47acdb7"
282                                  "51fb73e666c6c655ade8297297d07ad1"
283                                  "ba5e43f1bca32301651339e22904cc8c"
284                                  "42f58c30c04aafdb038dda0847dd988d"
285                                  "cda6f3bfd15c4b4c4525004aa06eeff8"
286                                  "ca61783aacec57fb3d1f92b0fe2fd1a8"
287                                  "5f6724517b65e614ad6808d6f6ee34df"
288                                  "f7310fdc82aebfd904b01e1dc54b2927"
289                                  "094b2db68d6f903b68401adebf5a7e08"
290                                  "d78ff4ef5d63653a65040cf9bfd4aca7"
291                                  "984a74d37145986780fc0b16ac451649"
292                                  "de6188a7dbdf191f64b5fc5e2ab47b57"
293                                  "f7f7276cd419c17a3ca8e1b939ae49e4"
294                                  "88acba6b965610b5480109c8b17b80e1"
295                                  "b7b750dfc7598d5d5011fd2dcc5600a3"
296                                  "2ef5b52a1ecc820e308aa342721aac09"
297                                  "43bf6686b64b2579376504ccc493d97e"
298                                  "6aed3fb0f9cd71a43dd497f01f17c0e2"
299                                  "cb3797aa2a2f256656168e6c496afc5f"
300                                  "b93246f6b1116398a346f1a641f3b041"
301                                  "e989f7914f90cc2c7fff357876e506b5"
302                                  "0d334ba77c225bc307ba537152f3f161"
303                                  "0e4eafe595f6d9d90d11faa933a15ef1"
304                                  "369546868a7f3a45a96768d40fd9d034"
305                                  "12c091c6315cf4fde7cb68606937380d"
306                                  "b2eaaa707b4c4185c32eddcdd306705e"
307                                  "4dc1ffc872eeee475a64dfac86aba41c"
308                                  "0618983f8741c5ef68d3a101e8a3b8ca"
309                                  "c60c905c15fc910840b94c00a0b9d0"),
310       },
311   };
312 
313   for (const TestVector &v : ed25519_vectors) {
314     // Add the public as a suffix to the private key. This is needed by the
315     // boringssl API.
316     util::SecretData private_key = util::SecretDataFromStringView(
317         absl::StrCat(v.private_key, v.public_key));
318 
319     // Create a new signer.
320     auto signer_result = Ed25519SignBoringSsl::New(private_key);
321     ASSERT_TRUE(signer_result.ok()) << signer_result.status();
322     auto signer = std::move(signer_result.value());
323 
324     // Create a new verifier.
325     auto verifier_result = Ed25519VerifyBoringSsl::New(v.public_key);
326     ASSERT_TRUE(verifier_result.ok()) << verifier_result.status();
327     auto verifier = std::move(verifier_result.value());
328 
329     std::string signature = signer->Sign(v.message).value();
330     EXPECT_TRUE(signature == v.expected_signature);
331 
332     auto status = verifier->Verify(signature, v.message);
333     EXPECT_TRUE(status.ok()) << status;
334   }
335 }
336 
TEST_F(Ed25519SignBoringSslTest,testFipsMode)337 TEST_F(Ed25519SignBoringSslTest, testFipsMode) {
338   if (!IsFipsModeEnabled()) {
339     GTEST_SKIP() << "Test assumes kOnlyUseFips.";
340   }
341 
342   // Generate a new key pair.
343   util::StatusOr<Ed25519KeyPair> key = NewKeyPair();
344   ASSERT_THAT(key, IsOk());
345 
346   // Create a new signer.
347   EXPECT_THAT(Ed25519SignBoringSsl::New(key->private_key).status(),
348               StatusIs(absl::StatusCode::kInternal));
349 }
350 
351 }  // namespace
352 }  // namespace subtle
353 }  // namespace tink
354 }  // namespace crypto
355