Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 120 additions & 5 deletions wolfcrypt/src/port/nxp/se050_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -1017,8 +1017,59 @@ int wc_se050_rsa_insert_public_key(word32 keyId, const byte* rsaDer,
}

/**
* Return sss_algorithm_t type for RSA sign/verify based on wolfCrypt pad type,
* hash value, and mask generation function (mgf).
* Free an RSA key object from the SE050. Erases key from persistent storage
* if it was allocated by wolfSSL (not pre-provisioned).
*
* key Pointer to initialized RsaKey structure
*/
void se050_rsa_free_key(struct RsaKey* key)
{
sss_status_t status = kStatus_SSS_Success;
sss_object_t keyObject;
sss_key_store_t host_keystore;

#ifdef SE050_DEBUG
printf("se050_rsa_free_key: key %p, keyId %d\n", key, key->keyId);
#endif

if (cfg_se050_i2c_pi == NULL) {
return;
}
if (key->keyIdSet == 0) {
return;
}

if (wolfSSL_CryptHwMutexLock() != 0) {
return;
}

status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
if (status == kStatus_SSS_Success) {
status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_RSA);
}
if (status == kStatus_SSS_Success) {
status = sss_key_object_init(&keyObject, &host_keystore);
}
if (status == kStatus_SSS_Success) {
status = sss_key_object_get_handle(&keyObject, key->keyId);
}

if (status == kStatus_SSS_Success) {
/* Erase key from SE050 persistent storage if it was allocated
* by wolfSSL (not a pre-provisioned key). Without this, persistent
* key objects leak on the SE050 and can exhaust secure storage. */
if (key->keyId >= SE050_KEYID_START) {
sss_key_store_erase_key(&host_keystore, &keyObject);
}
sss_key_object_free(&keyObject);
key->keyId = 0;
key->keyIdSet = 0;
}
wolfSSL_CryptHwMutexUnLock();
}

