Skip to content

Commit 0d7c58e

Browse files
authored
Merge pull request #9912 from LinuxJedi/se050-fixes2
Fix SE050 RSA-PSS signing, key cleanup, and mutex leaks
2 parents 533e9b0 + cfd8193 commit 0d7c58e

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
@@ -1022,8 +1022,59 @@ int wc_se050_rsa_insert_public_key(word32 keyId, const byte* rsaDer,
10221022
}
10231023

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

11831239
status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
1240+
#ifdef SE050_DEBUG
1241+
printf("se050_rsa_sign: sss_key_store_context_init status = %d\n", status);
1242+
#endif
11841243
if (status == kStatus_SSS_Success) {
11851244
status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_RSA);
1245+
#ifdef SE050_DEBUG
1246+
printf("se050_rsa_sign: sss_key_store_allocate status = %d\n", status);
1247+
#endif
11861248
}
11871249
if (status == kStatus_SSS_Success) {
11881250
status = sss_key_object_init(&newKey, &host_keystore);
1251+
#ifdef SE050_DEBUG
1252+
printf("se050_rsa_sign: sss_key_object_init status = %d\n", status);
1253+
#endif
11891254
}
11901255
if (status == kStatus_SSS_Success) {
11911256
keyId = key->keyId;
11921257
if (key->keyIdSet == 0) {
11931258
/* key was not generated in SE050, export RsaKey to DER
11941259
* and use that to store into SE050 keystore */
11951260
derSz = wc_RsaKeyToDer(key, NULL, 0);
1261+
#ifdef SE050_DEBUG
1262+
printf("se050_rsa_sign: wc_RsaKeyToDer size query = %d\n", derSz);
1263+
#endif
11961264
if (derSz < 0) {
11971265
status = kStatus_SSS_Fail;
11981266
ret = derSz;
@@ -1208,6 +1276,9 @@ int se050_rsa_sign(const byte* in, word32 inLen, byte* out,
12081276
}
12091277
if (status == kStatus_SSS_Success) {
12101278
derSz = wc_RsaKeyToDer(key, derBuf, derSz);
1279+
#ifdef SE050_DEBUG
1280+
printf("se050_rsa_sign: wc_RsaKeyToDer export = %d\n", derSz);
1281+
#endif
12111282
if (derSz < 0) {
12121283
status = kStatus_SSS_Fail;
12131284
ret = derSz;
@@ -1218,31 +1289,60 @@ int se050_rsa_sign(const byte* in, word32 inLen, byte* out,
12181289
status = sss_key_object_allocate_handle(&newKey, keyId,
12191290
kSSS_KeyPart_Pair, kSSS_CipherType_RSA, keySz,
12201291
kKeyObject_Mode_Persistent);
1292+
#ifdef SE050_DEBUG
1293+
printf("se050_rsa_sign: sss_key_object_allocate_handle "
1294+
"status = %d, keyId = %d\n", status, keyId);
1295+
#endif
12211296
}
12221297
if (status == kStatus_SSS_Success) {
12231298
/* Try to delete existing key first, ignore return since will
12241299
* fail if no key exists yet */
1225-
sss_key_store_erase_key(&host_keystore, &newKey);
1300+
status = sss_key_store_erase_key(&host_keystore, &newKey);
1301+
#ifdef SE050_DEBUG
1302+
printf("se050_rsa_sign: sss_key_store_erase_key "
1303+
"status = %d\n", status);
1304+
#endif
1305+
/* Reset status - erase failing is expected if key doesn't
1306+
* exist yet */
1307+
status = kStatus_SSS_Success;
12261308

12271309
keyCreated = 1;
12281310
status = sss_key_store_set_key(&host_keystore, &newKey, derBuf,
12291311
derSz, (keySz * 8), NULL, 0);
1312+
#ifdef SE050_DEBUG
1313+
printf("se050_rsa_sign: sss_key_store_set_key "
1314+
"status = %d, derSz = %d, keyBits = %d\n",
1315+
status, derSz, (keySz * 8));
1316+
#endif
12301317
}
12311318

12321319
XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12331320
}
12341321
else {
12351322
status = sss_key_object_get_handle(&newKey, keyId);
1323+
#ifdef SE050_DEBUG
1324+
printf("se050_rsa_sign: sss_key_object_get_handle "
1325+
"status = %d, keyId = %d\n", status, keyId);
1326+
#endif
12361327
}
12371328
}
12381329

12391330
if (status == kStatus_SSS_Success) {
12401331
status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi,
12411332
&newKey, algorithm, kMode_SSS_Sign);
1333+
#ifdef SE050_DEBUG
1334+
printf("se050_rsa_sign: sss_asymmetric_context_init "
1335+
"status = %d, algorithm = %d\n", status, algorithm);
1336+
#endif
12421337
if (status == kStatus_SSS_Success) {
12431338
sigSz = outLen;
1244-
status = sss_asymmetric_sign_digest(&ctx_asymm, (uint8_t*)in, inLen,
1245-
out, &sigSz);
1339+
status = sss_asymmetric_sign_digest(&ctx_asymm, (uint8_t*)in,
1340+
inLen, out, &sigSz);
1341+
#ifdef SE050_DEBUG
1342+
printf("se050_rsa_sign: sss_asymmetric_sign_digest "
1343+
"status = %d, inLen = %d, sigSz = %d\n",
1344+
status, inLen, (int)sigSz);
1345+
#endif
12461346
}
12471347
sss_asymmetric_context_free(&ctx_asymm);
12481348
}
@@ -1332,6 +1432,7 @@ int se050_rsa_verify(const byte* in, word32 inLen, byte* out, word32 outLen,
13321432
algorithm = se050_get_rsa_signature_type(pad_type, hash, mgf);
13331433
if (algorithm == kAlgorithm_None) {
13341434
WOLFSSL_MSG("Unsupported padding/hash/mgf combination for SE050");
1435+
wolfSSL_CryptHwMutexUnLock();
13351436
return BAD_FUNC_ARG;
13361437
}
13371438

@@ -1520,6 +1621,7 @@ int se050_rsa_public_encrypt(const byte* in, word32 inLen, byte* out,
15201621
algorithm = se050_get_rsa_encrypt_type(pad_type, hash);
15211622
if (algorithm == kAlgorithm_None) {
15221623
WOLFSSL_MSG("Unsupported padding/hash/mgf combination for SE050");
1624+
wolfSSL_CryptHwMutexUnLock();
15231625
return BAD_FUNC_ARG;
15241626
}
15251627

@@ -1678,6 +1780,7 @@ int se050_rsa_private_decrypt(const byte* in, word32 inLen, byte* out,
16781780
algorithm = se050_get_rsa_encrypt_type(pad_type, hash);
16791781
if (algorithm == kAlgorithm_None) {
16801782
WOLFSSL_MSG("Unsupported padding/hash/mgf combination for SE050");
1783+
wolfSSL_CryptHwMutexUnLock();
16811784
return BAD_FUNC_ARG;
16821785
}
16831786

@@ -2339,6 +2442,12 @@ void se050_ecc_free_key(struct ecc_key* key)
23392442
}
23402443

23412444
if (status == kStatus_SSS_Success) {
2445+
/* Erase key from SE050 persistent storage if it was allocated
2446+
* by wolfSSL (not a pre-provisioned key). Without this, persistent
2447+
* key objects leak on the SE050 and can exhaust secure storage. */
2448+
if (key->keyId >= SE050_KEYID_START) {
2449+
sss_key_store_erase_key(&host_keystore, &keyObject);
2450+
}
23422451
sss_key_object_free(&keyObject);
23432452
key->keyId = 0;
23442453
key->keyIdSet = 0;
@@ -2800,6 +2909,9 @@ void se050_ed25519_free_key(ed25519_key* key)
28002909
status = sss_key_object_get_handle(&newKey, key->keyId);
28012910
}
28022911
if (status == kStatus_SSS_Success) {
2912+
if (key->keyId >= SE050_KEYID_START) {
2913+
sss_key_store_erase_key(&host_keystore, &newKey);
2914+
}
28032915
sss_key_object_free(&newKey);
28042916
key->keyId = 0;
28052917
key->keyIdSet = 0;
@@ -3273,6 +3385,9 @@ void se050_curve25519_free_key(struct curve25519_key* key)
32733385
status = sss_key_object_get_handle(&newKey, key->keyId);
32743386
}
32753387
if (status == kStatus_SSS_Success) {
3388+
if (key->keyId >= SE050_KEYID_START) {
3389+
sss_key_store_erase_key(&host_keystore, &newKey);
3390+
}
32763391
sss_key_object_free(&newKey);
32773392
key->keyId = 0;
32783393
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)