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
setUp(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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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 */
dump_mac(keyid_t keyid,u_char * pmac,size_t octets)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