Untitled
Anonymous
plain_text
09/06/2024 6:58 AM
9.4 KB
15
Indexable
There are local temporary buffers aesKey and iv which used for crypto operation in encryptCertificateSigningRequest() function. The buffers are not cleared after use.
static int32_t encryptCertificateSigningRequest(TeeAppId_t teeAppId, const uint8_t* csr, const uint32_t csrLen,
uint8_t* outData, uint32_t* outDataLen)
{
int32_t ret = NOT_ERROR;
uint8_t tlvKeyBuf[RSA_BIT_SIZE_DEFAULT / 8], wrappedKeyData[RSA_BIT_SIZE_DEFAULT / 8];
int32_t tlvKeyBufDataLen = 0;
uint8_t aad[AES_BLOCK_SIZE], aesKey[AES256_KEY_SIZE], iv[IV_SIZE], authTag[AES_GCM_TAG_SIZE]; // <- allocating memory on a stack for aesKey and iv
uint8_t wbEncAesKey[AES256_KEY_SIZE * 2];
uint32_t wbEncAesKeyLen = sizeof(wbEncAesKey), unwrappedDataLen = csrLen;
uint8_t *pAesEncData = NULL, *pUnwrappedData = NULL;
#if (defined DEBUG_SELF_TEST)
uint8_t *pAesDecData = NULL;
uint8_t wbDecAesKey[AES256_KEY_SIZE];
uint32_t wbDecAesKeyLen = sizeof(wbDecAesKey);
const SwbTableData_t swbSakDecTableData = {swbSakMc, swbSakDecTable, swbSakDecTableTag};
#endif // End of DEBUG_SELF_TEST
KEY *pHsmRootCaKey = NULL;
const SwbTableData_t swbSakEncTableData = {swbSakMc, swbSakEncTable, swbSakEncTableTag};
if(csr == NULL || csrLen == 0 || csrLen > CSR_DATA_MAX_SIZE || outData == NULL || outDataLen == NULL)
{
LOGE("%s : Invalid agrument.", __func__);
return ERR_TA_INVALID_ARGUMENT;
}
// Unwrap encrypted CSR data.
if((pUnwrappedData = (uint8_t *)secMemoryManagerMalloc(csrLen)) == NULL)
{
LOGE("Failed to allocate memory.");
return ERR_TA_NOT_ENOUGH_MEMORY;
}
memset(pUnwrappedData, 0, csrLen);
if((ret = openSecureObject(csr, csrLen, pUnwrappedData, &unwrappedDataLen,
getTaUid(teeAppId), getTaUidLen(teeAppId))) != NOT_ERROR) // <- unwraping security object
{
LOGE("Failed to unwrap CSR with error %d.", ret);
goto cleanup;
}
// Encrypt CSR with AES256-GCM.
memset(aad, 0, sizeof(aad));
memset(iv, 0, sizeof(iv));
memset(aesKey, 0, sizeof(aesKey));
memset(authTag, 0, sizeof(authTag));
if((ret = getRandBlock(aad, sizeof(aad))) != sizeof(aad))
{
LOGE("Failed to generate AAD.");
goto cleanup;
}
if((ret = getRandBlock(aesKey, sizeof(aesKey))) != sizeof(aesKey)) // <- generating aesKey for encrypting
{
LOGE("Failed to generate AES key.");
goto cleanup;
}
if((ret = getRandBlock(iv, sizeof(iv))) != sizeof(iv)) // <- generating iv for encrypting
{
LOGE("Failed to generate IV.");
goto cleanup;
}
if((pAesEncData = (uint8_t *)secMemoryManagerMalloc(unwrappedDataLen)) == NULL)
{
LOGE("Failed to allocate memory.");
ret = ERR_TA_NOT_ENOUGH_MEMORY;
goto cleanup;
}
memset(pAesEncData, 0, unwrappedDataLen);
if((ret = encryptDataAES_GCM(pUnwrappedData, unwrappedDataLen, aesKey, sizeof(aesKey), iv, AES_GCM_IV_SIZE, // <- encrypting security object with aesKey and iv
aad, sizeof(aad), pAesEncData, authTag, sizeof(authTag))) != NOT_ERROR)
{
LOGE("AES256_GCM encryption is failed with error : %d", ret);
goto cleanup;
}
...
...
LOGD("Encrypt AES key with WB.");
memset(wbEncAesKey, 0, sizeof(wbEncAesKey));
if((ret = swbAesCbcEncrypt(aesKey, sizeof(aesKey), wbEncAesKey, &wbEncAesKeyLen, // <- encrypting aesKey to wbEncAesKey
iv, &swbSakEncTableData)) != NOT_ERROR)
{
LOGE("Failed to SWBC encryption with error %d.", ret);
goto cleanup;
}
#if (defined DEBUG_SELF_TEST)
...
...
#endif // End of DEBUG_SELF_TEST
// Make blob with ecrypted AES key and IV.
memset(tlvKeyBuf, 0, sizeof(tlvKeyBuf));
if((ret = tlvInit(tlvKeyBuf, sizeof(tlvKeyBuf))) != NOT_ERROR)
{
LOGE("Failed to init Tlv buffer with error %d.", ret);
ret += ERR_TA_BASE;
goto cleanup;
}
if((ret = tlvAdd(tlvKeyBuf, sizeof(tlvKeyBuf),
TLV_WRAPPED_KEY, wbEncAesKey, wbEncAesKeyLen)) != NOT_ERROR)
{
LOGE("Failed to set Tlv buffer with error %d.", ret);
ret += ERR_TA_BASE;
goto cleanup;
}
if((ret = tlvAdd(tlvKeyBuf, sizeof(tlvKeyBuf), TLV_IV, iv, sizeof(iv))) != NOT_ERROR)
{
LOGE("Failed to set Tlv buffer with error %d.", ret);
ret += ERR_TA_BASE;
goto cleanup;
}
if((tlvKeyBufDataLen = tlvSize(tlvKeyBuf, sizeof(tlvKeyBuf))) > sizeof(wrappedKeyData) ||
tlvKeyBufDataLen < 0)
{
LOGE("Tlv buffer overflow. %d %zu", tlvKeyBufDataLen, sizeof(wrappedKeyData));
ret = ERR_TA_BUFFER_OVERFLOW;
goto cleanup;
}
switch(teeAppId)
{
case TA_SKM :
case TA_KEYMASTER :
// Encrypt CSR data with HSM pubkey.
if((ret = getCAPublicKey(&pHsmRootCaKey, RSA_ENC_KEY)) != NOT_ERROR)
{
LOGE("Failed to get CA pubkey with error %d.", ret);
goto cleanup;
}
if((ret = KEY_public_encrypt(pHsmRootCaKey, tlvKeyBufDataLen, tlvKeyBuf,
wrappedKeyData, RSA_PKCS1_PADDING)) != NOT_ERROR)
{
LOGE("RSA encryption failed with error %d.", ret);
goto cleanup;
}
break;
default :
LOGE("Not supported AppId : %d", teeAppId);
ret = ERR_TA_INVALID_ARGUMENT;
goto cleanup;
}
// Make ECSR blob.
memset(outData, 0, *outDataLen);
if((ret = tlvInit(outData, *outDataLen)) != NOT_ERROR)
{
LOGE("Failed to init Tlv buffer with error %d.", ret);
ret += ERR_TA_BASE;
goto cleanup;
}
if((ret = tlvAdd(outData, *outDataLen, TLV_ENCRYPTED_DATA_BLOB, pAesEncData, unwrappedDataLen)) != NOT_ERROR)
{
LOGE("Failed to set Tlv buffer with error %d.", ret);
ret += ERR_TA_BASE;
goto cleanup;
}
if((ret = tlvAdd(outData, *outDataLen, TLV_WRAPPED_KEY,
wrappedKeyData, sizeof(wrappedKeyData))) != NOT_ERROR)
{
LOGE("Failed to set Tlv buffer with error %d.", ret);
ret += ERR_TA_BASE;
goto cleanup;
}
if((ret = tlvAdd(outData, *outDataLen, TLV_AUTH_DATA, aad, sizeof(aad))) != NOT_ERROR)
{
LOGE("Failed to set Tlv buffer with error %d.", ret);
ret += ERR_TA_BASE;
goto cleanup;
}
if((ret = tlvAdd(outData, *outDataLen, TLV_AUTH_TAG, authTag, sizeof(authTag))) != NOT_ERROR)
{
LOGE("Failed to set Tlv buffer with error %d.", ret);
ret += ERR_TA_BASE;
goto cleanup;
}
if((ret = tlvSize(outData, *outDataLen)) > *outDataLen || ret < 0)
{
LOGE("Tlv buffer overflow. %d %zu", tlvKeyBufDataLen, sizeof(wrappedKeyData));
ret = ERR_TA_BUFFER_OVERFLOW;
goto cleanup;
}
// Update outDataLen to TlvBufferSize.
*outDataLen = ret;
ret = NOT_ERROR;
LOGD("ECSR has been successfully generated.");
cleanup :
#if (defined DEBUG_SELF_TEST)
if(pAesDecData)
{
memset(pAesDecData, 0, unwrappedDataLen);
secMemoryManagerFree(pAesDecData);
}
#endif // End of DEBUG_SELF_TEST
if(pAesEncData)
{
memset(pAesEncData, 0, unwrappedDataLen);
secMemoryManagerFree(pAesEncData);
}
if(pHsmRootCaKey)
KEY_free(pHsmRootCaKey);
if(pUnwrappedData)
{
memset(pUnwrappedData, 0, csrLen);
secMemoryManagerFree(pUnwrappedData);
}
// <- aesKey , iv are not cleared
return ret;
}
//CONFIDENTIAL/TRUSTEDAPPS/APPS/DeviceRootKey/MAIN/provTee/src/prov/cryptoPlatform.c
Remediation
Memory of aesKey and iv buffers with sensitive data in plaintext form should be cleared after use.Editor is loading...
Leave a Comment