From: Dariusz Michaluk Date: Thu, 22 Aug 2024 12:38:32 +0000 (+0200) Subject: Support ML-KEM derive hybrid X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ba5a9649d7f84e18cf071b51f71da66dc1612b8b;p=platform%2Fcore%2Fsecurity%2Ftrusted%2Fkey-manager-ta.git Support ML-KEM derive hybrid Change-Id: Ice5abca74f028193715437022ea9794e94d876fd --- diff --git a/ta/include/cmd_exec.h b/ta/include/cmd_exec.h index a7defbc..270e76c 100644 --- a/ta/include/cmd_exec.h +++ b/ta/include/cmd_exec.h @@ -58,6 +58,8 @@ TEE_Result KM_ExecCmdDestroyData(TEE_Param param[4]); TEE_Result KM_ExecCmdDeriveKey(TEE_Param param[4]); +TEE_Result KM_ExecCmdDeriveHybridKey(TEE_Param param[4]); + TEE_Result KM_ExecCmdImportWrappedKey(TEE_Param param[4]); TEE_Result KM_ExecCmdExportWrappedKey(TEE_Param param[4]); diff --git a/ta/include/km_ta_defines.h b/ta/include/km_ta_defines.h index 856e07c..49cf1d1 100644 --- a/ta/include/km_ta_defines.h +++ b/ta/include/km_ta_defines.h @@ -57,6 +57,7 @@ typedef enum { CMD_GENERATE_EC_KEYPAIR, ///< Generate random EC key pair. CMD_GENERATE_KEM_KEYPAIR, ///< Generate random KEM key pair. CMD_DERIVE, ///< Derive secret or key + CMD_DERIVE_HYBRID, ///< Derive secret or key CMD_IMPORT_WRAPPED_KEY, ///< Import a wrapped key CMD_EXPORT_WRAPPED_KEY, ///< Export a key in a wrapped form CMD_CIPHER_INIT, ///< Initialize encryption/decryption context diff --git a/ta/src/cmd_exec.c b/ta/src/cmd_exec.c index 9db25f8..51fe988 100644 --- a/ta/src/cmd_exec.c +++ b/ta/src/cmd_exec.c @@ -1087,6 +1087,222 @@ clean: return ret; } +TEE_Result KM_ExecCmdDeriveHybridKbkdf(TEE_Param param[4]) +{ + TEE_Result ret = TEE_SUCCESS; + TEE_ObjectHandle key_handle = TEE_HANDLE_NULL; + + void *in_buffer = param[1].memref.buffer; + void *out_buffer = param[2].memref.buffer; + uint32_t in_size_guard = param[1].memref.size; + uint32_t out_size_guard = param[2].memref.size; + + uint32_t with_first_secret_pwd = 0, with_second_secret_pwd = 0; + KM_BinaryData first_secret_id = {0, NULL}; + KM_BinaryData second_secret_id = {0, NULL}; + KM_BinaryData label = {0, NULL}; + KM_BinaryData context = {0, NULL}; + KM_BinaryData fixed = {0, NULL}; + KM_BinaryData obj_id = {0, NULL}; + KM_BinaryData key_in_first = {0, NULL}; + KM_BinaryData key_in_second = {0, NULL}; + KM_BinaryData derived_key = {0, NULL}; + KM_BinaryData encrypted_derived_key = {0, NULL}; + KM_BinaryData tag = {0, NULL}; + KM_PwdData first_secret_pwd_data, second_secret_pwd_data, pwd_data; + uint32_t outlen; + uint32_t prf; + uint32_t mode; + uint32_t ctrloc; + uint32_t rlen; + uint32_t llen; + uint32_t no_separator; + uint32_t with_pwd = 0; + + // Deserialize data from REE + ret = KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &first_secret_id); + if (ret != TEE_SUCCESS) { + LOG("Error in deserialization of hash(first_secret_id), ret = %x", ret); + goto clean; + } + + ret = KM_DeserializeFlagAndPw(&in_buffer, &in_size_guard, &with_first_secret_pwd, &first_secret_pwd_data); + if (ret != TEE_SUCCESS) { + LOG("Error in deserialization of first secret flag and password, ret = %x", ret); + goto clean; + } + + ret = KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &second_secret_id); + if (ret != TEE_SUCCESS) { + LOG("Error in deserialization of hash(second_secret_id), ret = %x", ret); + goto clean; + } + + ret = KM_DeserializeFlagAndPw(&in_buffer, &in_size_guard, &with_second_secret_pwd, &second_secret_pwd_data); + if (ret != TEE_SUCCESS) { + LOG("Error in deserialization of second secret flag and password, ret = %x", ret); + goto clean; + } + + ret = KM_DeserializeFlag(&in_buffer, &in_size_guard, &outlen); + if (ret != TEE_SUCCESS) { + LOG("Error in deserialization of outlen flag, ret = %x", ret); + goto clean; + } + + ret = KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &label); + if (ret != TEE_SUCCESS) { + LOG("Error in deserialization of hash(label), ret = %x", ret); + goto clean; + } + + ret = KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &context); + if (ret != TEE_SUCCESS) { + LOG("Error in deserialization of hash(context), ret = %x", ret); + goto clean; + } + + ret = KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &fixed); + if (ret != TEE_SUCCESS) { + LOG("Error in deserialization of hash(fixed), ret = %x", ret); + goto clean; + } + + ret = KM_DeserializeFlag(&in_buffer, &in_size_guard, &prf); + if (ret != TEE_SUCCESS) { + LOG("Error in deserialization of prf flag, ret = %x", ret); + goto clean; + } + + ret = KM_DeserializeFlag(&in_buffer, &in_size_guard, &mode); + if (ret != TEE_SUCCESS) { + LOG("Error in deserialization of mode flag, ret = %x", ret); + goto clean; + } + + ret = KM_DeserializeFlag(&in_buffer, &in_size_guard, &ctrloc); + if (ret != TEE_SUCCESS) { + LOG("Error in deserialization of ctrloc flag, ret = %x", ret); + goto clean; + } + + ret = KM_DeserializeFlag(&in_buffer, &in_size_guard, &rlen); + if (ret != TEE_SUCCESS) { + LOG("Error in deserialization of rlen flag, ret = %x", ret); + goto clean; + } + + ret = KM_DeserializeFlag(&in_buffer, &in_size_guard, &llen); + if (ret != TEE_SUCCESS) { + LOG("Error in deserialization of llen flag, ret = %x", ret); + goto clean; + } + + ret = KM_DeserializeFlag(&in_buffer, &in_size_guard, &no_separator); + if (ret != TEE_SUCCESS) { + LOG("Error in deserialization of no_separator flag, ret = %x", ret); + goto clean; + } + + ret = KM_DeserializeFlagAndPw(&in_buffer, &in_size_guard, &with_pwd, &pwd_data); + if (ret != TEE_SUCCESS) { + LOG("Error in deserialization of secret flag and password, ret = %x", ret); + goto clean; + } + + ret = KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &obj_id); + if (ret != TEE_SUCCESS) { + LOG("Error in deserialization of hash(obj_id), ret = %x", ret); + goto clean; + } + + // Get Key_In from permanent storage + ret = KM_GetSecretValue(&first_secret_id, &key_in_first, with_first_secret_pwd, &first_secret_pwd_data); + if (ret != TEE_SUCCESS) { + LOGD_ID("Failed to get first Secret Value from object: ", first_secret_id.data, first_secret_id.data_size); + goto clean; + } + + // Get Key_In from permanent storage + ret = KM_GetSecretValue(&second_secret_id, &key_in_second, with_second_secret_pwd, &second_secret_pwd_data); + if (ret != TEE_SUCCESS) { + LOGD_ID("Failed to get second Secret Value from object: ", second_secret_id.data, second_secret_id.data_size); + goto clean; + } + + void *tmp; + uint32_t new_size = key_in_first.data_size + key_in_second.data_size; + tmp = TEE_Realloc(key_in_first.data, new_size); + if (tmp == NULL) { + LOG("Failed to reallocate buffer for concatenated keys"); + ret = TEE_ERROR_OUT_OF_MEMORY; + goto clean; + } + + key_in_first.data = tmp; + key_in_first.data_size = new_size; + memcpy(key_in_first.data + key_in_first.data_size, key_in_second.data, key_in_second.data_size); + + // execute KBKDF + derived_key.data = (unsigned char *) TEE_Malloc(outlen, 0); + derived_key.data_size = outlen; + if (derived_key.data == NULL) { + LOG("Failed to allocate input buffer for derived_key"); + ret = TEE_ERROR_OUT_OF_MEMORY; + goto clean; + } + + ret = KM_KbkdfHmacCtr(key_in_first.data, key_in_first.data_size, + prf, ctrloc, rlen, llen, + label.data, label.data_size, + context.data, context.data_size, + fixed.data, fixed.data_size, + no_separator, + derived_key.data, outlen); + if (ret != TEE_SUCCESS) { + LOG("Failed in KM_KbkdfHmacCtr(): ret=%x", ret); + goto clean; + } + + // Serialize data for sending to REE. + if (with_pwd) { + ret = KM_EncryptBinary(&pwd_data, &derived_key, &encrypted_derived_key, &tag); + if (ret != TEE_SUCCESS) { + LOG("Failed to encrypt new key"); + goto clean; + } + // output tag + if (KM_Serialize(&out_buffer, &out_size_guard, tag.data, tag.data_size)) { + LOG("Error in serialization"); + ret = TEE_ERROR_BAD_PARAMETERS; + goto clean; + } + ret = KM_CreateKey(TEE_TYPE_AES, encrypted_derived_key.data_size * 8, encrypted_derived_key.data, &key_handle); + } else { + ret = KM_CreateKey(TEE_TYPE_AES, derived_key.data_size * 8, derived_key.data, &key_handle); + } + if (ret != TEE_SUCCESS) { + LOG("Failed to create key"); + goto clean; + } + + ret = KM_SaveKey(NULL, 0, key_handle, obj_id.data, obj_id.data_size); + if (ret != TEE_SUCCESS) { + LOG("Failed to save generated key"); + goto clean; + } + + LOGD_ID("Derive KBKDF key: ", obj_id.data, obj_id.data_size); +clean: + TEE_CloseObject(key_handle); + TEE_Free(key_in_first.data); + TEE_Free(key_in_second.data); + TEE_Free(derived_key.data); + TEE_Free(encrypted_derived_key.data); + TEE_Free(tag.data); + + return ret; +} static TEE_Result KM_CopyEcdhPrivateAttributes(TEE_ObjectHandle dest_key, TEE_ObjectHandle src_key) @@ -1370,6 +1586,18 @@ TEE_Result KM_ExecCmdDeriveKey(TEE_Param param[4]) } } +TEE_Result KM_ExecCmdDeriveHybridKey(TEE_Param param[4]) +{ + tz_algo_type algo= param[0].value.a; + + if (algo == ALGO_KBKDF_DRV) { + return KM_ExecCmdDeriveHybridKbkdf(param); + } else { + LOG("Invalid algorithm, algo = %d", algo); + return TEE_ERROR_BAD_PARAMETERS; + } +} + static TEE_Result KM_GetWrappingKeyHandle(KM_BinaryData *wkey_id, uint32_t algo, uint32_t with_wkey_pwd, KM_PwdData *wkey_pwd_data, TEE_ObjectHandle *wkey) { diff --git a/ta/src/km_ta.c b/ta/src/km_ta.c index 7331c50..fc60adf 100644 --- a/ta/src/km_ta.c +++ b/ta/src/km_ta.c @@ -183,6 +183,11 @@ TEE_Result TA_InvokeCommandEntryPoint( ret = KM_ExecCmdDeriveKey(param); break; } + case CMD_DERIVE_HYBRID: { + LOGD("!!! Hybrid deriving a key !!!"); + ret = KM_ExecCmdDeriveHybridKey(param); + break; + } case CMD_IMPORT_WRAPPED_KEY: { LOGD("!!! Importing a wrapped key !!!"); ret = KM_ExecCmdImportWrappedKey(param);