Untitled

 avatar
unknown
plain_text
a year ago
7.2 kB
11
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