Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: add interface to load and decrypt/authenticate user TAs #1513

Merged
merged 1 commit into from
May 10, 2017

Conversation

jforissier
Copy link
Contributor

Some use cases may require custom load and verification methods for
user-mode Trusted Applications. Introduce struct user_ta_store_ops with
open(), get_size(), read() and close() functions to abstract these
tasks from the ELF loader code. Do the communication with
tee-supplicant as well as the hashing and signature verification of the
TA binary in core/arch/arm/kernel/ree_fs_ta.c, which may be disabled
and replaced by a different implementation if need be.

CC: Zeng Tao prime.zeng@hisilicon.com
Signed-off-by: Jerome Forissier jerome.forissier@linaro.org
Tested-by: Jerome Forissier jerome.forissier@linaro.org (HiKey, QEMU)

if (!*shdr)
return TEE_ERROR_SECURITY;
memcpy(*shdr, nw_ta, shdr_size);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should check shdr_size == SHDR_GET_SIZE(*shdr)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, will fix.

* Last read: time to check if our digest matches the expected
* one (from the signed header)
*/
res = check_digest(h);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a bit fragile. What if there's some mismatch that prevents h->offs from reaching h->nw_ta_size?
I don't have a good idea how to fix this right now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well the algorithm is unchanged actually, and we can consider it is a contract between the TA store and the TEE core that ta_get_size() bytes should be read (unless the core considers this size is unacceptable for some reason, or some other error occurs).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, please update the description of the interface to make that clear.

@jforissier
Copy link
Contributor Author

Updated. I'll probably rephrase the commit subject to be "core: add interface to load user TAs" because user_ta_store_ops has nothing to do with authentication or encryption (which is entirely left to the implementation).

@jenswi-linaro
Copy link
Contributor

With my last comment addressed:
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>

Copy link
Contributor

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few minor comment (could be discarded).
Yet, please crosscheck the comment about the assert() in init_session_with_ta_store().

core/sub.mk Outdated
@@ -2,9 +2,11 @@ subdirs-y += kernel
subdirs-y += tee
subdirs-y += drivers

ifeq ($(CFG_WITH_USER_TA)$(CFG_REE_FS_TA),yy)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpicking: prevent failure if one is not set and the other falsely set to yy:
ifeq ($(CFG_WITH_USER_TA)-$(CFG_REE_FS_TA),y-y)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

DMSG(" Load dynamic TA");
/* load and verify */
res = ta_load(uuid, signed_ta, &s->ctx);
DMSG("Load user TA %pUl", (void *)uuid);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: is this trace (the uuid address) useful ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the "special" format pUl ("pointer to UUID in little-endian format") so it will print the UUID, not the address ;)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, i didn't notice that (i saw it was merged more than 1 year ago!)


DMSG(" dyn TA : %pUl", (void *)&s->ctx->uuid);

assert(!memcmp(uuid, &s->ctx->uuid, sizeof(TEE_UUID)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace assert() with a non debug test.

ta_head->flags, opt_flags, man_flags);
if ((ta_head->flags & optional_flags) != ta_head->flags ||
(ta_head->flags & mandatory_flags) != mandatory_flags) {
EMSG("TA flag issue: flags=%x optional=%X mandatory=%X",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: ("issue" already in previous code) trace all field in either uppercase or lowercase.

if (!phta)
return TEE_ERROR_OUT_OF_MEMORY;

*ta = phys_to_virt(phta, MEM_AREA_NSEC_SHM);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: thread_rpc_alloc_payload() already insures that the overall buffer in non secure memory. Could assert or panic here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

static inline TEE_Result tee_ta_register_ta_store(
const struct user_ta_store_ops *ops __unused)
{
return TEE_SUCCESS;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should return TEE_ERROR_NOT_SUPPORTED

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

DMSG(" dyn TA : %pUl", (void *)&s->ctx->uuid);

if (memcmp(uuid, &s->ctx->uuid, sizeof(TEE_UUID)));
panic();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really panic here ? We can reach this case if the REE provides a TA binary that does not contain the requested TA. I think TEE should not panic here, but simply refuse to load the TA. I believe it should not be possible for the REE to make the TEE panicking.
Sorry if I was not that explicit in my previous comment.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This "can't happen" since ta_load() already does a memcmp() and returns an error on mismatch. The assert() should be good enough if that's even needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly, I'll remove this check and while I'm at it, drop init_session_with_ta_store() and call ta_load() directly from tee_ta_init_user_ta_session().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true. my fault. this test is useless.

@jforissier
Copy link
Contributor Author

Updated

Copy link
Contributor

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>

DMSG(" dyn TA : %pUl", (void *)&s->ctx->uuid);

if (memcmp(uuid, &s->ctx->uuid, sizeof(TEE_UUID)));
panic();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true. my fault. this test is useless.

@jenswi-linaro
Copy link
Contributor

Still OK with me.

Some use cases may require custom load and verification methods for
user-mode Trusted Applications. Introduce struct user_ta_store_ops with
open(), get_size(), read() and close() functions to abstract these
tasks from the ELF loader code. Do the communication with
tee-supplicant as well as the hashing and signature verification of the
TA binary in core/arch/arm/kernel/ree_fs_ta.c, which may be disabled
and replaced by a different implementation if need be.

CC: Zeng Tao <prime.zeng@hisilicon.com>
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (HiKey, QEMU)
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
@jforissier jforissier merged commit ee664c1 into OP-TEE:master May 10, 2017
@jforissier jforissier deleted the custom-ta-load2 branch May 10, 2017 07:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants