crypto.c revision 1.1.1.10 1 /* $NetBSD: crypto.c,v 1.1.1.10 2024/08/18 20:37:47 christos Exp $ */
2
3 #include "config.h"
4 #include "unity.h"
5 #include "ntp_types.h"
6
7 #include "sntptest.h"
8 #include "crypto.h"
9
10 #define CMAC "AES128CMAC"
11
12 #define SHA1_LENGTH 20
13 #define CMAC_LENGTH 16
14
15
16 void test_MakeSHAKE128Mac(void);
17 void test_MakeSHA1Mac(void);
18 void test_MakeCMac(void);
19 void test_VerifySHAKE128(void);
20 void test_VerifySHA1(void);
21 void test_VerifyCMAC(void);
22 void test_VerifyFailure(void);
23 void test_PacketSizeNotMultipleOfFourBytes(void);
24
25 void VerifyLocalCMAC(struct key *cmac);
26 void VerifyOpenSSLCMAC(struct key *cmac);
27
28
29 void
30 test_MakeSHAKE128Mac(void)
31 {
32 #ifdef OPENSSL
33
34 const char KEY[] = "SHAKE128 unit test key";
35 const u_char PAYLOAD[] = "packettestdata16";
36 const size_t PAYLOAD_LEN = sizeof(PAYLOAD) - 1;
37 const u_char EXPECTED_DIGEST[] =
38 "\x62\x5A\x8F\xE4\x66\xCB\xF3\xA6"
39 "\x73\x62\x68\x8D\x11\xB8\x42\xBB";
40 u_char actual[sizeof(EXPECTED_DIGEST) - 1];
41 struct key sk;
42
43 sk.next = NULL;
44 sk.key_id = 10;
45 sk.key_len = sizeof(KEY) - 1;
46 memcpy(&sk.key_seq, KEY, min(sizeof(sk.key_seq), sk.key_len));
47 strlcpy(sk.typen, "SHAKE128", sizeof(sk.typen));
48 sk.typei = keytype_from_text(sk.typen, NULL);
49
50 TEST_ASSERT_EQUAL(sizeof(actual),
51 make_mac(PAYLOAD, PAYLOAD_LEN, &sk, actual,
52 sizeof(actual)));
53
54 TEST_ASSERT_EQUAL_HEX8_ARRAY(EXPECTED_DIGEST, actual, sizeof(actual));
55 #else
56
57 TEST_IGNORE_MESSAGE("OpenSSL not found, skipping...");
58
59 #endif /* OPENSSL */
60 }
61
62
63 void
64 test_MakeSHA1Mac(void)
65 {
66 #ifdef OPENSSL
67
68 const char* PKT_DATA = "abcdefgh0123";
69 const int PKT_LEN = strlen(PKT_DATA);
70 const char* EXPECTED_DIGEST =
71 "\x17\xaa\x82\x97\xc7\x17\x13\x6a\x9b\xa9"
72 "\x63\x85\xb4\xce\xbe\x94\xa0\x97\x16\x1d";
73 char actual[SHA1_LENGTH];
74
75 struct key sha1;
76 sha1.next = NULL;
77 sha1.key_id = 20;
78 sha1.key_len = 7;
79 memcpy(&sha1.key_seq, "sha1seq", sha1.key_len);
80 strlcpy(sha1.typen, "SHA1", sizeof(sha1.typen));
81 sha1.typei = keytype_from_text(sha1.typen, NULL);
82
83 TEST_ASSERT_EQUAL(SHA1_LENGTH,
84 make_mac(PKT_DATA, PKT_LEN, &sha1, actual,
85 SHA1_LENGTH));
86
87 TEST_ASSERT_EQUAL_MEMORY(EXPECTED_DIGEST, actual, SHA1_LENGTH);
88
89 #else
90
91 TEST_IGNORE_MESSAGE("OpenSSL not found, skipping...");
92
93 #endif /* OPENSSL */
94 }
95
96
97 void
98 test_MakeCMac(void)
99 {
100 #if defined(OPENSSL) && defined(ENABLE_CMAC)
101
102 const char* PKT_DATA = "abcdefgh0123";
103 const int PKT_LEN = strlen(PKT_DATA);
104 const char* EXPECTED_DIGEST =
105 "\xdd\x35\xd5\xf5\x14\x23\xd9\xd6"
106 "\x38\x5d\x29\x80\xfe\x51\xb9\x6b";
107 char actual[CMAC_LENGTH];
108 struct key cmac;
109
110 cmac.next = NULL;
111 cmac.key_id = 30;
112 cmac.key_len = CMAC_LENGTH;
113 memcpy(&cmac.key_seq, "aes-128-cmac-seq", cmac.key_len);
114 memcpy(&cmac.typen, CMAC, strlen(CMAC) + 1);
115
116 TEST_ASSERT_EQUAL(CMAC_LENGTH,
117 make_mac(PKT_DATA, PKT_LEN, &cmac, actual, CMAC_LENGTH));
118
119 TEST_ASSERT_EQUAL_MEMORY(EXPECTED_DIGEST, actual, CMAC_LENGTH);
120
121 #else
122
123 TEST_IGNORE_MESSAGE("CMAC not enabled, skipping...");
124
125 #endif /* OPENSSL */
126 }
127
128
129 void
130 test_VerifySHAKE128(void)
131 {
132 #ifdef OPENSSL
133 const char KEY[] = "SHAKE128 unit test key";
134 const u_char PAYLOAD[] = "packettestdata16";
135 const size_t PAYLOAD_LEN = sizeof(PAYLOAD) - 1;
136 const u_char EXPECTED_DIGEST[] =
137 "\x62\x5A\x8F\xE4\x66\xCB\xF3\xA6"
138 "\x73\x62\x68\x8D\x11\xB8\x42\xBB";
139 const size_t DIGEST_LEN = sizeof(EXPECTED_DIGEST) - 1;
140 struct key sk;
141 u_char PKT_DATA[ PAYLOAD_LEN + sizeof(sk.key_id)
142 + DIGEST_LEN];
143 u_char *p;
144
145 sk.next = NULL;
146 sk.key_id = 0;
147 sk.key_len = sizeof(KEY) - 1;
148 memcpy(&sk.key_seq, KEY, min(sizeof(sk.key_seq), sk.key_len));
149 strlcpy(sk.typen, "SHAKE128", sizeof(sk.typen));
150 sk.typei = keytype_from_text(sk.typen, NULL);
151
152 p = PKT_DATA;
153 memcpy(p, PAYLOAD, PAYLOAD_LEN); p += PAYLOAD_LEN;
154 memcpy(p, &sk.key_id, sizeof(sk.key_id)); p += sizeof(sk.key_id);
155 memcpy(p, EXPECTED_DIGEST, DIGEST_LEN); p += DIGEST_LEN;
156 TEST_ASSERT_TRUE(sizeof(PKT_DATA) == p - PKT_DATA);
157
158 TEST_ASSERT_TRUE(auth_md5(PKT_DATA, PAYLOAD_LEN, DIGEST_LEN, &sk));
159 #else
160
161 TEST_IGNORE_MESSAGE("OpenSSL not found, skipping...");
162
163 #endif /* OPENSSL */
164 }
165
166
167 void
168 test_VerifySHA1(void)
169 {
170 #ifdef OPENSSL
171
172 const char* PKT_DATA =
173 "sometestdata" /* Data */
174 "\0\0\0\0" /* Key-ID (unused) */
175 "\xad\x07\xde\x36\x39\xa6\x77\xfa\x5b\xce" /* MAC */
176 "\x2d\x8a\x7d\x06\x96\xe6\x0c\xbc\xed\xe1";
177 const int PKT_LEN = 12;
178 struct key sha1;
179
180 sha1.next = NULL;
181 sha1.key_id = 0;
182 sha1.key_len = 7;
183 memcpy(&sha1.key_seq, "sha1key", sha1.key_len);
184 strlcpy(sha1.typen, "SHA1", sizeof(sha1.typen));
185 sha1.typei = keytype_from_text(sha1.typen, NULL);
186
187 TEST_ASSERT_TRUE(auth_md5(PKT_DATA, PKT_LEN, SHA1_LENGTH, &sha1));
188
189 #else
190
191 TEST_IGNORE_MESSAGE("OpenSSL not found, skipping...");
192
193 #endif /* OPENSSL */
194 }
195
196
197 void
198 test_VerifyCMAC(void)
199 {
200 struct key cmac;
201
202 cmac.next = NULL;
203 cmac.key_id = 0;
204 cmac.key_len = CMAC_LENGTH;
205 memcpy(&cmac.key_seq, "aes-128-cmac-key", cmac.key_len);
206 memcpy(&cmac.typen, CMAC, strlen(CMAC) + 1);
207
208 VerifyOpenSSLCMAC(&cmac);
209 VerifyLocalCMAC(&cmac);
210 }
211
212
213 void
214 VerifyOpenSSLCMAC(struct key *cmac)
215 {
216 #if defined(OPENSSL) && defined(ENABLE_CMAC)
217
218 /* XXX: HMS: auth_md5 must be renamed/incorrect. */
219 // TEST_ASSERT_TRUE(auth_md5(PKT_DATA, PKT_LEN, CMAC_LENGTH, cmac));
220 TEST_IGNORE_MESSAGE("VerifyOpenSSLCMAC needs to be implemented, skipping...");
221
222 #else
223
224 TEST_IGNORE_MESSAGE("CMAC not enabled, skipping...");
225
226 #endif /* OPENSSL */
227 return;
228 }
229
230
231 void
232 VerifyLocalCMAC(struct key *cmac)
233 {
234
235 /* XXX: HMS: auth_md5 must be renamed/incorrect. */
236 // TEST_ASSERT_TRUE(auth_md5(PKT_DATA, PKT_LEN, CMAC_LENGTH, cmac));
237
238 TEST_IGNORE_MESSAGE("Hook in the local AES-128-CMAC check!");
239
240 return;
241 }
242
243
244 void
245 test_VerifyFailure(void)
246 {
247 /*
248 * We use a copy of test_VerifySHAKE128(), but modify the
249 * last packet octet to make sure verification fails.
250 */
251 #ifdef OPENSSL
252 const char KEY[] = "SHAKE128 unit test key";
253 const u_char PAYLOAD[] = "packettestdata1_";
254 /* last packet byte different */
255 const size_t PAYLOAD_LEN = sizeof(PAYLOAD) - 1;
256 const u_char EXPECTED_DIGEST[] =
257 "\x62\x5A\x8F\xE4\x66\xCB\xF3\xA6"
258 "\x73\x62\x68\x8D\x11\xB8\x42\xBB";
259 const size_t DIGEST_LEN = sizeof(EXPECTED_DIGEST) - 1;
260 struct key sk;
261 u_char PKT_DATA[ PAYLOAD_LEN + sizeof(sk.key_id)
262 + DIGEST_LEN];
263 u_char *p;
264
265 sk.next = NULL;
266 sk.key_id = 0;
267 sk.key_len = sizeof(KEY) - 1;
268 memcpy(&sk.key_seq, KEY, min(sizeof(sk.key_seq), sk.key_len));
269 strlcpy(sk.typen, "SHAKE128", sizeof(sk.typen));
270 sk.typei = keytype_from_text(sk.typen, NULL);
271
272 p = PKT_DATA;
273 memcpy(p, PAYLOAD, PAYLOAD_LEN); p += PAYLOAD_LEN;
274 memcpy(p, &sk.key_id, sizeof(sk.key_id)); p += sizeof(sk.key_id);
275 memcpy(p, EXPECTED_DIGEST, DIGEST_LEN); p += DIGEST_LEN;
276 TEST_ASSERT_TRUE(sizeof(PKT_DATA) == p - PKT_DATA);
277
278 TEST_ASSERT_FALSE(auth_md5(PKT_DATA, PAYLOAD_LEN, DIGEST_LEN, &sk));
279 #else
280
281 TEST_IGNORE_MESSAGE("OpenSSL not found, skipping...");
282
283 #endif /* OPENSSL */
284 }
285
286
287 void
288 test_PacketSizeNotMultipleOfFourBytes(void)
289 {
290 /*
291 * We use a copy of test_MakeSHAKE128Mac(), but modify
292 * the packet length to 17.
293 */
294 #ifdef OPENSSL
295
296 const char KEY[] = "SHAKE128 unit test key";
297 const u_char PAYLOAD[] = "packettestdata_17";
298 const size_t PAYLOAD_LEN = sizeof(PAYLOAD) - 1;
299 const u_char EXPECTED_DIGEST[] =
300 "\x62\x5A\x8F\xE4\x66\xCB\xF3\xA6"
301 "\x73\x62\x68\x8D\x11\xB8\x42\xBB";
302 u_char actual[sizeof(EXPECTED_DIGEST) - 1];
303 struct key sk;
304
305 sk.next = NULL;
306 sk.key_id = 10;
307 sk.key_len = sizeof(KEY) - 1;
308 memcpy(&sk.key_seq, KEY, min(sizeof(sk.key_seq), sk.key_len));
309 strlcpy(sk.typen, "SHAKE128", sizeof(sk.typen));
310 sk.typei = keytype_from_text(sk.typen, NULL);
311
312 TEST_ASSERT_EQUAL(0,
313 make_mac(PAYLOAD, PAYLOAD_LEN, &sk, actual,
314 sizeof(actual)));
315 #else
316
317 TEST_IGNORE_MESSAGE("OpenSSL not found, skipping...");
318
319 #endif /* OPENSSL */
320 }
321