Skip to content

Commit 38b0fe1

Browse files
committed
Improvements to code for ECDHE and peer review fixes.
1 parent 16fb84d commit 38b0fe1

2 files changed

Lines changed: 60 additions & 203 deletions

File tree

.wolfssl_known_macro_extras

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,8 @@ STM32_NUTTX_RNG
548548
STSAFE_HOST_KEY_CIPHER
549549
STSAFE_HOST_KEY_MAC
550550
STSAFE_I2C_BUS
551+
STSE_CONF_ECC_BRAINPOOL_P_256
552+
STSE_CONF_ECC_BRAINPOOL_P_384
551553
TASK_EXTRA_STACK_SIZE
552554
TCP_NODELAY
553555
TFM_ALREADY_SET

wolfcrypt/src/port/st/stsafe.c

Lines changed: 58 additions & 203 deletions
Original file line numberDiff line numberDiff line change
@@ -276,12 +276,11 @@ int stsafe_interface_init(void)
276276
* \details Uses dedicated key slot (slot 1) for persistent keys.
277277
* For ephemeral ECDHE keys, use stsafe_create_ecdhe_key() instead.
278278
*/
279-
static int stsafe_create_key(stsafe_slot_t* pSlot, stsafe_curve_id_t curve_id,
279+
static int stsafe_create_key(stsafe_slot_t slot, stsafe_curve_id_t curve_id,
280280
uint8_t* pPubKeyRaw)
281281
{
282282
int rc = STSAFE_A_OK;
283283
stse_ReturnCode_t ret;
284-
stsafe_slot_t slot = STSAFE_KEY_SLOT_1; /* Use dedicated key slot for persistent keys */
285284

286285
if (pPubKeyRaw == NULL) {
287286
return BAD_FUNC_ARG;
@@ -299,10 +298,6 @@ static int stsafe_create_key(stsafe_slot_t* pSlot, stsafe_curve_id_t curve_id,
299298
rc = (int)ret;
300299
}
301300

302-
if (rc == STSAFE_A_OK && pSlot != NULL) {
303-
*pSlot = slot;
304-
}
305-
306301
return rc;
307302
}
308303

@@ -460,64 +455,6 @@ static int stsafe_shared_secret(stsafe_slot_t slot, stsafe_curve_id_t curve_id,
460455
return rc;
461456
}
462457

463-
/**
464-
* \brief ECDHE shared secret using STSAFE-A120
465-
* \details Computes shared secret using the ephemeral ECDHE private key
466-
* that was generated by stsafe_create_ecdhe_key(). The ephemeral
467-
* private key is stored internally in the STSE device.
468-
*/
469-
static int stsafe_shared_secret_ecdhe(stsafe_curve_id_t curve_id,
470-
uint8_t* pPubKeyX, uint8_t* pPubKeyY,
471-
uint8_t* pSharedSecret,
472-
int32_t* pSharedSecretLen)
473-
{
474-
int rc = STSAFE_A_OK;
475-
stse_ReturnCode_t ret;
476-
int key_sz = stsafe_get_key_size(curve_id);
477-
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
478-
uint8_t* peerPubKey = NULL;
479-
#else
480-
uint8_t peerPubKey[STSAFE_MAX_PUBKEY_RAW_LEN];
481-
#endif
482-
483-
if (pPubKeyX == NULL || pPubKeyY == NULL || pSharedSecret == NULL ||
484-
pSharedSecretLen == NULL || key_sz == 0) {
485-
return BAD_FUNC_ARG;
486-
}
487-
488-
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
489-
peerPubKey = (uint8_t*)XMALLOC(STSAFE_MAX_PUBKEY_RAW_LEN, NULL,
490-
DYNAMIC_TYPE_TMP_BUFFER);
491-
if (peerPubKey == NULL) {
492-
return MEMORY_E;
493-
}
494-
#endif
495-
496-
/* Combine peer X and Y (X||Y format) */
497-
XMEMCPY(peerPubKey, pPubKeyX, key_sz);
498-
XMEMCPY(peerPubKey + key_sz, pPubKeyY, key_sz);
499-
500-
/* Compute shared secret using ephemeral slot (0xFF)
501-
* The ephemeral private key was generated by stse_generate_ECDHE_key_pair() */
502-
ret = stse_ecc_establish_shared_secret(&g_stse_handler,
503-
STSAFE_KEY_SLOT_EPHEMERAL, (stse_ecc_key_type_t)curve_id, peerPubKey, pSharedSecret);
504-
if (ret != STSE_OK) {
505-
STSAFE_INTERFACE_PRINTF("stse_ecc_establish_shared_secret (ECDHE) error: %d\n",
506-
ret);
507-
rc = (int)ret;
508-
}
509-
510-
if (rc == STSAFE_A_OK) {
511-
*pSharedSecretLen = (int32_t)key_sz;
512-
}
513-
514-
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
515-
XFREE(peerPubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
516-
#endif
517-
518-
return rc;
519-
}
520-
521458
/**
522459
* \brief Read device certificate from STSAFE-A120
523460
*/
@@ -536,11 +473,16 @@ static int stsafe_read_certificate(uint8_t** ppCert, uint32_t* pCertLen)
536473

537474
/* First, get certificate size */
538475
ret = stse_get_device_certificate_size(&g_stse_handler, certZone, &certLen);
539-
if (ret != STSE_OK || certLen == 0) {
476+
if (ret != STSE_OK) {
540477
STSAFE_INTERFACE_PRINTF("stse_get_device_certificate_size error: %d\n",
541478
ret);
542479
rc = (int)ret;
543480
}
481+
else if (certLen == 0) {
482+
/* Certificate size is 0 - invalid certificate data */
483+
STSAFE_INTERFACE_PRINTF("stse_get_device_certificate_size returned zero length\n");
484+
rc = ASN_PARSE_E;
485+
}
544486

545487
/* Allocate buffer */
546488
if (rc == STSAFE_A_OK) {
@@ -988,6 +930,14 @@ static int stsafe_read_certificate(uint8_t** ppCert, uint32_t* pCertLen)
988930
}
989931
break;
990932
}
933+
/* Check if length parsing succeeded */
934+
if (*pCertLen == 0) {
935+
rc = ASN_PARSE_E;
936+
}
937+
}
938+
else {
939+
/* Invalid ASN.1 header - expected SEQUENCE tag */
940+
rc = ASN_PARSE_E;
991941
}
992942
}
993943
else {
@@ -1469,23 +1419,12 @@ int SSL_STSAFE_SharedSecretCb(WOLFSSL* ssl, ecc_key* otherKey,
14691419
}
14701420

14711421
if (err == 0) {
1472-
#ifdef WOLFSSL_STSAFEA120
1473-
/* Use ECDHE shared secret computation for A120 */
1474-
err = stsafe_shared_secret_ecdhe(curve_id, otherKeyX, otherKeyY,
1475-
out, (int32_t*)outlen);
1476-
if (err != STSAFE_A_OK) {
1477-
STSAFE_INTERFACE_PRINTF("stsafe_shared_secret_ecdhe error: %d\n", err);
1478-
err = WC_HW_E;
1479-
}
1480-
#else
1481-
/* Legacy A100/A110 uses slot-based shared secret */
14821422
err = stsafe_shared_secret(slot, curve_id, otherKeyX, otherKeyY,
14831423
out, (int32_t*)outlen);
14841424
if (err != STSAFE_A_OK) {
14851425
STSAFE_INTERFACE_PRINTF("stsafe_shared_secret error: %d\n", err);
14861426
err = WC_HW_E;
14871427
}
1488-
#endif
14891428
}
14901429

14911430
if (tmpKeyInit) {
@@ -1597,17 +1536,25 @@ int wolfSSL_STSAFE_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
15971536
key_sz = stsafe_get_key_size(curve_id);
15981537

15991538
/* For A120, generate keys in slot 1 (persistent slot) by default for ECDSA signing.
1600-
* For ECDH operations, ephemeral keys will be generated on-demand in the ECDH callback
1601-
* if needed (see WC_PK_TYPE_ECDH handling below). */
1539+
* For ECDH operations, the key slot from devCtx will be used directly.
1540+
* If ECDH is required, keys should be generated in the ephemeral slot from the start. */
16021541
#ifdef WOLFSSL_STSAFEA120
1603-
stse_ReturnCode_t ret;
1604-
slot = STSAFE_KEY_SLOT_1; /* Use persistent slot for ECDSA signing */
1605-
ret = stse_generate_ecc_key_pair(&g_stse_handler, slot,
1606-
(stse_ecc_key_type_t)curve_id,
1607-
STSAFE_PERSISTENT_KEY_USAGE_LIMIT,
1608-
pubKeyRaw);
1609-
if (ret != STSE_OK) {
1610-
STSAFE_INTERFACE_PRINTF("stse_generate_ecc_key_pair (slot 1) error: %d\n", ret);
1542+
/* Retrieve slot from devCtx if available, otherwise use default */
1543+
slot = STSAFE_KEY_SLOT_1; /* Default fallback */
1544+
if (info->pk.eckg.key != NULL && info->pk.eckg.key->devCtx != NULL) {
1545+
slot = STSAFE_DEVCXT_TO_SLOT(info->pk.eckg.key->devCtx);
1546+
}
1547+
1548+
STSAFE_INTERFACE_PRINTF("STSAFE: KeyGen slot %d, curve_id %d\n",
1549+
slot, curve_id);
1550+
1551+
if (slot == STSAFE_KEY_SLOT_EPHEMERAL) {
1552+
rc = stsafe_create_ecdhe_key(curve_id, pubKeyRaw);
1553+
} else {
1554+
rc = stsafe_create_key(slot, curve_id, pubKeyRaw);
1555+
}
1556+
if (rc != STSE_OK) {
1557+
STSAFE_INTERFACE_PRINTF("STSAFE: KeyGen (slot %d) error: %d\n", slot, rc);
16111558
rc = WC_HW_E;
16121559
} else {
16131560
rc = STSAFE_A_OK;
@@ -1624,21 +1571,17 @@ int wolfSSL_STSAFE_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
16241571
}
16251572

16261573
if (rc == 0) {
1627-
/* Store slot number directly in devCtx (no dynamic allocation) */
1628-
info->pk.eckg.key->devCtx = STSAFE_SLOT_TO_DEVCXT(slot);
1574+
/* Import public key */
1575+
rc = wc_ecc_import_unsigned(info->pk.eckg.key, pubKeyRaw,
1576+
&pubKeyRaw[key_sz], NULL, ecc_curve);
16291577
}
16301578

16311579
if (rc == 0) {
1632-
/* Import public key - preserve devCtx */
1633-
void* saved_devCtx = info->pk.eckg.key->devCtx;
1634-
rc = wc_ecc_import_unsigned(info->pk.eckg.key, pubKeyRaw,
1635-
&pubKeyRaw[key_sz], NULL, ecc_curve);
1636-
/* Restore devCtx in case import cleared it */
1637-
if (saved_devCtx != NULL && info->pk.eckg.key->devCtx != saved_devCtx) {
1638-
info->pk.eckg.key->devCtx = saved_devCtx;
1639-
}
1580+
/* Store slot number directly in devCtx */
1581+
info->pk.eckg.key->devCtx = STSAFE_SLOT_TO_DEVCXT(slot);
16401582
}
16411583

1584+
16421585
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
16431586
XFREE(pubKeyRaw, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16441587
#endif
@@ -1653,6 +1596,7 @@ int wolfSSL_STSAFE_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
16531596
#endif
16541597
byte* r;
16551598
byte* s;
1599+
stsafe_slot_t slot;
16561600
stsafe_curve_id_t curve_id;
16571601
int ecc_curve;
16581602
word32 inSz = info->pk.eccsign.inlen;
@@ -1690,12 +1634,12 @@ int wolfSSL_STSAFE_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
16901634

16911635
XMEMSET(sigRS, 0, STSAFE_MAX_SIG_LEN);
16921636
/* Retrieve slot from devCtx if available, otherwise use default */
1693-
stsafe_slot_t slot = STSAFE_KEY_SLOT_1; /* Default fallback */
1637+
slot = STSAFE_KEY_SLOT_1; /* Default fallback */
16941638
if (info->pk.eccsign.key != NULL && info->pk.eccsign.key->devCtx != NULL) {
16951639
slot = STSAFE_DEVCXT_TO_SLOT(info->pk.eccsign.key->devCtx);
1696-
STSAFE_INTERFACE_PRINTF("STSAFE: Using slot %d from devCtx for signing\n", slot);
1640+
STSAFE_INTERFACE_PRINTF("STSAFE: Sign using slot %d\n", slot);
16971641
} else {
1698-
WOLFSSL_MSG("STSAFE: Warning: devCtx not found, using default slot 1");
1642+
WOLFSSL_MSG("STSAFE: Sign using default slot 1");
16991643
}
17001644
rc = stsafe_sign(slot, curve_id, digest, sigRS);
17011645
if (rc != STSAFE_A_OK) {
@@ -1815,6 +1759,7 @@ int wolfSSL_STSAFE_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
18151759
word32 otherKeyX_len = STSAFE_MAX_KEY_LEN;
18161760
word32 otherKeyY_len = STSAFE_MAX_KEY_LEN;
18171761
stsafe_curve_id_t curve_id;
1762+
stsafe_slot_t slot;
18181763
int ecc_curve;
18191764

18201765
WOLFSSL_MSG("STSAFE: ECDH");
@@ -1872,116 +1817,26 @@ int wolfSSL_STSAFE_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
18721817
if (rc == 0) {
18731818
*info->pk.ecdh.outlen = 0;
18741819

1875-
/* Check if private key is software but public key is hardware.
1876-
* In this case, we can't use hardware for computation since the
1877-
* private key is not in a slot. Return CRYPTOCB_UNAVAILABLE to
1878-
* let software handle it (but software path may also fail if
1879-
* public key export fails). */
1880-
if (info->pk.ecdh.private_key == NULL ||
1881-
info->pk.ecdh.private_key->devId == INVALID_DEVID) {
1882-
if (info->pk.ecdh.public_key != NULL &&
1883-
info->pk.ecdh.public_key->devId != INVALID_DEVID) {
1884-
WOLFSSL_MSG("STSAFE: Private key is software, public key is hardware - cannot use hardware");
1885-
rc = CRYPTOCB_UNAVAILABLE;
1886-
}
1887-
}
1888-
18891820
if (rc == 0) {
1890-
/* For ECDH operations, use ephemeral slot (0xFF).
1891-
* Keys are generated in slot 1 by default (for ECDSA signing).
1892-
* If the key is in slot 1, generate a new ephemeral key for ECDH.
1893-
* If the key is already in the ephemeral slot, use it directly. */
1894-
stsafe_slot_t slot;
1895-
stsafe_slot_t original_slot = STSAFE_KEY_SLOT_1;
1896-
int need_ephemeral_key = 0;
1897-
1821+
/* For ECDH operations, use the slot from devCtx. */
1822+
slot = STSAFE_KEY_SLOT_EPHEMERAL;
18981823
if (info->pk.ecdh.private_key != NULL &&
18991824
info->pk.ecdh.private_key->devCtx != NULL) {
1900-
original_slot = STSAFE_DEVCXT_TO_SLOT(info->pk.ecdh.private_key->devCtx);
1901-
1902-
/* If key is in slot 1 (for ECDSA), we need to generate ephemeral key for ECDH */
1903-
if (original_slot == STSAFE_KEY_SLOT_1) {
1904-
need_ephemeral_key = 1;
1905-
}
1825+
slot = STSAFE_DEVCXT_TO_SLOT(info->pk.ecdh.private_key->devCtx);
19061826
}
19071827

1908-
if (need_ephemeral_key) {
1909-
#ifdef WOLFSSL_STSAFEA120
1910-
/* Key is in slot 1 (for ECDSA), but ECDH requires ephemeral slot.
1911-
* Generate ephemeral key pair for ECDH. Note: This will overwrite any
1912-
* existing key in ephemeral slot, so for bidirectional ECDH, both keys
1913-
* should be generated in ephemeral slot from the start. */
1914-
stse_ReturnCode_t ret;
1915-
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1916-
byte* ephemeralPubKey = NULL;
1917-
#else
1918-
byte ephemeralPubKey[STSAFE_MAX_PUBKEY_RAW_LEN];
1919-
#endif
1920-
int key_sz = stsafe_get_key_size(curve_id);
1921-
slot = STSAFE_KEY_SLOT_EPHEMERAL;
1922-
1923-
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1924-
ephemeralPubKey = (byte*)XMALLOC(STSAFE_MAX_PUBKEY_RAW_LEN, NULL,
1925-
DYNAMIC_TYPE_TMP_BUFFER);
1926-
if (ephemeralPubKey == NULL) {
1927-
rc = MEMORY_E;
1928-
}
1929-
#endif
1930-
1931-
if (rc == 0) {
1932-
ret = stse_generate_ecc_key_pair(&g_stse_handler, slot,
1933-
(stse_ecc_key_type_t)curve_id,
1934-
STSAFE_EPHEMERAL_KEY_USAGE_LIMIT,
1935-
ephemeralPubKey);
1936-
if (ret != STSE_OK) {
1937-
STSAFE_INTERFACE_PRINTF("stse_generate_ecc_key_pair (ephemeral for ECDH) error: %d\n", ret);
1938-
rc = (int)ret;
1939-
} else {
1940-
WOLFSSL_MSG("STSAFE: Generated ephemeral key for ECDH");
1941-
/* Update devCtx to reflect ephemeral slot for this key */
1942-
if (info->pk.ecdh.private_key != NULL) {
1943-
info->pk.ecdh.private_key->devCtx = STSAFE_SLOT_TO_DEVCXT(slot);
1944-
}
1945-
/* Update the public key in the key structure to match the new ephemeral key */
1946-
if (info->pk.ecdh.private_key != NULL && rc == 0) {
1947-
void* saved_devCtx = info->pk.ecdh.private_key->devCtx;
1948-
rc = wc_ecc_import_unsigned(info->pk.ecdh.private_key,
1949-
ephemeralPubKey, &ephemeralPubKey[key_sz],
1950-
NULL, ecc_curve);
1951-
/* Restore devCtx in case import cleared it */
1952-
if (saved_devCtx != NULL && info->pk.ecdh.private_key->devCtx != saved_devCtx) {
1953-
info->pk.ecdh.private_key->devCtx = saved_devCtx;
1954-
}
1955-
}
1956-
}
1957-
}
1958-
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1959-
XFREE(ephemeralPubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1960-
#endif
1961-
#else /* WOLFSSL_STSAFEA100 */
1962-
/* For A100/A110, ephemeral key generation in ECDH callback
1963-
* is not supported. Keys must be generated in ephemeral slot
1964-
* from the start for ECDH operations. */
1965-
WOLFSSL_MSG("STSAFE: ECDH requires ephemeral slot - key must be generated in ephemeral slot");
1828+
STSAFE_INTERFACE_PRINTF("STSAFE: ECDH with slot %d, curve_id %d\n",
1829+
slot, curve_id);
1830+
1831+
rc = stsafe_shared_secret(slot, curve_id,
1832+
otherKeyX, otherKeyY,
1833+
info->pk.ecdh.out, (int32_t*)info->pk.ecdh.outlen);
1834+
if (rc != STSAFE_A_OK) {
1835+
WOLFSSL_MSG("STSAFE: stsafe_shared_secret failed");
1836+
STSAFE_INTERFACE_PRINTF("stsafe_shared_secret "
1837+
"error: %d (slot: %d, curve_id: %d)\n",
1838+
rc, slot, curve_id);
19661839
rc = WC_HW_E;
1967-
#endif
1968-
} else {
1969-
/* Key is already in ephemeral slot, use it */
1970-
slot = STSAFE_KEY_SLOT_EPHEMERAL;
1971-
}
1972-
1973-
if (rc == 0) {
1974-
STSAFE_INTERFACE_PRINTF("STSAFE: Computing shared secret with ephemeral slot %d, curve_id %d\n",
1975-
slot, curve_id);
1976-
rc = stsafe_shared_secret(slot, curve_id,
1977-
otherKeyX, otherKeyY,
1978-
info->pk.ecdh.out, (int32_t*)info->pk.ecdh.outlen);
1979-
if (rc != STSAFE_A_OK) {
1980-
WOLFSSL_MSG("STSAFE: stsafe_shared_secret failed");
1981-
STSAFE_INTERFACE_PRINTF("stsafe_shared_secret error: %d (slot: %d, curve_id: %d)\n",
1982-
rc, slot, curve_id);
1983-
rc = WC_HW_E;
1984-
}
19851840
}
19861841
}
19871842
}

0 commit comments

Comments
 (0)