xref: /freebsd/contrib/ntp/sntp/tests/packetProcessing.c (revision f5f40dd63bc7acbb5312b26ac1ea1103c12352a6)
1 #include "config.h"
2 
3 #include "sntptest.h"
4 #include "networking.h"
5 #include "ntp_stdlib.h"
6 #include "unity.h"
7 
8 #define CMAC		"AES128CMAC"
9 #define CMAC_LENGTH	16
10 
11 
12 /* Hacks into the key database. */
13 extern struct key* key_ptr;
14 extern int key_cnt;
15 
16 
17 void PrepareAuthenticationTest(int key_id,int key_len,const char* type,const void* key_seq);
18 void setUp(void);
19 void tearDown(void);
20 void test_TooShortLength(void);
21 void test_LengthNotMultipleOfFour(void);
22 void test_TooShortExtensionFieldLength(void);
23 void test_UnauthenticatedPacketReject(void);
24 void test_CryptoNAKPacketReject(void);
25 void test_AuthenticatedPacketInvalid(void);
26 void test_AuthenticatedPacketUnknownKey(void);
27 void test_ServerVersionTooOld(void);
28 void test_ServerVersionTooNew(void);
29 void test_NonWantedMode(void);
30 void test_KoDRate(void);
31 void test_KoDDeny(void);
32 void test_RejectUnsyncedServer(void);
33 void test_RejectWrongResponseServerMode(void);
34 void test_AcceptNoSentPacketBroadcastMode(void);
35 void test_CorrectUnauthenticatedPacket(void);
36 void test_CorrectAuthenticatedPacketMD5(void);
37 void test_CorrectAuthenticatedPacketSHAKE128(void);
38 void test_CorrectAuthenticatedPacketSHA1(void);
39 void test_CorrectAuthenticatedPacketCMAC(void);
40 
41 /* [Bug 2998] There are some issues whith the definition of 'struct pkt'
42  * when AUTOKEY is undefined -- the formal struct is too small to hold
43  * all the extension fields that are going to be tested. We have to make
44  * sure we have the extra bytes, or the test yields undefined results due
45  * to buffer overrun.
46  */
47 #ifndef AUTOKEY
48 # define EXTRA_BUFSIZE 256
49 #else
50 # define EXTRA_BUFSIZE 0
51 #endif
52 
53 union tpkt {
54 	struct pkt p;
55 	u_char     b[sizeof(struct pkt) + EXTRA_BUFSIZE];
56 };
57 
58 static union tpkt testpkt;
59 static union tpkt testspkt;
60 static sockaddr_u testsock;
61 bool restoreKeyDb;
62 
63 
64 void
65 PrepareAuthenticationTest(
66 	int		key_id,
67 	int		key_len,
68 	const char *	type,
69 	const void *	key_seq
70 	)
71 {
72 	char str[25];
73 
74 	snprintf(str, sizeof(str), "%d", key_id);
75 	ActivateOption("-a", str);
76 
77 	key_cnt = 1;
78 	if (NULL == key_ptr) {
79 		key_ptr = emalloc(sizeof(*key_ptr));
80 	}
81 	key_ptr->next = NULL;
82 	key_ptr->key_id = key_id;
83 	key_ptr->key_len = key_len;
84 	strncpy(key_ptr->typen, type, sizeof(key_ptr->typen));
85 
86 	TEST_ASSERT_TRUE(key_len < sizeof(key_ptr->key_seq));
87 
88 	memcpy(key_ptr->key_seq, key_seq,
89 	       min(key_len, sizeof(key_ptr->key_seq)));
90 	restoreKeyDb = true;
91 }
92 
93 
94 void
95 setUp(void)
96 {
97 
98 	sntptest();
99 	restoreKeyDb = false;
100 
101 	/* Initialize the test packet and socket,
102 	 * so they contain at least some valid data.
103 	 */
104 	testpkt.p.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, NTP_VERSION,
105 					      MODE_SERVER);
106 	testpkt.p.stratum = STRATUM_REFCLOCK;
107 	memcpy(&testpkt.p.refid, "GPS\0", 4);
108 
109 	/* Set the origin timestamp of the received packet to the
110 	 * same value as the transmit timestamp of the sent packet.
111 	 */
112 	l_fp tmp;
113 	tmp.l_ui = 1000UL;
114 	tmp.l_uf = 0UL;
115 
116 	HTONL_FP(&tmp, &testpkt.p.org);
117 	HTONL_FP(&tmp, &testspkt.p.xmt);
118 }
119 
120 
121 void
122 tearDown(void)
123 {
124 	if (restoreKeyDb) {
125 		key_cnt = 0;
126 		free(key_ptr);
127 		key_ptr = NULL;
128 	}
129 
130 	sntptest_destroy(); /* only on the final test!! if counter == 0 etc... */
131 }
132 
133 
134 void
135 test_TooShortLength(void)
136 {
137 	TEST_ASSERT_EQUAL(PACKET_UNUSEABLE,
138 			  process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC - 1,
139 				      MODE_SERVER, &testspkt.p, "UnitTest"));
140 	TEST_ASSERT_EQUAL(PACKET_UNUSEABLE,
141 			  process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC - 1,
142 				      MODE_BROADCAST, &testspkt.p, "UnitTest"));
143 }
144 
145 
146 void
147 test_LengthNotMultipleOfFour(void)
148 {
149 	TEST_ASSERT_EQUAL(PACKET_UNUSEABLE,
150 			  process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC + 6,
151 				      MODE_SERVER, &testspkt.p, "UnitTest"));
152 	TEST_ASSERT_EQUAL(PACKET_UNUSEABLE,
153 			  process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC + 3,
154 				      MODE_BROADCAST, &testspkt.p, "UnitTest"));
155 }
156 
157 
158 void
159 test_TooShortExtensionFieldLength(void)
160 {
161 	/* [Bug 2998] We have to get around the formal specification of
162 	 * the extension field if AUTOKEY is undefined. (At least CLANG
163 	 * issues a warning in this case. It's just a warning, but
164 	 * still...
165 	 */
166 	uint32_t * pe = testpkt.p.exten + 7;
167 
168 	/* The lower 16-bits are the length of the extension field.
169 	 * This lengths must be multiples of 4 bytes, which gives
170 	 * a minimum of 4 byte extension field length.
171 	 */
172 	*pe = htonl(3); /* 3 bytes is too short. */
173 
174 	/* We send in a pkt_len of header size + 4 byte extension
175 	 * header + 24 byte MAC, this prevents the length error to
176 	 * be caught at an earlier stage
177 	 */
178 	int pkt_len = LEN_PKT_NOMAC + 4 + 24;
179 
180 	TEST_ASSERT_EQUAL(PACKET_UNUSEABLE,
181 			  process_pkt(&testpkt.p, &testsock, pkt_len,
182 				      MODE_SERVER, &testspkt.p, "UnitTest"));
183 }
184 
185 
186 void
187 test_UnauthenticatedPacketReject(void)
188 {
189 	/* Activate authentication option */
190 	ActivateOption("-a", "123");
191 	TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
192 
193 	int pkt_len = LEN_PKT_NOMAC;
194 
195 	/* We demand authentication, but no MAC header is present. */
196 	TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL,
197 			  process_pkt(&testpkt.p, &testsock, pkt_len,
198 				      MODE_SERVER, &testspkt.p, "UnitTest"));
199 }
200 
201 
202 void
203 test_CryptoNAKPacketReject(void)
204 {
205 	/* Activate authentication option */
206 	ActivateOption("-a", "123");
207 	TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
208 
209 	int pkt_len = LEN_PKT_NOMAC + 4; /* + 4 byte MAC = Crypto-NAK */
210 
211 	TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL,
212 			  process_pkt(&testpkt.p, &testsock, pkt_len,
213 				      MODE_SERVER, &testspkt.p, "UnitTest"));
214 }
215 
216 
217 void
218 test_AuthenticatedPacketInvalid(void)
219 {
220 #ifdef OPENSSL
221 	size_t pkt_len = LEN_PKT_NOMAC;
222 	size_t mac_len;
223 
224 	/* Activate authentication option */
225 	PrepareAuthenticationTest(50, 9, "SHAKE128", "123456789");
226 	TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
227 
228 	/* Prepare the packet. */
229 	testpkt.p.exten[0] = htonl(50);
230 	mac_len = make_mac(&testpkt.p, pkt_len, key_ptr,
231 			   &testpkt.p.exten[1], MAX_MDG_LEN);
232 
233 	pkt_len += KEY_MAC_LEN + mac_len;
234 
235 	/* Now, alter the MAC so it becomes invalid. */
236 	testpkt.p.exten[1] += 1;
237 
238 	TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL,
239 			  process_pkt(&testpkt.p, &testsock, pkt_len,
240 				      MODE_SERVER, &testspkt.p, "UnitTest"));
241 
242 #else
243 
244 	TEST_IGNORE_MESSAGE("OpenSSL not enabled, skipping...");
245 
246 #endif
247 }
248 
249 
250 void
251 test_AuthenticatedPacketUnknownKey(void)
252 {
253 #ifdef OPENSSL
254 	size_t pkt_len = LEN_PKT_NOMAC;
255 	size_t mac_len;
256 
257 	/* Activate authentication option */
258 	PrepareAuthenticationTest(30, 9, "SHAKE128", "123456789");
259 	TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
260 
261 	/* Prepare the packet. Note that the Key-ID expected is 30, but
262 	 * the packet has a key id of 50.
263 	 */
264 	testpkt.p.exten[0] = htonl(50);
265 	mac_len = make_mac(&testpkt.p, pkt_len, key_ptr,
266 			   &testpkt.p.exten[1], MAX_MDG_LEN);
267 	pkt_len += KEY_MAC_LEN + mac_len;
268 
269 	TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL,
270 			  process_pkt(&testpkt.p, &testsock, pkt_len,
271 				      MODE_SERVER, &testspkt.p, "UnitTest"));
272 
273 #else
274 
275 	TEST_IGNORE_MESSAGE("OpenSSL not enabled, skipping...");
276 
277 #endif
278 }
279 
280 
281 void
282 test_ServerVersionTooOld(void)
283 {
284 	TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
285 
286 	testpkt.p.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
287 					      NTP_OLDVERSION - 1,
288 					      MODE_CLIENT);
289 	TEST_ASSERT_TRUE(PKT_VERSION(testpkt.p.li_vn_mode) < NTP_OLDVERSION);
290 
291 	int pkt_len = LEN_PKT_NOMAC;
292 
293 	TEST_ASSERT_EQUAL(SERVER_UNUSEABLE,
294 			  process_pkt(&testpkt.p, &testsock, pkt_len,
295 				      MODE_SERVER, &testspkt.p, "UnitTest"));
296 }
297 
298 
299 void
300 test_ServerVersionTooNew(void)
301 {
302 	TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
303 
304 	testpkt.p.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
305 					      NTP_VERSION + 1,
306 					      MODE_CLIENT);
307 	TEST_ASSERT_TRUE(PKT_VERSION(testpkt.p.li_vn_mode) > NTP_VERSION);
308 
309 	int pkt_len = LEN_PKT_NOMAC;
310 
311 	TEST_ASSERT_EQUAL(SERVER_UNUSEABLE,
312 			  process_pkt(&testpkt.p, &testsock, pkt_len,
313 				      MODE_SERVER, &testspkt.p, "UnitTest"));
314 }
315 
316 
317 void
318 test_NonWantedMode(void)
319 {
320 	TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
321 
322 	testpkt.p.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
323 					      NTP_VERSION,
324 					      MODE_CLIENT);
325 
326 	/* The packet has a mode of MODE_CLIENT, but process_pkt expects
327 	 * MODE_SERVER
328 	 */
329 	TEST_ASSERT_EQUAL(SERVER_UNUSEABLE,
330 			  process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC,
331 				      MODE_SERVER, &testspkt.p, "UnitTest"));
332 }
333 
334 
335 /* Tests bug 1597 */
336 void
337 test_KoDRate(void)
338 {
339 	TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
340 
341 	testpkt.p.stratum = STRATUM_PKT_UNSPEC;
342 	memcpy(&testpkt.p.refid, "RATE", 4);
343 
344 	TEST_ASSERT_EQUAL(KOD_RATE,
345 			  process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC,
346 				      MODE_SERVER, &testspkt.p, "UnitTest"));
347 }
348 
349 
350 void
351 test_KoDDeny(void)
352 {
353 	TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
354 
355 	testpkt.p.stratum = STRATUM_PKT_UNSPEC;
356 	memcpy(&testpkt.p.refid, "DENY", 4);
357 
358 	TEST_ASSERT_EQUAL(KOD_DEMOBILIZE,
359 			  process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC,
360 				      MODE_SERVER, &testspkt.p, "UnitTest"));
361 }
362 
363 
364 void
365 test_RejectUnsyncedServer(void)
366 {
367 	TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
368 
369 	testpkt.p.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC,
370 					      NTP_VERSION,
371 					      MODE_SERVER);
372 
373 	TEST_ASSERT_EQUAL(SERVER_UNUSEABLE,
374 			  process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC,
375 				      MODE_SERVER, &testspkt.p, "UnitTest"));
376 }
377 
378 
379 void
380 test_RejectWrongResponseServerMode(void)
381 {
382 	TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
383 
384 	l_fp tmp;
385 	tmp.l_ui = 1000UL;
386 	tmp.l_uf = 0UL;
387 	HTONL_FP(&tmp, &testpkt.p.org);
388 
389 	tmp.l_ui = 2000UL;
390 	tmp.l_uf = 0UL;
391 	HTONL_FP(&tmp, &testspkt.p.xmt);
392 
393 	TEST_ASSERT_EQUAL(PACKET_UNUSEABLE,
394 			  process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC,
395 				      MODE_SERVER, &testspkt.p, "UnitTest"));
396 }
397 
398 
399 void
400 test_AcceptNoSentPacketBroadcastMode(void)
401 {
402 	TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
403 
404 	testpkt.p.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
405 					      NTP_VERSION,
406 					      MODE_BROADCAST);
407 
408 	TEST_ASSERT_EQUAL(LEN_PKT_NOMAC,
409 		  process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC,
410 			      MODE_BROADCAST, NULL, "UnitTest"));
411 }
412 
413 
414 void
415 test_CorrectUnauthenticatedPacket(void)
416 {
417 	TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
418 
419 	TEST_ASSERT_EQUAL(LEN_PKT_NOMAC,
420 			  process_pkt(&testpkt.p, &testsock, LEN_PKT_NOMAC,
421 				      MODE_SERVER, &testspkt.p, "UnitTest"));
422 }
423 
424 
425 void
426 test_CorrectAuthenticatedPacketMD5(void)
427 {
428 #ifdef OPENSSL
429 
430 	keyid_t k_id = 10;
431 	int pkt_len = LEN_PKT_NOMAC;
432 	int mac_len;
433 
434 	PrepareAuthenticationTest(k_id, 15, "MD5", "123456789abcdef");
435 	TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
436 
437 	/* Prepare the packet. */
438 	testpkt.p.exten[0] = htonl(k_id);
439 	mac_len = make_mac(&testpkt.p, pkt_len, key_ptr,
440 			   &testpkt.p.exten[1], MAX_MDG_LEN);
441 
442 	/* TODO: Should not expect failure if non-FIPS OpenSSL */
443 	TEST_EXPECT_FAIL_MESSAGE("FIPS OpenSSL bars MD5");
444 
445 	pkt_len += KEY_MAC_LEN + mac_len;
446 
447 	TEST_ASSERT_EQUAL(pkt_len,
448 			  process_pkt(&testpkt.p, &testsock, pkt_len,
449 				      MODE_SERVER, &testspkt.p, "UnitTest"));
450 
451 #else
452 
453 	TEST_IGNORE_MESSAGE("OpenSSL not enabled, skipping...");
454 
455 #endif
456 }
457 
458 
459 void
460 test_CorrectAuthenticatedPacketSHAKE128(void)
461 {
462 #ifdef OPENSSL
463 
464 	keyid_t k_id = 10;
465 	int pkt_len = LEN_PKT_NOMAC;
466 	int mac_len;
467 
468 	PrepareAuthenticationTest(k_id, 15, "SHAKE128", "123456789abcdef");
469 	TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
470 
471 	/* Prepare the packet. */
472 	testpkt.p.exten[0] = htonl(k_id);
473 	mac_len = make_mac(&testpkt.p, pkt_len, key_ptr, &testpkt.p.exten[1],
474 			   SHAKE128_LENGTH);
475 
476 	pkt_len += KEY_MAC_LEN + mac_len;
477 
478 	TEST_ASSERT_EQUAL(pkt_len,
479 			  process_pkt(&testpkt.p, &testsock, pkt_len,
480 				      MODE_SERVER, &testspkt.p, "UnitTest"));
481 
482 #else
483 
484 	TEST_IGNORE_MESSAGE("OpenSSL not enabled, skipping...");
485 
486 #endif
487 }
488 
489 
490 void
491 test_CorrectAuthenticatedPacketSHA1(void)
492 {
493 #ifdef OPENSSL
494 
495 	keyid_t k_id = 20;
496 	int pkt_len = LEN_PKT_NOMAC;
497 	int mac_len;
498 
499 	PrepareAuthenticationTest(k_id, 15, "SHA1", "abcdefghijklmno");
500 	TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
501 
502 	/* Prepare the packet. */
503 	testpkt.p.exten[0] = htonl(k_id);
504 	mac_len = make_mac(&testpkt.p, pkt_len, key_ptr, &testpkt.p.exten[1],
505 			   SHA1_LENGTH);
506 
507 	pkt_len += KEY_MAC_LEN + mac_len;
508 
509 	TEST_ASSERT_EQUAL(pkt_len,
510 			  process_pkt(&testpkt.p, &testsock, pkt_len,
511 				      MODE_SERVER, &testspkt.p, "UnitTest"));
512 
513 #else
514 
515 	TEST_IGNORE_MESSAGE("OpenSSL not enabled, skipping...");
516 
517 #endif
518 }
519 
520 
521 void
522 test_CorrectAuthenticatedPacketCMAC(void)
523 {
524 #if defined(OPENSSL) && defined(ENABLE_CMAC)
525 
526 	PrepareAuthenticationTest(30, CMAC_LENGTH, CMAC, "abcdefghijklmnop");
527 	TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
528 
529 	int pkt_len = LEN_PKT_NOMAC;
530 
531 	/* Prepare the packet. */
532 	testpkt.p.exten[0] = htonl(30);
533 	int mac_len = make_mac(&testpkt.p, pkt_len, key_ptr,
534 			       &testpkt.p.exten[1], MAX_MAC_LEN);
535 
536 	pkt_len += 4 + mac_len;
537 
538 	TEST_ASSERT_EQUAL(pkt_len,
539 			  process_pkt(&testpkt.p, &testsock, pkt_len,
540 				      MODE_SERVER, &testspkt.p, "UnitTest"));
541 
542 #else
543 
544 	TEST_IGNORE_MESSAGE("CMAC not enabled, skipping...");
545 
546 #endif	/* OPENSSL */
547 }
548 
549