From 245b63bfcf7314e9a2960304c724d0e9253e5c8f Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Tue, 30 Dec 2025 12:00:40 +0100 Subject: [PATCH] Cleanup the ipcrypt tests --- test/default/ipcrypt.c | 687 +++++++++++++++++++++++++++------------ test/default/ipcrypt.exp | 95 +++--- 2 files changed, 520 insertions(+), 262 deletions(-) diff --git a/test/default/ipcrypt.c b/test/default/ipcrypt.c index fe57b1bf..3bdf7a60 100644 --- a/test/default/ipcrypt.c +++ b/test/default/ipcrypt.c @@ -1,13 +1,21 @@ #define TEST_NAME "ipcrypt" #include "cmptest.h" -static void -dump_hex(const unsigned char *data, size_t len) +static int +check_expected(const char *test_name, const unsigned char *actual, const char *expected_hex, + size_t len) { - char hex[129]; + unsigned char expected[64]; + char actual_hex[129]; - sodium_bin2hex(hex, sizeof hex, data, len); - printf("%s\n", hex); + sodium_hex2bin(expected, sizeof expected, expected_hex, strlen(expected_hex), NULL, NULL, NULL); + if (memcmp(actual, expected, len) != 0) { + sodium_bin2hex(actual_hex, sizeof actual_hex, actual, len); + printf("FAILED %s: expected %s, got %s\n", test_name, expected_hex, actual_hex); + return 1; + } + printf("OK: %s\n", test_name); + return 0; } int @@ -41,213 +49,278 @@ main(void) printf("crypto_ipcrypt_PFX_KEYBYTES: %zu\n", crypto_ipcrypt_pfx_keybytes()); printf("crypto_ipcrypt_PFX_BYTES: %zu\n", crypto_ipcrypt_pfx_bytes()); - /* Test 1: Format-preserving encryption with known key/input */ - memset(key, 0x00, sizeof key); - key[0] = 0x01; - key[1] = 0x02; - key[2] = 0x03; - key[3] = 0x04; - key[4] = 0x05; - key[5] = 0x06; - key[6] = 0x07; - key[7] = 0x08; - key[8] = 0x09; - key[9] = 0x0a; - key[10] = 0x0b; - key[11] = 0x0c; - key[12] = 0x0d; - key[13] = 0x0e; - key[14] = 0x0f; - key[15] = 0x10; + printf("\nipcrypt-deterministic test vectors\n"); - /* IPv4-mapped IPv6 address: ::ffff:192.0.2.1 */ - memset(input, 0x00, sizeof input); + sodium_hex2bin(key, sizeof key, "0123456789abcdeffedcba9876543210", 32, NULL, NULL, NULL); + memset(input, 0, sizeof input); input[10] = 0xff; input[11] = 0xff; - input[12] = 0xc0; /* 192 */ - input[13] = 0x00; /* 0 */ - input[14] = 0x02; /* 2 */ - input[15] = 0x01; /* 1 */ - - printf("\nTest 1: Format-preserving encryption\n"); - printf("Key: "); - dump_hex(key, sizeof key); - printf("Input: "); - dump_hex(input, sizeof input); crypto_ipcrypt_encrypt(output, input, key); - printf("Encrypted: "); - dump_hex(output, sizeof output); - - crypto_ipcrypt_decrypt(decrypted, output, key); - printf("Decrypted: "); - dump_hex(decrypted, sizeof decrypted); - - if (memcmp(input, decrypted, sizeof input) != 0) { - printf("FAILED: Decrypted does not match input\n"); + if (check_expected("deterministic vector 1 (0.0.0.0)", output, + "bde96789d353824cd7c6f58a6bd226eb", 16) != 0) { + return 1; + } + crypto_ipcrypt_decrypt(decrypted, output, key); + if (memcmp(input, decrypted, sizeof input) != 0) { + printf("FAILED: deterministic vector 1 round-trip\n"); return 1; } - printf("OK: Round-trip successful\n"); - /* Test 2: Non-deterministic encryption (ND mode with 8-byte tweak) */ - memset(tweak_nd, 0, sizeof tweak_nd); - tweak_nd[0] = 0xaa; - tweak_nd[1] = 0xbb; - tweak_nd[2] = 0xcc; - tweak_nd[3] = 0xdd; - tweak_nd[4] = 0xee; - tweak_nd[5] = 0xff; - tweak_nd[6] = 0x11; - tweak_nd[7] = 0x22; + sodium_hex2bin(key, sizeof key, "1032547698badcfeefcdab8967452301", 32, NULL, NULL, NULL); + memset(input, 0, sizeof input); + input[10] = 0xff; + input[11] = 0xff; + input[12] = 0xff; + input[13] = 0xff; + input[14] = 0xff; + input[15] = 0xff; - printf("\nTest 2: Non-deterministic encryption (ND mode)\n"); - printf("Tweak: "); - dump_hex(tweak_nd, sizeof tweak_nd); + crypto_ipcrypt_encrypt(output, input, key); + if (check_expected("deterministic vector 2 (255.255.255.255)", output, + "aed292f6ea2358c348fd08b874e845d8", 16) != 0) { + return 1; + } + crypto_ipcrypt_decrypt(decrypted, output, key); + if (memcmp(input, decrypted, sizeof input) != 0) { + printf("FAILED: deterministic vector 2 round-trip\n"); + return 1; + } + + sodium_hex2bin(key, sizeof key, "2b7e151628aed2a6abf7158809cf4f3c", 32, NULL, NULL, NULL); + memset(input, 0, sizeof input); + input[10] = 0xff; + input[11] = 0xff; + input[12] = 192; + input[13] = 0; + input[14] = 2; + input[15] = 1; + + crypto_ipcrypt_encrypt(output, input, key); + if (check_expected("deterministic vector 3 (192.0.2.1)", output, + "1dbdc1b9fff175867d0b67b4e76e4777", 16) != 0) { + return 1; + } + crypto_ipcrypt_decrypt(decrypted, output, key); + if (memcmp(input, decrypted, sizeof input) != 0) { + printf("FAILED: deterministic vector 3 round-trip\n"); + return 1; + } + + printf("\nipcrypt-nd test vectors\n"); + + sodium_hex2bin(key, sizeof key, "0123456789abcdeffedcba9876543210", 32, NULL, NULL, NULL); + sodium_hex2bin(tweak_nd, sizeof tweak_nd, "08e0c289bff23b7c", 16, NULL, NULL, NULL); + memset(input, 0, sizeof input); + input[10] = 0xff; + input[11] = 0xff; crypto_ipcrypt_nd_encrypt(nd_output, input, tweak_nd, key); - printf("ND Encrypted: "); - dump_hex(nd_output, sizeof nd_output); - - crypto_ipcrypt_nd_decrypt(decrypted, nd_output, key); - printf("ND Decrypted: "); - dump_hex(decrypted, sizeof decrypted); - - if (memcmp(input, decrypted, sizeof input) != 0) { - printf("FAILED: ND decrypted does not match input\n"); + if (check_expected("nd vector 1 (0.0.0.0)", nd_output, + "08e0c289bff23b7cb349aadfe3bcef56221c384c7c217b16", 24) != 0) { return 1; } - printf("OK: ND round-trip successful\n"); - - /* Test 3: Non-deterministic encryption with extended tweak (NDX mode) */ - memset(ndx_key, 0x00, sizeof ndx_key); - for (i = 0; i < sizeof ndx_key; i++) { - ndx_key[i] = (unsigned char) (i + 1); + crypto_ipcrypt_nd_decrypt(decrypted, nd_output, key); + if (memcmp(input, decrypted, sizeof input) != 0) { + printf("FAILED: nd vector 1 round-trip\n"); + return 1; } - memset(tweak_ndx, 0, sizeof tweak_ndx); - for (i = 0; i < sizeof tweak_ndx; i++) { - tweak_ndx[i] = (unsigned char) (0xaa + i); + sodium_hex2bin(key, sizeof key, "1032547698badcfeefcdab8967452301", 32, NULL, NULL, NULL); + sodium_hex2bin(tweak_nd, sizeof tweak_nd, "21bd1834bc088cd2", 16, NULL, NULL, NULL); + memset(input, 0, sizeof input); + input[10] = 0xff; + input[11] = 0xff; + input[12] = 192; + input[13] = 0; + input[14] = 2; + input[15] = 1; + + crypto_ipcrypt_nd_encrypt(nd_output, input, tweak_nd, key); + if (check_expected("nd vector 2 (192.0.2.1)", nd_output, + "21bd1834bc088cd2e5e1fe55f95876e639faae2594a0caad", 24) != 0) { + return 1; + } + crypto_ipcrypt_nd_decrypt(decrypted, nd_output, key); + if (memcmp(input, decrypted, sizeof input) != 0) { + printf("FAILED: nd vector 2 round-trip\n"); + return 1; } - printf("\nTest 3: Non-deterministic encryption (NDX mode with 16-byte tweak)\n"); - printf("NDX Key: "); - dump_hex(ndx_key, sizeof ndx_key); - printf("NDX Tweak: "); - dump_hex(tweak_ndx, sizeof tweak_ndx); + sodium_hex2bin(key, sizeof key, "2b7e151628aed2a6abf7158809cf4f3c", 32, NULL, NULL, NULL); + sodium_hex2bin(tweak_nd, sizeof tweak_nd, "b4ecbe30b70898d7", 16, NULL, NULL, NULL); + memset(input, 0, sizeof input); + input[0] = 0x20; + input[1] = 0x01; + input[2] = 0x0d; + input[3] = 0xb8; + input[15] = 0x01; + + crypto_ipcrypt_nd_encrypt(nd_output, input, tweak_nd, key); + if (check_expected("nd vector 3 (2001:db8::1)", nd_output, + "b4ecbe30b70898d7553ac8974d1b4250eafc4b0aa1f80c96", 24) != 0) { + return 1; + } + crypto_ipcrypt_nd_decrypt(decrypted, nd_output, key); + if (memcmp(input, decrypted, sizeof input) != 0) { + printf("FAILED: nd vector 3 round-trip\n"); + return 1; + } + + printf("\nipcrypt-ndx test vectors\n"); + + sodium_hex2bin(ndx_key, sizeof ndx_key, + "0123456789abcdeffedcba98765432101032547698badcfeefcdab8967452301", 64, NULL, + NULL, NULL); + sodium_hex2bin(tweak_ndx, sizeof tweak_ndx, "21bd1834bc088cd2b4ecbe30b70898d7", 32, NULL, NULL, + NULL); + memset(input, 0, sizeof input); + input[10] = 0xff; + input[11] = 0xff; crypto_ipcrypt_ndx_encrypt(ndx_output, input, tweak_ndx, ndx_key); - printf("NDX Encrypted: "); - dump_hex(ndx_output, sizeof ndx_output); - + if (check_expected("ndx vector 1 (0.0.0.0)", ndx_output, + "21bd1834bc088cd2b4ecbe30b70898d782db0d4125fdace61db35b8339f20ee5", + 32) != 0) { + return 1; + } crypto_ipcrypt_ndx_decrypt(decrypted, ndx_output, ndx_key); - printf("NDX Decrypted: "); - dump_hex(decrypted, sizeof decrypted); - if (memcmp(input, decrypted, sizeof input) != 0) { - printf("FAILED: NDX decrypted does not match input\n"); + printf("FAILED: ndx vector 1 round-trip\n"); return 1; } - printf("OK: NDX round-trip successful\n"); - /* Test 4: Keygen functions - skip random output in .exp */ - printf("\nTest 4: Key generation\n"); - crypto_ipcrypt_keygen(key); - printf("Random key generated (skipped in output)\n"); + sodium_hex2bin(ndx_key, sizeof ndx_key, + "1032547698badcfeefcdab89674523010123456789abcdeffedcba9876543210", 64, NULL, + NULL, NULL); + sodium_hex2bin(tweak_ndx, sizeof tweak_ndx, "08e0c289bff23b7cb4ecbe30b70898d7", 32, NULL, NULL, + NULL); + memset(input, 0, sizeof input); + input[10] = 0xff; + input[11] = 0xff; + input[12] = 192; + input[13] = 0; + input[14] = 2; + input[15] = 1; - crypto_ipcrypt_ndx_keygen(ndx_key); - printf("Random NDX key generated (skipped in output)\n"); - - /* Test 5: Different inputs produce different outputs */ - printf("\nTest 5: Different inputs produce different outputs\n"); - memset(key, 0x42, sizeof key); - - for (i = 0; i < 4; i++) { - memset(input, 0, sizeof input); - input[10] = 0xff; - input[11] = 0xff; - input[15] = (unsigned char) i; - - crypto_ipcrypt_encrypt(output, input, key); - printf("Input[%zu]: ", i); - dump_hex(input, sizeof input); - dump_hex(output, sizeof output); - } - - /* Test 6: Verify deterministic encryption */ - printf("\nTest 6: Verify deterministic encryption\n"); - memset(key, 0x55, sizeof key); - memset(input, 0xaa, sizeof input); - - crypto_ipcrypt_encrypt(output, input, key); - crypto_ipcrypt_encrypt(decrypted, input, key); - - if (memcmp(output, decrypted, sizeof output) != 0) { - printf("FAILED: Deterministic encryption produced different outputs\n"); + crypto_ipcrypt_ndx_encrypt(ndx_output, input, tweak_ndx, ndx_key); + if (check_expected("ndx vector 2 (192.0.2.1)", ndx_output, + "08e0c289bff23b7cb4ecbe30b70898d7766a533392a69edf1ad0d3ce362ba98a", + 32) != 0) { return 1; } - printf("OK: Deterministic encryption verified\n"); - - printf("\nTest 7: In-place encryption and decryption\n"); - - crypto_ipcrypt_encrypt(output, input, key); - memcpy(decrypted, input, sizeof input); - crypto_ipcrypt_encrypt(decrypted, decrypted, key); - if (memcmp(output, decrypted, sizeof output) != 0) { - printf("FAILED: In-place encryption differs from out-of-place\n"); - return 1; - } - crypto_ipcrypt_decrypt(decrypted, decrypted, key); + crypto_ipcrypt_ndx_decrypt(decrypted, ndx_output, ndx_key); if (memcmp(input, decrypted, sizeof input) != 0) { - printf("FAILED: In-place decryption does not match original\n"); + printf("FAILED: ndx vector 2 round-trip\n"); return 1; } - printf("OK: In-place round-trip successful\n"); - /* Test 8: Prefix-preserving encryption (PFX mode) */ - printf("\nTest 8: Prefix-preserving encryption (PFX mode)\n"); + sodium_hex2bin(ndx_key, sizeof ndx_key, + "2b7e151628aed2a6abf7158809cf4f3c3c4fcf098815f7aba6d2ae2816157e2b", 64, NULL, + NULL, NULL); + sodium_hex2bin(tweak_ndx, sizeof tweak_ndx, "21bd1834bc088cd2b4ecbe30b70898d7", 32, NULL, NULL, + NULL); + memset(input, 0, sizeof input); + input[0] = 0x20; + input[1] = 0x01; + input[2] = 0x0d; + input[3] = 0xb8; + input[15] = 0x01; + + crypto_ipcrypt_ndx_encrypt(ndx_output, input, tweak_ndx, ndx_key); + if (check_expected("ndx vector 3 (2001:db8::1)", ndx_output, + "21bd1834bc088cd2b4ecbe30b70898d76089c7e05ae30c2d10ca149870a263e4", + 32) != 0) { + return 1; + } + crypto_ipcrypt_ndx_decrypt(decrypted, ndx_output, ndx_key); + if (memcmp(input, decrypted, sizeof input) != 0) { + printf("FAILED: ndx vector 3 round-trip\n"); + return 1; + } + + printf("\nipcrypt-pfx test vectors\n"); - /* Test vector from the specification: - * Key: 0123456789abcdeffedcba98765432101032547698badcfeefcdab8967452301 - * Input IP: 0.0.0.0 (IPv4-mapped) - * Expected: 151.82.155.134 - */ sodium_hex2bin(pfx_key, sizeof pfx_key, - "0123456789abcdeffedcba98765432101032547698badcfeefcdab8967452301", - 64, NULL, NULL, NULL); + "0123456789abcdeffedcba98765432101032547698badcfeefcdab8967452301", 64, NULL, + NULL, NULL); + memset(input, 0, sizeof input); + input[10] = 0xff; + input[11] = 0xff; + + crypto_ipcrypt_pfx_encrypt(pfx_output, input, pfx_key); + if (check_expected("pfx vector 1 (0.0.0.0)", pfx_output, "00000000000000000000ffff97529b86", + 16) != 0) { + return 1; + } + crypto_ipcrypt_pfx_decrypt(decrypted, pfx_output, pfx_key); + if (memcmp(input, decrypted, sizeof input) != 0) { + printf("FAILED: pfx vector 1 round-trip\n"); + return 1; + } memset(input, 0, sizeof input); input[10] = 0xff; input[11] = 0xff; - /* 0.0.0.0 */ - - printf("PFX Key: "); - dump_hex(pfx_key, sizeof pfx_key); - printf("Input (0.0.0.0): "); - dump_hex(input, sizeof input); + input[12] = 255; + input[13] = 255; + input[14] = 255; + input[15] = 255; crypto_ipcrypt_pfx_encrypt(pfx_output, input, pfx_key); - printf("PFX Encrypted: "); - dump_hex(pfx_output, sizeof pfx_output); - - crypto_ipcrypt_pfx_decrypt(decrypted, pfx_output, pfx_key); - printf("PFX Decrypted: "); - dump_hex(decrypted, sizeof decrypted); - - if (memcmp(input, decrypted, sizeof input) != 0) { - printf("FAILED: PFX decrypted does not match input\n"); + if (check_expected("pfx vector 2 (255.255.255.255)", pfx_output, + "00000000000000000000ffff5eb9a959", 16) != 0) { + return 1; + } + crypto_ipcrypt_pfx_decrypt(decrypted, pfx_output, pfx_key); + if (memcmp(input, decrypted, sizeof input) != 0) { + printf("FAILED: pfx vector 2 round-trip\n"); return 1; } - printf("OK: PFX round-trip successful\n"); - /* Test 9: Verify prefix preservation - IPs in same /24 should share encrypted prefix */ - printf("\nTest 9: Verify prefix preservation\n"); + memset(input, 0, sizeof input); + input[10] = 0xff; + input[11] = 0xff; + input[12] = 192; + input[13] = 0; + input[14] = 2; + input[15] = 1; + + crypto_ipcrypt_pfx_encrypt(pfx_output, input, pfx_key); + if (check_expected("pfx vector 3 (192.0.2.1)", pfx_output, "00000000000000000000ffff64734883", + 16) != 0) { + return 1; + } + crypto_ipcrypt_pfx_decrypt(decrypted, pfx_output, pfx_key); + if (memcmp(input, decrypted, sizeof input) != 0) { + printf("FAILED: pfx vector 3 round-trip\n"); + return 1; + } + + memset(input, 0, sizeof input); + input[0] = 0x20; + input[1] = 0x01; + input[2] = 0x0d; + input[3] = 0xb8; + input[15] = 0x01; + + crypto_ipcrypt_pfx_encrypt(pfx_output, input, pfx_key); + if (check_expected("pfx vector 4 (2001:db8::1)", pfx_output, "c1805dd42587352430abfa656ab60f88", + 16) != 0) { + return 1; + } + crypto_ipcrypt_pfx_decrypt(decrypted, pfx_output, pfx_key); + if (memcmp(input, decrypted, sizeof input) != 0) { + printf("FAILED: pfx vector 4 round-trip\n"); + return 1; + } + + printf("\nipcrypt-pfx prefix preservation\n"); - /* Use test vector key from spec */ sodium_hex2bin(pfx_key, sizeof pfx_key, - "2b7e151628aed2a6abf7158809cf4f3ca9f5ba40db214c3798f2e1c23456789a", - 64, NULL, NULL, NULL); + "2b7e151628aed2a6abf7158809cf4f3ca9f5ba40db214c3798f2e1c23456789a", 64, NULL, + NULL, NULL); - /* 10.0.0.47 */ memset(input, 0, sizeof input); input[10] = 0xff; input[11] = 0xff; @@ -256,63 +329,263 @@ main(void) input[14] = 0; input[15] = 47; - crypto_ipcrypt_pfx_encrypt(encrypted1, input, pfx_key); - printf("10.0.0.47 encrypted: "); - dump_hex(encrypted1, sizeof encrypted1); - - /* 10.0.0.129 */ - input[15] = 129; - - crypto_ipcrypt_pfx_encrypt(encrypted2, input, pfx_key); - printf("10.0.0.129 encrypted: "); - dump_hex(encrypted2, sizeof encrypted2); - - /* Check that the first 24 bits of the encrypted IPv4 addresses match (bytes 12-14) */ - if (memcmp(encrypted1 + 12, encrypted2 + 12, 3) != 0) { - printf("FAILED: Prefix not preserved for /24 addresses\n"); + crypto_ipcrypt_pfx_encrypt(pfx_output, input, pfx_key); + if (check_expected("pfx /24 test (10.0.0.47)", pfx_output, "00000000000000000000ffff13d6d2f4", + 16) != 0) { return 1; } - printf("OK: /24 prefix preserved\n"); - /* Test 10: PFX keygen */ - printf("\nTest 10: PFX key generation\n"); - crypto_ipcrypt_pfx_keygen(pfx_key); - printf("Random PFX key generated (skipped in output)\n"); + input[15] = 129; + crypto_ipcrypt_pfx_encrypt(encrypted1, input, pfx_key); + if (check_expected("pfx /24 test (10.0.0.129)", encrypted1, "00000000000000000000ffff13d6d250", + 16) != 0) { + return 1; + } - /* Test 11: IPv6 prefix preservation */ - printf("\nTest 11: IPv6 prefix-preserving encryption\n"); + input[15] = 234; + crypto_ipcrypt_pfx_encrypt(encrypted2, input, pfx_key); + if (check_expected("pfx /24 test (10.0.0.234)", encrypted2, "00000000000000000000ffff13d6d21e", + 16) != 0) { + return 1; + } - sodium_hex2bin(pfx_key, sizeof pfx_key, - "2b7e151628aed2a6abf7158809cf4f3ca9f5ba40db214c3798f2e1c23456789a", - 64, NULL, NULL, NULL); + if (memcmp(pfx_output + 12, encrypted1 + 12, 3) != 0 || + memcmp(pfx_output + 12, encrypted2 + 12, 3) != 0) { + printf("FAILED: IPv4 /24 prefix not preserved\n"); + return 1; + } + printf("OK: IPv4 /24 prefix preserved for 10.0.0.x\n"); - /* 2001:db8::1 */ memset(input, 0, sizeof input); - input[0] = 0x20; - input[1] = 0x01; - input[2] = 0x0d; - input[3] = 0xb8; - input[15] = 0x01; + input[10] = 0xff; + input[11] = 0xff; + input[12] = 172; + input[13] = 16; + input[14] = 5; + input[15] = 193; + + crypto_ipcrypt_pfx_encrypt(pfx_output, input, pfx_key); + if (check_expected("pfx /16 test (172.16.5.193)", pfx_output, + "00000000000000000000ffffd24ee588", 16) != 0) { + return 1; + } + + input[14] = 97; + input[15] = 42; + crypto_ipcrypt_pfx_encrypt(encrypted1, input, pfx_key); + if (check_expected("pfx /16 test (172.16.97.42)", encrypted1, + "00000000000000000000ffffd24eb3f1", 16) != 0) { + return 1; + } + + input[14] = 248; + input[15] = 177; + crypto_ipcrypt_pfx_encrypt(encrypted2, input, pfx_key); + if (check_expected("pfx /16 test (172.16.248.177)", encrypted2, + "00000000000000000000ffffd24e79d7", 16) != 0) { + return 1; + } + + if (memcmp(pfx_output + 12, encrypted1 + 12, 2) != 0 || + memcmp(pfx_output + 12, encrypted2 + 12, 2) != 0) { + printf("FAILED: IPv4 /16 prefix not preserved\n"); + return 1; + } + printf("OK: IPv4 /16 prefix preserved for 172.16.x.x\n"); + + /* 2001:db8::a5c9:4e2f:bb91:5a7d */ + memset(input, 0, sizeof input); + input[0] = 0x20; + input[1] = 0x01; + input[2] = 0x0d; + input[3] = 0xb8; + input[8] = 0xa5; + input[9] = 0xc9; + input[10] = 0x4e; + input[11] = 0x2f; + input[12] = 0xbb; + input[13] = 0x91; + input[14] = 0x5a; + input[15] = 0x7d; + + crypto_ipcrypt_pfx_encrypt(pfx_output, input, pfx_key); + if (check_expected("pfx /64 test (2001:db8::a5c9:4e2f:bb91:5a7d)", pfx_output, + "7cec702c12430f7019560125b9bd1aba", 16) != 0) { + return 1; + } + + /* 2001:db8::7234:d8f1:3c6e:9a52 */ + memset(input, 0, sizeof input); + input[0] = 0x20; + input[1] = 0x01; + input[2] = 0x0d; + input[3] = 0xb8; + input[8] = 0x72; + input[9] = 0x34; + input[10] = 0xd8; + input[11] = 0xf1; + input[12] = 0x3c; + input[13] = 0x6e; + input[14] = 0x9a; + input[15] = 0x52; crypto_ipcrypt_pfx_encrypt(encrypted1, input, pfx_key); - printf("2001:db8::1 encrypted: "); - dump_hex(encrypted1, sizeof encrypted1); + if (check_expected("pfx /64 test (2001:db8::7234:d8f1:3c6e:9a52)", encrypted1, + "7cec702c12430f70a3ef0c8e95c1cd0d", 16) != 0) { + return 1; + } - /* 2001:db8::2 */ - input[15] = 0x02; + /* 2001:db8::f1e0:937b:26d4:8c1a */ + memset(input, 0, sizeof input); + input[0] = 0x20; + input[1] = 0x01; + input[2] = 0x0d; + input[3] = 0xb8; + input[8] = 0xf1; + input[9] = 0xe0; + input[10] = 0x93; + input[11] = 0x7b; + input[12] = 0x26; + input[13] = 0xd4; + input[14] = 0x8c; + input[15] = 0x1a; crypto_ipcrypt_pfx_encrypt(encrypted2, input, pfx_key); - printf("2001:db8::2 encrypted: "); - dump_hex(encrypted2, sizeof encrypted2); + if (check_expected("pfx /64 test (2001:db8::f1e0:937b:26d4:8c1a)", encrypted2, + "7cec702c12430f70443c0c8e6a62b64d", 16) != 0) { + return 1; + } - /* Check that the first 64 bits match (bytes 0-7 for /64 prefix) */ - if (memcmp(encrypted1, encrypted2, 8) != 0) { + if (memcmp(pfx_output, encrypted1, 8) != 0 || memcmp(pfx_output, encrypted2, 8) != 0) { printf("FAILED: IPv6 /64 prefix not preserved\n"); return 1; } - printf("OK: IPv6 /64 prefix preserved\n"); + printf("OK: IPv6 /64 prefix preserved for 2001:db8::/64\n"); - printf("\nAll tests passed!\n"); + /* 2001:db8:3a5c:0:e7d1:4b9f:2c8a:f673 */ + memset(input, 0, sizeof input); + input[0] = 0x20; + input[1] = 0x01; + input[2] = 0x0d; + input[3] = 0xb8; + input[4] = 0x3a; + input[5] = 0x5c; + input[8] = 0xe7; + input[9] = 0xd1; + input[10] = 0x4b; + input[11] = 0x9f; + input[12] = 0x2c; + input[13] = 0x8a; + input[14] = 0xf6; + input[15] = 0x73; + + crypto_ipcrypt_pfx_encrypt(pfx_output, input, pfx_key); + if (check_expected("pfx /32 test (2001:db8:3a5c:0:e7d1:4b9f:2c8a:f673)", pfx_output, + "7cec702c35030befe61696bdbe33a9b9", 16) != 0) { + return 1; + } + + /* 2001:db8:9f27:0:b4e2:7a3d:5f91:c8e6 */ + memset(input, 0, sizeof input); + input[0] = 0x20; + input[1] = 0x01; + input[2] = 0x0d; + input[3] = 0xb8; + input[4] = 0x9f; + input[5] = 0x27; + input[8] = 0xb4; + input[9] = 0xe2; + input[10] = 0x7a; + input[11] = 0x3d; + input[12] = 0x5f; + input[13] = 0x91; + input[14] = 0xc8; + input[15] = 0xe6; + + crypto_ipcrypt_pfx_encrypt(encrypted1, input, pfx_key); + if (check_expected("pfx /32 test (2001:db8:9f27:0:b4e2:7a3d:5f91:c8e6)", encrypted1, + "7cec702ca504b74e194a3d90b0472d1a", 16) != 0) { + return 1; + } + + /* 2001:db8:d8b4:0:193c:a5e7:8b2f:46d1 */ + memset(input, 0, sizeof input); + input[0] = 0x20; + input[1] = 0x01; + input[2] = 0x0d; + input[3] = 0xb8; + input[4] = 0xd8; + input[5] = 0xb4; + input[8] = 0x19; + input[9] = 0x3c; + input[10] = 0xa5; + input[11] = 0xe7; + input[12] = 0x8b; + input[13] = 0x2f; + input[14] = 0x46; + input[15] = 0xd1; + + crypto_ipcrypt_pfx_encrypt(encrypted2, input, pfx_key); + if (check_expected("pfx /32 test (2001:db8:d8b4:0:193c:a5e7:8b2f:46d1)", encrypted2, + "7cec702cf840aa6701b8e84fac9d77fb", 16) != 0) { + return 1; + } + + if (memcmp(pfx_output, encrypted1, 4) != 0 || memcmp(pfx_output, encrypted2, 4) != 0) { + printf("FAILED: IPv6 /32 prefix not preserved\n"); + return 1; + } + printf("OK: IPv6 /32 prefix preserved for 2001:db8::/32\n"); + + printf("\nfunctional tests\n"); + + crypto_ipcrypt_keygen(key); + crypto_ipcrypt_ndx_keygen(ndx_key); + crypto_ipcrypt_pfx_keygen(pfx_key); + printf("OK: Key generation functions\n"); + + memset(key, 0x55, sizeof key); + memset(input, 0xaa, sizeof input); + crypto_ipcrypt_encrypt(output, input, key); + memcpy(decrypted, input, sizeof input); + crypto_ipcrypt_encrypt(decrypted, decrypted, key); + if (memcmp(output, decrypted, sizeof output) != 0) { + printf("FAILED: In-place encryption differs\n"); + return 1; + } + crypto_ipcrypt_decrypt(decrypted, decrypted, key); + if (memcmp(input, decrypted, sizeof input) != 0) { + printf("FAILED: In-place round-trip\n"); + return 1; + } + printf("OK: In-place encryption/decryption\n"); + + crypto_ipcrypt_encrypt(output, input, key); + crypto_ipcrypt_encrypt(decrypted, input, key); + if (memcmp(output, decrypted, sizeof output) != 0) { + printf("FAILED: Deterministic encryption\n"); + return 1; + } + printf("OK: Deterministic encryption\n"); + + memset(key, 0x42, sizeof key); + for (i = 0; i < 4; i++) { + memset(input, 0, sizeof input); + input[10] = 0xff; + input[11] = 0xff; + input[15] = (unsigned char) i; + crypto_ipcrypt_encrypt(output, input, key); + if (i > 0) { + if (memcmp(output, decrypted, sizeof output) == 0) { + printf("FAILED: Different inputs produced same output\n"); + return 1; + } + } + memcpy(decrypted, output, sizeof output); + } + printf("OK: Different inputs produce different outputs\n"); + + printf("\nAll specification test vectors passed!\n"); return 0; } diff --git a/test/default/ipcrypt.exp b/test/default/ipcrypt.exp index 8ba7e879..68e87dae 100644 --- a/test/default/ipcrypt.exp +++ b/test/default/ipcrypt.exp @@ -11,64 +11,49 @@ crypto_ipcrypt_NDX_OUTPUTBYTES: 32 crypto_ipcrypt_PFX_KEYBYTES: 32 crypto_ipcrypt_PFX_BYTES: 16 -Test 1: Format-preserving encryption -Key: 0102030405060708090a0b0c0d0e0f10 -Input: 00000000000000000000ffffc0000201 -Encrypted: 574549939d262d3dc317324ac05a8d59 -Decrypted: 00000000000000000000ffffc0000201 -OK: Round-trip successful +ipcrypt-deterministic test vectors +OK: deterministic vector 1 (0.0.0.0) +OK: deterministic vector 2 (255.255.255.255) +OK: deterministic vector 3 (192.0.2.1) -Test 2: Non-deterministic encryption (ND mode) -Tweak: aabbccddeeff1122 -ND Encrypted: aabbccddeeff1122377e9a17198d908604f3261d45fd639a -ND Decrypted: 00000000000000000000ffffc0000201 -OK: ND round-trip successful +ipcrypt-nd test vectors +OK: nd vector 1 (0.0.0.0) +OK: nd vector 2 (192.0.2.1) +OK: nd vector 3 (2001:db8::1) -Test 3: Non-deterministic encryption (NDX mode with 16-byte tweak) -NDX Key: 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 -NDX Tweak: aaabacadaeafb0b1b2b3b4b5b6b7b8b9 -NDX Encrypted: aaabacadaeafb0b1b2b3b4b5b6b7b8b97df52c417f76ef314bbe7bea5b30bcea -NDX Decrypted: 00000000000000000000ffffc0000201 -OK: NDX round-trip successful +ipcrypt-ndx test vectors +OK: ndx vector 1 (0.0.0.0) +OK: ndx vector 2 (192.0.2.1) +OK: ndx vector 3 (2001:db8::1) -Test 4: Key generation -Random key generated (skipped in output) -Random NDX key generated (skipped in output) +ipcrypt-pfx test vectors +OK: pfx vector 1 (0.0.0.0) +OK: pfx vector 2 (255.255.255.255) +OK: pfx vector 3 (192.0.2.1) +OK: pfx vector 4 (2001:db8::1) -Test 5: Different inputs produce different outputs -Input[0]: 00000000000000000000ffff00000000 -05406dbec71c4163c3033a3a76b9ebad -Input[1]: 00000000000000000000ffff00000001 -1672fc1d4626d0db668088eb5b54a40e -Input[2]: 00000000000000000000ffff00000002 -748c9d664ca12e3669ae344a280202c8 -Input[3]: 00000000000000000000ffff00000003 -524ca1315033ea4509bbaabf93c3ec80 +ipcrypt-pfx prefix preservation +OK: pfx /24 test (10.0.0.47) +OK: pfx /24 test (10.0.0.129) +OK: pfx /24 test (10.0.0.234) +OK: IPv4 /24 prefix preserved for 10.0.0.x +OK: pfx /16 test (172.16.5.193) +OK: pfx /16 test (172.16.97.42) +OK: pfx /16 test (172.16.248.177) +OK: IPv4 /16 prefix preserved for 172.16.x.x +OK: pfx /64 test (2001:db8::a5c9:4e2f:bb91:5a7d) +OK: pfx /64 test (2001:db8::7234:d8f1:3c6e:9a52) +OK: pfx /64 test (2001:db8::f1e0:937b:26d4:8c1a) +OK: IPv6 /64 prefix preserved for 2001:db8::/64 +OK: pfx /32 test (2001:db8:3a5c:0:e7d1:4b9f:2c8a:f673) +OK: pfx /32 test (2001:db8:9f27:0:b4e2:7a3d:5f91:c8e6) +OK: pfx /32 test (2001:db8:d8b4:0:193c:a5e7:8b2f:46d1) +OK: IPv6 /32 prefix preserved for 2001:db8::/32 -Test 6: Verify deterministic encryption -OK: Deterministic encryption verified +functional tests +OK: Key generation functions +OK: In-place encryption/decryption +OK: Deterministic encryption +OK: Different inputs produce different outputs -Test 7: In-place encryption and decryption -OK: In-place round-trip successful - -Test 8: Prefix-preserving encryption (PFX mode) -PFX Key: 0123456789abcdeffedcba98765432101032547698badcfeefcdab8967452301 -Input (0.0.0.0): 00000000000000000000ffff00000000 -PFX Encrypted: 00000000000000000000ffff97529b86 -PFX Decrypted: 00000000000000000000ffff00000000 -OK: PFX round-trip successful - -Test 9: Verify prefix preservation -10.0.0.47 encrypted: 00000000000000000000ffff13d6d2f4 -10.0.0.129 encrypted: 00000000000000000000ffff13d6d250 -OK: /24 prefix preserved - -Test 10: PFX key generation -Random PFX key generated (skipped in output) - -Test 11: IPv6 prefix-preserving encryption -2001:db8::1 encrypted: 7cec702c12430f70d5ff5bae0021b09b -2001:db8::2 encrypted: 7cec702c12430f70d5ff5bae0021b098 -OK: IPv6 /64 prefix preserved - -All tests passed! +All specification test vectors passed!