You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

279 lines
9.7 KiB

// test_etcp_crypto.c - Test ETCP encryption/decryption with secure channel
#include "../src/secure_channel.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
// Forward declaration for ETCP_CONN structure
struct ETCP_CONN {
struct ETCP_CONN* next;
int mtu;
uint8_t state;
struct secure_channel crypto_ctx;
uint64_t peer_node_id;
void* input_queue;
void* output_queue;
void* rx_list;
void* sent_list;
uint16_t rtt_last;
uint16_t rtt_avg_10;
uint16_t rtt_avg_100;
uint16_t jitter;
uint16_t bandwidth;
uint32_t bytes_sent_total;
uint16_t last_sent_timestamp;
uint32_t bytes_allowed;
uint32_t retransmissions_count;
uint32_t ack_packets_count;
uint32_t control_packets_count;
uint32_t total_packets_sent;
uint32_t unique_packets_sent;
uint32_t bytes_received_total;
uint16_t next_tx_id;
uint16_t last_sent_id;
uint16_t last_rx_id;
uint16_t last_delivered_id;
void* next_tx_timer;
void* retransmit_timer;
uint16_t rtt_history[100];
uint8_t rtt_history_idx;
uint8_t rtt_history_count;
uint16_t pending_ack_ids[32];
uint16_t pending_ack_timestamps[32];
uint8_t pending_ack_count;
uint16_t pending_retransmit_ids[32];
uint8_t pending_retransmit_count;
uint32_t unacked_bytes;
uint32_t window_size;
uint16_t last_acked_id;
uint16_t last_rx_ack_id;
uint16_t retrans_timer_period;
uint16_t next_retrans_time;
uint8_t window_blocked;
uint16_t oldest_missing_id;
uint16_t missing_since_time;
};
// Test configuration
#define TEST_DATA "Hello, encrypted world!"
#define TEST_DATA_LEN 23
// Simple test for secure channel encryption/decryption
static int test_secure_channel_crypto(void) {
printf("=== Testing Secure Channel Crypto ===\n");
// Create test keys
struct SC_MYKEYS server_keys, client_keys;
// Use fixed test keys
for (int i = 0; i < SC_PRIVKEY_SIZE; i++) {
server_keys.private_key[i] = i & 0xFF;
client_keys.private_key[i] = (i + 128) & 0xFF;
}
// Generate corresponding public keys (simplified for test)
for (int i = 0; i < SC_PUBKEY_SIZE; i++) {
server_keys.public_key[i] = (i * 2) & 0xFF;
client_keys.public_key[i] = (i * 2 + 1) & 0xFF;
}
// Initialize server context
sc_context_t server_ctx;
if (sc_init_ctx(&server_ctx, &server_keys) != SC_OK) {
printf("ERROR: Failed to initialize server crypto context\n");
return -1;
}
printf("✓ Server crypto context initialized\n");
// Initialize client context
sc_context_t client_ctx;
if (sc_init_ctx(&client_ctx, &client_keys) != SC_OK) {
printf("ERROR: Failed to initialize client crypto context\n");
return -1;
}
printf("✓ Client crypto context initialized\n");
// For this simple test, we'll manually set peer keys, session ready, and session key
// to bypass the ECC key exchange which requires proper ECC initialization
memcpy(client_ctx.peer_public_key, server_keys.public_key, SC_PUBKEY_SIZE);
memcpy(server_ctx.peer_public_key, client_keys.public_key, SC_PUBKEY_SIZE);
client_ctx.peer_key_set = 1;
client_ctx.session_ready = 1; // This is crucial for encryption to work
server_ctx.peer_key_set = 1;
server_ctx.session_ready = 1; // This is crucial for encryption to work
// Set test session keys manually (16 bytes for AES-128)
// In a real implementation, this would be derived from ECDH shared secret
uint8_t test_session_key[SC_SESSION_KEY_SIZE];
for (int i = 0; i < SC_SESSION_KEY_SIZE; i++) {
test_session_key[i] = i + 100;
}
memcpy(client_ctx.session_key, test_session_key, SC_SESSION_KEY_SIZE);
memcpy(server_ctx.session_key, test_session_key, SC_SESSION_KEY_SIZE);
printf("✓ Peer public keys and session keys set manually\n");
// Test data
uint8_t plaintext[] = TEST_DATA;
uint8_t ciphertext[256];
uint8_t decrypted[256];
size_t ciphertext_len, decrypted_len;
// Test encryption from client to server
printf("\n=== Testing Client to Server Encryption ===\n");
if (sc_encrypt(&client_ctx, plaintext, TEST_DATA_LEN, ciphertext, &ciphertext_len) != SC_OK) {
printf("ERROR: Encryption failed\n");
return -1;
}
printf("✓ Encrypted %zu bytes to %zu bytes\n", (size_t)TEST_DATA_LEN, ciphertext_len);
// Test decryption by server
if (sc_decrypt(&server_ctx, ciphertext, ciphertext_len, decrypted, &decrypted_len) != SC_OK) {
printf("ERROR: Decryption failed\n");
return -1;
}
printf("✓ Decrypted %zu bytes\n", decrypted_len);
// Verify decrypted data
if (decrypted_len != TEST_DATA_LEN || memcmp(plaintext, decrypted, TEST_DATA_LEN) != 0) {
printf("ERROR: Decrypted data doesn't match original\n");
printf(" Original: '%.*s'\n", TEST_DATA_LEN, plaintext);
printf(" Decrypted: '%.*s'\n", (int)decrypted_len, decrypted);
return -1;
}
printf("✓ Decrypted data matches original\n");
// Test encryption from server to client
printf("\n=== Testing Server to Client Encryption ===\n");
if (sc_encrypt(&server_ctx, plaintext, TEST_DATA_LEN, ciphertext, &ciphertext_len) != SC_OK) {
printf("ERROR: Server encryption failed\n");
return -1;
}
printf("✓ Server encrypted %zu bytes to %zu bytes\n", (size_t)TEST_DATA_LEN, ciphertext_len);
if (sc_decrypt(&client_ctx, ciphertext, ciphertext_len, decrypted, &decrypted_len) != SC_OK) {
printf("ERROR: Client decryption failed\n");
return -1;
}
printf("✓ Client decrypted %zu bytes\n", decrypted_len);
if (decrypted_len != TEST_DATA_LEN || memcmp(plaintext, decrypted, TEST_DATA_LEN) != 0) {
printf("ERROR: Client decrypted data doesn't match original\n");
return -1;
}
printf("✓ Client decrypted data matches original\n");
// Test with different data
printf("\n=== Testing with Different Data ===\n");
uint8_t test_data2[] = "The quick brown fox jumps over the lazy dog";
size_t test_data2_len = sizeof(test_data2) - 1;
if (sc_encrypt(&client_ctx, test_data2, test_data2_len, ciphertext, &ciphertext_len) != SC_OK) {
printf("ERROR: Encryption of test data 2 failed\n");
return -1;
}
if (sc_decrypt(&server_ctx, ciphertext, ciphertext_len, decrypted, &decrypted_len) != SC_OK) {
printf("ERROR: Decryption of test data 2 failed\n");
return -1;
}
if (decrypted_len != test_data2_len || memcmp(test_data2, decrypted, test_data2_len) != 0) {
printf("ERROR: Test data 2 decryption mismatch\n");
return -1;
}
printf("✓ Different data test passed\n");
printf("\n=== All Crypto Tests Passed! ===\n");
return 0;
}
// Test ETCP connection crypto
static int test_etcp_connection_crypto(void) {
printf("\n=== Testing ETCP Connection Crypto ===\n");
// Create a simple ETCP connection
struct ETCP_CONN* conn = calloc(1, sizeof(struct ETCP_CONN));
if (!conn) {
printf("ERROR: Failed to allocate ETCP connection\n");
return -1;
}
// Initialize connection basic parameters
conn->mtu = 1500;
conn->state = 1; // initialized
conn->peer_node_id = 0; // no peer yet
// Create test keys
struct SC_MYKEYS keys;
for (int i = 0; i < SC_PRIVKEY_SIZE; i++) {
keys.private_key[i] = i & 0xFF;
keys.public_key[i] = (i + 64) & 0xFF;
}
// Initialize crypto context
if (sc_init_ctx(&conn->crypto_ctx, &keys) != SC_OK) {
printf("ERROR: Failed to initialize connection crypto\n");
free(conn);
return -1;
}
printf("✓ ETCP connection crypto initialized\n");
// Test that we can use the crypto context for basic operations
uint8_t test_data[] = "ETCP connection test";
uint8_t encrypted[256];
uint8_t decrypted[256];
size_t encrypted_len, decrypted_len;
// Self-encryption test (set our own public key as peer and session key)
memcpy(conn->crypto_ctx.peer_public_key, keys.public_key, SC_PUBKEY_SIZE);
conn->crypto_ctx.peer_key_set = 1;
conn->crypto_ctx.session_ready = 1;
// Set test session key for self-encryption
memcpy(conn->crypto_ctx.session_key, keys.public_key, SC_SESSION_KEY_SIZE); // Use public key as session key for test
if (sc_encrypt(&conn->crypto_ctx, test_data, sizeof(test_data)-1, encrypted, &encrypted_len) != SC_OK) {
printf("ERROR: Connection encryption failed\n");
free(conn);
return -1;
}
printf("✓ Connection encryption works\n");
if (sc_decrypt(&conn->crypto_ctx, encrypted, encrypted_len, decrypted, &decrypted_len) != SC_OK) {
printf("ERROR: Connection decryption failed\n");
free(conn);
return -1;
}
if (decrypted_len != sizeof(test_data)-1 || memcmp(test_data, decrypted, sizeof(test_data)-1) != 0) {
printf("ERROR: Connection decryption mismatch\n");
free(conn);
return -1;
}
printf("✓ Connection decryption works\n");
free(conn);
printf("✓ ETCP connection crypto test passed\n");
return 0;
}
int main(void) {
printf("=== ETCP Crypto Test Suite ===\n");
int result1 = test_secure_channel_crypto();
if (result1 != 0) {
printf("ERROR: Secure channel crypto test failed\n");
return 1;
}
int result2 = test_etcp_connection_crypto();
if (result2 != 0) {
printf("ERROR: ETCP connection crypto test failed\n");
return 1;
}
printf("\n🎉 All crypto tests passed successfully!\n");
return 0;
}