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 int 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 ADD_FAILURE() << "Unknown RSA padding mode: " << name;
142 return false;
143 }
144
145 using KeyMap = std::map<std::string, bssl::UniquePtr<EVP_PKEY>>;
146
ImportKey(FileTest * t,KeyMap * key_map,EVP_PKEY * (* parse_func)(CBS * cbs),int (* marshal_func)(CBB * cbb,const EVP_PKEY * key))147 static bool ImportKey(FileTest *t, KeyMap *key_map,
148 EVP_PKEY *(*parse_func)(CBS *cbs),
149 int (*marshal_func)(CBB *cbb, const EVP_PKEY *key)) {
150 std::vector<uint8_t> input;
151 if (!t->GetBytes(&input, "Input")) {
152 return false;
153 }
154
155 CBS cbs;
156 CBS_init(&cbs, input.data(), input.size());
157 bssl::UniquePtr<EVP_PKEY> pkey(parse_func(&cbs));
158 if (!pkey) {
159 return false;
160 }
161
162 std::string key_type;
163 if (!t->GetAttribute(&key_type, "Type")) {
164 return false;
165 }
166 EXPECT_EQ(GetKeyType(t, key_type), EVP_PKEY_id(pkey.get()));
167
168 // The key must re-encode correctly.
169 bssl::ScopedCBB cbb;
170 uint8_t *der;
171 size_t der_len;
172 if (!CBB_init(cbb.get(), 0) ||
173 !marshal_func(cbb.get(), pkey.get()) ||
174 !CBB_finish(cbb.get(), &der, &der_len)) {
175 return false;
176 }
177 bssl::UniquePtr<uint8_t> free_der(der);
178
179 std::vector<uint8_t> output = input;
180 if (t->HasAttribute("Output") &&
181 !t->GetBytes(&output, "Output")) {
182 return false;
183 }
184 EXPECT_EQ(Bytes(output), Bytes(der, der_len))
185 << "Re-encoding the key did not match.";
186
187 if (t->HasAttribute("ExpectNoRawPrivate")) {
188 size_t len;
189 EXPECT_FALSE(EVP_PKEY_get_raw_private_key(pkey.get(), nullptr, &len));
190 } else if (t->HasAttribute("ExpectRawPrivate")) {
191 std::vector<uint8_t> expected;
192 if (!t->GetBytes(&expected, "ExpectRawPrivate")) {
193 return false;
194 }
195
196 std::vector<uint8_t> raw;
197 size_t len;
198 if (!EVP_PKEY_get_raw_private_key(pkey.get(), nullptr, &len)) {
199 return false;
200 }
201 raw.resize(len);
202 if (!EVP_PKEY_get_raw_private_key(pkey.get(), raw.data(), &len)) {
203 return false;
204 }
205 raw.resize(len);
206 EXPECT_EQ(Bytes(raw), Bytes(expected));
207
208 // Short buffers should be rejected.
209 raw.resize(len - 1);
210 len = raw.size();
211 EXPECT_FALSE(EVP_PKEY_get_raw_private_key(pkey.get(), raw.data(), &len));
212 }
213
214 if (t->HasAttribute("ExpectNoRawPublic")) {
215 size_t len;
216 EXPECT_FALSE(EVP_PKEY_get_raw_public_key(pkey.get(), nullptr, &len));
217 } else if (t->HasAttribute("ExpectRawPublic")) {
218 std::vector<uint8_t> expected;
219 if (!t->GetBytes(&expected, "ExpectRawPublic")) {
220 return false;
221 }
222
223 std::vector<uint8_t> raw;
224 size_t len;
225 if (!EVP_PKEY_get_raw_public_key(pkey.get(), nullptr, &len)) {
226 return false;
227 }
228 raw.resize(len);
229 if (!EVP_PKEY_get_raw_public_key(pkey.get(), raw.data(), &len)) {
230 return false;
231 }
232 raw.resize(len);
233 EXPECT_EQ(Bytes(raw), Bytes(expected));
234
235 // Short buffers should be rejected.
236 raw.resize(len - 1);
237 len = raw.size();
238 EXPECT_FALSE(EVP_PKEY_get_raw_public_key(pkey.get(), raw.data(), &len));
239 }
240
241 // Save the key for future tests.
242 const std::string &key_name = t->GetParameter();
243 EXPECT_EQ(0u, key_map->count(key_name)) << "Duplicate key: " << key_name;
244 (*key_map)[key_name] = std::move(pkey);
245 return true;
246 }
247
248 // SetupContext configures |ctx| based on attributes in |t|, with the exception
249 // of the signing digest which must be configured externally.
SetupContext(FileTest * t,KeyMap * key_map,EVP_PKEY_CTX * ctx)250 static bool SetupContext(FileTest *t, KeyMap *key_map, EVP_PKEY_CTX *ctx) {
251 if (t->HasAttribute("RSAPadding")) {
252 int padding;
253 if (!GetRSAPadding(t, &padding, t->GetAttributeOrDie("RSAPadding")) ||
254 !EVP_PKEY_CTX_set_rsa_padding(ctx, padding)) {
255 return false;
256 }
257 }
258 if (t->HasAttribute("PSSSaltLength") &&
259 !EVP_PKEY_CTX_set_rsa_pss_saltlen(
260 ctx, atoi(t->GetAttributeOrDie("PSSSaltLength").c_str()))) {
261 return false;
262 }
263 if (t->HasAttribute("MGF1Digest")) {
264 const EVP_MD *digest = GetDigest(t, t->GetAttributeOrDie("MGF1Digest"));
265 if (digest == nullptr || !EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, digest)) {
266 return false;
267 }
268 }
269 if (t->HasAttribute("OAEPDigest")) {
270 const EVP_MD *digest = GetDigest(t, t->GetAttributeOrDie("OAEPDigest"));
271 if (digest == nullptr || !EVP_PKEY_CTX_set_rsa_oaep_md(ctx, digest)) {
272 return false;
273 }
274 }
275 if (t->HasAttribute("OAEPLabel")) {
276 std::vector<uint8_t> label;
277 if (!t->GetBytes(&label, "OAEPLabel")) {
278 return false;
279 }
280 // For historical reasons, |EVP_PKEY_CTX_set0_rsa_oaep_label| expects to be
281 // take ownership of the input.
282 bssl::UniquePtr<uint8_t> buf(reinterpret_cast<uint8_t *>(
283 OPENSSL_memdup(label.data(), label.size())));
284 if (!buf ||
285 !EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, buf.get(), label.size())) {
286 return false;
287 }
288 buf.release();
289 }
290 if (t->HasAttribute("DerivePeer")) {
291 std::string derive_peer = t->GetAttributeOrDie("DerivePeer");
292 if (key_map->count(derive_peer) == 0) {
293 ADD_FAILURE() << "Could not find key " << derive_peer;
294 return false;
295 }
296 EVP_PKEY *derive_peer_key = (*key_map)[derive_peer].get();
297 if (!EVP_PKEY_derive_set_peer(ctx, derive_peer_key)) {
298 return false;
299 }
300 }
301 return true;
302 }
303
TestDerive(FileTest * t,KeyMap * key_map,EVP_PKEY * key)304 static bool TestDerive(FileTest *t, KeyMap *key_map, EVP_PKEY *key) {
305 bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(key, nullptr));
306 if (!ctx ||
307 !EVP_PKEY_derive_init(ctx.get()) ||
308 !SetupContext(t, key_map, ctx.get())) {
309 return false;
310 }
311
312 bssl::UniquePtr<EVP_PKEY_CTX> copy(EVP_PKEY_CTX_dup(ctx.get()));
313 if (!copy) {
314 return false;
315 }
316
317 for (EVP_PKEY_CTX *pctx : {ctx.get(), copy.get()}) {
318 size_t len;
319 std::vector<uint8_t> actual, output;
320 if (!EVP_PKEY_derive(pctx, nullptr, &len)) {
321 return false;
322 }
323 actual.resize(len);
324 if (!EVP_PKEY_derive(pctx, actual.data(), &len)) {
325 return false;
326 }
327 actual.resize(len);
328
329 // Defer looking up the attribute so Error works properly.
330 if (!t->GetBytes(&output, "Output")) {
331 return false;
332 }
333 EXPECT_EQ(Bytes(output), Bytes(actual));
334
335 // Test when the buffer is too large.
336 actual.resize(len + 1);
337 len = actual.size();
338 if (!EVP_PKEY_derive(pctx, actual.data(), &len)) {
339 return false;
340 }
341 actual.resize(len);
342 EXPECT_EQ(Bytes(output), Bytes(actual));
343
344 // Test when the buffer is too small.
345 actual.resize(len - 1);
346 len = actual.size();
347 if (t->HasAttribute("SmallBufferTruncates")) {
348 if (!EVP_PKEY_derive(pctx, actual.data(), &len)) {
349 return false;
350 }
351 actual.resize(len);
352 EXPECT_EQ(Bytes(output.data(), len), Bytes(actual));
353 } else {
354 EXPECT_FALSE(EVP_PKEY_derive(pctx, actual.data(), &len));
355 ERR_clear_error();
356 }
357 }
358 return true;
359 }
360
TestEVP(FileTest * t,KeyMap * key_map)361 static bool TestEVP(FileTest *t, KeyMap *key_map) {
362 if (t->GetType() == "PrivateKey") {
363 return ImportKey(t, key_map, EVP_parse_private_key,
364 EVP_marshal_private_key);
365 }
366
367 if (t->GetType() == "PublicKey") {
368 return ImportKey(t, key_map, EVP_parse_public_key, EVP_marshal_public_key);
369 }
370
371 // Load the key.
372 const std::string &key_name = t->GetParameter();
373 if (key_map->count(key_name) == 0) {
374 ADD_FAILURE() << "Could not find key " << key_name;
375 return false;
376 }
377 EVP_PKEY *key = (*key_map)[key_name].get();
378
379 int (*key_op_init)(EVP_PKEY_CTX *ctx) = nullptr;
380 int (*key_op)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len,
381 const uint8_t *in, size_t in_len) = nullptr;
382 int (*md_op_init)(EVP_MD_CTX * ctx, EVP_PKEY_CTX * *pctx, const EVP_MD *type,
383 ENGINE *e, EVP_PKEY *pkey) = nullptr;
384 bool is_verify = false;
385 if (t->GetType() == "Decrypt") {
386 key_op_init = EVP_PKEY_decrypt_init;
387 key_op = EVP_PKEY_decrypt;
388 } else if (t->GetType() == "Sign") {
389 key_op_init = EVP_PKEY_sign_init;
390 key_op = EVP_PKEY_sign;
391 } else if (t->GetType() == "Verify") {
392 key_op_init = EVP_PKEY_verify_init;
393 is_verify = true;
394 } else if (t->GetType() == "SignMessage") {
395 md_op_init = EVP_DigestSignInit;
396 } else if (t->GetType() == "VerifyMessage") {
397 md_op_init = EVP_DigestVerifyInit;
398 is_verify = true;
399 } else if (t->GetType() == "Encrypt") {
400 key_op_init = EVP_PKEY_encrypt_init;
401 key_op = EVP_PKEY_encrypt;
402 } else if (t->GetType() == "Derive") {
403 return TestDerive(t, key_map, key);
404 } else {
405 ADD_FAILURE() << "Unknown test " << t->GetType();
406 return false;
407 }
408
409 const EVP_MD *digest = nullptr;
410 if (t->HasAttribute("Digest")) {
411 digest = GetDigest(t, t->GetAttributeOrDie("Digest"));
412 if (digest == nullptr) {
413 return false;
414 }
415 }
416
417 // For verify tests, the "output" is the signature. Read it now so that, for
418 // tests which expect a failure in SetupContext, the attribute is still
419 // consumed.
420 std::vector<uint8_t> input, actual, output;
421 if (!t->GetBytes(&input, "Input") ||
422 (is_verify && !t->GetBytes(&output, "Output"))) {
423 return false;
424 }
425
426 if (md_op_init) {
427 bssl::ScopedEVP_MD_CTX ctx, copy;
428 EVP_PKEY_CTX *pctx;
429 if (!md_op_init(ctx.get(), &pctx, digest, nullptr, key) ||
430 !SetupContext(t, key_map, pctx) ||
431 !EVP_MD_CTX_copy_ex(copy.get(), ctx.get())) {
432 return false;
433 }
434
435 if (is_verify) {
436 return EVP_DigestVerify(ctx.get(), output.data(), output.size(),
437 input.data(), input.size()) &&
438 EVP_DigestVerify(copy.get(), output.data(), output.size(),
439 input.data(), input.size());
440 }
441
442 size_t len;
443 if (!EVP_DigestSign(ctx.get(), nullptr, &len, input.data(), input.size())) {
444 return false;
445 }
446 actual.resize(len);
447 if (!EVP_DigestSign(ctx.get(), actual.data(), &len, input.data(),
448 input.size()) ||
449 !t->GetBytes(&output, "Output")) {
450 return false;
451 }
452 actual.resize(len);
453 EXPECT_EQ(Bytes(output), Bytes(actual));
454
455 // Repeat the test with |copy|, to check |EVP_MD_CTX_copy_ex| duplicated
456 // everything.
457 if (!EVP_DigestSign(copy.get(), nullptr, &len, input.data(),
458 input.size())) {
459 return false;
460 }
461 actual.resize(len);
462 if (!EVP_DigestSign(copy.get(), actual.data(), &len, input.data(),
463 input.size()) ||
464 !t->GetBytes(&output, "Output")) {
465 return false;
466 }
467 actual.resize(len);
468 EXPECT_EQ(Bytes(output), Bytes(actual));
469 return true;
470 }
471
472 bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(key, nullptr));
473 if (!ctx ||
474 !key_op_init(ctx.get()) ||
475 (digest != nullptr &&
476 !EVP_PKEY_CTX_set_signature_md(ctx.get(), digest)) ||
477 !SetupContext(t, key_map, ctx.get())) {
478 return false;
479 }
480
481 bssl::UniquePtr<EVP_PKEY_CTX> copy(EVP_PKEY_CTX_dup(ctx.get()));
482 if (!copy) {
483 return false;
484 }
485
486 if (is_verify) {
487 return EVP_PKEY_verify(ctx.get(), output.data(), output.size(),
488 input.data(), input.size()) &&
489 EVP_PKEY_verify(copy.get(), output.data(), output.size(),
490 input.data(), input.size());
491 }
492
493 for (EVP_PKEY_CTX *pctx : {ctx.get(), copy.get()}) {
494 size_t len;
495 if (!key_op(pctx, nullptr, &len, input.data(), input.size())) {
496 return false;
497 }
498 actual.resize(len);
499 if (!key_op(pctx, actual.data(), &len, input.data(), input.size())) {
500 return false;
501 }
502
503 if (t->HasAttribute("CheckDecrypt")) {
504 // Encryption is non-deterministic, so we check by decrypting.
505 size_t plaintext_len;
506 bssl::UniquePtr<EVP_PKEY_CTX> decrypt_ctx(EVP_PKEY_CTX_new(key, nullptr));
507 if (!decrypt_ctx ||
508 !EVP_PKEY_decrypt_init(decrypt_ctx.get()) ||
509 (digest != nullptr &&
510 !EVP_PKEY_CTX_set_signature_md(decrypt_ctx.get(), digest)) ||
511 !SetupContext(t, key_map, decrypt_ctx.get()) ||
512 !EVP_PKEY_decrypt(decrypt_ctx.get(), nullptr, &plaintext_len,
513 actual.data(), actual.size())) {
514 return false;
515 }
516 output.resize(plaintext_len);
517 if (!EVP_PKEY_decrypt(decrypt_ctx.get(), output.data(), &plaintext_len,
518 actual.data(), actual.size())) {
519 ADD_FAILURE() << "Could not decrypt result.";
520 return false;
521 }
522 output.resize(plaintext_len);
523 EXPECT_EQ(Bytes(input), Bytes(output)) << "Decrypted result mismatch.";
524 } else if (t->HasAttribute("CheckVerify")) {
525 // Some signature schemes are non-deterministic, so we check by verifying.
526 bssl::UniquePtr<EVP_PKEY_CTX> verify_ctx(EVP_PKEY_CTX_new(key, nullptr));
527 if (!verify_ctx ||
528 !EVP_PKEY_verify_init(verify_ctx.get()) ||
529 (digest != nullptr &&
530 !EVP_PKEY_CTX_set_signature_md(verify_ctx.get(), digest)) ||
531 !SetupContext(t, key_map, verify_ctx.get())) {
532 return false;
533 }
534 if (t->HasAttribute("VerifyPSSSaltLength")) {
535 if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(
536 verify_ctx.get(),
537 atoi(t->GetAttributeOrDie("VerifyPSSSaltLength").c_str()))) {
538 return false;
539 }
540 }
541 EXPECT_TRUE(EVP_PKEY_verify(verify_ctx.get(), actual.data(),
542 actual.size(), input.data(), input.size()))
543 << "Could not verify result.";
544 } else {
545 // By default, check by comparing the result against Output.
546 if (!t->GetBytes(&output, "Output")) {
547 return false;
548 }
549 actual.resize(len);
550 EXPECT_EQ(Bytes(output), Bytes(actual));
551 }
552 }
553 return true;
554 }
555
TEST(EVPTest,TestVectors)556 TEST(EVPTest, TestVectors) {
557 KeyMap key_map;
558 FileTestGTest("crypto/evp/evp_tests.txt", [&](FileTest *t) {
559 bool result = TestEVP(t, &key_map);
560 if (t->HasAttribute("Error")) {
561 ASSERT_FALSE(result) << "Operation unexpectedly succeeded.";
562 uint32_t err = ERR_peek_error();
563 EXPECT_EQ(t->GetAttributeOrDie("Error"), ERR_reason_error_string(err));
564 } else if (!result) {
565 ADD_FAILURE() << "Operation unexpectedly failed.";
566 }
567 });
568 }
569
RunWycheproofVerifyTest(const char * path)570 static void RunWycheproofVerifyTest(const char *path) {
571 SCOPED_TRACE(path);
572 FileTestGTest(path, [](FileTest *t) {
573 t->IgnoreAllUnusedInstructions();
574
575 std::vector<uint8_t> der;
576 ASSERT_TRUE(t->GetInstructionBytes(&der, "keyDer"));
577 CBS cbs;
578 CBS_init(&cbs, der.data(), der.size());
579 bssl::UniquePtr<EVP_PKEY> key(EVP_parse_public_key(&cbs));
580 ASSERT_TRUE(key);
581
582 const EVP_MD *md = nullptr;
583 if (t->HasInstruction("sha")) {
584 md = GetWycheproofDigest(t, "sha", true);
585 ASSERT_TRUE(md);
586 }
587
588 bool is_pss = t->HasInstruction("mgf");
589 const EVP_MD *mgf1_md = nullptr;
590 int pss_salt_len = -1;
591 if (is_pss) {
592 ASSERT_EQ("MGF1", t->GetInstructionOrDie("mgf"));
593 mgf1_md = GetWycheproofDigest(t, "mgfSha", true);
594
595 std::string s_len;
596 ASSERT_TRUE(t->GetInstruction(&s_len, "sLen"));
597 pss_salt_len = atoi(s_len.c_str());
598 }
599
600 std::vector<uint8_t> msg;
601 ASSERT_TRUE(t->GetBytes(&msg, "msg"));
602 std::vector<uint8_t> sig;
603 ASSERT_TRUE(t->GetBytes(&sig, "sig"));
604 WycheproofResult result;
605 ASSERT_TRUE(GetWycheproofResult(t, &result));
606
607 if (EVP_PKEY_id(key.get()) == EVP_PKEY_DSA) {
608 // DSA is deprecated and is not usable via EVP.
609 DSA *dsa = EVP_PKEY_get0_DSA(key.get());
610 uint8_t digest[EVP_MAX_MD_SIZE];
611 unsigned digest_len;
612 ASSERT_TRUE(
613 EVP_Digest(msg.data(), msg.size(), digest, &digest_len, md, nullptr));
614 int valid;
615 bool sig_ok = DSA_check_signature(&valid, digest, digest_len, sig.data(),
616 sig.size(), dsa) &&
617 valid;
618 EXPECT_EQ(sig_ok, result.IsValid());
619 } else {
620 bssl::ScopedEVP_MD_CTX ctx;
621 EVP_PKEY_CTX *pctx;
622 ASSERT_TRUE(
623 EVP_DigestVerifyInit(ctx.get(), &pctx, md, nullptr, key.get()));
624 if (is_pss) {
625 ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING));
626 ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1_md));
627 ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, pss_salt_len));
628 }
629 int ret = EVP_DigestVerify(ctx.get(), sig.data(), sig.size(), msg.data(),
630 msg.size());
631 // BoringSSL does not enforce policies on weak keys and leaves it to the
632 // caller.
633 EXPECT_EQ(ret,
634 result.IsValid({"SmallModulus", "SmallPublicKey", "WeakHash"})
635 ? 1
636 : 0);
637 }
638 });
639 }
640
TEST(EVPTest,WycheproofDSA)641 TEST(EVPTest, WycheproofDSA) {
642 RunWycheproofVerifyTest("third_party/wycheproof_testvectors/dsa_test.txt");
643 }
644
TEST(EVPTest,WycheproofECDSAP224)645 TEST(EVPTest, WycheproofECDSAP224) {
646 RunWycheproofVerifyTest(
647 "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha224_test.txt");
648 RunWycheproofVerifyTest(
649 "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha256_test.txt");
650 RunWycheproofVerifyTest(
651 "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha512_test.txt");
652 }
653
TEST(EVPTest,WycheproofECDSAP256)654 TEST(EVPTest, WycheproofECDSAP256) {
655 RunWycheproofVerifyTest(
656 "third_party/wycheproof_testvectors/ecdsa_secp256r1_sha256_test.txt");
657 RunWycheproofVerifyTest(
658 "third_party/wycheproof_testvectors/ecdsa_secp256r1_sha512_test.txt");
659 }
660
TEST(EVPTest,WycheproofECDSAP384)661 TEST(EVPTest, WycheproofECDSAP384) {
662 RunWycheproofVerifyTest(
663 "third_party/wycheproof_testvectors/ecdsa_secp384r1_sha384_test.txt");
664 }
665
TEST(EVPTest,WycheproofECDSAP521)666 TEST(EVPTest, WycheproofECDSAP521) {
667 RunWycheproofVerifyTest(
668 "third_party/wycheproof_testvectors/ecdsa_secp384r1_sha512_test.txt");
669 RunWycheproofVerifyTest(
670 "third_party/wycheproof_testvectors/ecdsa_secp521r1_sha512_test.txt");
671 }
672
TEST(EVPTest,WycheproofEdDSA)673 TEST(EVPTest, WycheproofEdDSA) {
674 RunWycheproofVerifyTest("third_party/wycheproof_testvectors/eddsa_test.txt");
675 }
676
TEST(EVPTest,WycheproofRSAPKCS1)677 TEST(EVPTest, WycheproofRSAPKCS1) {
678 RunWycheproofVerifyTest(
679 "third_party/wycheproof_testvectors/rsa_signature_2048_sha224_test.txt");
680 RunWycheproofVerifyTest(
681 "third_party/wycheproof_testvectors/rsa_signature_2048_sha256_test.txt");
682 RunWycheproofVerifyTest(
683 "third_party/wycheproof_testvectors/rsa_signature_2048_sha384_test.txt");
684 RunWycheproofVerifyTest(
685 "third_party/wycheproof_testvectors/rsa_signature_2048_sha512_test.txt");
686 RunWycheproofVerifyTest(
687 "third_party/wycheproof_testvectors/rsa_signature_3072_sha256_test.txt");
688 RunWycheproofVerifyTest(
689 "third_party/wycheproof_testvectors/rsa_signature_3072_sha384_test.txt");
690 RunWycheproofVerifyTest(
691 "third_party/wycheproof_testvectors/rsa_signature_3072_sha512_test.txt");
692 RunWycheproofVerifyTest(
693 "third_party/wycheproof_testvectors/rsa_signature_4096_sha384_test.txt");
694 RunWycheproofVerifyTest(
695 "third_party/wycheproof_testvectors/rsa_signature_4096_sha512_test.txt");
696 // TODO(davidben): Is this file redundant with the tests above?
697 RunWycheproofVerifyTest(
698 "third_party/wycheproof_testvectors/rsa_signature_test.txt");
699 }
700
TEST(EVPTest,WycheproofRSAPKCS1Sign)701 TEST(EVPTest, WycheproofRSAPKCS1Sign) {
702 FileTestGTest(
703 "third_party/wycheproof_testvectors/rsa_sig_gen_misc_test.txt",
704 [](FileTest *t) {
705 t->IgnoreAllUnusedInstructions();
706
707 std::vector<uint8_t> pkcs8;
708 ASSERT_TRUE(t->GetInstructionBytes(&pkcs8, "privateKeyPkcs8"));
709 CBS cbs;
710 CBS_init(&cbs, pkcs8.data(), pkcs8.size());
711 bssl::UniquePtr<EVP_PKEY> key(EVP_parse_private_key(&cbs));
712 ASSERT_TRUE(key);
713
714 const EVP_MD *md = GetWycheproofDigest(t, "sha", true);
715 ASSERT_TRUE(md);
716
717 std::vector<uint8_t> msg, sig;
718 ASSERT_TRUE(t->GetBytes(&msg, "msg"));
719 ASSERT_TRUE(t->GetBytes(&sig, "sig"));
720 WycheproofResult result;
721 ASSERT_TRUE(GetWycheproofResult(t, &result));
722
723 bssl::ScopedEVP_MD_CTX ctx;
724 EVP_PKEY_CTX *pctx;
725 ASSERT_TRUE(
726 EVP_DigestSignInit(ctx.get(), &pctx, md, nullptr, key.get()));
727 std::vector<uint8_t> out(EVP_PKEY_size(key.get()));
728 size_t len = out.size();
729 int ret =
730 EVP_DigestSign(ctx.get(), out.data(), &len, msg.data(), msg.size());
731 // BoringSSL does not enforce policies on weak keys and leaves it to the
732 // caller.
733 bool is_valid =
734 result.IsValid({"SmallModulus", "SmallPublicKey", "WeakHash"});
735 EXPECT_EQ(ret, is_valid ? 1 : 0);
736 if (is_valid) {
737 out.resize(len);
738 EXPECT_EQ(Bytes(sig), Bytes(out));
739 }
740 });
741 }
742
TEST(EVPTest,WycheproofRSAPSS)743 TEST(EVPTest, WycheproofRSAPSS) {
744 RunWycheproofVerifyTest(
745 "third_party/wycheproof_testvectors/rsa_pss_2048_sha1_mgf1_20_test.txt");
746 RunWycheproofVerifyTest(
747 "third_party/wycheproof_testvectors/rsa_pss_2048_sha256_mgf1_0_test.txt");
748 RunWycheproofVerifyTest(
749 "third_party/wycheproof_testvectors/"
750 "rsa_pss_2048_sha256_mgf1_32_test.txt");
751 RunWycheproofVerifyTest(
752 "third_party/wycheproof_testvectors/"
753 "rsa_pss_3072_sha256_mgf1_32_test.txt");
754 RunWycheproofVerifyTest(
755 "third_party/wycheproof_testvectors/"
756 "rsa_pss_4096_sha256_mgf1_32_test.txt");
757 RunWycheproofVerifyTest(
758 "third_party/wycheproof_testvectors/"
759 "rsa_pss_4096_sha512_mgf1_32_test.txt");
760 RunWycheproofVerifyTest(
761 "third_party/wycheproof_testvectors/rsa_pss_misc_test.txt");
762 }
763
RunWycheproofDecryptTest(const char * path,std::function<void (FileTest *,EVP_PKEY_CTX *)> setup_cb)764 static void RunWycheproofDecryptTest(
765 const char *path,
766 std::function<void(FileTest *, EVP_PKEY_CTX *)> setup_cb) {
767 FileTestGTest(path, [&](FileTest *t) {
768 t->IgnoreAllUnusedInstructions();
769
770 std::vector<uint8_t> pkcs8;
771 ASSERT_TRUE(t->GetInstructionBytes(&pkcs8, "privateKeyPkcs8"));
772 CBS cbs;
773 CBS_init(&cbs, pkcs8.data(), pkcs8.size());
774 bssl::UniquePtr<EVP_PKEY> key(EVP_parse_private_key(&cbs));
775 ASSERT_TRUE(key);
776
777 std::vector<uint8_t> ct, msg;
778 ASSERT_TRUE(t->GetBytes(&ct, "ct"));
779 ASSERT_TRUE(t->GetBytes(&msg, "msg"));
780 WycheproofResult result;
781 ASSERT_TRUE(GetWycheproofResult(t, &result));
782
783 bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(key.get(), nullptr));
784 ASSERT_TRUE(ctx);
785 ASSERT_TRUE(EVP_PKEY_decrypt_init(ctx.get()));
786 ASSERT_NO_FATAL_FAILURE(setup_cb(t, ctx.get()));
787 std::vector<uint8_t> out(EVP_PKEY_size(key.get()));
788 size_t len = out.size();
789 int ret =
790 EVP_PKEY_decrypt(ctx.get(), out.data(), &len, ct.data(), ct.size());
791 // BoringSSL does not enforce policies on weak keys and leaves it to the
792 // caller.
793 bool is_valid = result.IsValid({"SmallModulus"});
794 EXPECT_EQ(ret, is_valid ? 1 : 0);
795 if (is_valid) {
796 out.resize(len);
797 EXPECT_EQ(Bytes(msg), Bytes(out));
798 }
799 });
800 }
801
RunWycheproofOAEPTest(const char * path)802 static void RunWycheproofOAEPTest(const char *path) {
803 RunWycheproofDecryptTest(path, [](FileTest *t, EVP_PKEY_CTX *ctx) {
804 const EVP_MD *md = GetWycheproofDigest(t, "sha", true);
805 ASSERT_TRUE(md);
806 const EVP_MD *mgf1_md = GetWycheproofDigest(t, "mgfSha", true);
807 ASSERT_TRUE(mgf1_md);
808 std::vector<uint8_t> label;
809 ASSERT_TRUE(t->GetBytes(&label, "label"));
810
811 ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING));
812 ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md));
813 ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1_md));
814 bssl::UniquePtr<uint8_t> label_copy(
815 static_cast<uint8_t *>(OPENSSL_memdup(label.data(), label.size())));
816 ASSERT_TRUE(label_copy || label.empty());
817 ASSERT_TRUE(
818 EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, label_copy.get(), label.size()));
819 // |EVP_PKEY_CTX_set0_rsa_oaep_label| takes ownership on success.
820 label_copy.release();
821 });
822 }
823
TEST(EVPTest,WycheproofRSAOAEP2048)824 TEST(EVPTest, WycheproofRSAOAEP2048) {
825 RunWycheproofOAEPTest(
826 "third_party/wycheproof_testvectors/"
827 "rsa_oaep_2048_sha1_mgf1sha1_test.txt");
828 RunWycheproofOAEPTest(
829 "third_party/wycheproof_testvectors/"
830 "rsa_oaep_2048_sha224_mgf1sha1_test.txt");
831 RunWycheproofOAEPTest(
832 "third_party/wycheproof_testvectors/"
833 "rsa_oaep_2048_sha224_mgf1sha224_test.txt");
834 RunWycheproofOAEPTest(
835 "third_party/wycheproof_testvectors/"
836 "rsa_oaep_2048_sha256_mgf1sha1_test.txt");
837 RunWycheproofOAEPTest(
838 "third_party/wycheproof_testvectors/"
839 "rsa_oaep_2048_sha256_mgf1sha256_test.txt");
840 RunWycheproofOAEPTest(
841 "third_party/wycheproof_testvectors/"
842 "rsa_oaep_2048_sha384_mgf1sha1_test.txt");
843 RunWycheproofOAEPTest(
844 "third_party/wycheproof_testvectors/"
845 "rsa_oaep_2048_sha384_mgf1sha384_test.txt");
846 RunWycheproofOAEPTest(
847 "third_party/wycheproof_testvectors/"
848 "rsa_oaep_2048_sha512_mgf1sha1_test.txt");
849 RunWycheproofOAEPTest(
850 "third_party/wycheproof_testvectors/"
851 "rsa_oaep_2048_sha512_mgf1sha512_test.txt");
852 }
853
TEST(EVPTest,WycheproofRSAOAEP3072)854 TEST(EVPTest, WycheproofRSAOAEP3072) {
855 RunWycheproofOAEPTest(
856 "third_party/wycheproof_testvectors/"
857 "rsa_oaep_3072_sha256_mgf1sha1_test.txt");
858 RunWycheproofOAEPTest(
859 "third_party/wycheproof_testvectors/"
860 "rsa_oaep_3072_sha256_mgf1sha256_test.txt");
861 RunWycheproofOAEPTest(
862 "third_party/wycheproof_testvectors/"
863 "rsa_oaep_3072_sha512_mgf1sha1_test.txt");
864 RunWycheproofOAEPTest(
865 "third_party/wycheproof_testvectors/"
866 "rsa_oaep_3072_sha512_mgf1sha512_test.txt");
867 }
868
TEST(EVPTest,WycheproofRSAOAEP4096)869 TEST(EVPTest, WycheproofRSAOAEP4096) {
870 RunWycheproofOAEPTest(
871 "third_party/wycheproof_testvectors/"
872 "rsa_oaep_4096_sha256_mgf1sha1_test.txt");
873 RunWycheproofOAEPTest(
874 "third_party/wycheproof_testvectors/"
875 "rsa_oaep_4096_sha256_mgf1sha256_test.txt");
876 RunWycheproofOAEPTest(
877 "third_party/wycheproof_testvectors/"
878 "rsa_oaep_4096_sha512_mgf1sha1_test.txt");
879 RunWycheproofOAEPTest(
880 "third_party/wycheproof_testvectors/"
881 "rsa_oaep_4096_sha512_mgf1sha512_test.txt");
882 }
883
TEST(EVPTest,WycheproofRSAOAEPMisc)884 TEST(EVPTest, WycheproofRSAOAEPMisc) {
885 RunWycheproofOAEPTest(
886 "third_party/wycheproof_testvectors/rsa_oaep_misc_test.txt");
887 }
888
RunWycheproofPKCS1DecryptTest(const char * path)889 static void RunWycheproofPKCS1DecryptTest(const char *path) {
890 RunWycheproofDecryptTest(path, [](FileTest *t, EVP_PKEY_CTX *ctx) {
891 // No setup needed. PKCS#1 is, sadly, the default.
892 });
893 }
894
TEST(EVPTest,WycheproofRSAPKCS1Decrypt)895 TEST(EVPTest, WycheproofRSAPKCS1Decrypt) {
896 RunWycheproofPKCS1DecryptTest(
897 "third_party/wycheproof_testvectors/rsa_pkcs1_2048_test.txt");
898 RunWycheproofPKCS1DecryptTest(
899 "third_party/wycheproof_testvectors/rsa_pkcs1_3072_test.txt");
900 RunWycheproofPKCS1DecryptTest(
901 "third_party/wycheproof_testvectors/rsa_pkcs1_4096_test.txt");
902 }
903