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