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 (KEY_MAC_LEN == 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 /* 384 * Dump a MAC in a form easy to cut and paste into the expected declaration. 385 */ 386 void dump_mac( 387 keyid_t keyid, 388 u_char * pmac, 389 size_t octets 390 ) 391 { 392 char dump[128]; 393 size_t dc = 0; 394 size_t idx; 395 396 dc += snprintf(dump + dc, sizeof(dump) - dc, "digest with key %u { ", keyid); 397 398 for (idx = 0; idx < octets; idx++) { 399 if (10 == idx) { 400 msyslog(LOG_DEBUG, "%s", dump); 401 dc = 0; 402 } 403 if (dc < sizeof(dump)) { 404 dc += snprintf(dump + dc, sizeof(dump) - dc, 405 "0x%02x, ", pmac[idx]); 406 } 407 } 408 409 if (dc < sizeof(dump)) { 410 dc += snprintf(dump + dc, sizeof(dump) - dc, "}"); 411 } 412 413 msyslog(LOG_DEBUG, "%s", dump); 414 } 415 416