- Move all test files to tests/ directory - Update Makefile to build tests in tests/ directory - Add fragment reassembly timeout mechanism (500ms default) - Add error count API (pkt_normalizer_get_error_count, pkt_normalizer_reset_error_count) - Enhance error handling with timeout callbacks - Add comprehensive stress tests and edge case tests - Update .gitignore for build artifacts
161 lines
5.8 KiB
C
161 lines
5.8 KiB
C
/* test_client_server.c - TinyCrypt test for client-server key exchange and encryption */
|
|
|
|
/*
|
|
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* - Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* - Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* - Neither the name of Intel Corporation nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include <tinycrypt/ecc.h>
|
|
#include <tinycrypt/ecc_dh.h>
|
|
#include <tinycrypt/aes.h>
|
|
#include <tinycrypt/ctr_mode.h>
|
|
#include <tinycrypt/constants.h>
|
|
#include <tinycrypt/ecc_platform_specific.h>
|
|
#include <test_utils.h>
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
static int test_key_exchange_and_encrypt(void)
|
|
{
|
|
const struct uECC_Curve_t *curve = uECC_secp256r1();
|
|
|
|
/* Client key pair */
|
|
uint8_t client_private[NUM_ECC_BYTES];
|
|
uint8_t client_public[2 * NUM_ECC_BYTES];
|
|
|
|
/* Server key pair */
|
|
uint8_t server_private[NUM_ECC_BYTES];
|
|
uint8_t server_public[2 * NUM_ECC_BYTES];
|
|
|
|
/* Shared secrets */
|
|
uint8_t client_secret[NUM_ECC_BYTES];
|
|
uint8_t server_secret[NUM_ECC_BYTES];
|
|
|
|
TC_PRINT("Generating client key pair...\n");
|
|
if (!uECC_make_key(client_public, client_private, curve)) {
|
|
TC_ERROR("Failed to generate client key pair\n");
|
|
return TC_FAIL;
|
|
}
|
|
|
|
TC_PRINT("Generating server key pair...\n");
|
|
if (!uECC_make_key(server_public, server_private, curve)) {
|
|
TC_ERROR("Failed to generate server key pair\n");
|
|
return TC_FAIL;
|
|
}
|
|
|
|
/* Compute shared secret on client side */
|
|
TC_PRINT("Computing shared secret on client side...\n");
|
|
if (!uECC_shared_secret(server_public, client_private, client_secret, curve)) {
|
|
TC_ERROR("Failed to compute client shared secret\n");
|
|
return TC_FAIL;
|
|
}
|
|
|
|
/* Compute shared secret on server side */
|
|
TC_PRINT("Computing shared secret on server side...\n");
|
|
if (!uECC_shared_secret(client_public, server_private, server_secret, curve)) {
|
|
TC_ERROR("Failed to compute server shared secret\n");
|
|
return TC_FAIL;
|
|
}
|
|
|
|
/* Verify that both shared secrets match */
|
|
if (memcmp(client_secret, server_secret, NUM_ECC_BYTES) != 0) {
|
|
TC_ERROR("Shared secrets do not match\n");
|
|
show_str("Client secret", client_secret, NUM_ECC_BYTES);
|
|
show_str("Server secret", server_secret, NUM_ECC_BYTES);
|
|
return TC_FAIL;
|
|
}
|
|
TC_PRINT("Shared secrets match.\n");
|
|
|
|
/* Derive AES key from shared secret (first 16 bytes) */
|
|
uint8_t aes_key[TC_AES_KEY_SIZE];
|
|
memcpy(aes_key, client_secret, TC_AES_KEY_SIZE);
|
|
|
|
/* Prepare test data */
|
|
const char *plaintext = "Hello, secure world!";
|
|
size_t plaintext_len = strlen(plaintext) + 1; /* include null terminator */
|
|
uint8_t ciphertext[plaintext_len];
|
|
uint8_t decrypted[plaintext_len];
|
|
|
|
/* Initialize AES key schedule */
|
|
struct tc_aes_key_sched_struct sched;
|
|
if (tc_aes128_set_encrypt_key(&sched, aes_key) != TC_CRYPTO_SUCCESS) {
|
|
TC_ERROR("Failed to set AES encryption key\n");
|
|
return TC_FAIL;
|
|
}
|
|
|
|
/* Initialize counter (little-endian 32-bit) */
|
|
uint8_t ctr[TC_AES_BLOCK_SIZE] = {0}; /* zero-initialized counter */
|
|
|
|
TC_PRINT("Encrypting plaintext...\n");
|
|
if (tc_ctr_mode(ciphertext, plaintext_len, (const uint8_t *)plaintext,
|
|
plaintext_len, ctr, &sched) != TC_CRYPTO_SUCCESS) {
|
|
TC_ERROR("Encryption failed\n");
|
|
return TC_FAIL;
|
|
}
|
|
|
|
/* Reset counter for decryption (CTR mode uses same counter sequence) */
|
|
memset(ctr, 0, TC_AES_BLOCK_SIZE);
|
|
|
|
TC_PRINT("Decrypting ciphertext...\n");
|
|
if (tc_ctr_mode(decrypted, plaintext_len, ciphertext,
|
|
plaintext_len, ctr, &sched) != TC_CRYPTO_SUCCESS) {
|
|
TC_ERROR("Decryption failed\n");
|
|
return TC_FAIL;
|
|
}
|
|
|
|
/* Verify decrypted matches original */
|
|
if (memcmp(plaintext, decrypted, plaintext_len) != 0) {
|
|
TC_ERROR("Decrypted text does not match original\n");
|
|
show_str("Original", (const uint8_t *)plaintext, plaintext_len);
|
|
show_str("Decrypted", decrypted, plaintext_len);
|
|
return TC_FAIL;
|
|
}
|
|
TC_PRINT("Decryption successful. Test passed.\n");
|
|
|
|
return TC_PASS;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
unsigned int result = TC_PASS;
|
|
|
|
TC_START("Performing client-server key exchange and encryption test:");
|
|
|
|
/* Setup cryptographically secure PRNG */
|
|
uECC_set_rng(&default_CSPRNG);
|
|
|
|
result = test_key_exchange_and_encrypt();
|
|
|
|
TC_END_RESULT(result);
|
|
TC_END_REPORT(result);
|
|
|
|
return result;
|
|
} |