Skip to content

Commit cfd8193

Browse files
committed
Fix SE050 RSA-PSS signing, key cleanup, and mutex leaks
RSA-PSS fix: Skip SE050 hardware path for RSA-PSS sign and verify operations in RsaPublicEncryptEx() and RsaPrivateDecryptEx(). The SE050's PSS sign API (Se05x_API_RSASign) is a hash-then-sign operation, which double-hashes when wolfSSL passes a pre-computed digest (as done during TLS CertificateVerify). PSS operations now fall through to the software RSA path. PKCS#1 v1.5 signing continues to use SE050 hardware. Key object leak fix: Add se050_rsa_free_key() called from wc_FreeRsaKey() to erase wolfSSL-allocated RSA key objects from SE050 persistent storage on free. Without this, persistent key slots on the SE050 are never reclaimed and eventually exhaust secure storage. Add matching sss_key_store_erase_key() calls to se050_ecc_free_key(), se050_ed25519_free_key(), and se050_curve25519_free_key(). Only keys with keyId >= SE050_KEYID_START are erased (pre-provisioned keys are left intact). Mutex leak fix: Add missing wolfSSL_CryptHwMutexUnLock() calls before early returns in se050_rsa_sign(), se050_rsa_verify(), se050_rsa_public_encrypt(), and se050_rsa_private_decrypt() when the algorithm lookup fails after the mutex has already been acquired. ZD 21212
1 parent 7de150e commit cfd8193

2 files changed

Lines changed: 136 additions & 7 deletions

File tree

wolfcrypt/src/port/nxp/se050_port.c

Lines changed: 120 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,8 +1017,59 @@ int wc_se050_rsa_insert_public_key(word32 keyId, const byte* rsaDer,
10171017
}
10181018

