- HWPSIRT-2021-67370 Stack Buffer Overflow in UnwrapKeyHandle
Stack Buffer Overflow in UnwrapKeyHandle
¶
The function UnwrapKeyHandle
parses TLV objects stored in pKeyHandlesIn
. After the parsing of the expected objects is finished, if there are remaining objects, they are stored into the pTags
variable of type ak_tlvs_t
.
cal_handle_t UnwrapKeyHandle(
createKeyHandleArgs_t *pArgs,
cal_blob_t *pTransactionContent,
cal_blob_t *pKeyHandlesIn,
ak_byte_t nKeyHandlesInNum,
ak_byte_t *usernamesin,
cal_blob_t *usernamesOut,
cal_blob_t **pKeyHandlesOut,
ak_byte_t *nKeyHandlesOutNum,
ak_tlvs_t *pTags)
{
// ...
InBLOB = pKeyHandlesIn[i];
OutBLOB.pData = 0;
OutBLOB.length = 0;
UnwrapData(&InBLOB, &OutBLOB, 0, 1);
pTemp = OutBLOB.pData;
remainingLen = OutBLOB.length;
// ...some parsing...
pTags->numTags = 0;
while (remainingLen >= 4) {
tag = &pTags->tlvs[pTags->numTags];
pTemp = AK_GetWord(tag->tag, pTemp, &remainingLen);
pTemp = AK_GetWord(tag->length, pTemp, &remainingLen);
if (!tag->tag) { /* ... */ }
if (remainingLen < tag->length) { /* ... */ }
tag->value = nnl_malloc(tag->length);
if (!tag->value) { /* ... */ }
pTemp = AK_GetBytes(tag->value, tag->length, pTemp, &remainingLen);
++pTags->numTags;
}
// ...
}
The ak_tlvs_t
structure can contain a fixed number (10) of extra objects. However, the function will continue storing objects even if there are more than 10, resulting in a buffer overflow of the pTags->tlvs
array.
struct ak_tlvs_t
{
ak_word_t numTags;
ak_tlv_t tlvs[10];
};
struct ak_tlv_t
{
ak_word_t tag;
ak_word_t length;
ak_byte_t *value;
};
The UnwrapKeyHandle
function is called from the Sign
function where the ak_tlvs_t
structure is declared on the stack.
ak_result_t Sign(
ak_internal_info_t *pAKInfo,
input_args_t *pInputArgs,
ak_byte_t *pResponse,
ak_word_t *pResponseLength)
{
// ...
ak_tlvs_t pKHTags;
// ...
hUauthKey = UnwrapKeyHandle(
&createKHArgs,
&pInputArgs->transactionContent,
pInputArgs->keyHandles,
pInputArgs->keyHandlesNum,
usernames,
signRespArgs.usernames,
signRespArgs.pKeyHandles,
&signRespArgs.keyHandleNum,
&pKHTags);
// ...
}
The pKeyHandlesIn
parameter of UnwrapKeyHandle
is fully user-controlled and comes from the ExtractInputArgs
function. This function will process TLV objects in the first TEE_Param
input buffer. The only limitation is that the key handle is smaller than or equal to 0x200 bytes.
int ta_cmd_handler(
uint32_t *ibuf0_addr,
uint32_t ibuf0_size,
uint32_t *obuf3_addr,
uint32_t obuf3_size)
{
// ...
UAF_AK_Process(ibuf0_addr, request_length, khaccesstoken, obuf3_addr, &obuf3_size);
// ...
}
ak_result_t UAF_AK_Process(
int pRequest,
int requestLength,
int a3,
ak_byte_t *pResponse,
ak_word_t *pResponseLength)
{
// ...
ExtractInputArgs(pRequest, requestLength, &inputArgs);
switch (inputArgs.operationType) {
case 0x3403:
// ...
Info = Sign(&gAKInfo, &inputArgs, pResponse, pResponseLength);
break;
}
// ...
}
ak_result_t ExtractInputArgs(const ak_byte_t *pRequest, ak_word_t requestLength, input_args_t *pInputArgs) {
// ...
ptr = pRequest;
remainder = requestLength;
// ...some parsing...
while (remainder > 0) {
// ...
ptr = AK_GetTlv(&tlv, ptr, &remainder);
// ...
if (tlv.tag == 0x2801) {
if (tlv.length > 0x200) { /* ... */ }
if (pInputArgs->keyHandlesNum > 0xF) { /* ... */ }
keyHandlesNum = pInputArgs->keyHandlesNum;
pInputArgs->keyHandles[keyHandlesNum].length = tlv.length;
pInputArgs->keyHandles[keyHandlesNum].pData = tlv.value;
pInputArgs->keyHandlesNum = keyHandlesNum + 1;
}
// ...
}
// ...
}
Because the stack frame of Sign
is too large compared to the size we can overflow, we did not find a way to exploit this vulnerability. As such, we did not attempt to trigger it.
Affected Devices¶
We have verified that the vulnerability impacted the following device(s):
- Kirin 990: P40 Pro (ELS)
Please note that other models might have been affected.
Patch¶
Name | Severity | CVE | Patch |
---|---|---|---|
Stack Buffer Overflow in UnwrapKeyHandle |
Low | N/A | Fixed |
Timeline¶
- Dec. 14, 2021 - A vulnerability report is sent to Huawei PSIRT.
- Jan. 12, 2022 - Huawei PSIRT acknowledges the vulnerability report.
- From Nov. 30, 2022 to Jul, 19 2023 - We exchange regularly about the release of our advisories.
Copyright © Impalabs 2021-2023