From 4785b05d592d3696d4ff5c1022f75d8d0f99f609 Mon Sep 17 00:00:00 2001 From: Jun Nie Date: Wed, 19 Jul 2023 14:42:06 +0800 Subject: split ECDSA verify and sign Signed-off-by: Jun Nie --- host/xtest/regression_4000.c | 9 +- ta/include/ta_key_demo.h | 1 + ta/key_demo/include/key_demo.h | 4 +- ta/key_demo/key_demo.c | 229 ++++++++++++++++++++++++++++++++--------- ta/key_demo/ta_entry.c | 5 +- 5 files changed, 198 insertions(+), 50 deletions(-) diff --git a/host/xtest/regression_4000.c b/host/xtest/regression_4000.c index fd90c24..1b2ed2a 100644 --- a/host/xtest/regression_4000.c +++ b/host/xtest/regression_4000.c @@ -6453,8 +6453,9 @@ static void xtest_tee_test_4032_single(ADBG_Case_t *c) xtest_teec_open_session(&sess, &key_demo_ta_uuid, NULL, &orig))) return; + /* all are input for verify !!! */ op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_VALUE_INPUT, - TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_OUTPUT); + TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT); op.params[0].tmpref.buffer = key1_id; op.params[0].tmpref.size = strlen(key1_id); @@ -6477,6 +6478,7 @@ static void xtest_tee_test_4033_single(ADBG_Case_t *c) uint32_t orig; TEEC_Operation op = TEEC_OPERATION_INITIALIZER; char key1_id[] = "ecckey#1"; /* string for the key */ + char sign[80]; if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(&sess, &key_demo_ta_uuid, NULL, &orig))) @@ -6491,8 +6493,11 @@ static void xtest_tee_test_4033_single(ADBG_Case_t *c) op.params[1].value.a = TEE_ALG_ECDSA_SHA256; op.params[1].value.b = TEE_MODE_SIGN; + op.params[3].tmpref.buffer = sign; + op.params[3].tmpref.size = 80; + ADBG_EXPECT_TEEC_SUCCESS(c, - TEEC_InvokeCommand(&sess, TA_KEY_DEMO_CMD_ECDSA_VERIFY, + TEEC_InvokeCommand(&sess, TA_KEY_DEMO_CMD_ECDSA_SIGN, &op, &orig)); TEEC_CloseSession(&sess); diff --git a/ta/include/ta_key_demo.h b/ta/include/ta_key_demo.h index 823da0f..ed694a5 100644 --- a/ta/include/ta_key_demo.h +++ b/ta/include/ta_key_demo.h @@ -60,6 +60,7 @@ typedef enum { #define TA_KEY_DEMO_CMD_CREATE_ECC_KEY 31 #define TA_KEY_DEMO_CMD_ECC_DERIVE_KEY 32 #define TA_KEY_DEMO_CMD_ECDSA_VERIFY 33 +#define TA_KEY_DEMO_CMD_ECDSA_SIGN 34 #endif /*__TA_KEY_DEMO_H*/ diff --git a/ta/key_demo/include/key_demo.h b/ta/key_demo/include/key_demo.h index a5a11e7..9accbe8 100644 --- a/ta/key_demo/include/key_demo.h +++ b/ta/key_demo/include/key_demo.h @@ -50,7 +50,9 @@ TEE_Result ta_key_generate_ecdh_key_pair(uint32_t param_types, TEE_Param params[4]); TEE_Result ta_key_derive_ecdh_key(uint32_t param_types, TEE_Param params[4]); -TEE_Result ta_key_ecdsa(uint32_t param_types, +TEE_Result ta_key_ecdsa_verify(uint32_t param_types, + TEE_Param params[4]); +TEE_Result ta_key_ecdsa_sign(uint32_t param_types, TEE_Param params[4]); #endif /*KEY_DEMO_H */ diff --git a/ta/key_demo/key_demo.c b/ta/key_demo/key_demo.c index cad4930..78e592c 100644 --- a/ta/key_demo/key_demo.c +++ b/ta/key_demo/key_demo.c @@ -1349,7 +1349,7 @@ static uint8_t nist_186_2_ecdsa_testvector_32_out[] = { }; #define TEE_MAX_HASH_SIZE 64 -TEE_Result ta_key_ecdsa(uint32_t param_types, TEE_Param params[4]) +TEE_Result ta_key_ecdsa_verify(uint32_t param_types, TEE_Param params[4]) { TEE_Result result = TEE_SUCCESS; TEE_ObjectHandle key = TEE_HANDLE_NULL; @@ -1376,19 +1376,9 @@ TEE_Result ta_key_ecdsa(uint32_t param_types, TEE_Param params[4]) ASSERT_PARAM_TYPE(TEE_PARAM_TYPES (TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_VALUE_INPUT, - TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_MEMREF_OUTPUT)); + TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_MEMREF_INPUT)); - if (TEE_MODE_SIGN == mode) { - msg = nist_186_2_ecdsa_testvector_32_ptx; - msgsz = sizeof(nist_186_2_ecdsa_testvector_32_ptx); - priv = nist_186_2_ecdsa_testvector_32_private; - privsz = sizeof(nist_186_2_ecdsa_testvector_32_private); - pub_x = nist_186_2_ecdsa_testvector_32_public_x; - pub_y = nist_186_2_ecdsa_testvector_32_public_y; - pubsz = sizeof(nist_186_2_ecdsa_testvector_32_public_y); - ref_out = nist_186_2_ecdsa_testvector_32_out; - refoutsz = sizeof(nist_186_2_ecdsa_testvector_32_out); - } else if (TEE_MODE_VERIFY == mode) { + if (TEE_MODE_VERIFY == mode) { msg = nist_186_2_ecdsa_testvector_31_ptx; msgsz = sizeof(nist_186_2_ecdsa_testvector_31_ptx); priv = nist_186_2_ecdsa_testvector_31_private; @@ -1399,7 +1389,7 @@ TEE_Result ta_key_ecdsa(uint32_t param_types, TEE_Param params[4]) ref_out = nist_186_2_ecdsa_testvector_31_out; refoutsz = sizeof(nist_186_2_ecdsa_testvector_31_out); } else { - EMSG("Invalid sign/verify mode: 0x%x", mode); + EMSG("Invalid verify mode: 0x%x", mode); return TEE_ERROR_BAD_PARAMETERS; } @@ -1421,6 +1411,7 @@ TEE_Result ta_key_ecdsa(uint32_t param_types, TEE_Param params[4]) if (!ptx_hash) return TEE_ERROR_OUT_OF_MEMORY; + /* TODO: we should use correct sha* */ result = TEE_AllocateOperation(&digest_op, TEE_ALG_SHA1, TEE_MODE_DIGEST, 0); if (result != TEE_SUCCESS) { @@ -1435,8 +1426,6 @@ TEE_Result ta_key_ecdsa(uint32_t param_types, TEE_Param params[4]) goto cleanup2; } - - key_id = TEE_Malloc(params[0].memref.size, 0); if (!key_id) return TEE_ERROR_OUT_OF_MEMORY; @@ -1470,18 +1459,179 @@ EMSG("-----------Open persistent object, res=0x%08x", result); a[2].attributeID = TEE_ATTR_ECC_PUBLIC_VALUE_X; a[2].content.ref.length = pubsz; a[2].content.ref.buffer = pub_x; + num_attrs = 3; + + key_type = TEE_TYPE_ECDSA_PUBLIC_KEY; + + result = TEE_AllocateTransientObject(key_type, key_size, + &key); + if (result != TEE_SUCCESS) { + EMSG("Failed to Allocate transient object handle : 0x%x", + result); + goto cleanup1; + } + + result = TEE_PopulateTransientObject(key, a, num_attrs); + if (result != TEE_SUCCESS) { + EMSG("Failed to populate key: 0x%x", result); + goto cleanup2; + } +#endif + + result = TEE_AllocateOperation(&ecdsa_op, alg, mode, + key_size); + if (result != TEE_SUCCESS) { + EMSG("Failed to allocate an operation: 0x%x", result); + goto cleanup2; + } + + result = TEE_SetOperationKey(ecdsa_op, key); + if (result != TEE_SUCCESS) { + EMSG("Failed to set operation key: 0x%x", result); + goto cleanup3; + } + + result = TEE_AsymmetricVerifyDigest(ecdsa_op, NULL, 0, + ptx_hash, ptx_hash_size, + ref_out, refoutsz); + + if (result != TEE_SUCCESS) { + EMSG("Failed to verify/sign : 0x%x", result); + goto cleanup3; + } + +cleanup3: + TEE_FreeOperation(ecdsa_op); +cleanup2: + TEE_Free(a); +#ifdef LOAD_PERSIST_KEY + TEE_CloseObject(key); +#else + TEE_FreeTransientObject(key); +#endif +cleanup1: + TEE_Free(key_id); + TEE_FreeOperation(digest_op); + return result; +} + +TEE_Result ta_key_ecdsa_sign(uint32_t param_types, TEE_Param params[4]) +{ + TEE_Result result = TEE_SUCCESS; + TEE_ObjectHandle key = TEE_HANDLE_NULL; + TEE_OperationHandle ecdsa_op = TEE_HANDLE_NULL; + TEE_OperationHandle digest_op = TEE_HANDLE_NULL; + size_t key_type; + size_t key_size = 256, num_attrs = 4, cnt; + uint32_t storage_id = KEY_DEMO_STORAGE; + uint32_t alg = params[1].value.a; + uint32_t mode = params[1].value.b; + char *key_id; + TEE_ObjectInfo keyInfo3; + TEE_Attribute *a; + char out[80]; + uint8_t *ptx_hash; + uint32_t ptx_hash_size = TEE_MAX_HASH_SIZE, outsz = 80; + uint8_t *msg, msgsz, *priv, privsz, *pub_x, *pub_y, pubsz, *ref_out, refoutsz; + + uint32_t flags = TEE_DATA_FLAG_ACCESS_READ | + TEE_DATA_FLAG_ACCESS_WRITE | + TEE_DATA_FLAG_ACCESS_WRITE_META | + TEE_DATA_FLAG_SHARE_READ | + TEE_DATA_FLAG_SHARE_WRITE; + + ASSERT_PARAM_TYPE(TEE_PARAM_TYPES + (TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_VALUE_INPUT, + TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_MEMREF_OUTPUT)); if (TEE_MODE_SIGN == mode) { - a[3].attributeID = TEE_ATTR_ECC_PRIVATE_VALUE; - a[3].content.ref.length = privsz; - a[3].content.ref.buffer = priv; - num_attrs = 4; - key_type = TEE_TYPE_ECDSA_KEYPAIR; + msg = nist_186_2_ecdsa_testvector_32_ptx; + msgsz = sizeof(nist_186_2_ecdsa_testvector_32_ptx); + priv = nist_186_2_ecdsa_testvector_32_private; + privsz = sizeof(nist_186_2_ecdsa_testvector_32_private); + pub_x = nist_186_2_ecdsa_testvector_32_public_x; + pub_y = nist_186_2_ecdsa_testvector_32_public_y; + pubsz = sizeof(nist_186_2_ecdsa_testvector_32_public_y); + ref_out = nist_186_2_ecdsa_testvector_32_out; + refoutsz = sizeof(nist_186_2_ecdsa_testvector_32_out); } else { - key_type = TEE_TYPE_ECDSA_PUBLIC_KEY; - num_attrs = 3; + EMSG("Invalid sign mode: 0x%x", mode); + return TEE_ERROR_BAD_PARAMETERS; + } + + switch (alg) { + case TEE_ALG_ECDSA_SHA512: + key_size = 521; + break; + case TEE_ALG_ECDSA_SHA1: + case TEE_ALG_ECDSA_SHA256: + case TEE_ALG_ECDSA_SHA384: + key_size = privsz * 8; + break; + default: + EMSG("Invalid alg: 0x%x", alg); + return TEE_ERROR_BAD_PARAMETERS; + } + + ptx_hash = TEE_Malloc(TEE_MAX_HASH_SIZE, 0); + if (!ptx_hash) + return TEE_ERROR_OUT_OF_MEMORY; + + /* TODO: we should use correct sha* */ + result = TEE_AllocateOperation(&digest_op, TEE_ALG_SHA1, + TEE_MODE_DIGEST, 0); + if (result != TEE_SUCCESS) { + EMSG("Failed to allocate digest operation: 0x%x", result); + goto cleanup2; } + result = TEE_DigestDoFinal(digest_op, msg, msgsz, + ptx_hash, &ptx_hash_size); + if (result != TEE_SUCCESS) { + EMSG("Failed to digest : 0x%x", result); + goto cleanup2; + } + + key_id = TEE_Malloc(params[0].memref.size, 0); + if (!key_id) + return TEE_ERROR_OUT_OF_MEMORY; + + TEE_MemMove(key_id, params[0].memref.buffer, params[0].memref.size); + +#ifdef LOAD_PERSIST_KEY + result = TEE_OpenPersistentObject(storage_id, + key_id, params[0].memref.size, + flags, &key); +EMSG("-----------Open persistent object, res=0x%08x", result); + if (result != TEE_SUCCESS) { + EMSG("Failed to open persistent key: 0x%x", result); + goto cleanup1; + } + + TEE_GetObjectInfo(key, &keyInfo3); +#else + + a = TEE_Malloc(num_attrs * sizeof(TEE_Attribute), 0); + if (!a) { + result = TEE_ERROR_OUT_OF_MEMORY; + goto cleanup1; + } + a[0].attributeID = TEE_ATTR_ECC_CURVE; + a[0].content.value.a = TEE_ECC_CURVE_NIST_P256; + a[0].content.value.b = 0; + a[1].attributeID = TEE_ATTR_ECC_PUBLIC_VALUE_Y; + a[1].content.ref.length = pubsz; + a[1].content.ref.buffer = pub_y; + a[2].attributeID = TEE_ATTR_ECC_PUBLIC_VALUE_X; + a[2].content.ref.length = pubsz; + a[2].content.ref.buffer = pub_x; + + a[3].attributeID = TEE_ATTR_ECC_PRIVATE_VALUE; + a[3].content.ref.length = privsz; + a[3].content.ref.buffer = priv; + num_attrs = 4; + key_type = TEE_TYPE_ECDSA_KEYPAIR; + result = TEE_AllocateTransientObject(key_type, key_size, &key); if (result != TEE_SUCCESS) { @@ -1510,36 +1660,23 @@ EMSG("-----------Open persistent object, res=0x%08x", result); goto cleanup3; } - if (TEE_MODE_VERIFY == mode) - result = TEE_AsymmetricVerifyDigest(ecdsa_op, NULL, 0, - ptx_hash, ptx_hash_size, - ref_out, refoutsz); - else - result = TEE_AsymmetricSignDigest(ecdsa_op, NULL, 0, - ptx_hash, ptx_hash_size, - out, &outsz); + result = TEE_AsymmetricSignDigest(ecdsa_op, NULL, 0, + ptx_hash, ptx_hash_size, + out, &outsz); if (result != TEE_SUCCESS) { EMSG("Failed to verify/sign : 0x%x", result); goto cleanup3; } - if (TEE_MODE_SIGN == mode) { - if (outsz != refoutsz) { - EMSG("output size is %d, while %d expected", outsz, refoutsz); - result = TEE_ERROR_GENERIC; - goto cleanup3; - } - - for (cnt = 0; cnt < outsz; cnt++) { - if (out[cnt] != ref_out[cnt]) { - EMSG("out[%d] 0x%x as 0x%x expected", cnt, out[cnt], - ref_out[cnt]); - result = TEE_ERROR_GENERIC; - goto cleanup3; - } - } + if (outsz > params[3].memref.size) { + EMSG("Err: output size is %d, while outbuf is only %d", + outsz, params[3].memref.size); + result = TEE_ERROR_GENERIC; + goto cleanup3; } + TEE_MemMove(params[3].memref.buffer, out, outsz); + params[3].memref.size = outsz; cleanup3: TEE_FreeOperation(ecdsa_op); diff --git a/ta/key_demo/ta_entry.c b/ta/key_demo/ta_entry.c index 768e5d7..e5f0c37 100644 --- a/ta/key_demo/ta_entry.c +++ b/ta/key_demo/ta_entry.c @@ -145,7 +145,10 @@ TEE_Result TA_InvokeCommandEntryPoint(void *pSessionContext, return ta_key_derive_ecdh_key(nParamTypes, pParams); case TA_KEY_DEMO_CMD_ECDSA_VERIFY: - return ta_key_ecdsa(nParamTypes, pParams); + return ta_key_ecdsa_verify(nParamTypes, pParams); + + case TA_KEY_DEMO_CMD_ECDSA_SIGN: + return ta_key_ecdsa_sign(nParamTypes, pParams); /* case TA_KEY_DEMO_CMD_LOOP: return ta_key_demo_cmd_loop(nParamTypes, pParams); -- cgit v1.2.3