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.

posted @ 2023-01-12 15:06  xiululu  阅读(68)  评论(0编辑  收藏  举报