xref: /openbsd-src/regress/lib/libcrypto/evp/evp_test.c (revision a7e633bbce673f356f1099557ddf2d975f8f5094)
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