Cleanup the ipcrypt tests

This commit is contained in:
Frank Denis
2025-12-30 12:00:40 +01:00
parent 3f02fdaea1
commit 245b63bfcf
2 changed files with 520 additions and 262 deletions
+480 -207
View File
@@ -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;
}
+40 -55
View File
@@ -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!