xref: /netbsd-src/external/bsd/ntp/dist/sntp/tests/crypto.c (revision eabc0478de71e4e011a5b4e0392741e01d491794)
1*eabc0478Schristos /*	$NetBSD: crypto.c,v 1.5 2024/08/18 20:47:26 christos Exp $	*/
248f8ae19Schristos 
3f17b710fSchristos #include "config.h"
4f17b710fSchristos #include "unity.h"
5f17b710fSchristos #include "ntp_types.h"
6f17b710fSchristos 
7f17b710fSchristos #include "sntptest.h"
8f17b710fSchristos #include "crypto.h"
9f17b710fSchristos 
1056f2724eSchristos #define CMAC "AES128CMAC"
1156f2724eSchristos 
12f17b710fSchristos #define SHA1_LENGTH 20
1356f2724eSchristos #define CMAC_LENGTH 16
14f17b710fSchristos 
15a6f3f22fSchristos 
16*eabc0478Schristos void test_MakeSHAKE128Mac(void);
17a6f3f22fSchristos void test_MakeSHA1Mac(void);
1856f2724eSchristos void test_MakeCMac(void);
19*eabc0478Schristos void test_VerifySHAKE128(void);
20a6f3f22fSchristos void test_VerifySHA1(void);
2156f2724eSchristos void test_VerifyCMAC(void);
22a6f3f22fSchristos void test_VerifyFailure(void);
23a6f3f22fSchristos void test_PacketSizeNotMultipleOfFourBytes(void);
24a6f3f22fSchristos 
2556f2724eSchristos void VerifyLocalCMAC(struct key *cmac);
2656f2724eSchristos void VerifyOpenSSLCMAC(struct key *cmac);
2756f2724eSchristos 
28a6f3f22fSchristos 
29a6f3f22fSchristos void
30*eabc0478Schristos test_MakeSHAKE128Mac(void)
31ae49d4a4Schristos {
32*eabc0478Schristos #ifdef OPENSSL
33f17b710fSchristos 
34*eabc0478Schristos 	const char KEY[] = "SHAKE128 unit test key";
35*eabc0478Schristos 	const u_char PAYLOAD[] = "packettestdata16";
36*eabc0478Schristos 	const size_t PAYLOAD_LEN = sizeof(PAYLOAD) - 1;
37*eabc0478Schristos 	const u_char EXPECTED_DIGEST[] =
38*eabc0478Schristos 		"\x62\x5A\x8F\xE4\x66\xCB\xF3\xA6"
39*eabc0478Schristos 		"\x73\x62\x68\x8D\x11\xB8\x42\xBB";
40*eabc0478Schristos 	u_char actual[sizeof(EXPECTED_DIGEST) - 1];
41*eabc0478Schristos 	struct key sk;
42f17b710fSchristos 
43*eabc0478Schristos 	sk.next = NULL;
44*eabc0478Schristos 	sk.key_id = 10;
45*eabc0478Schristos 	sk.key_len = sizeof(KEY) - 1;
46*eabc0478Schristos 	memcpy(&sk.key_seq, KEY, min(sizeof(sk.key_seq), sk.key_len));
47*eabc0478Schristos 	strlcpy(sk.typen, "SHAKE128", sizeof(sk.typen));
48*eabc0478Schristos 	sk.typei = keytype_from_text(sk.typen, NULL);
49f17b710fSchristos 
50*eabc0478Schristos 	TEST_ASSERT_EQUAL(sizeof(actual),
51*eabc0478Schristos 			  make_mac(PAYLOAD, PAYLOAD_LEN, &sk, actual,
52*eabc0478Schristos 				   sizeof(actual)));
53*eabc0478Schristos 
54*eabc0478Schristos 	TEST_ASSERT_EQUAL_HEX8_ARRAY(EXPECTED_DIGEST, actual, sizeof(actual));
55*eabc0478Schristos #else
56*eabc0478Schristos 
57*eabc0478Schristos 	TEST_IGNORE_MESSAGE("OpenSSL not found, skipping...");
58*eabc0478Schristos 
59*eabc0478Schristos #endif	/* OPENSSL */
60f17b710fSchristos }
61f17b710fSchristos 
62f17b710fSchristos 
63a6f3f22fSchristos void
64ae49d4a4Schristos test_MakeSHA1Mac(void)
65ae49d4a4Schristos {
66f17b710fSchristos #ifdef OPENSSL
67ae49d4a4Schristos 
68f17b710fSchristos 	const char* PKT_DATA = "abcdefgh0123";
69f17b710fSchristos 	const int PKT_LEN = strlen(PKT_DATA);
70f17b710fSchristos 	const char* EXPECTED_DIGEST =
71f17b710fSchristos 		"\x17\xaa\x82\x97\xc7\x17\x13\x6a\x9b\xa9"
72f17b710fSchristos 		"\x63\x85\xb4\xce\xbe\x94\xa0\x97\x16\x1d";
73f17b710fSchristos 	char actual[SHA1_LENGTH];
74f17b710fSchristos 
75f17b710fSchristos 	struct key sha1;
76f17b710fSchristos 	sha1.next = NULL;
77f17b710fSchristos 	sha1.key_id = 20;
78f17b710fSchristos 	sha1.key_len = 7;
79f17b710fSchristos 	memcpy(&sha1.key_seq, "sha1seq", sha1.key_len);
8056f2724eSchristos 	strlcpy(sha1.typen, "SHA1", sizeof(sha1.typen));
8156f2724eSchristos 	sha1.typei = keytype_from_text(sha1.typen, NULL);
82f17b710fSchristos 
83f17b710fSchristos 	TEST_ASSERT_EQUAL(SHA1_LENGTH,
84*eabc0478Schristos 			  make_mac(PKT_DATA, PKT_LEN, &sha1, actual,
85*eabc0478Schristos 				   SHA1_LENGTH));
86f17b710fSchristos 
87a6f3f22fSchristos 	TEST_ASSERT_EQUAL_MEMORY(EXPECTED_DIGEST, actual, SHA1_LENGTH);
88ae49d4a4Schristos 
89f17b710fSchristos #else
90ae49d4a4Schristos 
91f17b710fSchristos 	TEST_IGNORE_MESSAGE("OpenSSL not found, skipping...");
92ae49d4a4Schristos 
93f17b710fSchristos #endif	/* OPENSSL */
94f17b710fSchristos }
95f17b710fSchristos 
96f17b710fSchristos 
97a6f3f22fSchristos void
9856f2724eSchristos test_MakeCMac(void)
9956f2724eSchristos {
10079045f13Schristos #if defined(OPENSSL) && defined(ENABLE_CMAC)
10156f2724eSchristos 
10256f2724eSchristos 	const char* PKT_DATA = "abcdefgh0123";
10356f2724eSchristos 	const int PKT_LEN = strlen(PKT_DATA);
10456f2724eSchristos 	const char* EXPECTED_DIGEST =
10556f2724eSchristos 		"\xdd\x35\xd5\xf5\x14\x23\xd9\xd6"
10656f2724eSchristos 		"\x38\x5d\x29\x80\xfe\x51\xb9\x6b";
10756f2724eSchristos 	char actual[CMAC_LENGTH];
10856f2724eSchristos 	struct key cmac;
109*eabc0478Schristos 
11056f2724eSchristos 	cmac.next = NULL;
11156f2724eSchristos 	cmac.key_id = 30;
11256f2724eSchristos 	cmac.key_len = CMAC_LENGTH;
11356f2724eSchristos 	memcpy(&cmac.key_seq, "aes-128-cmac-seq", cmac.key_len);
11456f2724eSchristos 	memcpy(&cmac.typen, CMAC, strlen(CMAC) + 1);
11556f2724eSchristos 
11656f2724eSchristos 	TEST_ASSERT_EQUAL(CMAC_LENGTH,
117*eabc0478Schristos 		    make_mac(PKT_DATA, PKT_LEN, &cmac, actual, CMAC_LENGTH));
11856f2724eSchristos 
11956f2724eSchristos 	TEST_ASSERT_EQUAL_MEMORY(EXPECTED_DIGEST, actual, CMAC_LENGTH);
12056f2724eSchristos 
12156f2724eSchristos #else
12256f2724eSchristos 
123*eabc0478Schristos 	TEST_IGNORE_MESSAGE("CMAC not enabled, skipping...");
12456f2724eSchristos 
12556f2724eSchristos #endif	/* OPENSSL */
12656f2724eSchristos }
12756f2724eSchristos 
12856f2724eSchristos 
12956f2724eSchristos void
130*eabc0478Schristos test_VerifySHAKE128(void)
131ae49d4a4Schristos {
132*eabc0478Schristos #ifdef OPENSSL
133*eabc0478Schristos 	const char KEY[] = "SHAKE128 unit test key";
134*eabc0478Schristos 	const u_char PAYLOAD[] = "packettestdata16";
135*eabc0478Schristos 	const size_t PAYLOAD_LEN = sizeof(PAYLOAD) - 1;
136*eabc0478Schristos 	const u_char EXPECTED_DIGEST[] =
137*eabc0478Schristos 		"\x62\x5A\x8F\xE4\x66\xCB\xF3\xA6"
138*eabc0478Schristos 		"\x73\x62\x68\x8D\x11\xB8\x42\xBB";
139*eabc0478Schristos 	const size_t DIGEST_LEN = sizeof(EXPECTED_DIGEST) - 1;
140*eabc0478Schristos 	struct key sk;
141*eabc0478Schristos 	u_char PKT_DATA[  PAYLOAD_LEN + sizeof(sk.key_id)
142*eabc0478Schristos 			+ DIGEST_LEN];
143*eabc0478Schristos 	u_char *p;
144f17b710fSchristos 
145*eabc0478Schristos 	sk.next = NULL;
146*eabc0478Schristos 	sk.key_id = 0;
147*eabc0478Schristos 	sk.key_len = sizeof(KEY) - 1;
148*eabc0478Schristos 	memcpy(&sk.key_seq, KEY, min(sizeof(sk.key_seq), sk.key_len));
149*eabc0478Schristos 	strlcpy(sk.typen, "SHAKE128", sizeof(sk.typen));
150*eabc0478Schristos 	sk.typei = keytype_from_text(sk.typen, NULL);
151f17b710fSchristos 
152*eabc0478Schristos 	p = PKT_DATA;
153*eabc0478Schristos 	memcpy(p, PAYLOAD, PAYLOAD_LEN);	  p += PAYLOAD_LEN;
154*eabc0478Schristos 	memcpy(p, &sk.key_id, sizeof(sk.key_id)); p += sizeof(sk.key_id);
155*eabc0478Schristos 	memcpy(p, EXPECTED_DIGEST, DIGEST_LEN);	  p += DIGEST_LEN;
156*eabc0478Schristos 	TEST_ASSERT_TRUE(sizeof(PKT_DATA) == p - PKT_DATA);
157*eabc0478Schristos 
158*eabc0478Schristos 	TEST_ASSERT_TRUE(auth_md5(PKT_DATA, PAYLOAD_LEN, DIGEST_LEN, &sk));
159*eabc0478Schristos #else
160*eabc0478Schristos 
161*eabc0478Schristos 	TEST_IGNORE_MESSAGE("OpenSSL not found, skipping...");
162*eabc0478Schristos 
163*eabc0478Schristos #endif	/* OPENSSL */
164f17b710fSchristos }
165f17b710fSchristos 
166f17b710fSchristos 
167a6f3f22fSchristos void
168ae49d4a4Schristos test_VerifySHA1(void)
169ae49d4a4Schristos {
170f17b710fSchristos #ifdef OPENSSL
171ae49d4a4Schristos 
172f17b710fSchristos 	const char* PKT_DATA =
173ae49d4a4Schristos 	    "sometestdata"				/* Data */
174ae49d4a4Schristos 	    "\0\0\0\0"					/* Key-ID (unused) */
175ae49d4a4Schristos 	    "\xad\x07\xde\x36\x39\xa6\x77\xfa\x5b\xce"	/* MAC */
176f17b710fSchristos 	    "\x2d\x8a\x7d\x06\x96\xe6\x0c\xbc\xed\xe1";
177f17b710fSchristos 	const int PKT_LEN = 12;
178f17b710fSchristos 	struct key sha1;
179*eabc0478Schristos 
180f17b710fSchristos 	sha1.next = NULL;
181f17b710fSchristos 	sha1.key_id = 0;
182f17b710fSchristos 	sha1.key_len = 7;
183f17b710fSchristos 	memcpy(&sha1.key_seq, "sha1key", sha1.key_len);
18456f2724eSchristos 	strlcpy(sha1.typen, "SHA1", sizeof(sha1.typen));
18556f2724eSchristos 	sha1.typei = keytype_from_text(sha1.typen, NULL);
186f17b710fSchristos 
187ae49d4a4Schristos 	TEST_ASSERT_TRUE(auth_md5(PKT_DATA, PKT_LEN, SHA1_LENGTH, &sha1));
188ae49d4a4Schristos 
189f17b710fSchristos #else
190ae49d4a4Schristos 
191f17b710fSchristos 	TEST_IGNORE_MESSAGE("OpenSSL not found, skipping...");
192ae49d4a4Schristos 
193f17b710fSchristos #endif	/* OPENSSL */
194f17b710fSchristos }
195f17b710fSchristos 
19656f2724eSchristos 
19756f2724eSchristos void
19856f2724eSchristos test_VerifyCMAC(void)
19956f2724eSchristos {
20056f2724eSchristos 	struct key cmac;
20156f2724eSchristos 
20256f2724eSchristos 	cmac.next = NULL;
20356f2724eSchristos 	cmac.key_id = 0;
20456f2724eSchristos 	cmac.key_len = CMAC_LENGTH;
20556f2724eSchristos 	memcpy(&cmac.key_seq, "aes-128-cmac-key", cmac.key_len);
20656f2724eSchristos 	memcpy(&cmac.typen, CMAC, strlen(CMAC) + 1);
20756f2724eSchristos 
20856f2724eSchristos 	VerifyOpenSSLCMAC(&cmac);
20956f2724eSchristos 	VerifyLocalCMAC(&cmac);
21056f2724eSchristos }
21156f2724eSchristos 
21256f2724eSchristos 
21356f2724eSchristos void
21456f2724eSchristos VerifyOpenSSLCMAC(struct key *cmac)
21556f2724eSchristos {
21679045f13Schristos #if defined(OPENSSL) && defined(ENABLE_CMAC)
21756f2724eSchristos 
21856f2724eSchristos 	/* XXX: HMS: auth_md5 must be renamed/incorrect. */
21956f2724eSchristos 	// TEST_ASSERT_TRUE(auth_md5(PKT_DATA, PKT_LEN, CMAC_LENGTH, cmac));
22056f2724eSchristos 	TEST_IGNORE_MESSAGE("VerifyOpenSSLCMAC needs to be implemented, skipping...");
22156f2724eSchristos 
22256f2724eSchristos #else
22356f2724eSchristos 
224*eabc0478Schristos 	TEST_IGNORE_MESSAGE("CMAC not enabled, skipping...");
22556f2724eSchristos 
22656f2724eSchristos #endif	/* OPENSSL */
22756f2724eSchristos 	return;
22856f2724eSchristos }
22956f2724eSchristos 
23056f2724eSchristos 
23156f2724eSchristos void
23256f2724eSchristos VerifyLocalCMAC(struct key *cmac)
23356f2724eSchristos {
23456f2724eSchristos 
23556f2724eSchristos 	/* XXX: HMS: auth_md5 must be renamed/incorrect. */
23656f2724eSchristos 	// TEST_ASSERT_TRUE(auth_md5(PKT_DATA, PKT_LEN, CMAC_LENGTH, cmac));
23756f2724eSchristos 
23856f2724eSchristos 	TEST_IGNORE_MESSAGE("Hook in the local AES-128-CMAC check!");
23956f2724eSchristos 
24056f2724eSchristos 	return;
24156f2724eSchristos }
24256f2724eSchristos 
24356f2724eSchristos 
244a6f3f22fSchristos void
245ae49d4a4Schristos test_VerifyFailure(void)
246ae49d4a4Schristos {
247*eabc0478Schristos 	/*
248*eabc0478Schristos 	 * We use a copy of test_VerifySHAKE128(), but modify the
249*eabc0478Schristos 	 * last packet octet to make sure verification fails.
250ae49d4a4Schristos 	 */
251*eabc0478Schristos #ifdef OPENSSL
252*eabc0478Schristos 	const char KEY[] = "SHAKE128 unit test key";
253*eabc0478Schristos 	const u_char PAYLOAD[] = "packettestdata1_";
254*eabc0478Schristos 				/* last packet byte different */
255*eabc0478Schristos 	const size_t PAYLOAD_LEN = sizeof(PAYLOAD) - 1;
256*eabc0478Schristos 	const u_char EXPECTED_DIGEST[] =
257*eabc0478Schristos 		"\x62\x5A\x8F\xE4\x66\xCB\xF3\xA6"
258*eabc0478Schristos 		"\x73\x62\x68\x8D\x11\xB8\x42\xBB";
259*eabc0478Schristos 	const size_t DIGEST_LEN = sizeof(EXPECTED_DIGEST) - 1;
260*eabc0478Schristos 	struct key sk;
261*eabc0478Schristos 	u_char PKT_DATA[  PAYLOAD_LEN + sizeof(sk.key_id)
262*eabc0478Schristos 			+ DIGEST_LEN];
263*eabc0478Schristos 	u_char *p;
264f17b710fSchristos 
265*eabc0478Schristos 	sk.next = NULL;
266*eabc0478Schristos 	sk.key_id = 0;
267*eabc0478Schristos 	sk.key_len = sizeof(KEY) - 1;
268*eabc0478Schristos 	memcpy(&sk.key_seq, KEY, min(sizeof(sk.key_seq), sk.key_len));
269*eabc0478Schristos 	strlcpy(sk.typen, "SHAKE128", sizeof(sk.typen));
270*eabc0478Schristos 	sk.typei = keytype_from_text(sk.typen, NULL);
271f17b710fSchristos 
272*eabc0478Schristos 	p = PKT_DATA;
273*eabc0478Schristos 	memcpy(p, PAYLOAD, PAYLOAD_LEN);	  p += PAYLOAD_LEN;
274*eabc0478Schristos 	memcpy(p, &sk.key_id, sizeof(sk.key_id)); p += sizeof(sk.key_id);
275*eabc0478Schristos 	memcpy(p, EXPECTED_DIGEST, DIGEST_LEN);	  p += DIGEST_LEN;
276*eabc0478Schristos 	TEST_ASSERT_TRUE(sizeof(PKT_DATA) == p - PKT_DATA);
277*eabc0478Schristos 
278*eabc0478Schristos 	TEST_ASSERT_FALSE(auth_md5(PKT_DATA, PAYLOAD_LEN, DIGEST_LEN, &sk));
279*eabc0478Schristos #else
280*eabc0478Schristos 
281*eabc0478Schristos 	TEST_IGNORE_MESSAGE("OpenSSL not found, skipping...");
282*eabc0478Schristos 
283*eabc0478Schristos #endif	/* OPENSSL */
284f17b710fSchristos }
285f17b710fSchristos 
286a6f3f22fSchristos 
287a6f3f22fSchristos void
288ae49d4a4Schristos test_PacketSizeNotMultipleOfFourBytes(void)
289ae49d4a4Schristos {
290*eabc0478Schristos 	/*
291*eabc0478Schristos 	 * We use a copy of test_MakeSHAKE128Mac(), but modify
292*eabc0478Schristos 	 * the packet length to 17.
293*eabc0478Schristos 	 */
294*eabc0478Schristos #ifdef OPENSSL
295f17b710fSchristos 
296*eabc0478Schristos 	const char KEY[] = "SHAKE128 unit test key";
297*eabc0478Schristos 	const u_char PAYLOAD[] = "packettestdata_17";
298*eabc0478Schristos 	const size_t PAYLOAD_LEN = sizeof(PAYLOAD) - 1;
299*eabc0478Schristos 	const u_char EXPECTED_DIGEST[] =
300*eabc0478Schristos 		"\x62\x5A\x8F\xE4\x66\xCB\xF3\xA6"
301*eabc0478Schristos 		"\x73\x62\x68\x8D\x11\xB8\x42\xBB";
302*eabc0478Schristos 	u_char actual[sizeof(EXPECTED_DIGEST) - 1];
303*eabc0478Schristos 	struct key sk;
304f17b710fSchristos 
305*eabc0478Schristos 	sk.next = NULL;
306*eabc0478Schristos 	sk.key_id = 10;
307*eabc0478Schristos 	sk.key_len = sizeof(KEY) - 1;
308*eabc0478Schristos 	memcpy(&sk.key_seq, KEY, min(sizeof(sk.key_seq), sk.key_len));
309*eabc0478Schristos 	strlcpy(sk.typen, "SHAKE128", sizeof(sk.typen));
310*eabc0478Schristos 	sk.typei = keytype_from_text(sk.typen, NULL);
311*eabc0478Schristos 
312*eabc0478Schristos 	TEST_ASSERT_EQUAL(0,
313*eabc0478Schristos 			  make_mac(PAYLOAD, PAYLOAD_LEN, &sk, actual,
314*eabc0478Schristos 				   sizeof(actual)));
315*eabc0478Schristos #else
316*eabc0478Schristos 
317*eabc0478Schristos 	TEST_IGNORE_MESSAGE("OpenSSL not found, skipping...");
318*eabc0478Schristos 
319*eabc0478Schristos #endif	/* OPENSSL */
320f17b710fSchristos }
321