Skip to content

Commit

Permalink
core: add management pseudo TA
Browse files Browse the repository at this point in the history
Adds a pseudo TA for management of Trusted Applications and Security
Domains. The pseudo TA only provides a minimal interface, a more
advanced interface is supposed to be provided by a user TA using this
pseudo TA. Such a TA could for instance implement Global Platforms TEE
Management Framework or OTrP.

The management TA currently only supports installing bootstrap packaged
TAs in secure storage.

Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
  • Loading branch information
jenswi-linaro committed Nov 28, 2017
1 parent bb2076f commit deecfc3
Show file tree
Hide file tree
Showing 5 changed files with 243 additions and 0 deletions.
204 changes: 204 additions & 0 deletions core/arch/arm/pta/secstor_ta_mgmt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
/*
* Copyright (c) 2017, Linaro Limited
* All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#include <kernel/pseudo_ta.h>
#include <tee/tadb.h>
#include <pta_management.h>
#include <signed_hdr.h>
#include <string_ext.h>
#include <string.h>
#include <tee_api_types.h>
#include <crypto/crypto.h>
#include <tee/uuid.h>
#include <types_ext.h>
#include <utee_defines.h>

static TEE_Result check_install_conflict(const struct shdr_bootstrap_ta *bs_ta)
{
TEE_Result res;
struct tee_tadb_ta *ta;
TEE_UUID uuid;
const struct tee_tadb_property *prop;

tee_uuid_from_octets(&uuid, bs_ta->uuid);
res = tee_tadb_ta_open(&uuid, &ta);
if (res == TEE_ERROR_ITEM_NOT_FOUND)
return TEE_SUCCESS;
if (res)
return res;

prop = tee_tadb_ta_get_property(ta);
if (prop->version > bs_ta->version)
res = TEE_ERROR_ACCESS_CONFLICT;

tee_tadb_ta_close(ta);
return res;
}

static TEE_Result install_ta(struct shdr *shdr, const uint8_t *nw,
size_t nw_size)
{
TEE_Result res;
struct tee_tadb_ta *ta;
uint32_t hash_algo;
void *hash_ctx = NULL;
size_t hash_ctx_size;
size_t offs;
const size_t buf_size = 2 * 4096;
void *buf;
struct tee_tadb_property property;
struct shdr_bootstrap_ta bs_ta;

if (shdr->img_type != SHDR_BOOTSTRAP_TA)
return TEE_ERROR_SECURITY;

if (nw_size < (sizeof(struct shdr_bootstrap_ta) + SHDR_GET_SIZE(shdr)))
return TEE_ERROR_SECURITY;

if (shdr->hash_size > buf_size)
return TEE_ERROR_SECURITY;

buf = malloc(buf_size);
if (!buf)
return TEE_ERROR_OUT_OF_MEMORY;

/*
* Initialize a hash context and run the algorithm over the signed
* header (less the final file hash and its signature of course)
*/
hash_algo = TEE_DIGEST_HASH_TO_ALGO(shdr->algo);
res = crypto_hash_get_ctx_size(hash_algo, &hash_ctx_size);
if (res)
goto err;
hash_ctx = malloc(hash_ctx_size);
if (!hash_ctx) {
res = TEE_ERROR_OUT_OF_MEMORY;
goto err;
}
res = crypto_hash_init(hash_ctx, hash_algo);
if (res)
goto err_free_hash_ctx;
res = crypto_hash_update(hash_ctx, hash_algo, (uint8_t *)shdr,
sizeof(*shdr));
if (res)
goto err_free_hash_ctx;

offs = SHDR_GET_SIZE(shdr);
memcpy(&bs_ta, nw + offs, sizeof(bs_ta));

/* Check that we're not downgrading a TA */
res = check_install_conflict(&bs_ta);
if (res)
goto err_free_hash_ctx;

res = crypto_hash_update(hash_ctx, hash_algo, (uint8_t *)&bs_ta,
sizeof(bs_ta));
if (res)
goto err_free_hash_ctx;
offs += sizeof(bs_ta);

memset(&property, 0, sizeof(property));
COMPILE_TIME_ASSERT(sizeof(property.uuid) == sizeof(property.uuid));
tee_uuid_from_octets(&property.uuid, bs_ta.uuid);
property.is_ta = true;
property.is_root = true;
property.version = bs_ta.version;
property.custom_size = 0;
property.bin_size = nw_size - offs;
DMSG("Installing %pUl", (void *)&property.uuid);

res = tee_tadb_ta_create(&property, &ta);
if (res)
goto err_free_hash_ctx;

while (offs < nw_size) {
size_t l = MIN(buf_size, nw_size - offs);

memcpy(buf, nw + offs, l);
res = crypto_hash_update(hash_ctx, hash_algo, buf, l);
if (res)
goto err_ta_finalize;
res = tee_tadb_ta_write(ta, buf, l);
if (res)
goto err_ta_finalize;
offs += l;
}

res = crypto_hash_final(hash_ctx, hash_algo, buf, shdr->hash_size);
if (res)
goto err_free_hash_ctx;
if (buf_compare_ct(buf, SHDR_GET_HASH(shdr), shdr->hash_size)) {
res = TEE_ERROR_SECURITY;
goto err_free_hash_ctx;
}

