Untitled

mail@pastecode.io avatar
unknown
plain_text
4 months ago
7.2 kB
3
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.
Leave a Comment