10191019
/**
1020-
* Return sss_algorithm_t type for RSA sign/verify based on wolfCrypt pad type,
1021-
* hash value, and mask generation function (mgf).
1020+
* Free an RSA key object from the SE050. Erases key from persistent storage
1021+
* if it was allocated by wolfSSL (not pre-provisioned).
1022+
*
1023+
* key Pointer to initialized RsaKey structure
1024+
*/
1025+
void se050_rsa_free_key(struct RsaKey* key)
1026+
{
1027+
sss_status_t status = kStatus_SSS_Success;
1028+
sss_object_t keyObject;
1029+
sss_key_store_t host_keystore;
1030+
1031+
#ifdef SE050_DEBUG
1032+
printf("se050_rsa_free_key: key %p, keyId %d\n", key, key->keyId);
1033+
#endif
1034+
1035+
if (cfg_se050_i2c_pi == NULL) {
1036+
return;
1037+
}
1038+
if (key->keyIdSet == 0) {
1039+
return;
1040+
}
1041+
1042+
if (wolfSSL_CryptHwMutexLock() != 0) {
1043+
return;
1044+
}
1045+
1046+
status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
1047+
if (status == kStatus_SSS_Success) {
1048+
status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_RSA);
1049+
}
1050+
if (status == kStatus_SSS_Success) {
1051+
status = sss_key_object_init(&keyObject, &host_keystore);
1052+
}
1053+
if (status == kStatus_SSS_Success) {
1054+
status = sss_key_object_get_handle(&keyObject, key->keyId);
1055+
}
1056+
1057+
if (status == kStatus_SSS_Success) {
1058+
/* Erase key from SE050 persistent storage if it was allocated
1059+
* by wolfSSL (not a pre-provisioned key). Without this, persistent
1060+
* key objects leak on the SE050 and can exhaust secure storage. */
1061+
if (key->keyId >= SE050_KEYID_START) {
1062+
sss_key_store_erase_key(&host_keystore, &keyObject);
1063+
}
1064+
sss_key_object_free(&keyObject);
1065+
key->keyId = 0;
1066+
key->keyIdSet = 0;
1067+
}
1068+
wolfSSL_CryptHwMutexUnLock();
1069+
}
1070+
1071+
/**
1072+
* Get SSS algorithm type for RSA signature operations.
10221073
*
10231074
* padType padding type
10241075
* hash hash function
@@ -1172,22 +1223,39 @@ int se050_rsa_sign(const byte* in, word32 inLen, byte* out,
11721223
algorithm = se050_get_rsa_signature_type(pad_type, hash, mgf);
11731224
if (algorithm == kAlgorithm_None) {
11741225
WOLFSSL_MSG("Unsupported padding/hash/mgf combination for SE050");
1226+
wolfSSL_CryptHwMutexUnLock();
11751227
return BAD_FUNC_ARG;
11761228
}
1229+
#ifdef SE050_DEBUG
1230+
printf("se050_rsa_sign: algorithm = %d, keySz = %d, keyIdSet = %d\n",
1231+
algorithm, keySz, key->keyIdSet);
1232+
#endif
11771233

11781234
status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
1235+
#ifdef SE050_DEBUG
1236+
printf("se050_rsa_sign: sss_key_store_context_init status = %d\n", status);
1237+
#endif
11791238
if (status == kStatus_SSS_Success) {
11801239
status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_RSA);
1240+
#ifdef SE050_DEBUG
1241+
printf("se050_rsa_sign: sss_key_store_allocate status = %d\n", status);
1242+
#endif
11811243
}
11821244
if (status == kStatus_SSS_Success) {
11831245
status = sss_key_object_init(&newKey, &host_keystore);
1246+
#ifdef SE050_DEBUG
1247+
printf("se050_rsa_sign: sss_key_object_init status = %d\n", status);
1248+
#endif
11841249
}
11851250
if (status == kStatus_SSS_Success) {
11861251
keyId = key->keyId;
11871252
if (key->keyIdSet == 0) {
11881253
/* key was not generated in SE050, export RsaKey to DER
11891254
* and use that to store into SE050 keystore */
11901255
derSz = wc_RsaKeyToDer(key, NULL, 0);
1256+
#ifdef SE050_DEBUG
1257+
printf("se050_rsa_sign: wc_RsaKeyToDer size query = %d\n", derSz);
1258+
#endif
11911259
if (derSz < 0) {
11921260
status = kStatus_SSS_Fail;
11931261
ret = derSz;
@@ -1203,6 +1271,9 @@ int se050_rsa_sign(const byte* in, word32 inLen, byte* out,
12031271
}
12041272
if (status == kStatus_SSS_Success) {
12051273
derSz = wc_RsaKeyToDer(key, derBuf, derSz);
1274+
#ifdef SE050_DEBUG
1275+
printf("se050_rsa_sign: wc_RsaKeyToDer export = %d\n", derSz);
1276+
#endif
12061277
if (derSz < 0) {
12071278
status = kStatus_SSS_Fail;
12081279
ret = derSz;
@@ -1213,31 +1284,60 @@ int se050_rsa_sign(const byte* in, word32 inLen, byte* out,
12131284
status = sss_key_object_allocate_handle(&newKey, keyId,
12141285
kSSS_KeyPart_Pair, kSSS_CipherType_RSA, keySz,
12151286
kKeyObject_Mode_Persistent);
1287+
#ifdef SE050_DEBUG
1288+
printf("se050_rsa_sign: sss_key_object_allocate_handle "
1289+
"status = %d, keyId = %d\n", status, keyId);
1290+
#endif
12161291
}
12171292
if (status == kStatus_SSS_Success) {
12181293
/* Try to delete existing key first, ignore return since will
12191294
* fail if no key exists yet */
1220-
sss_key_store_erase_key(&host_keystore, &newKey);
1295+
status = sss_key_store_erase_key(&host_keystore, &newKey);
1296+
#ifdef SE050_DEBUG
1297+
printf("se050_rsa_sign: sss_key_store_erase_key "
1298+
"status = %d\n", status);
1299+
#endif
1300+
/* Reset status - erase failing is expected if key doesn't
1301+
* exist yet */
1302+
status = kStatus_SSS_Success;
12211303

12221304
keyCreated = 1;
12231305
status = sss_key_store_set_key(&host_keystore, &newKey, derBuf,
12241306
derSz, (keySz * 8), NULL, 0);
1307+
#ifdef SE050_DEBUG
1308+
printf("se050_rsa_sign: sss_key_store_set_key "
1309+
"status = %d, derSz = %d, keyBits = %d\n",
1310+
status, derSz, (keySz * 8));
1311+
#endif
12251312
}
12261313

12271314
XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12281315
}
12291316
else {
12301317
status = sss_key_object_get_handle(&newKey, keyId);
1318+
#ifdef SE050_DEBUG
1319+
printf("se050_rsa_sign: sss_key_object_get_handle "
1320+
"status = %d, keyId = %d\n", status, keyId);
1321+
#endif
12311322
}
12321323
}
12331324

12341325
if (status == kStatus_SSS_Success) {
12351326
status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi,
12361327
&newKey, algorithm, kMode_SSS_Sign);
1328+
#ifdef SE050_DEBUG
1329+
printf("se050_rsa_sign: sss_asymmetric_context_init "
1330+
"status = %d, algorithm = %d\n", status, algorithm);
1331+
#endif
12371332
if (status == kStatus_SSS_Success) {
12381333
sigSz = outLen;
1239-
status = sss_asymmetric_sign_digest(&ctx_asymm, (uint8_t*)in, inLen,
1240-
out, &sigSz);
1334+
status = sss_asymmetric_sign_digest(&ctx_asymm, (uint8_t*)in,
1335+
inLen, out, &sigSz);
1336+
#ifdef SE050_DEBUG
1337+
printf("se050_rsa_sign: sss_asymmetric_sign_digest "
1338+
"status = %d, inLen = %d, sigSz = %d\n",
1339+
status, inLen, (int)sigSz);
1340+
#endif
12411341
}
12421342
sss_asymmetric_context_free(&ctx_asymm);
12431343
}
@@ -1327,6 +1427,7 @@ int se050_rsa_verify(const byte* in, word32 inLen, byte* out, word32 outLen,
13271427
algorithm = se050_get_rsa_signature_type(pad_type, hash, mgf);
13281428
if (algorithm == kAlgorithm_None) {
13291429
WOLFSSL_MSG("Unsupported padding/hash/mgf combination for SE050");
1430+
wolfSSL_CryptHwMutexUnLock();
13301431
return BAD_FUNC_ARG;
13311432
}
13321433

@@ -1515,6 +1616,7 @@ int se050_rsa_public_encrypt(const byte* in, word32 inLen, byte* out,
15151616
algorithm = se050_get_rsa_encrypt_type(pad_type, hash);
15161617
if (algorithm == kAlgorithm_None) {
15171618
WOLFSSL_MSG("Unsupported padding/hash/mgf combination for SE050");
1619+
wolfSSL_CryptHwMutexUnLock();
15181620
return BAD_FUNC_ARG;
15191621
}
15201622

@@ -1673,6 +1775,7 @@ int se050_rsa_private_decrypt(const byte* in, word32 inLen, byte* out,
16731775
algorithm = se050_get_rsa_encrypt_type(pad_type, hash);
16741776
if (algorithm == kAlgorithm_None) {
16751777
WOLFSSL_MSG("Unsupported padding/hash/mgf combination for SE050");
1778+
wolfSSL_CryptHwMutexUnLock();
16761779
return BAD_FUNC_ARG;
16771780
}
16781781

@@ -2334,6 +2437,12 @@ void se050_ecc_free_key(struct ecc_key* key)
23342437
}
23352438

23362439
if (status == kStatus_SSS_Success) {
2440+
/* Erase key from SE050 persistent storage if it was allocated
2441+
* by wolfSSL (not a pre-provisioned key). Without this, persistent
2442+
* key objects leak on the SE050 and can exhaust secure storage. */
2443+
if (key->keyId >= SE050_KEYID_START) {
2444+
sss_key_store_erase_key(&host_keystore, &keyObject);
2445+
}
23372446
sss_key_object_free(&keyObject);
23382447
key->keyId = 0;
23392448
key->keyIdSet = 0;
@@ -2795,6 +2904,9 @@ void se050_ed25519_free_key(ed25519_key* key)
27952904
status = sss_key_object_get_handle(&newKey, key->keyId);
27962905
}
27972906
if (status == kStatus_SSS_Success) {
2907+
if (key->keyId >= SE050_KEYID_START) {
2908+
sss_key_store_erase_key(&host_keystore, &newKey);
2909+
}
27982910
sss_key_object_free(&newKey);
27992911
key->keyId = 0;
28002912
key->keyIdSet = 0;
@@ -3268,6 +3380,9 @@ void se050_curve25519_free_key(struct curve25519_key* key)
32683380
status = sss_key_object_get_handle(&newKey, key->keyId);
32693381
}
32703382
if (status == kStatus_SSS_Success) {
3383+
if (key->keyId >= SE050_KEYID_START) {
3384+
sss_key_store_erase_key(&host_keystore, &newKey);
3385+
}
32713386
sss_key_object_free(&newKey);
32723387
key->keyId = 0;
32733388
key->keyIdSet = 0;

wolfcrypt/src/rsa.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,10 @@ int wc_FreeRsaKey(RsaKey* key)
557557
return BAD_FUNC_ARG;
558558
}
559559

560+
#if defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_RSA)
561+
se050_rsa_free_key(key);
562+
#endif
563+
560564
wc_RsaCleanup(key);
561565

562566
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)
@@ -3389,7 +3393,12 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
33893393
mgf, label, labelSz, sz);
33903394
}
33913395
else if (rsa_type == RSA_PRIVATE_ENCRYPT &&
3392-
pad_value == RSA_BLOCK_TYPE_1) {
3396+
pad_value == RSA_BLOCK_TYPE_1 &&
3397+
pad_type != WC_RSA_PSS_PAD) {
3398+
/* SE050 handles PKCS#1 v1.5 signing directly. PSS signing falls
3399+
* through to software path because the SE050 PSS sign API
3400+
* (Se05x_API_RSASign) is hash-then-sign and does not support
3401+
* signing a pre-computed digest without double-hashing. */
33933402
return se050_rsa_sign(in, inLen, out, outLen, key, rsa_type,
33943403
pad_value, pad_type, hash, mgf, label,
33953404
labelSz, sz);
@@ -3555,7 +3564,12 @@ static int RsaPrivateDecryptEx(const byte* in, word32 inLen, byte* out,
35553564
return ret;
35563565
}
35573566
else if (rsa_type == RSA_PUBLIC_DECRYPT &&
3558-
pad_value == RSA_BLOCK_TYPE_1) {
3567+
pad_value == RSA_BLOCK_TYPE_1 &&
3568+
pad_type != WC_RSA_PSS_PAD) {
3569+
/* SE050 handles PKCS#1 v1.5 verification directly. PSS
3570+
* verification falls through to software path to match the
3571+
* software PSS signing path (SE050 PSS sign uses hash-then-sign
3572+
* which double-hashes a pre-computed digest). */
35593573
ret = se050_rsa_verify(in, inLen, out, outLen, key, rsa_type,
35603574
pad_value, pad_type, hash, mgf, label,
35613575
labelSz);

0 commit comments

Comments
 (0)