From f08d7ba950316e98de408b34cadd5f3bc1b03664 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Sun, 12 Apr 2026 10:50:02 +0100 Subject: [PATCH] Fix SE050 RSA port bugs - se050_rsa_verify: when the function uploads only the public part of the key (keyCreated == 1), erase the transient SE050 object and don't persist keyIdSet = 1. A subsequent sign on the same RsaKey was reusing the public-only SE050 object and failing. Pre-existing bindings (from wc_RsaUseKeyId or a prior sign that uploaded a keypair) are preserved untouched. - rsa_keygen_test: add WOLFSSL_SE050 to the existing WOLFSSL_CRYPTOCELL guard around the export-then-decode round-trip. SE050-generated keys keep their private components in the secure element, so wc_RsaKeyToDer + wc_RsaPrivateKeyDecode cannot complete. Matching guard on the idx declaration to avoid an unused-variable warning. --- wolfcrypt/src/port/nxp/se050_port.c | 18 ++++++++++++++++-- wolfcrypt/test/test.c | 11 +++++++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/wolfcrypt/src/port/nxp/se050_port.c b/wolfcrypt/src/port/nxp/se050_port.c index 987fdb5392..ea951452fd 100644 --- a/wolfcrypt/src/port/nxp/se050_port.c +++ b/wolfcrypt/src/port/nxp/se050_port.c @@ -1538,8 +1538,22 @@ int se050_rsa_verify(const byte* in, word32 inLen, byte* out, word32 outLen, } if (status == kStatus_SSS_Success) { - key->keyId = keyId; - key->keyIdSet = 1; + if (keyCreated) { + /* We uploaded only the public part of the key for this verify. + * Don't persist keyIdSet=1 — a later sign on the same RsaKey + * would reuse this binding and fail because the SE050 object has + * no private material. Erase the transient object so the next + * SE050 op (sign or verify) re-uploads from whatever the host + * RsaKey currently holds. */ + sss_key_store_erase_key(&host_keystore, &newKey); + sss_key_object_free(&newKey); + } + else { + /* Pre-existing keyIdSet=1 binding (e.g. wc_RsaUseKeyId or prior + * sign that uploaded a keypair). Preserve it. */ + key->keyId = keyId; + key->keyIdSet = 1; + } } else { if (keyCreated) { diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index debcb1b031..8d9ebd5924 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -25357,7 +25357,7 @@ static wc_test_ret_t rsa_keygen_test(WC_RNG* rng) #else byte der[1280]; #endif -#ifndef WOLFSSL_CRYPTOCELL +#if !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SE050) word32 idx = 0; #endif int derSz = 0; @@ -25435,13 +25435,16 @@ static wc_test_ret_t rsa_keygen_test(WC_RNG* rng) if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa); -#ifndef WOLFSSL_CRYPTOCELL +#if !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SE050) idx = 0; - /* The private key part of the key gen pairs from cryptocell can't be exported */ + /* The private key part of key pairs generated inside a secure element + * (CryptoCell, SE050) stays in hardware and isn't available to + * wc_RsaKeyToDer, so the exported DER can't be parsed back as a + * complete RSAPrivateKey. */ ret = wc_RsaPrivateKeyDecode(der, &idx, genKey, (word32)derSz); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa); -#endif /* WOLFSSL_CRYPTOCELL */ +#endif /* WOLFSSL_CRYPTOCELL && !WOLFSSL_SE050 */ #endif /* !WC_TEST_SKIP_RSA_PRIVATE_EXPORT */ exit_rsa: