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

Update i.MX ELE support #7256

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions core/arch/arm/plat-imx/conf.mk
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ CFG_TEE_CORE_NB_CORE ?= 2
$(call force,CFG_NXP_SNVS,n)
$(call force,CFG_IMX_OCOTP,n)
CFG_IMX_MU ?= y
CFG_IMX_ELE ?= n
CFG_IMX_ELE ?= y
else ifneq (,$(filter $(PLATFORM_FLAVOR),$(mx93-flavorlist)))
$(call force,CFG_MX93,y)
$(call force,CFG_ARM64_core,y)
Expand All @@ -241,7 +241,7 @@ $(call force,CFG_TZC380,n)
$(call force,CFG_CRYPTO_DRIVER,n)
$(call force,CFG_NXP_CAAM,n)
CFG_IMX_MU ?= y
CFG_IMX_ELE ?= n
CFG_IMX_ELE ?= y
else ifneq (,$(filter $(PLATFORM_FLAVOR),$(mx95-flavorlist)))
$(call force,CFG_MX95,y)
$(call force,CFG_ARM64_core,y)
Expand All @@ -263,7 +263,7 @@ $(call force,CFG_IMX_OCOTP,n)
$(call force,CFG_TZC380,n)
$(call force,CFG_NXP_CAAM,n)
CFG_IMX_MU ?= y
CFG_IMX_ELE ?= n
CFG_IMX_ELE ?= y
else
$(error Unsupported PLATFORM_FLAVOR "$(PLATFORM_FLAVOR)")
endif
Expand Down
90 changes: 80 additions & 10 deletions core/drivers/imx_ele.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@
/*
* Copyright 2022-2023 NXP
*/
#include <crypto/crypto.h>
#include <drivers/imx_mu.h>
#include <initcall.h>
#include <kernel/boot.h>
#include <kernel/delay.h>
#include <kernel/panic.h>
#include <kernel/tee_common_otp.h>
#include <kernel/tee_misc.h>
#include <mm/core_memprot.h>
#include <mm/core_mmu.h>
#include <rng_support.h>
#include <stdint.h>
#include <string_ext.h>
#include <tee/cache.h>
#include <tee_api_defines.h>
#include <tee/tee_cryp_utl.h>
#include <trace.h>
#include <types_ext.h>
#include <utee_types.h>
Expand Down Expand Up @@ -413,10 +418,22 @@ static TEE_Result imx_ele_rng_get_trng_state(void)
return TEE_SUCCESS;
}

unsigned long plat_get_aslr_seed(void)
/*
* Get random data from the EdgeLock Enclave.
*
* This function can be called when the MMU is off or on.
* virtual/physical address translation and cache maintenance
* is performed if needed.
*
* @buffer: data output
* @size: RNG data size
*/
static TEE_Result imx_ele_rng_get_random(void *buffer, size_t size)
{
TEE_Result res = TEE_ERROR_GENERIC;
uint64_t timeout = timeout_init_us(10 * 1000);
paddr_t pa;
Copy link
Contributor

Choose a reason for hiding this comment

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

TEE_Result = TEE_<something>;
paddr_t pa = 0;

void *buf = NULL;

struct rng_get_random_cmd {
uint32_t addr_msb;
uint32_t addr_lsb;
Expand All @@ -429,6 +446,44 @@ unsigned long plat_get_aslr_seed(void)
.header.tag = ELE_REQUEST_TAG,
.header.command = ELE_CMD_RNG_GET,
};

if (!buffer || !size)
return TEE_ERROR_BAD_PARAMETERS;

if (cpu_mmu_enabled()) {
buf = alloc_cache_aligned(size);
if (!buf)
return TEE_ERROR_OUT_OF_MEMORY;

cache_operation(TEE_CACHEFLUSH, buf, size);

pa = virt_to_phys(buf);
} else {
pa = (paddr_t)buffer;
}

reg_pair_from_64((uint64_t)pa, &cmd.addr_msb, &cmd.addr_lsb);

cmd.size = (uint32_t)size;

memcpy(msg.data.u8, &cmd, sizeof(cmd));
Copy link
Contributor

Choose a reason for hiding this comment

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

update_crc(&msg) really not needed?
If that is the case, could you explicitly mention that in the commit message.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This patch is based on [1] which removes this as well, so indeed it doesn't seem to be needed.
However, it also doesn't hurt, so I am considering just to keep it in.

[1] nxp-imx/imx-optee-os@e7dadb8

update_crc(&msg);

res = imx_ele_call(&msg);

if (cpu_mmu_enabled()) {
cache_operation(TEE_CACHEINVALIDATE, buf, size);
if (res == TEE_SUCCESS)
memcpy(buffer, buf, size);
free(buf);
}

return res;
}

unsigned long plat_get_aslr_seed(void)
{
uint64_t timeout = timeout_init_us(10 * 1000);
unsigned long aslr __aligned(CACHELINE_SIZE) = 0;

/*
Expand All @@ -438,9 +493,6 @@ unsigned long plat_get_aslr_seed(void)
*/
assert(!cpu_mmu_enabled());

reg_pair_from_64((uint64_t)&aslr, &cmd.addr_msb, &cmd.addr_lsb);
cmd.size = sizeof(aslr);

/*
* Check the current TRNG state of the ELE. The TRNG must be
* started with a command earlier in the boot to allow the TRNG
Expand All @@ -450,16 +502,34 @@ unsigned long plat_get_aslr_seed(void)
if (timeout_elapsed(timeout))
panic("ELE RNG is busy");

memcpy(msg.data.u8, &cmd, sizeof(cmd));
update_crc(&msg);

res = imx_ele_call(&msg);
if (res)
if (imx_ele_rng_get_random((uint8_t *)&aslr, sizeof(aslr)))
panic("Cannot retrieve random data from ELE");

return aslr;
}

#ifdef CFG_WITH_SOFTWARE_PRNG
void plat_rng_init(void)
Copy link
Contributor

Choose a reason for hiding this comment

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

Should consider whether or not CFG_WITH_SOFTWARE_PRNG is enabled?

{
TEE_Result res = TEE_ERROR_GENERIC;
uint8_t buf[32] = { };

res = imx_ele_rng_get_random(buf, sizeof(buf));
if (res) {
EMSG("Failed to read RNG: %#" PRIx32, res);
panic();
}

res = crypto_rng_init(buf, sizeof(buf));
if (res) {
EMSG("Failed to initialize RNG: %#" PRIx32, res);
panic();
}

IMSG("PRNG seeded from ELE RNG");
}
#endif

int tee_otp_get_die_id(uint8_t *buffer, size_t len)
{
uint32_t session_handle = 0;
Expand Down
Loading