The test PerInstance/SigningOperationsTest.RsaGetKeyCharacteristicsRequiresCorrectAppIdAppData/0_default is failing with multiple assertion errors. The test expects specific behavior when retrieving key characteristics with incorrect application IDs and application data, but the actual implementation returns unexpected results.
Key failures include:
- The function returns
OKinstead of the expectedINVALID_KEY_BLOBerror - The key characteristics contain 11 hardware-enforced and 1 software-enforced parameters when empty parameters are expected
Test Code Implementation
The test verifies that GetCharacteristics properly validates client identity and application data. The implementation checks four scenarios:
- Call with valid parameters (should succeed)
- Call with empty client ID (should fail with INVALID_KEY_BLOB)
- Call with empty application data (should fail with INVALID_KEY_BLOB)
- Call with both empty client ID and application data (should fail with INVALID_KEY_BLOB)
Serialization-Deserialization Mismatch
Investigation reveals a mismatch between the client-side serialization and Trusted Application (TA) deserialization processes:
Client-Side Serialization
The client first serializes a keymaster_key_blob_t structure, followed by an AuthorizationSet:
uint8_t* GetKeyCharacteristicsRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
buf = serialize_key_blob(key_blob, buf, end);
return additional_params.Serialize(buf, end);
}
TA-Side Deserialization
The TA deserializes the request in a different order, first extracting the key blob, then client ID, and finally application data:
in += TA_deserialize_key_blob_akms(in, in_end, &key_blob, &res);
if (res != KM_ERROR_OK)
goto exit;
in += TA_deserialize_blob_akms(in, in_end, &client_id, false, &res, false);
if (res != KM_ERROR_OK)
goto exit;
in += TA_deserialize_blob_akms(in, in_end, &app_data, false, &res, false);
if (res != KM_ERROR_OK)
goto exit;
Permission Check Logic Issue
After fixing the serialization-deserialization mismatch, another issue was found in the permission checking logic. The TEE_MemCompare function returns:
- 0 if buffers are identical
- A positive value if the first differing byte is higher in buffer1
- A negative value if the first differing byte is higher in buffer2
The original implementation incorrectly handled the comparison result:
client_id_same = TEE_MemCompare(client_id.data,
params->params[i].key_param.blob.data,
client_id.data_length);
The client_id_same variable was declared as a boolean but was assigned the integer result of TEE_MemCompare, leading to incorrect logic flow.
Corrected Implementation
The fix properly converts the comparison result to a boolean value and adjusts the condition checks:
client_id_same = (TEE_MemCompare(client_id.data,
params->params[i].key_param.blob.data,
client_id.data_length) == 0);
app_data_same = (TEE_MemCompare(app_data.data,
params->params[i].key_param.blob.data,
app_data.data_length) == 0);
if ((app_data_checked && !app_data_same) ||
(client_id_checked && !client_id_same)) {
EMSG("Invalid client id or app data!");
return KM_ERROR_INVALID_KEY_BLOB;
}
Test Results
After implementing both fixes, the test now passes successfully, confirming that the key characteristics verification properly handles invalid application IDs and application data.