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, ¶ms_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;