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