optee km4.0 VTS: ClearOperationsTest.TooManyOperations failed
VTS测试fail:
Note: Google Test filter = PerInstance/ClearOperationsTest.TooManyOperations/0_default
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from PerInstance/ClearOperationsTest
[ RUN ] PerInstance/ClearOperationsTest.TooManyOperations/0_default
hardware/interfaces/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp:4592: Failure
Expected equality of these values:
ErrorCode::TOO_MANY_OPERATIONS
Which is: TOO_MANY_OPERATIONS
Begin(KeyPurpose::ENCRYPT, key_blob_, params, &out_params, &op_handle_)
Which is: OK
hardware/interfaces/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp:4595: Failure
Expected equality of these values:
ErrorCode::TOO_MANY_OPERATIONS
Which is: TOO_MANY_OPERATIONS
Begin(KeyPurpose::ENCRYPT, key_blob_, params, &out_params, &op_handle_)
Which is: OK
hardware/interfaces/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp:4597: Failure
Expected equality of these values:
ErrorCode::OK
Which is: OK
Abort(op_handles[i])
Which is: INVALID_OPERATION_HANDLE
[ FAILED ] PerInstance/ClearOperationsTest.TooManyOperations/0_default, where GetParam() = "default" (25163 ms)
[----------] 1 test from PerInstance/ClearOperationsTest (25163 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (25164 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] PerInstance/ClearOperationsTest.TooManyOperations/0_default, where GetParam() = "default"
1 FAILED TEST
测试代码:
/* * ClearSlotsTest.TooManyOperations * * Verifies that TOO_MANY_OPERATIONS is returned after the max number of * operations are started without being finished or aborted. Also verifies * that aborting the operations clears the operations. * */ TEST_P(ClearOperationsTest, TooManyOperations) { ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) .RsaEncryptionKey(2048, 65537) .Padding(PaddingMode::NONE))); auto params = AuthorizationSetBuilder().Padding(PaddingMode::NONE); int max_operations = SecLevel() == SecurityLevel::STRONGBOX ? 4 : 16; OperationHandle op_handles[max_operations]; AuthorizationSet out_params; ALOGD("max_operations = %d", max_operations); for(int i=0; i<max_operations; i++) { EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, key_blob_, params, &out_params, &(op_handles[i]))); } EXPECT_EQ(ErrorCode::TOO_MANY_OPERATIONS, Begin(KeyPurpose::ENCRYPT, key_blob_, params, &out_params, &op_handle_)); // Try again just in case there's a weird overflow bug EXPECT_EQ(ErrorCode::TOO_MANY_OPERATIONS, Begin(KeyPurpose::ENCRYPT, key_blob_, params, &out_params, &op_handle_)); for(int i=0; i<max_operations; i++) { EXPECT_EQ(ErrorCode::OK, Abort(op_handles[i])); } EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, key_blob_, params, &out_params, &op_handle_)); AbortIfNeeded(); }
TA中相关代码:
keymaster_error_t TA_try_start_operation( const keymaster_operation_handle_t op_handle, const keymaster_key_blob_t key, const uint32_t min_sec, TEE_OperationHandle *operation, const keymaster_purpose_t purpose, TEE_OperationHandle *digest_op, const bool do_auth, const keymaster_padding_t padding, const keymaster_block_mode_t mode, const uint32_t mac_length, const keymaster_digest_t digest, const keymaster_blob_t nonce, uint8_t *key_id) { TEE_Time cur_t; DMSG("KM_MAX_OPERATION = %d", KM_MAX_OPERATION); for (uint32_t i = 0; i < KM_MAX_OPERATION; i++) {//这个值和测试程序中定义有差异,首先修改该值 if (operations[i].op_handle == UNDEFINED) { TEE_GetSystemTime(&cur_t); /* freed when operation aborted (TA_abort_operation) */ operations[i].key = TEE_Malloc( sizeof(keymaster_key_blob_t), TEE_MALLOC_FILL_ZERO); if (!operations[i].key) { EMSG("Failed to allocate memory for operation key struct"); return KM_ERROR_MEMORY_ALLOCATION_FAILED; } operations[i].key->key_material_size = key.key_material_size; /* freed when operation aborted (TA_abort_operation) */ operations[i].key->key_material = TEE_Malloc( key.key_material_size, TEE_MALLOC_FILL_ZERO); if (!operations[i].key->key_material) { EMSG("Failed to allocate memory for operation key data"); TEE_Free(operations[i].key); return KM_ERROR_MEMORY_ALLOCATION_FAILED; } TEE_MemMove(operations[i].key->key_material, key.key_material, key.key_material_size); operations[i].last_access = &cur_t; operations[i].min_sec = min_sec; operations[i].operation = operation; operations[i].purpose = purpose; operations[i].do_auth = do_auth; operations[i].digest_op = digest_op; operations[i].mac_length = mac_length; operations[i].padding = padding; operations[i].mode = mode; operations[i].digestLength = get_digest_size(&digest) / 8; /*in bytes*/ operations[i].nonce.data = TEE_Malloc( nonce.data_length, TEE_MALLOC_FILL_ZERO); if (!operations[i].nonce.data) { EMSG("Failed to allocate memory for nonce"); TEE_Free(operations[i].key->key_material); TEE_Free(operations[i].key); return KM_ERROR_MEMORY_ALLOCATION_FAILED; } TEE_MemMove(operations[i].nonce.data, nonce.data, nonce.data_length); operations[i].nonce.data_length = nonce.data_length; operations[i].op_handle = op_handle; memcpy(operations[i].key_id, key_id, sizeof(operations[i].key_id)); return KM_ERROR_OK; } } DMSG("return KM_ERROR_TOO_MANY_OPERATIONS"); return KM_ERROR_TOO_MANY_OPERATIONS; }
还有一个点:
keymaster_error_t TA_start_operation( const keymaster_operation_handle_t op_handle, const keymaster_key_blob_t key, uint32_t min_sec, TEE_OperationHandle *operation, const keymaster_purpose_t purpose, TEE_OperationHandle *digest_op, const bool do_auth, const keymaster_padding_t padding, const keymaster_block_mode_t mode, const uint32_t mac_length, const keymaster_digest_t digest, const keymaster_blob_t nonce, uint8_t *key_id) { keymaster_error_t res = TA_try_start_operation(op_handle, key, min_sec, operation, purpose, digest_op, do_auth, padding, mode, mac_length, digest, nonce, key_id); DMSG("TA_try_start_operation res = %d", res); if (res != KM_ERROR_OK) {//这里增加了重试机制,所以反而会导致超出max operation时不会报错 res = TA_kill_old_operation(); if (res == KM_ERROR_OK) { res = TA_try_start_operation(op_handle, key, min_sec, operation, purpose, digest_op, do_auth, padding, mode, mac_length, digest, nonce, key_id); } } return res; }
本地修复方法:
在重试机制处,增加判定条件,只有返回值不为KM_ERROR_TOO_MANY_OPERATIONS时,才会重试。
复测:
Note: Google Test filter = PerInstance/ClearOperationsTest.TooManyOperations/0_default
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from PerInstance/ClearOperationsTest
[ RUN ] PerInstance/ClearOperationsTest.TooManyOperations/0_default
[ OK ] PerInstance/ClearOperationsTest.TooManyOperations/0_default (23289 ms)
[----------] 1 test from PerInstance/ClearOperationsTest (23289 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (23291 ms total)
[ PASSED ] 1 test.