free(hash_ctx);
free(buf);
return tee_tadb_ta_close_and_commit(ta);

err_ta_finalize:
tee_tadb_ta_close_and_delete(ta);
err_free_hash_ctx:
free(hash_ctx);
err:
free(buf);
return res;
}

static TEE_Result bootstrap(struct tee_ta_session *s __unused,
uint32_t param_types,
TEE_Param params[TEE_NUM_PARAMS])
{
TEE_Result res;
struct shdr *shdr;
const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
TEE_PARAM_TYPE_NONE,
TEE_PARAM_TYPE_NONE,
TEE_PARAM_TYPE_NONE);

if (param_types != exp_pt)
return TEE_ERROR_BAD_PARAMETERS;

shdr = shdr_alloc_and_copy(params->memref.buffer, params->memref.size);
if (!shdr)
return TEE_ERROR_SECURITY;

res = shdr_verify_signature(shdr);
if (res)
goto out;

res = install_ta(shdr, params->memref.buffer, params->memref.size);
out:
shdr_free(shdr);
return res;
}

static TEE_Result invoke_command(void *sess_ctx __unused, uint32_t cmd_id,
uint32_t param_types,
TEE_Param params[TEE_NUM_PARAMS])
{
struct tee_ta_session *s = tee_ta_get_calling_session();

switch (cmd_id) {
case PTA_MANAGEMENT_BOOTSTRAP:
return bootstrap(s, param_types, params);
default:
break;
}
return TEE_ERROR_NOT_IMPLEMENTED;
}

pseudo_ta_register(.uuid = PTA_MANAGEMENT_UUID, .name = "management",
/*
* TA_FLAG_SINGLE_INSTANCE and TA_FLAG_MULTI_SESSION are
* current part of PTA_DEFAULT_FLAGS, but as this TA
* depends on those two flags we add them explicitly
* too.
*/
.flags = PTA_DEFAULT_FLAGS | TA_FLAG_SINGLE_INSTANCE |
TA_FLAG_MULTI_SESSION,
.invoke_command_entry_point = invoke_command);
1 change: 1 addition & 0 deletions core/arch/arm/pta/sub.mk
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ srcs-$(CFG_TEE_CORE_EMBED_INTERNAL_TESTS) += core_self_tests.c
srcs-$(CFG_TEE_CORE_EMBED_INTERNAL_TESTS) += interrupt_tests.c
srcs-$(CFG_TEE_CORE_EMBED_INTERNAL_TESTS) += core_mutex_tests.c
ifeq ($(CFG_WITH_USER_TA),y)
srcs-$(CFG_SECSTOR_TA_MGMT_PTA) += secstor_ta_mgmt.c
srcs-$(CFG_TEE_CORE_EMBED_INTERNAL_TESTS) += core_fs_htree_tests.c
endif
srcs-$(CFG_WITH_STATS) += stats.c
Expand Down
11 changes: 11 additions & 0 deletions core/core.mk
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,19 @@ include core/arch/$(ARCH)/$(ARCH).mk
PLATFORM_$(PLATFORM) := y
PLATFORM_FLAVOR_$(PLATFORM_FLAVOR) := y

#
# Sort out some configuration dependencies
#

$(call cfg-depends-all,CFG_PAGED_USER_TA,CFG_WITH_PAGER CFG_WITH_USER_TA)

$(call cfg-depends-all,CFG_SECSTOR_TA_MGMT_PTA,CFG_WITH_USER_TA)

ifeq ($(CFG_SECSTOR_TA_MGMT_PTA),y)
$(call force,CFG_SECSTOR_TA,y,required by CFG_SECSTOR_TA_MGMT_PTA)
endif


# Setup compiler for this sub module
COMPILER_$(sm) ?= $(COMPILER)
include mk/$(COMPILER_$(sm)).mk
Expand Down
24 changes: 24 additions & 0 deletions lib/libutee/include/pta_management.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2017, Linaro Limited
* All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#ifndef __PTA_MANAGEMENT_H
#define __PTA_MANAGEMENT_H

#define PTA_MANAGEMENT_TA_EXISTS 1

/*
* Bootstrap (install initial) Trusted Application or Secure Domain into
* secure storage from a signed binary.
*
* [in] memref[0]: signed binary
*/
#define PTA_MANAGEMENT_BOOTSTRAP 0

#define PTA_MANAGEMENT_UUID { 0x6e256cba, 0xfc4d, 0x4941, { \
0xad, 0x09, 0x2c, 0xa1, 0x86, 0x03, 0x42, 0xdd } }

#endif /*__PTA_MANAGEMENT_H*/
3 changes: 3 additions & 0 deletions mk/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,9 @@ CFG_SECURE_DATA_PATH ?= n
# Enable storage for TAs in secure storage
CFG_SECSTOR_TA ?= y

# Enable the pseudo TA that managages TA storage in secure storage
CFG_SECSTOR_TA_MGMT_PTA ?= y

# Define the number of cores per cluster used in calculating core position.
# The cluster number is shifted by this value and added to the core ID,
# so its value represents log2(cores/cluster).
Expand Down

0 comments on commit deecfc3

Please sign in to comment.