Skip to content

Conversation

@dgarske
Copy link
Contributor

@dgarske dgarske commented Jan 6, 2026

Add STSAFE-A120 Support via STSELib

Description

This PR adds support for the ST STSAFE-A120 secure element using the open-source STSELib SDK. The STSAFE-A120 is ST's latest secure element with enhanced cryptographic capabilities and is the successor to the STSAFE-A100/A110 series.

Changes

Files Modified:

  • wolfcrypt/src/port/st/stsafe.c - Added STSAFE-A120/STSELib implementation
  • wolfssl/wolfcrypt/port/st/stsafe.h - Added type abstractions and curve mappings
  • wolfcrypt/src/wc_port.c - Updated STSAFE initialization
  • wolfcrypt/src/port/st/README.md - Added documentation

Features

  • True Random Number Generation (TRNG) - Hardware RNG for seeding wolfSSL's RNG
  • ECC Key Generation - P-256 and P-384 key pair generation in secure element
  • ECDSA Sign/Verify - Hardware-accelerated ECDSA operations
  • ECDH Shared Secret - Elliptic curve Diffie-Hellman key exchange
  • Device Certificate - Read X.509 certificates from secure storage
  • Crypto Callbacks - Full integration with wolfSSL's crypto callback mechanism

Configuration

Enable with:

#define WOLFSSL_STSAFEA120Optional defines:
#define USE_STSAFE_RNG_SEED    /* Use STSAFE for RNG seeding */
#define WOLF_CRYPTO_CB         /* Enable crypto callbacks */
#define STSAFE_I2C_BUS 1       /* I2C bus number (default: 1) */

Dependencies

API Compatibility

The new implementation maintains API compatibility with the existing STSAFE-A100 code:

  • stsafe_interface_init() - Initialize device
  • wolfSSL_STSAFE_CryptoDevCb() - Crypto callback handler
  • SSL_STSAFE_* callback functions for TLS integration

Testing

Tested on Raspberry Pi 5 with STSAFE-A120 connected via I2C:

  • Echo command ✅
  • Random number generation ✅
  • ECC P-256 key generation ✅
  • ECC P-384 key generation ✅
  • ECDSA P-256 sign/verify ✅
  • ECDSA P-384 sign/verify ✅
  • Crypto callback integration ✅

Performance (Raspberry Pi 5)

Operation Time
ECC P-256 KeyGen ~40 ms
ECDSA P-256 Sign ~51 ms
ECDSA P-256 Verify ~79 ms
RNG (256 bytes) <1 ms

Notes

  • The STSELib uses conditional compilation for ECC curves via stse_conf.h
  • Curve ID values in stsafe.h depend on which curves are enabled in stse_conf.h
  • Default configuration enables NIST P-256 and P-384

Related

ZD 20780

@dgarske dgarske self-assigned this Jan 6, 2026
@devin-ai-integration
Copy link
Contributor

🛟 Devin Lifeguard found 3 likely issues in this PR

  • check-all-return-codes snippet: Capture the return value of stsafe_interface_init() in wolfCrypt_Init and, if it is non-zero, propagate or handle the error (e.g., ret = stsafe_interface_init(); if (ret != 0) return ret;).
  • no-memory-leaks snippet: After copying the shared secret, add XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); (and similarly free other SDK-allocated buffers such as pubX/pubY, signature, readBuf, echo_resp) before the function returns.
  • limit-stack-usage snippet: Replace large local buffers (e.g., sigRS, pubKeyX, pubKeyY in SSL_STSAFE_VerifyPeerCertCb) with heap allocations under the WOLFSSL_SMALL_STACK pattern, freeing them before return.

@dgarske
please take a look at the above issues which Devin flagged. Devin will not fix these issues automatically.

@dgarske
Copy link
Contributor Author

dgarske commented Jan 7, 2026

Jenkins retest this please: "AgentOfflineException"

0, 0, 4, &readBuf, STSAFE_A_NO_MAC);

if (status_code == STSAFE_A_OK && readBuf->Length == 4 &&
readBuf->Data[0] == 0x30) {
Copy link
Contributor

@JacobBarthelmeh JacobBarthelmeh Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of 0x30, 0x81, and 0x82 use ASN_SEQUENCE | ASN_CONSTRUCTED and the ASN length values. If this is hard set to avoid needed NO_ASN not defined then please add comments as to what the values are here.

}