/**
* Get SSS algorithm type for RSA signature operations.
*
* padType padding type
* hash hash function
Expand Down Expand Up @@ -1172,22 +1223,39 @@ int se050_rsa_sign(const byte* in, word32 inLen, byte* out,
algorithm = se050_get_rsa_signature_type(pad_type, hash, mgf);
if (algorithm == kAlgorithm_None) {
WOLFSSL_MSG("Unsupported padding/hash/mgf combination for SE050");
wolfSSL_CryptHwMutexUnLock();
return BAD_FUNC_ARG;
}
#ifdef SE050_DEBUG
printf("se050_rsa_sign: algorithm = %d, keySz = %d, keyIdSet = %d\n",
algorithm, keySz, key->keyIdSet);
#endif

status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi);
#ifdef SE050_DEBUG
printf("se050_rsa_sign: sss_key_store_context_init status = %d\n", status);
#endif
if (status == kStatus_SSS_Success) {
status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_RSA);
#ifdef SE050_DEBUG
printf("se050_rsa_sign: sss_key_store_allocate status = %d\n", status);
#endif
}
if (status == kStatus_SSS_Success) {
status = sss_key_object_init(&newKey, &host_keystore);
#ifdef SE050_DEBUG
printf("se050_rsa_sign: sss_key_object_init status = %d\n", status);
#endif
}
if (status == kStatus_SSS_Success) {
keyId = key->keyId;
if (key->keyIdSet == 0) {
/* key was not generated in SE050, export RsaKey to DER
* and use that to store into SE050 keystore */
derSz = wc_RsaKeyToDer(key, NULL, 0);
#ifdef SE050_DEBUG
printf("se050_rsa_sign: wc_RsaKeyToDer size query = %d\n", derSz);
#endif
if (derSz < 0) {
status = kStatus_SSS_Fail;
ret = derSz;
Expand All @@ -1203,6 +1271,9 @@ int se050_rsa_sign(const byte* in, word32 inLen, byte* out,
}
if (status == kStatus_SSS_Success) {
derSz = wc_RsaKeyToDer(key, derBuf, derSz);
#ifdef SE050_DEBUG
printf("se050_rsa_sign: wc_RsaKeyToDer export = %d\n", derSz);
#endif
if (derSz < 0) {
status = kStatus_SSS_Fail;
ret = derSz;
Expand All @@ -1213,31 +1284,60 @@ int se050_rsa_sign(const byte* in, word32 inLen, byte* out,
status = sss_key_object_allocate_handle(&newKey, keyId,
kSSS_KeyPart_Pair, kSSS_CipherType_RSA, keySz,
kKeyObject_Mode_Persistent);
#ifdef SE050_DEBUG
printf("se050_rsa_sign: sss_key_object_allocate_handle "
"status = %d, keyId = %d\n", status, keyId);
#endif
}
if (status == kStatus_SSS_Success) {
/* Try to delete existing key first, ignore return since will
* fail if no key exists yet */
sss_key_store_erase_key(&host_keystore, &newKey);
status = sss_key_store_erase_key(&host_keystore, &newKey);
#ifdef SE050_DEBUG
printf("se050_rsa_sign: sss_key_store_erase_key "
"status = %d\n", status);
#endif
/* Reset status - erase failing is expected if key doesn't
* exist yet */
status = kStatus_SSS_Success;

keyCreated = 1;
status = sss_key_store_set_key(&host_keystore, &newKey, derBuf,
derSz, (keySz * 8), NULL, 0);
#ifdef SE050_DEBUG
printf("se050_rsa_sign: sss_key_store_set_key "
"status = %d, derSz = %d, keyBits = %d\n",
status, derSz, (keySz * 8));
#endif
}

XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
else {
status = sss_key_object_get_handle(&newKey, keyId);
#ifdef SE050_DEBUG
printf("se050_rsa_sign: sss_key_object_get_handle "
"status = %d, keyId = %d\n", status, keyId);
#endif
}
}

if (status == kStatus_SSS_Success) {
status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi,
&newKey, algorithm, kMode_SSS_Sign);
#ifdef SE050_DEBUG
printf("se050_rsa_sign: sss_asymmetric_context_init "
"status = %d, algorithm = %d\n", status, algorithm);
#endif
if (status == kStatus_SSS_Success) {
sigSz = outLen;
status = sss_asymmetric_sign_digest(&ctx_asymm, (uint8_t*)in, inLen,
out, &sigSz);
status = sss_asymmetric_sign_digest(&ctx_asymm, (uint8_t*)in,
inLen, out, &sigSz);
#ifdef SE050_DEBUG
printf("se050_rsa_sign: sss_asymmetric_sign_digest "
"status = %d, inLen = %d, sigSz = %d\n",
status, inLen, (int)sigSz);
#endif
}
sss_asymmetric_context_free(&ctx_asymm);
}
Expand Down Expand Up @@ -1327,6 +1427,7 @@ int se050_rsa_verify(const byte* in, word32 inLen, byte* out, word32 outLen,
algorithm = se050_get_rsa_signature_type(pad_type, hash, mgf);
if (algorithm == kAlgorithm_None) {
WOLFSSL_MSG("Unsupported padding/hash/mgf combination for SE050");
wolfSSL_CryptHwMutexUnLock();
return BAD_FUNC_ARG;
}

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

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

Expand Down Expand Up @@ -2334,6 +2437,12 @@ void se050_ecc_free_key(struct ecc_key* key)
}

if (status == kStatus_SSS_Success) {
/* Erase key from SE050 persistent storage if it was allocated
* by wolfSSL (not a pre-provisioned key). Without this, persistent
* key objects leak on the SE050 and can exhaust secure storage. */
if (key->keyId >= SE050_KEYID_START) {
sss_key_store_erase_key(&host_keystore, &keyObject);
}
sss_key_object_free(&keyObject);
key->keyId = 0;
key->keyIdSet = 0;
Expand Down Expand Up @@ -2795,6 +2904,9 @@ void se050_ed25519_free_key(ed25519_key* key)
status = sss_key_object_get_handle(&newKey, key->keyId);
}
if (status == kStatus_SSS_Success) {
if (key->keyId >= SE050_KEYID_START) {
sss_key_store_erase_key(&host_keystore, &newKey);
}
sss_key_object_free(&newKey);
key->keyId = 0;
key->keyIdSet = 0;
Expand Down Expand Up @@ -3268,6 +3380,9 @@ void se050_curve25519_free_key(struct curve25519_key* key)
status = sss_key_object_get_handle(&newKey, key->keyId);
}
if (status == kStatus_SSS_Success) {
if (key->keyId >= SE050_KEYID_START) {
sss_key_store_erase_key(&host_keystore, &newKey);
}
sss_key_object_free(&newKey);
key->keyId = 0;
key->keyIdSet = 0;
Expand Down
18 changes: 16 additions & 2 deletions wolfcrypt/src/rsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,10 @@ int wc_FreeRsaKey(RsaKey* key)
return BAD_FUNC_ARG;
}

#if defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_RSA)
se050_rsa_free_key(key);
#endif

wc_RsaCleanup(key);

#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)
Expand Down Expand Up @@ -3395,7 +3399,12 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
mgf, label, labelSz, sz);
}
else if (rsa_type == RSA_PRIVATE_ENCRYPT &&
pad_value == RSA_BLOCK_TYPE_1) {
pad_value == RSA_BLOCK_TYPE_1 &&
pad_type != WC_RSA_PSS_PAD) {
/* SE050 handles PKCS#1 v1.5 signing directly. PSS signing falls
* through to software path because the SE050 PSS sign API
* (Se05x_API_RSASign) is hash-then-sign and does not support
* signing a pre-computed digest without double-hashing. */
return se050_rsa_sign(in, inLen, out, outLen, key, rsa_type,
pad_value, pad_type, hash, mgf, label,
labelSz, sz);
Expand Down Expand Up @@ -3561,7 +3570,12 @@ static int RsaPrivateDecryptEx(const byte* in, word32 inLen, byte* out,
return ret;
}
else if (rsa_type == RSA_PUBLIC_DECRYPT &&
pad_value == RSA_BLOCK_TYPE_1) {
pad_value == RSA_BLOCK_TYPE_1 &&
pad_type != WC_RSA_PSS_PAD) {
/* SE050 handles PKCS#1 v1.5 verification directly. PSS
* verification falls through to software path to match the
* software PSS signing path (SE050 PSS sign uses hash-then-sign
* which double-hashes a pre-computed digest). */
ret = se050_rsa_verify(in, inLen, out, outLen, key, rsa_type,
pad_value, pad_type, hash, mgf, label,
labelSz);
Expand Down