#include #include #include #include #include #include "EverCrypt.h" #include "quic_provider.h" #ifndef CDECL #if _WIN32 #define CDECL __cdecl #else #define CDECL #endif #endif void dump(const unsigned char buffer[], size_t len) { size_t i; for(i=0; ihash], aead_to_name[secret->ae]); result = quic_crypto_derive_key(&key, secret); if (result == 0) { printf("FAIL: quic_crypto_derive_key failed\n"); exit(1); } memset(cipher, 0, sizeof(cipher)); result = quic_crypto_encrypt(key, cipher, sn, ad, ad_len, plain, plain_len); if (result == 0) { printf("FAIL: quic_crypto_encrypt failed\n"); exit(1); } #if 0 // Capture expected results to files ready to paste into C source code char fname[64]; sprintf(fname, "results_%d_%d", secret->hash, secret->ae); FILE *fp = fopen(fname, "w"); dumptofile(fp, cipher, sizeof(cipher)); fclose(fp); #else // Verify that the computed text matches expectations check_result("quic_crypto_encrypt", cipher, expected_cipher, sizeof(cipher)); #endif unsigned char decrypted[plain_len]; result = quic_crypto_decrypt(key, decrypted, sn, ad, ad_len, cipher, sizeof(cipher)); if (result == 0) { printf("FAIL: quic_crypto_decrypt failed\n"); exit(1); } check_result("quic_crypto_decrypt", decrypted, plain, sizeof(decrypted)); result = quic_crypto_free_key(key); if (result == 0) { printf("FAIL: quic_crypto_free_key failed\n"); exit(1); } printf("PASS\n"); } const uint8_t expected_client_hs[] = { // client_hs (draft 19) 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xf5,0x2b,0x9b,0x3a,0xe4,0x67,0x7a, 0x63,0x67,0xa7,0x74,0x12,0xb1,0x9d,0xdb,0xf1,0x54,0xc9,0xa2,0x55,0xea,0xf8,0x77, 0x18,0x9d,0x96,0x09,0xad,0x5c,0x82,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; const uint8_t expected_server_hs[] = { // server_hs (draft 19) 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9a,0x52,0x97,0x7b,0xea,0xd3,0x53,0xc0, 0x8e,0xd7,0x6f,0x54,0x28,0xdb,0x69,0x3f,0xdb,0x74,0x5c,0x0d,0xbe,0xde,0xa2,0x23, 0xf0,0x1f,0x67,0xe5,0xf3,0x4c,0xb6,0xee,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; void test_pn_encrypt() { printf("==== test_pn_encrypt() ====\n"); quic_secret client_hs; memset(&client_hs, 0, sizeof(client_hs)); quic_secret server_hs; memset(&server_hs, 0, sizeof(server_hs)); quic_key *key; int result, i; /* From Quicly & picoquic test vectors */ static const uint8_t cid[] = { 0x77, 0x0d, 0xc2, 0x6c, 0x17, 0x50, 0x9b, 0x35 }; static const uint8_t salt[] = { 0xef, 0x4f, 0xb0, 0xab, 0xb4, 0x74, 0x70, 0xc4, 0x1b, 0xef, 0xcf, 0x80, 0x31, 0x33, 0x4f, 0xae, 0x48, 0x5e, 0x09, 0xa0 }; static const uint8_t sample[] = { 0x05, 0x80, 0x24, 0xa9, 0x72, 0x75, 0xf0, 0x1d, 0x2a, 0x1e, 0xc9, 0x1f, 0xd1, 0xc2, 0x65, 0xbb }; static const uint8_t encrypted_pn[] = { 0x70, 0x61, 0x87, 0x5e, 0x08 }; static const uint8_t expected_pn[] = { 0xc0, 0x00, 0x00, 0x00, 0x00 }; uint8_t pnmask[5] = {0}; result = quic_derive_initial_secrets(&client_hs, &server_hs, cid, sizeof(cid), salt, sizeof(salt)); if (result == 0) { printf("FAIL: quic_derive_initial_secrets failed\n"); exit(1); } result = quic_crypto_derive_key(&key, &client_hs); if (result == 0) { printf("FAIL: quic_crypto_derive_key failed\n"); exit(1); } if(quic_crypto_hp_mask(key, sample, pnmask)) { printf("PN encryption mask: "); dump(pnmask, 5); for(i = 0; i < 5; i++) pnmask[i] ^= encrypted_pn[i]; printf("Decrypted PN: "); dump(pnmask, 5); check_result("decrypted PN", pnmask, expected_pn, sizeof(pnmask)); } else { printf("PN encryption failed.\n"); exit(1); } } void test_initial_secrets() { int result; printf("==== test_initial_secrets() ====\n"); quic_secret client_hs; memset(&client_hs, 0, sizeof(client_hs)); quic_secret server_hs; memset(&server_hs, 0, sizeof(server_hs)); const unsigned char con_id[12] = {0xff,0xaa,0x55,0x00, 0x80,0x01,0x7f,0xee, 0x81,0x42,0x24,0x18 }; const unsigned char salt[] = {0xef, 0x4f, 0xb0, 0xab, 0xb4, 0x74, 0x70, 0xc4, 0x1b, 0xef, 0xcf, 0x80, 0x31, 0x33, 0x4f, 0xae, 0x48, 0x5e, 0x09, 0xa0}; result = quic_derive_initial_secrets(&client_hs, &server_hs, con_id, sizeof(con_id), salt, sizeof(salt)); if (result == 0) { printf("FAIL: quic_derive_initial_secrets failed\n"); exit(1); } #if 0 // Capture expected results to files ready to paste into C source code FILE *fp = fopen("client_hs", "w"); dumptofile(fp, (const uint8_t*)&client_hs, sizeof(client_hs)); fclose(fp); fp = fopen("server_hs", "w"); dumptofile(fp, (const uint8_t*)&server_hs, sizeof(server_hs)); fclose(fp); #else // Verify that the computed text matches expectations check_result("quic_derive_initial_secrets client", (const unsigned char*)&client_hs, (const unsigned char*)&expected_client_hs, sizeof(client_hs)); check_result("quic_derive_initial_secrets server", (const unsigned char*)&server_hs, (const unsigned char*)&expected_server_hs, sizeof(server_hs)); #endif printf("==== PASS: test_initial_secrets ==== \n"); } void exhaustive(void) { quic_secret secret; for (unsigned char i=0; i