1 /*
2 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project.
4 */
5 /* ====================================================================
6 * Copyright (c) 2015 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 */
53
54 #include <openssl/evp.h>
55
56 #include <stdio.h>
57 #include <stdint.h>
58 #include <stdlib.h>
59 #include <string.h>
60
61 OPENSSL_MSVC_PRAGMA(warning(push))
62 OPENSSL_MSVC_PRAGMA(warning(disable: 4702))
63
64 #include <map>
65 #include <string>
66 #include <utility>
67 #include <vector>
68
OPENSSL_MSVC_PRAGMA(warning (pop)) const69 OPENSSL_MSVC_PRAGMA(warning(pop))
70
71 #include <gtest/gtest.h>
72
73 #include <openssl/bytestring.h>
74 #include <openssl/crypto.h>
75 #include <openssl/digest.h>
76 #include <openssl/dsa.h>
77 #include <openssl/err.h>
78 #include <openssl/rsa.h>
79
80 #include "../test/file_test.h"
81 #include "../test/test_util.h"
82 #include "../test/wycheproof_util.h"
83
84
85 // evp_test dispatches between multiple test types. PrivateKey tests take a key
86 // name parameter and single block, decode it as a PEM private key, and save it
87 // under that key name. Decrypt, Sign, and Verify tests take a previously
88 // imported key name as parameter and test their respective operations.
89
90 static const EVP_MD *GetDigest(FileTest *t, const std::string &name) {
91 if (name == "MD5") {
92 return EVP_md5();
93 } else if (name == "SHA1") {
94 return EVP_sha1();
95 } else if (name == "SHA224") {
96 return EVP_sha224();
97 } else if (name == "SHA256") {
98 return EVP_sha256();
99 } else if (name == "SHA384") {
100 return EVP_sha384();
101 } else if (name == "SHA512") {
102 return EVP_sha512();
103 }
104 ADD_FAILURE() << "Unknown digest: " << name;
105 return nullptr;
106 }
107
GetKeyType(FileTest * t,const std::string & name)108 static int GetKeyType(FileTest *t, const std::string &name) {
109 if (name == "RSA") {
110 return EVP_PKEY_RSA;
111 }
112 if (name == "EC") {
113 return EVP_PKEY_EC;
114 }
115 if (name == "DSA") {
116 return EVP_PKEY_DSA;
117 }
118 if (name == "Ed25519") {
119 return EVP_PKEY_ED25519;
120 }
121 if (name == "X25519") {
122 return EVP_PKEY_X25519;
123 }
124 ADD_FAILURE() << "Unknown key type: " << name;
125 return EVP_PKEY_NONE;
126 }
127
GetRSAPadding(FileTest * t,int * out,const std::string & name)128 static bool GetRSAPadding(FileTest *t, int *out, const std::string &name) {
129 if (name == "PKCS1") {
130 *out = RSA_PKCS1_PADDING;
131 return true;
132 }
133 if (name == "PSS") {
134 *out = RSA_PKCS1_PSS_PADDING;
135 return true;
136 }
137 if (name == "OAEP") {
138 *out = RSA_PKCS1_OAEP_PADDING;
139 return true;
140 }
141 if (name == "None") {
142 *out = RSA_NO_PADDING;
143 return true;
144 }
145 ADD_FAILURE() << "Unknown RSA padding mode: " << name;
146 return false;
147 }
148
149 using KeyMap = std::map<std::string, bssl::UniquePtr<EVP_PKEY>>;
150
ImportKey(FileTest * t,KeyMap * key_map,EVP_PKEY * (* parse_func)(CBS * cbs),int (* marshal_func)(CBB * cbb,const EVP_PKEY * key))151 static bool ImportKey(FileTest *t, KeyMap *key_map,
152 EVP_PKEY *(*parse_func)(CBS *cbs),
153 int (*marshal_func)(CBB *cbb, const EVP_PKEY *key)) {
154 std::vector<uint8_t> input;
155 if (!t->GetBytes(&input, "Input")) {
156 return false;
157 }
158
159 CBS cbs;
160 CBS_init(&cbs, input.data(), input.size());
161 bssl::UniquePtr<EVP_PKEY> pkey(parse_func(&cbs));
162 if (!pkey) {
163 return false;
164 }
165
166 std::string key_type;
167 if (!t->GetAttribute(&key_type, "Type")) {
168 return false;
169 }
170 EXPECT_EQ(GetKeyType(t, key_type), EVP_PKEY_id(pkey.get()));
171
172 // The key must re-encode correctly.
173 bssl::ScopedCBB cbb;
174 uint8_t *der;
175 size_t der_len;
176 if (!CBB_init(cbb.get(), 0) ||
177 !marshal_func(cbb.get(), pkey.get()) ||
178 !CBB_finish(cbb.get(), &der, &der_len)) {
179 return false;
180 }
181 bssl::UniquePtr<uint8_t> free_der(der);
182
183 std::vector<uint8_t> output = input;
184 if (t->HasAttribute("Output") &&
185 !t->GetBytes(&output, "Output")) {
186 return false;
187 }
188 EXPECT_EQ(Bytes(output), Bytes(der, der_len))
189 << "Re-encoding the key did not match.";
190
191 if (t->HasAttribute("ExpectNoRawPrivate")) {
192 size_t len;
193 EXPECT_FALSE(EVP_PKEY_get_raw_private_key(pkey.get(), nullptr, &len));
194 } else if (t->HasAttribute("ExpectRawPrivate")) {
195 std::vector<uint8_t> expected;
196 if (!t->GetBytes(&expected, "ExpectRawPrivate")) {
197 return false;
198 }
199
200 std::vector<uint8_t> raw;
201 size_t len;
202 if (!EVP_PKEY_get_raw_private_key(pkey.get(), nullptr, &len)) {
203 return false;
204 }
205 raw.resize(len);
206 if (!EVP_PKEY_get_raw_private_key(pkey.get(), raw.data(), &len)) {
207 return false;
208 }
209 raw.resize(len);
210 EXPECT_EQ(Bytes(raw), Bytes(expected));
211
212 // Short buffers should be rejected.
213 raw.resize(len - 1);
214 len = raw.size();
215 EXPECT_FALSE(EVP_PKEY_get_raw_private_key(pkey.get(), raw.data(), &len));
216 }
217
218 if (t->HasAttribute("ExpectNoRawPublic")) {
219 size_t len;
220 EXPECT_FALSE(EVP_PKEY_get_raw_public_key(pkey.get(), nullptr, &len));
221 } else if (t->HasAttribute("ExpectRawPublic")) {
222 std::vector<uint8_t> expected;
223 if (!t->GetBytes(&expected, "ExpectRawPublic")) {
224 return false;
225 }
226
227 std::vector<uint8_t> raw;
228 size_t len;
229 if (!EVP_PKEY_get_raw_public_key(pkey.get(), nullptr, &len)) {
230 return false;
231 }
232 raw.resize(len);
233 if (!EVP_PKEY_get_raw_public_key(pkey.get(), raw.data(), &len)) {
234 return false;
235 }
236 raw.resize(len);
237 EXPECT_EQ(Bytes(raw), Bytes(expected));
238
239 // Short buffers should be rejected.
240 raw.resize(len - 1);
241 len = raw.size();
242 EXPECT_FALSE(EVP_PKEY_get_raw_public_key(pkey.get(), raw.data(), &len));
243 }
244
245 // Save the key for future tests.
246 const std::string &key_name = t->GetParameter();
247 EXPECT_EQ(0u, key_map->count(key_name)) << "Duplicate key: " << key_name;
248 (*key_map)[key_name] = std::move(pkey);
249 return true;
250 }
251
252 // SetupContext configures |ctx| based on attributes in |t|, with the exception
253 // of the signing digest which must be configured externally.
SetupContext(FileTest * t,KeyMap * key_map,EVP_PKEY_CTX * ctx)254 static bool SetupContext(FileTest *t, KeyMap *key_map, EVP_PKEY_CTX *ctx) {
255 if (t->HasAttribute("RSAPadding")) {
256 int padding;
257 if (!GetRSAPadding(t, &padding, t->GetAttributeOrDie("RSAPadding")) ||
258 !EVP_PKEY_CTX_set_rsa_padding(ctx, padding)) {
259 return false;
260 }
261 }
262 if (t->HasAttribute("PSSSaltLength") &&
263 !EVP_PKEY_CTX_set_rsa_pss_saltlen(
264 ctx, atoi(t->GetAttributeOrDie("PSSSaltLength").c_str()))) {
265 return false;
266 }
267 if (t->HasAttribute("MGF1Digest")) {
268 const EVP_MD *digest = GetDigest(t, t->GetAttributeOrDie("MGF1Digest"));
269 if (digest == nullptr || !EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, digest)) {
270 return false;
271 }
272 }
273 if (t->HasAttribute("OAEPDigest")) {
274 const EVP_MD *digest = GetDigest(t, t->GetAttributeOrDie("OAEPDigest"));
275 if (digest == nullptr || !EVP_PKEY_CTX_set_rsa_oaep_md(ctx, digest)) {
276 return false;
277 }
278 }
279 if (t->HasAttribute("OAEPLabel")) {
280 std::vector<uint8_t> label;
281 if (!t->GetBytes(&label, "OAEPLabel")) {
282 return false;
283 }
284 // For historical reasons, |EVP_PKEY_CTX_set0_rsa_oaep_label| expects to be
285 // take ownership of the input.
286 bssl::UniquePtr<uint8_t> buf(reinterpret_cast<uint8_t *>(
287 OPENSSL_memdup(label.data(), label.size())));
288 if (!buf ||
289 !EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, buf.get(), label.size())) {
290 return false;
291 }
292 buf.release();
293 }
294 if (t->HasAttribute("DerivePeer")) {
295 std::string derive_peer = t->GetAttributeOrDie("DerivePeer");
296 if (key_map->count(derive_peer) == 0) {
297 ADD_FAILURE() << "Could not find key " << derive_peer;
298 return false;
299 }
300 EVP_PKEY *derive_peer_key = (*key_map)[derive_peer].get();
301 if (!EVP_PKEY_derive_set_peer(ctx, derive_peer_key)) {
302 return false;
303 }
304 }
305 return true;
306 }
307
TestDerive(FileTest * t,KeyMap * key_map,EVP_PKEY * key)308 static bool TestDerive(FileTest *t, KeyMap *key_map, EVP_PKEY *key) {
309 bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(key, nullptr));
310 if (!ctx ||
311 !EVP_PKEY_derive_init(ctx.get()) ||
312 !SetupContext(t, key_map, ctx.get())) {
313 return false;
314 }
315
316 bssl::UniquePtr<EVP_PKEY_CTX> copy(EVP_PKEY_CTX_dup(ctx.get()));
317 if (!copy) {
318 return false;
319 }
320
321 for (EVP_PKEY_CTX *pctx : {ctx.get(), copy.get()}) {
322 size_t len;
323 std::vector<uint8_t> actual, output;
324 if (!EVP_PKEY_derive(pctx, nullptr, &len)) {
325 return false;
326 }
327 actual.resize(len);
328 if (!EVP_PKEY_derive(pctx, actual.data(), &len)) {
329 return false;
330 }
331 actual.resize(len);
332
333 // Defer looking up the attribute so Error works properly.
334 if (!t->GetBytes(&output, "Output")) {
335 return false;
336 }
337 EXPECT_EQ(Bytes(output), Bytes(actual));
338
339 // Test when the buffer is too large.
340 actual.resize(len + 1);
341 len = actual.size();
342 if (!EVP_PKEY_derive(pctx, actual.data(), &len)) {
343 return false;
344 }
345 actual.resize(len);
346 EXPECT_EQ(Bytes(output), Bytes(actual));
347
348 // Test when the buffer is too small.
349 actual.resize(len - 1);
350 len = actual.size();
351 if (t->HasAttribute("SmallBufferTruncates")) {
352 if (!EVP_PKEY_derive(pctx, actual.data(), &len)) {
353 return false;
354 }
355 actual.resize(len);
356 EXPECT_EQ(Bytes(output.data(), len), Bytes(actual));
357 } else {
358 EXPECT_FALSE(EVP_PKEY_derive(pctx, actual.data(), &len));
359 ERR_clear_error();
360 }
361 }
362 return true;
363 }
364
TestEVP(FileTest * t,KeyMap * key_map)365 static bool TestEVP(FileTest *t, KeyMap *key_map) {
366 if (t->GetType() == "PrivateKey") {
367 return ImportKey(t, key_map, EVP_parse_private_key,
368 EVP_marshal_private_key);
369 }
370
371 if (t->GetType() == "PublicKey") {
372 return ImportKey(t, key_map, EVP_parse_public_key, EVP_marshal_public_key);
373 }
374
375 // Load the key.
376 const std::string &key_name = t->GetParameter();
377 if (key_map->count(key_name) == 0) {
378 ADD_FAILURE() << "Could not find key " << key_name;
379 return false;
380 }
381 EVP_PKEY *key = (*key_map)[key_name].get();
382
383 int (*key_op_init)(EVP_PKEY_CTX *ctx) = nullptr;
384 int (*key_op)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len,
385 const uint8_t *in, size_t in_len) = nullptr;
386 int (*md_op_init)(EVP_MD_CTX * ctx, EVP_PKEY_CTX * *pctx, const EVP_MD *type,
387 ENGINE *e, EVP_PKEY *pkey) = nullptr;
388 bool is_verify = false;
389 if (t->GetType() == "Decrypt") {
390 key_op_init = EVP_PKEY_decrypt_init;
391 key_op = EVP_PKEY_decrypt;
392 } else if (t->GetType() == "Sign") {
393 key_op_init = EVP_PKEY_sign_init;
394 key_op = EVP_PKEY_sign;
395 } else if (t->GetType() == "Verify") {
396 key_op_init = EVP_PKEY_verify_init;
397 is_verify = true;
398 } else if (t->GetType() == "SignMessage") {
399 md_op_init = EVP_DigestSignInit;
400 } else if (t->GetType() == "VerifyMessage") {
401 md_op_init = EVP_DigestVerifyInit;
402 is_verify = true;
403 } else if (t->GetType() == "Encrypt") {
404 key_op_init = EVP_PKEY_encrypt_init;
405 key_op = EVP_PKEY_encrypt;
406 } else if (t->GetType() == "Derive") {
407 return TestDerive(t, key_map, key);
408 } else {
409 ADD_FAILURE() << "Unknown test " << t->GetType();
410 return false;
411 }
412
413 const EVP_MD *digest = nullptr;
414 if (t->HasAttribute("Digest")) {
415 digest = GetDigest(t, t->GetAttributeOrDie("Digest"));
416 if (digest == nullptr) {
417 return false;
418 }
419 }
420
421 // For verify tests, the "output" is the signature. Read it now so that, for
422 // tests which expect a failure in SetupContext, the attribute is still
423 // consumed.
424 std::vector<uint8_t> input, actual, output;
425 if (!t->GetBytes(&input, "Input") ||
426 (is_verify && !t->GetBytes(&output, "Output"))) {
427 return false;
428 }
429
430 if (md_op_init) {
431 bssl::ScopedEVP_MD_CTX ctx, copy;
432 EVP_PKEY_CTX *pctx;
433 if (!md_op_init(ctx.get(), &pctx, digest, nullptr, key) ||
434 !SetupContext(t, key_map, pctx) ||
435 !EVP_MD_CTX_copy_ex(copy.get(), ctx.get())) {
436 return false;
437 }
438
439 if (is_verify) {
440 return EVP_DigestVerify(ctx.get(), output.data(), output.size(),
441 input.data(), input.size()) &&
442 EVP_DigestVerify(copy.get(), output.data(), output.size(),
443 input.data(), input.size());
444 }
445
446 size_t len;
447 if (!EVP_DigestSign(ctx.get(), nullptr, &len, input.data(), input.size())) {
448 return false;
449 }
450 actual.resize(len);
451 if (!EVP_DigestSign(ctx.get(), actual.data(), &len, input.data(),
452 input.size()) ||
453 !t->GetBytes(&output, "Output")) {
454 return false;
455 }
456 actual.resize(len);
457 EXPECT_EQ(Bytes(output), Bytes(actual));
458
459 // Repeat the test with |copy|, to check |EVP_MD_CTX_copy_ex| duplicated
460 // everything.
461 if (!EVP_DigestSign(copy.get(), nullptr, &len, input.data(),
462 input.size())) {
463 return false;
464 }
465 actual.resize(len);
466 if (!EVP_DigestSign(copy.get(), actual.data(), &len, input.data(),
467 input.size()) ||
468 !t->GetBytes(&output, "Output")) {
469 return false;
470 }
471 actual.resize(len);
472 EXPECT_EQ(Bytes(output), Bytes(actual));
473 return true;
474 }
475
476 bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(key, nullptr));
477 if (!ctx ||
478 !key_op_init(ctx.get()) ||
479 (digest != nullptr &&
480 !EVP_PKEY_CTX_set_signature_md(ctx.get(), digest)) ||
481 !SetupContext(t, key_map, ctx.get())) {
482 return false;
483 }
484
485 bssl::UniquePtr<EVP_PKEY_CTX> copy(EVP_PKEY_CTX_dup(ctx.get()));
486 if (!copy) {
487 return false;
488 }
489
490 if (is_verify) {
491 return EVP_PKEY_verify(ctx.get(), output.data(), output.size(),
492 input.data(), input.size()) &&
493 EVP_PKEY_verify(copy.get(), output.data(), output.size(),
494 input.data(), input.size());
495 }
496
497 for (EVP_PKEY_CTX *pctx : {ctx.get(), copy.get()}) {
498 size_t len;
499 if (!key_op(pctx, nullptr, &len, input.data(), input.size())) {
500 return false;
501 }
502 actual.resize(len);
503 if (!key_op(pctx, actual.data(), &len, input.data(), input.size())) {
504 return false;
505 }
506
507 if (t->HasAttribute("CheckDecrypt")) {
508 // Encryption is non-deterministic, so we check by decrypting.
509 size_t plaintext_len;
510 bssl::UniquePtr<EVP_PKEY_CTX> decrypt_ctx(EVP_PKEY_CTX_new(key, nullptr));
511 if (!decrypt_ctx ||
512 !EVP_PKEY_decrypt_init(decrypt_ctx.get()) ||
513 (digest != nullptr &&
514 !EVP_PKEY_CTX_set_signature_md(decrypt_ctx.get(), digest)) ||
515 !SetupContext(t, key_map, decrypt_ctx.get()) ||
516 !EVP_PKEY_decrypt(decrypt_ctx.get(), nullptr, &plaintext_len,
517 actual.data(), actual.size())) {
518 return false;
519 }
520 output.resize(plaintext_len);
521 if (!EVP_PKEY_decrypt(decrypt_ctx.get(), output.data(), &plaintext_len,
522 actual.data(), actual.size())) {
523 ADD_FAILURE() << "Could not decrypt result.";
524 return false;
525 }
526 output.resize(plaintext_len);
527 EXPECT_EQ(Bytes(input), Bytes(output)) << "Decrypted result mismatch.";
528 } else if (t->HasAttribute("CheckVerify")) {
529 // Some signature schemes are non-deterministic, so we check by verifying.
530 bssl::UniquePtr<EVP_PKEY_CTX> verify_ctx(EVP_PKEY_CTX_new(key, nullptr));
531 if (!verify_ctx ||
532 !EVP_PKEY_verify_init(verify_ctx.get()) ||
533 (digest != nullptr &&
534 !EVP_PKEY_CTX_set_signature_md(verify_ctx.get(), digest)) ||
535 !SetupContext(t, key_map, verify_ctx.get())) {
536 return false;
537 }
538 if (t->HasAttribute("VerifyPSSSaltLength")) {
539 if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(
540 verify_ctx.get(),
541 atoi(t->GetAttributeOrDie("VerifyPSSSaltLength").c_str()))) {
542 return false;
543 }
544 }
545 EXPECT_TRUE(EVP_PKEY_verify(verify_ctx.get(), actual.data(),
546 actual.size(), input.data(), input.size()))
547 << "Could not verify result.";
548 } else {
549 // By default, check by comparing the result against Output.
550 if (!t->GetBytes(&output, "Output")) {
551 return false;
552 }
553 actual.resize(len);
554 EXPECT_EQ(Bytes(output), Bytes(actual));
555 }
556 }
557 return true;
558 }
559
TEST(EVPTest,TestVectors)560 TEST(EVPTest, TestVectors) {
561 KeyMap key_map;
562 FileTestGTest("crypto/evp/evp_tests.txt", [&](FileTest *t) {
563 bool result = TestEVP(t, &key_map);
564 if (t->HasAttribute("Error")) {
565 ASSERT_FALSE(result) << "Operation unexpectedly succeeded.";
566 uint32_t err = ERR_peek_error();
567 EXPECT_EQ(t->GetAttributeOrDie("Error"), ERR_reason_error_string(err));
568 } else if (!result) {
569 ADD_FAILURE() << "Operation unexpectedly failed.";
570 }
571 });
572 }
573
RunWycheproofVerifyTest(const char * path)574 static void RunWycheproofVerifyTest(const char *path) {
575 SCOPED_TRACE(path);
576 FileTestGTest(path, [](FileTest *t) {
577 t->IgnoreAllUnusedInstructions();
578
579 std::vector<uint8_t> der;
580 ASSERT_TRUE(t->GetInstructionBytes(&der, "keyDer"));
581 CBS cbs;
582 CBS_init(&cbs, der.data(), der.size());
583 bssl::UniquePtr<EVP_PKEY> key(EVP_parse_public_key(&cbs));
584 ASSERT_TRUE(key);
585
586 const EVP_MD *md = nullptr;
587 if (t->HasInstruction("sha")) {
588 md = GetWycheproofDigest(t, "sha", true);
589 ASSERT_TRUE(md);
590 }
591
592 bool is_pss = t->HasInstruction("mgf");
593 const EVP_MD *mgf1_md = nullptr;
594 int pss_salt_len = -1;
595 if (is_pss) {
596 ASSERT_EQ("MGF1", t->GetInstructionOrDie("mgf"));
597 mgf1_md = GetWycheproofDigest(t, "mgfSha", true);
598
599 std::string s_len;
600 ASSERT_TRUE(t->GetInstruction(&s_len, "sLen"));
601 pss_salt_len = atoi(s_len.c_str());
602 }
603
604 std::vector<uint8_t> msg;
605 ASSERT_TRUE(t->GetBytes(&msg, "msg"));
606 std::vector<uint8_t> sig;
607 ASSERT_TRUE(t->GetBytes(&sig, "sig"));
608 WycheproofResult result;
609 ASSERT_TRUE(GetWycheproofResult(t, &result));
610
611 if (EVP_PKEY_id(key.get()) == EVP_PKEY_DSA) {
612 // DSA is deprecated and is not usable via EVP.
613 DSA *dsa = EVP_PKEY_get0_DSA(key.get());
614 uint8_t digest[EVP_MAX_MD_SIZE];
615 unsigned digest_len;
616 ASSERT_TRUE(
617 EVP_Digest(msg.data(), msg.size(), digest, &digest_len, md, nullptr));
618 int valid;
619 bool sig_ok = DSA_check_signature(&valid, digest, digest_len, sig.data(),
620 sig.size(), dsa) &&
621 valid;
622 EXPECT_EQ(sig_ok, result.IsValid());
623 } else {
624 bssl::ScopedEVP_MD_CTX ctx;
625 EVP_PKEY_CTX *pctx;
626 ASSERT_TRUE(
627 EVP_DigestVerifyInit(ctx.get(), &pctx, md, nullptr, key.get()));
628 if (is_pss) {
629 ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING));
630 ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1_md));
631 ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, pss_salt_len));
632 }
633 int ret = EVP_DigestVerify(ctx.get(), sig.data(), sig.size(), msg.data(),
634 msg.size());
635 // BoringSSL does not enforce policies on weak keys and leaves it to the
636 // caller.
637 EXPECT_EQ(ret,
638 result.IsValid({"SmallModulus", "SmallPublicKey", "WeakHash"})
639 ? 1
640 : 0);
641 }
642 });
643 }
644
TEST(EVPTest,WycheproofDSA)645 TEST(EVPTest, WycheproofDSA) {
646 RunWycheproofVerifyTest("third_party/wycheproof_testvectors/dsa_test.txt");
647 }
648
TEST(EVPTest,WycheproofECDSAP224)649 TEST(EVPTest, WycheproofECDSAP224) {
650 RunWycheproofVerifyTest(
651 "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha224_test.txt");
652 RunWycheproofVerifyTest(
653 "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha256_test.txt");
654 RunWycheproofVerifyTest(
655 "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha512_test.txt");
656 }
657
TEST(EVPTest,WycheproofECDSAP256)658 TEST(EVPTest, WycheproofECDSAP256) {
659 RunWycheproofVerifyTest(
660 "third_party/wycheproof_testvectors/ecdsa_secp256r1_sha256_test.txt");
661 RunWycheproofVerifyTest(
662 "third_party/wycheproof_testvectors/ecdsa_secp256r1_sha512_test.txt");
663 }
664
TEST(EVPTest,WycheproofECDSAP384)665 TEST(EVPTest, WycheproofECDSAP384) {
666 RunWycheproofVerifyTest(
667 "third_party/wycheproof_testvectors/ecdsa_secp384r1_sha384_test.txt");
668 }
669
TEST(EVPTest,WycheproofECDSAP521)670 TEST(EVPTest, WycheproofECDSAP521) {
671 RunWycheproofVerifyTest(
672 "third_party/wycheproof_testvectors/ecdsa_secp384r1_sha512_test.txt");
673 RunWycheproofVerifyTest(
674 "third_party/wycheproof_testvectors/ecdsa_secp521r1_sha512_test.txt");
675 }
676
TEST(EVPTest,WycheproofEdDSA)677 TEST(EVPTest, WycheproofEdDSA) {
678 RunWycheproofVerifyTest("third_party/wycheproof_testvectors/eddsa_test.txt");
679 }
680
TEST(EVPTest,WycheproofRSAPKCS1)681 TEST(EVPTest, WycheproofRSAPKCS1) {
682 RunWycheproofVerifyTest(
683 "third_party/wycheproof_testvectors/rsa_signature_2048_sha224_test.txt");
684 RunWycheproofVerifyTest(
685 "third_party/wycheproof_testvectors/rsa_signature_2048_sha256_test.txt");
686 RunWycheproofVerifyTest(
687 "third_party/wycheproof_testvectors/rsa_signature_2048_sha384_test.txt");
688 RunWycheproofVerifyTest(
689 "third_party/wycheproof_testvectors/rsa_signature_2048_sha512_test.txt");
690 RunWycheproofVerifyTest(
691 "third_party/wycheproof_testvectors/rsa_signature_3072_sha256_test.txt");
692 RunWycheproofVerifyTest(
693 "third_party/wycheproof_testvectors/rsa_signature_3072_sha384_test.txt");
694 RunWycheproofVerifyTest(
695 "third_party/wycheproof_testvectors/rsa_signature_3072_sha512_test.txt");
696 RunWycheproofVerifyTest(
697 "third_party/wycheproof_testvectors/rsa_signature_4096_sha384_test.txt");
698 RunWycheproofVerifyTest(
699 "third_party/wycheproof_testvectors/rsa_signature_4096_sha512_test.txt");
700 // TODO(davidben): Is this file redundant with the tests above?
701 RunWycheproofVerifyTest(
702 "third_party/wycheproof_testvectors/rsa_signature_test.txt");
703 }
704
TEST(EVPTest,WycheproofRSAPKCS1Sign)705 TEST(EVPTest, WycheproofRSAPKCS1Sign) {
706 FileTestGTest(
707 "third_party/wycheproof_testvectors/rsa_sig_gen_misc_test.txt",
708 [](FileTest *t) {
709 t->IgnoreAllUnusedInstructions();
710
711 std::vector<uint8_t> pkcs8;
712 ASSERT_TRUE(t->GetInstructionBytes(&pkcs8, "privateKeyPkcs8"));
713 CBS cbs;
714 CBS_init(&cbs, pkcs8.data(), pkcs8.size());
715 bssl::UniquePtr<EVP_PKEY> key(EVP_parse_private_key(&cbs));
716 ASSERT_TRUE(key);
717
718 const EVP_MD *md = GetWycheproofDigest(t, "sha", true);
719 ASSERT_TRUE(md);
720
721 std::vector<uint8_t> msg, sig;
722 ASSERT_TRUE(t->GetBytes(&msg, "msg"));
723 ASSERT_TRUE(t->GetBytes(&sig, "sig"));
724 WycheproofResult result;
725 ASSERT_TRUE(GetWycheproofResult(t, &result));
726
727 bssl::ScopedEVP_MD_CTX ctx;
728 EVP_PKEY_CTX *pctx;
729 ASSERT_TRUE(
730 EVP_DigestSignInit(ctx.get(), &pctx, md, nullptr, key.get()));
731 std::vector<uint8_t> out(EVP_PKEY_size(key.get()));
732 size_t len = out.size();
733 int ret =
734 EVP_DigestSign(ctx.get(), out.data(), &len, msg.data(), msg.size());
735 // BoringSSL does not enforce policies on weak keys and leaves it to the
736 // caller.
737 bool is_valid =
738 result.IsValid({"SmallModulus", "SmallPublicKey", "WeakHash"});
739 EXPECT_EQ(ret, is_valid ? 1 : 0);
740 if (is_valid) {
741 out.resize(len);
742 EXPECT_EQ(Bytes(sig), Bytes(out));
743 }
744 });
745 }
746
TEST(EVPTest,WycheproofRSAPSS)747 TEST(EVPTest, WycheproofRSAPSS) {
748 RunWycheproofVerifyTest(
749 "third_party/wycheproof_testvectors/rsa_pss_2048_sha1_mgf1_20_test.txt");
750 RunWycheproofVerifyTest(
751 "third_party/wycheproof_testvectors/rsa_pss_2048_sha256_mgf1_0_test.txt");
752 RunWycheproofVerifyTest(
753 "third_party/wycheproof_testvectors/"
754 "rsa_pss_2048_sha256_mgf1_32_test.txt");
755 RunWycheproofVerifyTest(
756 "third_party/wycheproof_testvectors/"
757 "rsa_pss_3072_sha256_mgf1_32_test.txt");
758 RunWycheproofVerifyTest(
759 "third_party/wycheproof_testvectors/"
760 "rsa_pss_4096_sha256_mgf1_32_test.txt");
761 RunWycheproofVerifyTest(
762 "third_party/wycheproof_testvectors/"
763 "rsa_pss_4096_sha512_mgf1_32_test.txt");
764 RunWycheproofVerifyTest(
765 "third_party/wycheproof_testvectors/rsa_pss_misc_test.txt");
766 }
767
RunWycheproofDecryptTest(const char * path,std::function<void (FileTest *,EVP_PKEY_CTX *)> setup_cb)768 static void RunWycheproofDecryptTest(
769 const char *path,
770 std::function<void(FileTest *, EVP_PKEY_CTX *)> setup_cb) {
771 FileTestGTest(path, [&](FileTest *t) {
772 t->IgnoreAllUnusedInstructions();
773
774 std::vector<uint8_t> pkcs8;
775 ASSERT_TRUE(t->GetInstructionBytes(&pkcs8, "privateKeyPkcs8"));
776 CBS cbs;
777 CBS_init(&cbs, pkcs8.data(), pkcs8.size());
778 bssl::UniquePtr<EVP_PKEY> key(EVP_parse_private_key(&cbs));
779 ASSERT_TRUE(key);
780
781 std::vector<uint8_t> ct, msg;
782 ASSERT_TRUE(t->GetBytes(&ct, "ct"));
783 ASSERT_TRUE(t->GetBytes(&msg, "msg"));
784 WycheproofResult result;
785 ASSERT_TRUE(GetWycheproofResult(t, &result));
786
787 bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(key.get(), nullptr));
788 ASSERT_TRUE(ctx);
789 ASSERT_TRUE(EVP_PKEY_decrypt_init(ctx.get()));
790 ASSERT_NO_FATAL_FAILURE(setup_cb(t, ctx.get()));
791 std::vector<uint8_t> out(EVP_PKEY_size(key.get()));
792 size_t len = out.size();
793 int ret =
794 EVP_PKEY_decrypt(ctx.get(), out.data(), &len, ct.data(), ct.size());
795 // BoringSSL does not enforce policies on weak keys and leaves it to the
796 // caller.
797 bool is_valid = result.IsValid({"SmallModulus"});
798 EXPECT_EQ(ret, is_valid ? 1 : 0);
799 if (is_valid) {
800 out.resize(len);
801 EXPECT_EQ(Bytes(msg), Bytes(out));
802 }
803 });
804 }
805
RunWycheproofOAEPTest(const char * path)806 static void RunWycheproofOAEPTest(const char *path) {
807 RunWycheproofDecryptTest(path, [](FileTest *t, EVP_PKEY_CTX *ctx) {
808 const EVP_MD *md = GetWycheproofDigest(t, "sha", true);
809 ASSERT_TRUE(md);
810 const EVP_MD *mgf1_md = GetWycheproofDigest(t, "mgfSha", true);
811 ASSERT_TRUE(mgf1_md);
812 std::vector<uint8_t> label;
813 ASSERT_TRUE(t->GetBytes(&label, "label"));
814
815 ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING));
816 ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md));
817 ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1_md));
818 bssl::UniquePtr<uint8_t> label_copy(
819 static_cast<uint8_t *>(OPENSSL_memdup(label.data(), label.size())));
820 ASSERT_TRUE(label_copy || label.empty());
821 ASSERT_TRUE(
822 EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, label_copy.get(), label.size()));
823 // |EVP_PKEY_CTX_set0_rsa_oaep_label| takes ownership on success.
824 label_copy.release();
825 });
826 }
827
TEST(EVPTest,WycheproofRSAOAEP2048)828 TEST(EVPTest, WycheproofRSAOAEP2048) {
829 RunWycheproofOAEPTest(
830 "third_party/wycheproof_testvectors/"
831 "rsa_oaep_2048_sha1_mgf1sha1_test.txt");
832 RunWycheproofOAEPTest(
833 "third_party/wycheproof_testvectors/"
834 "rsa_oaep_2048_sha224_mgf1sha1_test.txt");
835 RunWycheproofOAEPTest(
836 "third_party/wycheproof_testvectors/"
837 "rsa_oaep_2048_sha224_mgf1sha224_test.txt");
838 RunWycheproofOAEPTest(
839 "third_party/wycheproof_testvectors/"
840 "rsa_oaep_2048_sha256_mgf1sha1_test.txt");
841 RunWycheproofOAEPTest(
842 "third_party/wycheproof_testvectors/"
843 "rsa_oaep_2048_sha256_mgf1sha256_test.txt");
844 RunWycheproofOAEPTest(
845 "third_party/wycheproof_testvectors/"
846 "rsa_oaep_2048_sha384_mgf1sha1_test.txt");
847 RunWycheproofOAEPTest(
848 "third_party/wycheproof_testvectors/"
849 "rsa_oaep_2048_sha384_mgf1sha384_test.txt");
850 RunWycheproofOAEPTest(
851 "third_party/wycheproof_testvectors/"
852 "rsa_oaep_2048_sha512_mgf1sha1_test.txt");
853 RunWycheproofOAEPTest(
854 "third_party/wycheproof_testvectors/"
855 "rsa_oaep_2048_sha512_mgf1sha512_test.txt");
856 }
857
TEST(EVPTest,WycheproofRSAOAEP3072)858 TEST(EVPTest, WycheproofRSAOAEP3072) {
859 RunWycheproofOAEPTest(
860 "third_party/wycheproof_testvectors/"
861 "rsa_oaep_3072_sha256_mgf1sha1_test.txt");
862 RunWycheproofOAEPTest(
863 "third_party/wycheproof_testvectors/"
864 "rsa_oaep_3072_sha256_mgf1sha256_test.txt");
865 RunWycheproofOAEPTest(
866 "third_party/wycheproof_testvectors/"
867 "rsa_oaep_3072_sha512_mgf1sha1_test.txt");
868 RunWycheproofOAEPTest(
869 "third_party/wycheproof_testvectors/"
870 "rsa_oaep_3072_sha512_mgf1sha512_test.txt");
871 }
872
TEST(EVPTest,WycheproofRSAOAEP4096)873 TEST(EVPTest, WycheproofRSAOAEP4096) {
874 RunWycheproofOAEPTest(
875 "third_party/wycheproof_testvectors/"
876 "rsa_oaep_4096_sha256_mgf1sha1_test.txt");
877 RunWycheproofOAEPTest(
878 "third_party/wycheproof_testvectors/"
879 "rsa_oaep_4096_sha256_mgf1sha256_test.txt");
880 RunWycheproofOAEPTest(
881 "third_party/wycheproof_testvectors/"
882 "rsa_oaep_4096_sha512_mgf1sha1_test.txt");
883 RunWycheproofOAEPTest(
884 "third_party/wycheproof_testvectors/"
885 "rsa_oaep_4096_sha512_mgf1sha512_test.txt");
886 }
887
TEST(EVPTest,WycheproofRSAOAEPMisc)888 TEST(EVPTest, WycheproofRSAOAEPMisc) {
889 RunWycheproofOAEPTest(
890 "third_party/wycheproof_testvectors/rsa_oaep_misc_test.txt");
891 }
892
RunWycheproofPKCS1DecryptTest(const char * path)893 static void RunWycheproofPKCS1DecryptTest(const char *path) {
894 RunWycheproofDecryptTest(path, [](FileTest *t, EVP_PKEY_CTX *ctx) {
895 // No setup needed. PKCS#1 is, sadly, the default.
896 });
897 }
898
TEST(EVPTest,WycheproofRSAPKCS1Decrypt)899 TEST(EVPTest, WycheproofRSAPKCS1Decrypt) {
900 RunWycheproofPKCS1DecryptTest(
901 "third_party/wycheproof_testvectors/rsa_pkcs1_2048_test.txt");
902 RunWycheproofPKCS1DecryptTest(
903 "third_party/wycheproof_testvectors/rsa_pkcs1_3072_test.txt");
904 RunWycheproofPKCS1DecryptTest(
905 "third_party/wycheproof_testvectors/rsa_pkcs1_4096_test.txt");
906 }
907