xref: /freebsd/crypto/openssh/regress/unittests/crypto/tests.c (revision bb5c77e9d281d6def6835d48249898764bc6a5fe)
1 /* 	$OpenBSD: tests.c,v 1.2 2026/06/16 08:15:35 dtucker Exp $ */
2 /*
3  * Regress test for crypto ergonomic API
4  *
5  * Placed in the public domain
6  */
7 
8 #include "includes.h"
9 
10 #include <ctype.h>
11 #include <stdlib.h>
12 #include <string.h>
13 
14 #include "../test_helper/test_helper.h"
15 #include "sshbuf.h"
16 
17 void mldsa_tests(void);
18 void mlkem_tests(void);
19 void ed25519_tests(void);
20 void mldsa_eddsa_tests(void);
21 
22 struct sshbuf *load_text_file(const char *name);
23 char *get_json_string(struct sshbuf *content, const char *key, int consume);
24 
25 static struct sshbuf *
load_file(const char * name)26 load_file(const char *name)
27 {
28 	struct sshbuf *ret = NULL;
29 
30 	ASSERT_INT_EQ(sshbuf_load_file(test_data_file(name), &ret), 0);
31 	ASSERT_PTR_NE(ret, NULL);
32 	return ret;
33 }
34 
35 struct sshbuf *
load_text_file(const char * name)36 load_text_file(const char *name)
37 {
38 	struct sshbuf *ret = load_file(name);
39 	const u_char *p;
40 	size_t len;
41 
42 	/* Trim whitespace at EOL */
43 	for (p = sshbuf_ptr(ret); (len = sshbuf_len(ret)) > 0;) {
44 		len--;
45 		if (p[len] == '\r' || p[len] == '\t' ||
46 		    p[len] == ' ' || p[len] == '\n')
47 			ASSERT_INT_EQ(sshbuf_consume_end(ret, 1), 0);
48 		else
49 			break;
50 	}
51 	/* \0 terminate */
52 	ASSERT_INT_EQ(sshbuf_put_u8(ret, 0), 0);
53 	return ret;
54 }
55 
56 
57 /*
58  * Simple JSON-ish parser for test vectors.
59  * Extracts the value for a given key.
60  * Errors cause ASSERT_* failures.
61  */
62 char *
get_json_string(struct sshbuf * content,const char * key,int consume)63 get_json_string(struct sshbuf *content, const char *key, int consume)
64 {
65 	struct sshbuf *tmp;
66 	char *k, *ret;
67 	size_t off, end_off;
68 	u_char c;
69 
70 	tmp = sshbuf_fromb(content);
71 	ASSERT_PTR_NE(tmp, NULL);
72 	ASSERT_INT_GT(asprintf(&k, "\"%s\"", key), 0);
73 	if (sshbuf_find(tmp, 0, k, strlen(k), &off) != 0) {
74 		fprintf(stderr, "Key %s not found in JSON\n", k);
75 		ASSERT_INT_EQ(1, 0);
76 	}
77 	ASSERT_INT_EQ(sshbuf_consume(tmp, off + strlen(k)), 0);
78 	free(k);
79 
80 	/* Skip colon, spaces, commas */
81 	while (sshbuf_len(tmp) > 0) {
82 		c = *sshbuf_ptr(tmp);
83 		if (isspace(c) || c == ':' || c == ',')
84 			ASSERT_INT_EQ(sshbuf_consume(tmp, 1), 0);
85 		else
86 			break;
87 	}
88 	/* Expect opening quote */
89 	ASSERT_INT_EQ(sshbuf_get_u8(tmp, &c), 0);
90 	ASSERT_CHAR_EQ(c, '"');
91 	/* Find closing quote */
92 	ASSERT_INT_EQ(sshbuf_find(tmp, 0, "\"", 1, &end_off), 0);
93 	ASSERT_PTR_NE(ret = malloc(end_off + 1), NULL);
94 	memcpy(ret, sshbuf_ptr(tmp), end_off);
95 	ret[end_off] = '\0';
96 	if (consume) {
97 		ASSERT_INT_EQ(sshbuf_consume(tmp, end_off), 0);
98 		ASSERT_INT_EQ(sshbuf_consume_upto_child(content, tmp), 0);
99 	}
100 	sshbuf_free(tmp);
101 	return ret;
102 }
103 
104 void
tests(void)105 tests(void)
106 {
107 #ifdef USE_MLDSA
108 	mldsa_tests();
109 #endif
110 #ifdef USE_MLKEM768X25519
111 	mlkem_tests();
112 #endif
113 	ed25519_tests();
114 #ifdef USE_MLDSA
115 	mldsa_eddsa_tests();
116 #endif
117 }
118 
119 void
benchmarks(void)120 benchmarks(void)
121 {
122 	/* none */
123 }
124