optee km4.0 VTS:PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default

异常日志1:GenerateKey时返回UNSUPPORTED_ALGORITHM

# ./VtsHalKeymasterV4_0TargetTest --gtest_filter=PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default
Note: Google Test filter = PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from PerInstance/EncryptionOperationsTest
[ RUN ] PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default
hardware/interfaces/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp:3719: Failure
Expected equality of these values:
ErrorCode::OK
Which is: OK
GenerateKey(auths)
Which is: UNSUPPORTED_ALGORITHM
[ FAILED ] PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default, where GetParam() = "default" (268 ms)
[----------] 1 test from PerInstance/EncryptionOperationsTest (268 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (269 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default, where GetParam() = "default"

1 FAILED TEST

对应VTS测试代码:

/*
 * EncryptionOperationsTest.TripleDesEcbRoundTripSuccess
 *
 * Verifies that 3DES is basically functional.
 */
TEST_P(EncryptionOperationsTest, TripleDesEcbRoundTripSuccess) {
    auto auths = AuthorizationSetBuilder()
                     .TripleDesEncryptionKey(168)
                     .BlockMode(BlockMode::ECB)
                     .Authorization(TAG_NO_AUTH_REQUIRED)
                     .Padding(PaddingMode::NONE);

    ASSERT_EQ(ErrorCode::OK, GenerateKey(auths));
    // Two-block message.
    string message = "1234567890123456";
    auto inParams = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::NONE);
    string ciphertext1 = EncryptMessage(message, inParams);
    EXPECT_EQ(message.size(), ciphertext1.size());

    string ciphertext2 = EncryptMessage(string(message), inParams);
    EXPECT_EQ(message.size(), ciphertext2.size());

    // ECB is deterministic.
    EXPECT_EQ(ciphertext1, ciphertext2);

    string plaintext = DecryptMessage(ciphertext1, inParams);
    EXPECT_EQ(message, plaintext);
}

异常1分析:

optee keymaster3 中TA_generate_key未针对KM_ALGORITHM_TRIPLE_DES算法做实现,所以在第一个switch-case分支这里就报错了,optee-km3源码如下:

keymaster_error_t TA_generate_key(const keymaster_algorithm_t algorithm,
                    const uint32_t key_size,
                    uint8_t *key_material,
                    const keymaster_digest_t digest,
                    const uint64_t rsa_public_exponent)
{
    TEE_ObjectHandle obj_h = TEE_HANDLE_NULL;
    TEE_Result res = TEE_SUCCESS;
    uint32_t padding = 0;
    uint32_t *attributes = NULL;
    uint32_t attr_count = 0;
    uint32_t attr_size = 0;
    uint32_t type = 0;
    uint32_t a = 0;
    uint32_t b = 0;
    uint32_t curve = UNDEFINED;
    uint8_t buffer[KM_MAX_ATTR_SIZE] = { 0 };
    uint8_t *buf_pe = NULL;
    uint64_t be_pe = 0;
    TEE_Attribute *attrs_in = NULL;
    uint32_t attrs_in_count = 0;

    switch (algorithm) {
    case KM_ALGORITHM_AES:
        attributes = attributes_aes_hmac;
        attr_count = KM_ATTR_COUNT_AES_HMAC;
        type = TEE_TYPE_AES;
        break;
    case KM_ALGORITHM_HMAC:
        attributes = attributes_aes_hmac;
        attr_count = KM_ATTR_COUNT_AES_HMAC;
        ......break;
    case KM_ALGORITHM_RSA:
        attributes = attributes_rsa;
        attr_count = KM_ATTR_COUNT_RSA;
        type = TEE_TYPE_RSA_KEYPAIR;
        attrs_in = TEE_Malloc(sizeof(TEE_Attribute),
                            TEE_MALLOC_FILL_ZERO);
        ......break;
    case KM_ALGORITHM_EC:
        attributes = attributes_ec;
        attr_count = KM_ATTR_COUNT_EC;
        type = TEE_TYPE_ECDSA_KEYPAIR;
        attrs_in = TEE_Malloc(sizeof(TEE_Attribute),
                            TEE_MALLOC_FILL_ZERO);
        ......break;
    default:
        return KM_ERROR_UNSUPPORTED_ALGORITHM;
    }
    res = TEE_AllocateTransientObject(type, key_size, &obj_h);
    if (res != TEE_SUCCESS) {
        EMSG("Failed to allocate transient object, res=%x", res);
        goto gk_out;
    }
    .............
gk_out:
    if (obj_h != TEE_HANDLE_NULL)
        TEE_FreeTransientObject(obj_h);
    free_attrs(attrs_in, attrs_in_count);

    return res;
}

代码中只处理了如下4中算法:

case KM_ALGORITHM_AES:
case KM_ALGORITHM_HMAC:
case KM_ALGORITHM_RSA:
case KM_ALGORITHM_EC:

KM_ALGORITHM_TRIPLE_DES = 33被归为缺省处理了。所以TA直接返回了不支持,VTS测试报错。

OPTEE CORE API文档中,TEE_GenerateKey:

这个接口涉及4个入参,针对TEE_TYPE_DES3算法,官方的说法是No parameter is necessary,所以只需要保证前面两个参数正常即可。

对比文档,并参考其他算法的实现方式,最终的改动是在TA_generate_key中增加了如下case:

    case KM_ALGORITHM_TRIPLE_DES:
        attributes = attributes_aes_hmac;
        attr_count = KM_ATTR_COUNT_AES_HMAC;
        type = TEE_TYPE_DES3;
        break;

这段处理增加之后,异常1不复存在。也就是说GenerateKey过了。但其实结果并没有验证,从接下来的测试可见一斑。

VTS测试下来,出现了异常2.

异常2:Begin操作返回INCOMPATIBLE_DIGEST

# ./VtsHalKeymasterV4_0TargetTest --gtest_filter=PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default
Note: Google Test filter = PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from PerInstance/EncryptionOperationsTest
[ RUN ] PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:462: Failure
Expected equality of these values:
ErrorCode::OK
Which is: OK
Begin(operation, key_blob, in_params, &begin_out_params, &op_handle_)
Which is: INCOMPATIBLE_DIGEST
Google Test trace:
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:456: ProcessMessage
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:605: EncryptMessage
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:611: EncryptMessage
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:616: EncryptMessage
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:470: Failure
Expected equality of these values:
ErrorCode::OK
Which is: OK
Update(op_handle_, update_params, message, &update_out_params, &output, &consumed)
Which is: INVALID_OPERATION_HANDLE
......
[ FAILED ] PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default, where GetParam() = "default" (4607 ms)
[----------] 1 test from PerInstance/EncryptionOperationsTest (4607 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (4609 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default, where GetParam() = "default"

1 FAILED TEST

KeymasterHidlTest.cpp:462对应的测试代码为:EXPECT_EQ(ErrorCode::OK, Begin(operation, key_blob, in_params, &begin_out_params, &op_handle_));

这意味着前面生成出来的key,在begin操作中异常了。

TA中输出的关键异常log:

D/TA: TA_restore_key:799 after decrypt key_material size = 296
D/TA: dumpData:121 [000] 0b 00 00 00 00 00 00 00 02 00 00 10 00 00 00 00
D/TA: TA_restore_key:802 -->TA_populate_key_attrs
D/TA: TA_populate_key_attrs:599 padding = 4 type = 0xb
D/TA: TA_populate_key_attrs:623 HMAC attrs_count = 1 algorithm = 128

key的前面4个字节对应的是算法类型,应该为TEE_TYPE_DES3    0xA0000013,实际restore出来为0b 00 00 00。

回头找key生成过程中的异常,通过添加log,发现TA_generate_key生成的key_material是正常的(至少前面4个字节正常)。

但在TA_generateKey==>TA_generate_key之后,调用TA_serialize_param_set(key_material + key_buffer_size, &params_t);这句的时候,key_materail就发生了变化。

原因:

key_buffer_size = TA_get_key_size(key_algorithm);中没有对KM_ALGORITHM_TRIPLE_DES处理,导致算出来的buffer size不对,直接返回了0,key_material前面的key被覆盖了。

修改点:

uint32_t TA_get_key_size(const keymaster_algorithm_t algorithm)
{
    switch (algorithm) {
    case KM_ALGORITHM_TRIPLE_DES:
        /* attr_count * (size of tag + size of attribute +
         * attribute data size) + size of algorithm + size of key size
         */
        return KM_ATTR_COUNT_AES_HMAC *
            (2 * sizeof(uint32_t) + KM_DES3_ATTR_SIZE)
            + sizeof(algorithm) + sizeof(uint32_t);
        break;
............
    default:
        return 0;
    }
}

异常3:TA_populate_key_attrs未支持TEE_TYPE_DES3

0374 D/TA: TA_restore_key:810 -->TA_populate_key_attrs
0375 D/TA: TA_populate_key_attrs:607 padding = 4 type = 0xa0000013
0383 D/TA: TA_check_hmac_key:549 type = a0000013
0384 D/TA: TA_check_hmac_key:582 default value: 0xa0000013, return -13
0385 E/TA: TA_restore_key:821 HMAC key checking failed res = -13
0386 E/TA: TA_restore_key:849 populate attrs is finished with err -13
0387 D/TA: TA_begin:1327 -->TA_serialize_rsp_err res = fffffff3

TA_populate_key_attrs中输入type打印正常,是DES3算法,但解析出去却变成了HMAC。

这里也缺少了针对DES3的处理。

解决方法:

keymaster_error_t TA_populate_key_attrs(uint8_t *key_material,
                    tee_key_attributes *att)
{
    uint32_t padding = 0;
    uint32_t tag;
    int res = KM_ERROR_UNKNOWN_ERROR;

    TEE_MemMove(&att->type, key_material, sizeof(att->type));
    padding += sizeof(att->type);

    DMSG("padding = %u *type = 0x%x", padding, att->type);
    switch (att->type) {
    case TEE_TYPE_DES3:
        att->attrs_count = KM_ATTR_COUNT_AES_HMAC;
        att->alg = KM_ALGORITHM_TRIPLE_DES;
        break;
    ......default: /* HMAC */
        att->attrs_count = KM_ATTR_COUNT_AES_HMAC;
        att->alg = KM_ALGORITHM_HMAC;
        DMSG("HMAC attrs_count = %u algorithm = %d",
             att->attrs_count, att->alg);
    }
    ......return KM_ERROR_OK;

out_err:
    free_attrs(att->attrs, att->attrs_count);
    TEE_MemFill((void*)att, 0, sizeof(*att));
    return res;
}

继续测试。

异常:TA_create_operation未支持KM_ALGORITHM_TRIPLE_DES

394 D/TA: TA_begin:1261 -->TA_check_params
420 D/TA: TA_begin:1298 -->TA_create_operation, algorithm = 33
421 D/TA: TA_begin:1299 -->TA_create_operation, digest = -1
422 D/TA: TA_begin:1300 -->TA_create_operation, mode = 1
423 D/TA: TA_begin:1301 -->TA_create_operation, padding = 1
424 D/TA: TA_begin:1302 -->TA_create_operation, purpose = 0
425 D/TA: TA_begin:1303 -->TA_create_operation, mac_length = -1
426 E/TA: TA_create_operation:1060 Unsupported algorithm
427 D/TA: TA_begin:1327 -->TA_serialize_rsp_err res = fffffffc

看来是TA_create_operation中没有针对DES3算法的处理。

修改点:

@@ -834,7 +884,21 @@ keymaster_error_t TA_create_operation(TEE_OperationHandle *operation,
 
        *operation = TEE_HANDLE_NULL;
 
+       DMSG("algorithm = %d, op_mode = %d, padding = %d, digest = %d", algorithm, op_mode, padding, digest);
        switch (algorithm) {
+       case KM_ALGORITHM_TRIPLE_DES:
+               switch (op_mode) {
+               case KM_MODE_ECB:
+                       algo = TEE_ALG_DES3_ECB_NOPAD;
+                       break;
+               case KM_MODE_CBC:
+                       algo = TEE_ALG_DES3_CBC_NOPAD;
+                       break;
+               default:
+                       algo = TEE_ALG_DES3_CMAC;
+                       break;
+               }
+               break;
        case (KM_ALGORITHM_AES):
                switch (op_mode) {
                case KM_MODE_ECB:
@@ -1025,6 +1089,12 @@ keymaster_error_t TA_create_operation(TEE_OperationHandle *operation,
        }
        DMSG("algorithm = %d op_mode = %d", algorithm, op_mode);
        switch (algorithm) {
+       case KM_ALGORITHM_TRIPLE_DES:
+               DMSG("-->TEE_CipherInit");
+               TEE_CipherInit(*operation,
+                               nonce.data,
+                               nonce.data_length);
+               break;
        case (KM_ALGORITHM_AES):
                if (op_mode == KM_MODE_GCM) {
                        DMSG("-->TEE_AEInit");

更新版本。继续解决。

新的异常:Update和Finish操作未支持DES3算法

# ./VtsHalKeymasterV4_0TargetTest --gtest_filter=PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default
Note: Google Test filter = PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from PerInstance/EncryptionOperationsTest
[ RUN ] PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:477: Failure
Expected equality of these values:
ErrorCode::OK
Which is: OK
Finish(op_handle_, finish_params, message.substr(consumed), unused, &finish_out_params, &output)
Which is: INVALID_OPERATION_HANDLE
Google Test trace:
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:456: ProcessMessage
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:605: EncryptMessage
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:611: EncryptMessage
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:616: EncryptMessage
hardware/interfaces/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp:3724: Failure
Expected equality of these values:
message.size()
Which is: 16
ciphertext1.size()
Which is: 0
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:477: Failure
Expected equality of these values:
ErrorCode::OK
Which is: OK
Finish(op_handle_, finish_params, message.substr(consumed), unused, &finish_out_params, &output)
Which is: INVALID_OPERATION_HANDLE
Google Test trace:
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:456: ProcessMessage
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:605: EncryptMessage
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:611: EncryptMessage
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:616: EncryptMessage
hardware/interfaces/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp:3727: Failure
Expected equality of these values:
message.size()
Which is: 16
ciphertext2.size()
Which is: 0
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:477: Failure
Expected equality of these values:
ErrorCode::OK
Which is: OK
Finish(op_handle_, finish_params, message.substr(consumed), unused, &finish_out_params, &output)
Which is: INVALID_OPERATION_HANDLE
Google Test trace:
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:456: ProcessMessage
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:674: DecryptMessage
hardware/interfaces/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp:683: DecryptMessage
hardware/interfaces/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp:3733: Failure
Expected equality of these values:
message
Which is: "1234567890123456"
plaintext
Which is: ""
[ FAILED ] PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default, where GetParam() = "default" (13538 ms)
[----------] 1 test from PerInstance/EncryptionOperationsTest (13538 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (13538 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default, where GetParam() = "default"

1 FAILED TEST

对应VTS代码:

    EXPECT_EQ(ErrorCode::OK, Finish(op_handle_, finish_params, message.substr(consumed), unused,
                                    &finish_out_params, &output));

走到Finish操作啦。

查看TA log,在Update操作时就已经出现panic了:

0581 F/TC:? 0 trace_syscall:154 syscall #2 (syscall_panic)
0583 E/TC:? 0 TA panicked with code 0x0
0605 D/TC:? 0 user_ta_enter:177 tee_user_ta_enter: TA panicked with code 0x0
0971 E/TA: TA_finish:1526 TA_get_operation failed, res = 0xffffffe4

新增DES3_Update相关接口TA_des3_update:

这个是仿照已有的AES update接口来写的,比较粗糙,VTS能跑过:

keymaster_error_t TA_des3_update(keymaster_operation_t *operation,
				keymaster_blob_t *input,
				keymaster_blob_t *output,
				uint32_t *out_size,
				const uint32_t input_provided,
				size_t *input_consumed,
				const keymaster_key_param_set_t *in_params,
				bool *is_input_ext)
{
	keymaster_error_t res = KM_ERROR_OK;
	uint32_t pos = 0U;
	uint32_t out_pos = 0U;
	uint32_t remainder = 0;
	uint32_t in_size = DES3_BLOCK_SIZE;

	/* KM_MODE_CBC, KM_MODE_ECB */
	DMSG("mode = %d, in_size = %u", operation->mode, in_size);
	if (!TA_is_stream_cipher(operation->mode)) {
		DMSG("block mode");
		if (operation->last_block.data != NULL && operation->last_block.data_length != 0) {
			DMSG("Restore last block");
			res = TA_restore_last_block(output, input_consumed, operation, &out_pos, DES3_BLOCK_SIZE);
			if (res != KM_ERROR_OK) {
				EMSG("Failed to restore last block");
				goto out;
			}
			operation->first = false;
		}
		if (operation->padding == KM_PAD_PKCS7) {
			if (operation->prev_in_size == input->data_length) {
				operation->buffering = false;
			} else {
				operation->buffering = true;
			}
			if (operation->prev_in_size == UNDEFINED
					&& input->data_length == DES3_BLOCK_SIZE) {
				operation->prev_in_size = input->data_length;
			}
			operation->prev_in_size = input->data_length;
		}
	}

	/* only KM_MODE_CBC and KM_MODE_ECB */
	remainder = input->data_length - pos;

	if ((operation->mode == KM_MODE_CBC && operation->padding == KM_PAD_NONE)
		|| (operation->mode == KM_MODE_CBC && operation->padding == KM_PAD_PKCS7)
		|| (operation->mode == KM_MODE_ECB && operation->padding == KM_PAD_NONE)
		|| (operation->mode == KM_MODE_ECB && operation->padding == KM_PAD_PKCS7)) {
		/* CTR is a stream mode */
		in_size = input->data_length;
	}

	while (remainder / DES3_BLOCK_SIZE != 0
			|| (operation->padding == KM_PAD_NONE && operation->mode == KM_MODE_CBC)
			|| (operation->padding == KM_PAD_PKCS7 && operation->mode == KM_MODE_CBC)
			|| (operation->padding == KM_PAD_NONE && operation->mode == KM_MODE_ECB)
			|| (operation->padding == KM_PAD_PKCS7 && operation->mode == KM_MODE_ECB)) {
		/* calculate memory left.
		 * Add BLOCK_SIZE in case adding padding
		 */
		*out_size = DES3_BLOCK_SIZE + input->data_length -
						output->data_length;
		res = TEE_CipherUpdate(*operation->operation,
				input->data + pos, in_size,
				output->data + out_pos, out_size);
		DMSG("TEE_CipherUpdate res = 0x%x", res);
		if (res != TEE_SUCCESS) {
			EMSG("Error TEE_CipherUpdate, res=%x", res);
			goto out;
		}
		output->data_length += *out_size;
		pos += in_size;
		*input_consumed += in_size;
		operation->prev_in_size -= in_size;
		remainder -= in_size;
		if (remainder < DES3_BLOCK_SIZE)
			break;
	}

	if (*input_consumed > input_provided)
		*input_consumed = input_provided;

	if (res == KM_ERROR_OK && operation->padding == KM_PAD_PKCS7 &&
			operation->purpose == KM_PURPOSE_DECRYPT
			&& *input_consumed == input_provided) {
		size_t buffer_size = TEE_GetOperationBufferOffs(*operation->operation);//(*(operation->operation))->buffer_offs;
		if (operation->buffering && output->data_length > 0
				&& output->data_length % DES3_BLOCK_SIZE == 0/*TA_check_pkcs7_pad(output)*/
				&& operation->first/* && input->data_length < BLOCK_SIZE*/ && buffer_size == 0) {
			DMSG("Store last block");
			res = TA_store_last_block(output, input_consumed,
								operation, DES3_BLOCK_SIZE);
			if (res != KM_ERROR_OK) {
				EMSG("Failed to store last block");
				goto out;
			}
			operation->first = true;
		} else if (operation->buffering && output->data_length == DES3_BLOCK_SIZE && !operation->first) {
			operation->first = true;
		}
	}
out:
	return res;
}

新增DES3 Finish接口TA_des3_finish:

参考AES Finish接口实现:

keymaster_error_t TA_des3_finish(keymaster_operation_t *operation,
 				keymaster_blob_t *input,
 				keymaster_blob_t *output, uint32_t *out_size,
				uint32_t tag_len, bool *is_input_ext,
				const keymaster_key_param_set_t *in_params)
{
	TEE_Result tee_res = TEE_SUCCESS;
	keymaster_error_t res = KM_ERROR_OK;
	uint8_t *tag = NULL;
	uint32_t out_pos = 0U;
	uint32_t pad;

	if (operation->padding == KM_PAD_PKCS7 &&
			operation->purpose == KM_PURPOSE_ENCRYPT) {
		DMSG("encrypt-pkcs7 padding");
		size_t buffer_size = TEE_GetOperationBufferOffs(*operation->operation);
		if (buffer_size > 0) {
			pad = DES3_BLOCK_SIZE - ((input->data_length + buffer_size) % DES3_BLOCK_SIZE);
		}
		res = TA_add_pkcs7_pad2(input, !operation->padded, output,
							out_size, is_input_ext, pad, DES3_BLOCK_SIZE);
		if (res != KM_ERROR_OK)
			goto out;
		operation->padded = true;
	} else if (operation->padding == KM_PAD_NONE && (operation->mode ==
			KM_MODE_CBC || operation->mode == KM_MODE_ECB) &&
			input->data_length % DES3_BLOCK_SIZE != 0) {
		EMSG("Input data size for CBC and ECB modes without padding must be a multiple of block size");
		res = KM_ERROR_INVALID_INPUT_LENGTH;
		goto out;
	} else if (operation->padding == KM_PAD_PKCS7 &&
			operation->purpose == KM_PURPOSE_DECRYPT &&
			input->data_length % DES3_BLOCK_SIZE != 0) {
		EMSG("Input data size for AES PKCS7 must be a multiple of block size");
		res = KM_ERROR_INVALID_INPUT_LENGTH;
		goto out;
	}
	res = TEE_CipherDoFinal(*operation->operation, input->data,
				input->data_length, output->data,
				out_size);
	output->data_length = *out_size;
	DMSG("TEE_CipherDoFinal res = 0x%x, out_size = %u", res, *out_size);
	if (res == KM_ERROR_OK && operation->padding == KM_PAD_PKCS7
			&& operation->purpose == KM_PURPOSE_DECRYPT) {
		if (operation->last_block.data != NULL && operation->last_block.data_length != 0) {
			size_t input_consumed;
			uint32_t pos = 0U;
			res = TA_restore_last_block(output, &input_consumed, operation, &pos, DES3_BLOCK_SIZE);
			if (res != KM_ERROR_OK) {
				EMSG("[%s] Failed to restore last block", __FILE__);
				goto out;
			}
		}
		if (output->data_length > 0) {
			res = TA_remove_pkcs7_pad(output, out_size, DES3_BLOCK_SIZE);
			if (res == KM_ERROR_OK)
				operation->padded = true;
		}
	}
out:
	if (tag)
		TEE_Free(tag);

	if (res == TEE_ERROR_BAD_PARAMETERS) {
		EMSG("GET TEE_ERROR_BAD_PARAMETERS");
		if (operation->padding == KM_PAD_NONE) {
			res = KM_ERROR_INVALID_INPUT_LENGTH;
		}
	}

	return res;
}

扩展的加padding接口:

optee keymaster3.0 中加padding的接口是有问题的,所以增加了一个接口来修订这个问题:

keymaster_error_t TA_add_pkcs7_pad2(keymaster_blob_t *input,
				const bool force, keymaster_blob_t *output,
				uint32_t *out_size, bool *is_input_ext, uint32_t pad, uint32_t block_size)
{
	uint8_t *data = NULL;

	if (input == NULL) {
		EMSG("Input is NULL");
		return KM_ERROR_UNEXPECTED_NULL_POINTER;
	}
	if (input->data_length == 0 && !force)
		return KM_ERROR_OK;
//	pad = BLOCK_SIZE - (input->data_length % BLOCK_SIZE);
	DMSG("pad = %u, block_size = %u, input->data_length = %zu", pad, block_size, input->data_length);
	pad = pad != 0 ? pad : block_size - (input->data_length % block_size);//其中block_size作为入参传入,AES对应的BLOCK_SIZE和DES3算法的block size两者是有差异的,所以不能直接通过AES的BLOCK_SIZE来计算
	DMSG("PKCS7 ADD pad = 0x%x", pad);
	/* if input data size is a multiple of block size add
	 * one extra block as padding
	 */
	if (pad == 0)
		pad = block_size;
	/* Freed before input blob is destroyed by caller */
	data = TEE_Malloc(pad + input->data_length, TEE_MALLOC_FILL_ZERO);
	if (!data) {
		EMSG("Failed to allocate memory for buffer on padding adding");
		return KM_ERROR_MEMORY_ALLOCATION_FAILED;
	}
	TEE_MemMove(data, input->data, input->data_length);
	TEE_MemFill(data + input->data_length, pad, pad);
	if (*is_input_ext)
		TEE_Free(input->data);
	input->data = data;
	input->data_length = input->data_length + pad;
	*is_input_ext = true;
	return TA_check_out_size(input->data_length, output, out_size, 0, block_size);
}

//其中block size差异如下:

#define BLOCK_SIZE 16U //AES算法的
#define DES3_BLOCK_SIZE 8U

VTS测试结果:

# ./VtsHalKeymasterV4_0TargetTest --gtest_filter=PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default
Note: Google Test filter = PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from PerInstance/EncryptionOperationsTest
[ RUN      ] PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default
[       OK ] PerInstance/EncryptionOperationsTest.TripleDesEcbRoundTripSuccess/0_default (4651 ms)
[----------] 1 test from PerInstance/EncryptionOperationsTest (4651 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (4651 ms total)
[  PASSED  ] 1 test.

其他一些小修改:

TEE_TYPE_DES3相关汇总:

部分已有接口中也会有相对DES3算法的一些小小改动:

---- TEE_TYPE_DES3 Matches (12 in 4 files) ----
TA_import_key in generator.c (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta) : 		type = TEE_TYPE_DES3;
TA_generate_key in generator.c (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta) : 		type = TEE_TYPE_DES3;
TA_populate_key_attrs in generator.c (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta) : 	case TEE_TYPE_DES3:
TA_possibe_size in keystore_ta.c (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta) : 	case TEE_TYPE_DES3:
TA_begin in keystore_ta.c (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta) : 	case TEE_TYPE_DES3://这里增加algorithm = KM_ALGORITHM_TRIPLE_DES;赋值处理
TA_update in keystore_ta.c (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta) : 	case TEE_TYPE_DES3: //这里是调用TA_des3_update
TA_finish in keystore_ta.c (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta) : 	case TEE_TYPE_DES3: //这里是调用TA_des3_finish

TA_possibe_size中修改: 

	case TEE_TYPE_DES3:
		return ((input.data_length + DES3_BLOCK_SIZE - 1)
				/ DES3_BLOCK_SIZE + 1) * DES3_BLOCK_SIZE + tag_len;
		break;

TA_populate_key_attrs中修改:

	case TEE_TYPE_DES3:
		att->attrs_count = KM_ATTR_COUNT_AES_HMAC;
		att->alg = KM_ALGORITHM_TRIPLE_DES;
		break;

TA_generate_key中修改:

	case KM_ALGORITHM_TRIPLE_DES:
		attributes = attributes_aes_hmac;
		attr_count = KM_ATTR_COUNT_AES_HMAC;
		type = TEE_TYPE_DES3;
		break;

TA_import_key中修改:

	case KM_ALGORITHM_TRIPLE_DES:
		type = TEE_TYPE_DES3;
		break;

KM_ALGORITHM_TRIPLE_DES相关汇总:

---- KM_ALGORITHM_TRIPLE_DES Matches (25 in 15 files) ----
TA_get_key_size in generator.c (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta) : 	case KM_ALGORITHM_TRIPLE_DES:
TA_import_key in generator.c (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta) : 	case KM_ALGORITHM_TRIPLE_DES:
TA_generate_key in generator.c (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta) : 	case KM_ALGORITHM_TRIPLE_DES:
TA_generate_key in generator.c (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta) : 		DMSG("KM_ALGORITHM_TRIPLE_DES");
TA_populate_key_attrs in generator.c (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta) : 		att->alg = KM_ALGORITHM_TRIPLE_DES;
TA_create_operation in generator.c (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta) : 	case KM_ALGORITHM_TRIPLE_DES:
TA_create_operation in generator.c (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta) : 	case KM_ALGORITHM_TRIPLE_DES:
TA_begin in keystore_ta.c (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta) : 		algorithm = KM_ALGORITHM_TRIPLE_DES;
TA_begin in keystore_ta.c (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta) : 	if ((algorithm == KM_ALGORITHM_AES || algorithm == KM_ALGORITHM_TRIPLE_DES)
TA_begin in keystore_ta.c (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta) : 		} else if (algorithm == KM_ALGORITHM_TRIPLE_DES) {
TA_check_params in parameters.c (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta) : 		if (*algorithm == KM_ALGORITHM_AES || *algorithm == KM_ALGORITHM_TRIPLE_DES) {
ta_ca_defs.h (vendor\jlq\jtee_sdk\src\secure_app\keymaster\ta\include) line 206 :     KM_ALGORITHM_TRIPLE_DES = 33,

TA_get_key_size中修改:

	case KM_ALGORITHM_TRIPLE_DES:
		/* attr_count * (size of tag + size of attribute +
		 * attribute data size) + size of algorithm + size of key size
		 */
		return KM_ATTR_COUNT_AES_HMAC *
			(2 * sizeof(uint32_t) + KM_DES3_ATTR_SIZE)
			+ sizeof(algorithm) + sizeof(uint32_t);
		break;

TA_import_key中修改:

	case KM_ALGORITHM_TRIPLE_DES:
		type = TEE_TYPE_DES3;
		break;

TA_generate_key中修改:

	case KM_ALGORITHM_TRIPLE_DES:
		attributes = attributes_aes_hmac;
		attr_count = KM_ATTR_COUNT_AES_HMAC;
		type = TEE_TYPE_DES3;
		break;

TA_populate_key_attrs中修改:

	case TEE_TYPE_DES3:
		att->attrs_count = KM_ATTR_COUNT_AES_HMAC;
		att->alg = KM_ALGORITHM_TRIPLE_DES;
		break;

TA_create_operation中修改:

	case KM_ALGORITHM_TRIPLE_DES:
		switch (op_mode) {
		case KM_MODE_ECB:
			algo = TEE_ALG_DES3_ECB_NOPAD;
			break;
		case KM_MODE_CBC:
			algo = TEE_ALG_DES3_CBC_NOPAD;
			break;
		default:
			algo = TEE_ALG_DES3_CMAC;
			break;
		}
		break;
        ............
	case KM_ALGORITHM_TRIPLE_DES:
		DMSG("-->TEE_CipherInit");
		TEE_CipherInit(*operation,
				nonce.data,
				nonce.data_length);
		break;

TA_begin中修改:

	case TEE_TYPE_DES3:
		algorithm = KM_ALGORITHM_TRIPLE_DES;
		break;
	if ((algorithm == KM_ALGORITHM_AES || algorithm == KM_ALGORITHM_TRIPLE_DES)
			&& mode != KM_MODE_ECB && nonce.data_length == 0) {
		if (algorithm == KM_ALGORITHM_AES) {
			if (mode == KM_MODE_CBC || mode == KM_MODE_CTR) {
				IVsize = 16;
			} else {/* GCM mode */
				IVsize = 12;
			}
		} else if (algorithm == KM_ALGORITHM_TRIPLE_DES) {
			if (mode == KM_MODE_CBC || mode == KM_MODE_CTR) {
				IVsize = 8;
			}
		}
		
		out_params.length = 1;
		secretIV = TEE_Malloc(IVsize, TEE_MALLOC_FILL_ZERO);
		if (!secretIV) {
			EMSG("Failed to allocate memory for secretIV");
			res = KM_ERROR_MEMORY_ALLOCATION_FAILED;
			goto out;
		}
		nonce_param = TEE_Malloc(sizeof(keymaster_key_param_t), TEE_MALLOC_FILL_ZERO);
		if (!nonce_param) {
			TEE_Free(secretIV);
			EMSG("Failed to allocate memory for parameters");
			res = KM_ERROR_MEMORY_ALLOCATION_FAILED;
			goto out;
		}
		TEE_GenerateRandom(secretIV, IVsize);
		nonce_param->tag = KM_TAG_NONCE;
		nonce_param->key_param.blob.data = secretIV;
		nonce_param->key_param.blob.data_length = IVsize;
		out_params.params = nonce_param;
		nonce.data_length = IVsize;
		nonce.data = secretIV;
	}

TA_check_params中修改:

		if (*algorithm == KM_ALGORITHM_AES || *algorithm == KM_ALGORITHM_TRIPLE_DES) {
			/* AES */
			match = false;
			if (*op_mode == UNDEFINED) {
				EMSG("Operation block mode is not set");
				res = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
				goto out_cp;
			}
			for (uint32_t i = 0; i < block_mode_count; i++) {
				if (*op_mode == block_mode[i]) {
					match = true;
					break;
				}
			}
			if (!match) {
				EMSG("Key does not support such blobk mode");
				res = KM_ERROR_INCOMPATIBLE_BLOCK_MODE;
				goto out_cp;
			}
			if (((*op_mode == KM_MODE_GCM ||
					*op_mode == KM_MODE_CTR) &&
					*op_padding != KM_PAD_NONE) ||
					((*op_mode == KM_MODE_ECB ||
					*op_mode == KM_MODE_CBC) &&
					*op_padding != KM_PAD_NONE
					&& *op_padding != KM_PAD_PKCS7)) {
				EMSG("Mode does not compatible with padding");
				res = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
				goto out_cp;
			}
			if (nonce->data_length > 0 && nonce->data_length != 12 &&
					nonce->data_length != 16 && *algorithm == KM_ALGORITHM_AES) {
				EMSG("Wrong nonce length is prohibited %ld", nonce->data_length);
				res = KM_ERROR_INVALID_NONCE;
				goto out_cp;
			}
		}

ta_ca_defs.h中修改:

/**
 * Algorithms that may be provided by keymaster implementations.  Those that must be provided by all
 * implementations are tagged as "required".
 */
typedef enum {
    /* Asymmetric algorithms. */
    KM_ALGORITHM_RSA = 1,
    // KM_ALGORITHM_DSA = 2, -- Removed, do not re-use value 2.
    KM_ALGORITHM_EC = 3,

    /* Block ciphers algorithms */
    KM_ALGORITHM_AES = 32,
    KM_ALGORITHM_TRIPLE_DES = 33,//增加算法定义

    /* MAC algorithms */
    KM_ALGORITHM_HMAC = 128,
} keymaster_algorithm_t;

  

posted @ 2023-02-16 14:20  xiululu  阅读(124)  评论(0编辑  收藏  举报