xref: /freebsd/contrib/ntp/tests/libntp/digests.c (revision c5c02a131a0e2ef52771e683269bc8778fe511f3)
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 (0 == 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 #define DSA_KEYID		8
384 #undef KEYID_A
385 #define KEYID_A			DSA_KEYID
386 #undef DG_SZ
387 #define DG_SZ			20
388 #undef KEYID_B
389 #define KEYID_B			(KEYID_A + HEX_KEYID_OFFSET)
390 void test_Digest_DSA(void);
391 void test_Digest_DSA(void)
392 {
393 #ifdef OPENSSL
394 	u_char expectedA[MAX_MAC_LEN] =
395 		{
396 			0, 0, 0, KEYID_A,
397 			0xaf, 0xa0, 0x1d, 0x0c,
398 			0x92, 0xcb, 0xca, 0x95,
399 			0x0d, 0x57, 0x60, 0x49,
400 			0xe5, 0x28, 0x03, 0xf2,
401 			0x7b, 0x5b, 0xb1, 0x4a
402 		};
403 	u_char expectedB[MAX_MAC_LEN] =
404 		{
405 			0, 0, 0, KEYID_B,
406 			0x77, 0xcd, 0x88, 0xc2,
407 			0xed, 0x5d, 0x57, 0xc5,
408 			0x28, 0x92, 0xf0, 0x21,
409 			0x2b, 0xb9, 0x48, 0xac,
410 			0xfe, 0x9f, 0xf5, 0x1c
411 		};
412 
413 	TEST_ASSERT(setup);
414 	TEST_ONE_DIGEST(KEYID_A, DG_SZ, expectedA);
415 	TEST_ONE_DIGEST(KEYID_B, DG_SZ, expectedB);
416 #else	/* ! OPENSSL follows  */
417 	TEST_IGNORE_MESSAGE("Skipping, no OPENSSL");
418 #endif
419 }
420 
421 
422 #define DSA_SHA_KEYID		9
423 #undef KEYID_A
424 #define KEYID_A			DSA_SHA_KEYID
425 #undef DG_SZ
426 #define DG_SZ			20
427 #undef KEYID_B
428 #define KEYID_B			(KEYID_A + HEX_KEYID_OFFSET)
429 void test_Digest_DSA_SHA(void);
430 void test_Digest_DSA_SHA(void)
431 {
432 #ifdef OPENSSL
433 	u_char expectedA[MAX_MAC_LEN] =
434 		{
435 			0, 0, 0, KEYID_A,
436 			0x7c, 0xb5, 0x79, 0xd0,
437 			0xf2, 0xcd, 0x47, 0xc0,
438 			0x21, 0xf3, 0xf5, 0x04,
439 			0x10, 0xc4, 0x59, 0x5c,
440 			0xd9, 0xa4, 0x4f, 0x3b
441 		};
442 	u_char expectedB[MAX_MAC_LEN] =
443 		{
444 			0, 0, 0, KEYID_B,
445 			0xb9, 0xca, 0xa6, 0x8e,
446 			0xd3, 0xcb, 0x94, 0x6a,
447 			0x6d, 0xae, 0xb4, 0xc8,
448 			0x0e, 0xc9, 0xf6, 0xed,
449 			0x58, 0x1a, 0xed, 0x22
450 		};
451 
452 	TEST_ASSERT(setup);
453 	TEST_ONE_DIGEST(KEYID_A, DG_SZ, expectedA);
454 	TEST_ONE_DIGEST(KEYID_B, DG_SZ, expectedB);
455 #else	/* ! OPENSSL follows  */
456 	TEST_IGNORE_MESSAGE("Skipping, no OPENSSL");
457 #endif
458 }
459 
460 
461 #define SHA_KEYID		10
462 #undef KEYID_A
463 #define KEYID_A			SHA_KEYID
464 #undef DG_SZ
465 #define DG_SZ			20
466 #undef KEYID_B
467 #define KEYID_B			(KEYID_A + HEX_KEYID_OFFSET)
468 void test_Digest_SHA(void);
469 void test_Digest_SHA(void)
470 {
471 #ifdef OPENSSL
472 	u_char expectedA[MAX_MAC_LEN] =
473 		{
474 			0, 0, 0, KEYID_A,
475 			0xd5, 0xbd, 0xb8, 0x55,
476 			0x9b, 0x9e, 0x5e, 0x8f,
477 			0x1a, 0x3d, 0x99, 0x60,
478 			0xbd, 0x70, 0x0c, 0x5c,
479 			0x68, 0xae, 0xb0, 0xbd
480 		};
481 	u_char expectedB[MAX_MAC_LEN] =
482 		{
483 			0, 0, 0, KEYID_B,
484 			0x63, 0x05, 0x41, 0x45,
485 			0xe9, 0x61, 0x84, 0xe7,
486 			0xc6, 0x94, 0x24, 0xa4,
487 			0x84, 0x76, 0xc7, 0xc9,
488 			0xdd, 0x80, 0x80, 0x89
489 		};
490 
491 	TEST_ASSERT(setup);
492 	TEST_ONE_DIGEST(KEYID_A, DG_SZ, expectedA);
493 	TEST_ONE_DIGEST(KEYID_B, DG_SZ, expectedB);
494 #else	/* ! OPENSSL follows  */
495 	TEST_IGNORE_MESSAGE("Skipping, no OPENSSL");
496 #endif
497 }
498 
499 
500 /*
501  * Dump a MAC in a form easy to cut and paste into the expected declaration.
502  */
503 void dump_mac(
504 	keyid_t		keyid,
505 	u_char *	pmac,
506 	size_t		octets
507 	)
508 {
509 	char	dump[128];
510 	size_t	dc = 0;
511 	size_t	idx;
512 
513 	dc += snprintf(dump + dc, sizeof(dump) - dc, "digest with key %u { ", keyid);
514 
515 	for (idx = 4; idx < octets; idx++) {
516 		if (14 == idx) {
517 			msyslog(LOG_DEBUG, "%s", dump);
518 			dc = 0;
519 		}
520 		if (dc < sizeof(dump)) {
521 			dc += snprintf(dump + dc, sizeof(dump) - dc,
522 				       "0x%02x, ", pmac[idx]);
523 		}
524 	}
525 
526 	if (dc < sizeof(dump)) {
527 		dc += snprintf(dump + dc, sizeof(dump) - dc, "}");
528 	}
529 
530 	msyslog(LOG_DEBUG, "%s", dump);
531 }
532 
533