@@ -15,3 +15,4 @@ srcs-$(CFG_TEE_BENCHMARK) += benchmark.c
srcs-$(CFG_SDP_PTA) += sdp_pta.c
srcs-$(CFG_SYSTEM_PTA) += system.c
srcs-$(CFG_DEVICE_ENUM_PTA) += device.c
+srcs-y += trusted_key.c
new file mode 100644
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (C) 2019, Linaro Limited
+ */
+
+#include <crypto/crypto.h>
+#include <kernel/pseudo_ta.h>
+#include <kernel/tee_ta_manager.h>
+#include <pta_trusted_key.h>
+#include <string.h>
+#include <tee/tee_fs_key_manager.h>
+#include <tee/uuid.h>
+#include <user_ta_header.h>
+
+#define PTA_NAME "trusted_key.pta"
+
+static TEE_Result get_random(uint32_t types,
+ TEE_Param params[TEE_NUM_PARAMS])
+{
+ FMSG("Invoked TA_CMD_GET_RANDOM");
+
+ if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT,
+ TEE_PARAM_TYPE_NONE,
+ TEE_PARAM_TYPE_NONE,
+ TEE_PARAM_TYPE_NONE))
+ return TEE_ERROR_BAD_PARAMETERS;
+
+ if (!params[0].memref.buffer || params[0].memref.size == 0)
+ return TEE_ERROR_BAD_PARAMETERS;
+
+ return crypto_rng_read(params[0].memref.buffer, params[0].memref.size);
+}
+
+static TEE_Result seal_trusted_key(uint32_t types,
+ TEE_Param params[TEE_NUM_PARAMS])
+{
+ TEE_Result res = TEE_SUCCESS;
+ const TEE_UUID uuid = PTA_TRUSTED_KEY_UUID;
+
+ FMSG("Invoked TA_CMD_SEAL");
+
+ if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
+ TEE_PARAM_TYPE_MEMREF_OUTPUT,
+ TEE_PARAM_TYPE_NONE,
+ TEE_PARAM_TYPE_NONE))
+ return TEE_ERROR_BAD_PARAMETERS;
+
+ if (!params[0].memref.buffer || params[0].memref.size == 0)
+ return TEE_ERROR_BAD_PARAMETERS;
+ if (!params[1].memref.buffer || params[1].memref.size == 0)
+ return TEE_ERROR_BAD_PARAMETERS;
+
+ res = tee_fs_fek_crypt(&uuid, TEE_MODE_ENCRYPT, params[0].memref.buffer,
+ params[0].memref.size, params[1].memref.buffer);
+ if (res == TEE_SUCCESS)
+ params[1].memref.size = params[0].memref.size;
+ else
+ params[1].memref.size = 0;
+
+ return res;
+}
+
+static TEE_Result unseal_trusted_key(uint32_t types,
+ TEE_Param params[TEE_NUM_PARAMS])
+{
+ TEE_Result res = TEE_SUCCESS;
+ const TEE_UUID uuid = PTA_TRUSTED_KEY_UUID;
+
+ FMSG("Invoked TA_CMD_UNSEAL");
+
+ if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
+ TEE_PARAM_TYPE_MEMREF_OUTPUT,
+ TEE_PARAM_TYPE_NONE,
+ TEE_PARAM_TYPE_NONE))
+ return TEE_ERROR_BAD_PARAMETERS;
+
+ if (!params[0].memref.buffer || params[0].memref.size == 0)
+ return TEE_ERROR_BAD_PARAMETERS;
+ if (!params[1].memref.buffer || params[1].memref.size == 0)
+ return TEE_ERROR_BAD_PARAMETERS;
+
+ res = tee_fs_fek_crypt(&uuid, TEE_MODE_DECRYPT, params[0].memref.buffer,
+ params[0].memref.size, params[1].memref.buffer);
+ if (res == TEE_SUCCESS)
+ params[1].memref.size = params[0].memref.size;
+ else
+ params[1].memref.size = 0;
+
+ return res;
+}
+
+static TEE_Result invoke_command(void *pSessionContext __unused,
+ uint32_t nCommandID, uint32_t nParamTypes,
+ TEE_Param pParams[TEE_NUM_PARAMS])
+{
+ switch (nCommandID) {
+ case TA_CMD_GET_RANDOM:
+ return get_random(nParamTypes, pParams);
+ case TA_CMD_SEAL:
+ return seal_trusted_key(nParamTypes, pParams);
+ case TA_CMD_UNSEAL:
+ return unseal_trusted_key(nParamTypes, pParams);
+ default:
+ break;
+ }
+
+ return TEE_ERROR_NOT_IMPLEMENTED;
+}
+
+static TEE_Result open_session(uint32_t param_types __unused,
+ TEE_Param params[TEE_NUM_PARAMS] __unused,
+ void **sess_ctx __unused)
+{
+ TEE_Result res = TEE_SUCCESS;
+ struct tee_ta_session *s;
+
+ /* Check that we're called from a REE kernel client */
+ res = tee_ta_get_current_session(&s);
+ if (res != TEE_SUCCESS)
+ return res;
+ if (s->clnt_id.login != TEE_LOGIN_REE_KERNEL)
+ res = TEE_ERROR_ACCESS_DENIED;
+
+ return res;
+}
+
+
+pseudo_ta_register(.uuid = PTA_TRUSTED_KEY_UUID, .name = PTA_NAME,
+ .flags = PTA_DEFAULT_FLAGS | TA_FLAG_DEVICE_ENUM,
+ .open_session_entry_point = open_session,
+ .invoke_command_entry_point = invoke_command);
@@ -281,6 +281,7 @@ static TEE_Result get_open_session_meta(size_t num_params,
clnt_id->login = params[1].u.value.c;
switch (clnt_id->login) {
case TEE_LOGIN_PUBLIC:
+ case TEE_LOGIN_REE_KERNEL:
memset(&clnt_id->uuid, 0, sizeof(clnt_id->uuid));
break;
case TEE_LOGIN_USER:
@@ -83,7 +83,7 @@ TEE_Result tee_fs_fek_crypt(const TEE_UUID *uuid, TEE_OperationMode mode,
if (!in_key || !out_key)
return TEE_ERROR_BAD_PARAMETERS;
- if (size != TEE_FS_KM_FEK_SIZE)
+ if (size > TEE_SHA256_HASH_SIZE)
return TEE_ERROR_BAD_PARAMETERS;
if (tee_fs_ssk.is_init == 0)
new file mode 100644
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Copyright (C) 2019, Linaro Limited
+ */
+
+/*
+ * Enumerate the pseudo TAs that have the TA_FLAG_DEVICE_ENUM flag enabled.
+ */
+
+#ifndef __PTA_TRUSTED_KEY_H
+#define __PTA_TRUSTED_KEY_H
+
+#define PTA_TRUSTED_KEY_UUID { 0xf04a0fe7, 0x1f5d, 0x4b9b, \
+ { 0xab, 0xf7, 0x61, 0x9b, 0x85, 0xb4, 0xce, 0x8c } }
+
+/*
+ * Get random data for symmetric key
+ *
+ * [out] memref[0] Random data
+ *
+ * Result:
+ * TEE_SUCCESS - Invoke command success
+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
+ */
+#define TA_CMD_GET_RANDOM 0x0
+
+/*
+ * Seal trusted key using hardware unique key
+ *
+ * [in] memref[0] Plain key
+ * [out] memref[1] Sealed key datablob
+ *
+ * Result:
+ * TEE_SUCCESS - Invoke command success
+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
+ */
+#define TA_CMD_SEAL 0x1
+
+/*
+ * Unseal trusted key using hardware unique key
+ *
+ * [in] memref[0] Sealed key datablob
+ * [out] memref[1] Plain key
+ *
+ * Result:
+ * TEE_SUCCESS - Invoke command success
+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
+ */
+#define TA_CMD_UNSEAL 0x2
+
+#endif /* __PTA_TRUSTED_KEY_H */
@@ -63,6 +63,8 @@
#define TEE_LOGIN_APPLICATION_USER 0x00000005
#define TEE_LOGIN_APPLICATION_GROUP 0x00000006
#define TEE_LOGIN_TRUSTED_APP 0xF0000000
+/* Private login method for REE kernel clients */
+#define TEE_LOGIN_REE_KERNEL 0x80000000
/* Origin Code Constants */
#define TEE_ORIGIN_API 0x00000001
This patch adds a pseudo TA which acts as Linux TEE bus device to provide a service of sealing/unsealing of trusted keys in case platform doesn't posses a TPM device. To do sealing/unsealing we use Secure Storage Key (SSK) using common api as done for FEK (using AES_ECB algo). Also, this pseudo TA only accepts login with a new private login method specifically used by REE kernel. Signed-off-by: Sumit Garg <sumit.garg@linaro.org> --- core/arch/arm/pta/sub.mk | 1 + core/arch/arm/pta/trusted_key.c | 131 ++++++++++++++++++++++++++++++++++ core/arch/arm/tee/entry_std.c | 1 + core/tee/tee_fs_key_manager.c | 2 +- lib/libutee/include/pta_trusted_key.h | 51 +++++++++++++ lib/libutee/include/tee_api_defines.h | 2 + 6 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 core/arch/arm/pta/trusted_key.c create mode 100644 lib/libutee/include/pta_trusted_key.h -- 2.7.4