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