699 lines
22 KiB
C
Executable File
699 lines
22 KiB
C
Executable File
/* wolfssl_stsafe_full_test.c
|
|
*
|
|
* Comprehensive wolfSSL integration tests with STSAFE-A120
|
|
* Tests: RNG, ECC KeyGen, ECDSA Sign/Verify, ECDH, Benchmarks, Brainpool curves
|
|
*
|
|
* Copyright (C) 2006-2026 wolfSSL Inc.
|
|
*
|
|
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
|
*
|
|
* wolfSSL is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* wolfSSL is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
#include <time.h>
|
|
#include <sys/time.h>
|
|
|
|
/* wolfSSL headers */
|
|
#include <wolfssl/options.h>
|
|
#include <wolfssl/wolfcrypt/settings.h>
|
|
#include <wolfssl/wolfcrypt/random.h>
|
|
#include <wolfssl/wolfcrypt/ecc.h>
|
|
#include <wolfssl/wolfcrypt/sha256.h>
|
|
#include <wolfssl/wolfcrypt/cryptocb.h>
|
|
#include <wolfssl/wolfcrypt/port/st/stsafe.h>
|
|
|
|
/* Test result macros */
|
|
#define TEST_PASS(msg) do { printf("[PASS] %s\n", msg); g_passed++; } while(0)
|
|
#define TEST_FAIL(msg) do { printf("[FAIL] %s\n", msg); g_failed++; } while(0)
|
|
|
|
static int g_passed = 0;
|
|
static int g_failed = 0;
|
|
|
|
/* STSAFE crypto callback context */
|
|
static wolfSTSAFE_CryptoCb_Ctx g_stsafe_ctx;
|
|
static int g_devId = INVALID_DEVID;
|
|
|
|
/* Get time in microseconds */
|
|
static double get_time_us(void)
|
|
{
|
|
struct timeval tv;
|
|
gettimeofday(&tv, NULL);
|
|
return (double)tv.tv_sec * 1000000.0 + (double)tv.tv_usec;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* Test: RNG Performance
|
|
*---------------------------------------------------------------------------*/
|
|
static int test_rng_benchmark(void)
|
|
{
|
|
WC_RNG rng;
|
|
byte rand_buf[256];
|
|
int ret;
|
|
int iterations = 100;
|
|
double start, end, elapsed;
|
|
int i;
|
|
|
|
printf("\nTest: RNG Benchmark (STSAFE-A120)\n");
|
|
|
|
ret = wc_InitRng_ex(&rng, NULL, g_devId);
|
|
if (ret != 0) {
|
|
printf(" Error: wc_InitRng_ex failed: %d\n", ret);
|
|
TEST_FAIL("RNG benchmark init");
|
|
return -1;
|
|
}
|
|
|
|
/* Warm up */
|
|
wc_RNG_GenerateBlock(&rng, rand_buf, sizeof(rand_buf));
|
|
|
|
/* Benchmark */
|
|
start = get_time_us();
|
|
for (i = 0; i < iterations; i++) {
|
|
ret = wc_RNG_GenerateBlock(&rng, rand_buf, sizeof(rand_buf));
|
|
if (ret != 0) break;
|
|
}
|
|
end = get_time_us();
|
|
elapsed = (end - start) / 1000.0; /* ms */
|
|
|
|
if (ret != 0) {
|
|
printf(" Error: wc_RNG_GenerateBlock failed: %d\n", ret);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("RNG benchmark");
|
|
return -1;
|
|
}
|
|
|
|
printf(" Generated %d x 256 bytes in %.2f ms\n", iterations, elapsed);
|
|
printf(" Throughput: %.2f KB/s\n",
|
|
(iterations * 256.0) / (elapsed / 1000.0) / 1024.0);
|
|
|
|
wc_FreeRng(&rng);
|
|
TEST_PASS("RNG benchmark");
|
|
return 0;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* Test: ECDSA P-256 Benchmark
|
|
*---------------------------------------------------------------------------*/
|
|
static int test_ecdsa_p256_benchmark(void)
|
|
{
|
|
ecc_key key;
|
|
WC_RNG rng;
|
|
int ret;
|
|
byte digest[32];
|
|
byte sig[128];
|
|
word32 sigLen;
|
|
int verified = 0;
|
|
int iterations = 10;
|
|
double start, end, elapsed;
|
|
int i;
|
|
|
|
printf("\nTest: ECDSA P-256 Benchmark (STSAFE-A120)\n");
|
|
|
|
ret = wc_InitRng(&rng);
|
|
if (ret != 0) {
|
|
printf(" Error: wc_InitRng failed: %d\n", ret);
|
|
TEST_FAIL("ECDSA P-256 benchmark RNG init");
|
|
return -1;
|
|
}
|
|
|
|
memset(digest, 0xAB, sizeof(digest));
|
|
|
|
ret = wc_ecc_init_ex(&key, NULL, g_devId);
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_init_ex failed: %d\n", ret);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDSA P-256 benchmark key init");
|
|
return -1;
|
|
}
|
|
|
|
/* Benchmark key generation */
|
|
start = get_time_us();
|
|
ret = wc_ecc_make_key_ex(&rng, 32, &key, ECC_SECP256R1);
|
|
end = get_time_us();
|
|
elapsed = (end - start) / 1000.0;
|
|
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_make_key_ex failed: %d\n", ret);
|
|
wc_ecc_free(&key);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDSA P-256 keygen");
|
|
return -1;
|
|
}
|
|
printf(" Key generation: %.2f ms\n", elapsed);
|
|
|
|
/* Benchmark signing */
|
|
start = get_time_us();
|
|
for (i = 0; i < iterations; i++) {
|
|
sigLen = sizeof(sig);
|
|
ret = wc_ecc_sign_hash(digest, sizeof(digest), sig, &sigLen, &rng, &key);
|
|
if (ret != 0) break;
|
|
}
|
|
end = get_time_us();
|
|
elapsed = (end - start) / 1000.0;
|
|
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_sign_hash failed: %d\n", ret);
|
|
wc_ecc_free(&key);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDSA P-256 sign");
|
|
return -1;
|
|
}
|
|
printf(" Signing: %d ops in %.2f ms (%.2f ops/sec)\n",
|
|
iterations, elapsed, iterations / (elapsed / 1000.0));
|
|
|
|
/* Benchmark verification */
|
|
start = get_time_us();
|
|
for (i = 0; i < iterations; i++) {
|
|
ret = wc_ecc_verify_hash(sig, sigLen, digest, sizeof(digest), &verified, &key);
|
|
if (ret != 0 || verified != 1) break;
|
|
}
|
|
end = get_time_us();
|
|
elapsed = (end - start) / 1000.0;
|
|
|
|
if (ret != 0 || verified != 1) {
|
|
printf(" Error: wc_ecc_verify_hash failed: %d, verified=%d\n", ret, verified);
|
|
wc_ecc_free(&key);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDSA P-256 verify");
|
|
return -1;
|
|
}
|
|
printf(" Verification: %d ops in %.2f ms (%.2f ops/sec)\n",
|
|
iterations, elapsed, iterations / (elapsed / 1000.0));
|
|
|
|
wc_ecc_free(&key);
|
|
wc_FreeRng(&rng);
|
|
TEST_PASS("ECDSA P-256 benchmark");
|
|
return 0;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* Test: ECDH Key Exchange
|
|
* Note: STSAFE has a single key slot, so we generate one key in STSAFE
|
|
* and one in software to test ECDH properly.
|
|
*---------------------------------------------------------------------------*/
|
|
static int test_ecdh_p256(void)
|
|
{
|
|
ecc_key keyHW; /* Hardware key in STSAFE */
|
|
ecc_key keySW; /* Software key */
|
|
WC_RNG rng;
|
|
int ret;
|
|
byte sharedHW[32], sharedSW[32];
|
|
word32 sharedHWLen = sizeof(sharedHW), sharedSWLen = sizeof(sharedSW);
|
|
double start, end;
|
|
int i;
|
|
|
|
printf("\nTest: ECDH P-256 Key Exchange (HW + SW)\n");
|
|
printf(" Note: STSAFE key used for one side, software for other\n");
|
|
|
|
ret = wc_InitRng(&rng);
|
|
if (ret != 0) {
|
|
printf(" Error: wc_InitRng failed: %d\n", ret);
|
|
TEST_FAIL("ECDH P-256 RNG init");
|
|
return -1;
|
|
}
|
|
|
|
/* Initialize hardware key (with STSAFE devId) */
|
|
ret = wc_ecc_init_ex(&keyHW, NULL, g_devId);
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_init_ex (HW) failed: %d\n", ret);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDH P-256 key init HW");
|
|
return -1;
|
|
}
|
|
|
|
/* Initialize software key (INVALID_DEVID for software) */
|
|
ret = wc_ecc_init_ex(&keySW, NULL, INVALID_DEVID);
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_init_ex (SW) failed: %d\n", ret);
|
|
wc_ecc_free(&keyHW);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDH P-256 key init SW");
|
|
return -1;
|
|
}
|
|
|
|
/* Generate hardware key pair (in STSAFE) */
|
|
printf(" Generating hardware key pair (STSAFE)...\n");
|
|
start = get_time_us();
|
|
ret = wc_ecc_make_key_ex(&rng, 32, &keyHW, ECC_SECP256R1);
|
|
end = get_time_us();
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_make_key_ex (HW) failed: %d\n", ret);
|
|
wc_ecc_free(&keyHW);
|
|
wc_ecc_free(&keySW);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDH P-256 keygen HW");
|
|
return -1;
|
|
}
|
|
printf(" HW Key generated in %.2f ms\n", (end - start) / 1000.0);
|
|
|
|
/* Generate software key pair */
|
|
printf(" Generating software key pair...\n");
|
|
start = get_time_us();
|
|
ret = wc_ecc_make_key_ex(&rng, 32, &keySW, ECC_SECP256R1);
|
|
end = get_time_us();
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_make_key_ex (SW) failed: %d\n", ret);
|
|
wc_ecc_free(&keyHW);
|
|
wc_ecc_free(&keySW);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDH P-256 keygen SW");
|
|
return -1;
|
|
}
|
|
printf(" SW Key generated in %.2f ms\n", (end - start) / 1000.0);
|
|
|
|
/* Set RNG on keys for shared secret computation */
|
|
ret = wc_ecc_set_rng(&keyHW, &rng);
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_set_rng (HW) failed: %d\n", ret);
|
|
wc_ecc_free(&keyHW);
|
|
wc_ecc_free(&keySW);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDH P-256 set RNG HW");
|
|
return -1;
|
|
}
|
|
ret = wc_ecc_set_rng(&keySW, &rng);
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_set_rng (SW) failed: %d\n", ret);
|
|
wc_ecc_free(&keyHW);
|
|
wc_ecc_free(&keySW);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDH P-256 set RNG SW");
|
|
return -1;
|
|
}
|
|
|
|
/* Compute shared secret using STSAFE (HW priv * SW pub) */
|
|
printf(" Computing shared secret (STSAFE: HW priv * SW pub)...\n");
|
|
start = get_time_us();
|
|
ret = wc_ecc_shared_secret(&keyHW, &keySW, sharedHW, &sharedHWLen);
|
|
end = get_time_us();
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_shared_secret (HW) failed: %d\n", ret);
|
|
wc_ecc_free(&keyHW);
|
|
wc_ecc_free(&keySW);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDH P-256 shared secret HW");
|
|
return -1;
|
|
}
|
|
printf(" STSAFE ECDH computed in %.2f ms\n", (end - start) / 1000.0);
|
|
|
|
/* Compute shared secret using software (SW priv * HW pub) */
|
|
printf(" Computing shared secret (Software: SW priv * HW pub)...\n");
|
|
start = get_time_us();
|
|
ret = wc_ecc_shared_secret(&keySW, &keyHW, sharedSW, &sharedSWLen);
|
|
end = get_time_us();
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_shared_secret (SW) failed: %d\n", ret);
|
|
wc_ecc_free(&keyHW);
|
|
wc_ecc_free(&keySW);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDH P-256 shared secret SW");
|
|
return -1;
|
|
}
|
|
printf(" Software ECDH computed in %.2f ms\n", (end - start) / 1000.0);
|
|
|
|
/* Compare shared secrets - they must match! */
|
|
if (sharedHWLen != sharedSWLen || memcmp(sharedHW, sharedSW, sharedHWLen) != 0) {
|
|
printf(" Error: Shared secrets don't match!\n");
|
|
printf(" HW: ");
|
|
for (i = 0; i < 8; i++) printf("%02X", sharedHW[i]);
|
|
printf("...\n");
|
|
printf(" SW: ");
|
|
for (i = 0; i < 8; i++) printf("%02X", sharedSW[i]);
|
|
printf("...\n");
|
|
wc_ecc_free(&keyHW);
|
|
wc_ecc_free(&keySW);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDH P-256 shared secret mismatch");
|
|
return -1;
|
|
}
|
|
|
|
printf(" Shared secrets match! (");
|
|
for (i = 0; i < 8; i++) printf("%02X", sharedHW[i]);
|
|
printf("...)\n");
|
|
|
|
wc_ecc_free(&keyHW);
|
|
wc_ecc_free(&keySW);
|
|
wc_FreeRng(&rng);
|
|
TEST_PASS("ECDH P-256 key exchange (HW+SW)");
|
|
return 0;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* Test: ECDSA Brainpool P-256 Benchmark
|
|
*---------------------------------------------------------------------------*/
|
|
#if defined(HAVE_ECC_BRAINPOOL) && defined(STSE_CONF_ECC_BRAINPOOL_P_256)
|
|
static int test_ecdsa_brainpool_p256_benchmark(void)
|
|
{
|
|
ecc_key key;
|
|
WC_RNG rng;
|
|
int ret;
|
|
byte digest[32];
|
|
byte sig[128];
|
|
word32 sigLen;
|
|
int verified = 0;
|
|
int iterations = 10;
|
|
double start, end, elapsed;
|
|
int i;
|
|
|
|
printf("\nTest: ECDSA Brainpool P-256 Benchmark (STSAFE-A120)\n");
|
|
|
|
ret = wc_InitRng(&rng);
|
|
if (ret != 0) {
|
|
printf(" Error: wc_InitRng failed: %d\n", ret);
|
|
TEST_FAIL("ECDSA Brainpool P-256 benchmark RNG init");
|
|
return -1;
|
|
}
|
|
|
|
memset(digest, 0xAB, sizeof(digest));
|
|
|
|
ret = wc_ecc_init_ex(&key, NULL, g_devId);
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_init_ex failed: %d\n", ret);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDSA Brainpool P-256 benchmark key init");
|
|
return -1;
|
|
}
|
|
|
|
/* Benchmark key generation */
|
|
start = get_time_us();
|
|
ret = wc_ecc_make_key_ex(&rng, 32, &key, ECC_BRAINPOOLP256R1);
|
|
end = get_time_us();
|
|
elapsed = (end - start) / 1000.0;
|
|
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_make_key_ex failed: %d\n", ret);
|
|
wc_ecc_free(&key);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDSA Brainpool P-256 keygen");
|
|
return -1;
|
|
}
|
|
printf(" Key generation: %.2f ms\n", elapsed);
|
|
|
|
/* Benchmark signing */
|
|
start = get_time_us();
|
|
for (i = 0; i < iterations; i++) {
|
|
sigLen = sizeof(sig);
|
|
ret = wc_ecc_sign_hash(digest, sizeof(digest), sig, &sigLen, &rng, &key);
|
|
if (ret != 0) break;
|
|
}
|
|
end = get_time_us();
|
|
elapsed = (end - start) / 1000.0;
|
|
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_sign_hash failed: %d\n", ret);
|
|
wc_ecc_free(&key);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDSA Brainpool P-256 sign");
|
|
return -1;
|
|
}
|
|
printf(" Signing: %d ops in %.2f ms (%.2f ops/sec)\n",
|
|
iterations, elapsed, iterations / (elapsed / 1000.0));
|
|
|
|
/* Benchmark verification */
|
|
start = get_time_us();
|
|
for (i = 0; i < iterations; i++) {
|
|
ret = wc_ecc_verify_hash(sig, sigLen, digest, sizeof(digest), &verified, &key);
|
|
if (ret != 0 || verified != 1) break;
|
|
}
|
|
end = get_time_us();
|
|
elapsed = (end - start) / 1000.0;
|
|
|
|
if (ret != 0 || verified != 1) {
|
|
printf(" Error: wc_ecc_verify_hash failed: %d, verified=%d\n", ret, verified);
|
|
wc_ecc_free(&key);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDSA Brainpool P-256 verify");
|
|
return -1;
|
|
}
|
|
printf(" Verification: %d ops in %.2f ms (%.2f ops/sec)\n",
|
|
iterations, elapsed, iterations / (elapsed / 1000.0));
|
|
|
|
wc_ecc_free(&key);
|
|
wc_FreeRng(&rng);
|
|
TEST_PASS("ECDSA Brainpool P-256 benchmark");
|
|
return 0;
|
|
}
|
|
#endif /* HAVE_ECC_BRAINPOOL && STSE_CONF_ECC_BRAINPOOL_P_256 */
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* Test: ECDSA Brainpool P-384 Benchmark
|
|
*---------------------------------------------------------------------------*/
|
|
#if defined(HAVE_ECC_BRAINPOOL) && defined(STSE_CONF_ECC_BRAINPOOL_P_384)
|
|
static int test_ecdsa_brainpool_p384_benchmark(void)
|
|
{
|
|
ecc_key key;
|
|
WC_RNG rng;
|
|
int ret;
|
|
byte digest[48];
|
|
byte sig[128];
|
|
word32 sigLen;
|
|
int verified = 0;
|
|
int iterations = 10;
|
|
double start, end, elapsed;
|
|
int i;
|
|
|
|
printf("\nTest: ECDSA Brainpool P-384 Benchmark (STSAFE-A120)\n");
|
|
|
|
ret = wc_InitRng(&rng);
|
|
if (ret != 0) {
|
|
printf(" Error: wc_InitRng failed: %d\n", ret);
|
|
TEST_FAIL("ECDSA Brainpool P-384 benchmark RNG init");
|
|
return -1;
|
|
}
|
|
|
|
memset(digest, 0xCD, sizeof(digest));
|
|
|
|
ret = wc_ecc_init_ex(&key, NULL, g_devId);
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_init_ex failed: %d\n", ret);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDSA Brainpool P-384 benchmark key init");
|
|
return -1;
|
|
}
|
|
|
|
/* Benchmark key generation */
|
|
start = get_time_us();
|
|
ret = wc_ecc_make_key_ex(&rng, 48, &key, ECC_BRAINPOOLP384R1);
|
|
end = get_time_us();
|
|
elapsed = (end - start) / 1000.0;
|
|
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_make_key_ex failed: %d\n", ret);
|
|
wc_ecc_free(&key);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDSA Brainpool P-384 keygen");
|
|
return -1;
|
|
}
|
|
printf(" Key generation: %.2f ms\n", elapsed);
|
|
|
|
/* Benchmark signing */
|
|
start = get_time_us();
|
|
for (i = 0; i < iterations; i++) {
|
|
sigLen = sizeof(sig);
|
|
ret = wc_ecc_sign_hash(digest, sizeof(digest), sig, &sigLen, &rng, &key);
|
|
if (ret != 0) break;
|
|
}
|
|
end = get_time_us();
|
|
elapsed = (end - start) / 1000.0;
|
|
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_sign_hash failed: %d\n", ret);
|
|
wc_ecc_free(&key);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDSA Brainpool P-384 sign");
|
|
return -1;
|
|
}
|
|
printf(" Signing: %d ops in %.2f ms (%.2f ops/sec)\n",
|
|
iterations, elapsed, iterations / (elapsed / 1000.0));
|
|
|
|
/* Benchmark verification */
|
|
start = get_time_us();
|
|
for (i = 0; i < iterations; i++) {
|
|
ret = wc_ecc_verify_hash(sig, sigLen, digest, sizeof(digest), &verified, &key);
|
|
if (ret != 0 || verified != 1) break;
|
|
}
|
|
end = get_time_us();
|
|
elapsed = (end - start) / 1000.0;
|
|
|
|
if (ret != 0 || verified != 1) {
|
|
printf(" Error: wc_ecc_verify_hash failed: %d, verified=%d\n", ret, verified);
|
|
wc_ecc_free(&key);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("ECDSA Brainpool P-384 verify");
|
|
return -1;
|
|
}
|
|
printf(" Verification: %d ops in %.2f ms (%.2f ops/sec)\n",
|
|
iterations, elapsed, iterations / (elapsed / 1000.0));
|
|
|
|
wc_ecc_free(&key);
|
|
wc_FreeRng(&rng);
|
|
TEST_PASS("ECDSA Brainpool P-384 benchmark");
|
|
return 0;
|
|
}
|
|
#endif /* HAVE_ECC_BRAINPOOL && STSE_CONF_ECC_BRAINPOOL_P_384 */
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* Test: Multiple Key Slots
|
|
*---------------------------------------------------------------------------*/
|
|
static int test_multiple_operations(void)
|
|
{
|
|
ecc_key keys[3];
|
|
WC_RNG rng;
|
|
int ret;
|
|
byte digest[32];
|
|
byte sigs[3][128];
|
|
word32 sigLens[3];
|
|
int verified;
|
|
int i;
|
|
|
|
printf("\nTest: Multiple Sequential Operations\n");
|
|
|
|
ret = wc_InitRng(&rng);
|
|
if (ret != 0) {
|
|
printf(" Error: wc_InitRng failed: %d\n", ret);
|
|
TEST_FAIL("Multiple ops RNG init");
|
|
return -1;
|
|
}
|
|
|
|
memset(digest, 0xCD, sizeof(digest));
|
|
|
|
/* Generate 3 key pairs and sign with each */
|
|
for (i = 0; i < 3; i++) {
|
|
ret = wc_ecc_init_ex(&keys[i], NULL, g_devId);
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_init_ex[%d] failed: %d\n", i, ret);
|
|
while (--i >= 0) wc_ecc_free(&keys[i]);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("Multiple ops key init");
|
|
return -1;
|
|
}
|
|
|
|
printf(" Generating key pair %d...\n", i + 1);
|
|
ret = wc_ecc_make_key_ex(&rng, 32, &keys[i], ECC_SECP256R1);
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_make_key_ex[%d] failed: %d\n", i, ret);
|
|
for (int j = 0; j <= i; j++) wc_ecc_free(&keys[j]);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("Multiple ops keygen");
|
|
return -1;
|
|
}
|
|
|
|
/* Sign with this key */
|
|
sigLens[i] = sizeof(sigs[i]);
|
|
ret = wc_ecc_sign_hash(digest, sizeof(digest), sigs[i], &sigLens[i], &rng, &keys[i]);
|
|
if (ret != 0) {
|
|
printf(" Error: wc_ecc_sign_hash[%d] failed: %d\n", i, ret);
|
|
for (int j = 0; j <= i; j++) wc_ecc_free(&keys[j]);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("Multiple ops sign");
|
|
return -1;
|
|
}
|
|
printf(" Key %d: Generated and signed successfully\n", i + 1);
|
|
}
|
|
|
|
/* Verify all signatures */
|
|
printf(" Verifying all signatures...\n");
|
|
for (i = 0; i < 3; i++) {
|
|
ret = wc_ecc_verify_hash(sigs[i], sigLens[i], digest, sizeof(digest),
|
|
&verified, &keys[i]);
|
|
if (ret != 0 || verified != 1) {
|
|
printf(" Error: Verification[%d] failed: ret=%d, verified=%d\n",
|
|
i, ret, verified);
|
|
for (int j = 0; j < 3; j++) wc_ecc_free(&keys[j]);
|
|
wc_FreeRng(&rng);
|
|
TEST_FAIL("Multiple ops verify");
|
|
return -1;
|
|
}
|
|
}
|
|
printf(" All 3 signatures verified!\n");
|
|
|
|
for (i = 0; i < 3; i++) wc_ecc_free(&keys[i]);
|
|
wc_FreeRng(&rng);
|
|
TEST_PASS("Multiple sequential operations");
|
|
return 0;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* Main
|
|
*---------------------------------------------------------------------------*/
|
|
int main(void)
|
|
{
|
|
int ret;
|
|
|
|
printf("================================================================\n");
|
|
printf("wolfSSL STSAFE-A120 Full Integration Test Suite\n");
|
|
printf("================================================================\n");
|
|
|
|
/* Initialize wolfCrypt */
|
|
ret = wolfCrypt_Init();
|
|
if (ret != 0) {
|
|
printf("Error: wolfCrypt_Init failed: %d\n", ret);
|
|
return 1;
|
|
}
|
|
|
|
/* Initialize STSAFE interface */
|
|
printf("\nInitializing STSAFE-A120...\n");
|
|
ret = stsafe_interface_init();
|
|
if (ret != 0) {
|
|
printf("Error: stsafe_interface_init failed: %d\n", ret);
|
|
wolfCrypt_Cleanup();
|
|
return 1;
|
|
}
|
|
printf("STSAFE-A120 initialized successfully.\n");
|
|
|
|
/* Register STSAFE crypto callback */
|
|
g_devId = 0x53545341; /* STSA */
|
|
memset(&g_stsafe_ctx, 0, sizeof(g_stsafe_ctx));
|
|
g_stsafe_ctx.devId = g_devId;
|
|
|
|
ret = wc_CryptoCb_RegisterDevice(g_devId, wolfSSL_STSAFE_CryptoDevCb,
|
|
&g_stsafe_ctx);
|
|
if (ret != 0) {
|
|
printf("Error: wc_CryptoCb_RegisterDevice failed: %d\n", ret);
|
|
wolfCrypt_Cleanup();
|
|
return 1;
|
|
}
|
|
printf("STSAFE crypto callback registered (devId: 0x%08X).\n", g_devId);
|
|
|
|
/* Run tests */
|
|
test_rng_benchmark();
|
|
test_ecdsa_p256_benchmark();
|
|
#if defined(HAVE_ECC_BRAINPOOL) && defined(STSE_CONF_ECC_BRAINPOOL_P_256)
|
|
test_ecdsa_brainpool_p256_benchmark();
|
|
#endif
|
|
#if defined(HAVE_ECC_BRAINPOOL) && defined(STSE_CONF_ECC_BRAINPOOL_P_384)
|
|
test_ecdsa_brainpool_p384_benchmark();
|
|
#endif
|
|
|
|
/* ECDH test - now uses ECDHE ephemeral keys */
|
|
test_ecdh_p256();
|
|
|
|
test_multiple_operations();
|
|
|
|
/* Cleanup */
|
|
wc_CryptoCb_UnRegisterDevice(g_devId);
|
|
wolfCrypt_Cleanup();
|
|
|
|
printf("\n================================================================\n");
|
|
printf("Test Summary: %d passed, %d failed\n", g_passed, g_failed);
|
|
printf("================================================================\n");
|
|
|
|
return (g_failed > 0) ? 1 : 0;
|
|
}
|
|
|