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