/* wolfssl_stsafe_test.c * * Test wolfSSL crypto callbacks with STSAFE-A120 * Tests: RNG, ECC P-256, ECC P-384, ECDSA Sign/Verify, 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 #include #include #include /* wolfSSL headers */ #include "user_settings.h" #include #include #include #include #include #include /* 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; /*----------------------------------------------------------------------------- * Test: RNG with STSAFE-A120 *---------------------------------------------------------------------------*/ static int test_rng(void) { WC_RNG rng; byte rand_buf[32]; int ret; int i; printf("\nTest: RNG with 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 initialization"); return -1; } /* Generate random bytes */ ret = wc_RNG_GenerateBlock(&rng, rand_buf, sizeof(rand_buf)); if (ret != 0) { printf(" Error: wc_RNG_GenerateBlock failed: %d\n", ret); wc_FreeRng(&rng); TEST_FAIL("RNG generation"); return -1; } /* Print random data */ printf(" Random data: "); for (i = 0; i < 16; i++) { printf("%02X ", rand_buf[i]); } printf("...\n"); wc_FreeRng(&rng); TEST_PASS("RNG with STSAFE-A120"); return 0; } /*----------------------------------------------------------------------------- * Test: ECC P-256 Key Generation with STSAFE-A120 *---------------------------------------------------------------------------*/ static int test_ecc_keygen_p256(void) { ecc_key key; WC_RNG rng; int ret; byte pubX[32], pubY[32]; word32 pubX_len = sizeof(pubX), pubY_len = sizeof(pubY); int i; printf("\nTest: ECC P-256 Key Generation with STSAFE-A120\n"); ret = wc_InitRng(&rng); if (ret != 0) { printf(" Error: wc_InitRng failed: %d\n", ret); TEST_FAIL("ECC P-256 RNG init"); return -1; } 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("ECC P-256 init"); return -1; } /* Generate P-256 key pair - should use STSAFE via crypto callback */ ret = wc_ecc_make_key_ex(&rng, 32, &key, ECC_SECP256R1); if (ret != 0) { printf(" Error: wc_ecc_make_key_ex failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECC P-256 key generation"); return -1; } /* Export public key */ ret = wc_ecc_export_public_raw(&key, pubX, &pubX_len, pubY, &pubY_len); if (ret != 0) { printf(" Error: wc_ecc_export_public_raw failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECC P-256 export public key"); return -1; } printf(" Public Key X: "); for (i = 0; i < 8; i++) printf("%02X", pubX[i]); printf("...\n"); printf(" Public Key Y: "); for (i = 0; i < 8; i++) printf("%02X", pubY[i]); printf("...\n"); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_PASS("ECC P-256 key generation"); return 0; } /*----------------------------------------------------------------------------- * Test: ECC P-384 Key Generation with STSAFE-A120 *---------------------------------------------------------------------------*/ static int test_ecc_keygen_p384(void) { ecc_key key; WC_RNG rng; int ret; byte pubX[48], pubY[48]; word32 pubX_len = sizeof(pubX), pubY_len = sizeof(pubY); int i; printf("\nTest: ECC P-384 Key Generation with STSAFE-A120\n"); ret = wc_InitRng(&rng); if (ret != 0) { printf(" Error: wc_InitRng failed: %d\n", ret); TEST_FAIL("ECC P-384 RNG init"); return -1; } 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("ECC P-384 init"); return -1; } /* Generate P-384 key pair - should use STSAFE via crypto callback */ ret = wc_ecc_make_key_ex(&rng, 48, &key, ECC_SECP384R1); if (ret != 0) { printf(" Error: wc_ecc_make_key_ex failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECC P-384 key generation"); return -1; } /* Export public key */ ret = wc_ecc_export_public_raw(&key, pubX, &pubX_len, pubY, &pubY_len); if (ret != 0) { printf(" Error: wc_ecc_export_public_raw failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECC P-384 export public key"); return -1; } printf(" Public Key X: "); for (i = 0; i < 8; i++) printf("%02X", pubX[i]); printf("...\n"); printf(" Public Key Y: "); for (i = 0; i < 8; i++) printf("%02X", pubY[i]); printf("...\n"); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_PASS("ECC P-384 key generation"); return 0; } /*----------------------------------------------------------------------------- * Test: ECDSA Sign/Verify P-256 with STSAFE-A120 *---------------------------------------------------------------------------*/ static int test_ecdsa_p256(void) { ecc_key key; WC_RNG rng; int ret; byte digest[32]; byte sig[128]; word32 sigLen = sizeof(sig); int verified = 0; int i; printf("\nTest: ECDSA P-256 Sign/Verify with STSAFE-A120\n"); /* Initialize RNG */ ret = wc_InitRng(&rng); if (ret != 0) { printf(" Error: wc_InitRng failed: %d\n", ret); TEST_FAIL("ECDSA P-256 RNG init"); return -1; } /* Create test digest */ 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 key init"); return -1; } /* Generate key pair using STSAFE */ ret = wc_ecc_make_key_ex(&rng, 32, &key, ECC_SECP256R1); 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 key generation"); return -1; } printf(" Key pair generated.\n"); /* Sign the digest using STSAFE */ ret = wc_ecc_sign_hash(digest, sizeof(digest), sig, &sigLen, &rng, &key); 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(" Signature (%d bytes): ", sigLen); for (i = 0; i < 8 && i < (int)sigLen; i++) printf("%02X", sig[i]); printf("...\n"); /* Verify the signature using software (public key only, no hardware needed) */ /* Clear devId to force software verification */ key.devId = INVALID_DEVID; ret = wc_ecc_verify_hash(sig, sigLen, digest, sizeof(digest), &verified, &key); if (ret != 0) { printf(" Error: wc_ecc_verify_hash failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDSA P-256 verify"); return -1; } if (verified != 1) { printf(" Error: Signature verification failed\n"); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDSA P-256 verification result"); return -1; } printf(" Signature verified!\n"); /* Also verify using hardware (STSAFE) */ printf(" Verifying signature using STSAFE hardware...\n"); /* Restore devId for hardware verification */ key.devId = g_devId; ret = wc_ecc_verify_hash(sig, sigLen, digest, sizeof(digest), &verified, &key); if (ret != 0) { printf(" Error: wc_ecc_verify_hash (HW) failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDSA P-256 verify HW"); return -1; } if (verified != 1) { printf(" Error: Hardware signature verification failed\n"); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDSA P-256 verification result HW"); return -1; } printf(" Hardware signature verified!\n"); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_PASS("ECDSA P-256 sign/verify"); return 0; } /*----------------------------------------------------------------------------- * Test: ECDSA Sign/Verify P-384 with STSAFE-A120 *---------------------------------------------------------------------------*/ static int test_ecdsa_p384(void) { ecc_key key; WC_RNG rng; int ret; byte digest[48]; byte sig[128]; word32 sigLen = sizeof(sig); int verified = 0; int i; printf("\nTest: ECDSA P-384 Sign/Verify with STSAFE-A120\n"); /* Initialize RNG */ ret = wc_InitRng(&rng); if (ret != 0) { printf(" Error: wc_InitRng failed: %d\n", ret); TEST_FAIL("ECDSA P-384 RNG init"); return -1; } /* Create test digest */ 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 P-384 key init"); return -1; } /* Generate key pair using STSAFE */ ret = wc_ecc_make_key_ex(&rng, 48, &key, ECC_SECP384R1); 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-384 key generation"); return -1; } printf(" Key pair generated.\n"); /* Sign the digest using STSAFE */ ret = wc_ecc_sign_hash(digest, sizeof(digest), sig, &sigLen, &rng, &key); if (ret != 0) { printf(" Error: wc_ecc_sign_hash failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDSA P-384 sign"); return -1; } printf(" Signature (%d bytes): ", sigLen); for (i = 0; i < 8 && i < (int)sigLen; i++) printf("%02X", sig[i]); printf("...\n"); /* Verify the signature using software (public key only, no hardware needed) */ /* Clear devId to force software verification */ key.devId = INVALID_DEVID; ret = wc_ecc_verify_hash(sig, sigLen, digest, sizeof(digest), &verified, &key); if (ret != 0) { printf(" Error: wc_ecc_verify_hash failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDSA P-384 verify"); return -1; } if (verified != 1) { printf(" Error: Signature verification failed\n"); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDSA P-384 verification result"); return -1; } printf(" Signature verified!\n"); /* Also verify using hardware (STSAFE) */ printf(" Verifying signature using STSAFE hardware...\n"); /* Restore devId for hardware verification */ key.devId = g_devId; ret = wc_ecc_verify_hash(sig, sigLen, digest, sizeof(digest), &verified, &key); if (ret != 0) { printf(" Error: wc_ecc_verify_hash (HW) failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDSA P-384 verify HW"); return -1; } if (verified != 1) { printf(" Error: Hardware signature verification failed\n"); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDSA P-384 verification result HW"); return -1; } printf(" Hardware signature verified!\n"); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_PASS("ECDSA P-384 sign/verify"); return 0; } /*----------------------------------------------------------------------------- * Test: ECC Brainpool P-256 Key Generation with STSAFE-A120 *---------------------------------------------------------------------------*/ #if defined(HAVE_ECC_BRAINPOOL) && defined(STSE_CONF_ECC_BRAINPOOL_P_256) static int test_ecc_keygen_brainpool_p256(void) { ecc_key key; WC_RNG rng; int ret; byte pubX[32], pubY[32]; word32 pubX_len = sizeof(pubX), pubY_len = sizeof(pubY); int i; printf("\nTest: ECC Brainpool P-256 Key Generation with STSAFE-A120\n"); ret = wc_InitRng(&rng); if (ret != 0) { printf(" Error: wc_InitRng failed: %d\n", ret); TEST_FAIL("ECC Brainpool P-256 RNG init"); return -1; } 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("ECC Brainpool P-256 init"); return -1; } /* Generate Brainpool P-256 key pair - should use STSAFE via crypto callback */ ret = wc_ecc_make_key_ex(&rng, 32, &key, ECC_BRAINPOOLP256R1); if (ret != 0) { printf(" Error: wc_ecc_make_key_ex failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECC Brainpool P-256 key generation"); return -1; } /* Export public key */ ret = wc_ecc_export_public_raw(&key, pubX, &pubX_len, pubY, &pubY_len); if (ret != 0) { printf(" Error: wc_ecc_export_public_raw failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECC Brainpool P-256 export public key"); return -1; } printf(" Public Key X: "); for (i = 0; i < 8; i++) printf("%02X", pubX[i]); printf("...\n"); printf(" Public Key Y: "); for (i = 0; i < 8; i++) printf("%02X", pubY[i]); printf("...\n"); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_PASS("ECC Brainpool P-256 key generation"); return 0; } #endif /* HAVE_ECC_BRAINPOOL && STSE_CONF_ECC_BRAINPOOL_P_256 */ /*----------------------------------------------------------------------------- * Test: ECC Brainpool P-384 Key Generation with STSAFE-A120 *---------------------------------------------------------------------------*/ #if defined(HAVE_ECC_BRAINPOOL) && defined(STSE_CONF_ECC_BRAINPOOL_P_384) static int test_ecc_keygen_brainpool_p384(void) { ecc_key key; WC_RNG rng; int ret; byte pubX[48], pubY[48]; word32 pubX_len = sizeof(pubX), pubY_len = sizeof(pubY); int i; printf("\nTest: ECC Brainpool P-384 Key Generation with STSAFE-A120\n"); ret = wc_InitRng(&rng); if (ret != 0) { printf(" Error: wc_InitRng failed: %d\n", ret); TEST_FAIL("ECC Brainpool P-384 RNG init"); return -1; } 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("ECC Brainpool P-384 init"); return -1; } /* Generate Brainpool P-384 key pair - should use STSAFE via crypto callback */ ret = wc_ecc_make_key_ex(&rng, 48, &key, ECC_BRAINPOOLP384R1); if (ret != 0) { printf(" Error: wc_ecc_make_key_ex failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECC Brainpool P-384 key generation"); return -1; } /* Export public key */ ret = wc_ecc_export_public_raw(&key, pubX, &pubX_len, pubY, &pubY_len); if (ret != 0) { printf(" Error: wc_ecc_export_public_raw failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECC Brainpool P-384 export public key"); return -1; } printf(" Public Key X: "); for (i = 0; i < 8; i++) printf("%02X", pubX[i]); printf("...\n"); printf(" Public Key Y: "); for (i = 0; i < 8; i++) printf("%02X", pubY[i]); printf("...\n"); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_PASS("ECC Brainpool P-384 key generation"); return 0; } #endif /* HAVE_ECC_BRAINPOOL && STSE_CONF_ECC_BRAINPOOL_P_384 */ /*----------------------------------------------------------------------------- * Test: ECDSA Sign/Verify Brainpool P-256 with STSAFE-A120 *---------------------------------------------------------------------------*/ #if defined(HAVE_ECC_BRAINPOOL) && defined(STSE_CONF_ECC_BRAINPOOL_P_256) static int test_ecdsa_brainpool_p256(void) { ecc_key key; WC_RNG rng; int ret; byte digest[32]; byte sig[128]; word32 sigLen = sizeof(sig); int verified = 0; int i; printf("\nTest: ECDSA Brainpool P-256 Sign/Verify with STSAFE-A120\n"); /* Initialize RNG */ ret = wc_InitRng(&rng); if (ret != 0) { printf(" Error: wc_InitRng failed: %d\n", ret); TEST_FAIL("ECDSA Brainpool P-256 RNG init"); return -1; } /* Create test digest */ 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 key init"); return -1; } /* Generate key pair using STSAFE */ ret = wc_ecc_make_key_ex(&rng, 32, &key, ECC_BRAINPOOLP256R1); 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 key generation"); return -1; } printf(" Key pair generated.\n"); /* Sign the digest using STSAFE */ ret = wc_ecc_sign_hash(digest, sizeof(digest), sig, &sigLen, &rng, &key); 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(" Signature (%d bytes): ", sigLen); for (i = 0; i < 8 && i < (int)sigLen; i++) printf("%02X", sig[i]); printf("...\n"); /* Verify the signature using software (public key only, no hardware needed) */ /* Clear devId to force software verification */ key.devId = INVALID_DEVID; ret = wc_ecc_verify_hash(sig, sigLen, digest, sizeof(digest), &verified, &key); if (ret != 0) { printf(" Error: wc_ecc_verify_hash failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDSA Brainpool P-256 verify"); return -1; } if (verified != 1) { printf(" Error: Signature verification failed\n"); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDSA Brainpool P-256 verification result"); return -1; } printf(" Signature verified!\n"); /* Also verify using hardware (STSAFE) */ printf(" Verifying signature using STSAFE hardware...\n"); /* Restore devId for hardware verification */ key.devId = g_devId; ret = wc_ecc_verify_hash(sig, sigLen, digest, sizeof(digest), &verified, &key); if (ret != 0) { printf(" Error: wc_ecc_verify_hash (HW) failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDSA Brainpool P-256 verify HW"); return -1; } if (verified != 1) { printf(" Error: Hardware signature verification failed\n"); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDSA Brainpool P-256 verification result HW"); return -1; } printf(" Hardware signature verified!\n"); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_PASS("ECDSA Brainpool P-256 sign/verify"); return 0; } #endif /* HAVE_ECC_BRAINPOOL && STSE_CONF_ECC_BRAINPOOL_P_256 */ /*----------------------------------------------------------------------------- * Test: ECDSA Sign/Verify Brainpool P-384 with STSAFE-A120 *---------------------------------------------------------------------------*/ #if defined(HAVE_ECC_BRAINPOOL) && defined(STSE_CONF_ECC_BRAINPOOL_P_384) static int test_ecdsa_brainpool_p384(void) { ecc_key key; WC_RNG rng; int ret; byte digest[48]; byte sig[128]; word32 sigLen = sizeof(sig); int verified = 0; int i; printf("\nTest: ECDSA Brainpool P-384 Sign/Verify with STSAFE-A120\n"); /* Initialize RNG */ ret = wc_InitRng(&rng); if (ret != 0) { printf(" Error: wc_InitRng failed: %d\n", ret); TEST_FAIL("ECDSA Brainpool P-384 RNG init"); return -1; } /* Create test digest */ 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 key init"); return -1; } /* Generate key pair using STSAFE */ ret = wc_ecc_make_key_ex(&rng, 48, &key, ECC_BRAINPOOLP384R1); 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 key generation"); return -1; } printf(" Key pair generated.\n"); /* Sign the digest using STSAFE */ ret = wc_ecc_sign_hash(digest, sizeof(digest), sig, &sigLen, &rng, &key); 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(" Signature (%d bytes): ", sigLen); for (i = 0; i < 8 && i < (int)sigLen; i++) printf("%02X", sig[i]); printf("...\n"); /* Verify the signature using software (public key only, no hardware needed) */ /* Clear devId to force software verification */ key.devId = INVALID_DEVID; ret = wc_ecc_verify_hash(sig, sigLen, digest, sizeof(digest), &verified, &key); if (ret != 0) { printf(" Error: wc_ecc_verify_hash failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDSA Brainpool P-384 verify"); return -1; } if (verified != 1) { printf(" Error: Signature verification failed\n"); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDSA Brainpool P-384 verification result"); return -1; } printf(" Signature verified!\n"); /* Also verify using hardware (STSAFE) */ printf(" Verifying signature using STSAFE hardware...\n"); /* Restore devId for hardware verification */ key.devId = g_devId; ret = wc_ecc_verify_hash(sig, sigLen, digest, sizeof(digest), &verified, &key); if (ret != 0) { printf(" Error: wc_ecc_verify_hash (HW) failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDSA Brainpool P-384 verify HW"); return -1; } if (verified != 1) { printf(" Error: Hardware signature verification failed\n"); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDSA Brainpool P-384 verification result HW"); return -1; } printf(" Hardware signature verified!\n"); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_PASS("ECDSA Brainpool P-384 sign/verify"); return 0; } #endif /* HAVE_ECC_BRAINPOOL && STSE_CONF_ECC_BRAINPOOL_P_384 */ /*----------------------------------------------------------------------------- * Test: ECDHE P-256 Key Generation with STSAFE-A120 * Note: This tests ephemeral key generation using stse_generate_ECDHE_key_pair *---------------------------------------------------------------------------*/ static int test_ecdhe_keygen_p256(void) { ecc_key key; WC_RNG rng; int ret; byte pubX[32], pubY[32]; word32 pubX_len = sizeof(pubX), pubY_len = sizeof(pubY); int i; printf("\nTest: ECDHE P-256 Ephemeral Key Generation with STSAFE-A120\n"); printf(" Note: Uses stse_generate_ECDHE_key_pair() for ephemeral keys\n"); ret = wc_InitRng(&rng); if (ret != 0) { printf(" Error: wc_InitRng failed: %d\n", ret); TEST_FAIL("ECDHE P-256 RNG init"); return -1; } 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("ECDHE P-256 init"); return -1; } /* Generate ECDHE ephemeral key pair - should use STSAFE ECDHE via crypto callback */ key.devCtx = (void*)STSAFE_KEY_SLOT_EPHEMERAL; ret = wc_ecc_make_key_ex(&rng, 32, &key, ECC_SECP256R1); if (ret != 0) { printf(" Error: wc_ecc_make_key_ex failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDHE P-256 key generation"); return -1; } /* Export public key */ ret = wc_ecc_export_public_raw(&key, pubX, &pubX_len, pubY, &pubY_len); if (ret != 0 || pubX_len != 32 || pubY_len != 32) { printf(" Error: wc_ecc_export_public_raw failed: %d\n", ret); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDHE P-256 export public key"); return -1; } /* Verify public key is non-zero */ int all_zero = 1; for (i = 0; i < 32; i++) { if (pubX[i] != 0 || pubY[i] != 0) { all_zero = 0; break; } } if (all_zero) { printf(" Error: Public key is all zeros\n"); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_FAIL("ECDHE P-256 invalid public key"); return -1; } printf(" Public Key X: "); for (i = 0; i < 8; i++) printf("%02X", pubX[i]); printf("...\n"); printf(" Public Key Y: "); for (i = 0; i < 8; i++) printf("%02X", pubY[i]); printf("...\n"); printf(" Ephemeral key generated successfully (private key in STSE internal memory)\n"); wc_ecc_free(&key); wc_FreeRng(&rng); TEST_PASS("ECDHE P-256 ephemeral key generation"); return 0; } /*----------------------------------------------------------------------------- * Test: ECDHE P-256 Shared Secret Computation with STSAFE-A120 * Note: This test uses crypto callbacks which use slot-based keys. * True ECDHE ephemeral keys are only used in TLS PK callbacks. *---------------------------------------------------------------------------*/ static int test_ecdhe_shared_secret_p256(void) { ecc_key keyHW; /* Hardware key in STSAFE (ephemeral slot via crypto callback) */ ecc_key keySW; /* Software key (wolfCrypt) */ WC_RNG rng; int ret; byte sharedHW[32], sharedSW[32]; word32 sharedHWLen = sizeof(sharedHW), sharedSWLen = sizeof(sharedSW); int i; printf("\nTest: ECDH P-256 Shared Secret Computation (STSAFE + wolfCrypt)\n"); printf(" Note: One side uses STSAFE hardware (ephemeral slot), other uses wolfCrypt software\n"); ret = wc_InitRng(&rng); if (ret != 0) { printf(" Error: wc_InitRng failed: %d\n", ret); TEST_FAIL("ECDHE P-256 shared secret RNG init"); return -1; } /* Initialize hardware ECDH 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("ECDHE P-256 key init HW"); return -1; } /* Initialize software key (INVALID_DEVID for software/wolfCrypt) */ 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("ECDHE P-256 key init SW"); return -1; } /* Generate hardware key pair (in STSAFE ephemeral slot via crypto callback) */ printf(" Generating hardware key pair (STSAFE ephemeral slot via crypto callback)...\n"); keyHW.devCtx = (void*)STSAFE_KEY_SLOT_EPHEMERAL; ret = wc_ecc_make_key_ex(&rng, 32, &keyHW, ECC_SECP256R1); 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 ephemeral slot)\n"); /* Generate software key pair (wolfCrypt) */ printf(" Generating software key pair (wolfCrypt)...\n"); ret = wc_ecc_make_key_ex(&rng, 32, &keySW, ECC_SECP256R1); 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\n"); /* 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"); ret = wc_ecc_shared_secret(&keyHW, &keySW, sharedHW, &sharedHWLen); 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 shared secret computed (%d bytes)\n", sharedHWLen); /* Compute shared secret using wolfCrypt (SW priv * HW pub) */ printf(" Computing shared secret (wolfCrypt: SW priv * HW pub)...\n"); ret = wc_ecc_shared_secret(&keySW, &keyHW, sharedSW, &sharedSWLen); 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(" wolfCrypt shared secret computed (%d bytes)\n", sharedSWLen); /* Compare shared secrets - they must match! */ if (sharedHWLen != sharedSWLen || memcmp(sharedHW, sharedSW, sharedHWLen) != 0) { printf(" Error: Shared secrets don't match!\n"); printf(" STSAFE: "); for (i = 0; i < 8; i++) printf("%02X", sharedHW[i]); printf("...\n"); printf(" wolfCrypt: "); 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; } /* Verify shared secret is non-zero */ int all_zero = 1; for (i = 0; i < (int)sharedHWLen; i++) { if (sharedHW[i] != 0) { all_zero = 0; break; } } if (all_zero) { printf(" Error: Shared secret is all zeros\n"); wc_ecc_free(&keyHW); wc_ecc_free(&keySW); wc_FreeRng(&rng); TEST_FAIL("ECDH P-256 invalid shared secret"); 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 shared secret computation"); return 0; } /*----------------------------------------------------------------------------- * Main *---------------------------------------------------------------------------*/ int main(void) { int ret; printf("================================================\n"); printf("wolfSSL STSAFE-A120 Crypto Callback 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(); test_ecc_keygen_p256(); test_ecc_keygen_p384(); test_ecdsa_p256(); test_ecdsa_p384(); #if defined(HAVE_ECC_BRAINPOOL) && defined(STSE_CONF_ECC_BRAINPOOL_P_256) test_ecc_keygen_brainpool_p256(); test_ecdsa_brainpool_p256(); #endif #if defined(HAVE_ECC_BRAINPOOL) && defined(STSE_CONF_ECC_BRAINPOOL_P_384) test_ecc_keygen_brainpool_p384(); test_ecdsa_brainpool_p384(); #endif /* ECDHE tests */ test_ecdhe_keygen_p256(); test_ecdhe_shared_secret_p256(); /* 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; }