xref: /freebsd/contrib/ntp/tests/libntp/digests.c (revision 2008043f386721d58158e37e0d7e50df8095942d)
1 #include "config.h"
2 
3 #include <fcntl.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <unistd.h>
7 
8 #include "unity.h"
9 #include "ntp.h"
10 #include "ntp_stdlib.h"
11 
12 /*
13  * tests/libntp/data/ntp.keys has two keys for each algorithm, 50 keyids apart.
14  * The first is 20 random ASCII chars, the 2nd 40 random hex values.
15  */
16 #define HEX_KEYID_OFFSET	50
17 
18 /* in generated srcdir.c */
19 extern const char srcdir[];
20 
21 /* needed by authtrust() */
22 u_long			current_time;
23 
24 static bool		setup;
25 static u_int32 *	pkt;
26 static size_t		pkt_sz;
27 static u_char *		mac;
28 
29 /* helper routine */
30 void dump_mac(keyid_t keyid, u_char *pmac, size_t octets);
31 
32 
33 /* unity calls setUp before each test routine */
34 void setUp(void);
35 void
36 setUp(void)
37 {
38 	static bool	done_once;
39 	const char	msg_rel_fname[] =	"data/mills,david-03.jpg";
40 	const char	keys_rel_fname[] =	"data/ntp.keys";
41 	char		msg_fname[PATH_MAX];
42 	char		keys_fname[PATH_MAX];
43 	int		msgf;
44 	int		result;
45 	struct stat	msg_stat;
46 	u_char *	msg;
47 	size_t		msg_sz;
48 	size_t		pad_sz;
49 	ssize_t		octets;
50 
51 	if (done_once) {
52 		return;
53 	}
54 	done_once = TRUE;
55 
56 	init_auth();
57 
58 	snprintf(keys_fname, sizeof(keys_fname), "%s/%s", srcdir,
59 		 keys_rel_fname);
60 	if (! authreadkeys(keys_fname)) {
61 		fprintf(stderr, "could not load keys %s\n", keys_fname);
62 		return;
63 	}
64 
65 	snprintf(msg_fname, sizeof(msg_fname), "%s/%s", srcdir, msg_rel_fname);
66 	msgf = open(msg_fname, O_RDONLY);
67 	if (msgf < 0) {
68 		fprintf(stderr, "could not open msg file %s\n", msg_fname);
69 		return;
70 	}
71 
72 	result = fstat(msgf, &msg_stat);
73 	if (result < 0) {
74 		fprintf(stderr, "could not get msg file %s size\n", msg_fname);
75 		return;
76 	}
77 
78 	msg_sz = msg_stat.st_size;
79 	/* round up to next multiple of 4 as needed by MD5authencrypt() */
80 	pad_sz = sizeof(u_int32) - (msg_sz % sizeof(u_int32));
81 	if (sizeof(u_int32) == pad_sz) {
82 		pad_sz = 0;
83 	}
84 	/* allocate room for the message, key ID, and MAC */
85 	msg = emalloc_zero(msg_sz + pad_sz + MAX_MAC_LEN);
86 	octets = read(msgf, msg, msg_sz);
87 	if (octets != msg_sz) {
88 		fprintf(stderr, "could not read msg from file %s, %u != %u\n",
89 			msg_fname, (u_int)octets, (u_int)msg_sz);
90 		return;
91 	}
92 	zero_mem(msg + msg_sz, pad_sz);
93 	pkt_sz = msg_sz + pad_sz;
94 	mac = (void *)((u_char *)msg + pkt_sz);
95 	pkt = (void *)msg;
96 
97 	setup = TRUE;
98 }
99 
100 /* reduce code duplication with an ugly macro */
101 #define TEST_ONE_DIGEST(key, exp_sz, exp_mac)				\
102 do {									\
103 	size_t res_sz;							\
104 									\
105 	zero_mem(mac, MAX_MAC_LEN);					\
106 	if (!auth_findkey(key)) {					\
107 		TEST_IGNORE_MESSAGE("MAC unsupported on this system");	\
108 		return;							\
109 	}								\
110 	authtrust((key), 1);						\
111 									\
112 	res_sz = authencrypt((key), pkt, pkt_sz);			\
113 	if (KEY_MAC_LEN == res_sz) {					\
114 		TEST_IGNORE_MESSAGE("Likely OpenSSL 3 failed digest "	\
115 				    "init.");				\
116 		return;							\
117 	}								\
118 	TEST_ASSERT_EQUAL_UINT((u_int)((exp_sz) + KEY_MAC_LEN), res_sz);\
119 	dump_mac((key), mac, res_sz);					\
120 	TEST_ASSERT_EQUAL_HEX8_ARRAY((exp_mac), mac, MAX_MAC_LEN);	\
121 } while (FALSE)
122 
123 
124 #define AES128CMAC_KEYID	1
125 #undef KEYID_A
126 #define KEYID_A			AES128CMAC_KEYID
127 #undef DG_SZ
128 #define DG_SZ			16
129 #undef KEYID_B
130 #define KEYID_B			(KEYID_A + HEX_KEYID_OFFSET)
131 void test_Digest_AES128CMAC(void);
132 void test_Digest_AES128CMAC(void)
133 {
134 #if defined(OPENSSL) && defined(ENABLE_CMAC)
135 	u_char expectedA[MAX_MAC_LEN] =
136 		{
137 			0, 0, 0, KEYID_A,
138 			0x34, 0x5b, 0xcf, 0xa8,
139 			0x85, 0x6e, 0x9d, 0x01,
140 			0xeb, 0x81, 0x25, 0xc2,
141 			0xa4, 0xb8, 0x1b, 0xe0
142 		};
143 	u_char expectedB[MAX_MAC_LEN] =
144 		{
145 			0, 0, 0, KEYID_B,
146 			0xd1, 0x04, 0x4e, 0xbf,
147 			0x79, 0x2d, 0x3a, 0x40,
148 			0xcd, 0xdc, 0x5a, 0x44,
149 			0xde, 0xe0, 0x0c, 0x84
150 		};
151 
152 	TEST_ASSERT(setup);
153 	TEST_ONE_DIGEST(KEYID_A, DG_SZ, expectedA);
154 	TEST_ONE_DIGEST(KEYID_B, DG_SZ, expectedB);
155 #else	/* ! (OPENSSL && ENABLE_CMAC) follows  */
156 	TEST_IGNORE_MESSAGE("Skipping, no OPENSSL or not ENABLE_CMAC");
157 #endif
158 }
159 
160 
161 #define MD4_KEYID		2
162 #undef KEYID_A
163 #define KEYID_A			MD4_KEYID
164 #undef DG_SZ
165 #define DG_SZ			16
166 #undef KEYID_B
167 #define KEYID_B			(KEYID_A + HEX_KEYID_OFFSET)
168 void test_Digest_MD4(void);
169 void test_Digest_MD4(void)
170 {
171 #ifdef OPENSSL
172 	u_char expectedA[MAX_MAC_LEN] =
173 		{
174 			0, 0, 0, KEYID_A,
175 			0xf3, 0x39, 0x34, 0xca,
176 			0xe0, 0x48, 0x26, 0x0f,
177 			0x13, 0xca, 0x56, 0x9e,
178 			0xbc, 0x53, 0x9c, 0x66
179 		};
180 	u_char expectedB[MAX_MAC_LEN] =
181 		{
182 			0, 0, 0, KEYID_B,
183 			0x5e, 0xe6, 0x81, 0xf2,
184 			0x57, 0x57, 0x8a, 0x2b,
185 			0xa8, 0x76, 0x8e, 0x7a,
186 			0xc4, 0xf4, 0x34, 0x7e
187 		};
188 
189 	TEST_ASSERT(setup);
190 	TEST_ONE_DIGEST(KEYID_A, DG_SZ, expectedA);
191 	TEST_ONE_DIGEST(KEYID_B, DG_SZ, expectedB);
192 #else	/* ! OPENSSL follows  */
193 	TEST_IGNORE_MESSAGE("Skipping, no OPENSSL");
194 #endif
195 }
196 
197 
198 #define MD5_KEYID		3
199 #undef KEYID_A
200 #define KEYID_A			MD5_KEYID
201 #undef DG_SZ
202 #define DG_SZ			16
203 #undef KEYID_B
204 #define KEYID_B			(KEYID_A + HEX_KEYID_OFFSET)
205 void test_Digest_MD5(void);
206 void test_Digest_MD5(void)
207 {
208 	u_char expectedA[MAX_MAC_LEN] =
209 		{
210 			0, 0, 0, KEYID_A,
211 			0xa6, 0x8d, 0x3a, 0xfe,
212 			0x52, 0xe5, 0xf7, 0xe9,
213 			0x4c, 0x97, 0x72, 0x16,
214 			0x7c, 0x28, 0x18, 0xaf
215 		};
216 	u_char expectedB[MAX_MAC_LEN] =
217 		{
218 			0, 0, 0, KEYID_B,
219 			0xd4, 0x11, 0x2c, 0xc6,
220 			0x66, 0x74, 0x46, 0x8b,
221 			0x12, 0xb1, 0x8c, 0x49,
222 			0xb0, 0x06, 0xda, 0x34
223 		};
224 
225 	TEST_ASSERT(setup);
226 	TEST_ONE_DIGEST(KEYID_A, DG_SZ, expectedA);
227 	TEST_ONE_DIGEST(KEYID_B, DG_SZ, expectedB);
228 }
229 
230 
231 #define MDC2_KEYID		4
232 #undef KEYID_A
233 #define KEYID_A			MDC2_KEYID
234 #undef DG_SZ
235 #define DG_SZ			16
236 #undef KEYID_B
237 #define KEYID_B			(KEYID_A + HEX_KEYID_OFFSET)
238 void test_Digest_MDC2(void);
239 void test_Digest_MDC2(void)
240 {
241 #ifdef OPENSSL
242 	u_char expectedA[MAX_MAC_LEN] =
243 		{
244 			0, 0, 0, KEYID_A,
245 			0xa0, 0xfc, 0x18, 0xb6,
246 			0xea, 0xba, 0xa5, 0x27,
247 			0xc9, 0x64, 0x0e, 0x41,
248 			0x95, 0x90, 0x5d, 0xf5
249 		};
250 	u_char expectedB[MAX_MAC_LEN] =
251 		{
252 			0, 0, 0, KEYID_B,
253 			0xe3, 0x2c, 0x1e, 0x64,
254 			0x7f, 0x85, 0x81, 0xe7,
255 			0x3b, 0xc3, 0x93, 0x5e,
256 			0xcd, 0x0e, 0x89, 0xeb
257 		};
258 
259 	TEST_ASSERT(setup);
260 	TEST_ONE_DIGEST(KEYID_A, DG_SZ, expectedA);
261 	TEST_ONE_DIGEST(KEYID_B, DG_SZ, expectedB);
262 #else	/* ! OPENSSL follows  */
263 	TEST_IGNORE_MESSAGE("Skipping, no OPENSSL");
264 #endif
265 }
266 
267 
268 #define RIPEMD160_KEYID		5
269 #undef KEYID_A
270 #define KEYID_A			RIPEMD160_KEYID
271 #undef DG_SZ
272 #define DG_SZ			20
273 #undef KEYID_B
274 #define KEYID_B			(KEYID_A + HEX_KEYID_OFFSET)
275 void test_Digest_RIPEMD160(void);
276 void test_Digest_RIPEMD160(void)
277 {
278 #ifdef OPENSSL
279 	u_char expectedA[MAX_MAC_LEN] =
280 		{
281 			0, 0, 0, KEYID_A,
282 			0x8c, 0x3e, 0x55, 0xbb,
283 			0xec, 0x7c, 0xf6, 0x30,
284 			0xef, 0xd1, 0x45, 0x8c,
285 			0xdd, 0x29, 0x32, 0x7e,
286 			0x04, 0x87, 0x6c, 0xd7
287 		};
288 	u_char expectedB[MAX_MAC_LEN] =
289 		{
290 			0, 0, 0, KEYID_B,
291 			0x2d, 0x4a, 0x48, 0xdd,
292 			0x28, 0x02, 0xb4, 0x9d,
293 			0xe3, 0x6d, 0x1b, 0x90,
294 			0x2b, 0xc4, 0x3f, 0xe5,
295 			0x19, 0x60, 0x12, 0xbc
296 		};
297 
298 	TEST_ASSERT(setup);
299 	TEST_ONE_DIGEST(KEYID_A, DG_SZ, expectedA);
300 	TEST_ONE_DIGEST(KEYID_B, DG_SZ, expectedB);
301 #else	/* ! OPENSSL follows  */
302 	TEST_IGNORE_MESSAGE("Skipping, no OPENSSL");
303 #endif
304 }
305 
306 
307 #define SHA1_KEYID		6
308 #undef KEYID_A
309 #define KEYID_A			SHA1_KEYID
310 #undef DG_SZ
311 #define DG_SZ			20
312 #undef KEYID_B
313 #define KEYID_B			(KEYID_A + HEX_KEYID_OFFSET)
314 void test_Digest_SHA1(void);
315 void test_Digest_SHA1(void)
316 {
317 #ifdef OPENSSL
318 	u_char expectedA[MAX_MAC_LEN] =
319 		{
320 			0, 0, 0, KEYID_A,
321 			0xe2, 0xc6, 0x17, 0x71,
322 			0x03, 0xc1, 0x85, 0x56,
323 			0x35, 0xc7, 0x4e, 0x75,
324 			0x79, 0x82, 0x9d, 0xcb,
325 			0x2d, 0x06, 0x0e, 0xfa
326 		};
327 	u_char expectedB[MAX_MAC_LEN] =
328 		{
329 			0, 0, 0, KEYID_B,
330 			0x01, 0x16, 0x37, 0xb4,
331 			0xf5, 0x2d, 0xe0, 0x97,
332 			0xaf, 0xd8, 0x58, 0xf7,
333 			0xad, 0xb3, 0x7e, 0x38,
334 			0x86, 0x85, 0x78, 0x44
335 		};
336 
337 	TEST_ASSERT(setup);
338 	TEST_ONE_DIGEST(KEYID_A, DG_SZ, expectedA);
339 	TEST_ONE_DIGEST(KEYID_B, DG_SZ, expectedB);
340 #else	/* ! OPENSSL follows  */
341 	TEST_IGNORE_MESSAGE("Skipping, no OPENSSL");
342 #endif
343 }
344 
345 
346 #define SHAKE128_KEYID		7
347 #undef KEYID_A
348 #define KEYID_A			SHAKE128_KEYID
349 #undef DG_SZ
350 #define DG_SZ			16
351 #undef KEYID_B
352 #define KEYID_B			(KEYID_A + HEX_KEYID_OFFSET)
353 void test_Digest_SHAKE128(void);
354 void test_Digest_SHAKE128(void)
355 {
356 #ifdef OPENSSL
357 	u_char expectedA[MAX_MAC_LEN] =
358 		{
359 			0, 0, 0, KEYID_A,
360 			0x5c, 0x0c, 0x1a, 0x85,
361 			0xad, 0x03, 0xb2, 0x9a,
362 			0xe4, 0x75, 0x37, 0x93,
363 			0xaa, 0xa6, 0xcd, 0x76
364 		};
365 	u_char expectedB[MAX_MAC_LEN] =
366 		{
367 			0, 0, 0, KEYID_B,
368 			0x07, 0x04, 0x63, 0xcc,
369 			0x46, 0xaf, 0xca, 0x00,
370 			0x7d, 0xd1, 0x5a, 0x39,
371 			0xfd, 0x34, 0xca, 0x10
372 		};
373 
374 	TEST_ASSERT(setup);
375 	TEST_ONE_DIGEST(KEYID_A, DG_SZ, expectedA);
376 	TEST_ONE_DIGEST(KEYID_B, DG_SZ, expectedB);
377 #else	/* ! OPENSSL follows  */
378 	TEST_IGNORE_MESSAGE("Skipping, no OPENSSL");
379 #endif
380 }
381 
382 
383 /*
384  * Dump a MAC in a form easy to cut and paste into the expected declaration.
385  */
386 void dump_mac(
387 	keyid_t		keyid,
388 	u_char *	pmac,
389 	size_t		octets
390 	)
391 {
392 	char	dump[128];
393 	size_t	dc = 0;
394 	size_t	idx;
395 
396 	dc += snprintf(dump + dc, sizeof(dump) - dc, "digest with key %u { ", keyid);
397 
398 	for (idx = 0; idx < octets; idx++) {
399 		if (10 == idx) {
400 			msyslog(LOG_DEBUG, "%s", dump);
401 			dc = 0;
402 		}
403 		if (dc < sizeof(dump)) {
404 			dc += snprintf(dump + dc, sizeof(dump) - dc,
405 				       "0x%02x, ", pmac[idx]);
406 		}
407 	}
408 
409 	if (dc < sizeof(dump)) {
410 		dc += snprintf(dump + dc, sizeof(dump) - dc, "}");
411 	}
412 
413 	msyslog(LOG_DEBUG, "%s", dump);
414 }
415 
416