if (rc == STSAFE_A_OK && *pCertLen > 0) {
step = 223 - (stsafe_a->CrcSupport ? 2 : 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic number here of 223.

r_length = ((uint16_t)signature->Data[0] << 8) | signature->Data[1];
s_length = ((uint16_t)signature->Data[2 + r_length] << 8) |
signature->Data[3 + r_length];

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be bounds checks here on r_length and s_length before use. It's unlikely that the ST function will return invalid or unexpected data with a status_code return of STSAFE_A_OK but better to have a sanity check.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@dgarske
Copy link
Contributor Author

dgarske commented Jan 12, 2026

Jenkins retest this please: "AgentOfflineException"

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


ret = stse_generate_ecc_key_pair(&g_stse_handler, slot,
(stse_ecc_key_type_t)curve_id,
STSAFEA_EPHEMERAL_KEY_USAGE_LIMIT,
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The macro STSAFEA_EPHEMERAL_KEY_USAGE_LIMIT is used but never defined anywhere in the codebase. This will cause a compilation error. This should likely be a numeric literal (e.g., 255) or defined as a macro in the header file.

Copilot uses AI. Check for mistakes.
Comment on lines 1854 to 1867
if (need_ephemeral_key) {
/* Key is in slot 1 (for ECDSA), but ECDH requires ephemeral slot.
* Generate ephemeral key pair for ECDH. Note: This will overwrite any
* existing key in ephemeral slot, so for bidirectional ECDH, both keys
* should be generated in ephemeral slot from the start. */
stse_ReturnCode_t ret;
byte ephemeralPubKey[STSAFE_MAX_PUBKEY_RAW_LEN];
int key_sz = stsafe_get_key_size(curve_id);
slot = STSAFE_KEY_SLOT_EPHEMERAL;

ret = stse_generate_ecc_key_pair(&g_stse_handler, slot,
(stse_ecc_key_type_t)curve_id,
STSAFEA_EPHEMERAL_KEY_USAGE_LIMIT,
ephemeralPubKey);
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code block uses A120-specific types (stse_ReturnCode_t) and functions (stse_generate_ecc_key_pair) without #ifdef WOLFSSL_STSAFEA120 guards. This will cause compilation errors when building with WOLFSSL_STSAFEA100 defined. The entire block from lines 1854-1892 should be wrapped in #ifdef WOLFSSL_STSAFEA120 ... #else ... #endif to provide appropriate implementation for both A100 and A120.

Copilot uses AI. Check for mistakes.
Comment on lines 1552 to 1558
#ifdef WOLFSSL_STSAFEA120
stse_ReturnCode_t ret;
slot = STSAFE_KEY_SLOT_1; /* Use persistent slot for ECDSA signing */
ret = stse_generate_ecc_key_pair(&g_stse_handler, slot,
(stse_ecc_key_type_t)curve_id,
255, /* usage_limit for persistent keys */
pubKeyRaw);
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The magic number 255 for usage_limit should be defined as a named constant (e.g., STSAFE_PERSISTENT_KEY_USAGE_LIMIT) for better code maintainability and consistency. This same value should be used throughout the codebase where applicable.

Copilot uses AI. Check for mistakes.
Comment on lines +1860 to +1861
byte ephemeralPubKey[STSAFE_MAX_PUBKEY_RAW_LEN];
int key_sz = stsafe_get_key_size(curve_id);
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable key_sz is declared but only used within the STSAFE-A120 specific code path at line 1881. This variable declaration should be moved inside the A120-specific #ifdef block (after adding the missing guards) to avoid unused variable warnings.

Suggested change
byte ephemeralPubKey[STSAFE_MAX_PUBKEY_RAW_LEN];
int key_sz = stsafe_get_key_size(curve_id);
byte ephemeralPubKey[STSAFE_MAX_PUBKEY_RAW_LEN];
#ifdef WOLFSSL_STSAFEA120
int key_sz = stsafe_get_key_size(curve_id);
#endif

Copilot uses AI. Check for mistakes.
@dgarske dgarske requested a review from Copilot January 16, 2026 00:18
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants