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