mirror of
https://github.com/jedisct1/libsodium.git
synced 2026-08-25 08:37:13 +09:00
Cleanup the ipcrypt tests
This commit is contained in:
+480
-207
@@ -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
@@ -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!
|
||||
|
||||
Reference in New Issue
Block a user