1 /* $OpenBSD: evp_test.c,v 1.20 2024/07/09 17:24:12 tb Exp $ */
2 /*
3 * Copyright (c) 2017, 2022 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2023, 2024 Theo Buehler <tb@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <assert.h>
20 #include <err.h>
21 #include <stdio.h>
22 #include <string.h>
23
24 #include <openssl/crypto.h>
25 #include <openssl/evp.h>
26 #include <openssl/kdf.h>
27 #include <openssl/objects.h>
28 #include <openssl/ossl_typ.h>
29
30 static int
evp_asn1_method_test(void)31 evp_asn1_method_test(void)
32 {
33 const EVP_PKEY_ASN1_METHOD *method;
34 int count, pkey_id, i;
35 int failed = 1;
36
37 if ((count = EVP_PKEY_asn1_get_count()) < 1) {
38 fprintf(stderr, "FAIL: failed to get pkey asn1 method count\n");
39 goto failure;
40 }
41 for (i = 0; i < count; i++) {
42 if ((method = EVP_PKEY_asn1_get0(i)) == NULL) {
43 fprintf(stderr, "FAIL: failed to get pkey %d\n", i);
44 goto failure;
45 }
46 }
47
48 if ((method = EVP_PKEY_asn1_find(NULL, EVP_PKEY_RSA)) == NULL) {
49 fprintf(stderr, "FAIL: failed to find RSA method\n");
50 goto failure;
51 }
52 if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, method)) {
53 fprintf(stderr, "FAIL: failed to get RSA method info\n");
54 goto failure;
55 }
56 if (pkey_id != EVP_PKEY_RSA) {
57 fprintf(stderr, "FAIL: method ID mismatch (%d != %d)\n",
58 pkey_id, EVP_PKEY_RSA);
59 goto failure;
60 }
61
62 if ((method = EVP_PKEY_asn1_find(NULL, EVP_PKEY_RSA_PSS)) == NULL) {
63 fprintf(stderr, "FAIL: failed to find RSA-PSS method\n");
64 goto failure;
65 }
66 if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, method)) {
67 fprintf(stderr, "FAIL: failed to get RSA-PSS method info\n");
68 goto failure;
69 }
70 if (pkey_id != EVP_PKEY_RSA_PSS) {
71 fprintf(stderr, "FAIL: method ID mismatch (%d != %d)\n",
72 pkey_id, EVP_PKEY_RSA_PSS);
73 goto failure;
74 }
75
76 if ((method = EVP_PKEY_asn1_find_str(NULL, "RSA", -1)) == NULL) {
77 fprintf(stderr, "FAIL: failed to find RSA method by str\n");
78 goto failure;
79 }
80 if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, method)) {
81 fprintf(stderr, "FAIL: failed to get RSA method info\n");
82 goto failure;
83 }
84 if (pkey_id != EVP_PKEY_RSA) {
85 fprintf(stderr, "FAIL: method ID mismatch (%d != %d)\n",
86 pkey_id, EVP_PKEY_RSA);
87 goto failure;
88 }
89
90 if ((method = EVP_PKEY_asn1_find_str(NULL, "RSA-PSS", -1)) == NULL) {
91 fprintf(stderr, "FAIL: failed to find RSA-PSS method\n");
92 goto failure;
93 }
94 if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, method)) {
95 fprintf(stderr, "FAIL: failed to get RSA-PSS method info\n");
96 goto failure;
97 }
98 if (pkey_id != EVP_PKEY_RSA_PSS) {
99 fprintf(stderr, "FAIL: method ID mismatch (%d != %d)\n",
100 pkey_id, EVP_PKEY_RSA_PSS);
101 goto failure;
102 }
103
104 failed = 0;
105
106 failure:
107
108 return failed;
109 }
110
111 /* EVP_PKEY_asn1_find() by hand. Allows cross-checking and finding duplicates. */
112 static const EVP_PKEY_ASN1_METHOD *
evp_pkey_asn1_find(int nid,int skip_id)113 evp_pkey_asn1_find(int nid, int skip_id)
114 {
115 const EVP_PKEY_ASN1_METHOD *ameth;
116 int count, i, pkey_id;
117
118 count = EVP_PKEY_asn1_get_count();
119 for (i = 0; i < count; i++) {
120 if (i == skip_id)
121 continue;
122 if ((ameth = EVP_PKEY_asn1_get0(i)) == NULL)
123 return NULL;
124 if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL,
125 NULL, NULL, ameth))
126 return NULL;
127 if (pkey_id == nid)
128 return ameth;
129 }
130
131 return NULL;
132 }
133
134 static int
evp_asn1_method_aliases_test(void)135 evp_asn1_method_aliases_test(void)
136 {
137 const EVP_PKEY_ASN1_METHOD *ameth;
138 int id, base_id, flags;
139 const char *info, *pem_str;
140 int count, i;
141 int failed = 0;
142
143 if ((count = EVP_PKEY_asn1_get_count()) <= 0) {
144 fprintf(stderr, "FAIL: EVP_PKEY_asn1_get_count(): %d\n", count);
145 failed |= 1;
146 }
147 for (i = 0; i < count; i++) {
148 if ((ameth = EVP_PKEY_asn1_get0(i)) == NULL) {
149 fprintf(stderr, "FAIL: no ameth for index %d < %d\n",
150 i, count);
151 failed |= 1;
152 continue;
153 }
154 if (!EVP_PKEY_asn1_get0_info(&id, &base_id, &flags,
155 &info, &pem_str, ameth)) {
156 fprintf(stderr, "FAIL: no info for ameth %d\n", i);
157 failed |= 1;
158 continue;
159 }
160
161 /*
162 * The following are all true or all false for any ameth:
163 * 1. ASN1_PKEY_ALIAS is set 2. id != base_id
164 * 3. info == NULL 4. pem_str == NULL
165 */
166
167 if ((flags & ASN1_PKEY_ALIAS) == 0) {
168 size_t pem_str_len;
169
170 if (id != base_id) {
171 fprintf(stderr, "FAIL: non-alias with "
172 "id %d != base_id %d\n", id, base_id);
173 failed |= 1;
174 continue;
175 }
176 if (info == NULL || strlen(info) == 0) {
177 fprintf(stderr, "FAIL: missing or empty info %d\n", id);
178 failed |= 1;
179 continue;
180 }
181 if (pem_str == NULL) {
182 fprintf(stderr, "FAIL: missing pem_str %d\n", id);
183 failed |= 1;
184 continue;
185 }
186 if ((pem_str_len = strlen(pem_str)) == 0) {
187 fprintf(stderr, "FAIL: empty pem_str %d\n", id);
188 failed |= 1;
189 continue;
190 }
191
192 if (evp_pkey_asn1_find(id, i) != NULL) {
193 fprintf(stderr, "FAIL: duplicate ameth %d\n", id);
194 failed |= 1;
195 continue;
196 }
197
198 if (ameth != EVP_PKEY_asn1_find(NULL, id)) {
199 fprintf(stderr, "FAIL: EVP_PKEY_asn1_find(%d) "
200 "returned different ameth\n", id);
201 failed |= 1;
202 continue;
203 }
204 if (ameth != EVP_PKEY_asn1_find_str(NULL, pem_str, -1)) {
205 fprintf(stderr, "FAIL: EVP_PKEY_asn1_find_str(%s) "
206 "returned different ameth\n", pem_str);
207 failed |= 1;
208 continue;
209 }
210 if (ameth != EVP_PKEY_asn1_find_str(NULL,
211 pem_str, pem_str_len)) {
212 fprintf(stderr, "FAIL: EVP_PKEY_asn1_find_str(%s, %zu) "
213 "returned different ameth\n", pem_str, pem_str_len);
214 failed |= 1;
215 continue;
216 }
217 if (EVP_PKEY_asn1_find_str(NULL, pem_str,
218 pem_str_len - 1) != NULL) {
219 fprintf(stderr, "FAIL: EVP_PKEY_asn1_find_str(%s, %zu) "
220 "returned an ameth\n", pem_str, pem_str_len - 1);
221 failed |= 1;
222 continue;
223 }
224 continue;
225 }
226
227 if (id == base_id) {
228 fprintf(stderr, "FAIL: alias with id %d == base_id %d\n",
229 id, base_id);
230 failed |= 1;
231 }
232 if (info != NULL) {
233 fprintf(stderr, "FAIL: alias %d with info %s\n", id, info);
234 failed |= 1;
235 }
236 if (pem_str != NULL) {
237 fprintf(stderr, "FAIL: alias %d with pem_str %s\n",
238 id, pem_str);
239 failed |= 1;
240 }
241
242 /* Check that ameth resolves to a non-alias. */
243 if ((ameth = evp_pkey_asn1_find(base_id, -1)) == NULL) {
244 fprintf(stderr, "FAIL: no ameth with pkey_id %d\n",
245 base_id);
246 failed |= 1;
247 continue;
248 }
249 if (!EVP_PKEY_asn1_get0_info(NULL, NULL, &flags, NULL, NULL, ameth)) {
250 fprintf(stderr, "FAIL: no info for ameth with pkey_id %d\n",
251 base_id);
252 failed |= 1;
253 continue;
254 }
255 if ((flags & ASN1_PKEY_ALIAS) != 0) {
256 fprintf(stderr, "FAIL: ameth with pkey_id %d "
257 "resolves to another alias\n", base_id);
258 failed |= 1;
259 }
260 }
261
262 return failed;
263 }
264
265 static const struct evp_iv_len_test {
266 const EVP_CIPHER *(*cipher)(void);
267 int iv_len;
268 int setlen;
269 int expect;
270 } evp_iv_len_tests[] = {
271 {
272 .cipher = EVP_aes_128_ccm,
273 .iv_len = 7,
274 .setlen = 11,
275 .expect = 1,
276 },
277 {
278 .cipher = EVP_aes_128_ccm,
279 .iv_len = 7,
280 .setlen = 6,
281 .expect = 0,
282 },
283 {
284 .cipher = EVP_aes_128_ccm,
285 .iv_len = 7,
286 .setlen = 13,
287 .expect = 1,
288 },
289 {
290 .cipher = EVP_aes_128_ccm,
291 .iv_len = 7,
292 .setlen = 14,
293 .expect = 0,
294 },
295
296 {
297 .cipher = EVP_aes_192_ccm,
298 .iv_len = 7,
299 .setlen = 11,
300 .expect = 1,
301 },
302 {
303 .cipher = EVP_aes_192_ccm,
304 .iv_len = 7,
305 .setlen = 6,
306 .expect = 0,
307 },
308 {
309 .cipher = EVP_aes_192_ccm,
310 .iv_len = 7,
311 .setlen = 13,
312 .expect = 1,
313 },
314 {
315 .cipher = EVP_aes_192_ccm,
316 .iv_len = 7,
317 .setlen = 14,
318 .expect = 0,
319 },
320
321 {
322 .cipher = EVP_aes_256_ccm,
323 .iv_len = 7,
324 .setlen = 11,
325 .expect = 1,
326 },
327 {
328 .cipher = EVP_aes_256_ccm,
329 .iv_len = 7,
330 .setlen = 6,
331 .expect = 0,
332 },
333 {
334 .cipher = EVP_aes_256_ccm,
335 .iv_len = 7,
336 .setlen = 13,
337 .expect = 1,
338 },
339 {
340 .cipher = EVP_aes_256_ccm,
341 .iv_len = 7,
342 .setlen = 14,
343 .expect = 0,
344 },
345
346 {
347 .cipher = EVP_aes_128_gcm,
348 .iv_len = 12,
349 .setlen = 16,
350 .expect = 1,
351 },
352 {
353 .cipher = EVP_aes_128_gcm,
354 .iv_len = 12,
355 .setlen = 0,
356 .expect = 0,
357 },
358 {
359 .cipher = EVP_aes_128_gcm,
360 .iv_len = 12,
361 .setlen = 1,
362 .expect = 1,
363 },
364 /* XXX - GCM IV length isn't capped... */
365 {
366 .cipher = EVP_aes_128_gcm,
367 .iv_len = 12,
368 .setlen = 1024 * 1024,
369 .expect = 1,
370 },
371
372 {
373 .cipher = EVP_aes_192_gcm,
374 .iv_len = 12,
375 .setlen = 16,
376 .expect = 1,
377 },
378 {
379 .cipher = EVP_aes_192_gcm,
380 .iv_len = 12,
381 .setlen = 0,
382 .expect = 0,
383 },
384 {
385 .cipher = EVP_aes_192_gcm,
386 .iv_len = 12,
387 .setlen = 1,
388 .expect = 1,
389 },
390 /* XXX - GCM IV length isn't capped... */
391 {
392 .cipher = EVP_aes_128_gcm,
393 .iv_len = 12,
394 .setlen = 1024 * 1024,
395 .expect = 1,
396 },
397
398 {
399 .cipher = EVP_aes_256_gcm,
400 .iv_len = 12,
401 .setlen = 16,
402 .expect = 1,
403 },
404 {
405 .cipher = EVP_aes_256_gcm,
406 .iv_len = 12,
407 .setlen = 0,
408 .expect = 0,
409 },
410 {
411 .cipher = EVP_aes_256_gcm,
412 .iv_len = 12,
413 .setlen = 1,
414 .expect = 1,
415 },
416 /* XXX - GCM IV length isn't capped... */
417 {
418 .cipher = EVP_aes_128_gcm,
419 .iv_len = 12,
420 .setlen = 1024 * 1024,
421 .expect = 1,
422 },
423
424 {
425 .cipher = EVP_aes_128_ecb,
426 .iv_len = 0,
427 .setlen = 11,
428 .expect = 0,
429 },
430
431 {
432 .cipher = EVP_chacha20_poly1305,
433 .iv_len = 12,
434 .setlen = 11,
435 .expect = 1,
436 },
437 {
438 .cipher = EVP_chacha20_poly1305,
439 .iv_len = 12,
440 .setlen = 12,
441 .expect = 1,
442 },
443 {
444 .cipher = EVP_chacha20_poly1305,
445 .iv_len = 12,
446 .setlen = 13,
447 .expect = 0,
448 },
449 {
450 .cipher = EVP_chacha20_poly1305,
451 .iv_len = 12,
452 .setlen = 1,
453 .expect = 1,
454 },
455 {
456 .cipher = EVP_chacha20_poly1305,
457 .iv_len = 12,
458 .setlen = 0,
459 .expect = 0,
460 },
461 };
462
463 #define N_EVP_IV_LEN_TESTS \
464 (sizeof(evp_iv_len_tests) / sizeof(evp_iv_len_tests[0]))
465
466 static int
evp_pkey_iv_len_testcase(const struct evp_iv_len_test * test)467 evp_pkey_iv_len_testcase(const struct evp_iv_len_test *test)
468 {
469 const EVP_CIPHER *cipher = test->cipher();
470 const char *name;
471 EVP_CIPHER_CTX *ctx;
472 int ret;
473 int failure = 1;
474
475 assert(cipher != NULL);
476 name = OBJ_nid2ln(EVP_CIPHER_nid(cipher));
477 assert(name != NULL);
478
479 if ((ctx = EVP_CIPHER_CTX_new()) == NULL) {
480 fprintf(stderr, "FAIL: %s: EVP_CIPHER_CTX_new()\n", name);
481 goto failure;
482 }
483
484 if ((ret = EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL)) <= 0) {
485 fprintf(stderr, "FAIL: %s: EVP_EncryptInit_ex:"
486 " want %d, got %d\n", name, 1, ret);
487 goto failure;
488 }
489 if ((ret = EVP_CIPHER_CTX_iv_length(ctx)) != test->iv_len) {
490 fprintf(stderr, "FAIL: %s EVP_CIPHER_CTX_iv_length (before set)"
491 " want %d, got %d\n", name, test->iv_len, ret);
492 goto failure;
493 }
494 if ((ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN,
495 test->setlen, NULL)) != test->expect) {
496 fprintf(stderr, "FAIL: %s EVP_CIPHER_CTX_ctrl"
497 " want %d, got %d\n", name, test->expect, ret);
498 goto failure;
499 }
500 if (test->expect == 0)
501 goto done;
502 if ((ret = EVP_CIPHER_CTX_iv_length(ctx)) != test->setlen) {
503 fprintf(stderr, "FAIL: %s EVP_CIPHER_CTX_iv_length (after set)"
504 " want %d, got %d\n", name, test->setlen, ret);
505 goto failure;
506 }
507
508 done:
509 failure = 0;
510
511 failure:
512 EVP_CIPHER_CTX_free(ctx);
513
514 return failure;
515 }
516
517 static int
evp_pkey_iv_len_test(void)518 evp_pkey_iv_len_test(void)
519 {
520 size_t i;
521 int failure = 0;
522
523 for (i = 0; i < N_EVP_IV_LEN_TESTS; i++)
524 failure |= evp_pkey_iv_len_testcase(&evp_iv_len_tests[i]);
525
526 return failure;
527 }
528
529 struct do_all_arg {
530 const char *previous;
531 int failure;
532 };
533
534 static void
evp_do_all_cb_common(const char * descr,const void * ptr,const char * from,const char * to,struct do_all_arg * arg)535 evp_do_all_cb_common(const char *descr, const void *ptr, const char *from,
536 const char *to, struct do_all_arg *arg)
537 {
538 const char *previous = arg->previous;
539
540 assert(from != NULL);
541 arg->previous = from;
542
543 if (ptr == NULL && to == NULL) {
544 arg->failure |= 1;
545 fprintf(stderr, "FAIL: %s %s: method and alias both NULL\n",
546 descr, from);
547 }
548 if (ptr != NULL && to != NULL) {
549 arg->failure |= 1;
550 fprintf(stderr, "FAIL: %s %s has method and alias \"%s\"\n",
551 descr, from, to);
552 }
553
554 if (previous == NULL)
555 return;
556
557 if (strcmp(previous, from) >= 0) {
558 arg->failure |= 1;
559 fprintf(stderr, "FAIL: %ss %s and %s out of order\n", descr,
560 previous, from);
561 }
562 }
563
564 static void
evp_cipher_do_all_cb(const EVP_CIPHER * cipher,const char * from,const char * to,void * arg)565 evp_cipher_do_all_cb(const EVP_CIPHER *cipher, const char *from, const char *to,
566 void *arg)
567 {
568 evp_do_all_cb_common("cipher", cipher, from, to, arg);
569 }
570
571 static void
evp_md_do_all_cb(const EVP_MD * md,const char * from,const char * to,void * arg)572 evp_md_do_all_cb(const EVP_MD *md, const char *from, const char *to, void *arg)
573 {
574 evp_do_all_cb_common("digest", md, from, to, arg);
575 }
576
577 static int
evp_do_all_test(void)578 evp_do_all_test(void)
579 {
580 struct do_all_arg arg;
581 int failure = 0;
582
583 memset(&arg, 0, sizeof(arg));
584 EVP_CIPHER_do_all(evp_cipher_do_all_cb, &arg);
585 failure |= arg.failure;
586
587 memset(&arg, 0, sizeof(arg));
588 EVP_MD_do_all(evp_md_do_all_cb, &arg);
589 failure |= arg.failure;
590
591 return failure;
592 }
593
594 static void
evp_cipher_aliases_cb(const EVP_CIPHER * cipher,const char * from,const char * to,void * arg)595 evp_cipher_aliases_cb(const EVP_CIPHER *cipher, const char *from, const char *to,
596 void *arg)
597 {
598 struct do_all_arg *do_all = arg;
599 const EVP_CIPHER *from_cipher, *to_cipher;
600
601 if (to == NULL)
602 return;
603
604 from_cipher = EVP_get_cipherbyname(from);
605 to_cipher = EVP_get_cipherbyname(to);
606
607 if (from_cipher != NULL && from_cipher == to_cipher)
608 return;
609
610 fprintf(stderr, "FAIL: cipher mismatch from \"%s\" to \"%s\": "
611 "from: %p, to: %p\n", from, to, from_cipher, to_cipher);
612 do_all->failure |= 1;
613 }
614
615 static void
evp_digest_aliases_cb(const EVP_MD * digest,const char * from,const char * to,void * arg)616 evp_digest_aliases_cb(const EVP_MD *digest, const char *from, const char *to,
617 void *arg)
618 {
619 struct do_all_arg *do_all = arg;
620 const EVP_MD *from_digest, *to_digest;
621
622 if (to == NULL)
623 return;
624
625 from_digest = EVP_get_digestbyname(from);
626 to_digest = EVP_get_digestbyname(to);
627
628 if (from_digest != NULL && from_digest == to_digest)
629 return;
630
631 fprintf(stderr, "FAIL: digest mismatch from \"%s\" to \"%s\": "
632 "from: %p, to: %p\n", from, to, from_digest, to_digest);
633 do_all->failure |= 1;
634 }
635
636 static int
evp_aliases_test(void)637 evp_aliases_test(void)
638 {
639 struct do_all_arg arg;
640 int failure = 0;
641
642 memset(&arg, 0, sizeof(arg));
643 EVP_CIPHER_do_all(evp_cipher_aliases_cb, &arg);
644 failure |= arg.failure;
645
646 memset(&arg, 0, sizeof(arg));
647 EVP_MD_do_all(evp_digest_aliases_cb, &arg);
648 failure |= arg.failure;
649
650 return failure;
651 }
652
653 static void
obj_name_cb(const OBJ_NAME * obj_name,void * do_all_arg)654 obj_name_cb(const OBJ_NAME *obj_name, void *do_all_arg)
655 {
656 struct do_all_arg *arg = do_all_arg;
657 struct do_all_arg arg_copy = *arg;
658 const char *previous = arg->previous;
659 const char *descr = "OBJ_NAME unknown";
660
661 assert(obj_name->name != NULL);
662 arg->previous = obj_name->name;
663
664 if (obj_name->type == OBJ_NAME_TYPE_CIPHER_METH) {
665 descr = "OBJ_NAME cipher";
666
667 if (obj_name->alias == 0) {
668 const EVP_CIPHER *cipher;
669
670 if ((cipher = EVP_get_cipherbyname(obj_name->name)) !=
671 (const EVP_CIPHER *)obj_name->data) {
672 arg->failure |= 1;
673 fprintf(stderr, "FAIL: %s by name %p != %p\n",
674 descr, cipher, obj_name->data);
675 }
676
677 evp_do_all_cb_common(descr, obj_name->data,
678 obj_name->name, NULL, &arg_copy);
679 } else if (obj_name->alias == OBJ_NAME_ALIAS) {
680 evp_cipher_aliases_cb(NULL, obj_name->name,
681 obj_name->data, &arg_copy);
682 } else {
683 fprintf(stderr, "FAIL %s %s: unexpected alias value %d\n",
684 descr, obj_name->name, obj_name->alias);
685 arg->failure |= 1;
686 }
687 } else if (obj_name->type == OBJ_NAME_TYPE_MD_METH) {
688 descr = "OBJ_NAME digest";
689
690 if (obj_name->alias == 0) {
691 const EVP_MD *evp_md;
692
693 if ((evp_md = EVP_get_digestbyname(obj_name->name)) !=
694 (const EVP_MD *)obj_name->data) {
695 arg->failure |= 1;
696 fprintf(stderr, "FAIL: %s by name %p != %p\n",
697 descr, evp_md, obj_name->data);
698 }
699
700 evp_do_all_cb_common(descr, obj_name->data,
701 obj_name->name, NULL, &arg_copy);
702 } else if (obj_name->alias == OBJ_NAME_ALIAS) {
703 evp_digest_aliases_cb(NULL, obj_name->name,
704 obj_name->data, &arg_copy);
705 } else {
706 fprintf(stderr, "FAIL: %s %s: unexpected alias value %d\n",
707 descr, obj_name->name, obj_name->alias);
708 arg->failure |= 1;
709 }
710 } else {
711 fprintf(stderr, "FAIL: unexpected OBJ_NAME type %d\n",
712 obj_name->type);
713 arg->failure |= 1;
714 }
715
716 if (previous != NULL && strcmp(previous, obj_name->name) >= 0) {
717 arg->failure |= 1;
718 fprintf(stderr, "FAIL: %ss %s and %s out of order\n", descr,
719 previous, obj_name->name);
720 }
721
722 arg->failure |= arg_copy.failure;
723 }
724
725 static int
obj_name_do_all_test(void)726 obj_name_do_all_test(void)
727 {
728 struct do_all_arg arg;
729 int failure = 0;
730
731 memset(&arg, 0, sizeof(arg));
732 OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, obj_name_cb, &arg);
733 failure |= arg.failure;
734
735 memset(&arg, 0, sizeof(arg));
736 OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, obj_name_cb, &arg);
737 failure |= arg.failure;
738
739 return failure;
740 }
741
742 static int
evp_get_cipherbyname_test(void)743 evp_get_cipherbyname_test(void)
744 {
745 int failure = 0;
746
747 /* Should handle NULL gracefully */
748 failure |= EVP_get_cipherbyname(NULL) != NULL;
749
750 return failure;
751 }
752
753 static int
evp_get_digestbyname_test(void)754 evp_get_digestbyname_test(void)
755 {
756 int failure = 0;
757
758 /* Should handle NULL gracefully */
759 failure |= EVP_get_digestbyname(NULL) != NULL;
760
761 return failure;
762 }
763
764 static void
hexdump(const unsigned char * buf,int len)765 hexdump(const unsigned char *buf, int len)
766 {
767 int i;
768
769 if (len <= 0) {
770 fprintf(stderr, "<negative length %d>\n", len);
771 return;
772 }
773
774 for (i = 1; i <= len; i++)
775 fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
776
777 fprintf(stderr, "\n");
778 }
779
780 static int
kdf_compare_bytes(const char * label,const unsigned char * d1,int len1,const unsigned char * d2,int len2)781 kdf_compare_bytes(const char *label, const unsigned char *d1, int len1,
782 const unsigned char *d2, int len2)
783 {
784 if (len1 != len2) {
785 fprintf(stderr, "FAIL: %s - byte lengths differ "
786 "(%d != %d)\n", label, len1, len2);
787 fprintf(stderr, "Got:\n");
788 hexdump(d1, len1);
789 fprintf(stderr, "Want:\n");
790 hexdump(d2, len2);
791 return 0;
792 }
793 if (memcmp(d1, d2, len1) != 0) {
794 fprintf(stderr, "FAIL: %s - bytes differ\n", label);
795 fprintf(stderr, "Got:\n");
796 hexdump(d1, len1);
797 fprintf(stderr, "Want:\n");
798 hexdump(d2, len2);
799 return 0;
800 }
801 return 1;
802 }
803
804 static int
evp_kdf_tls1_prf_basic(void)805 evp_kdf_tls1_prf_basic(void)
806 {
807 EVP_PKEY_CTX *pctx;
808 unsigned char got[16];
809 size_t got_len = sizeof(got);
810 unsigned char want[16] = {
811 0x8e, 0x4d, 0x93, 0x25, 0x30, 0xd7, 0x65, 0xa0,
812 0xaa, 0xe9, 0x74, 0xc3, 0x04, 0x73, 0x5e, 0xcc,
813 };
814 int failed = 1;
815
816 if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL)) == NULL) {
817 fprintf(stderr, "FAIL: EVP_PKEY_CTX_new_id\n");
818 goto err;
819 }
820
821 if (EVP_PKEY_derive_init(pctx) <= 0) {
822 fprintf(stderr, "FAIL: EVP_PKEY_derive_init\n");
823 goto err;
824 }
825
826 if (EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_sha256()) <= 0) {
827 fprintf(stderr, "FAIL: EVP_PKEY_CTX_set1_tls1_prf_md\n");
828 goto err;
829 }
830
831 if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, "secret", 6) <= 0) {
832 fprintf(stderr, "FAIL: EVP_PKEY_CTX_set1_tls1_prf_secret\n");
833 goto err;
834 }
835
836 if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, "seed", 4) <= 0) {
837 fprintf(stderr, "FAIL: EVP_PKEY_CTX_set1_tls1_prf_seed\n");
838 goto err;
839 }
840
841 if (EVP_PKEY_derive(pctx, got, &got_len) <= 0) {
842 fprintf(stderr, "FAIL: EVP_PKEY_derive\n");
843 goto err;
844 }
845
846 if (!kdf_compare_bytes("kdf test", got, got_len, want, sizeof(want)))
847 goto err;
848
849 failed = 0;
850
851 err:
852 EVP_PKEY_CTX_free(pctx);
853
854 return failed;
855 }
856
857 #define TLS_PRF_OUT_LEN 128
858
859 static const struct tls_prf_test {
860 const unsigned char *desc;
861 const EVP_MD *(*md)(void);
862 const uint16_t cipher_value;
863 const unsigned char out[TLS_PRF_OUT_LEN];
864 } tls_prf_tests[] = {
865 {
866 .desc = "MD5+SHA1",
867 .md = EVP_md5_sha1,
868 .cipher_value = 0x0033,
869 .out = {
870 0x03, 0xa1, 0xc1, 0x7d, 0x2c, 0xa5, 0x3d, 0xe8,
871 0x9d, 0x59, 0x5e, 0x30, 0xf5, 0x71, 0xbb, 0x96,
872 0xde, 0x5c, 0x8e, 0xdc, 0x25, 0x8a, 0x7c, 0x05,
873 0x9f, 0x7d, 0x35, 0x29, 0x45, 0xae, 0x56, 0xad,
874 0x9f, 0x57, 0x15, 0x5c, 0xdb, 0x83, 0x3a, 0xac,
875 0x19, 0xa8, 0x2b, 0x40, 0x72, 0x38, 0x1e, 0xed,
876 0xf3, 0x25, 0xde, 0x84, 0x84, 0xd8, 0xd1, 0xfc,
877 0x31, 0x85, 0x81, 0x12, 0x55, 0x4d, 0x12, 0xb5,
878 0xed, 0x78, 0x5e, 0xba, 0xc8, 0xec, 0x8d, 0x28,
879 0xa1, 0x21, 0x1e, 0x6e, 0x07, 0xf1, 0xfc, 0xf5,
880 0xbf, 0xe4, 0x8e, 0x8e, 0x97, 0x15, 0x93, 0x85,
881 0x75, 0xdd, 0x87, 0x09, 0xd0, 0x4e, 0xe5, 0xd5,
882 0x9e, 0x1f, 0xd6, 0x1c, 0x3b, 0xe9, 0xad, 0xba,
883 0xe0, 0x16, 0x56, 0x62, 0x90, 0xd6, 0x82, 0x84,
884 0xec, 0x8a, 0x22, 0xbe, 0xdc, 0x6a, 0x5e, 0x05,
885 0x12, 0x44, 0xec, 0x60, 0x61, 0xd1, 0x8a, 0x66,
886 },
887 },
888 {
889 .desc = "SHA256 (via TLSv1.2)",
890 .md = EVP_sha256,
891 .cipher_value = 0x0033,
892 .out = {
893 0x37, 0xa7, 0x06, 0x71, 0x6e, 0x19, 0x19, 0xda,
894 0x23, 0x8c, 0xcc, 0xb4, 0x2f, 0x31, 0x64, 0x9d,
895 0x05, 0x29, 0x1c, 0x33, 0x7e, 0x09, 0x1b, 0x0c,
896 0x0e, 0x23, 0xc1, 0xb0, 0x40, 0xcc, 0x31, 0xf7,
897 0x55, 0x66, 0x68, 0xd9, 0xa8, 0xae, 0x74, 0x75,
898 0xf3, 0x46, 0xe9, 0x3a, 0x54, 0x9d, 0xe0, 0x8b,
899 0x7e, 0x6c, 0x63, 0x1c, 0xfa, 0x2f, 0xfd, 0xc9,
900 0xd3, 0xf1, 0xd3, 0xfe, 0x7b, 0x9e, 0x14, 0x95,
901 0xb5, 0xd0, 0xad, 0x9b, 0xee, 0x78, 0x8c, 0x83,
902 0x18, 0x58, 0x7e, 0xa2, 0x23, 0xc1, 0x8b, 0x62,
903 0x94, 0x12, 0xcb, 0xb6, 0x60, 0x69, 0x32, 0xfe,
904 0x98, 0x0e, 0x93, 0xb0, 0x8e, 0x5c, 0xfb, 0x6e,
905 0xdb, 0x9a, 0xc2, 0x9f, 0x8c, 0x5c, 0x43, 0x19,
906 0xeb, 0x4a, 0x52, 0xad, 0x62, 0x2b, 0xdd, 0x9f,
907 0xa3, 0x74, 0xa6, 0x96, 0x61, 0x4d, 0x98, 0x40,
908 0x63, 0xa6, 0xd4, 0xbb, 0x17, 0x11, 0x75, 0xed,
909 },
910 },
911 {
912 .desc = "SHA384",
913 .md = EVP_sha384,
914 .cipher_value = 0x009d,
915 .out = {
916 0x00, 0x93, 0xc3, 0xfd, 0xa7, 0xbb, 0xdc, 0x5b,
917 0x13, 0x3a, 0xe6, 0x8b, 0x1b, 0xac, 0xf3, 0xfb,
918 0x3c, 0x9a, 0x78, 0xf6, 0x19, 0xf0, 0x13, 0x0f,
919 0x0d, 0x01, 0x9d, 0xdf, 0x0a, 0x28, 0x38, 0xce,
920 0x1a, 0x9b, 0x43, 0xbe, 0x56, 0x12, 0xa7, 0x16,
921 0x58, 0xe1, 0x8a, 0xe4, 0xc5, 0xbb, 0x10, 0x4c,
922 0x3a, 0xf3, 0x7f, 0xd3, 0xdb, 0xe4, 0xe0, 0x3d,
923 0xcc, 0x83, 0xca, 0xf0, 0xf9, 0x69, 0xcc, 0x70,
924 0x83, 0x32, 0xf6, 0xfc, 0x81, 0x80, 0x02, 0xe8,
925 0x31, 0x1e, 0x7c, 0x3b, 0x34, 0xf7, 0x34, 0xd1,
926 0xcf, 0x2a, 0xc4, 0x36, 0x2f, 0xe9, 0xaa, 0x7f,
927 0x6d, 0x1f, 0x5e, 0x0e, 0x39, 0x05, 0x15, 0xe1,
928 0xa2, 0x9a, 0x4d, 0x97, 0x8c, 0x62, 0x46, 0xf1,
929 0x87, 0x65, 0xd8, 0xe9, 0x14, 0x11, 0xa6, 0x48,
930 0xd7, 0x0e, 0x6e, 0x70, 0xad, 0xfb, 0x3f, 0x36,
931 0x05, 0x76, 0x4b, 0xe4, 0x28, 0x50, 0x4a, 0xf2,
932 },
933 },
934 };
935
936 #define N_TLS_PRF_TESTS \
937 (sizeof(tls_prf_tests) / sizeof(*tls_prf_tests))
938
939 #define TLS_PRF_SEED1 "tls prf seed 1"
940 #define TLS_PRF_SEED2 "tls prf seed 2"
941 #define TLS_PRF_SEED3 "tls prf seed 3"
942 #define TLS_PRF_SEED4 "tls prf seed 4"
943 #define TLS_PRF_SEED5 "tls prf seed 5"
944 #define TLS_PRF_SECRET "tls prf secretz"
945
946 static int
do_tls_prf_evp_test(int test_no,const struct tls_prf_test * test)947 do_tls_prf_evp_test(int test_no, const struct tls_prf_test *test)
948 {
949 EVP_PKEY_CTX *pkey_ctx = NULL;
950 unsigned char *out;
951 size_t len, out_len;
952 int failed = 1;
953
954 if ((pkey_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL)) == NULL)
955 errx(1, "EVP_PKEY_CTX_new_id");
956
957 if ((out = malloc(TLS_PRF_OUT_LEN)) == NULL)
958 errx(1, "malloc");
959
960 for (len = 1; len <= TLS_PRF_OUT_LEN; len++) {
961 if (EVP_PKEY_derive_init(pkey_ctx) <= 0)
962 errx(1, "EVP_PKEY_derive_init");
963
964 if (EVP_PKEY_CTX_set_tls1_prf_md(pkey_ctx, test->md()) <= 0)
965 errx(1, "EVP_PKEY_CTX_set_tls1_prf_md");
966
967 if (EVP_PKEY_CTX_set1_tls1_prf_secret(pkey_ctx, TLS_PRF_SECRET,
968 sizeof(TLS_PRF_SECRET)) <= 0)
969 errx(1, "EVP_PKEY_CTX_set1_tls1_prf_secret");
970 if (EVP_PKEY_CTX_add1_tls1_prf_seed(pkey_ctx, TLS_PRF_SEED1,
971 sizeof(TLS_PRF_SEED1)) <= 0)
972 errx(1, "EVP_PKEY_CTX_add1_tls1_prf_seed 1");
973 if (EVP_PKEY_CTX_add1_tls1_prf_seed(pkey_ctx, TLS_PRF_SEED2,
974 sizeof(TLS_PRF_SEED2)) <= 0)
975 errx(1, "EVP_PKEY_CTX_add1_tls1_prf_seed 2");
976 if (EVP_PKEY_CTX_add1_tls1_prf_seed(pkey_ctx, TLS_PRF_SEED3,
977 sizeof(TLS_PRF_SEED3)) <= 0)
978 errx(1, "EVP_PKEY_CTX_add1_tls1_prf_seed 3");
979 if (EVP_PKEY_CTX_add1_tls1_prf_seed(pkey_ctx, TLS_PRF_SEED4,
980 sizeof(TLS_PRF_SEED4)) <= 0)
981 errx(1, "EVP_PKEY_CTX_add1_tls1_prf_seed 4");
982 if (EVP_PKEY_CTX_add1_tls1_prf_seed(pkey_ctx, TLS_PRF_SEED5,
983 sizeof(TLS_PRF_SEED5)) <= 0)
984 errx(1, "EVP_PKEY_CTX_add1_tls1_prf_seed 5");
985
986 out_len = len;
987 if (EVP_PKEY_derive(pkey_ctx, out, &out_len) <= 0)
988 errx(1, "EVP_PKEY_derive");
989
990 if (out_len != len) {
991 fprintf(stderr, "FAIL: %s: length %zu != %zu\n",
992 __func__, out_len, len);
993 goto err;
994 }
995
996 if (memcmp(test->out, out, out_len) != 0) {
997 fprintf(stderr, "FAIL: tls_PRF output differs for "
998 "len %zu\n", len);
999 fprintf(stderr, "output:\n");
1000 hexdump(out, out_len);
1001 fprintf(stderr, "test data:\n");
1002 hexdump(test->out, len);
1003 goto err;
1004 }
1005 }
1006
1007 failed = 0;
1008
1009 err:
1010 EVP_PKEY_CTX_free(pkey_ctx);
1011 free(out);
1012
1013 return failed;
1014 }
1015
1016 static int
evp_kdf_tls1_prf(void)1017 evp_kdf_tls1_prf(void)
1018 {
1019 size_t i;
1020 int failed = 0;
1021
1022 for (i = 0; i < N_TLS_PRF_TESTS; i++)
1023 failed |= do_tls_prf_evp_test(i, &tls_prf_tests[i]);
1024
1025 return failed;
1026 }
1027
1028 int
main(int argc,char ** argv)1029 main(int argc, char **argv)
1030 {
1031 int failed = 0;
1032
1033 failed |= evp_asn1_method_test();
1034 failed |= evp_asn1_method_aliases_test();
1035 failed |= evp_pkey_iv_len_test();
1036 failed |= evp_do_all_test();
1037 failed |= evp_aliases_test();
1038 failed |= obj_name_do_all_test();
1039 failed |= evp_get_cipherbyname_test();
1040 failed |= evp_get_digestbyname_test();
1041 failed |= evp_kdf_tls1_prf_basic();
1042 failed |= evp_kdf_tls1_prf();
1043
1044 OPENSSL_cleanup();
1045
1046 return failed;
1047 }
1048