1 /* $NetBSD: crypto.c,v 1.5 2024/08/18 20:47:26 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