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