From 9f1cd1b81930f77763ca4adf492b878308fcd434 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Fri, 30 Jun 2023 15:12:54 +0200 Subject: [PATCH 01/43] plat-versal: add support for Versal Net variant Versal Net is a new SoC flavor based on the Versal architecture. This commit introduces it in versal platform code. Signed-off-by: Jeremie Corbier --- core/arch/arm/plat-versal/conf.mk | 26 +++++++++++++--- core/arch/arm/plat-versal/main.c | 2 +- core/arch/arm/plat-versal/platform_config.h | 33 +++++++++++++++++++-- core/drivers/versal_gpio.c | 4 +++ core/drivers/versal_mbox.c | 32 ++++++++++++++++---- 5 files changed, 85 insertions(+), 12 deletions(-) diff --git a/core/arch/arm/plat-versal/conf.mk b/core/arch/arm/plat-versal/conf.mk index 645462d49ba..b9d5d898f66 100644 --- a/core/arch/arm/plat-versal/conf.mk +++ b/core/arch/arm/plat-versal/conf.mk @@ -6,7 +6,11 @@ CFG_MMAP_REGIONS ?= 24 $(call force,CFG_SECURE_TIME_SOURCE_CNTPCT,y) $(call force,CFG_WITH_ARM_TRUSTED_FW,y) +ifeq ($(PLATFORM_FLAVOR),net) +$(call force,CFG_TEE_CORE_NB_CORE,16) +else $(call force,CFG_TEE_CORE_NB_CORE,2) +endif $(call force,CFG_ARM_GICV3,y) $(call force,CFG_PL011,y) $(call force,CFG_GIC,y) @@ -23,10 +27,20 @@ CFG_CORE_DYN_SHM ?= y CFG_WITH_STATS ?= y CFG_ARM64_core ?= y +# Default Versal NET memory allocation +ifeq ($(PLATFORM_FLAVOR),net) +CFG_TZDRAM_START ?= 0x22200000 +CFG_TZDRAM_SIZE ?= 0x2700000 +CFG_SHMEM_START ?= 0x24900000 +CFG_SHMEM_SIZE ?= 0x1800000 + +# Default Versal memory allocation +else CFG_TZDRAM_START ?= 0x60000000 CFG_TZDRAM_SIZE ?= 0x10000000 CFG_SHMEM_START ?= 0x70000000 CFG_SHMEM_SIZE ?= 0x10000000 +endif ifeq ($(CFG_ARM64_core),y) $(call force,CFG_CORE_ARM64_PA_BITS,43) @@ -34,6 +48,10 @@ else $(call force,CFG_ARM32_core,y) endif +CFG_RPMB_FS ?= n +CFG_RPMB_TESTKEY ?= y +CFG_RPMB_WRITE_KEY ?=y + # GPIO CFG_VERSAL_GPIO ?= y @@ -44,7 +62,10 @@ CFG_VERSAL_TRACE_PLM ?= n $(call force, CFG_VERSAL_MBOX,y) # MBOX configuration -CFG_VERSAL_MBOX_IPI_ID ?= 3 +CFG_VERSAL_MBOX_IPI_ID ?= 1 + +# PM driver +CFG_VERSAL_PM ?= y $(call force, CFG_VERSAL_RNG_DRV,y) $(call force, CFG_WITH_SOFTWARE_PRNG,n) @@ -67,9 +88,6 @@ endif # SHA3-384 crypto engine CFG_VERSAL_SHA3_384 ?= y -# PM driver -CFG_VERSAL_PM ?= y - # Physical Unclonable Function CFG_VERSAL_PUF ?= y diff --git a/core/arch/arm/plat-versal/main.c b/core/arch/arm/plat-versal/main.c index b443269bd4a..5b487b3e8ed 100644 --- a/core/arch/arm/plat-versal/main.c +++ b/core/arch/arm/plat-versal/main.c @@ -87,7 +87,7 @@ static TEE_Result platform_banner(void) return TEE_SUCCESS; } -#if defined(CFG_RPMB_FS) +#if defined(CFG_RPMB_FS) && !defined(CFG_RPMB_TESTKEY) bool plat_rpmb_key_is_ready(void) { vaddr_t plm_rtca = (vaddr_t)phys_to_virt(PLM_RTCA, MEM_AREA_IO_SEC, diff --git a/core/arch/arm/plat-versal/platform_config.h b/core/arch/arm/plat-versal/platform_config.h index 8f9b3674be8..61f4bce69bd 100644 --- a/core/arch/arm/plat-versal/platform_config.h +++ b/core/arch/arm/plat-versal/platform_config.h @@ -12,11 +12,11 @@ #define CACHELINE_LEN 64 #define STACK_ALIGNMENT CACHELINE_LEN -#if defined(PLATFORM_FLAVOR_generic) - #define PLM_RTCA 0xF2014000 #define PLM_RTCA_LEN 0x1000 +#if defined(PLATFORM_FLAVOR_generic) + #define GIC_BASE 0xF9000000 #define UART0_BASE 0xFF000000 #define UART1_BASE 0xFF010000 @@ -44,6 +44,35 @@ #define GICD_OFFSET 0 #define GICC_OFFSET 0x40000 +#elif defined(PLATFORM_FLAVOR_net) + +#define GIC_BASE 0xE2000000 +#define UART0_BASE 0xF1920000 +#define UART1_BASE 0xF1930000 + +#define IT_UART0 57 +#define IT_UART1 58 + +#define UART0_CLK_IN_HZ 100000000 +#define UART1_CLK_IN_HZ 100000000 +#define CONSOLE_UART_BASE UART0_BASE +#define IT_CONSOLE_UART IT_UART0 +#define CONSOLE_UART_CLK_IN_HZ UART0_CLK_IN_HZ + +#define DRAM0_BASE 0 +#define DRAM0_SIZE 0x7FF00000 + +#ifdef ARM64 +/* DDR High area base is only available when compiling for 64 bits */ +#define DRAM1_BASE 0x800000000 +#define DRAM1_SIZE 0x800000000 +#define DRAM2_BASE 0xC000000000 +#define DRAM2_SIZE 0x4000000000 +#endif + +#define GICD_OFFSET 0 +#define GICC_OFFSET 0x40000 + #else #error "Unknown platform flavor" #endif diff --git a/core/drivers/versal_gpio.c b/core/drivers/versal_gpio.c index 514ee405b4b..e4147c5f63a 100644 --- a/core/drivers/versal_gpio.c +++ b/core/drivers/versal_gpio.c @@ -56,7 +56,11 @@ static const struct versal_gpio_platform_data versal_gpio_pmc_def = { * 00 - 25, Bank 0 * 26 - 57, Bank 3 */ +#if defined(PLATFORM_FLAVOR_net) +#define VERSAL_GPIO_PS_BASE 0xf19d0000 +#else #define VERSAL_GPIO_PS_BASE 0xff0b0000 +#endif #define VERSAL_GPIO_PS_NR_GPIOS 58 #define VERSAL_GPIO_PS_MAX_BANK 4 diff --git a/core/drivers/versal_mbox.c b/core/drivers/versal_mbox.c index 2f276276e6a..9592b258425 100644 --- a/core/drivers/versal_mbox.c +++ b/core/drivers/versal_mbox.c @@ -17,20 +17,32 @@ /* IPI targets */ #define IPI_ID_PMC 1 #define IPI_ID_0 2 -#define IPI_ID_RPU0 3 -#define IPI_ID_RPU1 4 +#define IPI_ID_1 3 +#define IPI_ID_2 4 #define IPI_ID_3 5 #define IPI_ID_4 6 #define IPI_ID_5 7 /* Buffers */ +#if defined(PLATFORM_FLAVOR_net) +#define IPI_BUFFER_BASEADDR 0xEB3F0000 +#else #define IPI_BUFFER_BASEADDR 0xFF3F0000 +#endif +#define IPI_BUFFER_PMC_BASE (IPI_BUFFER_BASEADDR + 0x200) #define IPI_BUFFER_APU_ID_0_BASE (IPI_BUFFER_BASEADDR + 0x400) +#define IPI_BUFFER_APU_ID_1_BASE (IPI_BUFFER_BASEADDR + 0x600) +#define IPI_BUFFER_APU_ID_2_BASE (IPI_BUFFER_BASEADDR + 0x800) #define IPI_BUFFER_APU_ID_3_BASE (IPI_BUFFER_BASEADDR + 0xA00) #define IPI_BUFFER_APU_ID_4_BASE (IPI_BUFFER_BASEADDR + 0xC00) #define IPI_BUFFER_APU_ID_5_BASE (IPI_BUFFER_BASEADDR + 0xE00) -#define IPI_BUFFER_PMC_BASE (IPI_BUFFER_BASEADDR + 0x200) + +#if defined(PLATFORM_FLAVOR_net) +#define IPI_BUFFER_TARGET_APU_OFFSET 0x1C0 +#else #define IPI_BUFFER_TARGET_APU_OFFSET 0x80 +#endif + #define IPI_BUFFER_TARGET_PMC_OFFSET 0x40 #define IPI_BUFFER_REQ_OFFSET 0x0 #define IPI_BUFFER_RESP_OFFSET 0x20 @@ -61,9 +73,9 @@ static struct versal_ipi { void *rsp; void *req; } ipi = { - .buf = IPI_BUFFER_APU_ID_3_BASE, + .buf = IPI_BUFFER_APU_ID_5_BASE, .rmt = IPI_ID_PMC, - .lcl = IPI_ID_3, + .lcl = IPI_ID_5, }; static const char *const nvm_id[] = { @@ -344,7 +356,17 @@ static TEE_Result versal_mbox_init(void) ipi.buf = IPI_BUFFER_APU_ID_0_BASE; ipi.lcl = IPI_ID_0; break; + case 1: + ipi.buf = IPI_BUFFER_APU_ID_1_BASE; + ipi.lcl = IPI_ID_1; + break; + case 2: + ipi.buf = IPI_BUFFER_APU_ID_2_BASE; + ipi.lcl = IPI_ID_2; + break; case 3: + ipi.buf = IPI_BUFFER_APU_ID_3_BASE; + ipi.lcl = IPI_ID_3; break; case 4: ipi.buf = IPI_BUFFER_APU_ID_4_BASE; From 0b8feb3cea1c087113aa8bf32b6d5abb3dab26f7 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Fri, 20 Oct 2023 17:08:23 +0200 Subject: [PATCH 02/43] drivers: versal: rework mbox driver Make it more generic and still provide a default IPI channel to the PMC for the other drivers. Signed-off-by: Jeremie Corbier --- core/drivers/crypto/versal/authenc.c | 79 ++++-- core/drivers/crypto/versal/ipi.c | 6 +- core/drivers/crypto/versal/rsa.c | 62 +++-- core/drivers/versal_huk.c | 71 +++-- core/drivers/versal_mbox.c | 382 ++++++++++++++++++--------- core/drivers/versal_nvm.c | 2 +- core/drivers/versal_pm.c | 4 +- core/drivers/versal_puf.c | 84 ++++-- core/drivers/versal_sha3_384.c | 17 +- core/include/drivers/versal_mbox.h | 36 ++- 10 files changed, 512 insertions(+), 231 deletions(-) diff --git a/core/drivers/crypto/versal/authenc.c b/core/drivers/crypto/versal/authenc.c index 8776dac5670..76f0ecc1cdc 100644 --- a/core/drivers/crypto/versal/authenc.c +++ b/core/drivers/crypto/versal/authenc.c @@ -343,7 +343,9 @@ static TEE_Result do_init(struct drvcrypt_authenc_init *dinit) } /* Write the key */ - versal_mbox_alloc(dinit->key.length, dinit->key.data, &key); + ret = versal_mbox_alloc(dinit->key.length, dinit->key.data, &key); + if (ret) + return ret; arg.data[arg.dlen++] = key_len; arg.data[arg.dlen++] = engine.key_src; @@ -358,8 +360,12 @@ static TEE_Result do_init(struct drvcrypt_authenc_init *dinit) memset(&arg, 0, sizeof(arg)); /* Send the initialization structure */ - versal_mbox_alloc(sizeof(*init), NULL, &init_buf); - versal_mbox_alloc(dinit->nonce.length, dinit->nonce.data, &nonce); + ret = versal_mbox_alloc(sizeof(*init), NULL, &init_buf); + if (ret) + goto out1; + ret = versal_mbox_alloc(dinit->nonce.length, dinit->nonce.data, &nonce); + if (ret) + goto out2; init = init_buf.buf; init->iv_addr = virt_to_phys(nonce.buf); @@ -400,9 +406,11 @@ static TEE_Result do_init(struct drvcrypt_authenc_init *dinit) return TEE_SUCCESS; error: - free(key.buf); - free(init_buf.buf); - free(nonce.buf); + versal_mbox_free(&nonce); +out2: + versal_mbox_free(&init_buf); +out1: + versal_mbox_free(&key); return ret; } @@ -427,7 +435,9 @@ static TEE_Result do_update_aad(struct drvcrypt_authenc_update_aad *dupdate) if (engine.state == FINALIZED) do_replay(); - versal_mbox_alloc(dupdate->aad.length, dupdate->aad.data, &p); + ret = versal_mbox_alloc(dupdate->aad.length, dupdate->aad.data, &p); + if (ret) + return ret; arg.data[arg.dlen++] = p.len % 16 ? p.alloc_len : p.len; arg.ibuf[0].mem = p; @@ -455,7 +465,7 @@ static TEE_Result do_update_aad(struct drvcrypt_authenc_update_aad *dupdate) return TEE_SUCCESS; error: - free(p.buf); + versal_mbox_free(&p); return ret; } @@ -481,9 +491,15 @@ update_payload(struct drvcrypt_authenc_update_payload *dupdate, bool is_last) return TEE_ERROR_BAD_PARAMETERS; } - versal_mbox_alloc(dupdate->src.length, dupdate->src.data, &p); - versal_mbox_alloc(dupdate->dst.length, NULL, &q); - versal_mbox_alloc(sizeof(*input), NULL, &input_cmd); + ret = versal_mbox_alloc(dupdate->src.length, dupdate->src.data, &p); + if (ret) + return ret; + ret = versal_mbox_alloc(dupdate->dst.length, NULL, &q); + if (ret) + goto out1; + ret = versal_mbox_alloc(sizeof(*input), NULL, &input_cmd); + if (ret) + goto out2; input = input_cmd.buf; input->input_addr = virt_to_phys(p.buf); @@ -505,7 +521,7 @@ update_payload(struct drvcrypt_authenc_update_payload *dupdate, bool is_last) if (versal_crypto_request(id, &arg, &err)) { EMSG("AES_UPDATE_PAYLOAD error: %s", versal_aes_error(err)); ret = TEE_ERROR_GENERIC; - goto out; + goto error; } if (dupdate->dst.data) @@ -515,7 +531,7 @@ update_payload(struct drvcrypt_authenc_update_payload *dupdate, bool is_last) node = calloc(1, sizeof(*node)); if (!node) { ret = TEE_ERROR_OUT_OF_MEMORY; - goto out; + goto error; } node->is_aad = false; @@ -527,10 +543,12 @@ update_payload(struct drvcrypt_authenc_update_payload *dupdate, bool is_last) return TEE_SUCCESS; } -out: - free(p.buf); - free(q.buf); - free(input_cmd.buf); +error: + versal_mbox_free(&input_cmd); +out2: + versal_mbox_free(&q); +out1: + versal_mbox_free(&p); return ret; } @@ -594,7 +612,9 @@ static TEE_Result do_enc_final(struct drvcrypt_authenc_final *dfinal) memcpy(dfinal->dst.data, last.dst.data, dfinal->dst.length); - versal_mbox_alloc(GCM_TAG_LEN, NULL, &p); + ret = versal_mbox_alloc(GCM_TAG_LEN, NULL, &p); + if (ret) + return ret; arg.ibuf[0].mem = p; if (versal_crypto_request(VERSAL_AES_ENCRYPT_FINAL, &arg, &err)) { @@ -606,7 +626,7 @@ static TEE_Result do_enc_final(struct drvcrypt_authenc_final *dfinal) memcpy(dfinal->tag.data, p.buf, GCM_TAG_LEN); dfinal->tag.length = GCM_TAG_LEN; out: - free(p.buf); + versal_mbox_free(&p); if (refcount_val(&engine.refc) > 1) engine.state = FINALIZED; @@ -646,7 +666,10 @@ static TEE_Result do_dec_final(struct drvcrypt_authenc_final *dfinal) if (ret) return ret; - versal_mbox_alloc(dfinal->tag.length, dfinal->tag.data, &p); + ret = versal_mbox_alloc(dfinal->tag.length, dfinal->tag.data, &p); + if (ret) + return ret; + arg.ibuf[0].mem = p; if (versal_crypto_request(VERSAL_AES_DECRYPT_FINAL, &arg, &err)) { @@ -659,7 +682,7 @@ static TEE_Result do_dec_final(struct drvcrypt_authenc_final *dfinal) memcpy(dfinal->tag.data, p.buf, GCM_TAG_LEN); dfinal->tag.length = GCM_TAG_LEN; out: - free(p.buf); + versal_mbox_free(&p); if (refcount_val(&engine.refc) > 1) engine.state = FINALIZED; @@ -687,19 +710,19 @@ static void do_free(void *ctx) release = true; refcount_set(&engine.refc, 1); engine.state = READY; - free(engine.init.init_buf.buf); - free(engine.init.nonce.buf); - free(engine.init.key.buf); + versal_mbox_free(&engine.init.init_buf); + versal_mbox_free(&engine.init.nonce); + versal_mbox_free(&engine.init.key); memset(&engine.init, 0, sizeof(engine.init)); STAILQ_FOREACH_SAFE(node, &engine.replay_list, link, next) { STAILQ_REMOVE(&engine.replay_list, node, versal_node, link); if (node->is_aad) { - free(node->aad.mem.buf); + versal_mbox_free(&node->aad.mem); } else { - free(node->payload.dst.buf); - free(node->payload.src.buf); - free(node->payload.input_cmd.buf); + versal_mbox_free(&node->payload.dst); + versal_mbox_free(&node->payload.src); + versal_mbox_free(&node->payload.input_cmd); } free(node); } diff --git a/core/drivers/crypto/versal/ipi.c b/core/drivers/crypto/versal/ipi.c index ba2b636bdf4..a7cbe686955 100644 --- a/core/drivers/crypto/versal/ipi.c +++ b/core/drivers/crypto/versal/ipi.c @@ -44,7 +44,7 @@ static TEE_Result versal_sha3_request(enum versal_crypto_api id, cmd.ibuf[0].mem = arg->ibuf[0].mem; } - return versal_mbox_notify(&cmd, NULL, NULL); + return versal_mbox_notify_pmc(&cmd, NULL, NULL); } static TEE_Result versal_aes_update_aad_request(enum versal_crypto_api id, @@ -63,7 +63,7 @@ static TEE_Result versal_aes_update_aad_request(enum versal_crypto_api id, cmd.ibuf[0].mem = arg->ibuf[0].mem; - return versal_mbox_notify(&cmd, NULL, NULL); + return versal_mbox_notify_pmc(&cmd, NULL, NULL); } TEE_Result versal_crypto_request(enum versal_crypto_api id, @@ -106,5 +106,5 @@ TEE_Result versal_crypto_request(enum versal_crypto_api id, for (i = 0; i < VERSAL_MAX_IPI_BUF; i++) cmd.ibuf[i].mem = arg->ibuf[i].mem; notify: - return versal_mbox_notify(&cmd, NULL, err); + return versal_mbox_notify_pmc(&cmd, NULL, err); } diff --git a/core/drivers/crypto/versal/rsa.c b/core/drivers/crypto/versal/rsa.c index bbfe979128d..2fd0237ce44 100644 --- a/core/drivers/crypto/versal/rsa.c +++ b/core/drivers/crypto/versal/rsa.c @@ -72,15 +72,25 @@ static TEE_Result do_encrypt(struct drvcrypt_rsa_ed *rsa_data) assert(0); } - versal_mbox_alloc(RSA_MAX_MOD_LEN + RSA_MAX_PUB_EXP_LEN, NULL, &key); + ret = versal_mbox_alloc(RSA_MAX_MOD_LEN + RSA_MAX_PUB_EXP_LEN, + NULL, &key); + if (ret) + return ret; + crypto_bignum_bn2bin_pad(rsa_data->key.n_size, p->n, key.buf); crypto_bignum_bn2bin_pad(RSA_MAX_PUB_EXP_LEN, p->e, (uint8_t *)key.buf + RSA_MAX_MOD_LEN); - versal_mbox_alloc(rsa_data->message.length, rsa_data->message.data, - &msg); - versal_mbox_alloc(rsa_data->cipher.length, NULL, &cipher); - versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf); + ret = versal_mbox_alloc(rsa_data->message.length, + rsa_data->message.data, &msg); + if (ret) + goto out1; + ret = versal_mbox_alloc(rsa_data->cipher.length, NULL, &cipher); + if (ret) + goto out2; + ret = versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf); + if (ret) + goto out3; cmd = cmd_buf.buf; cmd->key_len = rsa_data->key.n_size; @@ -107,10 +117,13 @@ static TEE_Result do_encrypt(struct drvcrypt_rsa_ed *rsa_data) memcpy(rsa_data->cipher.data, cipher.buf, rsa_data->key.n_size); } - free(cipher.buf); - free(cmd); - free(msg.buf); - free(key.buf); + versal_mbox_free(&cmd_buf); +out3: + versal_mbox_free(&cipher); +out2: + versal_mbox_free(&msg); +out1: + versal_mbox_free(&key); return ret; } @@ -161,15 +174,25 @@ static TEE_Result do_decrypt(struct drvcrypt_rsa_ed *rsa_data) assert(0); } - versal_mbox_alloc(RSA_MAX_MOD_LEN + RSA_MAX_PRIV_EXP_LEN, NULL, &key); + ret = versal_mbox_alloc(RSA_MAX_MOD_LEN + RSA_MAX_PRIV_EXP_LEN, + NULL, &key); + if (ret) + return ret; + crypto_bignum_bn2bin_pad(rsa_data->key.n_size, p->n, key.buf); crypto_bignum_bn2bin_pad(rsa_data->key.n_size, p->d, (uint8_t *)key.buf + RSA_MAX_MOD_LEN); - versal_mbox_alloc(rsa_data->cipher.length, rsa_data->cipher.data, - &cipher); - versal_mbox_alloc(rsa_data->message.length, NULL, &msg); - versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf); + ret = versal_mbox_alloc(rsa_data->cipher.length, rsa_data->cipher.data, + &cipher); + if (ret) + goto out1; + ret = versal_mbox_alloc(rsa_data->message.length, NULL, &msg); + if (ret) + goto out2; + ret = versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf); + if (ret) + goto out3; cmd = cmd_buf.buf; cmd->key_len = rsa_data->key.n_size; @@ -192,10 +215,13 @@ static TEE_Result do_decrypt(struct drvcrypt_rsa_ed *rsa_data) memcpy(rsa_data->message.data, msg.buf, rsa_data->key.n_size); } - free(cipher.buf); - free(cmd); - free(key.buf); - free(msg.buf); + versal_mbox_free(&cmd_buf); +out3: + versal_mbox_free(&msg); +out2: + versal_mbox_free(&cipher); +out1: + versal_mbox_free(&key); return ret; } diff --git a/core/drivers/versal_huk.c b/core/drivers/versal_huk.c index 1260c026cb1..251105f3344 100644 --- a/core/drivers/versal_huk.c +++ b/core/drivers/versal_huk.c @@ -186,7 +186,7 @@ static TEE_Result aes_gcm_encrypt(uint8_t *src, size_t src_len, return TEE_ERROR_BAD_PARAMETERS; cmd.data[0] = API_ID(VERSAL_AES_INIT); - if (versal_mbox_notify(&cmd, NULL, NULL)) { + if (versal_mbox_notify_pmc(&cmd, NULL, NULL)) { EMSG("AES_INIT error"); return TEE_ERROR_GENERIC; } @@ -195,18 +195,21 @@ static TEE_Result aes_gcm_encrypt(uint8_t *src, size_t src_len, for (i = 0; i < ARRAY_SIZE(key_data); i++) key_data[i] = TEE_U32_BSWAP(key_data[i]); - versal_mbox_alloc(key_len, key_data, &p); + ret = versal_mbox_alloc(key_len, key_data, &p); + if (ret) + return ret; + cmd.data[0] = API_ID(VERSAL_AES_WRITE_KEY); cmd.data[1] = VERSAL_AES_KEY_SIZE_256; cmd.data[2] = key_id; reg_pair_from_64(virt_to_phys(p.buf), &cmd.data[4], &cmd.data[3]); cmd.ibuf[0].mem = p; - if (versal_mbox_notify(&cmd, NULL, NULL)) { + if (versal_mbox_notify_pmc(&cmd, NULL, NULL)) { EMSG("AES_WRITE_KEY error"); ret = TEE_ERROR_GENERIC; } - free(p.buf); + versal_mbox_free(&p); memset(&cmd, 0, sizeof(cmd)); if (ret) return ret; @@ -215,8 +218,15 @@ static TEE_Result aes_gcm_encrypt(uint8_t *src, size_t src_len, /* Trace indication that it is safe to generate a RPMB key */ IMSG("Using %s HUK", secure ? "Production" : "Development"); - versal_mbox_alloc(sizeof(*init), NULL, &init_buf); - versal_mbox_alloc(nce_len, nce_data, &p); + ret = versal_mbox_alloc(sizeof(*init), NULL, &init_buf); + if (ret) + return ret; + ret = versal_mbox_alloc(nce_len, nce_data, &p); + if (ret) { + versal_mbox_free(&init_buf); + return ret; + } + init = init_buf.buf; init->operation = VERSAL_AES_GCM_ENCRYPT; init->key_len = VERSAL_AES_KEY_SIZE_256; @@ -226,17 +236,20 @@ static TEE_Result aes_gcm_encrypt(uint8_t *src, size_t src_len, reg_pair_from_64(virt_to_phys(init), &cmd.data[2], &cmd.data[1]); cmd.ibuf[0].mem = init_buf; cmd.ibuf[1].mem = p; - if (versal_mbox_notify(&cmd, NULL, NULL)) { + if (versal_mbox_notify_pmc(&cmd, NULL, NULL)) { EMSG("AES_OP_INIT error"); ret = TEE_ERROR_GENERIC; } - free(init); - free(p.buf); + versal_mbox_free(&init_buf); + versal_mbox_free(&p); memset(&cmd, 0, sizeof(cmd)); if (ret) return ret; - versal_mbox_alloc(aad_len, aad_data, &p); + ret = versal_mbox_alloc(aad_len, aad_data, &p); + if (ret) + return ret; + cmd.data[0] = API_ID(VERSAL_AES_UPDATE_AAD); reg_pair_from_64(virt_to_phys(p.buf), &cmd.data[2], &cmd.data[1]); if (p.len % 16) @@ -244,18 +257,30 @@ static TEE_Result aes_gcm_encrypt(uint8_t *src, size_t src_len, else cmd.data[3] = p.len; cmd.ibuf[0].mem = p; - if (versal_mbox_notify(&cmd, NULL, NULL)) { + if (versal_mbox_notify_pmc(&cmd, NULL, NULL)) { EMSG("AES_UPDATE_AAD error"); ret = TEE_ERROR_GENERIC; } - free(p.buf); + versal_mbox_free(&p); memset(&cmd, 0, sizeof(cmd)); if (ret) return ret; - versal_mbox_alloc(sizeof(*input), NULL, &input_cmd); - versal_mbox_alloc(src_len, src, &p); - versal_mbox_alloc(dst_len, NULL, &q); + ret = versal_mbox_alloc(sizeof(*input), NULL, &input_cmd); + if (ret) + return ret; + ret = versal_mbox_alloc(src_len, src, &p); + if (ret) { + versal_mbox_free(&input_cmd); + return ret; + } + ret = versal_mbox_alloc(dst_len, NULL, &q); + if (ret) { + versal_mbox_free(&input_cmd); + versal_mbox_free(&p); + return ret; + } + input = input_cmd.buf; input->input_addr = virt_to_phys(p.buf); input->input_len = p.len; @@ -266,26 +291,28 @@ static TEE_Result aes_gcm_encrypt(uint8_t *src, size_t src_len, cmd.ibuf[0].mem = input_cmd; cmd.ibuf[1].mem = p; cmd.ibuf[2].mem = q; - if (versal_mbox_notify(&cmd, NULL, NULL)) { + if (versal_mbox_notify_pmc(&cmd, NULL, NULL)) { EMSG("AES_UPDATE_PAYLOAD error"); ret = TEE_ERROR_GENERIC; } memcpy(dst, q.buf, dst_len); - free(input); - free(p.buf); - free(q.buf); + versal_mbox_free(&input_cmd); + versal_mbox_free(&p); + versal_mbox_free(&q); memset(&cmd, 0, sizeof(cmd)); if (ret) return ret; - versal_mbox_alloc(16, NULL, &p); + ret = versal_mbox_alloc(16, NULL, &p); + if (ret) + return ret; cmd.data[0] = API_ID(VERSAL_AES_ENCRYPT_FINAL); reg_pair_from_64(virt_to_phys(p.buf), &cmd.data[2], &cmd.data[1]); - if (versal_mbox_notify(&cmd, NULL, NULL)) { + if (versal_mbox_notify_pmc(&cmd, NULL, NULL)) { EMSG("AES_ENCRYPT_FINAL error"); ret = TEE_ERROR_GENERIC; } - free(p.buf); + versal_mbox_free(&p); memzero_explicit(&cmd, sizeof(cmd)); return ret; diff --git a/core/drivers/versal_mbox.c b/core/drivers/versal_mbox.c index 9592b258425..97370cc806f 100644 --- a/core/drivers/versal_mbox.c +++ b/core/drivers/versal_mbox.c @@ -2,9 +2,13 @@ /* * Copyright (C) 2022 Foundries.io Ltd * Jorge Ramirez-Ortiz + * + * Copyright (C) 2023 ProvenRun S.A.S */ +#include #include +#include #include #include #include @@ -12,24 +16,42 @@ #include #include "drivers/versal_mbox.h" -#define PM_SIP_SVC 0xc2000000 - -/* IPI targets */ -#define IPI_ID_PMC 1 -#define IPI_ID_0 2 -#define IPI_ID_1 3 -#define IPI_ID_2 4 -#define IPI_ID_3 5 -#define IPI_ID_4 6 -#define IPI_ID_5 7 - -/* Buffers */ #if defined(PLATFORM_FLAVOR_net) +#define IPI_REGS_BASEADDR 0xEB300000 #define IPI_BUFFER_BASEADDR 0xEB3F0000 #else +#define IPI_REGS_BASEADDR 0xFF300000 #define IPI_BUFFER_BASEADDR 0xFF3F0000 #endif -#define IPI_BUFFER_PMC_BASE (IPI_BUFFER_BASEADDR + 0x200) + +#define IPI_SIZE 0x10000 + +#define IPI_TRIG_OFFSET 0x00 +#define IPI_OBR_OFFSET 0x04 +#define IPI_ISR_OFFSET 0x10 +#define IPI_IMR_OFFSET 0x14 +#define IPI_IER_OFFSET 0x18 +#define IPI_IDR_OFFSET 0x1C + +#define IPI_PMC_TRIG_BIT BIT(1) +#define IPI0_TRIG_BIT BIT(2) +#define IPI1_TRIG_BIT BIT(3) +#define IPI2_TRIG_BIT BIT(4) +#define IPI3_TRIG_BIT BIT(5) +#define IPI4_TRIG_BIT BIT(6) +#define IPI5_TRIG_BIT BIT(7) + +/* Interrupt Config Registers */ +#define IPI_PMC_REG_BASE (IPI_REGS_BASEADDR + 0x20000) +#define IPI0_REG_BASE (IPI_REGS_BASEADDR + 0x30000) +#define IPI1_REG_BASE (IPI_REGS_BASEADDR + 0x40000) +#define IPI2_REG_BASE (IPI_REGS_BASEADDR + 0x50000) +#define IPI3_REG_BASE (IPI_REGS_BASEADDR + 0x60000) +#define IPI4_REG_BASE (IPI_REGS_BASEADDR + 0x70000) +#define IPI5_REG_BASE (IPI_REGS_BASEADDR + 0x80000) + +/* Buffers */ +#define IPI_BUFFER_PMC_BASE (IPI_BUFFER_BASEADDR + 0x200) #define IPI_BUFFER_APU_ID_0_BASE (IPI_BUFFER_BASEADDR + 0x400) #define IPI_BUFFER_APU_ID_1_BASE (IPI_BUFFER_BASEADDR + 0x600) #define IPI_BUFFER_APU_ID_2_BASE (IPI_BUFFER_BASEADDR + 0x800) @@ -37,46 +59,84 @@ #define IPI_BUFFER_APU_ID_4_BASE (IPI_BUFFER_BASEADDR + 0xC00) #define IPI_BUFFER_APU_ID_5_BASE (IPI_BUFFER_BASEADDR + 0xE00) -#if defined(PLATFORM_FLAVOR_net) -#define IPI_BUFFER_TARGET_APU_OFFSET 0x1C0 -#else -#define IPI_BUFFER_TARGET_APU_OFFSET 0x80 -#endif - #define IPI_BUFFER_TARGET_PMC_OFFSET 0x40 +#define IPI_BUFFER_TARGET_ID_0_OFFSET 0x80 +#define IPI_BUFFER_TARGET_ID_1_OFFSET 0xC0 +#define IPI_BUFFER_TARGET_ID_2_OFFSET 0x100 +#define IPI_BUFFER_TARGET_ID_3_OFFSET 0x140 +#define IPI_BUFFER_TARGET_ID_4_OFFSET 0x180 +#define IPI_BUFFER_TARGET_ID_5_OFFSET 0x1C0 + #define IPI_BUFFER_REQ_OFFSET 0x0 #define IPI_BUFFER_RESP_OFFSET 0x20 -#define IPI_BUFFER_LOCAL_OFFSET IPI_BUFFER_TARGET_APU_OFFSET -#define IPI_BUFFER_REMOTE_OFFSET IPI_BUFFER_TARGET_PMC_OFFSET - -#define IPI_BLOCK 1 -#define IPI_NON_BLOCK 0 - -/* Mailbox api */ -enum versal_ipi_api_id { - IPI_MAILBOX_OPEN = 0x1000, - IPI_MAILBOX_RELEASE, - IPI_MAILBOX_STATUS_ENQUIRY, - IPI_MAILBOX_NOTIFY, - IPI_MAILBOX_ACK, - IPI_MAILBOX_ENABLE_IRQ, - IPI_MAILBOX_DISABLE_IRQ +static const struct versal_ipi_config { + uint32_t ipi_bit_mask; + uint32_t ipi_reg_base; + uint32_t ipi_buf_base; + uint32_t ipi_remote_offset; +} versal_ipi_table[] = { + /* PMC IPI */ + [IPI_ID_PMC] = { + .ipi_bit_mask = IPI_PMC_TRIG_BIT, + .ipi_reg_base = IPI_PMC_REG_BASE, + .ipi_buf_base = IPI_BUFFER_PMC_BASE, + .ipi_remote_offset = IPI_BUFFER_TARGET_PMC_OFFSET, + }, + + /* IPI0 IPI */ + [IPI_ID_0] = { + .ipi_bit_mask = IPI0_TRIG_BIT, + .ipi_reg_base = IPI0_REG_BASE, + .ipi_buf_base = IPI_BUFFER_APU_ID_0_BASE, + .ipi_remote_offset = IPI_BUFFER_TARGET_ID_0_OFFSET, + }, + + /* IPI1 IPI */ + [IPI_ID_1] = { + .ipi_bit_mask = IPI1_TRIG_BIT, + .ipi_reg_base = IPI1_REG_BASE, + .ipi_buf_base = IPI_BUFFER_APU_ID_1_BASE, + .ipi_remote_offset = IPI_BUFFER_TARGET_ID_1_OFFSET, + }, + + /* IPI2 IPI */ + [IPI_ID_2] = { + .ipi_bit_mask = IPI2_TRIG_BIT, + .ipi_reg_base = IPI2_REG_BASE, + .ipi_buf_base = IPI_BUFFER_APU_ID_2_BASE, + .ipi_remote_offset = IPI_BUFFER_TARGET_ID_2_OFFSET, + }, + + /* IPI3 IPI */ + [IPI_ID_3] = { + .ipi_bit_mask = IPI3_TRIG_BIT, + .ipi_reg_base = IPI3_REG_BASE, + .ipi_buf_base = IPI_BUFFER_APU_ID_3_BASE, + .ipi_remote_offset = IPI_BUFFER_TARGET_ID_3_OFFSET, + }, + + /* IPI4 IPI */ + [IPI_ID_4] = { + .ipi_bit_mask = IPI4_TRIG_BIT, + .ipi_reg_base = IPI4_REG_BASE, + .ipi_buf_base = IPI_BUFFER_APU_ID_4_BASE, + .ipi_remote_offset = IPI_BUFFER_TARGET_ID_4_OFFSET, + }, + + /* IPI5 IPI */ + [IPI_ID_5] = { + .ipi_bit_mask = IPI5_TRIG_BIT, + .ipi_reg_base = IPI5_REG_BASE, + .ipi_buf_base = IPI_BUFFER_APU_ID_5_BASE, + .ipi_remote_offset = IPI_BUFFER_TARGET_ID_5_OFFSET, + }, }; -static struct versal_ipi { - uint32_t lcl; - const uint32_t rmt; - paddr_t buf; - /* Exclusive access to the IPI shared buffer */ - struct mutex lock; - void *rsp; - void *req; -} ipi = { - .buf = IPI_BUFFER_APU_ID_5_BASE, - .rmt = IPI_ID_PMC, - .lcl = IPI_ID_5, -}; +#define IPI_REG_BASE(I) (versal_ipi_table[I].ipi_reg_base) +#define IPI_BIT_MASK(I) (versal_ipi_table[I].ipi_bit_mask) +#define IPI_BUF_BASE(I) (versal_ipi_table[I].ipi_buf_base) +#define IPI_REMOTE_OFFSET(I) (versal_ipi_table[I].ipi_remote_offset) static const char *const nvm_id[] = { [0] = "API_FEATURES", @@ -85,6 +145,39 @@ static const char *const nvm_id[] = { [3] = "BBRAM_WRITE_USER_DATA", [4] = "BBRAM_READ_USER_DATA", [5] = "BBRAM_LOCK_WRITE_USER_DATA", +#ifdef PLATFORM_FLAVOR_net + [6] = "BBRAM_WRITE_AES_KEY_FROM_PLOAD", + [7] = "EFUSE_WRITE_AES_KEY", + [8] = "EFUSE_WRITE_AES_KEY_FROM_PLOAD", + [9] = "EFUSE_WRITE_PPK_HASH", + [10] = "EFUSE_WRITE_PPK_HASH_FROM_PLOAD", + [11] = "EFUSE_WRITE_IV", + [12] = "EFUSE_WRITE_IV_FROM_PLOAD", + [13] = "EFUSE_WRITE_GLITCH_CONFIG", + [14] = "EFUSE_WRITE_DEC_ONLY", + [15] = "EFUSE_WRITE_REVOCATION_ID", + [16] = "EFUSE_WRITE_OFFCHIP_REVOKE_ID", + [17] = "EFUSE_WRITE_MISC_CTRL_BITS", + [18] = "EFUSE_WRITE_SEC_CTRL_BITS", + [19] = "EFUSE_WRITE_MISC1_CTRL_BITS", + [20] = "EFUSE_WRITE_BOOT_ENV_CTRL_BITS", + [21] = "EFUSE_WRITE_FIPS_INFO", + [22] = "EFUSE_WRITE_UDS_FROM_PLOAD", + [23] = "EFUSE_WRITE_DME_KEY_FROM_PLOAD", + [24] = "EFUSE_WRITE_DME_REVOKE", + [25] = "EFUSE_WRITE_PLM_UPDATE", + [26] = "EFUSE_WRITE_BOOT_MODE_DISABLE", + [27] = "EFUSE_WRITE_CRC", + [28] = "EFUSE_WRITE_DME_MODE", + [29] = "EFUSE_WRITE_PUF_HD_FROM_PLOAD", + [30] = "EFUSE_WRITE_PUF", + [31] = "EFUSE_WRITE_ROM_RSVD", + [32] = "EFUSE_WRITE_PUF_CTRL_BITS", + [33] = "EFUSE_READ_CACHE", + [34] = "EFUSE_RELOAD_N_PRGM_PROT_BITS", + [35] = "EFUSE_INVALID", + +#else [6] = "EFUSE_WRITE", [7] = "EFUSE_WRITE_PUF", [8] = "EFUSE_PUF_USER_FUSE_WRITE", @@ -103,6 +196,7 @@ static const char *const nvm_id[] = { [21] = "EFUSE_READ_PUF_USER_FUSES", [22] = "EFUSE_READ_PUF", [23] = "EFUSE_INVALID", +#endif }; static const char *const crypto_id[] = { @@ -188,31 +282,14 @@ static void versal_mbox_call_trace(uint32_t call) val ? val : "Invalid"); }; -static TEE_Result mbox_call(enum versal_ipi_api_id id, uint32_t blocking_call) -{ - struct thread_smc_args args = { - .a0 = PM_SIP_SVC | id, - .a1 = reg_pair_to_64(0, ipi.lcl), - .a2 = reg_pair_to_64(0, ipi.rmt), - .a3 = reg_pair_to_64(0, blocking_call), - }; - - thread_smccc(&args); - - /* Give the PLM time to access the console */ - if (IS_ENABLED(CFG_VERSAL_TRACE_PLM)) - mdelay(500); - - if (args.a0) - return TEE_ERROR_GENERIC; - - return TEE_SUCCESS; -} - -static TEE_Result versal_mbox_write_req(struct versal_ipi_cmd *cmd) +static TEE_Result versal_mbox_write_req(struct versal_ipi *ipi, + struct versal_ipi_cmd *cmd) { size_t i = 0; + assert(ipi); + assert(cmd); + for (i = 0; i < VERSAL_MAX_IPI_BUF; i++) { if (!cmd->ibuf[i].mem.buf) continue; @@ -234,30 +311,34 @@ static TEE_Result versal_mbox_write_req(struct versal_ipi_cmd *cmd) cmd->ibuf[i].mem.alloc_len); } - memcpy(ipi.req, cmd->data, sizeof(cmd->data)); + memcpy(ipi->req, cmd->data, sizeof(cmd->data)); /* Cache operation on the IPI buffer is safe */ - cache_operation(TEE_CACHEFLUSH, ipi.req, sizeof(cmd->data)); + cache_operation(TEE_CACHEFLUSH, ipi->req, sizeof(cmd->data)); return TEE_SUCCESS; } -static TEE_Result versal_mbox_read_rsp(struct versal_ipi_cmd *cmd, +static TEE_Result versal_mbox_read_rsp(struct versal_ipi *ipi, + struct versal_ipi_cmd *cmd, struct versal_ipi_cmd *rsp, uint32_t *status) { size_t i = 0; + assert(ipi); + assert(cmd); + /* Cache operation on the IPI buffer is safe */ - cache_operation(TEE_CACHEINVALIDATE, ipi.rsp, sizeof(rsp->data)); + cache_operation(TEE_CACHEINVALIDATE, ipi->rsp, sizeof(rsp->data)); - *status = *(uint32_t *)ipi.rsp; + *status = *(uint32_t *)ipi->rsp; if (*status) return TEE_ERROR_GENERIC; if (rsp) - memcpy(rsp->data, ipi.rsp, sizeof(rsp->data)); + memcpy(rsp->data, ipi->rsp, sizeof(rsp->data)); for (i = 0; i < VERSAL_MAX_IPI_BUF; i++) { if (!cmd->ibuf[i].mem.buf) @@ -284,12 +365,57 @@ static TEE_Result versal_mbox_read_rsp(struct versal_ipi_cmd *cmd, return TEE_SUCCESS; } +TEE_Result versal_mbox_open(uint32_t local, uint32_t remote, + struct versal_ipi *ipi) +{ + assert(ipi); + + ipi->regs = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, + IPI_REG_BASE(local), + IPI_SIZE); + + ipi->req = core_mmu_add_mapping(MEM_AREA_IO_SEC, + IPI_BUF_BASE(local) + + IPI_REMOTE_OFFSET(remote) + + IPI_BUFFER_REQ_OFFSET, + sizeof(struct versal_ipi_cmd)); + + ipi->rsp = core_mmu_add_mapping(MEM_AREA_IO_SEC, + IPI_BUF_BASE(local) + + IPI_REMOTE_OFFSET(remote) + + IPI_BUFFER_RESP_OFFSET, + sizeof(struct versal_ipi_cmd)); + + ipi->lcl = local; + ipi->rmt = remote; + + if (!ipi->regs || !ipi->req || !ipi->rsp) + panic(); + + mutex_init(&ipi->lock); + + io_write32(ipi->regs + IPI_IDR_OFFSET, IPI_BIT_MASK(remote)); + io_write32(ipi->regs + IPI_ISR_OFFSET, IPI_BIT_MASK(remote)); + + return TEE_SUCCESS; +} + +TEE_Result versal_mbox_close(struct versal_ipi *ipi) +{ + assert(ipi); + + io_write32(ipi->regs + IPI_IDR_OFFSET, + IPI_BIT_MASK(ipi->rmt)); + + return TEE_SUCCESS; +} + TEE_Result versal_mbox_alloc(size_t len, const void *init, struct versal_mbox_mem *mem) { mem->buf = memalign(CACHELINE_LEN, ROUNDUP(len, CACHELINE_LEN)); if (!mem->buf) - panic(); + return TEE_ERROR_OUT_OF_MEMORY; memset(mem->buf, 0, ROUNDUP(len, CACHELINE_LEN)); @@ -302,99 +428,109 @@ TEE_Result versal_mbox_alloc(size_t len, const void *init, return TEE_SUCCESS; } -TEE_Result versal_mbox_notify(struct versal_ipi_cmd *cmd, +TEE_Result versal_mbox_free(struct versal_mbox_mem *mem) +{ + if (!mem) + return TEE_ERROR_BAD_PARAMETERS; + + free(mem->buf); + return TEE_SUCCESS; +} + +TEE_Result versal_mbox_notify(struct versal_ipi *ipi, + struct versal_ipi_cmd *cmd, struct versal_ipi_cmd *rsp, uint32_t *err) { TEE_Result ret = TEE_SUCCESS; - uint32_t remote_status = 0; + uint32_t status = 0; - mutex_lock(&ipi.lock); + mutex_lock(&ipi->lock); - ret = versal_mbox_write_req(cmd); + ret = versal_mbox_write_req(ipi, cmd); if (ret) { EMSG("Can't write the request command"); goto out; } - if (IS_ENABLED(CFG_VERSAL_TRACE_MBOX)) - versal_mbox_call_trace(cmd->data[0]); + /* Trigger interrupt to remote */ + io_write32(ipi->regs + IPI_TRIG_OFFSET, + IPI_BIT_MASK(ipi->rmt)); - ret = mbox_call(IPI_MAILBOX_NOTIFY, IPI_BLOCK); - if (ret) { - EMSG("IPI error"); - goto out; - } + /* Wait for remote to acknowledge the interrupt */ + do { + status = io_read32(ipi->regs + IPI_OBR_OFFSET); + } while (status & IPI_BIT_MASK(ipi->rmt)); - ret = versal_mbox_read_rsp(cmd, rsp, &remote_status); + ret = versal_mbox_read_rsp(ipi, cmd, rsp, &status); if (ret) EMSG("Can't read the remote response"); - if (remote_status) { + if (status) { if (err) - *err = remote_status; + *err = status; + + ret = TEE_ERROR_GENERIC; + } +out: + mutex_unlock(&ipi->lock); + + return ret; +} + +static struct versal_ipi ipi_pmc; + +TEE_Result versal_mbox_notify_pmc(struct versal_ipi_cmd *cmd, + struct versal_ipi_cmd *rsp, uint32_t *err) +{ + TEE_Result ret; + + if (IS_ENABLED(CFG_VERSAL_TRACE_MBOX)) + versal_mbox_call_trace(cmd->data[0]); + + ret = versal_mbox_notify(&ipi_pmc, cmd, rsp, err); + + if (ret != TEE_SUCCESS && err) { /* * Check the remote code (FSBL repository) in xplmi_status.h * and the relevant service error (ie, xsecure_error.h) for * detailed information. */ DMSG("PLM: plm status = 0x%" PRIx32 ", lib_status = 0x%" PRIx32, - (remote_status & 0xFFFF0000) >> 16, - (remote_status & 0x0000FFFF)); - - ret = TEE_ERROR_GENERIC; + (*err & 0xFFFF0000) >> 16, + (*err & 0x0000FFFF)); } -out: - mutex_unlock(&ipi.lock); return ret; } static TEE_Result versal_mbox_init(void) { + uint32_t lcl; + switch (CFG_VERSAL_MBOX_IPI_ID) { case 0: - ipi.buf = IPI_BUFFER_APU_ID_0_BASE; - ipi.lcl = IPI_ID_0; + lcl = IPI_ID_0; break; case 1: - ipi.buf = IPI_BUFFER_APU_ID_1_BASE; - ipi.lcl = IPI_ID_1; + lcl = IPI_ID_1; break; case 2: - ipi.buf = IPI_BUFFER_APU_ID_2_BASE; - ipi.lcl = IPI_ID_2; + lcl = IPI_ID_2; break; case 3: - ipi.buf = IPI_BUFFER_APU_ID_3_BASE; - ipi.lcl = IPI_ID_3; + lcl = IPI_ID_3; break; case 4: - ipi.buf = IPI_BUFFER_APU_ID_4_BASE; - ipi.lcl = IPI_ID_4; + lcl = IPI_ID_4; break; case 5: - ipi.buf = IPI_BUFFER_APU_ID_5_BASE; - ipi.lcl = IPI_ID_5; + lcl = IPI_ID_5; break; default: EMSG("Invalid IPI requested"); return TEE_ERROR_GENERIC; } - ipi.req = core_mmu_add_mapping(MEM_AREA_RAM_SEC, - ipi.buf + IPI_BUFFER_REMOTE_OFFSET + - IPI_BUFFER_REQ_OFFSET, - sizeof(struct versal_ipi_cmd)); - - ipi.rsp = core_mmu_add_mapping(MEM_AREA_RAM_SEC, - ipi.buf + IPI_BUFFER_REMOTE_OFFSET + - IPI_BUFFER_RESP_OFFSET, - sizeof(struct versal_ipi_cmd)); - if (!ipi.req || !ipi.rsp) - panic(); - - mutex_init(&ipi.lock); - - return mbox_call(IPI_MAILBOX_OPEN, IPI_BLOCK); + return versal_mbox_open(lcl, IPI_ID_PMC, &ipi_pmc); } early_init(versal_mbox_init); diff --git a/core/drivers/versal_nvm.c b/core/drivers/versal_nvm.c index b17ae632d29..657dfa93494 100644 --- a/core/drivers/versal_nvm.c +++ b/core/drivers/versal_nvm.c @@ -151,7 +151,7 @@ static TEE_Result efuse_req(enum versal_nvm_api_id efuse, if (ret) return ret; - ret = versal_mbox_notify(&cmd, NULL, NULL); + ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); if (ret) EMSG("Mailbox error"); diff --git a/core/drivers/versal_pm.c b/core/drivers/versal_pm.c index 84b1cbec5a3..b1ac7128000 100644 --- a/core/drivers/versal_pm.c +++ b/core/drivers/versal_pm.c @@ -140,7 +140,7 @@ TEE_Result versal_write_fpga(paddr_t pa) cmd.data[1] = PDI_SRC_DDR; reg_pair_from_64(pa, &cmd.data[2], &cmd.data[3]); - if (versal_mbox_notify(&cmd, NULL, NULL)) + if (versal_mbox_notify_pmc(&cmd, NULL, NULL)) return TEE_ERROR_GENERIC; return TEE_SUCCESS; @@ -199,7 +199,7 @@ static TEE_Result versal_check_pm_abi(void) } cmd.data[0] = PM_API_ID(PM_GET_API_VERSION); - if (versal_mbox_notify(&cmd, &rsp, NULL)) + if (versal_mbox_notify_pmc(&cmd, &rsp, NULL)) return TEE_ERROR_GENERIC; major = rsp.data[1] & 0xFFFF; diff --git a/core/drivers/versal_puf.c b/core/drivers/versal_puf.c index d65cbe1965d..47706f91fd9 100644 --- a/core/drivers/versal_puf.c +++ b/core/drivers/versal_puf.c @@ -112,13 +112,23 @@ TEE_Result versal_puf_register(struct versal_puf_data *buf, TEE_Result ret = TEE_SUCCESS; uint32_t err = 0; - versal_mbox_alloc(sizeof(buf->puf_id), buf->puf_id, &puf_id_addr); - versal_mbox_alloc(sizeof(buf->chash), &buf->chash, &hash_addr); - versal_mbox_alloc(sizeof(buf->aux), &buf->aux, &aux_addr); - versal_mbox_alloc(sizeof(buf->efuse_syn_data), buf->efuse_syn_data, - &efuse_syn_data_addr); - versal_mbox_alloc(sizeof(buf->syndrome_data), buf->syndrome_data, - &syndrome_data_addr); + ret = versal_mbox_alloc(sizeof(buf->puf_id), buf->puf_id, &puf_id_addr); + if (ret) + return ret; + ret = versal_mbox_alloc(sizeof(buf->chash), &buf->chash, &hash_addr); + if (ret) + goto out1; + ret = versal_mbox_alloc(sizeof(buf->aux), &buf->aux, &aux_addr); + if (ret) + goto out2; + ret = versal_mbox_alloc(sizeof(buf->efuse_syn_data), + buf->efuse_syn_data, &efuse_syn_data_addr); + if (ret) + goto out3; + ret = versal_mbox_alloc(sizeof(buf->syndrome_data), buf->syndrome_data, + &syndrome_data_addr); + if (ret) + goto out4; arg.ibuf[0].mem = request; arg.ibuf[1].mem = syndrome_data_addr; @@ -143,7 +153,7 @@ TEE_Result versal_puf_register(struct versal_puf_data *buf, reg_pair_from_64(virt_to_phys(arg.ibuf[0].mem.buf), &arg.data[2], &arg.data[1]); - if (versal_mbox_notify(&arg, NULL, &err)) { + if (versal_mbox_notify_pmc(&arg, NULL, &err)) { EMSG("Versal, failed to register the PUF [%s]", versal_puf_error(err)); @@ -159,11 +169,15 @@ TEE_Result versal_puf_register(struct versal_puf_data *buf, memcpy(buf->syndrome_data, syndrome_data_addr.buf, sizeof(buf->syndrome_data)); - free(syndrome_data_addr.buf); - free(hash_addr.buf); - free(aux_addr.buf); - free(puf_id_addr.buf); - free(efuse_syn_data_addr.buf); + versal_mbox_free(&syndrome_data_addr); +out4: + versal_mbox_free(&efuse_syn_data_addr); +out3: + versal_mbox_free(&aux_addr); +out2: + versal_mbox_free(&hash_addr); +out1: + versal_mbox_free(&puf_id_addr); return ret; } @@ -192,13 +206,23 @@ TEE_Result versal_puf_regenerate(struct versal_puf_data *buf, TEE_Result ret = TEE_SUCCESS; uint32_t err = 0; - versal_mbox_alloc(sizeof(buf->puf_id), buf->puf_id, &puf_id_addr); - versal_mbox_alloc(sizeof(buf->chash), &buf->chash, &hash_addr); - versal_mbox_alloc(sizeof(buf->aux), &buf->aux, &aux_addr); - versal_mbox_alloc(sizeof(buf->efuse_syn_data), buf->efuse_syn_data, - &efuse_syn_data_addr); - versal_mbox_alloc(sizeof(buf->syndrome_data), buf->syndrome_data, - &syndrome_data_addr); + ret = versal_mbox_alloc(sizeof(buf->puf_id), buf->puf_id, &puf_id_addr); + if (ret) + return ret; + ret = versal_mbox_alloc(sizeof(buf->chash), &buf->chash, &hash_addr); + if (ret) + goto out1; + ret = versal_mbox_alloc(sizeof(buf->aux), &buf->aux, &aux_addr); + if (ret) + goto out2; + ret = versal_mbox_alloc(sizeof(buf->efuse_syn_data), + buf->efuse_syn_data, &efuse_syn_data_addr); + if (ret) + goto out3; + ret = versal_mbox_alloc(sizeof(buf->syndrome_data), buf->syndrome_data, + &syndrome_data_addr); + if (ret) + goto out4; arg.ibuf[0].mem = request; arg.ibuf[1].mem = syndrome_data_addr; @@ -223,7 +247,7 @@ TEE_Result versal_puf_regenerate(struct versal_puf_data *buf, reg_pair_from_64(virt_to_phys(arg.ibuf[0].mem.buf), &arg.data[2], &arg.data[1]); - if (versal_mbox_notify(&arg, NULL, &err)) { + if (versal_mbox_notify_pmc(&arg, NULL, &err)) { EMSG("Versal, failed to regenerate the PUF [%s]", versal_puf_error(err)); @@ -233,11 +257,15 @@ TEE_Result versal_puf_regenerate(struct versal_puf_data *buf, /* Return the updated PUF_ID */ memcpy(buf->puf_id, puf_id_addr.buf, sizeof(buf->puf_id)); - free(syndrome_data_addr.buf); - free(hash_addr.buf); - free(aux_addr.buf); - free(puf_id_addr.buf); - free(efuse_syn_data_addr.buf); + versal_mbox_free(&syndrome_data_addr); +out4: + versal_mbox_free(&efuse_syn_data_addr); +out3: + versal_mbox_free(&aux_addr); +out2: + versal_mbox_free(&hash_addr); +out1: + versal_mbox_free(&puf_id_addr); return ret; } @@ -253,7 +281,7 @@ TEE_Result versal_puf_clear_id(void) arg.data[0] = PUF_API_ID(VERSAL_PUF_CLEAR_ID); - if (versal_mbox_notify(&arg, NULL, NULL)) { + if (versal_mbox_notify_pmc(&arg, NULL, NULL)) { EMSG("Versal, failed to clear the PUF_ID"); return TEE_ERROR_GENERIC; @@ -270,7 +298,7 @@ TEE_Result versal_puf_check_api(enum versal_puf_api id) arg.data[0] = PUF_API_ID(VERSAL_PUF_API_FEATURES); arg.data[1] = id; - if (versal_mbox_notify(&arg, NULL, NULL)) + if (versal_mbox_notify_pmc(&arg, NULL, NULL)) return TEE_ERROR_GENERIC; return TEE_SUCCESS; diff --git a/core/drivers/versal_sha3_384.c b/core/drivers/versal_sha3_384.c index 3a46db00114..52ded36042a 100644 --- a/core/drivers/versal_sha3_384.c +++ b/core/drivers/versal_sha3_384.c @@ -28,15 +28,20 @@ static TEE_Result input_plaintext(const uint8_t *src, size_t src_len) while (src_len && !ret) { len = MIN(src_len, SMALL_PAGE_SIZE); src_len -= len; - versal_mbox_alloc(len, src + i * SMALL_PAGE_SIZE, &p); + ret = versal_mbox_alloc(len, src + i * SMALL_PAGE_SIZE, &p); + if (ret) + return ret; arg.data[0] = first | VERSAL_SHA3_384_NEXT_PACKET | len; arg.ibuf[0].mem = p; ret = versal_crypto_request(VERSAL_SHA3_UPDATE, &arg, NULL); - if (ret) + if (ret) { EMSG("VERSAL_SHA3_UPDATE [%ld, len = %zu]", i, len); + versal_mbox_free(&p); + break; + } - free(p.buf); + versal_mbox_free(&p); first = 0; i++; } @@ -50,7 +55,9 @@ static TEE_Result get_ciphertext(uint8_t *dst, size_t dst_len) struct versal_mbox_mem p = { }; TEE_Result ret = TEE_SUCCESS; - versal_mbox_alloc(TEE_SHA384_HASH_SIZE, NULL, &p); + ret = versal_mbox_alloc(TEE_SHA384_HASH_SIZE, NULL, &p); + if (ret) + return ret; arg.ibuf[0].mem = p; ret = versal_crypto_request(VERSAL_SHA3_UPDATE, &arg, NULL); @@ -59,7 +66,7 @@ static TEE_Result get_ciphertext(uint8_t *dst, size_t dst_len) else EMSG("VERSAL_SHA3_UPDATE final"); - free(p.buf); + versal_mbox_free(&p); return ret; } diff --git a/core/include/drivers/versal_mbox.h b/core/include/drivers/versal_mbox.h index 04e0c092f6b..6067d53c10c 100644 --- a/core/include/drivers/versal_mbox.h +++ b/core/include/drivers/versal_mbox.h @@ -6,6 +6,7 @@ #define __DRIVERS_VERSAL_MBOX_H #include +#include #include #include @@ -27,8 +28,41 @@ struct versal_ipi_cmd { struct versal_ipi_buf ibuf[VERSAL_MAX_IPI_BUF]; }; -TEE_Result versal_mbox_notify(struct versal_ipi_cmd *cmd, +struct versal_ipi { + uint32_t lcl; + uint32_t rmt; + + /* Exclusive access to the IPI shared buffer */ + struct mutex lock; + + vaddr_t regs; + + void *rsp; + void *req; +}; + +/* IPI IDs */ +#define IPI_ID_PMC 1 +#define IPI_ID_0 2 +#define IPI_ID_1 3 +#define IPI_ID_2 4 +#define IPI_ID_3 5 +#define IPI_ID_4 6 +#define IPI_ID_5 7 + +TEE_Result versal_mbox_open(uint32_t local, uint32_t remote, + struct versal_ipi *ipi); +TEE_Result versal_mbox_close(struct versal_ipi *ipi); + +TEE_Result versal_mbox_notify(struct versal_ipi *ipi, + struct versal_ipi_cmd *cmd, struct versal_ipi_cmd *rsp, uint32_t *err); + +TEE_Result versal_mbox_notify_pmc(struct versal_ipi_cmd *cmd, + struct versal_ipi_cmd *rsp, uint32_t *err); + TEE_Result versal_mbox_alloc(size_t len, const void *init, struct versal_mbox_mem *mem); +TEE_Result versal_mbox_free(struct versal_mbox_mem *mem); + #endif /* __DRIVERS_VERSAL_MBOX_H */ From e0f5515906c6c3f2deff0c35f0cd04d8d99fae52 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Fri, 8 Dec 2023 10:24:49 +0100 Subject: [PATCH 03/43] drivers: versal: use PLM for generic RNG operations PLM HWRNG driver cannot provide more than 32 bytes of entropy at a time. Split bigger requests into 32 bytes chunks. Signed-off-by: Jeremie Corbier --- core/arch/arm/plat-versal/conf.mk | 5 +++ core/drivers/versal_trng.c | 73 +++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/core/arch/arm/plat-versal/conf.mk b/core/arch/arm/plat-versal/conf.mk index b9d5d898f66..762c7ae4acb 100644 --- a/core/arch/arm/plat-versal/conf.mk +++ b/core/arch/arm/plat-versal/conf.mk @@ -67,12 +67,17 @@ CFG_VERSAL_MBOX_IPI_ID ?= 1 # PM driver CFG_VERSAL_PM ?= y +# TRNG driver $(call force, CFG_VERSAL_RNG_DRV,y) $(call force, CFG_WITH_SOFTWARE_PRNG,n) +ifeq ($(PLATFORM_FLAVOR),net) +$(call force,CFG_VERSAL_RNG_PLM,y) +else # TRNG configuration CFG_VERSAL_TRNG_SEED_LIFE ?= 3 CFG_VERSAL_TRNG_DF_MUL ?= 2 +endif # eFuse and BBRAM driver $(call force, CFG_VERSAL_NVM,y) diff --git a/core/drivers/versal_trng.c b/core/drivers/versal_trng.c index 792c46a25e3..63e894c9344 100644 --- a/core/drivers/versal_trng.c +++ b/core/drivers/versal_trng.c @@ -58,13 +58,16 @@ #include #include #include +#include #include #include #include #include #include #include +#include +#ifndef CFG_VERSAL_RNG_PLM #define TRNG_BASE 0xF1230000 #define TRNG_SIZE 0x10000 @@ -1147,3 +1150,73 @@ static TEE_Result trng_hrng_mode_init(void) } driver_init(trng_hrng_mode_init); + +#else +#define SEC_MODULE_SHIFT 8 +#define SEC_MODULE_ID 5 + +#define CRYPTO_API_ID(__x) ((SEC_MODULE_ID << SEC_MODULE_SHIFT) | (__x)) + +#define VERSAL_TRNG_GENERATE 22 + +#define VERSAL_TRNG_SEC_STRENGTH_IN_BYTES 32 + +TEE_Result hw_get_random_bytes(void *buf, size_t len) +{ + uint32_t a = 0; + uint32_t b = 0; + struct versal_ipi_cmd cmd = { }; + struct versal_mbox_mem p = { }; + TEE_Result ret = TEE_SUCCESS; + uint32_t status = 0; + uint32_t offset = 0; + + ret = versal_mbox_alloc(len, NULL, &p); + if (ret) + return ret; + + cmd.data[0] = CRYPTO_API_ID(VERSAL_TRNG_GENERATE); + cmd.ibuf[0].mem = p; + + while (len > VERSAL_TRNG_SEC_STRENGTH_IN_BYTES) { + reg_pair_from_64(virt_to_phys(p.buf) + offset, &b, &a); + + cmd.data[1] = a; + cmd.data[2] = b; + cmd.data[3] = (uint32_t)VERSAL_TRNG_SEC_STRENGTH_IN_BYTES; + + ret = versal_mbox_notify_pmc(&cmd, NULL, &status); + if (!ret) { + memcpy((uint8_t *)buf + offset, + (uint8_t *)p.buf + offset, + VERSAL_TRNG_SEC_STRENGTH_IN_BYTES); + } else { + DMSG("Getting randomness returned 0x%" PRIx32, status); + goto out; + } + + offset += VERSAL_TRNG_SEC_STRENGTH_IN_BYTES; + len -= VERSAL_TRNG_SEC_STRENGTH_IN_BYTES; + } + + reg_pair_from_64(virt_to_phys(p.buf) + offset, &b, &a); + + cmd.data[1] = a; + cmd.data[2] = b; + cmd.data[3] = (uint32_t)len; + + ret = versal_mbox_notify_pmc(&cmd, NULL, &status); + if (!ret) + memcpy((uint8_t *)buf + offset, (uint8_t *)p.buf + offset, len); + else + DMSG("Getting randomness returned 0x%" PRIx32, status); + +out: + versal_mbox_free(&p); + return ret; +} + +void plat_rng_init(void) +{ +} +#endif From 5f23b2b8c85d492fa58fad008cc1fccf6dbc142d Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 25 Oct 2023 18:17:40 +0200 Subject: [PATCH 04/43] drivers: versal: PKI engine driver for Versal Net The Versal Net variant comes with a dedicated PKI engine. This driver makes use of the engine for ECDSA P-256, P-384, and P-521 sign, verify and key generation operations. Signed-off-by: Jeremie Corbier --- core/arch/arm/plat-versal/conf.mk | 13 +- core/drivers/crypto/versal/ecc.c | 377 ++------ core/drivers/crypto/versal/ecc_mbox.c | 328 +++++++ core/drivers/crypto/versal/include/ecc.h | 38 + .../crypto/versal/pki/ecc_pki_engine.c | 838 ++++++++++++++++++ core/drivers/crypto/versal/pki/ecc_pki_kat.c | 477 ++++++++++ core/drivers/crypto/versal/pki/sub.mk | 4 + core/drivers/crypto/versal/sub.mk | 5 + core/drivers/versal_trng.c | 171 ++-- core/include/drivers/versal_trng.h | 95 ++ 10 files changed, 1942 insertions(+), 404 deletions(-) create mode 100644 core/drivers/crypto/versal/ecc_mbox.c create mode 100644 core/drivers/crypto/versal/include/ecc.h create mode 100644 core/drivers/crypto/versal/pki/ecc_pki_engine.c create mode 100644 core/drivers/crypto/versal/pki/ecc_pki_kat.c create mode 100644 core/drivers/crypto/versal/pki/sub.mk create mode 100644 core/include/drivers/versal_trng.h diff --git a/core/arch/arm/plat-versal/conf.mk b/core/arch/arm/plat-versal/conf.mk index 762c7ae4acb..77205da6d2b 100644 --- a/core/arch/arm/plat-versal/conf.mk +++ b/core/arch/arm/plat-versal/conf.mk @@ -73,11 +73,11 @@ $(call force, CFG_WITH_SOFTWARE_PRNG,n) ifeq ($(PLATFORM_FLAVOR),net) $(call force,CFG_VERSAL_RNG_PLM,y) -else +endif + # TRNG configuration CFG_VERSAL_TRNG_SEED_LIFE ?= 3 CFG_VERSAL_TRNG_DF_MUL ?= 2 -endif # eFuse and BBRAM driver $(call force, CFG_VERSAL_NVM,y) @@ -88,6 +88,15 @@ ifeq ($(CFG_VERSAL_CRYPTO_DRIVER),y) # Disable Fault Mitigation: triggers false positives due to # the driver's software fallback operations - need further work CFG_FAULT_MITIGATION ?= n + +ifeq ($(PLATFORM_FLAVOR),net) +CFG_VERSAL_PKI_DRIVER ?= y + +ifeq ($(CFG_VERSAL_PKI_DRIVER),y) +CFG_VERSAL_PKI_COUNTER_MEASURES ?= n +CFG_VERSAL_PKI_PWCT ?= y +endif +endif endif # SHA3-384 crypto engine diff --git a/core/drivers/crypto/versal/ecc.c b/core/drivers/crypto/versal/ecc.c index 64a919e218f..e2dde64dd1f 100644 --- a/core/drivers/crypto/versal/ecc.c +++ b/core/drivers/crypto/versal/ecc.c @@ -8,82 +8,31 @@ #include #include #include -#include +#include #include +#include #include +#include #include #include #include #include - -/* AMD/Xilinx Versal's Known Answer Tests */ -#define XSECURE_ECDSA_KAT_NIST_P384 0 -#define XSECURE_ECDSA_KAT_NIST_P521 2 +#include +#include /* Software based ECDSA operations */ static const struct crypto_ecc_keypair_ops *pair_ops; static const struct crypto_ecc_public_ops *pub_ops; -enum versal_ecc_err { - KAT_KEY_NOTVALID_ERROR = 0xC0, - KAT_FAILED_ERROR, - NON_SUPPORTED_CURVE, - KEY_ZERO, - KEY_WRONG_ORDER, - KEY_NOT_ON_CURVE, - BAD_SIGN, - GEN_SIGN_INCORRECT_HASH_LEN, - VER_SIGN_INCORRECT_HASH_LEN, - GEN_SIGN_BAD_RAND_NUM, - GEN_KEY_ERR, - INVALID_PARAM, - VER_SIGN_R_ZERO, - VER_SIGN_S_ZERO, - VER_SIGN_R_ORDER_ERROR, - VER_SIGN_S_ORDER_ERROR, - KAT_INVLD_CRV_ERROR, -}; - -#define VERSAL_ECC_ERROR(m) { .error = (m), .name = TO_STR(m) } - -static const char *versal_ecc_error(uint8_t err) -{ - struct { - enum versal_ecc_err error; - const char *name; - } elist[] = { - VERSAL_ECC_ERROR(KAT_KEY_NOTVALID_ERROR), - VERSAL_ECC_ERROR(KAT_FAILED_ERROR), - VERSAL_ECC_ERROR(NON_SUPPORTED_CURVE), - VERSAL_ECC_ERROR(KEY_ZERO), - VERSAL_ECC_ERROR(KEY_WRONG_ORDER), - VERSAL_ECC_ERROR(KEY_NOT_ON_CURVE), - VERSAL_ECC_ERROR(BAD_SIGN), - VERSAL_ECC_ERROR(GEN_SIGN_INCORRECT_HASH_LEN), - VERSAL_ECC_ERROR(VER_SIGN_INCORRECT_HASH_LEN), - VERSAL_ECC_ERROR(GEN_SIGN_BAD_RAND_NUM), - VERSAL_ECC_ERROR(GEN_KEY_ERR), - VERSAL_ECC_ERROR(INVALID_PARAM), - VERSAL_ECC_ERROR(VER_SIGN_R_ZERO), - VERSAL_ECC_ERROR(VER_SIGN_S_ZERO), - VERSAL_ECC_ERROR(VER_SIGN_R_ORDER_ERROR), - VERSAL_ECC_ERROR(VER_SIGN_S_ORDER_ERROR), - VERSAL_ECC_ERROR(KAT_INVLD_CRV_ERROR), - }; - - if (err <= KAT_INVLD_CRV_ERROR && err >= KAT_KEY_NOTVALID_ERROR) { - if (elist[err - KAT_KEY_NOTVALID_ERROR].name) - return elist[err - KAT_KEY_NOTVALID_ERROR].name; - - return "Invalid"; - } - - return "Unknown"; -} - -static TEE_Result ecc_get_key_size(uint32_t curve, size_t *bytes, size_t *bits) +TEE_Result versal_ecc_get_key_size(uint32_t curve, size_t *bytes, size_t *bits) { switch (curve) { +#if defined(CFG_VERSAL_PKI_DRIVER) + case TEE_ECC_CURVE_NIST_P256: + *bits = 256; + *bytes = 32; + break; +#endif case TEE_ECC_CURVE_NIST_P384: *bits = 384; *bytes = 48; @@ -99,7 +48,7 @@ static TEE_Result ecc_get_key_size(uint32_t curve, size_t *bytes, size_t *bits) return TEE_SUCCESS; } -static void memcpy_swp(uint8_t *to, const uint8_t *from, size_t len) +void memcpy_swp(uint8_t *to, const uint8_t *from, size_t len) { size_t i = 0; @@ -107,217 +56,51 @@ static void memcpy_swp(uint8_t *to, const uint8_t *from, size_t len) to[i] = from[len - 1 - i]; } -static void crypto_bignum_bn2bin_eswap(uint32_t curve, - struct bignum *from, uint8_t *to) +void crypto_bignum_bn2bin_eswap(uint32_t curve, struct bignum *from, + uint8_t *to) { uint8_t pad[66] = { 0 }; size_t len = crypto_bignum_num_bytes(from); size_t bytes = 0; size_t bits = 0; - if (ecc_get_key_size(curve, &bytes, &bits)) + if (versal_ecc_get_key_size(curve, &bytes, &bits)) panic(); crypto_bignum_bn2bin(from, pad + bytes - len); memcpy_swp(to, pad, bytes); } -static TEE_Result ecc_prepare_msg(uint32_t algo, const uint8_t *msg, - size_t msg_len, struct versal_mbox_mem *p) +void crypto_bignum_bin2bn_eswap(const uint8_t *from, size_t sz, + struct bignum *to) { - uint8_t swp[TEE_SHA512_HASH_SIZE + 2] = { 0 }; - size_t len = 0; + uint8_t pad[66] = { 0 }; + memcpy_swp(pad, from, sz); + crypto_bignum_bin2bn(pad, sz, to); +} + +TEE_Result versal_ecc_prepare_msg(uint32_t algo, const uint8_t *msg, + size_t msg_len, size_t *len, uint8_t *buf) +{ if (msg_len > TEE_SHA512_HASH_SIZE + 2) return TEE_ERROR_BAD_PARAMETERS; if (algo == TEE_ALG_ECDSA_SHA384) - len = TEE_SHA384_HASH_SIZE; + *len = TEE_SHA384_HASH_SIZE; else if (algo == TEE_ALG_ECDSA_SHA512) - len = TEE_SHA512_HASH_SIZE + 2; + *len = TEE_SHA512_HASH_SIZE + 2; +#if defined(PLATFORM_FLAVOR_net) + else if (algo == TEE_ALG_ECDSA_SHA256) + *len = TEE_SHA256_HASH_SIZE; +#endif else return TEE_ERROR_NOT_SUPPORTED; /* Swap the hash/message and pad if necessary */ - memcpy_swp(swp, msg, msg_len); - return versal_mbox_alloc(len, swp, p); -} - -static TEE_Result verify(uint32_t algo, struct ecc_public_key *key, - const uint8_t *msg, size_t msg_len, - const uint8_t *sig, size_t sig_len) -{ - TEE_Result ret = TEE_SUCCESS; - struct versal_ecc_verify_param *cmd = NULL; - struct versal_cmd_args arg = { }; - struct versal_mbox_mem x = { }; - struct versal_mbox_mem s = { }; - struct versal_mbox_mem p = { }; - struct versal_mbox_mem cmd_buf = { }; - uint32_t err = 0; - size_t bytes = 0; - size_t bits = 0; - - if (sig_len % 2) - return TEE_ERROR_SIGNATURE_INVALID; - - ret = ecc_get_key_size(key->curve, &bytes, &bits); - if (ret != TEE_SUCCESS) { - if (ret != TEE_ERROR_NOT_SUPPORTED) - return ret; - - /* Fallback to software */ - return pub_ops->verify(algo, key, msg, msg_len, sig, sig_len); - } - - ret = ecc_prepare_msg(algo, msg, msg_len, &p); - if (ret) - return ret; - - versal_mbox_alloc(bytes * 2, NULL, &x); - crypto_bignum_bn2bin_eswap(key->curve, key->x, x.buf); - crypto_bignum_bn2bin_eswap(key->curve, key->y, - (uint8_t *)x.buf + bytes); - /* Validate the public key for the curve */ - arg.data[0] = key->curve; - arg.dlen = 1; - arg.ibuf[0].mem = x; - if (versal_crypto_request(VERSAL_ELLIPTIC_VALIDATE_PUBLIC_KEY, - &arg, &err)) { - EMSG("Versal ECC: %s", versal_ecc_error(err)); - ret = TEE_ERROR_GENERIC; - goto out; - } - memset(&arg, 0, sizeof(arg)); - - versal_mbox_alloc(sig_len, NULL, &s); - /* Swap the {R,S} components */ - memcpy_swp(s.buf, sig, sig_len / 2); - memcpy_swp((uint8_t *)s.buf + sig_len / 2, sig + sig_len / 2, - sig_len / 2); - versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf); - - cmd = cmd_buf.buf; - cmd->signature_addr = virt_to_phys(s.buf); - cmd->pub_key_addr = virt_to_phys(x.buf); - cmd->hash_addr = virt_to_phys(p.buf); - cmd->hash_len = p.len; - cmd->curve = key->curve; - - arg.ibuf[0].mem = cmd_buf; - arg.ibuf[1].mem = p; - arg.ibuf[1].only_cache = true; - arg.ibuf[2].mem = x; - arg.ibuf[3].mem = s; - - if (versal_crypto_request(VERSAL_ELLIPTIC_VERIFY_SIGN, &arg, &err)) { - EMSG("Versal ECC: %s", versal_ecc_error(err)); - ret = TEE_ERROR_GENERIC; - } -out: - free(p.buf); - free(x.buf); - free(s.buf); - free(cmd); - - return ret; -} - -static TEE_Result sign(uint32_t algo, struct ecc_keypair *key, - const uint8_t *msg, size_t msg_len, - uint8_t *sig, size_t *sig_len) -{ - struct versal_ecc_sign_param *cmd = NULL; - struct versal_mbox_mem cmd_buf = { }; - struct ecc_keypair ephemeral = { }; - struct versal_cmd_args arg = { }; - struct versal_mbox_mem p = { }; - struct versal_mbox_mem k = { }; - struct versal_mbox_mem d = { }; - struct versal_mbox_mem s = { }; - TEE_Result ret = TEE_SUCCESS; - uint32_t err = 0; - size_t bytes = 0; - size_t bits = 0; - - ret = ecc_get_key_size(key->curve, &bytes, &bits); - if (ret != TEE_SUCCESS) { - if (ret != TEE_ERROR_NOT_SUPPORTED) - return ret; - - /* Fallback to software */ - return pair_ops->sign(algo, key, msg, msg_len, sig, sig_len); - } - - /* Hash and update the length */ - ret = ecc_prepare_msg(algo, msg, msg_len, &p); - if (ret) - return ret; - - /* Ephemeral private key */ - ret = drvcrypt_asym_alloc_ecc_keypair(&ephemeral, - TEE_TYPE_ECDSA_KEYPAIR, bits); - if (ret) { - EMSG("Versal, can't allocate the ephemeral key"); - return ret; - } - - ephemeral.curve = key->curve; - ret = crypto_acipher_gen_ecc_key(&ephemeral, bits); - if (ret) { - EMSG("Versal, can't generate the ephemeral key"); - return ret; - } + memcpy_swp(buf, msg, msg_len); - versal_mbox_alloc(bytes, NULL, &k); - crypto_bignum_bn2bin_eswap(key->curve, ephemeral.d, k.buf); - crypto_bignum_free(&ephemeral.d); - crypto_bignum_free(&ephemeral.x); - crypto_bignum_free(&ephemeral.y); - - /* Private key*/ - versal_mbox_alloc(bytes, NULL, &d); - crypto_bignum_bn2bin_eswap(key->curve, key->d, d.buf); - - /* Signature */ - versal_mbox_alloc(*sig_len, NULL, &s); - - /* IPI command */ - versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf); - - cmd = cmd_buf.buf; - cmd->priv_key_addr = virt_to_phys(d.buf); - cmd->epriv_key_addr = virt_to_phys(k.buf); - cmd->hash_addr = virt_to_phys(p.buf); - cmd->hash_len = p.len; - cmd->curve = key->curve; - - arg.ibuf[0].mem = cmd_buf; - arg.ibuf[1].mem = s; - arg.ibuf[2].mem = k; - arg.ibuf[3].mem = d; - arg.ibuf[4].mem = p; - - if (versal_crypto_request(VERSAL_ELLIPTIC_GENERATE_SIGN, &arg, &err)) { - EMSG("Versal ECC: %s", versal_ecc_error(err)); - ret = TEE_ERROR_GENERIC; - goto out; - } - - *sig_len = 2 * bytes; - - /* Swap the {R,S} components */ - memcpy_swp(sig, s.buf, *sig_len / 2); - memcpy_swp(sig + *sig_len / 2, (uint8_t *)s.buf + *sig_len / 2, - *sig_len / 2); -out: - free(cmd); - free(k.buf); - free(p.buf); - free(s.buf); - free(d.buf); - - return ret; + return TEE_SUCCESS; } static TEE_Result shared_secret(struct ecc_keypair *private_key, @@ -338,32 +121,63 @@ static TEE_Result do_shared_secret(struct drvcrypt_secret_data *sdata) static TEE_Result do_sign(struct drvcrypt_sign_data *sdata) { - return sign(sdata->algo, - sdata->key, - sdata->message.data, - sdata->message.length, - sdata->signature.data, - &sdata->signature.length); + TEE_Result ret; + + ret = versal_ecc_sign(sdata->algo, + sdata->key, + sdata->message.data, + sdata->message.length, + sdata->signature.data, + &sdata->signature.length); + + if (ret == TEE_ERROR_NOT_SUPPORTED) + /* Fallback to software */ + return pair_ops->sign(sdata->algo, sdata->key, + sdata->message.data, + sdata->message.length, + sdata->signature.data, + &sdata->signature.length); + + return ret; } static TEE_Result do_verify(struct drvcrypt_sign_data *sdata) { - return verify(sdata->algo, - sdata->key, - sdata->message.data, - sdata->message.length, - sdata->signature.data, - sdata->signature.length); + TEE_Result ret; + + ret = versal_ecc_verify(sdata->algo, + sdata->key, + sdata->message.data, + sdata->message.length, + sdata->signature.data, + sdata->signature.length); + + if (ret == TEE_ERROR_NOT_SUPPORTED) + /* Fallback to software */ + return pub_ops->verify(sdata->algo, sdata->key, + sdata->message.data, + sdata->message.length, + sdata->signature.data, + sdata->signature.length); + + return ret; } static TEE_Result do_gen_keypair(struct ecc_keypair *s, size_t size_bits) { - /* - * Versal requires little endian so need to memcpy_swp on Versal IP ops. - * We chose not to do it here because some tests might be using - * their own keys - */ - return pair_ops->generate(s, size_bits); + TEE_Result ret = versal_ecc_gen_keypair(s); + + if (ret == TEE_ERROR_NOT_SUPPORTED) + return pair_ops->generate(s, size_bits); + +#ifdef CFG_VERSAL_PKI_PWCT + /* Perform a pairwise consistencty test on the generated key pair */ + ret = versal_ecc_keypair_pwct(s); + if (ret) + DMSG("Pair-wise consistency test failed (0x%" PRIx32 ")", ret); +#endif + + return ret; } static TEE_Result do_alloc_keypair(struct ecc_keypair *s, @@ -431,24 +245,19 @@ static struct drvcrypt_ecc driver_ecc = { static TEE_Result ecc_init(void) { - struct versal_cmd_args arg = { }; - uint32_t err = 0; - - arg.data[arg.dlen++] = XSECURE_ECDSA_KAT_NIST_P384; - if (versal_crypto_request(VERSAL_ELLIPTIC_KAT, &arg, &err)) { - EMSG("Versal KAG NIST_P384: %s", versal_ecc_error(err)); - return TEE_ERROR_GENERIC; - } + TEE_Result ret; - /* Clean previous request */ - arg.dlen = 0; + /* HW initialization if needed */ + ret = versal_ecc_hw_init(); + if (ret != TEE_SUCCESS) + return ret; - arg.data[arg.dlen++] = XSECURE_ECDSA_KAT_NIST_P521; - if (versal_crypto_request(VERSAL_ELLIPTIC_KAT, &arg, &err)) { - EMSG("Versal KAG NIST_P521 %s", versal_ecc_error(err)); - return TEE_ERROR_GENERIC; - } + /* Run KAT self-tests */ + ret = versal_ecc_kat(); + if (ret != TEE_SUCCESS) + return ret; + /* Fall back to software implementations if needed */ pair_ops = crypto_asym_get_ecc_keypair_ops(TEE_TYPE_ECDSA_KEYPAIR); if (!pair_ops) return TEE_ERROR_GENERIC; diff --git a/core/drivers/crypto/versal/ecc_mbox.c b/core/drivers/crypto/versal/ecc_mbox.c new file mode 100644 index 00000000000..aff70cd12d7 --- /dev/null +++ b/core/drivers/crypto/versal/ecc_mbox.c @@ -0,0 +1,328 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (C) Foundries Ltd. 2022. + * Author: Jorge Ramirez + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum versal_ecc_err { + KAT_KEY_NOTVALID_ERROR = 0xC0, + KAT_FAILED_ERROR, + NON_SUPPORTED_CURVE, + KEY_ZERO, + KEY_WRONG_ORDER, + KEY_NOT_ON_CURVE, + BAD_SIGN, + GEN_SIGN_INCORRECT_HASH_LEN, + VER_SIGN_INCORRECT_HASH_LEN, + GEN_SIGN_BAD_RAND_NUM, + GEN_KEY_ERR, + INVALID_PARAM, + VER_SIGN_R_ZERO, + VER_SIGN_S_ZERO, + VER_SIGN_R_ORDER_ERROR, + VER_SIGN_S_ORDER_ERROR, + KAT_INVLD_CRV_ERROR, +}; + +#define VERSAL_ECC_ERROR(m) { .error = (m), .name = TO_STR(m) } + +static const char *versal_ecc_error(uint8_t err) +{ + struct { + enum versal_ecc_err error; + const char *name; + } elist[] = { + VERSAL_ECC_ERROR(KAT_KEY_NOTVALID_ERROR), + VERSAL_ECC_ERROR(KAT_FAILED_ERROR), + VERSAL_ECC_ERROR(NON_SUPPORTED_CURVE), + VERSAL_ECC_ERROR(KEY_ZERO), + VERSAL_ECC_ERROR(KEY_WRONG_ORDER), + VERSAL_ECC_ERROR(KEY_NOT_ON_CURVE), + VERSAL_ECC_ERROR(BAD_SIGN), + VERSAL_ECC_ERROR(GEN_SIGN_INCORRECT_HASH_LEN), + VERSAL_ECC_ERROR(VER_SIGN_INCORRECT_HASH_LEN), + VERSAL_ECC_ERROR(GEN_SIGN_BAD_RAND_NUM), + VERSAL_ECC_ERROR(GEN_KEY_ERR), + VERSAL_ECC_ERROR(INVALID_PARAM), + VERSAL_ECC_ERROR(VER_SIGN_R_ZERO), + VERSAL_ECC_ERROR(VER_SIGN_S_ZERO), + VERSAL_ECC_ERROR(VER_SIGN_R_ORDER_ERROR), + VERSAL_ECC_ERROR(VER_SIGN_S_ORDER_ERROR), + VERSAL_ECC_ERROR(KAT_INVLD_CRV_ERROR), + }; + + if (err <= KAT_INVLD_CRV_ERROR && err >= KAT_KEY_NOTVALID_ERROR) { + if (elist[err - KAT_KEY_NOTVALID_ERROR].name) + return elist[err - KAT_KEY_NOTVALID_ERROR].name; + + return "Invalid"; + } + + return "Unknown"; +} + +TEE_Result versal_ecc_verify(uint32_t algo, struct ecc_public_key *key, + const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len) +{ + TEE_Result ret = TEE_SUCCESS; + uint8_t swp[TEE_SHA512_HASH_SIZE + 2] = { 0 }; + size_t len = 0; + struct versal_ecc_verify_param *cmd = NULL; + struct versal_cmd_args arg = { }; + struct versal_mbox_mem x = { }; + struct versal_mbox_mem s = { }; + struct versal_mbox_mem p = { }; + struct versal_mbox_mem cmd_buf = { }; + uint32_t err = 0; + size_t bytes = 0; + size_t bits = 0; + + if (sig_len % 2) + return TEE_ERROR_SIGNATURE_INVALID; + + ret = versal_ecc_get_key_size(key->curve, &bytes, &bits); + if (ret) + return ret; + + ret = versal_ecc_prepare_msg(algo, msg, msg_len, &len, (uint8_t *)&swp); + if (ret) + return ret; + + ret = versal_mbox_alloc(len, swp, &p); + if (ret) + return ret; + + ret = versal_mbox_alloc(bytes * 2, NULL, &x); + if (ret) + goto out1; + + crypto_bignum_bn2bin_eswap(key->curve, key->x, x.buf); + crypto_bignum_bn2bin_eswap(key->curve, key->y, + (uint8_t *)x.buf + bytes); + /* Validate the public key for the curve */ + arg.data[0] = key->curve; + arg.dlen = 1; + arg.ibuf[0].mem = x; + if (versal_crypto_request(VERSAL_ELLIPTIC_VALIDATE_PUBLIC_KEY, + &arg, &err)) { + EMSG("Versal ECC: %s", versal_ecc_error(err)); + ret = TEE_ERROR_GENERIC; + goto out2; + } + memset(&arg, 0, sizeof(arg)); + + ret = versal_mbox_alloc(sig_len, NULL, &s); + if (ret) + goto out2; + + /* Swap the {R,S} components */ + memcpy_swp(s.buf, sig, sig_len / 2); + memcpy_swp((uint8_t *)s.buf + sig_len / 2, sig + sig_len / 2, + sig_len / 2); + + ret = versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf); + if (ret) + goto out3; + + cmd = cmd_buf.buf; + cmd->signature_addr = virt_to_phys(s.buf); + cmd->pub_key_addr = virt_to_phys(x.buf); + cmd->hash_addr = virt_to_phys(p.buf); + cmd->hash_len = p.len; + cmd->curve = key->curve; + + arg.ibuf[0].mem = cmd_buf; + arg.ibuf[1].mem = p; + arg.ibuf[1].only_cache = true; + arg.ibuf[2].mem = x; + arg.ibuf[3].mem = s; + + if (versal_crypto_request(VERSAL_ELLIPTIC_VERIFY_SIGN, &arg, &err)) { + EMSG("Versal ECC: %s", versal_ecc_error(err)); + ret = TEE_ERROR_GENERIC; + } + + versal_mbox_free(&cmd_buf); +out3: + versal_mbox_free(&s); +out2: + versal_mbox_free(&x); +out1: + versal_mbox_free(&p); + + return ret; +} + +TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len) +{ + uint8_t swp[TEE_SHA512_HASH_SIZE + 2] = { 0 }; + size_t len = 0; + struct versal_ecc_sign_param *cmd = NULL; + struct versal_mbox_mem cmd_buf = { }; + struct ecc_keypair ephemeral = { }; + struct versal_cmd_args arg = { }; + struct versal_mbox_mem p = { }; + struct versal_mbox_mem k = { }; + struct versal_mbox_mem d = { }; + struct versal_mbox_mem s = { }; + TEE_Result ret = TEE_SUCCESS; + uint32_t err = 0; + size_t bytes = 0; + size_t bits = 0; + + ret = versal_ecc_get_key_size(key->curve, &bytes, &bits); + if (ret) + return ret; + + /* Hash and update the length */ + ret = versal_ecc_prepare_msg(algo, msg, msg_len, &len, (uint8_t *)&swp); + if (ret) + return ret; + ret = versal_mbox_alloc(len, swp, &p); + if (ret) + return ret; + + /* Ephemeral private key */ + ret = drvcrypt_asym_alloc_ecc_keypair(&ephemeral, + TEE_TYPE_ECDSA_KEYPAIR, bits); + if (ret) { + EMSG("Versal, can't allocate the ephemeral key"); + versal_mbox_free(&p); + return ret; + } + + ephemeral.curve = key->curve; + ret = crypto_acipher_gen_ecc_key(&ephemeral, bits); + if (ret) { + EMSG("Versal, can't generate the ephemeral key"); + versal_mbox_free(&p); + return ret; + } + + ret = versal_mbox_alloc(bytes, NULL, &k); + if (ret) + goto out1; + + crypto_bignum_bn2bin_eswap(key->curve, ephemeral.d, k.buf); + crypto_bignum_free(&ephemeral.d); + crypto_bignum_free(&ephemeral.x); + crypto_bignum_free(&ephemeral.y); + + /* Private key*/ + ret = versal_mbox_alloc(bytes, NULL, &d); + if (ret) + goto out2; + crypto_bignum_bn2bin_eswap(key->curve, key->d, d.buf); + + /* Signature */ + ret = versal_mbox_alloc(*sig_len, NULL, &s); + if (ret) + goto out3; + + /* IPI command */ + ret = versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf); + if (ret) + goto out4; + + cmd = cmd_buf.buf; + cmd->priv_key_addr = virt_to_phys(d.buf); + cmd->epriv_key_addr = virt_to_phys(k.buf); + cmd->hash_addr = virt_to_phys(p.buf); + cmd->hash_len = p.len; + cmd->curve = key->curve; + + arg.ibuf[0].mem = cmd_buf; + arg.ibuf[1].mem = s; + arg.ibuf[2].mem = k; + arg.ibuf[3].mem = d; + arg.ibuf[4].mem = p; + + if (versal_crypto_request(VERSAL_ELLIPTIC_GENERATE_SIGN, &arg, &err)) { + EMSG("Versal ECC: %s", versal_ecc_error(err)); + ret = TEE_ERROR_GENERIC; + goto error; + } + + *sig_len = 2 * bytes; + + /* Swap the {R,S} components */ + memcpy_swp(sig, s.buf, *sig_len / 2); + memcpy_swp(sig + *sig_len / 2, (uint8_t *)s.buf + *sig_len / 2, + *sig_len / 2); +error: + versal_mbox_free(&cmd_buf); +out4: + versal_mbox_free(&s); +out3: + versal_mbox_free(&d); +out2: + versal_mbox_free(&k); +out1: + versal_mbox_free(&p); + + return ret; +} + +/* AMD/Xilinx Versal's Known Answer Tests */ +#define XSECURE_ECDSA_KAT_NIST_P384 0 + +TEE_Result versal_ecc_kat(void) +{ + struct versal_cmd_args arg = { }; + uint32_t err = 0; + + arg.data[arg.dlen++] = VERSAL_ELLIPTIC_SIGN_GEN_KAT; + arg.data[arg.dlen++] = XSECURE_ECDSA_KAT_NIST_P384; + if (versal_crypto_request(VERSAL_KAT, &arg, &err)) { + EMSG("Versal KAG NIST_P384: %s", versal_ecc_error(err)); + return TEE_ERROR_GENERIC; + } + + /* Clean previous request */ + arg.dlen = 0; + + arg.data[arg.dlen++] = VERSAL_ELLIPTIC_SIGN_VERIFY_KAT; + arg.data[arg.dlen++] = XSECURE_ECDSA_KAT_NIST_P384; + if (versal_crypto_request(VERSAL_KAT, &arg, &err)) { + EMSG("Versal KAG NIST_P521 %s", versal_ecc_error(err)); + return TEE_ERROR_GENERIC; + } + + return TEE_SUCCESS; +} + +TEE_Result versal_ecc_gen_keypair(struct ecc_keypair *s __maybe_unused) +{ + /* + * Versal requires little endian so need to memcpy_swp on Versal IP ops. + * We chose not to do it here because some tests might be using + * their own keys + */ + + return TEE_ERROR_NOT_SUPPORTED; +} + +TEE_Result versal_ecc_hw_init(void) +{ + return TEE_SUCCESS; +} diff --git a/core/drivers/crypto/versal/include/ecc.h b/core/drivers/crypto/versal/include/ecc.h new file mode 100644 index 00000000000..496f95001d3 --- /dev/null +++ b/core/drivers/crypto/versal/include/ecc.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (C) ProvenRun SAS, 2023 + */ + +#ifndef ECC_H +#define ECC_H + +TEE_Result versal_ecc_get_key_size(uint32_t curve, size_t *bytes, size_t *bits); +TEE_Result versal_ecc_prepare_msg(uint32_t algo, const uint8_t *msg, + size_t msg_len, size_t *len, uint8_t *buf); + +TEE_Result versal_ecc_hw_init(void); +TEE_Result versal_ecc_kat(void); + +TEE_Result versal_ecc_gen_keypair(struct ecc_keypair *s); +#ifdef CFG_VERSAL_PKI_PWCT +TEE_Result versal_ecc_keypair_pwct(struct ecc_keypair *s); +#endif +TEE_Result versal_ecc_verify(uint32_t algo, struct ecc_public_key *key, + const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len); +TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len); +TEE_Result versal_ecc_sign_ephemeral(uint32_t algo, size_t bytes, + struct ecc_keypair *key, + struct ecc_keypair *ephemeral, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len); + +void memcpy_swp(uint8_t *to, const uint8_t *from, size_t len); +void crypto_bignum_bn2bin_eswap(uint32_t curve, struct bignum *from, + uint8_t *to); +void crypto_bignum_bin2bn_eswap(const uint8_t *from, size_t sz, + struct bignum *to); + +#endif diff --git a/core/drivers/crypto/versal/pki/ecc_pki_engine.c b/core/drivers/crypto/versal/pki/ecc_pki_engine.c new file mode 100644 index 00000000000..cd451fafbf6 --- /dev/null +++ b/core/drivers/crypto/versal/pki/ecc_pki_engine.c @@ -0,0 +1,838 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (C) ProvenRun SAS 2023. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* PKI Engine TRNG driver */ +#define TRNG_BASE UINT64_C(0x20400051000) +#define TRNG_SIZE 0x10000 + +static struct versal_trng ecc_pki_trng = { + .cfg.base = TRNG_BASE, + .cfg.len = TRNG_SIZE, +}; + +static TEE_Result versal_ecc_trng_init(void) +{ + const uint8_t pers_str[TRNG_PERS_STR_LEN] = { + 0xB2, 0x80, 0x7E, 0x4C, 0xD0, 0xE4, 0xE2, 0xA9, + 0x2F, 0x1F, 0x5D, 0xC1, 0xA2, 0x1F, 0x40, 0xFC, + 0x1F, 0x24, 0x5D, 0x42, 0x61, 0x80, 0xE6, 0xE9, + 0x71, 0x05, 0x17, 0x5B, 0xAF, 0x70, 0x30, 0x18, + 0xBC, 0x23, 0x18, 0x15, 0xCB, 0xB8, 0xA6, 0x3E, + 0x83, 0xB8, 0x4A, 0xFE, 0x38, 0xFC, 0x25, 0x87, + }; + + /* configure in hybrid mode with derivative function enabled */ + struct trng_usr_cfg usr_cfg = { + .mode = TRNG_HRNG, + .seed_life = CFG_VERSAL_TRNG_SEED_LIFE, + .predict_en = false, + .df_disable = false, + .dfmul = CFG_VERSAL_TRNG_DF_MUL, + .iseed_en = false, + .pstr_en = true, + }; + + memcpy(usr_cfg.pstr, pers_str, TRNG_PERS_STR_LEN); + + return versal_trng_hw_init(&ecc_pki_trng, &usr_cfg); +} + +static TEE_Result versal_ecc_trng_get_random_bytes(void *buf, size_t len) +{ + return versal_trng_get_random_bytes(&ecc_pki_trng, buf, len); +} + +#define FPD_PKI_CRYPTO_BASEADDR UINT64_C(0x20400000000) +#define FPD_PKI_CTRLSTAT_BASEADDR UINT64_C(0x20400050000) + +#define FPD_PKI_SIZE 0x10000 + +#define PKI_ENGINE_GEN_CTRL_OFFSET UINT64_C(0x00000000) +#define PKI_ENGINE_GEN_CTRL_TZ 0x100 + +#define PKI_ENGINE_CTRL_OFFSET UINT64_C(0x00000C00) +#define PKI_ENGINE_CTRL_CM_MASK 0x1 + +#define PKI_CRYPTO_SOFT_RESET_OFFSET UINT64_C(0x00000038) +#define PKI_CRYPTO_IRQ_STATUS_OFFSET UINT64_C(0x00000088) +#define PKI_CRYPTO_IRQ_ENABLE_OFFSET UINT64_C(0x00000090) +#define PKI_CRYPTO_IRQ_RESET_OFFSET UINT64_C(0x000000A0) +#define PKI_RQ_CFG_PAGE_ADDR_IN_OFFSET UINT64_C(0x00000100) +#define PKI_RQ_CFG_PAGE_ADDR_OUT_OFFSET UINT64_C(0x00000108) +#define PKI_RQ_CFG_PAGE_SIZE_OFFSET UINT64_C(0x00000120) +#define PKI_RQ_CFG_CQID_OFFSET UINT64_C(0x00000128) +#define PKI_RQ_CFG_PERMISSIONS_OFFSET UINT64_C(0x00000130) +#define PKI_RQ_CFG_QUEUE_DEPTH_OFFSET UINT64_C(0x00000140) +#define PKI_CQ_CFG_ADDR_OFFSET UINT64_C(0x00001100) +#define PKI_CQ_CFG_SIZE_OFFSET UINT64_C(0x00001108) +#define PKI_CQ_CFG_IRQ_IDX_OFFSET UINT64_C(0x00001110) +#define PKI_RQ_CTL_NEW_REQUEST_OFFSET UINT64_C(0x00002000) +#define PKI_CQ_CTL_TRIGPOS_OFFSET UINT64_C(0x00002028) + +#define PKI_RQ_CFG_PERMISSIONS_SAFE 0x0 +#define PKI_RQ_CFG_PAGE_SIZE_1024 0x10 +#define PKI_RQ_CFG_CQID 0x0 +#define PKI_CQ_CFG_SIZE_4096 0xC +#define PKI_CQ_CFG_IRQ_ID_VAL 0x0 +#define PKI_RQ_CFG_QUEUE_DEPTH_VAL 0x80 +#define PKI_IRQ_ENABLE_VAL 0xFFFF +#define PKI_CQ_CTL_TRIGPOS_VAL 0x201 + +#define PKI_IRQ_DONE_STATUS_VAL 0x1 + +#define PKI_NEW_REQUEST_MASK 0x00000FFF + +#define PKI_MAX_RETRY_COUNT 10000 + +#define PKI_QUEUE_BUF_SIZE 0x1000 + +struct versal_pki { + vaddr_t regs; + + uint8_t *rq_in; + uint8_t *rq_out; + uint8_t *cq; +}; + +static struct versal_pki versal_pki; + +/* + * PKI Engine Descriptors + */ + +#define PKI_DESC_LEN_BYTES 0x20 + +#define PKI_DESC_TAG_START 0x00000002 +#define PKI_DESC_TAG_TFRI(sz) ((sz) << 16 | 0x0006) +#define PKI_DESC_TAG_TFRO(sz) ((sz) << 16 | 0x000E) +#define PKI_DESC_TAG_NTFY(id) ((id) << 16 | 0x0016) + +#define PKI_DESC_OPTYPE_MOD_ADD 0x01 +#define PKI_DESC_OPTYPE_ECC_POINTMUL 0x22 +#define PKI_DESC_OPTYPE_ECDSA_SIGN 0x30 +#define PKI_DESC_OPTYPE_ECDSA_VERIFY 0x31 + +#define PKI_DESC_ECC_FIELD_GFP 0x0 + +#define PKI_DESC_OPSIZE_P256 0x1F +#define PKI_DESC_OPSIZE_P384 0x2F +#define PKI_DESC_OPSIZE_P521 0x41 + +#define PKI_DESC_SELCURVE_P256 0x1 +#define PKI_DESC_SELCURVE_P384 0x2 +#define PKI_DESC_SELCURVE_P521 0x3 + +#define PKI_DESC_TAG_START_CMD(op, opsize, selcurve, field) \ + ((op) | ((field) << 7) | ((opsize) << 8) | ((selcurve) << 20)) + +#define PKI_SIGN_INPUT_OP_COUNT 3 +#define PKI_VERIFY_INPUT_OP_COUNT 5 +#define PKI_MOD_ADD_INPUT_OP_COUNT 3 +#define PKI_ECC_POINTMUL_INPUT_OP_COUNT 3 + +#define PKI_SIGN_OUTPUT_OP_COUNT 2 +#define PKI_VERIFY_OUTPUT_OP_COUNT 0 +#define PKI_MOD_ADD_OUTPUT_OP_COUNT 1 +#define PKI_ECC_POINTMUL_OUTPUT_OP_COUNT 2 + +#define PKI_SIGN_P521_PADD_BYTES 2 +#define PKI_VERIFY_P521_PADD_BYTES 6 + +#define PKI_DEFAULT_REQID 0xB04EU + +#define PKI_EXPECTED_CQ_STATUS 0 +#define PKI_EXPECTED_CQ_VALUE (PKI_DEFAULT_REQID << 16 | 0x1) + +#define PKI_RESET_DELAY_US 10 + +static void pki_get_opsize(uint32_t curve, uint32_t op, size_t *in_sz, + size_t *out_sz) +{ + size_t bits; + size_t bytes; + + versal_ecc_get_key_size(curve, &bytes, &bits); + + switch (op) { + case PKI_DESC_OPTYPE_ECDSA_SIGN: + *in_sz = bytes * PKI_SIGN_INPUT_OP_COUNT; + *out_sz = bytes * PKI_SIGN_OUTPUT_OP_COUNT; + break; + case PKI_DESC_OPTYPE_ECDSA_VERIFY: + *in_sz = bytes * PKI_VERIFY_INPUT_OP_COUNT; + *out_sz = bytes * PKI_VERIFY_OUTPUT_OP_COUNT; + break; + case PKI_DESC_OPTYPE_MOD_ADD: + *in_sz = bytes * PKI_MOD_ADD_INPUT_OP_COUNT; + *out_sz = bytes * PKI_MOD_ADD_OUTPUT_OP_COUNT; + break; + case PKI_DESC_OPTYPE_ECC_POINTMUL: + *in_sz = bytes * PKI_ECC_POINTMUL_INPUT_OP_COUNT; + *out_sz = bytes * PKI_ECC_POINTMUL_OUTPUT_OP_COUNT; + break; + default: + break; + } +} + +static TEE_Result pki_build_descriptors(uint32_t curve, uint32_t op, + uint32_t *descs) +{ + size_t in_sz = 0; + size_t out_sz = 0; + uint32_t opsize = 0; + uint32_t selcurve = 0; + + pki_get_opsize(curve, op, &in_sz, &out_sz); + + switch (curve) { + case TEE_ECC_CURVE_NIST_P256: + opsize = PKI_DESC_OPSIZE_P256; + selcurve = PKI_DESC_SELCURVE_P256; + break; + case TEE_ECC_CURVE_NIST_P384: + opsize = PKI_DESC_OPSIZE_P384; + selcurve = PKI_DESC_SELCURVE_P384; + break; + case TEE_ECC_CURVE_NIST_P521: + opsize = PKI_DESC_OPSIZE_P521; + selcurve = PKI_DESC_SELCURVE_P521; + break; + default: + return TEE_ERROR_NOT_SUPPORTED; + } + + /* SelCurve must be zero for ModAdd */ + if (op == PKI_DESC_OPTYPE_MOD_ADD) + selcurve = 0; + + descs[0] = PKI_DESC_TAG_START; + descs[1] = PKI_DESC_TAG_START_CMD(op, opsize, selcurve, + PKI_DESC_ECC_FIELD_GFP); + descs[2] = PKI_DESC_TAG_TFRI(in_sz); + descs[3] = 0; + descs[4] = PKI_DESC_TAG_TFRO(out_sz); + descs[5] = 0x10000; + descs[6] = PKI_DESC_TAG_NTFY(PKI_DEFAULT_REQID); + descs[7] = 0; + + return TEE_SUCCESS; +} + +static TEE_Result pki_start_operation(uint32_t reqval) +{ + TEE_Result ret = TEE_ERROR_TIMEOUT; + + uint32_t retries = PKI_MAX_RETRY_COUNT; + + /* Soft reset */ + io_write32(versal_pki.regs + PKI_CRYPTO_SOFT_RESET_OFFSET, 1); + udelay(PKI_RESET_DELAY_US); + io_write32(versal_pki.regs + PKI_CRYPTO_SOFT_RESET_OFFSET, 0); + + cache_operation(TEE_CACHEFLUSH, versal_pki.rq_in, PKI_QUEUE_BUF_SIZE); + cache_operation(TEE_CACHEFLUSH, versal_pki.rq_out, PKI_QUEUE_BUF_SIZE); + cache_operation(TEE_CACHEFLUSH, versal_pki.cq, PKI_QUEUE_BUF_SIZE); + + io_write32(versal_pki.regs + PKI_RQ_CFG_PERMISSIONS_OFFSET, + PKI_RQ_CFG_PERMISSIONS_SAFE); + io_write64(versal_pki.regs + PKI_RQ_CFG_PAGE_ADDR_IN_OFFSET, + virt_to_phys(versal_pki.rq_in)); + io_write64(versal_pki.regs + PKI_RQ_CFG_PAGE_ADDR_OUT_OFFSET, + virt_to_phys(versal_pki.rq_out)); + io_write64(versal_pki.regs + PKI_CQ_CFG_ADDR_OFFSET, + virt_to_phys(versal_pki.cq)); + io_write32(versal_pki.regs + PKI_RQ_CFG_PAGE_SIZE_OFFSET, + PKI_RQ_CFG_PAGE_SIZE_1024); + io_write32(versal_pki.regs + PKI_RQ_CFG_CQID_OFFSET, PKI_RQ_CFG_CQID); + io_write32(versal_pki.regs + PKI_CQ_CFG_SIZE_OFFSET, + PKI_CQ_CFG_SIZE_4096); + io_write32(versal_pki.regs + PKI_CQ_CFG_IRQ_IDX_OFFSET, + PKI_CQ_CFG_IRQ_ID_VAL); + io_write32(versal_pki.regs + PKI_RQ_CFG_QUEUE_DEPTH_OFFSET, + PKI_RQ_CFG_QUEUE_DEPTH_VAL); + io_write64(versal_pki.regs + PKI_CRYPTO_IRQ_ENABLE_OFFSET, + PKI_IRQ_ENABLE_VAL); + + io_write32(versal_pki.regs + PKI_CQ_CTL_TRIGPOS_OFFSET, + PKI_CQ_CTL_TRIGPOS_VAL); + io_write64(versal_pki.regs + PKI_RQ_CTL_NEW_REQUEST_OFFSET, reqval); + + /* Wait for completion */ + while (retries--) { + uint64_t irq_status = io_read64(versal_pki.regs + + PKI_CRYPTO_IRQ_STATUS_OFFSET); + if (irq_status == PKI_IRQ_DONE_STATUS_VAL) { + io_write64(versal_pki.regs + + PKI_CRYPTO_IRQ_RESET_OFFSET, + PKI_IRQ_DONE_STATUS_VAL); + ret = TEE_SUCCESS; + break; + } + } + + return ret; +} + +static TEE_Result pki_check_status(void) +{ + uint32_t cq_status; + uint32_t cq_value; + + cache_operation(TEE_CACHEFLUSH, versal_pki.cq, PKI_QUEUE_BUF_SIZE); + + cq_status = io_read32((vaddr_t)versal_pki.cq); + cq_value = io_read32((vaddr_t)versal_pki.cq + 4); + + if (cq_status != PKI_EXPECTED_CQ_STATUS || + cq_value != PKI_EXPECTED_CQ_VALUE) + return TEE_ERROR_GENERIC; + + return TEE_SUCCESS; +} + +TEE_Result versal_ecc_verify(uint32_t algo, struct ecc_public_key *key, + const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len) +{ + TEE_Result ret = TEE_SUCCESS; + + size_t bits = 0; + size_t bytes = 0; + size_t len = 0; + + uintptr_t addr = (uintptr_t)versal_pki.rq_in; + + ret = versal_ecc_get_key_size(key->curve, &bytes, &bits); + if (ret) + return ret; + + /* Copy public key */ + crypto_bignum_bn2bin_eswap(key->curve, key->x, (uint8_t *)addr); + addr += bytes; + crypto_bignum_bn2bin_eswap(key->curve, key->y, (uint8_t *)addr); + addr += bytes; + + /* Copy signature */ + memcpy_swp((uint8_t *)addr, sig, sig_len / 2); + addr += sig_len / 2; + memcpy_swp((uint8_t *)addr, sig + sig_len / 2, sig_len / 2); + addr += sig_len / 2; + + /* Copy hash */ + ret = versal_ecc_prepare_msg(algo, msg, msg_len, &len, (uint8_t *)addr); + if (ret) + return ret; + if (len < bytes) + memset((uint8_t *)addr + len, 0, bytes - len); + addr += bytes; + + if (key->curve == TEE_ECC_CURVE_NIST_P521) { + memset((uint8_t *)addr, 0, PKI_VERIFY_P521_PADD_BYTES); + addr += PKI_VERIFY_P521_PADD_BYTES; + } + + /* Build descriptors */ + ret = pki_build_descriptors(key->curve, PKI_DESC_OPTYPE_ECDSA_VERIFY, + (uint32_t *)addr); + if (ret) + return ret; + + ret = pki_start_operation(PKI_NEW_REQUEST_MASK & (addr + 1)); + if (ret) + return ret; + + ret = pki_check_status(); + if (ret) + return ret; + + /* Clear memory */ + memset(versal_pki.rq_in, 0, PKI_QUEUE_BUF_SIZE); + memset(versal_pki.cq, 0, PKI_QUEUE_BUF_SIZE); + + return TEE_SUCCESS; +} + +TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len) +{ + TEE_Result ret = TEE_SUCCESS; + size_t bits = 0; + size_t bytes = 0; + struct ecc_keypair ephemeral = { }; + + ret = versal_ecc_get_key_size(key->curve, &bytes, &bits); + if (ret) + return ret; + + /* Ephemeral private key */ + ret = drvcrypt_asym_alloc_ecc_keypair(&ephemeral, + TEE_TYPE_ECDSA_KEYPAIR, bits); + if (ret) { + EMSG("Versal, can't allocate the ephemeral key"); + return ret; + } + + ephemeral.curve = key->curve; + ret = versal_ecc_gen_keypair(&ephemeral); + if (ret) { + EMSG("Versal, can't generate the ephemeral key"); + return ret; + } + + ret = versal_ecc_sign_ephemeral(algo, bytes, key, &ephemeral, msg, + msg_len, sig, sig_len); + + crypto_bignum_free(&ephemeral.d); + crypto_bignum_free(&ephemeral.x); + crypto_bignum_free(&ephemeral.y); + + return ret; +} + +TEE_Result versal_ecc_sign_ephemeral(uint32_t algo, size_t bytes, + struct ecc_keypair *key, + struct ecc_keypair *ephemeral, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len) +{ + TEE_Result ret = TEE_SUCCESS; + size_t len = 0; + + uintptr_t addr = (uintptr_t)versal_pki.rq_in; + + /* Copy private key */ + crypto_bignum_bn2bin_eswap(key->curve, key->d, (uint8_t *)addr); + addr += bytes; + + /* Copy ephemeral key */ + crypto_bignum_bn2bin_eswap(key->curve, ephemeral->d, (uint8_t *)addr); + addr += bytes; + + /* Copy hash */ + ret = versal_ecc_prepare_msg(algo, msg, msg_len, &len, (uint8_t *)addr); + if (ret) + return ret; + if (len < bytes) + memset((uint8_t *)addr + len, 0, bytes - len); + addr += bytes; + + if (key->curve == TEE_ECC_CURVE_NIST_P521) { + memset((uint8_t *)addr, 0, PKI_SIGN_P521_PADD_BYTES); + addr += PKI_SIGN_P521_PADD_BYTES; + } + + /* Build descriptors */ + ret = pki_build_descriptors(key->curve, PKI_DESC_OPTYPE_ECDSA_SIGN, + (uint32_t *)addr); + if (ret) + return ret; + + ret = pki_start_operation(PKI_NEW_REQUEST_MASK & (addr + 1)); + if (ret) + return ret; + + ret = pki_check_status(); + if (ret) + return ret; + + /* Copy signature back */ + *sig_len = 2 * bytes; + + cache_operation(TEE_CACHEFLUSH, versal_pki.rq_out, PKI_QUEUE_BUF_SIZE); + + memcpy_swp(sig, versal_pki.rq_out, bytes); + memcpy_swp(sig + bytes, versal_pki.rq_out + bytes, bytes); + + /* Clear memory */ + memset(versal_pki.rq_in, 0, PKI_QUEUE_BUF_SIZE); + memset(versal_pki.rq_out, 0, PKI_QUEUE_BUF_SIZE); + memset(versal_pki.cq, 0, PKI_QUEUE_BUF_SIZE); + + return ret; +} + +static const uint8_t Order_P256[] = { + 0x51, 0x25, 0x63, 0xfc, 0xc2, 0xca, 0xb9, 0xf3, + 0x84, 0x9e, 0x17, 0xa7, 0xad, 0xfa, 0xe6, 0xbc, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, +}; + +static const uint8_t Order_P384[] = { + 0x73, 0x29, 0xc5, 0xcc, 0x6a, 0x19, 0xec, 0xec, + 0x7a, 0xa7, 0xb0, 0x48, 0xb2, 0x0d, 0x1a, 0x58, + 0xdf, 0x2d, 0x37, 0xf4, 0x81, 0x4d, 0x63, 0xc7, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; + +static const uint8_t Order_P521[] = { + 0x09, 0x64, 0x38, 0x91, 0x1e, 0xb7, 0x6f, 0xbb, + 0xae, 0x47, 0x9c, 0x89, 0xb8, 0xc9, 0xb5, 0x3b, + 0xd0, 0xa5, 0x09, 0xf7, 0x48, 0x01, 0xcc, 0x7f, + 0x6b, 0x96, 0x2f, 0xbf, 0x83, 0x87, 0x86, 0x51, + 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x01 +}; + +static const uint8_t EcdsaGpoint_P256_Gx[] = { + 0x96, 0xc2, 0x98, 0xd8, 0x45, 0x39, 0xa1, 0xf4, + 0xa0, 0x33, 0xeb, 0x2d, 0x81, 0x7d, 0x03, 0x77, + 0xf2, 0x40, 0xa4, 0x63, 0xe5, 0xe6, 0xbc, 0xf8, + 0x47, 0x42, 0x2c, 0xe1, 0xf2, 0xd1, 0x17, 0x6b +}; + +static const uint8_t EcdsaGpoint_P256_Gy[] = { + 0xf5, 0x51, 0xbf, 0x37, 0x68, 0x40, 0xb6, 0xcb, + 0xce, 0x5e, 0x31, 0x6b, 0x57, 0x33, 0xce, 0x2b, + 0x16, 0x9e, 0x0f, 0x7c, 0x4a, 0xeb, 0xe7, 0x8e, + 0x9b, 0x7f, 0x1a, 0xfe, 0xe2, 0x42, 0xe3, 0x4f +}; + +static const uint8_t EcdsaGpoint_P384_Gx[] = { + 0xb7, 0x0a, 0x76, 0x72, 0x38, 0x5e, 0x54, 0x3a, + 0x6c, 0x29, 0x55, 0xbf, 0x5d, 0xf2, 0x02, 0x55, + 0x38, 0x2a, 0x54, 0x82, 0xe0, 0x41, 0xf7, 0x59, + 0x98, 0x9b, 0xa7, 0x8b, 0x62, 0x3b, 0x1d, 0x6e, + 0x74, 0xad, 0x20, 0xf3, 0x1e, 0xc7, 0xb1, 0x8e, + 0x37, 0x05, 0x8b, 0xbe, 0x22, 0xca, 0x87, 0xaa +}; + +static const uint8_t EcdsaGpoint_P384_Gy[] = { + 0x5f, 0x0e, 0xea, 0x90, 0x7c, 0x1d, 0x43, 0x7a, + 0x9d, 0x81, 0x7e, 0x1d, 0xce, 0xb1, 0x60, 0x0a, + 0xc0, 0xb8, 0xf0, 0xb5, 0x13, 0x31, 0xda, 0xe9, + 0x7c, 0x14, 0x9a, 0x28, 0xbd, 0x1d, 0xf4, 0xf8, + 0x29, 0xdc, 0x92, 0x92, 0xbf, 0x98, 0x9e, 0x5d, + 0x6f, 0x2c, 0x26, 0x96, 0x4a, 0xde, 0x17, 0x36 +}; + +static const uint8_t EcdsaGpoint_P521_Gx[] = { + 0x66, 0xbd, 0xe5, 0xc2, 0x31, 0x7e, 0x7e, 0xf9, + 0x9b, 0x42, 0x6a, 0x85, 0xc1, 0xb3, 0x48, 0x33, + 0xde, 0xa8, 0xff, 0xa2, 0x27, 0xc1, 0x1d, 0xfe, + 0x28, 0x59, 0xe7, 0xef, 0x77, 0x5e, 0x4b, 0xa1, + 0xba, 0x3d, 0x4d, 0x6b, 0x60, 0xaf, 0x28, 0xf8, + 0x21, 0xb5, 0x3f, 0x05, 0x39, 0x81, 0x64, 0x9c, + 0x42, 0xb4, 0x95, 0x23, 0x66, 0xcb, 0x3e, 0x9e, + 0xcd, 0xe9, 0x04, 0x04, 0xb7, 0x06, 0x8e, 0x85, + 0xc6, 0x00 +}; + +static const uint8_t EcdsaGpoint_P521_Gy[] = { + 0x50, 0x66, 0xd1, 0x9f, 0x76, 0x94, 0xbe, 0x88, + 0x40, 0xc2, 0x72, 0xa2, 0x86, 0x70, 0x3c, 0x35, + 0x61, 0x07, 0xad, 0x3f, 0x01, 0xb9, 0x50, 0xc5, + 0x40, 0x26, 0xf4, 0x5e, 0x99, 0x72, 0xee, 0x97, + 0x2c, 0x66, 0x3e, 0x27, 0x17, 0xbd, 0xaf, 0x17, + 0x68, 0x44, 0x9b, 0x57, 0x49, 0x44, 0xf5, 0x98, + 0xd9, 0x1b, 0x7d, 0x2c, 0xb4, 0x5f, 0x8a, 0x5c, + 0x04, 0xc0, 0x3b, 0x9a, 0x78, 0x6a, 0x29, 0x39, + 0x18, 0x01 +}; + +static TEE_Result versal_ecc_gen_private_key(uint32_t curve, uint8_t *priv, + size_t bytes) +{ + TEE_Result ret = TEE_SUCCESS; + const uint8_t *order; + uintptr_t addr = (uintptr_t)versal_pki.rq_in; + + switch (curve) { + case TEE_ECC_CURVE_NIST_P256: + order = Order_P256; + break; + case TEE_ECC_CURVE_NIST_P384: + order = Order_P384; + break; + case TEE_ECC_CURVE_NIST_P521: + order = Order_P521; + break; + default: + return TEE_ERROR_NOT_SUPPORTED; + } + + /* Copy curve order N */ + memcpy((uint8_t *)addr, order, bytes); + addr += bytes; + + /* Copy A = random */ + ret = versal_ecc_trng_get_random_bytes((uint8_t *)addr, bytes); + if (ret) + return ret; + addr += bytes; + + /* Copy B = 1 */ + memset((uint8_t *)addr, 1, 1); + memset((uint8_t *)addr + 1, 0, bytes - 1); + addr += bytes; + + if (curve == TEE_ECC_CURVE_NIST_P521) { + memset((uint8_t *)addr, 0, PKI_SIGN_P521_PADD_BYTES); + addr += PKI_SIGN_P521_PADD_BYTES; + } + + /* Build descriptors */ + ret = pki_build_descriptors(curve, PKI_DESC_OPTYPE_MOD_ADD, + (uint32_t *)addr); + if (ret) + return ret; + + /* Use PKI engine to compute A+B mod N */ + ret = pki_start_operation(PKI_NEW_REQUEST_MASK & (addr + 1)); + if (ret) + return ret; + + ret = pki_check_status(); + if (ret) + return ret; + + cache_operation(TEE_CACHEFLUSH, versal_pki.rq_out, PKI_QUEUE_BUF_SIZE); + + /* Copy back result */ + memcpy(priv, versal_pki.rq_out, bytes); + + return ret; +} + +TEE_Result versal_ecc_gen_keypair(struct ecc_keypair *s) +{ + TEE_Result ret = TEE_SUCCESS; + size_t bytes; + size_t bits; + const uint8_t *Gx; + const uint8_t *Gy; + uintptr_t addr = (uintptr_t)versal_pki.rq_in; + + ret = versal_ecc_get_key_size(s->curve, &bytes, &bits); + if (ret) + return ret; + + switch (s->curve) { + case TEE_ECC_CURVE_NIST_P256: + Gx = EcdsaGpoint_P256_Gx; + Gy = EcdsaGpoint_P256_Gy; + break; + case TEE_ECC_CURVE_NIST_P384: + Gx = EcdsaGpoint_P384_Gx; + Gy = EcdsaGpoint_P384_Gy; + break; + case TEE_ECC_CURVE_NIST_P521: + Gx = EcdsaGpoint_P521_Gx; + Gy = EcdsaGpoint_P521_Gy; + break; + default: + return TEE_ERROR_NOT_SUPPORTED; + } + + /* Generate private key */ + ret = versal_ecc_gen_private_key(s->curve, (uint8_t *)addr, bytes); + if (ret) + return ret; + addr += bytes; + + /* Copy generator point x coordinate */ + memcpy((uint8_t *)addr, Gx, bytes); + addr += bytes; + + /* Copy generator point y coordinate */ + memcpy((uint8_t *)addr, Gy, bytes); + addr += bytes; + + if (s->curve == TEE_ECC_CURVE_NIST_P521) { + memset((uint8_t *)addr, 0, PKI_SIGN_P521_PADD_BYTES); + addr += PKI_SIGN_P521_PADD_BYTES; + } + + /* Build descriptors */ + ret = pki_build_descriptors(s->curve, PKI_DESC_OPTYPE_ECC_POINTMUL, + (uint32_t *)addr); + if (ret) + return ret; + + /* Use PKI engine to compute Q = priv * G */ + ret = pki_start_operation(PKI_NEW_REQUEST_MASK & (addr + 1)); + if (ret) + return ret; + + ret = pki_check_status(); + if (ret) + return ret; + + cache_operation(TEE_CACHEFLUSH, versal_pki.rq_out, PKI_QUEUE_BUF_SIZE); + + /* Copy private and public keys back */ + crypto_bignum_bin2bn_eswap(versal_pki.rq_in, bytes, s->d); + crypto_bignum_bin2bn_eswap(versal_pki.rq_out, bytes, s->x); + crypto_bignum_bin2bn_eswap(versal_pki.rq_out + bytes, bytes, s->y); + + /* Clear memory */ + memset(versal_pki.rq_in, 0, PKI_QUEUE_BUF_SIZE); + memset(versal_pki.rq_out, 0, PKI_QUEUE_BUF_SIZE); + memset(versal_pki.cq, 0, PKI_QUEUE_BUF_SIZE); + + return ret; +} + +#define PSX_CRF_RST_PKI 0xEC200340 + +#define PKI_ASSERT_RESET 1 +#define PKI_DEASSERT_RESET 0 + +static TEE_Result versal_pki_engine_reset(void) +{ + vaddr_t reset; + + /* Reset the PKI engine */ + reset = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, + PSX_CRF_RST_PKI, SMALL_PAGE_SIZE); + if (!reset) + return TEE_ERROR_GENERIC; + + io_write32(reset, PKI_ASSERT_RESET); + udelay(PKI_RESET_DELAY_US); + io_write32(reset, PKI_DEASSERT_RESET); + + core_mmu_remove_mapping(MEM_AREA_IO_SEC, (void *)reset, + SMALL_PAGE_SIZE); + + return TEE_SUCCESS; +} + +#define FPD_SLCR_BASEADDR 0xEC8C0000 +#define FPD_SLCR_SIZE 0x4000 + +#define FPD_SLCR_WPROT0_OFFSET 0x00000000 +#define FPD_SLCR_PKI_MUX_SEL_OFFSET 0x00002000 + +#define FPD_CLEAR_WRITE_PROTECT 0 +#define FPD_ENABLE_WRITE_PROTECT 1 + +#define PKI_MUX_SEL_MASK 0x00000001 +#define PKI_MUX_SELECT 0x00000001 + +static TEE_Result versal_pki_engine_slcr_config(void) +{ + vaddr_t fpd_slcr; + + fpd_slcr = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, + FPD_SLCR_BASEADDR, + FPD_SLCR_SIZE); + if (!fpd_slcr) + return TEE_ERROR_GENERIC; + + /* Clear FPD SCLR write protect reg */ + io_write32(fpd_slcr + FPD_SLCR_WPROT0_OFFSET, + FPD_CLEAR_WRITE_PROTECT); + + /* PKI mux selection */ + io_mask32(fpd_slcr + FPD_SLCR_PKI_MUX_SEL_OFFSET, + PKI_MUX_SELECT, PKI_MUX_SEL_MASK); + + /* Re-enable FPD SCLR write protect */ + io_write32(fpd_slcr + FPD_SLCR_WPROT0_OFFSET, + FPD_ENABLE_WRITE_PROTECT); + + core_mmu_remove_mapping(MEM_AREA_IO_SEC, + (void *)fpd_slcr, FPD_SLCR_SIZE); + + return TEE_SUCCESS; +} + +static TEE_Result versal_pki_engine_config(void) +{ + vaddr_t regs; + uint64_t val; + + regs = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, + FPD_PKI_CTRLSTAT_BASEADDR, + FPD_PKI_SIZE); + if (!regs) + return TEE_ERROR_GENERIC; + + /* Counter-measures configuration */ + val = io_read64(regs + PKI_ENGINE_CTRL_OFFSET); + if (IS_ENABLED(CFG_VERSAL_PKI_COUNTER_MEASURES)) + val &= ~PKI_ENGINE_CTRL_CM_MASK; + else + val |= PKI_ENGINE_CTRL_CM_MASK; + io_write64(regs + PKI_ENGINE_CTRL_OFFSET, val); + + /* Mark PKI engine transactions as secure */ + val = io_read64(regs + PKI_ENGINE_GEN_CTRL_OFFSET); + val &= ~PKI_ENGINE_GEN_CTRL_TZ; + io_write64(regs + PKI_ENGINE_GEN_CTRL_OFFSET, val); + + core_mmu_remove_mapping(MEM_AREA_IO_SEC, + (void *)regs, FPD_PKI_SIZE); + + return TEE_SUCCESS; +} + +TEE_Result versal_ecc_hw_init(void) +{ + TEE_Result ret; + + ret = versal_pki_engine_slcr_config(); + if (ret != TEE_SUCCESS) + return ret; + + ret = versal_pki_engine_reset(); + if (ret != TEE_SUCCESS) + return ret; + + ret = versal_pki_engine_config(); + if (ret != TEE_SUCCESS) + return ret; + + ret = versal_ecc_trng_init(); + if (ret != TEE_SUCCESS) + return ret; + + versal_pki.regs = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, + FPD_PKI_CRYPTO_BASEADDR, FPD_PKI_SIZE); + if (!versal_pki.regs) + return TEE_ERROR_GENERIC; + + /* Allocate queues */ + versal_pki.rq_in = memalign(CACHELINE_LEN, PKI_QUEUE_BUF_SIZE); + if (!versal_pki.rq_in) + return TEE_ERROR_GENERIC; + + versal_pki.rq_out = memalign(CACHELINE_LEN, PKI_QUEUE_BUF_SIZE); + if (!versal_pki.rq_out) + return TEE_ERROR_GENERIC; + + versal_pki.cq = memalign(CACHELINE_LEN, PKI_QUEUE_BUF_SIZE); + if (!versal_pki.cq) + return TEE_ERROR_GENERIC; + + return TEE_SUCCESS; +} diff --git a/core/drivers/crypto/versal/pki/ecc_pki_kat.c b/core/drivers/crypto/versal/pki/ecc_pki_kat.c new file mode 100644 index 00000000000..73fe2c39d8f --- /dev/null +++ b/core/drivers/crypto/versal/pki/ecc_pki_kat.c @@ -0,0 +1,477 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (C) ProvenRun SAS 2023. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const uint8_t PubkeyQx_P256[] = { + 0xb7, 0xe0, 0x8a, 0xfd, 0xfe, 0x94, 0xba, 0xd3, + 0xf1, 0xdc, 0x8c, 0x73, 0x47, 0x98, 0xba, 0x1c, + 0x62, 0xb3, 0xa0, 0xad, 0x1e, 0x9e, 0xa2, 0xa3, + 0x82, 0x01, 0xcd, 0x08, 0x89, 0xbc, 0x7a, 0x19 +}; + +static const uint8_t PubkeyQy_P256[] = { + 0x36, 0x03, 0xf7, 0x47, 0x95, 0x9d, 0xbf, 0x7a, + 0x4b, 0xb2, 0x26, 0xe4, 0x19, 0x28, 0x72, 0x90, + 0x63, 0xad, 0xc7, 0xae, 0x43, 0x52, 0x9e, 0x61, + 0xb5, 0x63, 0xbb, 0xc6, 0x06, 0xcc, 0x5e, 0x09, +}; + +static const uint8_t PubkeyQx_P384[] = { + 0x3b, 0xf7, 0x01, 0xbc, 0x9e, 0x9d, 0x36, 0xb4, + 0xd5, 0xf1, 0x45, 0x53, 0x43, 0xf0, 0x91, 0x26, + 0xf2, 0x56, 0x43, 0x90, 0xf2, 0xb4, 0x87, 0x36, + 0x50, 0x71, 0x24, 0x3c, 0x61, 0xe6, 0x47, 0x1f, + 0xb9, 0xd2, 0xab, 0x74, 0x65, 0x7b, 0x82, 0xf9, + 0x08, 0x64, 0x89, 0xd9, 0xef, 0x0f, 0x5c, 0xb5, +}; + +static const uint8_t PubkeyQy_P384[] = { + 0xd1, 0xa3, 0x58, 0xea, 0xfb, 0xf9, 0x52, 0xe6, + 0x8d, 0x53, 0x38, 0x55, 0xcc, 0xbd, 0xaa, 0x6f, + 0xf7, 0x5b, 0x13, 0x7a, 0x51, 0x01, 0x44, 0x31, + 0x99, 0x32, 0x55, 0x83, 0x55, 0x2a, 0x62, 0x95, + 0xff, 0xe5, 0x38, 0x2d, 0x00, 0xcf, 0xcd, 0xa3, + 0x03, 0x44, 0xa9, 0xb5, 0xb6, 0x8d, 0xb8, 0x55, +}; + +static const uint8_t PubkeyQx_P521[] = { + 0x00, 0x98, 0xe9, 0x1e, 0xef, 0x9a, 0x68, 0x45, + 0x28, 0x22, 0x30, 0x9c, 0x52, 0xfa, 0xb4, 0x53, + 0xf5, 0xf1, 0x17, 0xc1, 0xda, 0x8e, 0xd7, 0x96, + 0xb2, 0x55, 0xe9, 0xab, 0x8f, 0x64, 0x10, 0xcc, + 0xa1, 0x6e, 0x59, 0xdf, 0x40, 0x3a, 0x6b, 0xdc, + 0x6c, 0xa4, 0x67, 0xa3, 0x70, 0x56, 0xb1, 0xe5, + 0x4b, 0x30, 0x05, 0xd8, 0xac, 0x03, 0x0d, 0xec, + 0xfe, 0xb6, 0x8d, 0xf1, 0x8b, 0x17, 0x18, 0x85, + 0xd5, 0xc4, +}; + +static const uint8_t PubkeyQy_P521[] = { + 0x01, 0x64, 0x35, 0x0c, 0x32, 0x1a, 0xec, 0xfc, + 0x1c, 0xca, 0x1b, 0xa4, 0x36, 0x4c, 0x9b, 0x15, + 0x65, 0x61, 0x50, 0xb4, 0xb7, 0x8d, 0x6a, 0x48, + 0xd7, 0xd2, 0x8e, 0x7f, 0x31, 0x98, 0x5e, 0xf1, + 0x7b, 0xe8, 0x55, 0x43, 0x76, 0xb7, 0x29, 0x00, + 0x71, 0x2c, 0x4b, 0x83, 0xad, 0x66, 0x83, 0x27, + 0x23, 0x15, 0x26, 0xe3, 0x13, 0xf5, 0xf0, 0x92, + 0x99, 0x9a, 0x46, 0x32, 0xfd, 0x50, 0xd9, 0x46, + 0xbc, 0x2e, +}; + +/* Signature */ +static const uint8_t SignR_P256[] = { + 0x2b, 0x42, 0xf5, 0x76, 0xd0, 0x7f, 0x41, 0x65, + 0xff, 0x65, 0xd1, 0xf3, 0xb1, 0x50, 0x0f, 0x81, + 0xe4, 0x4c, 0x31, 0x6f, 0x1f, 0x0b, 0x3e, 0xf5, + 0x73, 0x25, 0xb6, 0x9a, 0xca, 0x46, 0x10, 0x4f, +}; + +static const uint8_t SignS_P256[] = { + 0xdc, 0x42, 0xc2, 0x12, 0x2d, 0x63, 0x92, 0xcd, + 0x3e, 0x3a, 0x99, 0x3a, 0x89, 0x50, 0x2a, 0x81, + 0x98, 0xc1, 0x88, 0x6f, 0xe6, 0x9d, 0x26, 0x2c, + 0x4b, 0x32, 0x9b, 0xdb, 0x6b, 0x63, 0xfa, 0xf1, +}; + +static const uint8_t SignR_P384[] = { + 0x30, 0xea, 0x51, 0x4f, 0xc0, 0xd3, 0x8d, 0x82, + 0x08, 0x75, 0x6f, 0x06, 0x81, 0x13, 0xc7, 0xca, + 0xda, 0x9f, 0x66, 0xa3, 0xb4, 0x0e, 0xa3, 0xb3, + 0x13, 0xd0, 0x40, 0xd9, 0xb5, 0x7d, 0xd4, 0x1a, + 0x33, 0x27, 0x95, 0xd0, 0x2c, 0xc7, 0xd5, 0x07, + 0xfc, 0xef, 0x9f, 0xaf, 0x01, 0xa2, 0x70, 0x88, +}; + +static const uint8_t SignS_P384[] = { + 0xcc, 0x80, 0x8e, 0x50, 0x4b, 0xe4, 0x14, 0xf4, + 0x6c, 0x90, 0x27, 0xbc, 0xbf, 0x78, 0xad, 0xf0, + 0x67, 0xa4, 0x39, 0x22, 0xd6, 0xfc, 0xaa, 0x66, + 0xc4, 0x47, 0x68, 0x75, 0xfb, 0xb7, 0xb9, 0x4e, + 0xfd, 0x1f, 0x7d, 0x5d, 0xbe, 0x62, 0x0b, 0xfb, + 0x82, 0x1c, 0x46, 0xd5, 0x49, 0x68, 0x3a, 0xd8, +}; + +static const uint8_t SignR_P521[] = { + 0x01, 0x40, 0xc8, 0xed, 0xca, 0x57, 0x10, 0x8c, + 0xe3, 0xf7, 0xe7, 0xa2, 0x40, 0xdd, 0xd3, 0xad, + 0x74, 0xd8, 0x1e, 0x2d, 0xe6, 0x24, 0x51, 0xfc, + 0x1d, 0x55, 0x8f, 0xdc, 0x79, 0x26, 0x9a, 0xda, + 0xcd, 0x1c, 0x25, 0x26, 0xee, 0xee, 0xf3, 0x2f, + 0x8c, 0x04, 0x32, 0xa9, 0xd5, 0x6e, 0x2b, 0x4a, + 0x8a, 0x73, 0x28, 0x91, 0xc3, 0x7c, 0x9b, 0x96, + 0x64, 0x1a, 0x92, 0x54, 0xcc, 0xfe, 0x5d, 0xc3, + 0xe2, 0xba, +}; + +static const uint8_t SignS_P521[] = { + 0x00, 0xb2, 0x51, 0x88, 0x49, 0x2d, 0x58, 0xe8, + 0x08, 0xed, 0xeb, 0xd7, 0xbf, 0x44, 0x0e, 0xd2, + 0x0d, 0xb7, 0x71, 0xca, 0x7c, 0x61, 0x85, 0x95, + 0xd5, 0x39, 0x8e, 0x1b, 0x1c, 0x00, 0x98, 0xe3, + 0x00, 0xd8, 0xc8, 0x03, 0xec, 0x69, 0xec, 0x5f, + 0x46, 0xc8, 0x4f, 0xc6, 0x19, 0x67, 0xa3, 0x02, + 0xd3, 0x66, 0xc6, 0x27, 0xfc, 0xfa, 0x56, 0xf8, + 0x7f, 0x24, 0x1e, 0xf9, 0x21, 0xb6, 0xe6, 0x27, + 0xad, 0xbf, +}; + +static const uint8_t D_P256[] = { + 0xc4, 0x77, 0xf9, 0xf6, 0x5c, 0x22, 0xcc, 0xe2, + 0x06, 0x57, 0xfa, 0xa5, 0xb2, 0xd1, 0xd8, 0x12, + 0x23, 0x36, 0xf8, 0x51, 0xa5, 0x08, 0xa1, 0xed, + 0x04, 0xe4, 0x79, 0xc3, 0x49, 0x85, 0xbf, 0x96, +}; + +static const uint8_t D_P384[] = { + 0xf9, 0x2c, 0x02, 0xed, 0x62, 0x9e, 0x4b, 0x48, + 0xc0, 0x58, 0x4b, 0x1c, 0x6c, 0xe3, 0xa3, 0xe3, + 0xb4, 0xfa, 0xae, 0x4a, 0xfc, 0x6a, 0xcb, 0x04, + 0x55, 0xe7, 0x3d, 0xfc, 0x39, 0x2e, 0x6a, 0x0a, + 0xe3, 0x93, 0xa8, 0x56, 0x5e, 0x6b, 0x97, 0x14, + 0xd1, 0x22, 0x4b, 0x57, 0xd8, 0x3f, 0x8a, 0x08, +}; + +static const uint8_t D_P521[] = { + 0x01, 0x00, 0x08, 0x5f, 0x47, 0xb8, 0xe1, 0xb8, + 0xb1, 0x1b, 0x7e, 0xb3, 0x30, 0x28, 0xc0, 0xb2, + 0x88, 0x8e, 0x30, 0x4b, 0xfc, 0x98, 0x50, 0x19, + 0x55, 0xb4, 0x5b, 0xba, 0x14, 0x78, 0xdc, 0x18, + 0x4e, 0xee, 0xdf, 0x09, 0xb8, 0x6a, 0x5f, 0x7c, + 0x21, 0x99, 0x44, 0x06, 0x07, 0x27, 0x87, 0x20, + 0x5e, 0x69, 0xa6, 0x37, 0x09, 0xfe, 0x35, 0xaa, + 0x93, 0xba, 0x33, 0x35, 0x14, 0xb2, 0x4f, 0x96, + 0x17, 0x22, +}; + +static const uint8_t K_P256[] = { + 0x7a, 0x1a, 0x7e, 0x52, 0x79, 0x7f, 0xc8, 0xca, + 0xaa, 0x43, 0x5d, 0x2a, 0x4d, 0xac, 0xe3, 0x91, + 0x58, 0x50, 0x4b, 0xf2, 0x04, 0xfb, 0xe1, 0x9f, + 0x14, 0xdb, 0xb4, 0x27, 0xfa, 0xee, 0x50, 0xae, +}; + +static const uint8_t K_P384[] = { + 0x2e, 0x44, 0xef, 0x1f, 0x8c, 0x0b, 0xea, 0x83, + 0x94, 0xe3, 0xdd, 0xa8, 0x1e, 0xc6, 0xa7, 0x84, + 0x2a, 0x45, 0x9b, 0x53, 0x47, 0x01, 0x74, 0x9e, + 0x2e, 0xd9, 0x5f, 0x05, 0x4f, 0x01, 0x37, 0x68, + 0x08, 0x78, 0xe0, 0x74, 0x9f, 0xc4, 0x3f, 0x85, + 0xed, 0xca, 0xe0, 0x6c, 0xc2, 0xf4, 0x3f, 0xef, +}; + +static const uint8_t K_P521[] = { + 0x00, 0x00, 0xc9, 0x1e, 0x23, 0x49, 0xef, 0x6c, + 0xa2, 0x2d, 0x2d, 0xe3, 0x9d, 0xd5, 0x18, 0x19, + 0xb6, 0xaa, 0xd9, 0x22, 0xd3, 0xae, 0xcd, 0xea, + 0xb4, 0x52, 0xba, 0x17, 0x2f, 0x7d, 0x63, 0xe3, + 0x70, 0xce, 0xcd, 0x70, 0x57, 0x5f, 0x59, 0x7c, + 0x09, 0xa1, 0x74, 0xba, 0x76, 0xbe, 0xd0, 0x5a, + 0x48, 0xe5, 0x62, 0xbe, 0x06, 0x25, 0x33, 0x6d, + 0x16, 0xb8, 0x70, 0x31, 0x47, 0xa6, 0xa2, 0x31, + 0xd6, 0xbf, +}; + +static const uint8_t H_P256[] = { + 0xa4, 0x1a, 0x41, 0xa1, 0x2a, 0x79, 0x95, 0x48, + 0x21, 0x1c, 0x41, 0x0c, 0x65, 0xd8, 0x13, 0x3a, + 0xfd, 0xe3, 0x4d, 0x28, 0xbd, 0xd5, 0x42, 0xe4, + 0xb6, 0x80, 0xcf, 0x28, 0x99, 0xc8, 0xa8, 0xc4, +}; + +static const uint8_t H_P384[] = { + 0x5a, 0xea, 0x18, 0x7d, 0x1c, 0x4f, 0x6e, 0x1b, + 0x35, 0x05, 0x7d, 0x20, 0x12, 0x6d, 0x83, 0x6c, + 0x6a, 0xdb, 0xbc, 0x70, 0x49, 0xee, 0x02, 0x99, + 0xc9, 0x52, 0x9f, 0x5e, 0x0b, 0x3f, 0x8b, 0x5a, + 0x74, 0x11, 0x14, 0x9d, 0x6c, 0x30, 0xd6, 0xcb, + 0x2b, 0x8a, 0xf7, 0x0e, 0x0a, 0x78, 0x1e, 0x89, +}; + +static const uint8_t H_P521[] = { + 0x00, 0x00, 0xef, 0x88, 0xfb, 0x5a, 0xc0, 0x1f, + 0x35, 0xf5, 0xcb, 0x8a, 0x1b, 0x00, 0x8e, 0x80, + 0x11, 0x46, 0xc1, 0x39, 0x83, 0xcf, 0x8c, 0x2c, + 0xcf, 0x1d, 0x88, 0xaf, 0xa8, 0xe9, 0xfe, 0xde, + 0x12, 0x1c, 0x11, 0xfe, 0x82, 0x9d, 0x41, 0xb4, + 0x02, 0xb3, 0x2a, 0xdf, 0xde, 0x20, 0x67, 0x9c, + 0x3f, 0x4d, 0x91, 0x01, 0xa3, 0xc4, 0x07, 0x3a, + 0x2e, 0x49, 0x03, 0x9f, 0x5d, 0x38, 0x06, 0x1c, + 0xdb, 0xcc, +}; + +static TEE_Result versal_ecc_sign_kat(uint32_t curve) +{ + TEE_Result ret = TEE_SUCCESS; + size_t bytes; + size_t bits; + struct ecc_keypair key; + struct ecc_keypair ephemeral; + + uint32_t algo; + uint8_t *D; + uint8_t *K; + uint8_t *SignR; + uint8_t *SignS; + uint8_t *hash; + uint8_t sig[(TEE_SHA512_HASH_SIZE + 2) * 2]; + size_t sig_len = 0; + + switch (curve) { + case TEE_ECC_CURVE_NIST_P256: + algo = TEE_ALG_ECDSA_SHA256; + D = (uint8_t *)D_P256; + K = (uint8_t *)K_P256; + SignR = (uint8_t *)SignR_P256; + SignS = (uint8_t *)SignS_P256; + hash = (uint8_t *)H_P256; + break; + case TEE_ECC_CURVE_NIST_P384: + algo = TEE_ALG_ECDSA_SHA384; + D = (uint8_t *)D_P384; + K = (uint8_t *)K_P384; + SignR = (uint8_t *)SignR_P384; + SignS = (uint8_t *)SignS_P384; + hash = (uint8_t *)H_P384; + break; + case TEE_ECC_CURVE_NIST_P521: + algo = TEE_ALG_ECDSA_SHA512; + D = (uint8_t *)D_P521; + K = (uint8_t *)K_P521; + SignR = (uint8_t *)SignR_P521; + SignS = (uint8_t *)SignS_P521; + hash = (uint8_t *)H_P521; + break; + default: + return TEE_ERROR_NOT_SUPPORTED; + } + + ret = versal_ecc_get_key_size(curve, &bytes, &bits); + if (ret) + return ret; + + /* Prepare private key */ + ret = crypto_asym_alloc_ecc_keypair(&key, TEE_TYPE_ECDSA_KEYPAIR, bits); + if (ret) + return ret; + key.curve = curve; + + ret = crypto_bignum_bin2bn(D, bytes, key.d); + if (ret) + goto end; + + /* Prepare ephemeral key */ + ret = crypto_asym_alloc_ecc_keypair(&ephemeral, TEE_TYPE_ECDSA_KEYPAIR, + bits); + if (ret) + goto end; + + ret = crypto_bignum_bin2bn(K, bytes, ephemeral.d); + if (ret) + goto endk; + + /* Call PKI hW */ + ret = versal_ecc_sign_ephemeral(algo, bytes, &key, &ephemeral, hash, + bytes, sig, &sig_len); + if (ret == TEE_SUCCESS) { + /* Check generated signature */ + if ((memcmp((uint8_t *)sig, SignR, bytes) != 0) || + (memcmp((uint8_t *)sig + bytes, SignS, bytes) != 0)) + ret = TEE_ERROR_SIGNATURE_INVALID; + } + +endk: + crypto_bignum_free(&ephemeral.x); + crypto_bignum_free(&ephemeral.y); + crypto_bignum_free(&ephemeral.d); +end: + crypto_bignum_free(&key.x); + crypto_bignum_free(&key.y); + crypto_bignum_free(&key.d); + + return ret; +} + +static TEE_Result versal_ecc_verify_kat(uint32_t curve) +{ + TEE_Result ret = TEE_SUCCESS; + size_t bytes; + size_t bits; + struct ecc_public_key pkey; + + uint32_t algo; + uint8_t *Qx; + uint8_t *Qy; + uint8_t *SignR; + uint8_t *SignS; + uint8_t *hash; + uint8_t sig[(TEE_SHA512_HASH_SIZE + 2) * 2]; + + switch (curve) { + case TEE_ECC_CURVE_NIST_P256: + algo = TEE_ALG_ECDSA_SHA256; + Qx = (uint8_t *)PubkeyQx_P256; + Qy = (uint8_t *)PubkeyQy_P256; + SignR = (uint8_t *)SignR_P256; + SignS = (uint8_t *)SignS_P256; + hash = (uint8_t *)H_P256; + break; + case TEE_ECC_CURVE_NIST_P384: + algo = TEE_ALG_ECDSA_SHA384; + Qx = (uint8_t *)PubkeyQx_P384; + Qy = (uint8_t *)PubkeyQy_P384; + SignR = (uint8_t *)SignR_P384; + SignS = (uint8_t *)SignS_P384; + hash = (uint8_t *)H_P384; + break; + case TEE_ECC_CURVE_NIST_P521: + algo = TEE_ALG_ECDSA_SHA512; + Qx = (uint8_t *)PubkeyQx_P521; + Qy = (uint8_t *)PubkeyQy_P521; + SignR = (uint8_t *)SignR_P521; + SignS = (uint8_t *)SignS_P521; + hash = (uint8_t *)H_P521; + break; + default: + return TEE_ERROR_NOT_SUPPORTED; + } + + ret = versal_ecc_get_key_size(curve, &bytes, &bits); + if (ret) + return ret; + + /* Prepare public key */ + ret = crypto_asym_alloc_ecc_public_key(&pkey, TEE_TYPE_ECDSA_PUBLIC_KEY, + bits); + if (ret) + return ret; + pkey.curve = curve; + + ret = crypto_bignum_bin2bn(Qx, bytes, pkey.x); + if (ret) + goto end; + ret = crypto_bignum_bin2bn(Qy, bytes, pkey.y); + if (ret) + goto end; + + /* Prepare signature to verify */ + memcpy((uint8_t *)sig, SignR, bytes); + memcpy((uint8_t *)sig + bytes, SignS, bytes); + + /* Call PKI hW */ + ret = versal_ecc_verify(algo, &pkey, hash, bytes, sig, 2 * bytes); + +end: + crypto_bignum_free(&pkey.x); + crypto_bignum_free(&pkey.y); + return ret; +} + +TEE_Result versal_ecc_kat(void) +{ + TEE_Result ret = TEE_SUCCESS; + + ret = versal_ecc_sign_kat(TEE_ECC_CURVE_NIST_P256); + if (ret) + return ret; + + ret = versal_ecc_verify_kat(TEE_ECC_CURVE_NIST_P256); + if (ret) + return ret; + + ret = versal_ecc_sign_kat(TEE_ECC_CURVE_NIST_P384); + if (ret) + return ret; + + ret = versal_ecc_verify_kat(TEE_ECC_CURVE_NIST_P384); + if (ret) + return ret; + + ret = versal_ecc_sign_kat(TEE_ECC_CURVE_NIST_P521); + if (ret) + return ret; + + ret = versal_ecc_verify_kat(TEE_ECC_CURVE_NIST_P521); + if (ret) + return ret; + + return ret; +} + +#ifdef CFG_VERSAL_PKI_PWCT +TEE_Result versal_ecc_keypair_pwct(struct ecc_keypair *s) +{ + struct ecc_public_key pkey; + TEE_Result ret = TEE_SUCCESS; + + uint32_t algo; + size_t bytes; + size_t bits; + size_t len; + + uint8_t msg[TEE_SHA512_HASH_SIZE + 2] = { }; + uint8_t sig[(TEE_SHA512_HASH_SIZE + 2) * 2] = { }; + + switch (s->curve) { + case TEE_ECC_CURVE_NIST_P256: + algo = TEE_ALG_ECDSA_SHA256; + break; + case TEE_ECC_CURVE_NIST_P384: + algo = TEE_ALG_ECDSA_SHA384; + break; + case TEE_ECC_CURVE_NIST_P521: + algo = TEE_ALG_ECDSA_SHA512; + break; + default: + return TEE_ERROR_NOT_SUPPORTED; + } + + ret = versal_ecc_get_key_size(s->curve, &bytes, &bits); + if (ret) + return ret; + + len = bytes * 2; + + ret = versal_ecc_sign(algo, s, msg, bytes, sig, &len); + if (ret) { + DMSG("Error signing message 0x%" PRIx32, ret); + return ret; + } + + ret = crypto_acipher_alloc_ecc_public_key(&pkey, + TEE_TYPE_ECDSA_PUBLIC_KEY, + bits); + if (ret) { + DMSG("Error allocating ECDSA public key 0x%" PRIx32, ret); + return ret; + } + + crypto_bignum_free(&pkey.x); + crypto_bignum_free(&pkey.y); + pkey.x = s->x; + pkey.y = s->y; + pkey.curve = s->curve; + + ret = versal_ecc_verify(algo, &pkey, msg, bytes, sig, bytes * 2); + if (ret) + DMSG("Error verifying signature 0x%" PRIx32, ret); + + return ret; +} +#endif diff --git a/core/drivers/crypto/versal/pki/sub.mk b/core/drivers/crypto/versal/pki/sub.mk new file mode 100644 index 00000000000..27083570893 --- /dev/null +++ b/core/drivers/crypto/versal/pki/sub.mk @@ -0,0 +1,4 @@ +incdirs-y += ../include + +srcs-y += ecc_pki_engine.c +srcs-y += ecc_pki_kat.c diff --git a/core/drivers/crypto/versal/sub.mk b/core/drivers/crypto/versal/sub.mk index 56184690001..b4cc1bbc165 100644 --- a/core/drivers/crypto/versal/sub.mk +++ b/core/drivers/crypto/versal/sub.mk @@ -3,4 +3,9 @@ incdirs-y += include srcs-y += ipi.c srcs-y += authenc.c srcs-y += ecc.c +ifeq ($(CFG_VERSAL_PKI_DRIVER),y) +subdirs-y += pki +else +srcs-y += ecc_mbox.c +endif srcs-y += rsa.c diff --git a/core/drivers/versal_trng.c b/core/drivers/versal_trng.c index 63e894c9344..62e812507c5 100644 --- a/core/drivers/versal_trng.c +++ b/core/drivers/versal_trng.c @@ -65,12 +65,9 @@ #include #include #include +#include #include -#ifndef CFG_VERSAL_RNG_PLM -#define TRNG_BASE 0xF1230000 -#define TRNG_SIZE 0x10000 - #define TRNG_STATUS 0x04 #define TRNG_STATUS_QCNT_SHIFT 9 #define TRNG_STATUS_QCNT_MASK (BIT(9) | BIT(10) | BIT(11)) @@ -137,87 +134,12 @@ #define PRNGMODE_GEN TRNG_CTRL_PRNGMODE_MASK #define RESET_DELAY 10 #define TRNG_SEC_STRENGTH_LEN 32 -#define TRNG_PERS_STR_REGS 12 -#define TRNG_PERS_STR_LEN 48 #define TRNG_SEED_REGS 12 -#define TRNG_SEED_LEN 48 #define TRNG_GEN_LEN 32 -#define RAND_BUF_LEN 4 #define BYTES_PER_BLOCK 16 #define ALL_A_PATTERN_32 0xAAAAAAAA #define ALL_5_PATTERN_32 0x55555555 -/* Derivative function helper macros */ -#define DF_SEED 0 -#define DF_RAND 1 -#define DF_IP_IV_LEN 4 -#define DF_PAD_DATA_LEN 8 -#define MAX_PRE_DF_LEN 160 -#define MAX_PRE_DF_LEN_WORDS 40 -#define DF_PERS_STR_LEN TRNG_PERS_STR_LEN -#define DF_PAD_VAL 0x80 -#define DF_KEY_LEN 32 -#define BLK_SIZE 16 -#define MAX_ROUNDS 14 - -enum trng_status { - TRNG_UNINITIALIZED = 0, - TRNG_HEALTHY, - TRNG_ERROR, - TRNG_CATASTROPHIC -}; - -enum trng_mode { - TRNG_HRNG = 0, - TRNG_DRNG, - TRNG_PTRNG -}; - -struct trng_cfg { - paddr_t base; - vaddr_t addr; - size_t len; -}; - -struct trng_usr_cfg { - enum trng_mode mode; - uint64_t seed_life; /* number of TRNG requests per seed */ - bool predict_en; /* enable prediction resistance */ - bool pstr_en; /* enable personalization string */ - uint32_t pstr[TRNG_PERS_STR_REGS]; - bool iseed_en; /* enable an initial seed */ - uint32_t init_seed[MAX_PRE_DF_LEN_WORDS]; - uint32_t df_disable; /* disable the derivative function */ - uint32_t dfmul; /* derivative function multiplier */ -}; - -struct trng_stats { - uint64_t bytes; - uint64_t bytes_reseed; - uint64_t elapsed_seed_life; -}; - -/* block cipher derivative function algorithm */ -struct trng_dfin { - uint32_t ivc[DF_IP_IV_LEN]; - uint32_t val1; - uint32_t val2; - uint8_t entropy[MAX_PRE_DF_LEN]; /* input entropy */ - uint8_t pstr[DF_PERS_STR_LEN]; /* personalization string */ - uint8_t pad_data[DF_PAD_DATA_LEN]; /* pad to multiples of 16 bytes*/ -}; - -struct versal_trng { - struct trng_cfg cfg; - struct trng_usr_cfg usr_cfg; - struct trng_stats stats; - enum trng_status status; - uint32_t buf[RAND_BUF_LEN]; /* buffer of random bits */ - size_t len; - struct trng_dfin dfin; - uint8_t dfout[TRNG_SEED_LEN]; /* output of the DF operation */ -}; - /* Derivative function variables */ static unsigned char sbx1[256]; static unsigned char sbx2[256]; @@ -1064,25 +986,21 @@ static TEE_Result trng_kat_test(struct versal_trng *trng) return TEE_ERROR_GENERIC; } -static struct versal_trng versal_trng = { - .cfg.base = TRNG_BASE, - .cfg.len = TRNG_SIZE, -}; - -TEE_Result hw_get_random_bytes(void *buf, size_t len) +TEE_Result versal_trng_get_random_bytes(struct versal_trng *trng, + void *buf, size_t len) { uint8_t random[TRNG_SEC_STRENGTH_LEN] = { 0 }; uint8_t *p = buf; size_t i = 0; for (i = 0; i < len / TRNG_SEC_STRENGTH_LEN; i++) { - if (trng_generate(&versal_trng, p + i * TRNG_SEC_STRENGTH_LEN, + if (trng_generate(trng, p + i * TRNG_SEC_STRENGTH_LEN, TRNG_SEC_STRENGTH_LEN, false)) panic(); } if (len % TRNG_SEC_STRENGTH_LEN) { - if (trng_generate(&versal_trng, random, TRNG_SEC_STRENGTH_LEN, + if (trng_generate(trng, random, TRNG_SEC_STRENGTH_LEN, false)) panic(); memcpy(p + i * TRNG_SEC_STRENGTH_LEN, random, @@ -1092,8 +1010,52 @@ TEE_Result hw_get_random_bytes(void *buf, size_t len) return TEE_SUCCESS; } -void plat_rng_init(void) +TEE_Result versal_trng_hw_init(struct versal_trng *trng, + struct trng_usr_cfg *usr_cfg) { + trng->cfg.addr = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, + trng->cfg.base, + trng->cfg.len); + if (!trng->cfg.addr) { + EMSG("Failed to map TRNG"); + panic(); + } + + if (trng_kat_test(trng)) { + EMSG("KAT Failed"); + panic(); + } + + if (trng_health_test(trng)) { + EMSG("RunHealthTest Failed"); + panic(); + } + + if (trng_instantiate(trng, usr_cfg)) { + EMSG("Driver instantiation Failed"); + panic(); + } + + if (trng_reseed(trng, NULL, usr_cfg->dfmul)) { + EMSG("Reseed Failed"); + panic(); + } + + return TEE_SUCCESS; +} + +#ifndef CFG_VERSAL_RNG_PLM +#define TRNG_BASE 0xF1230000 +#define TRNG_SIZE 0x10000 + +static struct versal_trng versal_trng = { + .cfg.base = TRNG_BASE, + .cfg.len = TRNG_SIZE, +}; + +TEE_Result hw_get_random_bytes(void *buf, size_t len) +{ + return versal_trng_get_random_bytes(&versal_trng, buf, len); } static TEE_Result trng_hrng_mode_init(void) @@ -1106,6 +1068,7 @@ static TEE_Result trng_hrng_mode_init(void) 0xBC, 0x23, 0x18, 0x15, 0xCB, 0xB8, 0xA6, 0x3E, 0x83, 0xB8, 0x4A, 0xFE, 0x38, 0xFC, 0x25, 0x87, }; + /* configure in hybrid mode with derivative function enabled */ struct trng_usr_cfg usr_cfg = { .mode = TRNG_HRNG, @@ -1118,39 +1081,11 @@ static TEE_Result trng_hrng_mode_init(void) }; memcpy(usr_cfg.pstr, pers_str, TRNG_PERS_STR_LEN); - versal_trng.cfg.addr = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, - versal_trng.cfg.base, - versal_trng.cfg.len); - if (!versal_trng.cfg.addr) { - EMSG("Failed to map TRNG"); - panic(); - } - if (trng_kat_test(&versal_trng)) { - EMSG("KAT Failed"); - panic(); - } - - if (trng_health_test(&versal_trng)) { - EMSG("RunHealthTest Failed"); - panic(); - } - - if (trng_instantiate(&versal_trng, &usr_cfg)) { - EMSG("Driver instantiation Failed"); - panic(); - } - - if (trng_reseed(&versal_trng, NULL, usr_cfg.dfmul)) { - EMSG("Reseed Failed"); - panic(); - } - - return TEE_SUCCESS; + return versal_trng_hw_init(&versal_trng, &usr_cfg); } driver_init(trng_hrng_mode_init); - #else #define SEC_MODULE_SHIFT 8 #define SEC_MODULE_ID 5 @@ -1215,8 +1150,8 @@ TEE_Result hw_get_random_bytes(void *buf, size_t len) versal_mbox_free(&p); return ret; } +#endif void plat_rng_init(void) { } -#endif diff --git a/core/include/drivers/versal_trng.h b/core/include/drivers/versal_trng.h new file mode 100644 index 00000000000..26b75cc111c --- /dev/null +++ b/core/include/drivers/versal_trng.h @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (C) 2023 ProvenRun SAS. + */ + +#ifndef __DRIVERS_VERSAL_TRNG_H +#define __DRIVERS_VERSAL_TRNG_H + +#include +#include +#include +#include + +#define TRNG_SEED_LEN 48 +#define TRNG_PERS_STR_REGS 12 +#define TRNG_PERS_STR_LEN 48 +#define RAND_BUF_LEN 4 + +/* Derivative function helper macros */ +#define DF_SEED 0 +#define DF_RAND 1 +#define DF_IP_IV_LEN 4 +#define DF_PAD_DATA_LEN 8 +#define MAX_PRE_DF_LEN 160 +#define MAX_PRE_DF_LEN_WORDS 40 +#define DF_PERS_STR_LEN TRNG_PERS_STR_LEN +#define DF_PAD_VAL 0x80 +#define DF_KEY_LEN 32 +#define BLK_SIZE 16 +#define MAX_ROUNDS 14 + +enum trng_status { + TRNG_UNINITIALIZED = 0, + TRNG_HEALTHY, + TRNG_ERROR, + TRNG_CATASTROPHIC +}; + +enum trng_mode { + TRNG_HRNG = 0, + TRNG_DRNG, + TRNG_PTRNG +}; + +struct trng_cfg { + paddr_t base; + vaddr_t addr; + size_t len; +}; + +struct trng_usr_cfg { + enum trng_mode mode; + uint64_t seed_life; /* number of TRNG requests per seed */ + bool predict_en; /* enable prediction resistance */ + bool pstr_en; /* enable personalization string */ + uint32_t pstr[TRNG_PERS_STR_REGS]; + bool iseed_en; /* enable an initial seed */ + uint32_t init_seed[MAX_PRE_DF_LEN_WORDS]; + uint32_t df_disable; /* disable the derivative function */ + uint32_t dfmul; /* derivative function multiplier */ +}; + +struct trng_stats { + uint64_t bytes; + uint64_t bytes_reseed; + uint64_t elapsed_seed_life; +}; + +/* block cipher derivative function algorithm */ +struct trng_dfin { + uint32_t ivc[DF_IP_IV_LEN]; + uint32_t val1; + uint32_t val2; + uint8_t entropy[MAX_PRE_DF_LEN]; /* input entropy */ + uint8_t pstr[DF_PERS_STR_LEN]; /* personalization string */ + uint8_t pad_data[DF_PAD_DATA_LEN]; /* pad to multiples of 16 bytes*/ +}; + +struct versal_trng { + struct trng_cfg cfg; + struct trng_usr_cfg usr_cfg; + struct trng_stats stats; + enum trng_status status; + uint32_t buf[RAND_BUF_LEN]; /* buffer of random bits */ + size_t len; + struct trng_dfin dfin; + uint8_t dfout[TRNG_SEED_LEN]; /* output of the DF operation */ +}; + +TEE_Result versal_trng_hw_init(struct versal_trng *trng, + struct trng_usr_cfg *usr_cfg); +TEE_Result versal_trng_get_random_bytes(struct versal_trng *trng, + void *buf, size_t len); + +#endif /* __DRIVERS_VERSAL_TRNG_H */ From 5e0d4a9dc3091932df80eda42cc2667476c87fec Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Mon, 11 Dec 2023 16:45:17 +0100 Subject: [PATCH 05/43] drivers: versal: use HKDF to derive the HUK The original HUK driver generated the HUK using SHA-256. This commit replaces this mechanism with the more robust HKDF-SHA256. Signed-off-by: Jeremie Corbier --- core/drivers/versal_huk.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/core/drivers/versal_huk.c b/core/drivers/versal_huk.c index 251105f3344..900fb4d1ee0 100644 --- a/core/drivers/versal_huk.c +++ b/core/drivers/versal_huk.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include @@ -341,8 +341,15 @@ TEE_Result tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey) goto cleanup; } - if (tee_hash_createdigest(TEE_ALG_SHA256, enc_data, sizeof(enc_data), - huk.key, sizeof(huk.key))) { + /* + * Use RFC 5869 HKDF to derive a key from HUK-seed: + * HUK-seed = AES-GCM-encrypt(K, DNA) + * where K is either PUF KEK or eFuse User Keys 0 or 1 + * + * HKDF salt and info are set empty for now + */ + if (tee_cryp_hkdf(TEE_MAIN_ALGO_SHA256, enc_data, sizeof(enc_data), + NULL, 0, NULL, 0, huk.key, sizeof(huk.key))) { ret = TEE_ERROR_GENERIC; goto cleanup; } From caf9ea91c65dd3009230edc544883ebea3d64644 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Thu, 14 Dec 2023 17:27:59 +0100 Subject: [PATCH 06/43] core: pta: add Versal FPGA PTA Add simple PTA allowing to dynamically load data in the Versal PL. Signed-off-by: Jeremie Corbier --- core/arch/arm/plat-versal/conf.mk | 2 + core/pta/sub.mk | 3 +- core/pta/versal/fpga_pta.c | 55 +++++++++++++++++++++++++++ core/pta/versal/sub.mk | 1 + lib/libutee/include/pta_versal_fpga.h | 25 ++++++++++++ 5 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 core/pta/versal/fpga_pta.c create mode 100644 core/pta/versal/sub.mk create mode 100644 lib/libutee/include/pta_versal_fpga.h diff --git a/core/arch/arm/plat-versal/conf.mk b/core/arch/arm/plat-versal/conf.mk index 77205da6d2b..c0e116cf14a 100644 --- a/core/arch/arm/plat-versal/conf.mk +++ b/core/arch/arm/plat-versal/conf.mk @@ -117,4 +117,6 @@ ifneq ($(CFG_VERSAL_HUK_KEY),$(filter 6 7 11 12,$(firstword $(CFG_VERSAL_HUK_KEY $(error Invalid value: CFG_VERSAL_HUK_KEY=$(CFG_VERSAL_HUK_KEY)) endif +CFG_VERSAL_FPGA_LOADER_PTA ?= y + CFG_CORE_HEAP_SIZE ?= 262144 diff --git a/core/pta/sub.mk b/core/pta/sub.mk index 1cb148a32c1..f07171043f2 100644 --- a/core/pta/sub.mk +++ b/core/pta/sub.mk @@ -19,6 +19,7 @@ subdirs-y += bcm subdirs-y += stm32mp subdirs-y += imx subdirs-y += k3 +subdirs-y += versal ifeq ($(CFG_REMOTEPROC_PTA),y) gensrcs-y += rproc_pub_key @@ -27,4 +28,4 @@ depends-rproc_pub_key = $(RPROC_SIGN_KEY) scripts/pem_to_pub_c.py recipe-rproc_pub_key = $(PYTHON3) scripts/pem_to_pub_c.py \ --prefix rproc_pub_key --key $(RPROC_SIGN_KEY) \ --out $(sub-dir-out)/rproc_pub_key.c -endif \ No newline at end of file +endif diff --git a/core/pta/versal/fpga_pta.c b/core/pta/versal/fpga_pta.c new file mode 100644 index 00000000000..2bf941be85c --- /dev/null +++ b/core/pta/versal/fpga_pta.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright 2023 ProvenRun SAS + */ +#include +#include +#include +#include +#include +#include +#include + +#define FPGA_PTA_NAME "fpga.pta" + +static TEE_Result pta_versal_fpga_write(uint32_t param_types, + TEE_Param params[TEE_NUM_PARAMS]) +{ + uint8_t *buf; + size_t bufsize; + uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE); + + if (param_types != exp_param_types) + return TEE_ERROR_BAD_PARAMETERS; + + bufsize = ROUNDUP(params[0].memref.size, CACHELINE_LEN); + + buf = memalign(CACHELINE_LEN, bufsize); + if (!buf) + return TEE_ERROR_OUT_OF_MEMORY; + + memcpy(buf, params[0].memref.buffer, bufsize); + cache_operation(TEE_CACHEFLUSH, buf, bufsize); + + return versal_write_fpga(virt_to_phys(buf)); +} + +static TEE_Result invokeCommandEntryPoint(void *sess_ctx __unused, + uint32_t cmd_id, + uint32_t param_types, + TEE_Param params[TEE_NUM_PARAMS]) +{ + switch (cmd_id) { + case PTA_VERSAL_FPGA_WRITE: + return pta_versal_fpga_write(param_types, params); + default: + return TEE_ERROR_BAD_PARAMETERS; + } +} + +pseudo_ta_register(.uuid = PTA_VERSAL_FPGA_UUID, .name = FPGA_PTA_NAME, + .flags = PTA_DEFAULT_FLAGS, + .invoke_command_entry_point = invokeCommandEntryPoint); diff --git a/core/pta/versal/sub.mk b/core/pta/versal/sub.mk new file mode 100644 index 00000000000..f31de801902 --- /dev/null +++ b/core/pta/versal/sub.mk @@ -0,0 +1 @@ +srcs-$(CFG_VERSAL_FPGA_LOADER_PTA) += fpga_pta.c diff --git a/lib/libutee/include/pta_versal_fpga.h b/lib/libutee/include/pta_versal_fpga.h new file mode 100644 index 00000000000..c5a2ba30643 --- /dev/null +++ b/lib/libutee/include/pta_versal_fpga.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (C) 2023, ProvenRun SAS + */ + +#ifndef __PTA_VERSAL_FPGA_H +#define __PTA_VERSAL_FPGA_H + +#define PTA_VERSAL_FPGA_UUID { 0xa6b493c0, 0xe100, 0x4a13, \ + { 0x9b, 0x00, 0xbc, 0xe4, 0x2d, 0x53, 0xce, 0xd8 } } + +/** + * Write FPGA bitstream + * + * [in] memref[0].buffer FPGA bitstream buffer + * [in] memref[0].size FPGA bitstream buffer size + * + * Return codes: + * TEE_SUCCESS - Invoke command success + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param + * TEE_ERROR_OUT_OF_MEMORY - Could not alloc internal buffer + */ +#define PTA_VERSAL_FPGA_WRITE 0x0 + + #endif /* __PTA_VERSAL_FPGA_H */ From 9267cb6e4143161e0169cef6359018779224bf94 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 24 Jan 2024 15:49:24 +0100 Subject: [PATCH 07/43] drivers: versal: update to support more recent versions of the PLM - update crypto API IDs - update calls to the KAT subsystem Signed-off-by: Jeremie Corbier --- core/drivers/crypto/versal/include/ipi.h | 27 ++++++++++----- core/drivers/crypto/versal/rsa.c | 23 ++++++++++++- core/drivers/versal_huk.c | 4 +-- core/drivers/versal_mbox.c | 44 +++++++++++------------- core/drivers/versal_pm.c | 15 +++++--- core/drivers/versal_sha3_384.c | 10 +++++- 6 files changed, 83 insertions(+), 40 deletions(-) diff --git a/core/drivers/crypto/versal/include/ipi.h b/core/drivers/crypto/versal/include/ipi.h index 2c92a1a9bc1..2c3c08ec2d8 100644 --- a/core/drivers/crypto/versal/include/ipi.h +++ b/core/drivers/crypto/versal/include/ipi.h @@ -57,15 +57,12 @@ enum versal_crypto_api { VERSAL_RSA_SIGN_VERIFY, VERSAL_RSA_PUBLIC_ENCRYPT, VERSAL_RSA_PRIVATE_DECRYPT, - VERSAL_RSA_KAT, - VERSAL_SHA3_UPDATE = 32U, - VERSAL_SHA3_KAT, - VERSAL_ELLIPTIC_GENERATE_PUBLIC_KEY = 64U, + VERSAL_SHA3_UPDATE, + VERSAL_ELLIPTIC_GENERATE_PUBLIC_KEY, VERSAL_ELLIPTIC_GENERATE_SIGN, VERSAL_ELLIPTIC_VALIDATE_PUBLIC_KEY, VERSAL_ELLIPTIC_VERIFY_SIGN, - VERSAL_ELLIPTIC_KAT, - VERSAL_AES_INIT = 96U, + VERSAL_AES_INIT, VERSAL_AES_OP_INIT, VERSAL_AES_UPDATE_AAD, VERSAL_AES_ENCRYPT_UPDATE, @@ -77,11 +74,25 @@ enum versal_crypto_api { VERSAL_AES_LOCK_USER_KEY, VERSAL_AES_KEK_DECRYPT, VERSAL_AES_SET_DPA_CM, - VERSAL_AES_DECRYPT_KAT, - VERSAL_AES_DECRYPT_CM_KAT, + VERSAL_KAT, + VERSAL_TRNG_GENERATE, + VERSAL_AES_PERFORM_OPERATION, VERSAL_CRYPTO_API_MAX }; +enum versal_crypto_kat { + VERSAL_AES_DECRYPT_KAT = 0U, + VERSAL_AES_DECRYPT_CM_KAT, + VERSAL_RSA_PUB_ENC_KAT, + VERSAL_ELLIPTIC_SIGN_VERIFY_KAT, + VERSAL_SHA3_KAT, + VERSAL_AES_ENCRYPT_KAT, + VERSAL_RSA_PRIVATE_DEC_KAT, + VERSAL_ELLIPTIC_SIGN_GEN_KAT, + VERSAL_TRNG_KAT, + VERSAL_UPDATE_KAT_STATUS, +}; + #define VERSAL_MAX_IPI_REGS 6 struct versal_cmd_args { diff --git a/core/drivers/crypto/versal/rsa.c b/core/drivers/crypto/versal/rsa.c index 2fd0237ce44..46e4195b886 100644 --- a/core/drivers/crypto/versal/rsa.c +++ b/core/drivers/crypto/versal/rsa.c @@ -359,11 +359,32 @@ static struct drvcrypt_rsa driver_rsa = { static TEE_Result rsa_init(void) { + uint32_t err = 0; struct versal_cmd_args arg = { }; - if (versal_crypto_request(VERSAL_RSA_KAT, &arg, NULL)) + arg.data[arg.dlen++] = VERSAL_RSA_PUB_ENC_KAT; + + if (versal_crypto_request(VERSAL_KAT, &arg, &err)) + return TEE_ERROR_GENERIC; + + if (err) { + DMSG("RSA_PUB_ENC_KAT returned 0x%" PRIx32, err); + return TEE_ERROR_GENERIC; + } + + /* Clear previous request */ + arg.dlen = 0; + + arg.data[arg.dlen++] = VERSAL_RSA_PRIVATE_DEC_KAT; + + if (versal_crypto_request(VERSAL_KAT, &arg, &err)) return TEE_ERROR_GENERIC; + if (err) { + DMSG("RSA_PRIVATE_DEC_KAT returned 0x%" PRIx32, err); + return TEE_ERROR_GENERIC; + } + return drvcrypt_register_rsa(&driver_rsa); } diff --git a/core/drivers/versal_huk.c b/core/drivers/versal_huk.c index 900fb4d1ee0..6646153a96f 100644 --- a/core/drivers/versal_huk.c +++ b/core/drivers/versal_huk.c @@ -56,7 +56,7 @@ enum versal_aes_key_src { }; enum versal_crypto_api { - VERSAL_AES_INIT = 96U, + VERSAL_AES_INIT = 9U, VERSAL_AES_OP_INIT, VERSAL_AES_UPDATE_AAD, VERSAL_AES_ENCRYPT_UPDATE, @@ -68,8 +68,6 @@ enum versal_crypto_api { VERSAL_AES_LOCK_USER_KEY, VERSAL_AES_KEK_DECRYPT, VERSAL_AES_SET_DPA_CM, - VERSAL_AES_DECRYPT_KAT, - VERSAL_AES_DECRYPT_CM_KAT, }; struct versal_aes_input_param { diff --git a/core/drivers/versal_mbox.c b/core/drivers/versal_mbox.c index 97370cc806f..4a276be9dc7 100644 --- a/core/drivers/versal_mbox.c +++ b/core/drivers/versal_mbox.c @@ -204,29 +204,27 @@ static const char *const crypto_id[] = { [1] = "RSA_SIGN_VERIFY", [2] = "RSA_PUBLIC_ENCRYPT", [3] = "RSA_PRIVATE_DECRYPT", - [4] = "RSA_KAT", - [32] = "SHA3_UPDATE", - [33] = "SHA3_KAT", - [64] = "ELLIPTIC_GENERATE_PUBLIC_KEY", - [65] = "ELLIPTIC_GENERATE_SIGN", - [66] = "ELLIPTIC_VALIDATE_PUBLIC_KEY", - [67] = "ELLIPTIC_VERIFY_SIGN", - [68] = "ELLIPTIC_KAT", - [96] = "AES_INIT", - [97] = "AES_OP_INIT", - [98] = "AES_UPDATE_AAD", - [99] = "AES_ENCRYPT_UPDATE", - [100] = "AES_ENCRYPT_FINAL", - [101] = "AES_DECRYPT_UPDATE", - [102] = "AES_DECRYPT_FINAL", - [103] = "AES_KEY_ZERO", - [104] = "AES_WRITE_KEY", - [105] = "AES_LOCK_USER_KEY", - [106] = "AES_KEK_DECRYPT", - [107] = "AES_SET_DPA_CM", - [108] = "AES_DECRYPT_KAT", - [109] = "AES_DECRYPT_CM_KAT", - [110] = "MAX", + [4] = "SHA3_UPDATE", + [5] = "ELLIPTIC_GENERATE_PUBLIC_KEY", + [6] = "ELLIPTIC_GENERATE_SIGN", + [7] = "ELLIPTIC_VALIDATE_PUBLIC_KEY", + [8] = "ELLIPTIC_VERIFY_SIGN", + [9] = "AES_INIT", + [10] = "AES_OP_INIT", + [11] = "AES_UPDATE_AAD", + [12] = "AES_ENCRYPT_UPDATE", + [13] = "AES_ENCRYPT_FINAL", + [14] = "AES_DECRYPT_UPDATE", + [15] = "AES_DECRYPT_FINAL", + [16] = "AES_KEY_ZERO", + [17] = "AES_WRITE_KEY", + [18] = "AES_LOCK_USER_KEY", + [19] = "AES_KEK_DECRYPT", + [20] = "AES_SET_DPA_CM", + [21] = "KAT", + [22] = "TRNG_GENERATE", + [23] = "AES_PERFORM_OPERATION", + [24] = "MAX", }; static const char *const puf_id[] = { diff --git a/core/drivers/versal_pm.c b/core/drivers/versal_pm.c index b1ac7128000..ee43592b0e4 100644 --- a/core/drivers/versal_pm.c +++ b/core/drivers/versal_pm.c @@ -19,10 +19,17 @@ #include /* VERSAL_SIP_UID: 2ab9e4ec-93b9-11e7-a019dfe0dbad0ae0 */ +#if defined(PLATFORM_FLAVOR_net) +#define VERSAL_SIP_UID_0 U(0x5ac2d480) +#define VERSAL_SIP_UID_1 U(0xeb11afeb) +#define VERSAL_SIP_UID_2 U(0x4e0b6894) +#define VERSAL_SIP_UID_3 U(0x60c38f3b) +#else #define VERSAL_SIP_UID_0 U(0xece4b92a) #define VERSAL_SIP_UID_1 U(0xe711b993) #define VERSAL_SIP_UID_2 U(0xe0df19a0) #define VERSAL_SIP_UID_3 U(0xe00aaddb) +#endif #define VERSAL_SIP_MAJOR 0 #define VERSAL_SIP_MINOR 1 @@ -36,8 +43,8 @@ #define PM_MODULE_SHIFT 8 #define PM_MODULE 2 #define PM_API_ID(x) ((PM_MODULE << PM_MODULE_SHIFT) | (x)) -#define VERSAL_PM_MAJOR 0 -#define VERSAL_PM_MINOR 1 +#define VERSAL_PM_MAJOR 1 +#define VERSAL_PM_MINOR 0 /* PM API ids */ #define PM_GET_API_VERSION 1 @@ -202,8 +209,8 @@ static TEE_Result versal_check_pm_abi(void) if (versal_mbox_notify_pmc(&cmd, &rsp, NULL)) return TEE_ERROR_GENERIC; - major = rsp.data[1] & 0xFFFF; - minor = rsp.data[1] >> 16; + minor = rsp.data[1] & 0xFFFF; + major = rsp.data[1] >> 16; if (major != VERSAL_PM_MAJOR || minor < VERSAL_PM_MINOR) { EMSG("Invalid PM version: Major %d, Minor %d", major, minor); return TEE_ERROR_GENERIC; diff --git a/core/drivers/versal_sha3_384.c b/core/drivers/versal_sha3_384.c index 52ded36042a..10520890a7c 100644 --- a/core/drivers/versal_sha3_384.c +++ b/core/drivers/versal_sha3_384.c @@ -95,13 +95,21 @@ TEE_Result versal_sha3_384(const uint8_t *src, size_t src_len, static TEE_Result versal_sha3_384_init(void) { + uint32_t err = 0; struct versal_cmd_args arg = { }; TEE_Result ret = TEE_SUCCESS; - ret = versal_crypto_request(VERSAL_SHA3_KAT, &arg, NULL); + arg.data[arg.dlen++] = VERSAL_SHA3_KAT; + + ret = versal_crypto_request(VERSAL_KAT, &arg, &err); if (!ret) engine_ready = true; + if (err) { + DMSG("SHA3 KAT returned 0x%" PRIx32, err); + return TEE_ERROR_GENERIC; + } + return ret; } From 10d334a2e46b9ad37b682d1a49aa9072100bde1f Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Tue, 30 Jan 2024 14:21:52 +0100 Subject: [PATCH 08/43] drivers: versal: NVM driver for Versal Net The XilNvm API has heavily changed between Versal and Versal Net. This commit adds support for the Net variant. Signed-off-by: Jeremie Corbier --- core/arch/arm/plat-versal/conf.mk | 1 + core/drivers/versal_huk.c | 11 + core/drivers/versal_nvm.c | 1171 ++++++++++++++++++++++++----- core/include/drivers/versal_nvm.h | 10 + 4 files changed, 1024 insertions(+), 169 deletions(-) diff --git a/core/arch/arm/plat-versal/conf.mk b/core/arch/arm/plat-versal/conf.mk index c0e116cf14a..1cae4af59e0 100644 --- a/core/arch/arm/plat-versal/conf.mk +++ b/core/arch/arm/plat-versal/conf.mk @@ -106,6 +106,7 @@ CFG_VERSAL_SHA3_384 ?= y CFG_VERSAL_PUF ?= y # Enable Hardware Unique Key driver +CFG_VERSAL_DUMMY_DNA ?= n CFG_VERSAL_HUK ?= y # AES-GCM supported key sources for HUK: # 6 : eFUSE USR 0 diff --git a/core/drivers/versal_huk.c b/core/drivers/versal_huk.c index 6646153a96f..f42866da4d7 100644 --- a/core/drivers/versal_huk.c +++ b/core/drivers/versal_huk.c @@ -108,6 +108,13 @@ struct versal_aes_init { 0xa1, 0x33, \ } +#ifdef CFG_VERSAL_DUMMY_DNA +static uint8_t dummy_dna[EFUSE_DNA_LEN] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, +}; +#endif + static bool versal_persistent_key(enum versal_aes_key_src src, bool *secure) { struct versal_efuse_puf_sec_ctrl_bits puf_ctrl = { }; @@ -326,8 +333,12 @@ TEE_Result tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey) if (huk.ready) goto out; +#ifndef CFG_VERSAL_DUMMY_DNA if (versal_efuse_read_dna(dna, sizeof(dna))) return TEE_ERROR_GENERIC; +#else + memcpy(dna, dummy_dna, EFUSE_DNA_LEN); +#endif if (versal_sha3_384((uint8_t *)dna, sizeof(dna), sha, sizeof(sha))) { ret = TEE_ERROR_GENERIC; diff --git a/core/drivers/versal_nvm.c b/core/drivers/versal_nvm.c index 657dfa93494..9c4c78e4631 100644 --- a/core/drivers/versal_nvm.c +++ b/core/drivers/versal_nvm.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "drivers/versal_nvm.h" @@ -41,6 +42,46 @@ struct versal_efuse_puf_fuse_addr { */ #define EFUSE_MAX_LEN (EFUSE_MAX_USER_FUSES * sizeof(uint32_t)) +#if defined(PLATFORM_FLAVOR_net) +enum versal_nvm_api_id { + API_FEATURES = 0, + BBRAM_WRITE_AES_KEY = 1, + BBRAM_ZEROIZE = 2, + BBRAM_WRITE_USER_DATA = 3, + BBRAM_READ_USER_DATA = 4, + BBRAM_LOCK_WRITE_USER_DATA = 5, + BBRAM_WRITE_AES_KEY_FROM_PLOAD = 6, + EFUSE_WRITE_AES_KEY = 7, + EFUSE_WRITE_AES_KEY_FROM_PLOAD = 8, + EFUSE_WRITE_PPK_HASH = 9, + EFUSE_WRITE_PPK_HASH_FROM_PLOAD = 10, + EFUSE_WRITE_IV = 11, + EFUSE_WRITE_IV_FROM_PLOAD = 12, + EFUSE_WRITE_GLITCH_CONFIG = 13, + EFUSE_WRITE_DEC_ONLY = 14, + EFUSE_WRITE_REVOCATION_ID = 15, + EFUSE_WRITE_OFFCHIP_REVOKE_ID = 16, + EFUSE_WRITE_MISC_CTRL_BITS = 17, + EFUSE_WRITE_SEC_CTRL_BITS = 18, + EFUSE_WRITE_MISC1_CTRL_BITS = 19, + EFUSE_WRITE_BOOT_ENV_CTRL_BITS = 20, + EFUSE_WRITE_FIPS_INFO = 21, + EFUSE_WRITE_UDS_FROM_PLOAD = 22, + EFUSE_WRITE_DME_KEY_FROM_PLOAD = 23, + EFUSE_WRITE_DME_REVOKE = 24, + EFUSE_WRITE_PLM_UPDATE = 25, + EFUSE_WRITE_BOOT_MODE_DISABLE = 26, + EFUSE_WRITE_CRC = 27, + EFUSE_WRITE_DME_MODE = 28, + EFUSE_WRITE_PUF_HD_FROM_PLOAD = 29, + EFUSE_WRITE_PUF = 30, + EFUSE_WRITE_ROM_RSVD = 31, + EFUSE_WRITE_PUF_CTRL_BITS = 32, + EFUSE_READ_CACHE = 33, + EFUSE_RELOAD_N_PRGM_PROT_BITS = 34, + EFUSE_INVALID = 35, +}; +#else enum versal_nvm_api_id { API_FEATURES = 0, BBRAM_WRITE_AES_KEY = 1, @@ -67,6 +108,7 @@ enum versal_nvm_api_id { EFUSE_READ_PUF = 22, EFUSE_INVALID = 23, }; +#endif /* uint64_t are memory addresses */ struct versal_efuse_data { @@ -125,132 +167,1008 @@ prepare_cmd(struct versal_ipi_cmd *cmd, enum versal_nvm_api_id efuse, if (arg) cmd->data[i++] = *arg; - if (!ibufs[0].buf) - return TEE_SUCCESS; + if (!ibufs[0].buf) + return TEE_SUCCESS; + + reg_pair_from_64(virt_to_phys(ibufs[0].buf), &b, &a); + + cmd->data[i++] = a; + cmd->data[i++] = b; + + for (i = 0; i < VERSAL_MAX_IPI_BUF; i++) { + cmd->ibuf[i].mem.alloc_len = ibufs[i].len; + cmd->ibuf[i].mem.buf = ibufs[i].buf; + } + + return TEE_SUCCESS; +} + +static TEE_Result efuse_req(enum versal_nvm_api_id efuse, + struct versal_nvm_buf *ibufs, uint32_t *arg) +{ + struct versal_ipi_cmd cmd = { }; + TEE_Result ret = TEE_SUCCESS; + + ret = prepare_cmd(&cmd, efuse, ibufs, arg); + if (ret) + return ret; + + ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); + if (ret) + EMSG("Mailbox error"); + + return ret; +} + +static TEE_Result versal_alloc_read_buffer(struct versal_nvm_read_req *req) +{ + assert(req); + req->ibuf[0].len = 1024; + req->ibuf[0].buf = alloc_cache_aligned(req->ibuf[0].len); + if (!req->ibuf[0].buf) + return TEE_ERROR_OUT_OF_MEMORY; + + return TEE_SUCCESS; +} + +static void versal_free_read_buffer(struct versal_nvm_read_req *req) +{ + assert(req); + free(req->ibuf[0].buf); +} + +static void *versal_get_read_buffer(struct versal_nvm_read_req *req) +{ + assert(req); + return req->ibuf[0].buf; +} + +#if defined(PLATFORM_FLAVOR_net) +static TEE_Result versal_nvm_read(struct versal_nvm_read_req *req) +{ + if (!req) + return TEE_ERROR_GENERIC; + + switch (req->efuse_id) { + case EFUSE_READ_CACHE: + case BBRAM_READ_USER_DATA: + break; + default: + return TEE_ERROR_GENERIC; + } + + return efuse_req(req->efuse_id, req->ibuf, NULL); +} + +static TEE_Result versal_nvm_write(struct versal_nvm_write_req *req) +{ + uint32_t *arg = NULL; + uint32_t val = 0; + + switch (req->efuse_id) { + case BBRAM_WRITE_AES_KEY: + val = req->bbram.aes_key_len; + arg = &val; + break; + case BBRAM_WRITE_USER_DATA: + val = req->bbram.user_data; + arg = &val; + break; + case BBRAM_ZEROIZE: + break; + default: + return TEE_ERROR_GENERIC; + } + + return efuse_req(req->efuse_id, req->ibuf, arg); +} +#else +static TEE_Result versal_nvm_read(struct versal_nvm_read_req *req) +{ + uint32_t *arg = NULL; + uint32_t val = 0; + + if (!req) + return TEE_ERROR_GENERIC; + + switch (req->efuse_id) { + case EFUSE_READ_DNA: + case EFUSE_READ_DEC_EFUSE_ONLY: + case EFUSE_READ_PUF_SEC_CTRL: + case EFUSE_READ_BOOT_ENV_CTRL: + case EFUSE_READ_SEC_CTRL: + case EFUSE_READ_MISC_CTRL: + case EFUSE_READ_SEC_MISC1: + case EFUSE_READ_USER_FUSES: + case EFUSE_READ_PUF_USER_FUSES: + case EFUSE_READ_PUF: + break; + case EFUSE_READ_OFFCHIP_REVOCATION_ID: + val = req->offchip_id; + arg = &val; + break; + case EFUSE_READ_REVOCATION_ID: + val = req->revocation_id; + arg = &val; + break; + case EFUSE_READ_IV: + val = req->iv_type; + arg = &val; + break; + case EFUSE_READ_PPK_HASH: + val = req->ppk_type; + arg = &val; + break; + case BBRAM_READ_USER_DATA: + break; + default: + return TEE_ERROR_GENERIC; + } + + return efuse_req(req->efuse_id, req->ibuf, arg); +} + +static TEE_Result versal_nvm_write(struct versal_nvm_write_req *req) +{ + uint32_t *arg = NULL; + uint32_t val = 0; + + switch (req->efuse_id) { + case BBRAM_WRITE_AES_KEY: + val = req->bbram.aes_key_len; + arg = &val; + break; + case BBRAM_WRITE_USER_DATA: + val = req->bbram.user_data; + arg = &val; + break; + case BBRAM_ZEROIZE: + case EFUSE_PUF_USER_FUSE_WRITE: + case EFUSE_WRITE_PUF: + case EFUSE_WRITE: + break; + default: + return TEE_ERROR_GENERIC; + } + + return efuse_req(req->efuse_id, req->ibuf, arg); +} +#endif + +TEE_Result versal_bbram_write_aes_key(uint8_t *key, size_t len) +{ + struct versal_nvm_write_req req __aligned_efuse = { + .efuse_id = BBRAM_WRITE_AES_KEY, + .bbram.aes_key_len = len, + }; + void *buf = NULL; + + if (len != 32) + return TEE_ERROR_BAD_PARAMETERS; + + buf = alloc_cache_aligned(1024); + if (!buf) + return TEE_ERROR_OUT_OF_MEMORY; + + memcpy(buf, key, len); + + req.ibuf[0].buf = buf; + req.ibuf[0].len = 1024; + + if (versal_nvm_write(&req)) { + free(buf); + return TEE_ERROR_GENERIC; + } + free(buf); + + return TEE_SUCCESS; +} + +TEE_Result versal_bbram_zeroize(void) +{ + struct versal_nvm_write_req req __aligned_efuse = { + .efuse_id = BBRAM_ZEROIZE, + }; + + if (versal_nvm_write(&req)) + return TEE_ERROR_GENERIC; + + return TEE_SUCCESS; +} + +TEE_Result versal_bbram_write_user_data(uint32_t data) +{ + struct versal_nvm_write_req req __aligned_efuse = { + .efuse_id = BBRAM_WRITE_USER_DATA, + .bbram.user_data = data, + }; + + if (versal_nvm_write(&req)) + return TEE_ERROR_GENERIC; + + return TEE_SUCCESS; +} + +TEE_Result versal_bbram_read_user_data(uint32_t *data) +{ + struct versal_nvm_read_req req = { + .efuse_id = BBRAM_READ_USER_DATA, + }; + + if (versal_alloc_read_buffer(&req)) + return TEE_ERROR_OUT_OF_MEMORY; + + if (versal_nvm_read(&req)) { + versal_free_read_buffer(&req); + return TEE_ERROR_GENERIC; + } + + memcpy(data, versal_get_read_buffer(&req), sizeof(*data)); + versal_free_read_buffer(&req); + + return TEE_SUCCESS; +} + +TEE_Result versal_bbram_lock_write_user_data(void) +{ + struct versal_nvm_write_req req __aligned_efuse = { + .efuse_id = BBRAM_LOCK_WRITE_USER_DATA, + }; + + if (versal_nvm_write(&req)) + return TEE_ERROR_GENERIC; + + return TEE_SUCCESS; +} + +#if defined(PLATFORM_FLAVOR_net) +static TEE_Result versal_efuse_read_cache(uint16_t off, uint16_t num, + uint32_t *buf, size_t len) +{ + struct versal_ipi_cmd cmd = { }; + struct versal_mbox_mem p = { }; + TEE_Result ret = TEE_SUCCESS; + uint32_t a = 0; + uint32_t b = 0; + + if (!buf) + return TEE_ERROR_BAD_PARAMETERS; + + if (len < num * NVM_WORD_LEN) + return TEE_ERROR_BAD_PARAMETERS; + + ret = versal_mbox_alloc(num * NVM_WORD_LEN, NULL, &p); + if (ret) + return ret; + + reg_pair_from_64(virt_to_phys(p.buf), &b, &a); + + cmd.data[0] = NVM_API_ID(EFUSE_READ_CACHE); + cmd.data[1] = (num << 16) | off; + cmd.data[2] = a; + cmd.data[3] = b; + + cmd.ibuf[0].mem = p; + + ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); + if (ret) + EMSG("Mailbox error"); + else + memcpy(buf, p.buf, num * NVM_WORD_LEN); + + versal_mbox_free(&p); + return ret; +} + +#define EFUSE_CACHE_DNA_OFFSET 0x20 +#define EFUSE_CACHE_BOOT_ENV_CTRL_OFFSET 0x94 +#define EFUSE_CACHE_MISC_CTRL_OFFSET 0xA0 +#define EFUSE_CACHE_PUF_ECC_CTRL_OFFSET 0xA4 +#define EFUSE_CACHE_PUF_CHASH_OFFSET 0xA8 +#define EFUSE_CACHE_SEC_CTRL_OFFSET 0xAC +#define EFUSE_CACHE_REVOCATION_ID0_OFFSET 0xB0 +#define EFUSE_CACHE_SEC_MISC0_OFFSET 0xE4 +#define EFUSE_CACHE_SEC_MISC1_OFFSET 0xE8 +#define EFUSE_CACHE_PPK0_OFFSET 0x100 +#define EFUSE_CACHE_PPK1_OFFSET 0x120 +#define EFUSE_CACHE_PPK2_OFFSET 0x140 +#define EFUSE_CACHE_OFFCHIP_REVOKE_ID0_OFFSET 0x160 +#define EFUSE_CACHE_METAHEADER_IV_RANGE0_OFFSET 0x180 +#define EFUSE_CACHE_BLACK_IV0_OFFSET 0x1D0 +#define EFUSE_CACHE_PLM_IV_RANGE0_OFFSET 0x1DC +#define EFUSE_CACHE_DATA_PARTITION_IV_RANGE0_OFFSET 0x1E8 +#define EFUSE_CACHE_USER0_OFFSET 0x240 +#define EFUSE_CACHE_PUF_SYN0_OFFSET 0x300 + +TEE_Result versal_efuse_read_dna(uint32_t *buf, size_t len) +{ + if (len < EFUSE_DNA_LEN) + return TEE_ERROR_BAD_PARAMETERS; + + return versal_efuse_read_cache(EFUSE_CACHE_DNA_OFFSET, + EFUSE_DNA_LEN / NVM_WORD_LEN, buf, len); +} + +TEE_Result versal_efuse_read_user_data(uint32_t *buf, size_t len, + uint32_t first, size_t num) +{ + uint16_t offset; + + if (first + num > EFUSE_MAX_USER_FUSES || len < num * NVM_WORD_LEN) + return TEE_ERROR_BAD_PARAMETERS; + + offset = EFUSE_CACHE_USER0_OFFSET + first * NVM_WORD_LEN; + + return versal_efuse_read_cache(offset, num, buf, len); +} + +TEE_Result versal_efuse_read_iv(uint32_t *buf, size_t len, + enum versal_nvm_iv_type type) +{ + uint16_t offset; + + switch (type) { + case EFUSE_META_HEADER_IV_RANGE: + offset = EFUSE_CACHE_METAHEADER_IV_RANGE0_OFFSET; + break; + case EFUSE_BLACK_IV: + offset = EFUSE_CACHE_BLACK_IV0_OFFSET; + break; + case EFUSE_PLM_IV_RANGE: + offset = EFUSE_CACHE_PLM_IV_RANGE0_OFFSET; + break; + case EFUSE_DATA_PARTITION_IV_RANGE: + offset = EFUSE_CACHE_DATA_PARTITION_IV_RANGE0_OFFSET; + break; + default: + return TEE_ERROR_BAD_PARAMETERS; + } + + return versal_efuse_read_cache(offset, EFUSE_IV_LEN / NVM_WORD_LEN, + buf, len); +} + +TEE_Result versal_efuse_read_ppk(uint32_t *buf, size_t len, + enum versal_nvm_ppk_type type) +{ + uint16_t offset; + + switch (type) { + case EFUSE_PPK0: + offset = EFUSE_CACHE_PPK0_OFFSET; + break; + case EFUSE_PPK1: + offset = EFUSE_CACHE_PPK1_OFFSET; + break; + case EFUSE_PPK2: + offset = EFUSE_CACHE_PPK2_OFFSET; + break; + default: + return TEE_ERROR_BAD_PARAMETERS; + } + + return versal_efuse_read_cache(offset, EFUSE_PPK_LEN / NVM_WORD_LEN, + buf, len); +} + +TEE_Result versal_efuse_read_revoke_id(uint32_t *buf, size_t len, + enum versal_nvm_revocation_id id) +{ + return versal_efuse_read_cache(EFUSE_CACHE_REVOCATION_ID0_OFFSET + + id * NVM_WORD_LEN, + EFUSE_REVOCATION_ID_LEN / NVM_WORD_LEN, + buf, len); +} + +TEE_Result versal_efuse_read_misc_ctrl(struct versal_efuse_misc_ctrl_bits *buf) +{ + TEE_Result ret = TEE_SUCCESS; + uint32_t misc_ctrl = 0; + + if (!buf) + return TEE_ERROR_BAD_PARAMETERS; + + ret = versal_efuse_read_cache(EFUSE_CACHE_MISC_CTRL_OFFSET, 1, + &misc_ctrl, sizeof(uint32_t)); + if (ret) + return ret; + + buf->glitch_det_halt_boot_en = ((misc_ctrl & GENMASK_32(31, 30)) >> 30); + buf->glitch_det_rom_monitor_en = ((misc_ctrl & BIT(29)) >> 29); + buf->halt_boot_error = ((misc_ctrl & GENMASK_32(22, 21)) >> 21); + buf->halt_boot_env = ((misc_ctrl & GENMASK_32(20, 19)) >> 19); + buf->crypto_kat_en = ((misc_ctrl & BIT(15)) >> 15); + buf->lbist_en = ((misc_ctrl & BIT(14)) >> 14); + buf->safety_mission_en = ((misc_ctrl & BIT(8)) >> 8); + buf->ppk0_invalid = ((misc_ctrl & GENMASK_32(7, 6)) >> 6); + buf->ppk1_invalid = ((misc_ctrl & GENMASK_32(5, 4)) >> 4); + buf->ppk2_invalid = ((misc_ctrl & GENMASK_32(3, 2)) >> 2); + + return ret; +} + +TEE_Result versal_efuse_read_sec_ctrl(struct versal_efuse_sec_ctrl_bits *buf) +{ + TEE_Result ret = TEE_SUCCESS; + uint32_t sec_ctrl = 0; + + if (!buf) + return TEE_ERROR_BAD_PARAMETERS; + + ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_CTRL_OFFSET, 1, + &sec_ctrl, sizeof(uint32_t)); + if (ret) + return ret; + + buf->aes_dis = (sec_ctrl & BIT(0)); + buf->jtag_err_out_dis = ((sec_ctrl & BIT(1)) >> 1); + buf->jtag_dis = ((sec_ctrl & BIT(2)) >> 2); + buf->ppk0_wr_lk = ((sec_ctrl & BIT(6)) >> 6); + buf->ppk1_wr_lk = ((sec_ctrl & BIT(7)) >> 7); + buf->ppk2_wr_lk = ((sec_ctrl & BIT(8)) >> 8); + buf->aes_crc_lk = ((sec_ctrl & GENMASK_32(10, 9)) >> 9); + buf->aes_wr_lk = ((sec_ctrl & BIT(11)) >> 11); + buf->user_key0_crc_lk = ((sec_ctrl & BIT(12)) >> 12); + buf->user_key0_wr_lk = ((sec_ctrl & BIT(13)) >> 13); + buf->user_key1_crc_lk = ((sec_ctrl & BIT(14)) >> 14); + buf->user_key1_wr_lk = ((sec_ctrl & BIT(15)) >> 15); + buf->sec_dbg_dis = ((sec_ctrl & GENMASK_32(20, 19)) >> 19); + buf->sec_lock_dbg_dis = ((sec_ctrl & GENMASK_32(22, 21)) >> 21); + buf->boot_env_wr_lk = ((sec_ctrl & BIT(28)) >> 28); + buf->reg_init_dis = ((sec_ctrl & GENMASK_32(31, 30)) >> 30); + + return ret; +} + +TEE_Result versal_efuse_read_sec_misc1(struct versal_efuse_sec_misc1_bits *buf) +{ + TEE_Result ret = TEE_SUCCESS; + uint32_t sec_misc1 = 0; + + if (!buf) + return TEE_ERROR_BAD_PARAMETERS; + + ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_MISC1_OFFSET, 1, + &sec_misc1, sizeof(uint32_t)); + if (ret) + return ret; + + buf->lpd_mbist_en = ((sec_misc1 & GENMASK_32(12, 10)) >> 10); + buf->pmc_mbist_en = ((sec_misc1 & GENMASK_32(9, 7)) >> 7); + buf->lpd_noc_sc_en = ((sec_misc1 & GENMASK_32(6, 4)) >> 4); + buf->sysmon_volt_mon_en = ((sec_misc1 & GENMASK_32(3, 2)) >> 2); + buf->sysmon_temp_mon_en = (sec_misc1 & GENMASK_32(1, 0)); + + return ret; +} + +TEE_Result +versal_efuse_read_boot_env_ctrl(struct versal_efuse_boot_env_ctrl_bits *buf) +{ + TEE_Result ret = TEE_SUCCESS; + uint32_t boot_env_ctrl = 0; + + if (!buf) + return TEE_ERROR_BAD_PARAMETERS; + + ret = versal_efuse_read_cache(EFUSE_CACHE_BOOT_ENV_CTRL_OFFSET, 1, + &boot_env_ctrl, sizeof(uint32_t)); + if (ret) + return ret; + + buf->sysmon_temp_en = ((boot_env_ctrl & BIT(21)) >> 21); + buf->sysmon_volt_en = ((boot_env_ctrl & BIT(20)) >> 20); + buf->sysmon_temp_hot = ((boot_env_ctrl & GENMASK_32(18, 17)) >> 17); + buf->sysmon_volt_pmc = ((boot_env_ctrl & GENMASK_32(13, 12)) >> 12); + buf->sysmon_volt_pslp = ((boot_env_ctrl & GENMASK_32(11, 10)) >> 10); + buf->sysmon_volt_soc = ((boot_env_ctrl & GENMASK_32(9, 8)) >> 8); + buf->sysmon_temp_cold = (boot_env_ctrl & GENMASK_32(1, 0)); + + return ret; +} + +TEE_Result versal_efuse_read_offchip_revoke_id(uint32_t *buf, size_t len, + enum versal_nvm_offchip_id id) +{ + if (id == EFUSE_INVLD) + return TEE_ERROR_BAD_PARAMETERS; + + return versal_efuse_read_cache(EFUSE_CACHE_OFFCHIP_REVOKE_ID0_OFFSET + + id * NVM_WORD_LEN, + EFUSE_REVOCATION_ID_LEN / NVM_WORD_LEN, + buf, len); +} + +TEE_Result versal_efuse_read_dec_only(uint32_t *buf, size_t len) +{ + TEE_Result ret = TEE_SUCCESS; + uint32_t sec_misc0 = 0; + + if (len < EFUSE_DEC_ONLY_LEN) + return TEE_ERROR_BAD_PARAMETERS; + + ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_MISC0_OFFSET, 1, + &sec_misc0, sizeof(uint32_t)); + if (ret) + return ret; + + sec_misc0 &= GENMASK_32(15, 0); + + memcpy(buf, &sec_misc0, EFUSE_DEC_ONLY_LEN); + + return ret; +} + +TEE_Result versal_efuse_read_puf_sec_ctrl(struct versal_efuse_puf_sec_ctrl_bits + *buf) +{ + TEE_Result ret = TEE_SUCCESS; + uint32_t puf_ctrl = 0; + uint32_t sec_ctrl = 0; + + if (!buf) + return TEE_ERROR_BAD_PARAMETERS; + + ret = versal_efuse_read_cache(EFUSE_CACHE_PUF_ECC_CTRL_OFFSET, 1, + &puf_ctrl, sizeof(uint32_t)); + if (ret) + return ret; + + /* + * Some fuses have moved from PUF_ECC_CTRL to SECURITY_CTRL + */ + ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_CTRL_OFFSET, 1, + &sec_ctrl, sizeof(uint32_t)); + if (ret) + return ret; + + buf->puf_regen_dis = ((puf_ctrl & BIT(31)) >> 31); + buf->puf_hd_invalid = ((puf_ctrl & BIT(30)) >> 30); + buf->puf_test2_dis = ((puf_ctrl & BIT(29)) >> 29); + buf->puf_dis = ((sec_ctrl & BIT(18)) >> 18); + buf->puf_syn_lk = ((sec_ctrl & BIT(16)) >> 16); + + return ret; +} + +TEE_Result versal_efuse_read_puf(struct versal_efuse_puf_header *buf) +{ + TEE_Result ret = TEE_SUCCESS; + + if (!buf) + return TEE_ERROR_BAD_PARAMETERS; + + ret = versal_efuse_read_puf_sec_ctrl(&buf->sec_ctrl); + if (ret) + return ret; + + ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_CTRL_OFFSET, 1, + &buf->aux, sizeof(uint32_t)); + if (ret) + return ret; + + buf->aux &= GENMASK_32(23, 0); + + ret = versal_efuse_read_cache(EFUSE_CACHE_PUF_CHASH_OFFSET, 1, + &buf->chash, sizeof(uint32_t)); + if (ret) + return ret; + + ret = versal_efuse_read_cache(EFUSE_CACHE_PUF_SYN0_OFFSET, + PUF_SYN_DATA_WORDS, buf->efuse_syn_data, + PUF_SYN_DATA_WORDS * NVM_WORD_LEN); + return ret; +} + +TEE_Result +versal_efuse_read_puf_as_user_fuse(struct versal_efuse_puf_user_fuse + *p __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result versal_efuse_write_user_data(uint32_t *buf __unused, + size_t len __unused, + uint32_t first __unused, + size_t num __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +#define EFUSE_ENV_DIS_FLAG 0 + +#define EFUSE_AES_KEY_ID 0 +#define EFUSE_USER_KEY0_ID 1 +#define EFUSE_USER_KEY1_ID 2 + +static TEE_Result do_write_efuses_buffer(enum versal_nvm_api_id id, + uint16_t type, uint32_t *buf, + size_t len) +{ + struct versal_ipi_cmd cmd = { }; + struct versal_mbox_mem p = { }; + TEE_Result ret = TEE_SUCCESS; + uint32_t a = 0; + uint32_t b = 0; + + ret = versal_mbox_alloc(len, buf, &p); + if (ret) + return ret; + + reg_pair_from_64(virt_to_phys(p.buf), &b, &a); + + cmd.data[0] = NVM_API_ID(id); + cmd.data[1] = (type << 16) | EFUSE_ENV_DIS_FLAG; + cmd.data[2] = a; + cmd.data[3] = b; + + cmd.ibuf[0].mem = p; + + ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); + + versal_mbox_free(&p); + return ret; +} + +static TEE_Result do_write_efuses_value(enum versal_nvm_api_id id, uint32_t val) +{ + struct versal_ipi_cmd cmd = { }; + TEE_Result ret = TEE_SUCCESS; + + cmd.data[0] = NVM_API_ID(id); + cmd.data[1] = EFUSE_ENV_DIS_FLAG; + cmd.data[2] = val; + + ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); + + return ret; +} + +static TEE_Result do_write_efuses(enum versal_nvm_api_id id) +{ + return do_write_efuses_value(id, 0); +} + +TEE_Result versal_efuse_write_aes_keys(struct versal_efuse_aes_keys *keys) +{ + TEE_Result ret = TEE_SUCCESS; + TEE_Result res; + + if (!keys) + return TEE_ERROR_BAD_PARAMETERS; + + if (keys->prgm_aes_key) { + res = do_write_efuses_buffer(EFUSE_WRITE_AES_KEY, + EFUSE_AES_KEY_ID, + keys->aes_key, EFUSE_AES_KEY_LEN); + if (res) { + DMSG("Error programming AES key (0x%" PRIx32 ")", res); + ret = TEE_ERROR_GENERIC; + } + } + + if (keys->prgm_user_key0) { + res = do_write_efuses_buffer(EFUSE_WRITE_AES_KEY, + EFUSE_USER_KEY0_ID, + keys->user_key0, + EFUSE_AES_KEY_LEN); + if (res) { + DMSG("Error programming User key 0 (0x%" PRIx32 ")", + res); + ret = TEE_ERROR_GENERIC; + } + } + + if (keys->prgm_user_key1) { + res = do_write_efuses_buffer(EFUSE_WRITE_AES_KEY, + EFUSE_USER_KEY1_ID, + keys->user_key1, + EFUSE_AES_KEY_LEN); + if (res) { + DMSG("Error programming User key 1 (0x%" PRIx32 ")", + res); + ret = TEE_ERROR_GENERIC; + } + } + + return ret; +} + +TEE_Result versal_efuse_write_ppk_hash(struct versal_efuse_ppk_hash *hash) +{ + TEE_Result ret = TEE_SUCCESS; + TEE_Result res; + + if (!hash) + return TEE_ERROR_BAD_PARAMETERS; - reg_pair_from_64(virt_to_phys(ibufs[0].buf), &b, &a); + if (hash->prgm_ppk0_hash) { + res = do_write_efuses_buffer(EFUSE_WRITE_PPK_HASH, EFUSE_PPK0, + hash->ppk0_hash, EFUSE_PPK_LEN); + if (res) { + DMSG("Error programming PPK hash 0 (0x%" PRIx32 ")", + res); + ret = TEE_ERROR_GENERIC; + } + } - cmd->data[i++] = a; - cmd->data[i++] = b; + if (hash->prgm_ppk1_hash) { + res = do_write_efuses_buffer(EFUSE_WRITE_PPK_HASH, EFUSE_PPK1, + hash->ppk1_hash, EFUSE_PPK_LEN); + if (res) { + DMSG("Error programming PPK hash 1 (0x%" PRIx32 ")", + res); + ret = TEE_ERROR_GENERIC; + } + } - for (i = 0; i < VERSAL_MAX_IPI_BUF; i++) { - cmd->ibuf[i].mem.alloc_len = ibufs[i].len; - cmd->ibuf[i].mem.buf = ibufs[i].buf; + if (hash->prgm_ppk2_hash) { + res = do_write_efuses_buffer(EFUSE_WRITE_PPK_HASH, EFUSE_PPK2, + hash->ppk2_hash, EFUSE_PPK_LEN); + if (res) { + DMSG("Error programming PPK hash 2 (0x%" PRIx32 ")", + res); + ret = TEE_ERROR_GENERIC; + } } - return TEE_SUCCESS; + return ret; } -static TEE_Result efuse_req(enum versal_nvm_api_id efuse, - struct versal_nvm_buf *ibufs, uint32_t *arg) +TEE_Result versal_efuse_write_iv(struct versal_efuse_ivs *p) { - struct versal_ipi_cmd cmd = { }; TEE_Result ret = TEE_SUCCESS; + TEE_Result res; - ret = prepare_cmd(&cmd, efuse, ibufs, arg); - if (ret) - return ret; + if (!p) + return TEE_ERROR_BAD_PARAMETERS; - ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); - if (ret) - EMSG("Mailbox error"); + if (p->prgm_meta_header_iv) { + res = do_write_efuses_buffer(EFUSE_WRITE_IV, + EFUSE_META_HEADER_IV_RANGE, + p->meta_header_iv, EFUSE_IV_LEN); + if (res) { + DMSG("Error programming meta header IV (0x%" PRIx32 ")", + res); + ret = TEE_ERROR_GENERIC; + } + } + + if (p->prgm_blk_obfus_iv) { + res = do_write_efuses_buffer(EFUSE_WRITE_IV, EFUSE_BLACK_IV, + p->blk_obfus_iv, EFUSE_IV_LEN); + if (res) { + DMSG("Error programming black IV (0x%" PRIx32 ")", res); + ret = TEE_ERROR_GENERIC; + } + } + + if (p->prgm_plm_iv) { + res = do_write_efuses_buffer(EFUSE_WRITE_IV, EFUSE_PLM_IV_RANGE, + p->plm_iv, EFUSE_IV_LEN); + if (res) { + DMSG("Error programming plm IV (0x%" PRIx32 ")", res); + ret = TEE_ERROR_GENERIC; + } + } + + if (p->prgm_data_partition_iv) { + res = do_write_efuses_buffer(EFUSE_WRITE_IV, + EFUSE_DATA_PARTITION_IV_RANGE, + p->data_partition_iv, + EFUSE_IV_LEN); + if (res) { + DMSG("Error programming data IV (0x%" PRIx32 ")", res); + ret = TEE_ERROR_GENERIC; + } + } return ret; } -static TEE_Result versal_alloc_read_buffer(struct versal_nvm_read_req *req) +TEE_Result versal_efuse_write_dec_only(struct versal_efuse_dec_only *p) { - assert(req); - req->ibuf[0].len = 1024; - req->ibuf[0].buf = alloc_cache_aligned(req->ibuf[0].len); - if (!req->ibuf[0].buf) - return TEE_ERROR_OUT_OF_MEMORY; + if (!p) + return TEE_ERROR_BAD_PARAMETERS; - return TEE_SUCCESS; + if (!p->prgm_dec_only) + return TEE_SUCCESS; + + return do_write_efuses(EFUSE_WRITE_DEC_ONLY); } -static void versal_free_read_buffer(struct versal_nvm_read_req *req) +TEE_Result versal_efuse_write_sec(struct versal_efuse_sec_ctrl_bits *p) { - assert(req); - free(req->ibuf[0].buf); + uint32_t val = 0; + + if (!p) + return TEE_ERROR_BAD_PARAMETERS; + + val = ((p->reg_init_dis & 0x3) << 30) | + ((p->boot_env_wr_lk & 0x1) << 28) | + ((p->sec_lock_dbg_dis & 0x3) << 21) | + ((p->sec_dbg_dis & 0x3) << 19) | + ((p->user_key1_wr_lk & 0x1) << 15) | + ((p->user_key1_crc_lk & 0x1) << 14) | + ((p->user_key0_wr_lk & 0x1) << 13) | + ((p->user_key0_crc_lk & 0x1) << 12) | + ((p->aes_wr_lk & 0x1) << 11) | + ((p->aes_crc_lk & 0x3) << 9) | + ((p->ppk2_wr_lk & 0x1) << 8) | + ((p->ppk1_wr_lk & 0x1) << 7) | + ((p->ppk0_wr_lk & 0x1) << 6) | + ((p->jtag_dis & 0x1) << 2) | + ((p->jtag_err_out_dis & 0x1) << 1) | + (p->aes_dis & 0x1); + + return do_write_efuses_value(EFUSE_WRITE_SEC_CTRL_BITS, val); } -static void *versal_get_read_buffer(struct versal_nvm_read_req *req) +TEE_Result versal_efuse_write_misc(struct versal_efuse_misc_ctrl_bits *p) { - assert(req); - return req->ibuf[0].buf; + uint32_t val = 0; + + if (!p) + return TEE_ERROR_BAD_PARAMETERS; + + val = ((p->glitch_det_halt_boot_en & 0x3) << 30) | + ((p->glitch_det_rom_monitor_en & 0x1) << 29) | + ((p->halt_boot_error & 0x3) << 21) | + ((p->halt_boot_env & 0x3) << 19) | + ((p->crypto_kat_en & 0x1) << 15) | + ((p->lbist_en & 0x1) << 14) | + ((p->safety_mission_en & 0x1) << 8) | + ((p->ppk2_invalid & 0x3) << 6) | + ((p->ppk1_invalid & 0x3) << 4) | + ((p->ppk0_invalid & 0x3) << 2); + + return do_write_efuses_value(EFUSE_WRITE_MISC_CTRL_BITS, val); } -static TEE_Result versal_nvm_read(struct versal_nvm_read_req *req) +TEE_Result +versal_efuse_write_glitch_cfg(struct versal_efuse_glitch_cfg_bits *p) { - uint32_t *arg = NULL; uint32_t val = 0; - if (!req) - return TEE_ERROR_GENERIC; + if (!p) + return TEE_ERROR_BAD_PARAMETERS; - switch (req->efuse_id) { - case EFUSE_READ_DNA: - case EFUSE_READ_DEC_EFUSE_ONLY: - case EFUSE_READ_PUF_SEC_CTRL: - case EFUSE_READ_BOOT_ENV_CTRL: - case EFUSE_READ_SEC_CTRL: - case EFUSE_READ_MISC_CTRL: - case EFUSE_READ_SEC_MISC1: - case EFUSE_READ_USER_FUSES: - case EFUSE_READ_PUF_USER_FUSES: - case EFUSE_READ_PUF: - break; - case EFUSE_READ_OFFCHIP_REVOCATION_ID: - val = req->offchip_id; - arg = &val; - break; - case EFUSE_READ_REVOCATION_ID: - val = req->revocation_id; - arg = &val; - break; - case EFUSE_READ_IV: - val = req->iv_type; - arg = &val; - break; - case EFUSE_READ_PPK_HASH: - val = req->ppk_type; - arg = &val; - break; - case BBRAM_READ_USER_DATA: - break; - default: - return TEE_ERROR_GENERIC; - } + if (!p->prgm_glitch) + return TEE_SUCCESS; - return efuse_req(req->efuse_id, req->ibuf, arg); + val = ((p->glitch_det_wr_lk & 0x1) << 31) | p->glitch_det_trim; + + return do_write_efuses_value(EFUSE_WRITE_GLITCH_CONFIG, val); } -static TEE_Result versal_nvm_write(struct versal_nvm_write_req *req) +TEE_Result +versal_efuse_write_boot_env(struct versal_efuse_boot_env_ctrl_bits *p) { - uint32_t *arg = NULL; uint32_t val = 0; - switch (req->efuse_id) { - case BBRAM_WRITE_AES_KEY: - val = req->bbram.aes_key_len; - arg = &val; + if (!p) + return TEE_ERROR_BAD_PARAMETERS; + + val = ((p->sysmon_temp_en & 0x1) << 21) | + ((p->sysmon_volt_en & 0x1) << 20) | + ((p->sysmon_temp_hot & 0x3) << 17) | + ((p->sysmon_volt_pmc & 0x3) << 12) | + ((p->sysmon_volt_pslp & 0x3) << 10) | + ((p->sysmon_volt_soc & 0x3) << 8) | + (p->sysmon_temp_cold & 0x2); + + return do_write_efuses_value(EFUSE_WRITE_BOOT_ENV_CTRL_BITS, val); +} + +TEE_Result versal_efuse_write_sec_misc1(struct versal_efuse_sec_misc1_bits *p) +{ + uint32_t val = 0; + + if (!p) + return TEE_ERROR_BAD_PARAMETERS; + + val = ((p->lpd_mbist_en & 0x7) << 10) | + ((p->pmc_mbist_en & 0x7) << 7) | + ((p->lpd_noc_sc_en & 0x7) << 4) | + ((p->sysmon_volt_mon_en & 0x3) << 2) | + (p->sysmon_temp_mon_en & 0x3); + + return do_write_efuses_value(EFUSE_WRITE_MISC1_CTRL_BITS, val); +} + +TEE_Result versal_efuse_write_offchip_ids(uint32_t id) +{ + return do_write_efuses_value(EFUSE_WRITE_OFFCHIP_REVOKE_ID, id); +} + +TEE_Result versal_efuse_write_revoke_ppk(enum versal_nvm_ppk_type type) +{ + struct versal_efuse_misc_ctrl_bits misc_ctrl; + + memset(&misc_ctrl, 0, sizeof(struct versal_efuse_misc_ctrl_bits)); + + switch (type) { + case EFUSE_PPK0: + misc_ctrl.ppk0_invalid = 0x3; break; - case BBRAM_WRITE_USER_DATA: - val = req->bbram.user_data; - arg = &val; + case EFUSE_PPK1: + misc_ctrl.ppk1_invalid = 0x3; break; - case EFUSE_PUF_USER_FUSE_WRITE: - case EFUSE_WRITE_PUF: - case EFUSE_WRITE: + case EFUSE_PPK2: + misc_ctrl.ppk2_invalid = 0x3; break; default: - return TEE_ERROR_GENERIC; + return TEE_ERROR_BAD_PARAMETERS; } - return efuse_req(req->efuse_id, req->ibuf, arg); + return versal_efuse_write_misc(&misc_ctrl); +} + +TEE_Result versal_efuse_write_revoke_id(uint32_t id) +{ + return do_write_efuses_value(EFUSE_WRITE_REVOCATION_ID, id); +} + +TEE_Result versal_efuse_write_puf_as_user_fuse(struct versal_efuse_puf_user_fuse + *p __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; } +#define EFUSE_WRITE_PUF_DATA_WORDS (PUF_SYN_DATA_WORDS + 6) + +struct versal_efuse_write_puf_data { + uint32_t sec_ctrl; + uint32_t prgm_puf_helper_data; + uint32_t env_monitor_dis; + uint32_t syn[PUF_SYN_DATA_WORDS]; + uint32_t chash; + uint32_t aux; + uint32_t ro_swap; +}; + +TEE_Result versal_efuse_write_puf(struct versal_efuse_puf_header *buf) +{ + struct versal_ipi_cmd cmd = { }; + struct versal_mbox_mem p = { }; + TEE_Result ret = TEE_SUCCESS; + uint32_t a = 0; + uint32_t b = 0; + struct versal_efuse_write_puf_data *data; + + if (!buf) + return TEE_ERROR_BAD_PARAMETERS; + + ret = versal_mbox_alloc(EFUSE_WRITE_PUF_DATA_WORDS * NVM_WORD_LEN, + NULL, &p); + if (ret) + return ret; + + data = p.buf; + + data->sec_ctrl = 0; + data->prgm_puf_helper_data = buf->prmg_puf_helper_data; + data->env_monitor_dis = buf->env_monitor_dis; + memcpy(data->syn, buf->efuse_syn_data, + PUF_SYN_DATA_WORDS * NVM_WORD_LEN); + data->chash = buf->chash; + data->aux = buf->aux; + data->ro_swap = 0; + + reg_pair_from_64(virt_to_phys(p.buf), &b, &a); + + cmd.data[0] = NVM_API_ID(EFUSE_WRITE_PUF); + cmd.data[2] = a; + cmd.data[3] = b; + + cmd.ibuf[0].mem = p; + + ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); + + versal_mbox_free(&p); + return ret; +} +#else TEE_Result versal_efuse_read_user_data(uint32_t *buf, size_t len, uint32_t first, size_t num) { @@ -917,89 +1835,4 @@ TEE_Result versal_efuse_write_puf(struct versal_efuse_puf_header *buf) return TEE_SUCCESS; } - -TEE_Result versal_bbram_write_aes_key(uint8_t *key, size_t len) -{ - struct versal_nvm_write_req req __aligned_efuse = { - .efuse_id = BBRAM_WRITE_AES_KEY, - .bbram.aes_key_len = len, - }; - void *buf = NULL; - - if (len != 32) - return TEE_ERROR_BAD_PARAMETERS; - - buf = alloc_cache_aligned(1024); - if (!buf) - return TEE_ERROR_OUT_OF_MEMORY; - - memcpy(buf, key, len); - - req.ibuf[0].buf = buf; - req.ibuf[0].len = 1024; - - if (versal_nvm_write(&req)) { - free(buf); - return TEE_ERROR_GENERIC; - } - free(buf); - - return TEE_SUCCESS; -} - -TEE_Result versal_bbram_zeroize(void) -{ - struct versal_nvm_write_req req __aligned_efuse = { - .efuse_id = BBRAM_ZEROIZE, - }; - - if (versal_nvm_write(&req)) - return TEE_ERROR_GENERIC; - - return TEE_SUCCESS; -} - -TEE_Result versal_bbram_write_user_data(uint32_t data) -{ - struct versal_nvm_write_req req __aligned_efuse = { - .efuse_id = BBRAM_WRITE_USER_DATA, - .bbram.user_data = data, - }; - - if (versal_nvm_write(&req)) - return TEE_ERROR_GENERIC; - - return TEE_SUCCESS; -} - -TEE_Result versal_bbram_read_user_data(uint32_t *data) -{ - struct versal_nvm_read_req req = { - .efuse_id = BBRAM_READ_USER_DATA, - }; - - if (versal_alloc_read_buffer(&req)) - return TEE_ERROR_OUT_OF_MEMORY; - - if (versal_nvm_read(&req)) { - versal_free_read_buffer(&req); - return TEE_ERROR_GENERIC; - } - - memcpy(data, versal_get_read_buffer(&req), sizeof(*data)); - versal_free_read_buffer(&req); - - return TEE_SUCCESS; -} - -TEE_Result versal_bbram_lock_write_user_data(void) -{ - struct versal_nvm_write_req req __aligned_efuse = { - .efuse_id = BBRAM_LOCK_WRITE_USER_DATA, - }; - - if (versal_nvm_write(&req)) - return TEE_ERROR_GENERIC; - - return TEE_SUCCESS; -} +#endif diff --git a/core/include/drivers/versal_nvm.h b/core/include/drivers/versal_nvm.h index 948ebb27125..aac8aaf20c7 100644 --- a/core/include/drivers/versal_nvm.h +++ b/core/include/drivers/versal_nvm.h @@ -14,7 +14,12 @@ #define PUF_EFUSES_WORDS (128) #define PUF_SYN_DATA_WORDS (127) + +#if defined(PLATFORM_FLAVOR_net) +#define EFUSE_MAX_USER_FUSES (48) +#else #define EFUSE_MAX_USER_FUSES (64) +#endif #define EFUSE_OFFCHIP_REVOCATION_ID_LEN (4) #define EFUSE_REVOCATION_ID_LEN (4) @@ -22,6 +27,7 @@ #define EFUSE_DNA_LEN (16) #define EFUSE_PPK_LEN (32) #define EFUSE_IV_LEN (12) +#define EFUSE_AES_KEY_LEN (32) enum versal_nvm_iv_type { EFUSE_META_HEADER_IV_RANGE = 0, @@ -243,7 +249,11 @@ TEE_Result versal_efuse_write_glitch_cfg(struct versal_efuse_glitch_cfg_bits TEE_Result versal_efuse_write_boot_env(struct versal_efuse_boot_env_ctrl_bits *p); TEE_Result versal_efuse_write_sec_misc1(struct versal_efuse_sec_misc1_bits *p); +#if defined(PLATFORM_FLAVOR_net) +TEE_Result versal_efuse_write_offchip_ids(uint32_t id); +#else TEE_Result versal_efuse_write_offchip_ids(struct versal_efuse_offchip_ids *p); +#endif TEE_Result versal_efuse_write_revoke_ppk(enum versal_nvm_ppk_type type); TEE_Result versal_efuse_write_revoke_id(uint32_t id); TEE_Result versal_efuse_read_revoke_id(uint32_t *buf, size_t len, From c668e586ea583c857a16644e3fcea7ae6c016c7e Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 14 Feb 2024 11:24:23 +0100 Subject: [PATCH 09/43] drivers: versal: fix RSA driver XilSecure has been updated to pack the public exponent right after the modulus rather than at a fixed 512 bytes (RSA 4096 key size) offset. See commit below for more details: https://github.com/Xilinx/embeddedsw/commit/c2dd2eb Signed-off-by: Jeremie Corbier --- core/drivers/crypto/versal/rsa.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/drivers/crypto/versal/rsa.c b/core/drivers/crypto/versal/rsa.c index 46e4195b886..c2a8db72e42 100644 --- a/core/drivers/crypto/versal/rsa.c +++ b/core/drivers/crypto/versal/rsa.c @@ -78,8 +78,8 @@ static TEE_Result do_encrypt(struct drvcrypt_rsa_ed *rsa_data) return ret; crypto_bignum_bn2bin_pad(rsa_data->key.n_size, p->n, key.buf); - crypto_bignum_bn2bin_pad(RSA_MAX_PUB_EXP_LEN, - p->e, (uint8_t *)key.buf + RSA_MAX_MOD_LEN); + crypto_bignum_bn2bin_pad(RSA_MAX_PUB_EXP_LEN, p->e, + (uint8_t *)key.buf + rsa_data->key.n_size); ret = versal_mbox_alloc(rsa_data->message.length, rsa_data->message.data, &msg); @@ -181,7 +181,7 @@ static TEE_Result do_decrypt(struct drvcrypt_rsa_ed *rsa_data) crypto_bignum_bn2bin_pad(rsa_data->key.n_size, p->n, key.buf); crypto_bignum_bn2bin_pad(rsa_data->key.n_size, p->d, - (uint8_t *)key.buf + RSA_MAX_MOD_LEN); + (uint8_t *)key.buf + rsa_data->key.n_size); ret = versal_mbox_alloc(rsa_data->cipher.length, rsa_data->cipher.data, &cipher); From d477ff3cb4f6c7b62bee4cbf6d02a30a5039b97c Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Tue, 2 Apr 2024 16:01:38 +0200 Subject: [PATCH 10/43] fixup! drivers: versal: NVM driver for Versal Net Split NVM code into two seperate drivers, one for Versal, one for Versal Net, since both variants have very different NVM PLM code. Signed-off-by: Jeremie Corbier --- core/arch/arm/plat-versal/conf.mk | 4 + core/drivers/sub.mk | 1 + core/drivers/versal_net_nvm.c | 1067 ++++++++++++++++++++++++++ core/drivers/versal_nvm.c | 1195 +++++------------------------ 4 files changed, 1253 insertions(+), 1014 deletions(-) create mode 100644 core/drivers/versal_net_nvm.c diff --git a/core/arch/arm/plat-versal/conf.mk b/core/arch/arm/plat-versal/conf.mk index 1cae4af59e0..f8f572886ea 100644 --- a/core/arch/arm/plat-versal/conf.mk +++ b/core/arch/arm/plat-versal/conf.mk @@ -80,7 +80,11 @@ CFG_VERSAL_TRNG_SEED_LIFE ?= 3 CFG_VERSAL_TRNG_DF_MUL ?= 2 # eFuse and BBRAM driver +ifeq ($(PLATFORM_FLAVOR),net) +$(call force, CFG_VERSAL_NET_NVM,y) +else $(call force, CFG_VERSAL_NVM,y) +endif # Crypto driver CFG_VERSAL_CRYPTO_DRIVER ?= y diff --git a/core/drivers/sub.mk b/core/drivers/sub.mk index 8788e5f2d61..04255624bee 100644 --- a/core/drivers/sub.mk +++ b/core/drivers/sub.mk @@ -72,6 +72,7 @@ srcs-$(CFG_VERSAL_PM) += versal_pm.c srcs-$(CFG_STM32MP15_HUK) += stm32mp15_huk.c srcs-$(CFG_VERSAL_RNG_DRV) += versal_trng.c srcs-$(CFG_VERSAL_NVM) += versal_nvm.c +srcs-$(CFG_VERSAL_NET_NVM) += versal_net_nvm.c srcs-$(CFG_VERSAL_SHA3_384) += versal_sha3_384.c srcs-$(CFG_VERSAL_PUF) += versal_puf.c srcs-$(CFG_VERSAL_HUK) += versal_huk.c diff --git a/core/drivers/versal_net_nvm.c b/core/drivers/versal_net_nvm.c new file mode 100644 index 00000000000..5c1761ed1a5 --- /dev/null +++ b/core/drivers/versal_net_nvm.c @@ -0,0 +1,1067 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (C) 2022 Foundries.io Ltd + * Jorge Ramirez-Ortiz + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "drivers/versal_nvm.h" + +#define NVM_WORD_LEN 4 + +/* Protocol API with the remote processor */ +#define NVM_MODULE_SHIFT 8 +#define NVM_MODULE 11 +#define NVM_API_ID(_id) ((NVM_MODULE << NVM_MODULE_SHIFT) | (_id)) + +#define __aligned_efuse __aligned(CACHELINE_LEN) + +/* Internal */ +struct versal_efuse_puf_fuse_addr { + uint64_t data_addr; + uint32_t start_row; + uint32_t num_rows; + uint8_t env_monitor_dis; + uint8_t prgm_puf_fuse; + uint8_t pad[46]; +}; + +/* + * Max size of the buffer needed for the remote processor to DMA efuse _data_ + * to/from + */ +#define EFUSE_MAX_LEN (EFUSE_MAX_USER_FUSES * sizeof(uint32_t)) + +enum versal_nvm_api_id { + API_FEATURES = 0, + BBRAM_WRITE_AES_KEY = 1, + BBRAM_ZEROIZE = 2, + BBRAM_WRITE_USER_DATA = 3, + BBRAM_READ_USER_DATA = 4, + BBRAM_LOCK_WRITE_USER_DATA = 5, + BBRAM_WRITE_AES_KEY_FROM_PLOAD = 6, + EFUSE_WRITE_AES_KEY = 7, + EFUSE_WRITE_AES_KEY_FROM_PLOAD = 8, + EFUSE_WRITE_PPK_HASH = 9, + EFUSE_WRITE_PPK_HASH_FROM_PLOAD = 10, + EFUSE_WRITE_IV = 11, + EFUSE_WRITE_IV_FROM_PLOAD = 12, + EFUSE_WRITE_GLITCH_CONFIG = 13, + EFUSE_WRITE_DEC_ONLY = 14, + EFUSE_WRITE_REVOCATION_ID = 15, + EFUSE_WRITE_OFFCHIP_REVOKE_ID = 16, + EFUSE_WRITE_MISC_CTRL_BITS = 17, + EFUSE_WRITE_SEC_CTRL_BITS = 18, + EFUSE_WRITE_MISC1_CTRL_BITS = 19, + EFUSE_WRITE_BOOT_ENV_CTRL_BITS = 20, + EFUSE_WRITE_FIPS_INFO = 21, + EFUSE_WRITE_UDS_FROM_PLOAD = 22, + EFUSE_WRITE_DME_KEY_FROM_PLOAD = 23, + EFUSE_WRITE_DME_REVOKE = 24, + EFUSE_WRITE_PLM_UPDATE = 25, + EFUSE_WRITE_BOOT_MODE_DISABLE = 26, + EFUSE_WRITE_CRC = 27, + EFUSE_WRITE_DME_MODE = 28, + EFUSE_WRITE_PUF_HD_FROM_PLOAD = 29, + EFUSE_WRITE_PUF = 30, + EFUSE_WRITE_ROM_RSVD = 31, + EFUSE_WRITE_PUF_CTRL_BITS = 32, + EFUSE_READ_CACHE = 33, + EFUSE_RELOAD_N_PRGM_PROT_BITS = 34, + EFUSE_INVALID = 35, +}; + +/* uint64_t are memory addresses */ +struct versal_efuse_data { + uint64_t env_mon_dis_flag; + uint64_t aes_key_addr; + uint64_t ppk_hash_addr; + uint64_t dec_only_addr; + uint64_t sec_ctrl_addr; + uint64_t misc_ctrl_addr; + uint64_t revoke_id_addr; + uint64_t iv_addr; + uint64_t user_fuse_addr; + uint64_t glitch_cfg_addr; + uint64_t boot_env_ctrl_addr; + uint64_t misc1_ctrl_addr; + uint64_t offchip_id_addr; + uint8_t pad[24]; +}; + +/* Helper read and write requests (not part of the protocol) */ +struct versal_nvm_buf { + size_t len; + void *buf; +}; + +struct versal_nvm_read_req { + enum versal_nvm_api_id efuse_id; + enum versal_nvm_revocation_id revocation_id; + enum versal_nvm_offchip_id offchip_id; + enum versal_nvm_ppk_type ppk_type; + enum versal_nvm_iv_type iv_type; + struct versal_nvm_buf ibuf[VERSAL_MAX_IPI_BUF]; +}; + +struct versal_bbram_data { + size_t aes_key_len; + uint32_t user_data; +}; + +struct versal_nvm_write_req { + struct versal_efuse_data data; + struct versal_bbram_data bbram; + struct versal_nvm_buf ibuf[VERSAL_MAX_IPI_BUF]; + enum versal_nvm_api_id efuse_id; +}; + +static TEE_Result +prepare_cmd(struct versal_ipi_cmd *cmd, enum versal_nvm_api_id efuse, + struct versal_nvm_buf *ibufs, uint32_t *arg) +{ + uint32_t a = 0; + uint32_t b = 0; + size_t i = 0; + + cmd->data[i++] = NVM_API_ID(efuse); + if (arg) + cmd->data[i++] = *arg; + + if (!ibufs[0].buf) + return TEE_SUCCESS; + + reg_pair_from_64(virt_to_phys(ibufs[0].buf), &b, &a); + + cmd->data[i++] = a; + cmd->data[i++] = b; + + for (i = 0; i < VERSAL_MAX_IPI_BUF; i++) { + cmd->ibuf[i].mem.alloc_len = ibufs[i].len; + cmd->ibuf[i].mem.buf = ibufs[i].buf; + } + + return TEE_SUCCESS; +} + +static TEE_Result efuse_req(enum versal_nvm_api_id efuse, + struct versal_nvm_buf *ibufs, uint32_t *arg) +{ + struct versal_ipi_cmd cmd = { }; + TEE_Result ret = TEE_SUCCESS; + + ret = prepare_cmd(&cmd, efuse, ibufs, arg); + if (ret) + return ret; + + ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); + if (ret) + EMSG("Mailbox error"); + + return ret; +} + +static TEE_Result versal_alloc_read_buffer(struct versal_nvm_read_req *req) +{ + assert(req); + req->ibuf[0].len = 1024; + req->ibuf[0].buf = alloc_cache_aligned(req->ibuf[0].len); + if (!req->ibuf[0].buf) + return TEE_ERROR_OUT_OF_MEMORY; + + return TEE_SUCCESS; +} + +static void versal_free_read_buffer(struct versal_nvm_read_req *req) +{ + assert(req); + free(req->ibuf[0].buf); +} + +static void *versal_get_read_buffer(struct versal_nvm_read_req *req) +{ + assert(req); + return req->ibuf[0].buf; +} + +static TEE_Result versal_nvm_read(struct versal_nvm_read_req *req) +{ + if (!req) + return TEE_ERROR_GENERIC; + + switch (req->efuse_id) { + case EFUSE_READ_CACHE: + case BBRAM_READ_USER_DATA: + break; + default: + return TEE_ERROR_GENERIC; + } + + return efuse_req(req->efuse_id, req->ibuf, NULL); +} + +static TEE_Result versal_nvm_write(struct versal_nvm_write_req *req) +{ + uint32_t *arg = NULL; + uint32_t val = 0; + + switch (req->efuse_id) { + case BBRAM_WRITE_AES_KEY: + val = req->bbram.aes_key_len; + arg = &val; + break; + case BBRAM_WRITE_USER_DATA: + val = req->bbram.user_data; + arg = &val; + break; + case BBRAM_ZEROIZE: + break; + default: + return TEE_ERROR_GENERIC; + } + + return efuse_req(req->efuse_id, req->ibuf, arg); +} + +TEE_Result versal_bbram_write_aes_key(uint8_t *key, size_t len) +{ + struct versal_nvm_write_req req __aligned_efuse = { + .efuse_id = BBRAM_WRITE_AES_KEY, + .bbram.aes_key_len = len, + }; + void *buf = NULL; + + if (len != 32) + return TEE_ERROR_BAD_PARAMETERS; + + buf = alloc_cache_aligned(1024); + if (!buf) + return TEE_ERROR_OUT_OF_MEMORY; + + memcpy(buf, key, len); + + req.ibuf[0].buf = buf; + req.ibuf[0].len = 1024; + + if (versal_nvm_write(&req)) { + free(buf); + return TEE_ERROR_GENERIC; + } + free(buf); + + return TEE_SUCCESS; +} + +TEE_Result versal_bbram_zeroize(void) +{ + struct versal_nvm_write_req req __aligned_efuse = { + .efuse_id = BBRAM_ZEROIZE, + }; + + if (versal_nvm_write(&req)) + return TEE_ERROR_GENERIC; + + return TEE_SUCCESS; +} + +TEE_Result versal_bbram_write_user_data(uint32_t data) +{ + struct versal_nvm_write_req req __aligned_efuse = { + .efuse_id = BBRAM_WRITE_USER_DATA, + .bbram.user_data = data, + }; + + if (versal_nvm_write(&req)) + return TEE_ERROR_GENERIC; + + return TEE_SUCCESS; +} + +TEE_Result versal_bbram_read_user_data(uint32_t *data) +{ + struct versal_nvm_read_req req = { + .efuse_id = BBRAM_READ_USER_DATA, + }; + + if (versal_alloc_read_buffer(&req)) + return TEE_ERROR_OUT_OF_MEMORY; + + if (versal_nvm_read(&req)) { + versal_free_read_buffer(&req); + return TEE_ERROR_GENERIC; + } + + memcpy(data, versal_get_read_buffer(&req), sizeof(*data)); + versal_free_read_buffer(&req); + + return TEE_SUCCESS; +} + +TEE_Result versal_bbram_lock_write_user_data(void) +{ + struct versal_nvm_write_req req __aligned_efuse = { + .efuse_id = BBRAM_LOCK_WRITE_USER_DATA, + }; + + if (versal_nvm_write(&req)) + return TEE_ERROR_GENERIC; + + return TEE_SUCCESS; +} + +static TEE_Result versal_efuse_read_cache(uint16_t off, uint16_t num, + uint32_t *buf, size_t len) +{ + struct versal_ipi_cmd cmd = { }; + struct versal_mbox_mem p = { }; + TEE_Result ret = TEE_SUCCESS; + uint32_t a = 0; + uint32_t b = 0; + + if (!buf) + return TEE_ERROR_BAD_PARAMETERS; + + if (len < num * NVM_WORD_LEN) + return TEE_ERROR_BAD_PARAMETERS; + + ret = versal_mbox_alloc(num * NVM_WORD_LEN, NULL, &p); + if (ret) + return ret; + + reg_pair_from_64(virt_to_phys(p.buf), &b, &a); + + cmd.data[0] = NVM_API_ID(EFUSE_READ_CACHE); + cmd.data[1] = (num << 16) | off; + cmd.data[2] = a; + cmd.data[3] = b; + + cmd.ibuf[0].mem = p; + + ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); + if (ret) + EMSG("Mailbox error"); + else + memcpy(buf, p.buf, num * NVM_WORD_LEN); + + versal_mbox_free(&p); + return ret; +} + +#define EFUSE_CACHE_DNA_OFFSET 0x20 +#define EFUSE_CACHE_BOOT_ENV_CTRL_OFFSET 0x94 +#define EFUSE_CACHE_MISC_CTRL_OFFSET 0xA0 +#define EFUSE_CACHE_PUF_ECC_CTRL_OFFSET 0xA4 +#define EFUSE_CACHE_PUF_CHASH_OFFSET 0xA8 +#define EFUSE_CACHE_SEC_CTRL_OFFSET 0xAC +#define EFUSE_CACHE_REVOCATION_ID0_OFFSET 0xB0 +#define EFUSE_CACHE_SEC_MISC0_OFFSET 0xE4 +#define EFUSE_CACHE_SEC_MISC1_OFFSET 0xE8 +#define EFUSE_CACHE_PPK0_OFFSET 0x100 +#define EFUSE_CACHE_PPK1_OFFSET 0x120 +#define EFUSE_CACHE_PPK2_OFFSET 0x140 +#define EFUSE_CACHE_OFFCHIP_REVOKE_ID0_OFFSET 0x160 +#define EFUSE_CACHE_METAHEADER_IV_RANGE0_OFFSET 0x180 +#define EFUSE_CACHE_BLACK_IV0_OFFSET 0x1D0 +#define EFUSE_CACHE_PLM_IV_RANGE0_OFFSET 0x1DC +#define EFUSE_CACHE_DATA_PARTITION_IV_RANGE0_OFFSET 0x1E8 +#define EFUSE_CACHE_USER0_OFFSET 0x240 +#define EFUSE_CACHE_PUF_SYN0_OFFSET 0x300 + +TEE_Result versal_efuse_read_dna(uint32_t *buf, size_t len) +{ + if (len < EFUSE_DNA_LEN) + return TEE_ERROR_BAD_PARAMETERS; + + return versal_efuse_read_cache(EFUSE_CACHE_DNA_OFFSET, + EFUSE_DNA_LEN / NVM_WORD_LEN, buf, len); +} + +TEE_Result versal_efuse_read_user_data(uint32_t *buf, size_t len, + uint32_t first, size_t num) +{ + uint16_t offset; + + if (first + num > EFUSE_MAX_USER_FUSES || len < num * NVM_WORD_LEN) + return TEE_ERROR_BAD_PARAMETERS; + + offset = EFUSE_CACHE_USER0_OFFSET + first * NVM_WORD_LEN; + + return versal_efuse_read_cache(offset, num, buf, len); +} + +TEE_Result versal_efuse_read_iv(uint32_t *buf, size_t len, + enum versal_nvm_iv_type type) +{ + uint16_t offset; + + switch (type) { + case EFUSE_META_HEADER_IV_RANGE: + offset = EFUSE_CACHE_METAHEADER_IV_RANGE0_OFFSET; + break; + case EFUSE_BLACK_IV: + offset = EFUSE_CACHE_BLACK_IV0_OFFSET; + break; + case EFUSE_PLM_IV_RANGE: + offset = EFUSE_CACHE_PLM_IV_RANGE0_OFFSET; + break; + case EFUSE_DATA_PARTITION_IV_RANGE: + offset = EFUSE_CACHE_DATA_PARTITION_IV_RANGE0_OFFSET; + break; + default: + return TEE_ERROR_BAD_PARAMETERS; + } + + return versal_efuse_read_cache(offset, EFUSE_IV_LEN / NVM_WORD_LEN, + buf, len); +} + +TEE_Result versal_efuse_read_ppk(uint32_t *buf, size_t len, + enum versal_nvm_ppk_type type) +{ + uint16_t offset; + + switch (type) { + case EFUSE_PPK0: + offset = EFUSE_CACHE_PPK0_OFFSET; + break; + case EFUSE_PPK1: + offset = EFUSE_CACHE_PPK1_OFFSET; + break; + case EFUSE_PPK2: + offset = EFUSE_CACHE_PPK2_OFFSET; + break; + default: + return TEE_ERROR_BAD_PARAMETERS; + } + + return versal_efuse_read_cache(offset, EFUSE_PPK_LEN / NVM_WORD_LEN, + buf, len); +} + +TEE_Result versal_efuse_read_revoke_id(uint32_t *buf, size_t len, + enum versal_nvm_revocation_id id) +{ + return versal_efuse_read_cache(EFUSE_CACHE_REVOCATION_ID0_OFFSET + + id * NVM_WORD_LEN, + EFUSE_REVOCATION_ID_LEN / NVM_WORD_LEN, + buf, len); +} + +TEE_Result versal_efuse_read_misc_ctrl(struct versal_efuse_misc_ctrl_bits *buf) +{ + TEE_Result ret = TEE_SUCCESS; + uint32_t misc_ctrl = 0; + + if (!buf) + return TEE_ERROR_BAD_PARAMETERS; + + ret = versal_efuse_read_cache(EFUSE_CACHE_MISC_CTRL_OFFSET, 1, + &misc_ctrl, sizeof(uint32_t)); + if (ret) + return ret; + + buf->glitch_det_halt_boot_en = ((misc_ctrl & GENMASK_32(31, 30)) >> 30); + buf->glitch_det_rom_monitor_en = ((misc_ctrl & BIT(29)) >> 29); + buf->halt_boot_error = ((misc_ctrl & GENMASK_32(22, 21)) >> 21); + buf->halt_boot_env = ((misc_ctrl & GENMASK_32(20, 19)) >> 19); + buf->crypto_kat_en = ((misc_ctrl & BIT(15)) >> 15); + buf->lbist_en = ((misc_ctrl & BIT(14)) >> 14); + buf->safety_mission_en = ((misc_ctrl & BIT(8)) >> 8); + buf->ppk0_invalid = ((misc_ctrl & GENMASK_32(7, 6)) >> 6); + buf->ppk1_invalid = ((misc_ctrl & GENMASK_32(5, 4)) >> 4); + buf->ppk2_invalid = ((misc_ctrl & GENMASK_32(3, 2)) >> 2); + + return ret; +} + +TEE_Result versal_efuse_read_sec_ctrl(struct versal_efuse_sec_ctrl_bits *buf) +{ + TEE_Result ret = TEE_SUCCESS; + uint32_t sec_ctrl = 0; + + if (!buf) + return TEE_ERROR_BAD_PARAMETERS; + + ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_CTRL_OFFSET, 1, + &sec_ctrl, sizeof(uint32_t)); + if (ret) + return ret; + + buf->aes_dis = (sec_ctrl & BIT(0)); + buf->jtag_err_out_dis = ((sec_ctrl & BIT(1)) >> 1); + buf->jtag_dis = ((sec_ctrl & BIT(2)) >> 2); + buf->ppk0_wr_lk = ((sec_ctrl & BIT(6)) >> 6); + buf->ppk1_wr_lk = ((sec_ctrl & BIT(7)) >> 7); + buf->ppk2_wr_lk = ((sec_ctrl & BIT(8)) >> 8); + buf->aes_crc_lk = ((sec_ctrl & GENMASK_32(10, 9)) >> 9); + buf->aes_wr_lk = ((sec_ctrl & BIT(11)) >> 11); + buf->user_key0_crc_lk = ((sec_ctrl & BIT(12)) >> 12); + buf->user_key0_wr_lk = ((sec_ctrl & BIT(13)) >> 13); + buf->user_key1_crc_lk = ((sec_ctrl & BIT(14)) >> 14); + buf->user_key1_wr_lk = ((sec_ctrl & BIT(15)) >> 15); + buf->sec_dbg_dis = ((sec_ctrl & GENMASK_32(20, 19)) >> 19); + buf->sec_lock_dbg_dis = ((sec_ctrl & GENMASK_32(22, 21)) >> 21); + buf->boot_env_wr_lk = ((sec_ctrl & BIT(28)) >> 28); + buf->reg_init_dis = ((sec_ctrl & GENMASK_32(31, 30)) >> 30); + + return ret; +} + +TEE_Result versal_efuse_read_sec_misc1(struct versal_efuse_sec_misc1_bits *buf) +{ + TEE_Result ret = TEE_SUCCESS; + uint32_t sec_misc1 = 0; + + if (!buf) + return TEE_ERROR_BAD_PARAMETERS; + + ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_MISC1_OFFSET, 1, + &sec_misc1, sizeof(uint32_t)); + if (ret) + return ret; + + buf->lpd_mbist_en = ((sec_misc1 & GENMASK_32(12, 10)) >> 10); + buf->pmc_mbist_en = ((sec_misc1 & GENMASK_32(9, 7)) >> 7); + buf->lpd_noc_sc_en = ((sec_misc1 & GENMASK_32(6, 4)) >> 4); + buf->sysmon_volt_mon_en = ((sec_misc1 & GENMASK_32(3, 2)) >> 2); + buf->sysmon_temp_mon_en = (sec_misc1 & GENMASK_32(1, 0)); + + return ret; +} + +TEE_Result +versal_efuse_read_boot_env_ctrl(struct versal_efuse_boot_env_ctrl_bits *buf) +{ + TEE_Result ret = TEE_SUCCESS; + uint32_t boot_env_ctrl = 0; + + if (!buf) + return TEE_ERROR_BAD_PARAMETERS; + + ret = versal_efuse_read_cache(EFUSE_CACHE_BOOT_ENV_CTRL_OFFSET, 1, + &boot_env_ctrl, sizeof(uint32_t)); + if (ret) + return ret; + + buf->sysmon_temp_en = ((boot_env_ctrl & BIT(21)) >> 21); + buf->sysmon_volt_en = ((boot_env_ctrl & BIT(20)) >> 20); + buf->sysmon_temp_hot = ((boot_env_ctrl & GENMASK_32(18, 17)) >> 17); + buf->sysmon_volt_pmc = ((boot_env_ctrl & GENMASK_32(13, 12)) >> 12); + buf->sysmon_volt_pslp = ((boot_env_ctrl & GENMASK_32(11, 10)) >> 10); + buf->sysmon_volt_soc = ((boot_env_ctrl & GENMASK_32(9, 8)) >> 8); + buf->sysmon_temp_cold = (boot_env_ctrl & GENMASK_32(1, 0)); + + return ret; +} + +TEE_Result versal_efuse_read_offchip_revoke_id(uint32_t *buf, size_t len, + enum versal_nvm_offchip_id id) +{ + if (id == EFUSE_INVLD) + return TEE_ERROR_BAD_PARAMETERS; + + return versal_efuse_read_cache(EFUSE_CACHE_OFFCHIP_REVOKE_ID0_OFFSET + + id * NVM_WORD_LEN, + EFUSE_REVOCATION_ID_LEN / NVM_WORD_LEN, + buf, len); +} + +TEE_Result versal_efuse_read_dec_only(uint32_t *buf, size_t len) +{ + TEE_Result ret = TEE_SUCCESS; + uint32_t sec_misc0 = 0; + + if (len < EFUSE_DEC_ONLY_LEN) + return TEE_ERROR_BAD_PARAMETERS; + + ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_MISC0_OFFSET, 1, + &sec_misc0, sizeof(uint32_t)); + if (ret) + return ret; + + sec_misc0 &= GENMASK_32(15, 0); + + memcpy(buf, &sec_misc0, EFUSE_DEC_ONLY_LEN); + + return ret; +} + +TEE_Result versal_efuse_read_puf_sec_ctrl(struct versal_efuse_puf_sec_ctrl_bits + *buf) +{ + TEE_Result ret = TEE_SUCCESS; + uint32_t puf_ctrl = 0; + uint32_t sec_ctrl = 0; + + if (!buf) + return TEE_ERROR_BAD_PARAMETERS; + + ret = versal_efuse_read_cache(EFUSE_CACHE_PUF_ECC_CTRL_OFFSET, 1, + &puf_ctrl, sizeof(uint32_t)); + if (ret) + return ret; + + /* + * Some fuses have moved from PUF_ECC_CTRL to SECURITY_CTRL + */ + ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_CTRL_OFFSET, 1, + &sec_ctrl, sizeof(uint32_t)); + if (ret) + return ret; + + buf->puf_regen_dis = ((puf_ctrl & BIT(31)) >> 31); + buf->puf_hd_invalid = ((puf_ctrl & BIT(30)) >> 30); + buf->puf_test2_dis = ((puf_ctrl & BIT(29)) >> 29); + buf->puf_dis = ((sec_ctrl & BIT(18)) >> 18); + buf->puf_syn_lk = ((sec_ctrl & BIT(16)) >> 16); + + return ret; +} + +TEE_Result versal_efuse_read_puf(struct versal_efuse_puf_header *buf) +{ + TEE_Result ret = TEE_SUCCESS; + + if (!buf) + return TEE_ERROR_BAD_PARAMETERS; + + ret = versal_efuse_read_puf_sec_ctrl(&buf->sec_ctrl); + if (ret) + return ret; + + ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_CTRL_OFFSET, 1, + &buf->aux, sizeof(uint32_t)); + if (ret) + return ret; + + buf->aux &= GENMASK_32(23, 0); + + ret = versal_efuse_read_cache(EFUSE_CACHE_PUF_CHASH_OFFSET, 1, + &buf->chash, sizeof(uint32_t)); + if (ret) + return ret; + + ret = versal_efuse_read_cache(EFUSE_CACHE_PUF_SYN0_OFFSET, + PUF_SYN_DATA_WORDS, buf->efuse_syn_data, + PUF_SYN_DATA_WORDS * NVM_WORD_LEN); + return ret; +} + +TEE_Result +versal_efuse_read_puf_as_user_fuse(struct versal_efuse_puf_user_fuse + *p __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result versal_efuse_write_user_data(uint32_t *buf __unused, + size_t len __unused, + uint32_t first __unused, + size_t num __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +#define EFUSE_ENV_DIS_FLAG 0 + +#define EFUSE_AES_KEY_ID 0 +#define EFUSE_USER_KEY0_ID 1 +#define EFUSE_USER_KEY1_ID 2 + +static TEE_Result do_write_efuses_buffer(enum versal_nvm_api_id id, + uint16_t type, uint32_t *buf, + size_t len) +{ + struct versal_ipi_cmd cmd = { }; + struct versal_mbox_mem p = { }; + TEE_Result ret = TEE_SUCCESS; + uint32_t a = 0; + uint32_t b = 0; + + ret = versal_mbox_alloc(len, buf, &p); + if (ret) + return ret; + + reg_pair_from_64(virt_to_phys(p.buf), &b, &a); + + cmd.data[0] = NVM_API_ID(id); + cmd.data[1] = (type << 16) | EFUSE_ENV_DIS_FLAG; + cmd.data[2] = a; + cmd.data[3] = b; + + cmd.ibuf[0].mem = p; + + ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); + + versal_mbox_free(&p); + return ret; +} + +static TEE_Result do_write_efuses_value(enum versal_nvm_api_id id, uint32_t val) +{ + struct versal_ipi_cmd cmd = { }; + TEE_Result ret = TEE_SUCCESS; + + cmd.data[0] = NVM_API_ID(id); + cmd.data[1] = EFUSE_ENV_DIS_FLAG; + cmd.data[2] = val; + + ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); + + return ret; +} + +static TEE_Result do_write_efuses(enum versal_nvm_api_id id) +{ + return do_write_efuses_value(id, 0); +} + +TEE_Result versal_efuse_write_aes_keys(struct versal_efuse_aes_keys *keys) +{ + TEE_Result ret = TEE_SUCCESS; + TEE_Result res; + + if (!keys) + return TEE_ERROR_BAD_PARAMETERS; + + if (keys->prgm_aes_key) { + res = do_write_efuses_buffer(EFUSE_WRITE_AES_KEY, + EFUSE_AES_KEY_ID, + keys->aes_key, EFUSE_AES_KEY_LEN); + if (res) { + DMSG("Error programming AES key (0x%" PRIx32 ")", res); + ret = TEE_ERROR_GENERIC; + } + } + + if (keys->prgm_user_key0) { + res = do_write_efuses_buffer(EFUSE_WRITE_AES_KEY, + EFUSE_USER_KEY0_ID, + keys->user_key0, + EFUSE_AES_KEY_LEN); + if (res) { + DMSG("Error programming User key 0 (0x%" PRIx32 ")", + res); + ret = TEE_ERROR_GENERIC; + } + } + + if (keys->prgm_user_key1) { + res = do_write_efuses_buffer(EFUSE_WRITE_AES_KEY, + EFUSE_USER_KEY1_ID, + keys->user_key1, + EFUSE_AES_KEY_LEN); + if (res) { + DMSG("Error programming User key 1 (0x%" PRIx32 ")", + res); + ret = TEE_ERROR_GENERIC; + } + } + + return ret; +} + +TEE_Result versal_efuse_write_ppk_hash(struct versal_efuse_ppk_hash *hash) +{ + TEE_Result ret = TEE_SUCCESS; + TEE_Result res; + + if (!hash) + return TEE_ERROR_BAD_PARAMETERS; + + if (hash->prgm_ppk0_hash) { + res = do_write_efuses_buffer(EFUSE_WRITE_PPK_HASH, EFUSE_PPK0, + hash->ppk0_hash, EFUSE_PPK_LEN); + if (res) { + DMSG("Error programming PPK hash 0 (0x%" PRIx32 ")", + res); + ret = TEE_ERROR_GENERIC; + } + } + + if (hash->prgm_ppk1_hash) { + res = do_write_efuses_buffer(EFUSE_WRITE_PPK_HASH, EFUSE_PPK1, + hash->ppk1_hash, EFUSE_PPK_LEN); + if (res) { + DMSG("Error programming PPK hash 1 (0x%" PRIx32 ")", + res); + ret = TEE_ERROR_GENERIC; + } + } + + if (hash->prgm_ppk2_hash) { + res = do_write_efuses_buffer(EFUSE_WRITE_PPK_HASH, EFUSE_PPK2, + hash->ppk2_hash, EFUSE_PPK_LEN); + if (res) { + DMSG("Error programming PPK hash 2 (0x%" PRIx32 ")", + res); + ret = TEE_ERROR_GENERIC; + } + } + + return ret; +} + +TEE_Result versal_efuse_write_iv(struct versal_efuse_ivs *p) +{ + TEE_Result ret = TEE_SUCCESS; + TEE_Result res; + + if (!p) + return TEE_ERROR_BAD_PARAMETERS; + + if (p->prgm_meta_header_iv) { + res = do_write_efuses_buffer(EFUSE_WRITE_IV, + EFUSE_META_HEADER_IV_RANGE, + p->meta_header_iv, EFUSE_IV_LEN); + if (res) { + DMSG("Error programming meta header IV (0x%" PRIx32 ")", + res); + ret = TEE_ERROR_GENERIC; + } + } + + if (p->prgm_blk_obfus_iv) { + res = do_write_efuses_buffer(EFUSE_WRITE_IV, EFUSE_BLACK_IV, + p->blk_obfus_iv, EFUSE_IV_LEN); + if (res) { + DMSG("Error programming black IV (0x%" PRIx32 ")", res); + ret = TEE_ERROR_GENERIC; + } + } + + if (p->prgm_plm_iv) { + res = do_write_efuses_buffer(EFUSE_WRITE_IV, EFUSE_PLM_IV_RANGE, + p->plm_iv, EFUSE_IV_LEN); + if (res) { + DMSG("Error programming plm IV (0x%" PRIx32 ")", res); + ret = TEE_ERROR_GENERIC; + } + } + + if (p->prgm_data_partition_iv) { + res = do_write_efuses_buffer(EFUSE_WRITE_IV, + EFUSE_DATA_PARTITION_IV_RANGE, + p->data_partition_iv, + EFUSE_IV_LEN); + if (res) { + DMSG("Error programming data IV (0x%" PRIx32 ")", res); + ret = TEE_ERROR_GENERIC; + } + } + + return ret; +} + +TEE_Result versal_efuse_write_dec_only(struct versal_efuse_dec_only *p) +{ + if (!p) + return TEE_ERROR_BAD_PARAMETERS; + + if (!p->prgm_dec_only) + return TEE_SUCCESS; + + return do_write_efuses(EFUSE_WRITE_DEC_ONLY); +} + +TEE_Result versal_efuse_write_sec(struct versal_efuse_sec_ctrl_bits *p) +{ + uint32_t val = 0; + + if (!p) + return TEE_ERROR_BAD_PARAMETERS; + + val = ((p->reg_init_dis & 0x3) << 30) | + ((p->boot_env_wr_lk & 0x1) << 28) | + ((p->sec_lock_dbg_dis & 0x3) << 21) | + ((p->sec_dbg_dis & 0x3) << 19) | + ((p->user_key1_wr_lk & 0x1) << 15) | + ((p->user_key1_crc_lk & 0x1) << 14) | + ((p->user_key0_wr_lk & 0x1) << 13) | + ((p->user_key0_crc_lk & 0x1) << 12) | + ((p->aes_wr_lk & 0x1) << 11) | + ((p->aes_crc_lk & 0x3) << 9) | + ((p->ppk2_wr_lk & 0x1) << 8) | + ((p->ppk1_wr_lk & 0x1) << 7) | + ((p->ppk0_wr_lk & 0x1) << 6) | + ((p->jtag_dis & 0x1) << 2) | + ((p->jtag_err_out_dis & 0x1) << 1) | + (p->aes_dis & 0x1); + + return do_write_efuses_value(EFUSE_WRITE_SEC_CTRL_BITS, val); +} + +TEE_Result versal_efuse_write_misc(struct versal_efuse_misc_ctrl_bits *p) +{ + uint32_t val = 0; + + if (!p) + return TEE_ERROR_BAD_PARAMETERS; + + val = ((p->glitch_det_halt_boot_en & 0x3) << 30) | + ((p->glitch_det_rom_monitor_en & 0x1) << 29) | + ((p->halt_boot_error & 0x3) << 21) | + ((p->halt_boot_env & 0x3) << 19) | + ((p->crypto_kat_en & 0x1) << 15) | + ((p->lbist_en & 0x1) << 14) | + ((p->safety_mission_en & 0x1) << 8) | + ((p->ppk2_invalid & 0x3) << 6) | + ((p->ppk1_invalid & 0x3) << 4) | + ((p->ppk0_invalid & 0x3) << 2); + + return do_write_efuses_value(EFUSE_WRITE_MISC_CTRL_BITS, val); +} + +TEE_Result +versal_efuse_write_glitch_cfg(struct versal_efuse_glitch_cfg_bits *p) +{ + uint32_t val = 0; + + if (!p) + return TEE_ERROR_BAD_PARAMETERS; + + if (!p->prgm_glitch) + return TEE_SUCCESS; + + val = ((p->glitch_det_wr_lk & 0x1) << 31) | p->glitch_det_trim; + + return do_write_efuses_value(EFUSE_WRITE_GLITCH_CONFIG, val); +} + +TEE_Result +versal_efuse_write_boot_env(struct versal_efuse_boot_env_ctrl_bits *p) +{ + uint32_t val = 0; + + if (!p) + return TEE_ERROR_BAD_PARAMETERS; + + val = ((p->sysmon_temp_en & 0x1) << 21) | + ((p->sysmon_volt_en & 0x1) << 20) | + ((p->sysmon_temp_hot & 0x3) << 17) | + ((p->sysmon_volt_pmc & 0x3) << 12) | + ((p->sysmon_volt_pslp & 0x3) << 10) | + ((p->sysmon_volt_soc & 0x3) << 8) | + (p->sysmon_temp_cold & 0x2); + + return do_write_efuses_value(EFUSE_WRITE_BOOT_ENV_CTRL_BITS, val); +} + +TEE_Result versal_efuse_write_sec_misc1(struct versal_efuse_sec_misc1_bits *p) +{ + uint32_t val = 0; + + if (!p) + return TEE_ERROR_BAD_PARAMETERS; + + val = ((p->lpd_mbist_en & 0x7) << 10) | + ((p->pmc_mbist_en & 0x7) << 7) | + ((p->lpd_noc_sc_en & 0x7) << 4) | + ((p->sysmon_volt_mon_en & 0x3) << 2) | + (p->sysmon_temp_mon_en & 0x3); + + return do_write_efuses_value(EFUSE_WRITE_MISC1_CTRL_BITS, val); +} + +TEE_Result versal_efuse_write_offchip_ids(uint32_t id) +{ + return do_write_efuses_value(EFUSE_WRITE_OFFCHIP_REVOKE_ID, id); +} + +TEE_Result versal_efuse_write_revoke_ppk(enum versal_nvm_ppk_type type) +{ + struct versal_efuse_misc_ctrl_bits misc_ctrl; + + memset(&misc_ctrl, 0, sizeof(struct versal_efuse_misc_ctrl_bits)); + + switch (type) { + case EFUSE_PPK0: + misc_ctrl.ppk0_invalid = 0x3; + break; + case EFUSE_PPK1: + misc_ctrl.ppk1_invalid = 0x3; + break; + case EFUSE_PPK2: + misc_ctrl.ppk2_invalid = 0x3; + break; + default: + return TEE_ERROR_BAD_PARAMETERS; + } + + return versal_efuse_write_misc(&misc_ctrl); +} + +TEE_Result versal_efuse_write_revoke_id(uint32_t id) +{ + return do_write_efuses_value(EFUSE_WRITE_REVOCATION_ID, id); +} + +TEE_Result versal_efuse_write_puf_as_user_fuse(struct versal_efuse_puf_user_fuse + *p __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +#define EFUSE_WRITE_PUF_DATA_WORDS (PUF_SYN_DATA_WORDS + 6) + +struct versal_efuse_write_puf_data { + uint32_t sec_ctrl; + uint32_t prgm_puf_helper_data; + uint32_t env_monitor_dis; + uint32_t syn[PUF_SYN_DATA_WORDS]; + uint32_t chash; + uint32_t aux; + uint32_t ro_swap; +}; + +TEE_Result versal_efuse_write_puf(struct versal_efuse_puf_header *buf) +{ + struct versal_ipi_cmd cmd = { }; + struct versal_mbox_mem p = { }; + TEE_Result ret = TEE_SUCCESS; + uint32_t a = 0; + uint32_t b = 0; + struct versal_efuse_write_puf_data *data; + + if (!buf) + return TEE_ERROR_BAD_PARAMETERS; + + ret = versal_mbox_alloc(EFUSE_WRITE_PUF_DATA_WORDS * NVM_WORD_LEN, + NULL, &p); + if (ret) + return ret; + + data = p.buf; + + data->sec_ctrl = 0; + data->prgm_puf_helper_data = buf->prmg_puf_helper_data; + data->env_monitor_dis = buf->env_monitor_dis; + memcpy(data->syn, buf->efuse_syn_data, + PUF_SYN_DATA_WORDS * NVM_WORD_LEN); + data->chash = buf->chash; + data->aux = buf->aux; + data->ro_swap = 0; + + reg_pair_from_64(virt_to_phys(p.buf), &b, &a); + + cmd.data[0] = NVM_API_ID(EFUSE_WRITE_PUF); + cmd.data[2] = a; + cmd.data[3] = b; + + cmd.ibuf[0].mem = p; + + ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); + + versal_mbox_free(&p); + return ret; +} diff --git a/core/drivers/versal_nvm.c b/core/drivers/versal_nvm.c index 9c4c78e4631..657dfa93494 100644 --- a/core/drivers/versal_nvm.c +++ b/core/drivers/versal_nvm.c @@ -13,7 +13,6 @@ #include #include #include -#include #include "drivers/versal_nvm.h" @@ -42,46 +41,6 @@ struct versal_efuse_puf_fuse_addr { */ #define EFUSE_MAX_LEN (EFUSE_MAX_USER_FUSES * sizeof(uint32_t)) -#if defined(PLATFORM_FLAVOR_net) -enum versal_nvm_api_id { - API_FEATURES = 0, - BBRAM_WRITE_AES_KEY = 1, - BBRAM_ZEROIZE = 2, - BBRAM_WRITE_USER_DATA = 3, - BBRAM_READ_USER_DATA = 4, - BBRAM_LOCK_WRITE_USER_DATA = 5, - BBRAM_WRITE_AES_KEY_FROM_PLOAD = 6, - EFUSE_WRITE_AES_KEY = 7, - EFUSE_WRITE_AES_KEY_FROM_PLOAD = 8, - EFUSE_WRITE_PPK_HASH = 9, - EFUSE_WRITE_PPK_HASH_FROM_PLOAD = 10, - EFUSE_WRITE_IV = 11, - EFUSE_WRITE_IV_FROM_PLOAD = 12, - EFUSE_WRITE_GLITCH_CONFIG = 13, - EFUSE_WRITE_DEC_ONLY = 14, - EFUSE_WRITE_REVOCATION_ID = 15, - EFUSE_WRITE_OFFCHIP_REVOKE_ID = 16, - EFUSE_WRITE_MISC_CTRL_BITS = 17, - EFUSE_WRITE_SEC_CTRL_BITS = 18, - EFUSE_WRITE_MISC1_CTRL_BITS = 19, - EFUSE_WRITE_BOOT_ENV_CTRL_BITS = 20, - EFUSE_WRITE_FIPS_INFO = 21, - EFUSE_WRITE_UDS_FROM_PLOAD = 22, - EFUSE_WRITE_DME_KEY_FROM_PLOAD = 23, - EFUSE_WRITE_DME_REVOKE = 24, - EFUSE_WRITE_PLM_UPDATE = 25, - EFUSE_WRITE_BOOT_MODE_DISABLE = 26, - EFUSE_WRITE_CRC = 27, - EFUSE_WRITE_DME_MODE = 28, - EFUSE_WRITE_PUF_HD_FROM_PLOAD = 29, - EFUSE_WRITE_PUF = 30, - EFUSE_WRITE_ROM_RSVD = 31, - EFUSE_WRITE_PUF_CTRL_BITS = 32, - EFUSE_READ_CACHE = 33, - EFUSE_RELOAD_N_PRGM_PROT_BITS = 34, - EFUSE_INVALID = 35, -}; -#else enum versal_nvm_api_id { API_FEATURES = 0, BBRAM_WRITE_AES_KEY = 1, @@ -108,7 +67,6 @@ enum versal_nvm_api_id { EFUSE_READ_PUF = 22, EFUSE_INVALID = 23, }; -#endif /* uint64_t are memory addresses */ struct versal_efuse_data { @@ -155,1020 +113,144 @@ struct versal_nvm_write_req { enum versal_nvm_api_id efuse_id; }; -static TEE_Result -prepare_cmd(struct versal_ipi_cmd *cmd, enum versal_nvm_api_id efuse, - struct versal_nvm_buf *ibufs, uint32_t *arg) -{ - uint32_t a = 0; - uint32_t b = 0; - size_t i = 0; - - cmd->data[i++] = NVM_API_ID(efuse); - if (arg) - cmd->data[i++] = *arg; - - if (!ibufs[0].buf) - return TEE_SUCCESS; - - reg_pair_from_64(virt_to_phys(ibufs[0].buf), &b, &a); - - cmd->data[i++] = a; - cmd->data[i++] = b; - - for (i = 0; i < VERSAL_MAX_IPI_BUF; i++) { - cmd->ibuf[i].mem.alloc_len = ibufs[i].len; - cmd->ibuf[i].mem.buf = ibufs[i].buf; - } - - return TEE_SUCCESS; -} - -static TEE_Result efuse_req(enum versal_nvm_api_id efuse, - struct versal_nvm_buf *ibufs, uint32_t *arg) -{ - struct versal_ipi_cmd cmd = { }; - TEE_Result ret = TEE_SUCCESS; - - ret = prepare_cmd(&cmd, efuse, ibufs, arg); - if (ret) - return ret; - - ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); - if (ret) - EMSG("Mailbox error"); - - return ret; -} - -static TEE_Result versal_alloc_read_buffer(struct versal_nvm_read_req *req) -{ - assert(req); - req->ibuf[0].len = 1024; - req->ibuf[0].buf = alloc_cache_aligned(req->ibuf[0].len); - if (!req->ibuf[0].buf) - return TEE_ERROR_OUT_OF_MEMORY; - - return TEE_SUCCESS; -} - -static void versal_free_read_buffer(struct versal_nvm_read_req *req) -{ - assert(req); - free(req->ibuf[0].buf); -} - -static void *versal_get_read_buffer(struct versal_nvm_read_req *req) -{ - assert(req); - return req->ibuf[0].buf; -} - -#if defined(PLATFORM_FLAVOR_net) -static TEE_Result versal_nvm_read(struct versal_nvm_read_req *req) -{ - if (!req) - return TEE_ERROR_GENERIC; - - switch (req->efuse_id) { - case EFUSE_READ_CACHE: - case BBRAM_READ_USER_DATA: - break; - default: - return TEE_ERROR_GENERIC; - } - - return efuse_req(req->efuse_id, req->ibuf, NULL); -} - -static TEE_Result versal_nvm_write(struct versal_nvm_write_req *req) -{ - uint32_t *arg = NULL; - uint32_t val = 0; - - switch (req->efuse_id) { - case BBRAM_WRITE_AES_KEY: - val = req->bbram.aes_key_len; - arg = &val; - break; - case BBRAM_WRITE_USER_DATA: - val = req->bbram.user_data; - arg = &val; - break; - case BBRAM_ZEROIZE: - break; - default: - return TEE_ERROR_GENERIC; - } - - return efuse_req(req->efuse_id, req->ibuf, arg); -} -#else -static TEE_Result versal_nvm_read(struct versal_nvm_read_req *req) -{ - uint32_t *arg = NULL; - uint32_t val = 0; - - if (!req) - return TEE_ERROR_GENERIC; - - switch (req->efuse_id) { - case EFUSE_READ_DNA: - case EFUSE_READ_DEC_EFUSE_ONLY: - case EFUSE_READ_PUF_SEC_CTRL: - case EFUSE_READ_BOOT_ENV_CTRL: - case EFUSE_READ_SEC_CTRL: - case EFUSE_READ_MISC_CTRL: - case EFUSE_READ_SEC_MISC1: - case EFUSE_READ_USER_FUSES: - case EFUSE_READ_PUF_USER_FUSES: - case EFUSE_READ_PUF: - break; - case EFUSE_READ_OFFCHIP_REVOCATION_ID: - val = req->offchip_id; - arg = &val; - break; - case EFUSE_READ_REVOCATION_ID: - val = req->revocation_id; - arg = &val; - break; - case EFUSE_READ_IV: - val = req->iv_type; - arg = &val; - break; - case EFUSE_READ_PPK_HASH: - val = req->ppk_type; - arg = &val; - break; - case BBRAM_READ_USER_DATA: - break; - default: - return TEE_ERROR_GENERIC; - } - - return efuse_req(req->efuse_id, req->ibuf, arg); -} - -static TEE_Result versal_nvm_write(struct versal_nvm_write_req *req) -{ - uint32_t *arg = NULL; - uint32_t val = 0; - - switch (req->efuse_id) { - case BBRAM_WRITE_AES_KEY: - val = req->bbram.aes_key_len; - arg = &val; - break; - case BBRAM_WRITE_USER_DATA: - val = req->bbram.user_data; - arg = &val; - break; - case BBRAM_ZEROIZE: - case EFUSE_PUF_USER_FUSE_WRITE: - case EFUSE_WRITE_PUF: - case EFUSE_WRITE: - break; - default: - return TEE_ERROR_GENERIC; - } - - return efuse_req(req->efuse_id, req->ibuf, arg); -} -#endif - -TEE_Result versal_bbram_write_aes_key(uint8_t *key, size_t len) -{ - struct versal_nvm_write_req req __aligned_efuse = { - .efuse_id = BBRAM_WRITE_AES_KEY, - .bbram.aes_key_len = len, - }; - void *buf = NULL; - - if (len != 32) - return TEE_ERROR_BAD_PARAMETERS; - - buf = alloc_cache_aligned(1024); - if (!buf) - return TEE_ERROR_OUT_OF_MEMORY; - - memcpy(buf, key, len); - - req.ibuf[0].buf = buf; - req.ibuf[0].len = 1024; - - if (versal_nvm_write(&req)) { - free(buf); - return TEE_ERROR_GENERIC; - } - free(buf); - - return TEE_SUCCESS; -} - -TEE_Result versal_bbram_zeroize(void) -{ - struct versal_nvm_write_req req __aligned_efuse = { - .efuse_id = BBRAM_ZEROIZE, - }; - - if (versal_nvm_write(&req)) - return TEE_ERROR_GENERIC; - - return TEE_SUCCESS; -} - -TEE_Result versal_bbram_write_user_data(uint32_t data) -{ - struct versal_nvm_write_req req __aligned_efuse = { - .efuse_id = BBRAM_WRITE_USER_DATA, - .bbram.user_data = data, - }; - - if (versal_nvm_write(&req)) - return TEE_ERROR_GENERIC; - - return TEE_SUCCESS; -} - -TEE_Result versal_bbram_read_user_data(uint32_t *data) -{ - struct versal_nvm_read_req req = { - .efuse_id = BBRAM_READ_USER_DATA, - }; - - if (versal_alloc_read_buffer(&req)) - return TEE_ERROR_OUT_OF_MEMORY; - - if (versal_nvm_read(&req)) { - versal_free_read_buffer(&req); - return TEE_ERROR_GENERIC; - } - - memcpy(data, versal_get_read_buffer(&req), sizeof(*data)); - versal_free_read_buffer(&req); - - return TEE_SUCCESS; -} - -TEE_Result versal_bbram_lock_write_user_data(void) -{ - struct versal_nvm_write_req req __aligned_efuse = { - .efuse_id = BBRAM_LOCK_WRITE_USER_DATA, - }; - - if (versal_nvm_write(&req)) - return TEE_ERROR_GENERIC; - - return TEE_SUCCESS; -} - -#if defined(PLATFORM_FLAVOR_net) -static TEE_Result versal_efuse_read_cache(uint16_t off, uint16_t num, - uint32_t *buf, size_t len) -{ - struct versal_ipi_cmd cmd = { }; - struct versal_mbox_mem p = { }; - TEE_Result ret = TEE_SUCCESS; - uint32_t a = 0; - uint32_t b = 0; - - if (!buf) - return TEE_ERROR_BAD_PARAMETERS; - - if (len < num * NVM_WORD_LEN) - return TEE_ERROR_BAD_PARAMETERS; - - ret = versal_mbox_alloc(num * NVM_WORD_LEN, NULL, &p); - if (ret) - return ret; - - reg_pair_from_64(virt_to_phys(p.buf), &b, &a); - - cmd.data[0] = NVM_API_ID(EFUSE_READ_CACHE); - cmd.data[1] = (num << 16) | off; - cmd.data[2] = a; - cmd.data[3] = b; - - cmd.ibuf[0].mem = p; - - ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); - if (ret) - EMSG("Mailbox error"); - else - memcpy(buf, p.buf, num * NVM_WORD_LEN); - - versal_mbox_free(&p); - return ret; -} - -#define EFUSE_CACHE_DNA_OFFSET 0x20 -#define EFUSE_CACHE_BOOT_ENV_CTRL_OFFSET 0x94 -#define EFUSE_CACHE_MISC_CTRL_OFFSET 0xA0 -#define EFUSE_CACHE_PUF_ECC_CTRL_OFFSET 0xA4 -#define EFUSE_CACHE_PUF_CHASH_OFFSET 0xA8 -#define EFUSE_CACHE_SEC_CTRL_OFFSET 0xAC -#define EFUSE_CACHE_REVOCATION_ID0_OFFSET 0xB0 -#define EFUSE_CACHE_SEC_MISC0_OFFSET 0xE4 -#define EFUSE_CACHE_SEC_MISC1_OFFSET 0xE8 -#define EFUSE_CACHE_PPK0_OFFSET 0x100 -#define EFUSE_CACHE_PPK1_OFFSET 0x120 -#define EFUSE_CACHE_PPK2_OFFSET 0x140 -#define EFUSE_CACHE_OFFCHIP_REVOKE_ID0_OFFSET 0x160 -#define EFUSE_CACHE_METAHEADER_IV_RANGE0_OFFSET 0x180 -#define EFUSE_CACHE_BLACK_IV0_OFFSET 0x1D0 -#define EFUSE_CACHE_PLM_IV_RANGE0_OFFSET 0x1DC -#define EFUSE_CACHE_DATA_PARTITION_IV_RANGE0_OFFSET 0x1E8 -#define EFUSE_CACHE_USER0_OFFSET 0x240 -#define EFUSE_CACHE_PUF_SYN0_OFFSET 0x300 - -TEE_Result versal_efuse_read_dna(uint32_t *buf, size_t len) -{ - if (len < EFUSE_DNA_LEN) - return TEE_ERROR_BAD_PARAMETERS; - - return versal_efuse_read_cache(EFUSE_CACHE_DNA_OFFSET, - EFUSE_DNA_LEN / NVM_WORD_LEN, buf, len); -} - -TEE_Result versal_efuse_read_user_data(uint32_t *buf, size_t len, - uint32_t first, size_t num) -{ - uint16_t offset; - - if (first + num > EFUSE_MAX_USER_FUSES || len < num * NVM_WORD_LEN) - return TEE_ERROR_BAD_PARAMETERS; - - offset = EFUSE_CACHE_USER0_OFFSET + first * NVM_WORD_LEN; - - return versal_efuse_read_cache(offset, num, buf, len); -} - -TEE_Result versal_efuse_read_iv(uint32_t *buf, size_t len, - enum versal_nvm_iv_type type) -{ - uint16_t offset; - - switch (type) { - case EFUSE_META_HEADER_IV_RANGE: - offset = EFUSE_CACHE_METAHEADER_IV_RANGE0_OFFSET; - break; - case EFUSE_BLACK_IV: - offset = EFUSE_CACHE_BLACK_IV0_OFFSET; - break; - case EFUSE_PLM_IV_RANGE: - offset = EFUSE_CACHE_PLM_IV_RANGE0_OFFSET; - break; - case EFUSE_DATA_PARTITION_IV_RANGE: - offset = EFUSE_CACHE_DATA_PARTITION_IV_RANGE0_OFFSET; - break; - default: - return TEE_ERROR_BAD_PARAMETERS; - } - - return versal_efuse_read_cache(offset, EFUSE_IV_LEN / NVM_WORD_LEN, - buf, len); -} - -TEE_Result versal_efuse_read_ppk(uint32_t *buf, size_t len, - enum versal_nvm_ppk_type type) -{ - uint16_t offset; - - switch (type) { - case EFUSE_PPK0: - offset = EFUSE_CACHE_PPK0_OFFSET; - break; - case EFUSE_PPK1: - offset = EFUSE_CACHE_PPK1_OFFSET; - break; - case EFUSE_PPK2: - offset = EFUSE_CACHE_PPK2_OFFSET; - break; - default: - return TEE_ERROR_BAD_PARAMETERS; - } - - return versal_efuse_read_cache(offset, EFUSE_PPK_LEN / NVM_WORD_LEN, - buf, len); -} - -TEE_Result versal_efuse_read_revoke_id(uint32_t *buf, size_t len, - enum versal_nvm_revocation_id id) -{ - return versal_efuse_read_cache(EFUSE_CACHE_REVOCATION_ID0_OFFSET + - id * NVM_WORD_LEN, - EFUSE_REVOCATION_ID_LEN / NVM_WORD_LEN, - buf, len); -} - -TEE_Result versal_efuse_read_misc_ctrl(struct versal_efuse_misc_ctrl_bits *buf) -{ - TEE_Result ret = TEE_SUCCESS; - uint32_t misc_ctrl = 0; - - if (!buf) - return TEE_ERROR_BAD_PARAMETERS; - - ret = versal_efuse_read_cache(EFUSE_CACHE_MISC_CTRL_OFFSET, 1, - &misc_ctrl, sizeof(uint32_t)); - if (ret) - return ret; - - buf->glitch_det_halt_boot_en = ((misc_ctrl & GENMASK_32(31, 30)) >> 30); - buf->glitch_det_rom_monitor_en = ((misc_ctrl & BIT(29)) >> 29); - buf->halt_boot_error = ((misc_ctrl & GENMASK_32(22, 21)) >> 21); - buf->halt_boot_env = ((misc_ctrl & GENMASK_32(20, 19)) >> 19); - buf->crypto_kat_en = ((misc_ctrl & BIT(15)) >> 15); - buf->lbist_en = ((misc_ctrl & BIT(14)) >> 14); - buf->safety_mission_en = ((misc_ctrl & BIT(8)) >> 8); - buf->ppk0_invalid = ((misc_ctrl & GENMASK_32(7, 6)) >> 6); - buf->ppk1_invalid = ((misc_ctrl & GENMASK_32(5, 4)) >> 4); - buf->ppk2_invalid = ((misc_ctrl & GENMASK_32(3, 2)) >> 2); - - return ret; -} - -TEE_Result versal_efuse_read_sec_ctrl(struct versal_efuse_sec_ctrl_bits *buf) -{ - TEE_Result ret = TEE_SUCCESS; - uint32_t sec_ctrl = 0; - - if (!buf) - return TEE_ERROR_BAD_PARAMETERS; - - ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_CTRL_OFFSET, 1, - &sec_ctrl, sizeof(uint32_t)); - if (ret) - return ret; - - buf->aes_dis = (sec_ctrl & BIT(0)); - buf->jtag_err_out_dis = ((sec_ctrl & BIT(1)) >> 1); - buf->jtag_dis = ((sec_ctrl & BIT(2)) >> 2); - buf->ppk0_wr_lk = ((sec_ctrl & BIT(6)) >> 6); - buf->ppk1_wr_lk = ((sec_ctrl & BIT(7)) >> 7); - buf->ppk2_wr_lk = ((sec_ctrl & BIT(8)) >> 8); - buf->aes_crc_lk = ((sec_ctrl & GENMASK_32(10, 9)) >> 9); - buf->aes_wr_lk = ((sec_ctrl & BIT(11)) >> 11); - buf->user_key0_crc_lk = ((sec_ctrl & BIT(12)) >> 12); - buf->user_key0_wr_lk = ((sec_ctrl & BIT(13)) >> 13); - buf->user_key1_crc_lk = ((sec_ctrl & BIT(14)) >> 14); - buf->user_key1_wr_lk = ((sec_ctrl & BIT(15)) >> 15); - buf->sec_dbg_dis = ((sec_ctrl & GENMASK_32(20, 19)) >> 19); - buf->sec_lock_dbg_dis = ((sec_ctrl & GENMASK_32(22, 21)) >> 21); - buf->boot_env_wr_lk = ((sec_ctrl & BIT(28)) >> 28); - buf->reg_init_dis = ((sec_ctrl & GENMASK_32(31, 30)) >> 30); - - return ret; -} - -TEE_Result versal_efuse_read_sec_misc1(struct versal_efuse_sec_misc1_bits *buf) -{ - TEE_Result ret = TEE_SUCCESS; - uint32_t sec_misc1 = 0; - - if (!buf) - return TEE_ERROR_BAD_PARAMETERS; - - ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_MISC1_OFFSET, 1, - &sec_misc1, sizeof(uint32_t)); - if (ret) - return ret; - - buf->lpd_mbist_en = ((sec_misc1 & GENMASK_32(12, 10)) >> 10); - buf->pmc_mbist_en = ((sec_misc1 & GENMASK_32(9, 7)) >> 7); - buf->lpd_noc_sc_en = ((sec_misc1 & GENMASK_32(6, 4)) >> 4); - buf->sysmon_volt_mon_en = ((sec_misc1 & GENMASK_32(3, 2)) >> 2); - buf->sysmon_temp_mon_en = (sec_misc1 & GENMASK_32(1, 0)); - - return ret; -} - -TEE_Result -versal_efuse_read_boot_env_ctrl(struct versal_efuse_boot_env_ctrl_bits *buf) -{ - TEE_Result ret = TEE_SUCCESS; - uint32_t boot_env_ctrl = 0; - - if (!buf) - return TEE_ERROR_BAD_PARAMETERS; - - ret = versal_efuse_read_cache(EFUSE_CACHE_BOOT_ENV_CTRL_OFFSET, 1, - &boot_env_ctrl, sizeof(uint32_t)); - if (ret) - return ret; - - buf->sysmon_temp_en = ((boot_env_ctrl & BIT(21)) >> 21); - buf->sysmon_volt_en = ((boot_env_ctrl & BIT(20)) >> 20); - buf->sysmon_temp_hot = ((boot_env_ctrl & GENMASK_32(18, 17)) >> 17); - buf->sysmon_volt_pmc = ((boot_env_ctrl & GENMASK_32(13, 12)) >> 12); - buf->sysmon_volt_pslp = ((boot_env_ctrl & GENMASK_32(11, 10)) >> 10); - buf->sysmon_volt_soc = ((boot_env_ctrl & GENMASK_32(9, 8)) >> 8); - buf->sysmon_temp_cold = (boot_env_ctrl & GENMASK_32(1, 0)); - - return ret; -} - -TEE_Result versal_efuse_read_offchip_revoke_id(uint32_t *buf, size_t len, - enum versal_nvm_offchip_id id) -{ - if (id == EFUSE_INVLD) - return TEE_ERROR_BAD_PARAMETERS; - - return versal_efuse_read_cache(EFUSE_CACHE_OFFCHIP_REVOKE_ID0_OFFSET + - id * NVM_WORD_LEN, - EFUSE_REVOCATION_ID_LEN / NVM_WORD_LEN, - buf, len); -} - -TEE_Result versal_efuse_read_dec_only(uint32_t *buf, size_t len) -{ - TEE_Result ret = TEE_SUCCESS; - uint32_t sec_misc0 = 0; - - if (len < EFUSE_DEC_ONLY_LEN) - return TEE_ERROR_BAD_PARAMETERS; - - ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_MISC0_OFFSET, 1, - &sec_misc0, sizeof(uint32_t)); - if (ret) - return ret; - - sec_misc0 &= GENMASK_32(15, 0); - - memcpy(buf, &sec_misc0, EFUSE_DEC_ONLY_LEN); - - return ret; -} - -TEE_Result versal_efuse_read_puf_sec_ctrl(struct versal_efuse_puf_sec_ctrl_bits - *buf) -{ - TEE_Result ret = TEE_SUCCESS; - uint32_t puf_ctrl = 0; - uint32_t sec_ctrl = 0; - - if (!buf) - return TEE_ERROR_BAD_PARAMETERS; - - ret = versal_efuse_read_cache(EFUSE_CACHE_PUF_ECC_CTRL_OFFSET, 1, - &puf_ctrl, sizeof(uint32_t)); - if (ret) - return ret; - - /* - * Some fuses have moved from PUF_ECC_CTRL to SECURITY_CTRL - */ - ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_CTRL_OFFSET, 1, - &sec_ctrl, sizeof(uint32_t)); - if (ret) - return ret; - - buf->puf_regen_dis = ((puf_ctrl & BIT(31)) >> 31); - buf->puf_hd_invalid = ((puf_ctrl & BIT(30)) >> 30); - buf->puf_test2_dis = ((puf_ctrl & BIT(29)) >> 29); - buf->puf_dis = ((sec_ctrl & BIT(18)) >> 18); - buf->puf_syn_lk = ((sec_ctrl & BIT(16)) >> 16); - - return ret; -} - -TEE_Result versal_efuse_read_puf(struct versal_efuse_puf_header *buf) -{ - TEE_Result ret = TEE_SUCCESS; - - if (!buf) - return TEE_ERROR_BAD_PARAMETERS; - - ret = versal_efuse_read_puf_sec_ctrl(&buf->sec_ctrl); - if (ret) - return ret; - - ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_CTRL_OFFSET, 1, - &buf->aux, sizeof(uint32_t)); - if (ret) - return ret; - - buf->aux &= GENMASK_32(23, 0); - - ret = versal_efuse_read_cache(EFUSE_CACHE_PUF_CHASH_OFFSET, 1, - &buf->chash, sizeof(uint32_t)); - if (ret) - return ret; - - ret = versal_efuse_read_cache(EFUSE_CACHE_PUF_SYN0_OFFSET, - PUF_SYN_DATA_WORDS, buf->efuse_syn_data, - PUF_SYN_DATA_WORDS * NVM_WORD_LEN); - return ret; -} - -TEE_Result -versal_efuse_read_puf_as_user_fuse(struct versal_efuse_puf_user_fuse - *p __unused) -{ - return TEE_ERROR_NOT_IMPLEMENTED; -} - -TEE_Result versal_efuse_write_user_data(uint32_t *buf __unused, - size_t len __unused, - uint32_t first __unused, - size_t num __unused) -{ - return TEE_ERROR_NOT_IMPLEMENTED; -} - -#define EFUSE_ENV_DIS_FLAG 0 - -#define EFUSE_AES_KEY_ID 0 -#define EFUSE_USER_KEY0_ID 1 -#define EFUSE_USER_KEY1_ID 2 - -static TEE_Result do_write_efuses_buffer(enum versal_nvm_api_id id, - uint16_t type, uint32_t *buf, - size_t len) -{ - struct versal_ipi_cmd cmd = { }; - struct versal_mbox_mem p = { }; - TEE_Result ret = TEE_SUCCESS; - uint32_t a = 0; - uint32_t b = 0; - - ret = versal_mbox_alloc(len, buf, &p); - if (ret) - return ret; - - reg_pair_from_64(virt_to_phys(p.buf), &b, &a); - - cmd.data[0] = NVM_API_ID(id); - cmd.data[1] = (type << 16) | EFUSE_ENV_DIS_FLAG; - cmd.data[2] = a; - cmd.data[3] = b; - - cmd.ibuf[0].mem = p; - - ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); - - versal_mbox_free(&p); - return ret; -} - -static TEE_Result do_write_efuses_value(enum versal_nvm_api_id id, uint32_t val) -{ - struct versal_ipi_cmd cmd = { }; - TEE_Result ret = TEE_SUCCESS; - - cmd.data[0] = NVM_API_ID(id); - cmd.data[1] = EFUSE_ENV_DIS_FLAG; - cmd.data[2] = val; - - ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); - - return ret; -} - -static TEE_Result do_write_efuses(enum versal_nvm_api_id id) -{ - return do_write_efuses_value(id, 0); -} - -TEE_Result versal_efuse_write_aes_keys(struct versal_efuse_aes_keys *keys) -{ - TEE_Result ret = TEE_SUCCESS; - TEE_Result res; - - if (!keys) - return TEE_ERROR_BAD_PARAMETERS; - - if (keys->prgm_aes_key) { - res = do_write_efuses_buffer(EFUSE_WRITE_AES_KEY, - EFUSE_AES_KEY_ID, - keys->aes_key, EFUSE_AES_KEY_LEN); - if (res) { - DMSG("Error programming AES key (0x%" PRIx32 ")", res); - ret = TEE_ERROR_GENERIC; - } - } - - if (keys->prgm_user_key0) { - res = do_write_efuses_buffer(EFUSE_WRITE_AES_KEY, - EFUSE_USER_KEY0_ID, - keys->user_key0, - EFUSE_AES_KEY_LEN); - if (res) { - DMSG("Error programming User key 0 (0x%" PRIx32 ")", - res); - ret = TEE_ERROR_GENERIC; - } - } - - if (keys->prgm_user_key1) { - res = do_write_efuses_buffer(EFUSE_WRITE_AES_KEY, - EFUSE_USER_KEY1_ID, - keys->user_key1, - EFUSE_AES_KEY_LEN); - if (res) { - DMSG("Error programming User key 1 (0x%" PRIx32 ")", - res); - ret = TEE_ERROR_GENERIC; - } - } - - return ret; -} - -TEE_Result versal_efuse_write_ppk_hash(struct versal_efuse_ppk_hash *hash) -{ - TEE_Result ret = TEE_SUCCESS; - TEE_Result res; - - if (!hash) - return TEE_ERROR_BAD_PARAMETERS; - - if (hash->prgm_ppk0_hash) { - res = do_write_efuses_buffer(EFUSE_WRITE_PPK_HASH, EFUSE_PPK0, - hash->ppk0_hash, EFUSE_PPK_LEN); - if (res) { - DMSG("Error programming PPK hash 0 (0x%" PRIx32 ")", - res); - ret = TEE_ERROR_GENERIC; - } - } - - if (hash->prgm_ppk1_hash) { - res = do_write_efuses_buffer(EFUSE_WRITE_PPK_HASH, EFUSE_PPK1, - hash->ppk1_hash, EFUSE_PPK_LEN); - if (res) { - DMSG("Error programming PPK hash 1 (0x%" PRIx32 ")", - res); - ret = TEE_ERROR_GENERIC; - } - } - - if (hash->prgm_ppk2_hash) { - res = do_write_efuses_buffer(EFUSE_WRITE_PPK_HASH, EFUSE_PPK2, - hash->ppk2_hash, EFUSE_PPK_LEN); - if (res) { - DMSG("Error programming PPK hash 2 (0x%" PRIx32 ")", - res); - ret = TEE_ERROR_GENERIC; - } - } - - return ret; -} - -TEE_Result versal_efuse_write_iv(struct versal_efuse_ivs *p) +static TEE_Result +prepare_cmd(struct versal_ipi_cmd *cmd, enum versal_nvm_api_id efuse, + struct versal_nvm_buf *ibufs, uint32_t *arg) { - TEE_Result ret = TEE_SUCCESS; - TEE_Result res; + uint32_t a = 0; + uint32_t b = 0; + size_t i = 0; - if (!p) - return TEE_ERROR_BAD_PARAMETERS; + cmd->data[i++] = NVM_API_ID(efuse); + if (arg) + cmd->data[i++] = *arg; - if (p->prgm_meta_header_iv) { - res = do_write_efuses_buffer(EFUSE_WRITE_IV, - EFUSE_META_HEADER_IV_RANGE, - p->meta_header_iv, EFUSE_IV_LEN); - if (res) { - DMSG("Error programming meta header IV (0x%" PRIx32 ")", - res); - ret = TEE_ERROR_GENERIC; - } - } + if (!ibufs[0].buf) + return TEE_SUCCESS; - if (p->prgm_blk_obfus_iv) { - res = do_write_efuses_buffer(EFUSE_WRITE_IV, EFUSE_BLACK_IV, - p->blk_obfus_iv, EFUSE_IV_LEN); - if (res) { - DMSG("Error programming black IV (0x%" PRIx32 ")", res); - ret = TEE_ERROR_GENERIC; - } - } + reg_pair_from_64(virt_to_phys(ibufs[0].buf), &b, &a); - if (p->prgm_plm_iv) { - res = do_write_efuses_buffer(EFUSE_WRITE_IV, EFUSE_PLM_IV_RANGE, - p->plm_iv, EFUSE_IV_LEN); - if (res) { - DMSG("Error programming plm IV (0x%" PRIx32 ")", res); - ret = TEE_ERROR_GENERIC; - } - } + cmd->data[i++] = a; + cmd->data[i++] = b; - if (p->prgm_data_partition_iv) { - res = do_write_efuses_buffer(EFUSE_WRITE_IV, - EFUSE_DATA_PARTITION_IV_RANGE, - p->data_partition_iv, - EFUSE_IV_LEN); - if (res) { - DMSG("Error programming data IV (0x%" PRIx32 ")", res); - ret = TEE_ERROR_GENERIC; - } + for (i = 0; i < VERSAL_MAX_IPI_BUF; i++) { + cmd->ibuf[i].mem.alloc_len = ibufs[i].len; + cmd->ibuf[i].mem.buf = ibufs[i].buf; } - return ret; + return TEE_SUCCESS; } -TEE_Result versal_efuse_write_dec_only(struct versal_efuse_dec_only *p) +static TEE_Result efuse_req(enum versal_nvm_api_id efuse, + struct versal_nvm_buf *ibufs, uint32_t *arg) { - if (!p) - return TEE_ERROR_BAD_PARAMETERS; - - if (!p->prgm_dec_only) - return TEE_SUCCESS; - - return do_write_efuses(EFUSE_WRITE_DEC_ONLY); -} + struct versal_ipi_cmd cmd = { }; + TEE_Result ret = TEE_SUCCESS; -TEE_Result versal_efuse_write_sec(struct versal_efuse_sec_ctrl_bits *p) -{ - uint32_t val = 0; + ret = prepare_cmd(&cmd, efuse, ibufs, arg); + if (ret) + return ret; - if (!p) - return TEE_ERROR_BAD_PARAMETERS; + ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); + if (ret) + EMSG("Mailbox error"); - val = ((p->reg_init_dis & 0x3) << 30) | - ((p->boot_env_wr_lk & 0x1) << 28) | - ((p->sec_lock_dbg_dis & 0x3) << 21) | - ((p->sec_dbg_dis & 0x3) << 19) | - ((p->user_key1_wr_lk & 0x1) << 15) | - ((p->user_key1_crc_lk & 0x1) << 14) | - ((p->user_key0_wr_lk & 0x1) << 13) | - ((p->user_key0_crc_lk & 0x1) << 12) | - ((p->aes_wr_lk & 0x1) << 11) | - ((p->aes_crc_lk & 0x3) << 9) | - ((p->ppk2_wr_lk & 0x1) << 8) | - ((p->ppk1_wr_lk & 0x1) << 7) | - ((p->ppk0_wr_lk & 0x1) << 6) | - ((p->jtag_dis & 0x1) << 2) | - ((p->jtag_err_out_dis & 0x1) << 1) | - (p->aes_dis & 0x1); - - return do_write_efuses_value(EFUSE_WRITE_SEC_CTRL_BITS, val); + return ret; } -TEE_Result versal_efuse_write_misc(struct versal_efuse_misc_ctrl_bits *p) +static TEE_Result versal_alloc_read_buffer(struct versal_nvm_read_req *req) { - uint32_t val = 0; - - if (!p) - return TEE_ERROR_BAD_PARAMETERS; + assert(req); + req->ibuf[0].len = 1024; + req->ibuf[0].buf = alloc_cache_aligned(req->ibuf[0].len); + if (!req->ibuf[0].buf) + return TEE_ERROR_OUT_OF_MEMORY; - val = ((p->glitch_det_halt_boot_en & 0x3) << 30) | - ((p->glitch_det_rom_monitor_en & 0x1) << 29) | - ((p->halt_boot_error & 0x3) << 21) | - ((p->halt_boot_env & 0x3) << 19) | - ((p->crypto_kat_en & 0x1) << 15) | - ((p->lbist_en & 0x1) << 14) | - ((p->safety_mission_en & 0x1) << 8) | - ((p->ppk2_invalid & 0x3) << 6) | - ((p->ppk1_invalid & 0x3) << 4) | - ((p->ppk0_invalid & 0x3) << 2); - - return do_write_efuses_value(EFUSE_WRITE_MISC_CTRL_BITS, val); + return TEE_SUCCESS; } -TEE_Result -versal_efuse_write_glitch_cfg(struct versal_efuse_glitch_cfg_bits *p) +static void versal_free_read_buffer(struct versal_nvm_read_req *req) { - uint32_t val = 0; - - if (!p) - return TEE_ERROR_BAD_PARAMETERS; - - if (!p->prgm_glitch) - return TEE_SUCCESS; - - val = ((p->glitch_det_wr_lk & 0x1) << 31) | p->glitch_det_trim; - - return do_write_efuses_value(EFUSE_WRITE_GLITCH_CONFIG, val); + assert(req); + free(req->ibuf[0].buf); } -TEE_Result -versal_efuse_write_boot_env(struct versal_efuse_boot_env_ctrl_bits *p) +static void *versal_get_read_buffer(struct versal_nvm_read_req *req) { - uint32_t val = 0; - - if (!p) - return TEE_ERROR_BAD_PARAMETERS; - - val = ((p->sysmon_temp_en & 0x1) << 21) | - ((p->sysmon_volt_en & 0x1) << 20) | - ((p->sysmon_temp_hot & 0x3) << 17) | - ((p->sysmon_volt_pmc & 0x3) << 12) | - ((p->sysmon_volt_pslp & 0x3) << 10) | - ((p->sysmon_volt_soc & 0x3) << 8) | - (p->sysmon_temp_cold & 0x2); - - return do_write_efuses_value(EFUSE_WRITE_BOOT_ENV_CTRL_BITS, val); + assert(req); + return req->ibuf[0].buf; } -TEE_Result versal_efuse_write_sec_misc1(struct versal_efuse_sec_misc1_bits *p) +static TEE_Result versal_nvm_read(struct versal_nvm_read_req *req) { + uint32_t *arg = NULL; uint32_t val = 0; - if (!p) - return TEE_ERROR_BAD_PARAMETERS; - - val = ((p->lpd_mbist_en & 0x7) << 10) | - ((p->pmc_mbist_en & 0x7) << 7) | - ((p->lpd_noc_sc_en & 0x7) << 4) | - ((p->sysmon_volt_mon_en & 0x3) << 2) | - (p->sysmon_temp_mon_en & 0x3); + if (!req) + return TEE_ERROR_GENERIC; - return do_write_efuses_value(EFUSE_WRITE_MISC1_CTRL_BITS, val); -} + switch (req->efuse_id) { + case EFUSE_READ_DNA: + case EFUSE_READ_DEC_EFUSE_ONLY: + case EFUSE_READ_PUF_SEC_CTRL: + case EFUSE_READ_BOOT_ENV_CTRL: + case EFUSE_READ_SEC_CTRL: + case EFUSE_READ_MISC_CTRL: + case EFUSE_READ_SEC_MISC1: + case EFUSE_READ_USER_FUSES: + case EFUSE_READ_PUF_USER_FUSES: + case EFUSE_READ_PUF: + break; + case EFUSE_READ_OFFCHIP_REVOCATION_ID: + val = req->offchip_id; + arg = &val; + break; + case EFUSE_READ_REVOCATION_ID: + val = req->revocation_id; + arg = &val; + break; + case EFUSE_READ_IV: + val = req->iv_type; + arg = &val; + break; + case EFUSE_READ_PPK_HASH: + val = req->ppk_type; + arg = &val; + break; + case BBRAM_READ_USER_DATA: + break; + default: + return TEE_ERROR_GENERIC; + } -TEE_Result versal_efuse_write_offchip_ids(uint32_t id) -{ - return do_write_efuses_value(EFUSE_WRITE_OFFCHIP_REVOKE_ID, id); + return efuse_req(req->efuse_id, req->ibuf, arg); } -TEE_Result versal_efuse_write_revoke_ppk(enum versal_nvm_ppk_type type) +static TEE_Result versal_nvm_write(struct versal_nvm_write_req *req) { - struct versal_efuse_misc_ctrl_bits misc_ctrl; - - memset(&misc_ctrl, 0, sizeof(struct versal_efuse_misc_ctrl_bits)); + uint32_t *arg = NULL; + uint32_t val = 0; - switch (type) { - case EFUSE_PPK0: - misc_ctrl.ppk0_invalid = 0x3; + switch (req->efuse_id) { + case BBRAM_WRITE_AES_KEY: + val = req->bbram.aes_key_len; + arg = &val; break; - case EFUSE_PPK1: - misc_ctrl.ppk1_invalid = 0x3; + case BBRAM_WRITE_USER_DATA: + val = req->bbram.user_data; + arg = &val; break; - case EFUSE_PPK2: - misc_ctrl.ppk2_invalid = 0x3; + case EFUSE_PUF_USER_FUSE_WRITE: + case EFUSE_WRITE_PUF: + case EFUSE_WRITE: break; default: - return TEE_ERROR_BAD_PARAMETERS; + return TEE_ERROR_GENERIC; } - return versal_efuse_write_misc(&misc_ctrl); -} - -TEE_Result versal_efuse_write_revoke_id(uint32_t id) -{ - return do_write_efuses_value(EFUSE_WRITE_REVOCATION_ID, id); -} - -TEE_Result versal_efuse_write_puf_as_user_fuse(struct versal_efuse_puf_user_fuse - *p __unused) -{ - return TEE_ERROR_NOT_IMPLEMENTED; + return efuse_req(req->efuse_id, req->ibuf, arg); } -#define EFUSE_WRITE_PUF_DATA_WORDS (PUF_SYN_DATA_WORDS + 6) - -struct versal_efuse_write_puf_data { - uint32_t sec_ctrl; - uint32_t prgm_puf_helper_data; - uint32_t env_monitor_dis; - uint32_t syn[PUF_SYN_DATA_WORDS]; - uint32_t chash; - uint32_t aux; - uint32_t ro_swap; -}; - -TEE_Result versal_efuse_write_puf(struct versal_efuse_puf_header *buf) -{ - struct versal_ipi_cmd cmd = { }; - struct versal_mbox_mem p = { }; - TEE_Result ret = TEE_SUCCESS; - uint32_t a = 0; - uint32_t b = 0; - struct versal_efuse_write_puf_data *data; - - if (!buf) - return TEE_ERROR_BAD_PARAMETERS; - - ret = versal_mbox_alloc(EFUSE_WRITE_PUF_DATA_WORDS * NVM_WORD_LEN, - NULL, &p); - if (ret) - return ret; - - data = p.buf; - - data->sec_ctrl = 0; - data->prgm_puf_helper_data = buf->prmg_puf_helper_data; - data->env_monitor_dis = buf->env_monitor_dis; - memcpy(data->syn, buf->efuse_syn_data, - PUF_SYN_DATA_WORDS * NVM_WORD_LEN); - data->chash = buf->chash; - data->aux = buf->aux; - data->ro_swap = 0; - - reg_pair_from_64(virt_to_phys(p.buf), &b, &a); - - cmd.data[0] = NVM_API_ID(EFUSE_WRITE_PUF); - cmd.data[2] = a; - cmd.data[3] = b; - - cmd.ibuf[0].mem = p; - - ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); - - versal_mbox_free(&p); - return ret; -} -#else TEE_Result versal_efuse_read_user_data(uint32_t *buf, size_t len, uint32_t first, size_t num) { @@ -1835,4 +917,89 @@ TEE_Result versal_efuse_write_puf(struct versal_efuse_puf_header *buf) return TEE_SUCCESS; } -#endif + +TEE_Result versal_bbram_write_aes_key(uint8_t *key, size_t len) +{ + struct versal_nvm_write_req req __aligned_efuse = { + .efuse_id = BBRAM_WRITE_AES_KEY, + .bbram.aes_key_len = len, + }; + void *buf = NULL; + + if (len != 32) + return TEE_ERROR_BAD_PARAMETERS; + + buf = alloc_cache_aligned(1024); + if (!buf) + return TEE_ERROR_OUT_OF_MEMORY; + + memcpy(buf, key, len); + + req.ibuf[0].buf = buf; + req.ibuf[0].len = 1024; + + if (versal_nvm_write(&req)) { + free(buf); + return TEE_ERROR_GENERIC; + } + free(buf); + + return TEE_SUCCESS; +} + +TEE_Result versal_bbram_zeroize(void) +{ + struct versal_nvm_write_req req __aligned_efuse = { + .efuse_id = BBRAM_ZEROIZE, + }; + + if (versal_nvm_write(&req)) + return TEE_ERROR_GENERIC; + + return TEE_SUCCESS; +} + +TEE_Result versal_bbram_write_user_data(uint32_t data) +{ + struct versal_nvm_write_req req __aligned_efuse = { + .efuse_id = BBRAM_WRITE_USER_DATA, + .bbram.user_data = data, + }; + + if (versal_nvm_write(&req)) + return TEE_ERROR_GENERIC; + + return TEE_SUCCESS; +} + +TEE_Result versal_bbram_read_user_data(uint32_t *data) +{ + struct versal_nvm_read_req req = { + .efuse_id = BBRAM_READ_USER_DATA, + }; + + if (versal_alloc_read_buffer(&req)) + return TEE_ERROR_OUT_OF_MEMORY; + + if (versal_nvm_read(&req)) { + versal_free_read_buffer(&req); + return TEE_ERROR_GENERIC; + } + + memcpy(data, versal_get_read_buffer(&req), sizeof(*data)); + versal_free_read_buffer(&req); + + return TEE_SUCCESS; +} + +TEE_Result versal_bbram_lock_write_user_data(void) +{ + struct versal_nvm_write_req req __aligned_efuse = { + .efuse_id = BBRAM_LOCK_WRITE_USER_DATA, + }; + + if (versal_nvm_write(&req)) + return TEE_ERROR_GENERIC; + + return TEE_SUCCESS; +} From 9dd3ef951999e566685ec69ec13e49298322be7d Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Tue, 2 Apr 2024 17:06:05 +0200 Subject: [PATCH 11/43] fixup! plat-versal: add support for Versal Net variant - Do not enable RPMB configs on Versal - Do not modify Versal IPI ID - Do not enable FPGA PTA on Versal Signed-off-by: Jeremie Corbier --- core/arch/arm/plat-versal/conf.mk | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/core/arch/arm/plat-versal/conf.mk b/core/arch/arm/plat-versal/conf.mk index f8f572886ea..f94f27c7e44 100644 --- a/core/arch/arm/plat-versal/conf.mk +++ b/core/arch/arm/plat-versal/conf.mk @@ -27,14 +27,12 @@ CFG_CORE_DYN_SHM ?= y CFG_WITH_STATS ?= y CFG_ARM64_core ?= y -# Default Versal NET memory allocation +# Default memory allocation ifeq ($(PLATFORM_FLAVOR),net) CFG_TZDRAM_START ?= 0x22200000 CFG_TZDRAM_SIZE ?= 0x2700000 CFG_SHMEM_START ?= 0x24900000 CFG_SHMEM_SIZE ?= 0x1800000 - -# Default Versal memory allocation else CFG_TZDRAM_START ?= 0x60000000 CFG_TZDRAM_SIZE ?= 0x10000000 @@ -48,9 +46,11 @@ else $(call force,CFG_ARM32_core,y) endif +ifeq ($(PLATFORM_FLAVOR),net) CFG_RPMB_FS ?= n CFG_RPMB_TESTKEY ?= y CFG_RPMB_WRITE_KEY ?=y +endif # GPIO CFG_VERSAL_GPIO ?= y @@ -62,7 +62,11 @@ CFG_VERSAL_TRACE_PLM ?= n $(call force, CFG_VERSAL_MBOX,y) # MBOX configuration +ifeq ($(PLATFORM_FLAVOR),net) CFG_VERSAL_MBOX_IPI_ID ?= 1 +else +CFG_VERSAL_MBOX_IPI_ID ?= 3 +endif # PM driver CFG_VERSAL_PM ?= y @@ -100,7 +104,7 @@ ifeq ($(CFG_VERSAL_PKI_DRIVER),y) CFG_VERSAL_PKI_COUNTER_MEASURES ?= n CFG_VERSAL_PKI_PWCT ?= y endif -endif +endif # PLATFORM_FLAVOR is net endif # SHA3-384 crypto engine @@ -122,6 +126,8 @@ ifneq ($(CFG_VERSAL_HUK_KEY),$(filter 6 7 11 12,$(firstword $(CFG_VERSAL_HUK_KEY $(error Invalid value: CFG_VERSAL_HUK_KEY=$(CFG_VERSAL_HUK_KEY)) endif +ifeq ($(PLATFORM_FLAVOR),net) CFG_VERSAL_FPGA_LOADER_PTA ?= y +endif CFG_CORE_HEAP_SIZE ?= 262144 From 1dd1efa95c190ec521e94efcf3801dcdbdd5e34b Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Tue, 2 Apr 2024 17:12:42 +0200 Subject: [PATCH 12/43] fixup! core: pta: add Versal FPGA PTA - s!invokeCommandEntryPoint!invoke_command! - Return TEE_ERROR_NOT_SUPPORTED rather than BAD_PARAMS in case an invalid command ID is used - Re-order includes as requested Signed-off-by: Jeremie Corbier --- core/pta/versal/fpga_pta.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/core/pta/versal/fpga_pta.c b/core/pta/versal/fpga_pta.c index 2bf941be85c..3fe6c92dd0d 100644 --- a/core/pta/versal/fpga_pta.c +++ b/core/pta/versal/fpga_pta.c @@ -2,13 +2,13 @@ /* * Copyright 2023 ProvenRun SAS */ -#include #include +#include #include -#include -#include #include +#include #include +#include #define FPGA_PTA_NAME "fpga.pta" @@ -37,19 +37,19 @@ static TEE_Result pta_versal_fpga_write(uint32_t param_types, return versal_write_fpga(virt_to_phys(buf)); } -static TEE_Result invokeCommandEntryPoint(void *sess_ctx __unused, - uint32_t cmd_id, - uint32_t param_types, - TEE_Param params[TEE_NUM_PARAMS]) +static TEE_Result invoke_command(void *sess_ctx __unused, + uint32_t cmd_id, + uint32_t param_types, + TEE_Param params[TEE_NUM_PARAMS]) { switch (cmd_id) { case PTA_VERSAL_FPGA_WRITE: return pta_versal_fpga_write(param_types, params); default: - return TEE_ERROR_BAD_PARAMETERS; + return TEE_ERROR_NOT_SUPPORTED; } } pseudo_ta_register(.uuid = PTA_VERSAL_FPGA_UUID, .name = FPGA_PTA_NAME, .flags = PTA_DEFAULT_FLAGS, - .invoke_command_entry_point = invokeCommandEntryPoint); + .invoke_command_entry_point = invoke_command); From 6d01a341403ac150ba780df976a9c4903c3f435a Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Tue, 2 Apr 2024 18:20:44 +0200 Subject: [PATCH 13/43] fixup! drivers: versal: rework mbox driver - Add timeout in case the remote processor is unresponsive - versal_mbox_free explicitely sets the pointer to NULL Signed-off-by: Jeremie Corbier --- core/arch/arm/plat-versal/conf.mk | 1 + core/drivers/versal_mbox.c | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/core/arch/arm/plat-versal/conf.mk b/core/arch/arm/plat-versal/conf.mk index f94f27c7e44..6bb69c64a97 100644 --- a/core/arch/arm/plat-versal/conf.mk +++ b/core/arch/arm/plat-versal/conf.mk @@ -67,6 +67,7 @@ CFG_VERSAL_MBOX_IPI_ID ?= 1 else CFG_VERSAL_MBOX_IPI_ID ?= 3 endif +CFG_VERSAL_MBOX_TIMEOUT ?= 1000 # PM driver CFG_VERSAL_PM ?= y diff --git a/core/drivers/versal_mbox.c b/core/drivers/versal_mbox.c index 4a276be9dc7..326f49a4107 100644 --- a/core/drivers/versal_mbox.c +++ b/core/drivers/versal_mbox.c @@ -432,6 +432,8 @@ TEE_Result versal_mbox_free(struct versal_mbox_mem *mem) return TEE_ERROR_BAD_PARAMETERS; free(mem->buf); + mem->buf = NULL; + return TEE_SUCCESS; } @@ -455,9 +457,12 @@ TEE_Result versal_mbox_notify(struct versal_ipi *ipi, IPI_BIT_MASK(ipi->rmt)); /* Wait for remote to acknowledge the interrupt */ - do { - status = io_read32(ipi->regs + IPI_OBR_OFFSET); - } while (status & IPI_BIT_MASK(ipi->rmt)); + if (IO_READ32_POLL_TIMEOUT(ipi->regs + IPI_OBR_OFFSET, status, + status & IPI_BIT_MASK(ipi->rmt), 0, + CFG_VERSAL_MBOX_TIMEOUT)) { + ret = TEE_ERROR_GENERIC; + goto out; + } ret = versal_mbox_read_rsp(ipi, cmd, rsp, &status); if (ret) From 446148defc22872e50026c190701c08cc49e5608 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 3 Apr 2024 18:13:48 +0200 Subject: [PATCH 14/43] fixup! drivers: versal: rework mbox driver No need for all the different error labels. Signed-off-by: Jeremie Corbier --- core/drivers/crypto/versal/authenc.c | 12 ++++-------- core/drivers/crypto/versal/rsa.c | 20 ++++++++------------ core/drivers/versal_puf.c | 26 ++++++++++---------------- 3 files changed, 22 insertions(+), 36 deletions(-) diff --git a/core/drivers/crypto/versal/authenc.c b/core/drivers/crypto/versal/authenc.c index 76f0ecc1cdc..6e5f183767d 100644 --- a/core/drivers/crypto/versal/authenc.c +++ b/core/drivers/crypto/versal/authenc.c @@ -362,10 +362,10 @@ static TEE_Result do_init(struct drvcrypt_authenc_init *dinit) /* Send the initialization structure */ ret = versal_mbox_alloc(sizeof(*init), NULL, &init_buf); if (ret) - goto out1; + goto error; ret = versal_mbox_alloc(dinit->nonce.length, dinit->nonce.data, &nonce); if (ret) - goto out2; + goto error; init = init_buf.buf; init->iv_addr = virt_to_phys(nonce.buf); @@ -407,9 +407,7 @@ static TEE_Result do_init(struct drvcrypt_authenc_init *dinit) return TEE_SUCCESS; error: versal_mbox_free(&nonce); -out2: versal_mbox_free(&init_buf); -out1: versal_mbox_free(&key); return ret; @@ -496,10 +494,10 @@ update_payload(struct drvcrypt_authenc_update_payload *dupdate, bool is_last) return ret; ret = versal_mbox_alloc(dupdate->dst.length, NULL, &q); if (ret) - goto out1; + goto error; ret = versal_mbox_alloc(sizeof(*input), NULL, &input_cmd); if (ret) - goto out2; + goto error; input = input_cmd.buf; input->input_addr = virt_to_phys(p.buf); @@ -545,9 +543,7 @@ update_payload(struct drvcrypt_authenc_update_payload *dupdate, bool is_last) } error: versal_mbox_free(&input_cmd); -out2: versal_mbox_free(&q); -out1: versal_mbox_free(&p); return ret; diff --git a/core/drivers/crypto/versal/rsa.c b/core/drivers/crypto/versal/rsa.c index c2a8db72e42..2b97017564a 100644 --- a/core/drivers/crypto/versal/rsa.c +++ b/core/drivers/crypto/versal/rsa.c @@ -84,13 +84,13 @@ static TEE_Result do_encrypt(struct drvcrypt_rsa_ed *rsa_data) ret = versal_mbox_alloc(rsa_data->message.length, rsa_data->message.data, &msg); if (ret) - goto out1; + goto error; ret = versal_mbox_alloc(rsa_data->cipher.length, NULL, &cipher); if (ret) - goto out2; + goto error; ret = versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf); if (ret) - goto out3; + goto error; cmd = cmd_buf.buf; cmd->key_len = rsa_data->key.n_size; @@ -117,12 +117,10 @@ static TEE_Result do_encrypt(struct drvcrypt_rsa_ed *rsa_data) memcpy(rsa_data->cipher.data, cipher.buf, rsa_data->key.n_size); } +error: versal_mbox_free(&cmd_buf); -out3: versal_mbox_free(&cipher); -out2: versal_mbox_free(&msg); -out1: versal_mbox_free(&key); return ret; @@ -186,13 +184,13 @@ static TEE_Result do_decrypt(struct drvcrypt_rsa_ed *rsa_data) ret = versal_mbox_alloc(rsa_data->cipher.length, rsa_data->cipher.data, &cipher); if (ret) - goto out1; + goto error; ret = versal_mbox_alloc(rsa_data->message.length, NULL, &msg); if (ret) - goto out2; + goto error; ret = versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf); if (ret) - goto out3; + goto error; cmd = cmd_buf.buf; cmd->key_len = rsa_data->key.n_size; @@ -215,12 +213,10 @@ static TEE_Result do_decrypt(struct drvcrypt_rsa_ed *rsa_data) memcpy(rsa_data->message.data, msg.buf, rsa_data->key.n_size); } +error: versal_mbox_free(&cmd_buf); -out3: versal_mbox_free(&msg); -out2: versal_mbox_free(&cipher); -out1: versal_mbox_free(&key); return ret; diff --git a/core/drivers/versal_puf.c b/core/drivers/versal_puf.c index 47706f91fd9..f54f8cfea96 100644 --- a/core/drivers/versal_puf.c +++ b/core/drivers/versal_puf.c @@ -117,18 +117,18 @@ TEE_Result versal_puf_register(struct versal_puf_data *buf, return ret; ret = versal_mbox_alloc(sizeof(buf->chash), &buf->chash, &hash_addr); if (ret) - goto out1; + goto error; ret = versal_mbox_alloc(sizeof(buf->aux), &buf->aux, &aux_addr); if (ret) - goto out2; + goto error; ret = versal_mbox_alloc(sizeof(buf->efuse_syn_data), buf->efuse_syn_data, &efuse_syn_data_addr); if (ret) - goto out3; + goto error; ret = versal_mbox_alloc(sizeof(buf->syndrome_data), buf->syndrome_data, &syndrome_data_addr); if (ret) - goto out4; + goto error; arg.ibuf[0].mem = request; arg.ibuf[1].mem = syndrome_data_addr; @@ -169,14 +169,11 @@ TEE_Result versal_puf_register(struct versal_puf_data *buf, memcpy(buf->syndrome_data, syndrome_data_addr.buf, sizeof(buf->syndrome_data)); +error: versal_mbox_free(&syndrome_data_addr); -out4: versal_mbox_free(&efuse_syn_data_addr); -out3: versal_mbox_free(&aux_addr); -out2: versal_mbox_free(&hash_addr); -out1: versal_mbox_free(&puf_id_addr); return ret; @@ -211,18 +208,18 @@ TEE_Result versal_puf_regenerate(struct versal_puf_data *buf, return ret; ret = versal_mbox_alloc(sizeof(buf->chash), &buf->chash, &hash_addr); if (ret) - goto out1; + goto error; ret = versal_mbox_alloc(sizeof(buf->aux), &buf->aux, &aux_addr); if (ret) - goto out2; + goto error; ret = versal_mbox_alloc(sizeof(buf->efuse_syn_data), buf->efuse_syn_data, &efuse_syn_data_addr); if (ret) - goto out3; + goto error; ret = versal_mbox_alloc(sizeof(buf->syndrome_data), buf->syndrome_data, &syndrome_data_addr); if (ret) - goto out4; + goto error; arg.ibuf[0].mem = request; arg.ibuf[1].mem = syndrome_data_addr; @@ -257,14 +254,11 @@ TEE_Result versal_puf_regenerate(struct versal_puf_data *buf, /* Return the updated PUF_ID */ memcpy(buf->puf_id, puf_id_addr.buf, sizeof(buf->puf_id)); +error: versal_mbox_free(&syndrome_data_addr); -out4: versal_mbox_free(&efuse_syn_data_addr); -out3: versal_mbox_free(&aux_addr); -out2: versal_mbox_free(&hash_addr); -out1: versal_mbox_free(&puf_id_addr); return ret; From cc6883d69b742eaba726696a7af35ffcfe56fe66 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Thu, 20 Jun 2024 16:02:49 +0200 Subject: [PATCH 15/43] fixup! drivers: versal: PKI engine driver for Versal Net Signed-off-by: Jeremie Corbier --- core/drivers/crypto/versal/ecc.c | 12 +++++++----- core/drivers/crypto/versal/ecc_mbox.c | 6 ++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/drivers/crypto/versal/ecc.c b/core/drivers/crypto/versal/ecc.c index e2dde64dd1f..6acbc3387b6 100644 --- a/core/drivers/crypto/versal/ecc.c +++ b/core/drivers/crypto/versal/ecc.c @@ -4,11 +4,13 @@ * Author: Jorge Ramirez */ +#include +#include #include #include -#include -#include #include +#include +#include #include #include #include @@ -17,8 +19,6 @@ #include #include #include -#include -#include /* Software based ECDSA operations */ static const struct crypto_ecc_keypair_ops *pair_ops; @@ -76,6 +76,8 @@ void crypto_bignum_bin2bn_eswap(const uint8_t *from, size_t sz, { uint8_t pad[66] = { 0 }; + assert(sz <= sizeof(pad)); + memcpy_swp(pad, from, sz); crypto_bignum_bin2bn(pad, sz, to); } @@ -121,7 +123,7 @@ static TEE_Result do_shared_secret(struct drvcrypt_secret_data *sdata) static TEE_Result do_sign(struct drvcrypt_sign_data *sdata) { - TEE_Result ret; + TEE_Result ret = TEE_SUCCESS; ret = versal_ecc_sign(sdata->algo, sdata->key, diff --git a/core/drivers/crypto/versal/ecc_mbox.c b/core/drivers/crypto/versal/ecc_mbox.c index aff70cd12d7..7d96e0e1f6b 100644 --- a/core/drivers/crypto/versal/ecc_mbox.c +++ b/core/drivers/crypto/versal/ecc_mbox.c @@ -207,16 +207,14 @@ TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key, TEE_TYPE_ECDSA_KEYPAIR, bits); if (ret) { EMSG("Versal, can't allocate the ephemeral key"); - versal_mbox_free(&p); - return ret; + goto out1; } ephemeral.curve = key->curve; ret = crypto_acipher_gen_ecc_key(&ephemeral, bits); if (ret) { EMSG("Versal, can't generate the ephemeral key"); - versal_mbox_free(&p); - return ret; + goto out1; } ret = versal_mbox_alloc(bytes, NULL, &k); From 8f59535ce25d904f8224e0cdad5226ab123eef6c Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Thu, 20 Jun 2024 16:50:53 +0200 Subject: [PATCH 16/43] fixup! drivers: versal: NVM driver for Versal Net Signed-off-by: Jeremie Corbier --- core/drivers/versal_net_nvm.c | 126 ++++++++++++++++------------------ 1 file changed, 60 insertions(+), 66 deletions(-) diff --git a/core/drivers/versal_net_nvm.c b/core/drivers/versal_net_nvm.c index 5c1761ed1a5..667b32a9292 100644 --- a/core/drivers/versal_net_nvm.c +++ b/core/drivers/versal_net_nvm.c @@ -341,7 +341,7 @@ static TEE_Result versal_efuse_read_cache(uint16_t off, uint16_t num, reg_pair_from_64(virt_to_phys(p.buf), &b, &a); cmd.data[0] = NVM_API_ID(EFUSE_READ_CACHE); - cmd.data[1] = (num << 16) | off; + cmd.data[1] = SHIFT_U32(num, 16) | off; cmd.data[2] = a; cmd.data[3] = b; @@ -389,7 +389,7 @@ TEE_Result versal_efuse_read_dna(uint32_t *buf, size_t len) TEE_Result versal_efuse_read_user_data(uint32_t *buf, size_t len, uint32_t first, size_t num) { - uint16_t offset; + uint16_t offset = 0; if (first + num > EFUSE_MAX_USER_FUSES || len < num * NVM_WORD_LEN) return TEE_ERROR_BAD_PARAMETERS; @@ -402,7 +402,7 @@ TEE_Result versal_efuse_read_user_data(uint32_t *buf, size_t len, TEE_Result versal_efuse_read_iv(uint32_t *buf, size_t len, enum versal_nvm_iv_type type) { - uint16_t offset; + uint16_t offset = 0; switch (type) { case EFUSE_META_HEADER_IV_RANGE: @@ -428,7 +428,7 @@ TEE_Result versal_efuse_read_iv(uint32_t *buf, size_t len, TEE_Result versal_efuse_read_ppk(uint32_t *buf, size_t len, enum versal_nvm_ppk_type type) { - uint16_t offset; + uint16_t offset = 0; switch (type) { case EFUSE_PPK0: @@ -470,18 +470,18 @@ TEE_Result versal_efuse_read_misc_ctrl(struct versal_efuse_misc_ctrl_bits *buf) if (ret) return ret; - buf->glitch_det_halt_boot_en = ((misc_ctrl & GENMASK_32(31, 30)) >> 30); - buf->glitch_det_rom_monitor_en = ((misc_ctrl & BIT(29)) >> 29); - buf->halt_boot_error = ((misc_ctrl & GENMASK_32(22, 21)) >> 21); - buf->halt_boot_env = ((misc_ctrl & GENMASK_32(20, 19)) >> 19); - buf->crypto_kat_en = ((misc_ctrl & BIT(15)) >> 15); - buf->lbist_en = ((misc_ctrl & BIT(14)) >> 14); - buf->safety_mission_en = ((misc_ctrl & BIT(8)) >> 8); - buf->ppk0_invalid = ((misc_ctrl & GENMASK_32(7, 6)) >> 6); - buf->ppk1_invalid = ((misc_ctrl & GENMASK_32(5, 4)) >> 4); - buf->ppk2_invalid = ((misc_ctrl & GENMASK_32(3, 2)) >> 2); + buf->glitch_det_halt_boot_en = (misc_ctrl & GENMASK_32(31, 30)) >> 30; + buf->glitch_det_rom_monitor_en = (misc_ctrl & BIT(29)) >> 29; + buf->halt_boot_error = (misc_ctrl & GENMASK_32(22, 21)) >> 21; + buf->halt_boot_env = (misc_ctrl & GENMASK_32(20, 19)) >> 19; + buf->crypto_kat_en = (misc_ctrl & BIT(15)) >> 15; + buf->lbist_en = (misc_ctrl & BIT(14)) >> 14; + buf->safety_mission_en = (misc_ctrl & BIT(8)) >> 8; + buf->ppk0_invalid = (misc_ctrl & GENMASK_32(7, 6)) >> 6; + buf->ppk1_invalid = (misc_ctrl & GENMASK_32(5, 4)) >> 4; + buf->ppk2_invalid = (misc_ctrl & GENMASK_32(3, 2)) >> 2; - return ret; + return TEE_SUCCESS; } TEE_Result versal_efuse_read_sec_ctrl(struct versal_efuse_sec_ctrl_bits *buf) @@ -497,24 +497,24 @@ TEE_Result versal_efuse_read_sec_ctrl(struct versal_efuse_sec_ctrl_bits *buf) if (ret) return ret; - buf->aes_dis = (sec_ctrl & BIT(0)); - buf->jtag_err_out_dis = ((sec_ctrl & BIT(1)) >> 1); - buf->jtag_dis = ((sec_ctrl & BIT(2)) >> 2); - buf->ppk0_wr_lk = ((sec_ctrl & BIT(6)) >> 6); - buf->ppk1_wr_lk = ((sec_ctrl & BIT(7)) >> 7); - buf->ppk2_wr_lk = ((sec_ctrl & BIT(8)) >> 8); - buf->aes_crc_lk = ((sec_ctrl & GENMASK_32(10, 9)) >> 9); - buf->aes_wr_lk = ((sec_ctrl & BIT(11)) >> 11); - buf->user_key0_crc_lk = ((sec_ctrl & BIT(12)) >> 12); - buf->user_key0_wr_lk = ((sec_ctrl & BIT(13)) >> 13); - buf->user_key1_crc_lk = ((sec_ctrl & BIT(14)) >> 14); - buf->user_key1_wr_lk = ((sec_ctrl & BIT(15)) >> 15); - buf->sec_dbg_dis = ((sec_ctrl & GENMASK_32(20, 19)) >> 19); - buf->sec_lock_dbg_dis = ((sec_ctrl & GENMASK_32(22, 21)) >> 21); - buf->boot_env_wr_lk = ((sec_ctrl & BIT(28)) >> 28); - buf->reg_init_dis = ((sec_ctrl & GENMASK_32(31, 30)) >> 30); + buf->aes_dis = sec_ctrl & BIT(0); + buf->jtag_err_out_dis = (sec_ctrl & BIT(1)) >> 1; + buf->jtag_dis = (sec_ctrl & BIT(2)) >> 2; + buf->ppk0_wr_lk = (sec_ctrl & BIT(6)) >> 6; + buf->ppk1_wr_lk = (sec_ctrl & BIT(7)) >> 7; + buf->ppk2_wr_lk = (sec_ctrl & BIT(8)) >> 8; + buf->aes_crc_lk = (sec_ctrl & GENMASK_32(10, 9)) >> 9; + buf->aes_wr_lk = (sec_ctrl & BIT(11)) >> 11; + buf->user_key0_crc_lk = (sec_ctrl & BIT(12)) >> 12; + buf->user_key0_wr_lk = (sec_ctrl & BIT(13)) >> 13; + buf->user_key1_crc_lk = (sec_ctrl & BIT(14)) >> 14; + buf->user_key1_wr_lk = (sec_ctrl & BIT(15)) >> 15; + buf->sec_dbg_dis = (sec_ctrl & GENMASK_32(20, 19)) >> 19; + buf->sec_lock_dbg_dis = (sec_ctrl & GENMASK_32(22, 21)) >> 21; + buf->boot_env_wr_lk = (sec_ctrl & BIT(28)) >> 28; + buf->reg_init_dis = (sec_ctrl & GENMASK_32(31, 30)) >> 30; - return ret; + return TEE_SUCCESS; } TEE_Result versal_efuse_read_sec_misc1(struct versal_efuse_sec_misc1_bits *buf) @@ -530,13 +530,13 @@ TEE_Result versal_efuse_read_sec_misc1(struct versal_efuse_sec_misc1_bits *buf) if (ret) return ret; - buf->lpd_mbist_en = ((sec_misc1 & GENMASK_32(12, 10)) >> 10); - buf->pmc_mbist_en = ((sec_misc1 & GENMASK_32(9, 7)) >> 7); - buf->lpd_noc_sc_en = ((sec_misc1 & GENMASK_32(6, 4)) >> 4); - buf->sysmon_volt_mon_en = ((sec_misc1 & GENMASK_32(3, 2)) >> 2); - buf->sysmon_temp_mon_en = (sec_misc1 & GENMASK_32(1, 0)); + buf->lpd_mbist_en = (sec_misc1 & GENMASK_32(12, 10)) >> 10; + buf->pmc_mbist_en = (sec_misc1 & GENMASK_32(9, 7)) >> 7; + buf->lpd_noc_sc_en = (sec_misc1 & GENMASK_32(6, 4)) >> 4; + buf->sysmon_volt_mon_en = (sec_misc1 & GENMASK_32(3, 2)) >> 2; + buf->sysmon_temp_mon_en = sec_misc1 & GENMASK_32(1, 0); - return ret; + return TEE_SUCCESS; } TEE_Result @@ -553,15 +553,15 @@ versal_efuse_read_boot_env_ctrl(struct versal_efuse_boot_env_ctrl_bits *buf) if (ret) return ret; - buf->sysmon_temp_en = ((boot_env_ctrl & BIT(21)) >> 21); - buf->sysmon_volt_en = ((boot_env_ctrl & BIT(20)) >> 20); - buf->sysmon_temp_hot = ((boot_env_ctrl & GENMASK_32(18, 17)) >> 17); - buf->sysmon_volt_pmc = ((boot_env_ctrl & GENMASK_32(13, 12)) >> 12); - buf->sysmon_volt_pslp = ((boot_env_ctrl & GENMASK_32(11, 10)) >> 10); - buf->sysmon_volt_soc = ((boot_env_ctrl & GENMASK_32(9, 8)) >> 8); - buf->sysmon_temp_cold = (boot_env_ctrl & GENMASK_32(1, 0)); + buf->sysmon_temp_en = (boot_env_ctrl & BIT(21)) >> 21; + buf->sysmon_volt_en = (boot_env_ctrl & BIT(20)) >> 20; + buf->sysmon_temp_hot = (boot_env_ctrl & GENMASK_32(18, 17)) >> 17; + buf->sysmon_volt_pmc = (boot_env_ctrl & GENMASK_32(13, 12)) >> 12; + buf->sysmon_volt_pslp = (boot_env_ctrl & GENMASK_32(11, 10)) >> 10; + buf->sysmon_volt_soc = (boot_env_ctrl & GENMASK_32(9, 8)) >> 8; + buf->sysmon_temp_cold = boot_env_ctrl & GENMASK_32(1, 0); - return ret; + return TEE_SUCCESS; } TEE_Result versal_efuse_read_offchip_revoke_id(uint32_t *buf, size_t len, @@ -593,7 +593,7 @@ TEE_Result versal_efuse_read_dec_only(uint32_t *buf, size_t len) memcpy(buf, &sec_misc0, EFUSE_DEC_ONLY_LEN); - return ret; + return TEE_SUCCESS; } TEE_Result versal_efuse_read_puf_sec_ctrl(struct versal_efuse_puf_sec_ctrl_bits @@ -619,13 +619,13 @@ TEE_Result versal_efuse_read_puf_sec_ctrl(struct versal_efuse_puf_sec_ctrl_bits if (ret) return ret; - buf->puf_regen_dis = ((puf_ctrl & BIT(31)) >> 31); - buf->puf_hd_invalid = ((puf_ctrl & BIT(30)) >> 30); - buf->puf_test2_dis = ((puf_ctrl & BIT(29)) >> 29); - buf->puf_dis = ((sec_ctrl & BIT(18)) >> 18); - buf->puf_syn_lk = ((sec_ctrl & BIT(16)) >> 16); + buf->puf_regen_dis = (puf_ctrl & BIT(31)) >> 31; + buf->puf_hd_invalid = (puf_ctrl & BIT(30)) >> 30; + buf->puf_test2_dis = (puf_ctrl & BIT(29)) >> 29; + buf->puf_dis = (sec_ctrl & BIT(18)) >> 18; + buf->puf_syn_lk = (sec_ctrl & BIT(16)) >> 16; - return ret; + return TEE_SUCCESS; } TEE_Result versal_efuse_read_puf(struct versal_efuse_puf_header *buf) @@ -651,10 +651,9 @@ TEE_Result versal_efuse_read_puf(struct versal_efuse_puf_header *buf) if (ret) return ret; - ret = versal_efuse_read_cache(EFUSE_CACHE_PUF_SYN0_OFFSET, + return versal_efuse_read_cache(EFUSE_CACHE_PUF_SYN0_OFFSET, PUF_SYN_DATA_WORDS, buf->efuse_syn_data, PUF_SYN_DATA_WORDS * NVM_WORD_LEN); - return ret; } TEE_Result @@ -710,15 +709,12 @@ static TEE_Result do_write_efuses_buffer(enum versal_nvm_api_id id, static TEE_Result do_write_efuses_value(enum versal_nvm_api_id id, uint32_t val) { struct versal_ipi_cmd cmd = { }; - TEE_Result ret = TEE_SUCCESS; cmd.data[0] = NVM_API_ID(id); cmd.data[1] = EFUSE_ENV_DIS_FLAG; cmd.data[2] = val; - ret = versal_mbox_notify_pmc(&cmd, NULL, NULL); - - return ret; + return versal_mbox_notify_pmc(&cmd, NULL, NULL); } static TEE_Result do_write_efuses(enum versal_nvm_api_id id) @@ -729,7 +725,7 @@ static TEE_Result do_write_efuses(enum versal_nvm_api_id id) TEE_Result versal_efuse_write_aes_keys(struct versal_efuse_aes_keys *keys) { TEE_Result ret = TEE_SUCCESS; - TEE_Result res; + TEE_Result res = TEE_SUCCESS; if (!keys) return TEE_ERROR_BAD_PARAMETERS; @@ -774,7 +770,7 @@ TEE_Result versal_efuse_write_aes_keys(struct versal_efuse_aes_keys *keys) TEE_Result versal_efuse_write_ppk_hash(struct versal_efuse_ppk_hash *hash) { TEE_Result ret = TEE_SUCCESS; - TEE_Result res; + TEE_Result res = TEE_SUCCESS; if (!hash) return TEE_ERROR_BAD_PARAMETERS; @@ -815,7 +811,7 @@ TEE_Result versal_efuse_write_ppk_hash(struct versal_efuse_ppk_hash *hash) TEE_Result versal_efuse_write_iv(struct versal_efuse_ivs *p) { TEE_Result ret = TEE_SUCCESS; - TEE_Result res; + TEE_Result res = TEE_SUCCESS; if (!p) return TEE_ERROR_BAD_PARAMETERS; @@ -980,9 +976,7 @@ TEE_Result versal_efuse_write_offchip_ids(uint32_t id) TEE_Result versal_efuse_write_revoke_ppk(enum versal_nvm_ppk_type type) { - struct versal_efuse_misc_ctrl_bits misc_ctrl; - - memset(&misc_ctrl, 0, sizeof(struct versal_efuse_misc_ctrl_bits)); + struct versal_efuse_misc_ctrl_bits misc_ctrl = {}; switch (type) { case EFUSE_PPK0: @@ -1031,7 +1025,7 @@ TEE_Result versal_efuse_write_puf(struct versal_efuse_puf_header *buf) TEE_Result ret = TEE_SUCCESS; uint32_t a = 0; uint32_t b = 0; - struct versal_efuse_write_puf_data *data; + struct versal_efuse_write_puf_data *data = NULL; if (!buf) return TEE_ERROR_BAD_PARAMETERS; From a9df558c882fe9520e454c2276fed986cce7fb56 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Thu, 20 Jun 2024 18:06:45 +0200 Subject: [PATCH 17/43] fixup! drivers: versal: PKI engine driver for Versal Net Signed-off-by: Jeremie Corbier --- core/drivers/crypto/versal/ecc.c | 12 +- core/drivers/crypto/versal/ecc_mbox.c | 10 +- core/drivers/crypto/versal/include/ecc.h | 6 +- .../crypto/versal/pki/ecc_pki_engine.c | 143 ++++++++------ core/drivers/crypto/versal/pki/ecc_pki_kat.c | 185 +++++++++--------- 5 files changed, 185 insertions(+), 171 deletions(-) diff --git a/core/drivers/crypto/versal/ecc.c b/core/drivers/crypto/versal/ecc.c index 6acbc3387b6..b2e47b95b9e 100644 --- a/core/drivers/crypto/versal/ecc.c +++ b/core/drivers/crypto/versal/ecc.c @@ -56,7 +56,7 @@ void memcpy_swp(uint8_t *to, const uint8_t *from, size_t len) to[i] = from[len - 1 - i]; } -void crypto_bignum_bn2bin_eswap(uint32_t curve, struct bignum *from, +void versal_crypto_bignum_bn2bin_eswap(uint32_t curve, struct bignum *from, uint8_t *to) { uint8_t pad[66] = { 0 }; @@ -71,7 +71,7 @@ void crypto_bignum_bn2bin_eswap(uint32_t curve, struct bignum *from, memcpy_swp(to, pad, bytes); } -void crypto_bignum_bin2bn_eswap(const uint8_t *from, size_t sz, +void versal_crypto_bignum_bin2bn_eswap(const uint8_t *from, size_t sz, struct bignum *to) { uint8_t pad[66] = { 0 }; @@ -132,13 +132,14 @@ static TEE_Result do_sign(struct drvcrypt_sign_data *sdata) sdata->signature.data, &sdata->signature.length); - if (ret == TEE_ERROR_NOT_SUPPORTED) + if (ret == TEE_ERROR_NOT_SUPPORTED) { /* Fallback to software */ return pair_ops->sign(sdata->algo, sdata->key, sdata->message.data, sdata->message.length, sdata->signature.data, &sdata->signature.length); + } return ret; } @@ -154,13 +155,14 @@ static TEE_Result do_verify(struct drvcrypt_sign_data *sdata) sdata->signature.data, sdata->signature.length); - if (ret == TEE_ERROR_NOT_SUPPORTED) + if (ret == TEE_ERROR_NOT_SUPPORTED) { /* Fallback to software */ return pub_ops->verify(sdata->algo, sdata->key, sdata->message.data, sdata->message.length, sdata->signature.data, sdata->signature.length); + } return ret; } @@ -255,7 +257,7 @@ static TEE_Result ecc_init(void) return ret; /* Run KAT self-tests */ - ret = versal_ecc_kat(); + ret = versal_ecc_kat_test(); if (ret != TEE_SUCCESS) return ret; diff --git a/core/drivers/crypto/versal/ecc_mbox.c b/core/drivers/crypto/versal/ecc_mbox.c index 7d96e0e1f6b..91ba5fe1709 100644 --- a/core/drivers/crypto/versal/ecc_mbox.c +++ b/core/drivers/crypto/versal/ecc_mbox.c @@ -114,8 +114,8 @@ TEE_Result versal_ecc_verify(uint32_t algo, struct ecc_public_key *key, if (ret) goto out1; - crypto_bignum_bn2bin_eswap(key->curve, key->x, x.buf); - crypto_bignum_bn2bin_eswap(key->curve, key->y, + versal_crypto_bignum_bn2bin_eswap(key->curve, key->x, x.buf); + versal_crypto_bignum_bn2bin_eswap(key->curve, key->y, (uint8_t *)x.buf + bytes); /* Validate the public key for the curve */ arg.data[0] = key->curve; @@ -221,7 +221,7 @@ TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key, if (ret) goto out1; - crypto_bignum_bn2bin_eswap(key->curve, ephemeral.d, k.buf); + versal_crypto_bignum_bn2bin_eswap(key->curve, ephemeral.d, k.buf); crypto_bignum_free(&ephemeral.d); crypto_bignum_free(&ephemeral.x); crypto_bignum_free(&ephemeral.y); @@ -230,7 +230,7 @@ TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key, ret = versal_mbox_alloc(bytes, NULL, &d); if (ret) goto out2; - crypto_bignum_bn2bin_eswap(key->curve, key->d, d.buf); + versal_crypto_bignum_bn2bin_eswap(key->curve, key->d, d.buf); /* Signature */ ret = versal_mbox_alloc(*sig_len, NULL, &s); @@ -284,7 +284,7 @@ TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key, /* AMD/Xilinx Versal's Known Answer Tests */ #define XSECURE_ECDSA_KAT_NIST_P384 0 -TEE_Result versal_ecc_kat(void) +TEE_Result versal_ecc_kat_test(void) { struct versal_cmd_args arg = { }; uint32_t err = 0; diff --git a/core/drivers/crypto/versal/include/ecc.h b/core/drivers/crypto/versal/include/ecc.h index 496f95001d3..4a6f0ca1685 100644 --- a/core/drivers/crypto/versal/include/ecc.h +++ b/core/drivers/crypto/versal/include/ecc.h @@ -11,7 +11,7 @@ TEE_Result versal_ecc_prepare_msg(uint32_t algo, const uint8_t *msg, size_t msg_len, size_t *len, uint8_t *buf); TEE_Result versal_ecc_hw_init(void); -TEE_Result versal_ecc_kat(void); +TEE_Result versal_ecc_kat_test(void); TEE_Result versal_ecc_gen_keypair(struct ecc_keypair *s); #ifdef CFG_VERSAL_PKI_PWCT @@ -30,9 +30,9 @@ TEE_Result versal_ecc_sign_ephemeral(uint32_t algo, size_t bytes, uint8_t *sig, size_t *sig_len); void memcpy_swp(uint8_t *to, const uint8_t *from, size_t len); -void crypto_bignum_bn2bin_eswap(uint32_t curve, struct bignum *from, +void versal_crypto_bignum_bn2bin_eswap(uint32_t curve, struct bignum *from, uint8_t *to); -void crypto_bignum_bin2bn_eswap(const uint8_t *from, size_t sz, +void versal_crypto_bignum_bin2bn_eswap(const uint8_t *from, size_t sz, struct bignum *to); #endif diff --git a/core/drivers/crypto/versal/pki/ecc_pki_engine.c b/core/drivers/crypto/versal/pki/ecc_pki_engine.c index cd451fafbf6..eb55fc23f06 100644 --- a/core/drivers/crypto/versal/pki/ecc_pki_engine.c +++ b/core/drivers/crypto/versal/pki/ecc_pki_engine.c @@ -3,24 +3,24 @@ * Copyright (C) ProvenRun SAS 2023. */ +#include +#include +#include #include #include -#include -#include #include -#include -#include +#include +#include #include +#include #include #include +#include +#include #include #include #include #include -#include -#include -#include -#include /* PKI Engine TRNG driver */ #define TRNG_BASE UINT64_C(0x20400051000) @@ -162,17 +162,20 @@ static struct versal_pki versal_pki; #define PKI_DEFAULT_REQID 0xB04EU #define PKI_EXPECTED_CQ_STATUS 0 -#define PKI_EXPECTED_CQ_VALUE (PKI_DEFAULT_REQID << 16 | 0x1) +#define PKI_EXPECTED_CQ_VALUE (SHIFT_U32(PKI_DEFAULT_REQID, 16) | 0x1) #define PKI_RESET_DELAY_US 10 -static void pki_get_opsize(uint32_t curve, uint32_t op, size_t *in_sz, +static TEE_Result pki_get_opsize(uint32_t curve, uint32_t op, size_t *in_sz, size_t *out_sz) { - size_t bits; - size_t bytes; + TEE_Result ret = TEE_SUCCESS; + size_t bits = 0; + size_t bytes = 0; - versal_ecc_get_key_size(curve, &bytes, &bits); + ret = versal_ecc_get_key_size(curve, &bytes, &bits); + if (ret) + return ret; switch (op) { case PKI_DESC_OPTYPE_ECDSA_SIGN: @@ -192,19 +195,24 @@ static void pki_get_opsize(uint32_t curve, uint32_t op, size_t *in_sz, *out_sz = bytes * PKI_ECC_POINTMUL_OUTPUT_OP_COUNT; break; default: - break; + return TEE_ERROR_NOT_SUPPORTED; } + + return TEE_SUCCESS; } static TEE_Result pki_build_descriptors(uint32_t curve, uint32_t op, uint32_t *descs) { + TEE_Result ret = TEE_SUCCESS; size_t in_sz = 0; size_t out_sz = 0; uint32_t opsize = 0; uint32_t selcurve = 0; - pki_get_opsize(curve, op, &in_sz, &out_sz); + ret = pki_get_opsize(curve, op, &in_sz, &out_sz); + if (ret) + return ret; switch (curve) { case TEE_ECC_CURVE_NIST_P256: @@ -243,7 +251,6 @@ static TEE_Result pki_build_descriptors(uint32_t curve, uint32_t op, static TEE_Result pki_start_operation(uint32_t reqval) { TEE_Result ret = TEE_ERROR_TIMEOUT; - uint32_t retries = PKI_MAX_RETRY_COUNT; /* Soft reset */ @@ -297,8 +304,8 @@ static TEE_Result pki_start_operation(uint32_t reqval) static TEE_Result pki_check_status(void) { - uint32_t cq_status; - uint32_t cq_value; + uint32_t cq_status = 0; + uint32_t cq_value = 0; cache_operation(TEE_CACHEFLUSH, versal_pki.cq, PKI_QUEUE_BUF_SIZE); @@ -317,11 +324,9 @@ TEE_Result versal_ecc_verify(uint32_t algo, struct ecc_public_key *key, const uint8_t *sig, size_t sig_len) { TEE_Result ret = TEE_SUCCESS; - size_t bits = 0; size_t bytes = 0; size_t len = 0; - uintptr_t addr = (uintptr_t)versal_pki.rq_in; ret = versal_ecc_get_key_size(key->curve, &bytes, &bits); @@ -329,9 +334,9 @@ TEE_Result versal_ecc_verify(uint32_t algo, struct ecc_public_key *key, return ret; /* Copy public key */ - crypto_bignum_bn2bin_eswap(key->curve, key->x, (uint8_t *)addr); + versal_crypto_bignum_bn2bin_eswap(key->curve, key->x, (uint8_t *)addr); addr += bytes; - crypto_bignum_bn2bin_eswap(key->curve, key->y, (uint8_t *)addr); + versal_crypto_bignum_bn2bin_eswap(key->curve, key->y, (uint8_t *)addr); addr += bytes; /* Copy signature */ @@ -399,12 +404,13 @@ TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key, ret = versal_ecc_gen_keypair(&ephemeral); if (ret) { EMSG("Versal, can't generate the ephemeral key"); - return ret; + goto out; } ret = versal_ecc_sign_ephemeral(algo, bytes, key, &ephemeral, msg, msg_len, sig, sig_len); +out: crypto_bignum_free(&ephemeral.d); crypto_bignum_free(&ephemeral.x); crypto_bignum_free(&ephemeral.y); @@ -420,15 +426,15 @@ TEE_Result versal_ecc_sign_ephemeral(uint32_t algo, size_t bytes, { TEE_Result ret = TEE_SUCCESS; size_t len = 0; - uintptr_t addr = (uintptr_t)versal_pki.rq_in; /* Copy private key */ - crypto_bignum_bn2bin_eswap(key->curve, key->d, (uint8_t *)addr); + versal_crypto_bignum_bn2bin_eswap(key->curve, key->d, (uint8_t *)addr); addr += bytes; /* Copy ephemeral key */ - crypto_bignum_bn2bin_eswap(key->curve, ephemeral->d, (uint8_t *)addr); + versal_crypto_bignum_bn2bin_eswap(key->curve, ephemeral->d, + (uint8_t *)addr); addr += bytes; /* Copy hash */ @@ -474,14 +480,14 @@ TEE_Result versal_ecc_sign_ephemeral(uint32_t algo, size_t bytes, return ret; } -static const uint8_t Order_P256[] = { +static const uint8_t order_p256[] = { 0x51, 0x25, 0x63, 0xfc, 0xc2, 0xca, 0xb9, 0xf3, 0x84, 0x9e, 0x17, 0xa7, 0xad, 0xfa, 0xe6, 0xbc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, }; -static const uint8_t Order_P384[] = { +static const uint8_t order_p384[] = { 0x73, 0x29, 0xc5, 0xcc, 0x6a, 0x19, 0xec, 0xec, 0x7a, 0xa7, 0xb0, 0x48, 0xb2, 0x0d, 0x1a, 0x58, 0xdf, 0x2d, 0x37, 0xf4, 0x81, 0x4d, 0x63, 0xc7, @@ -490,7 +496,7 @@ static const uint8_t Order_P384[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; -static const uint8_t Order_P521[] = { +static const uint8_t order_p521[] = { 0x09, 0x64, 0x38, 0x91, 0x1e, 0xb7, 0x6f, 0xbb, 0xae, 0x47, 0x9c, 0x89, 0xb8, 0xc9, 0xb5, 0x3b, 0xd0, 0xa5, 0x09, 0xf7, 0x48, 0x01, 0xcc, 0x7f, @@ -502,21 +508,21 @@ static const uint8_t Order_P521[] = { 0xff, 0x01 }; -static const uint8_t EcdsaGpoint_P256_Gx[] = { +static const uint8_t ecdsa_gpoint_p256_gx[] = { 0x96, 0xc2, 0x98, 0xd8, 0x45, 0x39, 0xa1, 0xf4, 0xa0, 0x33, 0xeb, 0x2d, 0x81, 0x7d, 0x03, 0x77, 0xf2, 0x40, 0xa4, 0x63, 0xe5, 0xe6, 0xbc, 0xf8, 0x47, 0x42, 0x2c, 0xe1, 0xf2, 0xd1, 0x17, 0x6b }; -static const uint8_t EcdsaGpoint_P256_Gy[] = { +static const uint8_t ecdsa_gpoint_p256_gy[] = { 0xf5, 0x51, 0xbf, 0x37, 0x68, 0x40, 0xb6, 0xcb, 0xce, 0x5e, 0x31, 0x6b, 0x57, 0x33, 0xce, 0x2b, 0x16, 0x9e, 0x0f, 0x7c, 0x4a, 0xeb, 0xe7, 0x8e, 0x9b, 0x7f, 0x1a, 0xfe, 0xe2, 0x42, 0xe3, 0x4f }; -static const uint8_t EcdsaGpoint_P384_Gx[] = { +static const uint8_t ecdsa_gpoint_p384_gx[] = { 0xb7, 0x0a, 0x76, 0x72, 0x38, 0x5e, 0x54, 0x3a, 0x6c, 0x29, 0x55, 0xbf, 0x5d, 0xf2, 0x02, 0x55, 0x38, 0x2a, 0x54, 0x82, 0xe0, 0x41, 0xf7, 0x59, @@ -525,7 +531,7 @@ static const uint8_t EcdsaGpoint_P384_Gx[] = { 0x37, 0x05, 0x8b, 0xbe, 0x22, 0xca, 0x87, 0xaa }; -static const uint8_t EcdsaGpoint_P384_Gy[] = { +static const uint8_t ecdsa_gpoint_p384_gy[] = { 0x5f, 0x0e, 0xea, 0x90, 0x7c, 0x1d, 0x43, 0x7a, 0x9d, 0x81, 0x7e, 0x1d, 0xce, 0xb1, 0x60, 0x0a, 0xc0, 0xb8, 0xf0, 0xb5, 0x13, 0x31, 0xda, 0xe9, @@ -534,7 +540,7 @@ static const uint8_t EcdsaGpoint_P384_Gy[] = { 0x6f, 0x2c, 0x26, 0x96, 0x4a, 0xde, 0x17, 0x36 }; -static const uint8_t EcdsaGpoint_P521_Gx[] = { +static const uint8_t ecdsa_gpoint_p521_gx[] = { 0x66, 0xbd, 0xe5, 0xc2, 0x31, 0x7e, 0x7e, 0xf9, 0x9b, 0x42, 0x6a, 0x85, 0xc1, 0xb3, 0x48, 0x33, 0xde, 0xa8, 0xff, 0xa2, 0x27, 0xc1, 0x1d, 0xfe, @@ -546,7 +552,7 @@ static const uint8_t EcdsaGpoint_P521_Gx[] = { 0xc6, 0x00 }; -static const uint8_t EcdsaGpoint_P521_Gy[] = { +static const uint8_t ecdsa_gpoint_p521_gy[] = { 0x50, 0x66, 0xd1, 0x9f, 0x76, 0x94, 0xbe, 0x88, 0x40, 0xc2, 0x72, 0xa2, 0x86, 0x70, 0x3c, 0x35, 0x61, 0x07, 0xad, 0x3f, 0x01, 0xb9, 0x50, 0xc5, @@ -562,18 +568,18 @@ static TEE_Result versal_ecc_gen_private_key(uint32_t curve, uint8_t *priv, size_t bytes) { TEE_Result ret = TEE_SUCCESS; - const uint8_t *order; + const uint8_t *order = NULL; uintptr_t addr = (uintptr_t)versal_pki.rq_in; switch (curve) { case TEE_ECC_CURVE_NIST_P256: - order = Order_P256; + order = order_p256; break; case TEE_ECC_CURVE_NIST_P384: - order = Order_P384; + order = order_p384; break; case TEE_ECC_CURVE_NIST_P521: - order = Order_P521; + order = order_p521; break; default: return TEE_ERROR_NOT_SUPPORTED; @@ -619,16 +625,16 @@ static TEE_Result versal_ecc_gen_private_key(uint32_t curve, uint8_t *priv, /* Copy back result */ memcpy(priv, versal_pki.rq_out, bytes); - return ret; + return TEE_SUCCESS; } TEE_Result versal_ecc_gen_keypair(struct ecc_keypair *s) { TEE_Result ret = TEE_SUCCESS; - size_t bytes; - size_t bits; - const uint8_t *Gx; - const uint8_t *Gy; + size_t bytes = 0; + size_t bits = 0; + const uint8_t *gx = NULL; + const uint8_t *gy = NULL; uintptr_t addr = (uintptr_t)versal_pki.rq_in; ret = versal_ecc_get_key_size(s->curve, &bytes, &bits); @@ -637,16 +643,16 @@ TEE_Result versal_ecc_gen_keypair(struct ecc_keypair *s) switch (s->curve) { case TEE_ECC_CURVE_NIST_P256: - Gx = EcdsaGpoint_P256_Gx; - Gy = EcdsaGpoint_P256_Gy; + gx = ecdsa_gpoint_p256_gx; + gy = ecdsa_gpoint_p256_gy; break; case TEE_ECC_CURVE_NIST_P384: - Gx = EcdsaGpoint_P384_Gx; - Gy = EcdsaGpoint_P384_Gy; + gx = ecdsa_gpoint_p384_gx; + gy = ecdsa_gpoint_p384_gy; break; case TEE_ECC_CURVE_NIST_P521: - Gx = EcdsaGpoint_P521_Gx; - Gy = EcdsaGpoint_P521_Gy; + gx = ecdsa_gpoint_p521_gx; + gy = ecdsa_gpoint_p521_gy; break; default: return TEE_ERROR_NOT_SUPPORTED; @@ -659,11 +665,11 @@ TEE_Result versal_ecc_gen_keypair(struct ecc_keypair *s) addr += bytes; /* Copy generator point x coordinate */ - memcpy((uint8_t *)addr, Gx, bytes); + memcpy((uint8_t *)addr, gx, bytes); addr += bytes; /* Copy generator point y coordinate */ - memcpy((uint8_t *)addr, Gy, bytes); + memcpy((uint8_t *)addr, gy, bytes); addr += bytes; if (s->curve == TEE_ECC_CURVE_NIST_P521) { @@ -689,16 +695,16 @@ TEE_Result versal_ecc_gen_keypair(struct ecc_keypair *s) cache_operation(TEE_CACHEFLUSH, versal_pki.rq_out, PKI_QUEUE_BUF_SIZE); /* Copy private and public keys back */ - crypto_bignum_bin2bn_eswap(versal_pki.rq_in, bytes, s->d); - crypto_bignum_bin2bn_eswap(versal_pki.rq_out, bytes, s->x); - crypto_bignum_bin2bn_eswap(versal_pki.rq_out + bytes, bytes, s->y); + versal_crypto_bignum_bin2bn_eswap(versal_pki.rq_in, bytes, s->d); + versal_crypto_bignum_bin2bn_eswap(versal_pki.rq_out, bytes, s->x); + versal_crypto_bignum_bin2bn_eswap(versal_pki.rq_out + bytes, bytes, s->y); /* Clear memory */ memset(versal_pki.rq_in, 0, PKI_QUEUE_BUF_SIZE); memset(versal_pki.rq_out, 0, PKI_QUEUE_BUF_SIZE); memset(versal_pki.cq, 0, PKI_QUEUE_BUF_SIZE); - return ret; + return TEE_SUCCESS; } #define PSX_CRF_RST_PKI 0xEC200340 @@ -708,7 +714,7 @@ TEE_Result versal_ecc_gen_keypair(struct ecc_keypair *s) static TEE_Result versal_pki_engine_reset(void) { - vaddr_t reset; + vaddr_t reset = 0; /* Reset the PKI engine */ reset = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, @@ -740,7 +746,7 @@ static TEE_Result versal_pki_engine_reset(void) static TEE_Result versal_pki_engine_slcr_config(void) { - vaddr_t fpd_slcr; + vaddr_t fpd_slcr = 0; fpd_slcr = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, FPD_SLCR_BASEADDR, @@ -768,8 +774,8 @@ static TEE_Result versal_pki_engine_slcr_config(void) static TEE_Result versal_pki_engine_config(void) { - vaddr_t regs; - uint64_t val; + vaddr_t regs = 0; + uint64_t val = 0; regs = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, FPD_PKI_CTRLSTAT_BASEADDR, @@ -798,7 +804,7 @@ static TEE_Result versal_pki_engine_config(void) TEE_Result versal_ecc_hw_init(void) { - TEE_Result ret; + TEE_Result ret = TEE_SUCCESS; ret = versal_pki_engine_slcr_config(); if (ret != TEE_SUCCESS) @@ -824,15 +830,24 @@ TEE_Result versal_ecc_hw_init(void) /* Allocate queues */ versal_pki.rq_in = memalign(CACHELINE_LEN, PKI_QUEUE_BUF_SIZE); if (!versal_pki.rq_in) - return TEE_ERROR_GENERIC; + goto error; versal_pki.rq_out = memalign(CACHELINE_LEN, PKI_QUEUE_BUF_SIZE); if (!versal_pki.rq_out) - return TEE_ERROR_GENERIC; + goto error; versal_pki.cq = memalign(CACHELINE_LEN, PKI_QUEUE_BUF_SIZE); if (!versal_pki.cq) - return TEE_ERROR_GENERIC; + goto error; return TEE_SUCCESS; + +error: + free(versal_pki.rq_in); + free(versal_pki.rq_out); + + core_mmu_remove_mapping(MEM_AREA_IO_SEC, + (void *)versal_pki.regs, FPD_PKI_SIZE); + + return TEE_ERROR_GENERIC; } diff --git a/core/drivers/crypto/versal/pki/ecc_pki_kat.c b/core/drivers/crypto/versal/pki/ecc_pki_kat.c index 73fe2c39d8f..0e11a89ac19 100644 --- a/core/drivers/crypto/versal/pki/ecc_pki_kat.c +++ b/core/drivers/crypto/versal/pki/ecc_pki_kat.c @@ -3,37 +3,37 @@ * Copyright (C) ProvenRun SAS 2023. */ +#include +#include #include #include -#include -#include #include -#include +#include +#include #include +#include #include #include #include #include #include #include -#include -#include -static const uint8_t PubkeyQx_P256[] = { +static const uint8_t pubkey_qx_p256[] = { 0xb7, 0xe0, 0x8a, 0xfd, 0xfe, 0x94, 0xba, 0xd3, 0xf1, 0xdc, 0x8c, 0x73, 0x47, 0x98, 0xba, 0x1c, 0x62, 0xb3, 0xa0, 0xad, 0x1e, 0x9e, 0xa2, 0xa3, 0x82, 0x01, 0xcd, 0x08, 0x89, 0xbc, 0x7a, 0x19 }; -static const uint8_t PubkeyQy_P256[] = { +static const uint8_t pubkey_qy_p256[] = { 0x36, 0x03, 0xf7, 0x47, 0x95, 0x9d, 0xbf, 0x7a, 0x4b, 0xb2, 0x26, 0xe4, 0x19, 0x28, 0x72, 0x90, 0x63, 0xad, 0xc7, 0xae, 0x43, 0x52, 0x9e, 0x61, 0xb5, 0x63, 0xbb, 0xc6, 0x06, 0xcc, 0x5e, 0x09, }; -static const uint8_t PubkeyQx_P384[] = { +static const uint8_t pubkey_qx_p384[] = { 0x3b, 0xf7, 0x01, 0xbc, 0x9e, 0x9d, 0x36, 0xb4, 0xd5, 0xf1, 0x45, 0x53, 0x43, 0xf0, 0x91, 0x26, 0xf2, 0x56, 0x43, 0x90, 0xf2, 0xb4, 0x87, 0x36, @@ -42,7 +42,7 @@ static const uint8_t PubkeyQx_P384[] = { 0x08, 0x64, 0x89, 0xd9, 0xef, 0x0f, 0x5c, 0xb5, }; -static const uint8_t PubkeyQy_P384[] = { +static const uint8_t pubkey_qy_p384[] = { 0xd1, 0xa3, 0x58, 0xea, 0xfb, 0xf9, 0x52, 0xe6, 0x8d, 0x53, 0x38, 0x55, 0xcc, 0xbd, 0xaa, 0x6f, 0xf7, 0x5b, 0x13, 0x7a, 0x51, 0x01, 0x44, 0x31, @@ -51,7 +51,7 @@ static const uint8_t PubkeyQy_P384[] = { 0x03, 0x44, 0xa9, 0xb5, 0xb6, 0x8d, 0xb8, 0x55, }; -static const uint8_t PubkeyQx_P521[] = { +static const uint8_t pubkey_qx_p521[] = { 0x00, 0x98, 0xe9, 0x1e, 0xef, 0x9a, 0x68, 0x45, 0x28, 0x22, 0x30, 0x9c, 0x52, 0xfa, 0xb4, 0x53, 0xf5, 0xf1, 0x17, 0xc1, 0xda, 0x8e, 0xd7, 0x96, @@ -63,7 +63,7 @@ static const uint8_t PubkeyQx_P521[] = { 0xd5, 0xc4, }; -static const uint8_t PubkeyQy_P521[] = { +static const uint8_t pubkey_qy_p521[] = { 0x01, 0x64, 0x35, 0x0c, 0x32, 0x1a, 0xec, 0xfc, 0x1c, 0xca, 0x1b, 0xa4, 0x36, 0x4c, 0x9b, 0x15, 0x65, 0x61, 0x50, 0xb4, 0xb7, 0x8d, 0x6a, 0x48, @@ -76,21 +76,21 @@ static const uint8_t PubkeyQy_P521[] = { }; /* Signature */ -static const uint8_t SignR_P256[] = { +static const uint8_t sign_r_p256[] = { 0x2b, 0x42, 0xf5, 0x76, 0xd0, 0x7f, 0x41, 0x65, 0xff, 0x65, 0xd1, 0xf3, 0xb1, 0x50, 0x0f, 0x81, 0xe4, 0x4c, 0x31, 0x6f, 0x1f, 0x0b, 0x3e, 0xf5, 0x73, 0x25, 0xb6, 0x9a, 0xca, 0x46, 0x10, 0x4f, }; -static const uint8_t SignS_P256[] = { +static const uint8_t sign_s_p256[] = { 0xdc, 0x42, 0xc2, 0x12, 0x2d, 0x63, 0x92, 0xcd, 0x3e, 0x3a, 0x99, 0x3a, 0x89, 0x50, 0x2a, 0x81, 0x98, 0xc1, 0x88, 0x6f, 0xe6, 0x9d, 0x26, 0x2c, 0x4b, 0x32, 0x9b, 0xdb, 0x6b, 0x63, 0xfa, 0xf1, }; -static const uint8_t SignR_P384[] = { +static const uint8_t sign_r_p384[] = { 0x30, 0xea, 0x51, 0x4f, 0xc0, 0xd3, 0x8d, 0x82, 0x08, 0x75, 0x6f, 0x06, 0x81, 0x13, 0xc7, 0xca, 0xda, 0x9f, 0x66, 0xa3, 0xb4, 0x0e, 0xa3, 0xb3, @@ -99,7 +99,7 @@ static const uint8_t SignR_P384[] = { 0xfc, 0xef, 0x9f, 0xaf, 0x01, 0xa2, 0x70, 0x88, }; -static const uint8_t SignS_P384[] = { +static const uint8_t sign_s_p384[] = { 0xcc, 0x80, 0x8e, 0x50, 0x4b, 0xe4, 0x14, 0xf4, 0x6c, 0x90, 0x27, 0xbc, 0xbf, 0x78, 0xad, 0xf0, 0x67, 0xa4, 0x39, 0x22, 0xd6, 0xfc, 0xaa, 0x66, @@ -108,7 +108,7 @@ static const uint8_t SignS_P384[] = { 0x82, 0x1c, 0x46, 0xd5, 0x49, 0x68, 0x3a, 0xd8, }; -static const uint8_t SignR_P521[] = { +static const uint8_t sign_r_p521[] = { 0x01, 0x40, 0xc8, 0xed, 0xca, 0x57, 0x10, 0x8c, 0xe3, 0xf7, 0xe7, 0xa2, 0x40, 0xdd, 0xd3, 0xad, 0x74, 0xd8, 0x1e, 0x2d, 0xe6, 0x24, 0x51, 0xfc, @@ -120,7 +120,7 @@ static const uint8_t SignR_P521[] = { 0xe2, 0xba, }; -static const uint8_t SignS_P521[] = { +static const uint8_t sign_s_p521[] = { 0x00, 0xb2, 0x51, 0x88, 0x49, 0x2d, 0x58, 0xe8, 0x08, 0xed, 0xeb, 0xd7, 0xbf, 0x44, 0x0e, 0xd2, 0x0d, 0xb7, 0x71, 0xca, 0x7c, 0x61, 0x85, 0x95, @@ -132,14 +132,14 @@ static const uint8_t SignS_P521[] = { 0xad, 0xbf, }; -static const uint8_t D_P256[] = { +static const uint8_t d_p256[] = { 0xc4, 0x77, 0xf9, 0xf6, 0x5c, 0x22, 0xcc, 0xe2, 0x06, 0x57, 0xfa, 0xa5, 0xb2, 0xd1, 0xd8, 0x12, 0x23, 0x36, 0xf8, 0x51, 0xa5, 0x08, 0xa1, 0xed, 0x04, 0xe4, 0x79, 0xc3, 0x49, 0x85, 0xbf, 0x96, }; -static const uint8_t D_P384[] = { +static const uint8_t d_p384[] = { 0xf9, 0x2c, 0x02, 0xed, 0x62, 0x9e, 0x4b, 0x48, 0xc0, 0x58, 0x4b, 0x1c, 0x6c, 0xe3, 0xa3, 0xe3, 0xb4, 0xfa, 0xae, 0x4a, 0xfc, 0x6a, 0xcb, 0x04, @@ -148,7 +148,7 @@ static const uint8_t D_P384[] = { 0xd1, 0x22, 0x4b, 0x57, 0xd8, 0x3f, 0x8a, 0x08, }; -static const uint8_t D_P521[] = { +static const uint8_t d_p521[] = { 0x01, 0x00, 0x08, 0x5f, 0x47, 0xb8, 0xe1, 0xb8, 0xb1, 0x1b, 0x7e, 0xb3, 0x30, 0x28, 0xc0, 0xb2, 0x88, 0x8e, 0x30, 0x4b, 0xfc, 0x98, 0x50, 0x19, @@ -160,14 +160,14 @@ static const uint8_t D_P521[] = { 0x17, 0x22, }; -static const uint8_t K_P256[] = { +static const uint8_t k_p256[] = { 0x7a, 0x1a, 0x7e, 0x52, 0x79, 0x7f, 0xc8, 0xca, 0xaa, 0x43, 0x5d, 0x2a, 0x4d, 0xac, 0xe3, 0x91, 0x58, 0x50, 0x4b, 0xf2, 0x04, 0xfb, 0xe1, 0x9f, 0x14, 0xdb, 0xb4, 0x27, 0xfa, 0xee, 0x50, 0xae, }; -static const uint8_t K_P384[] = { +static const uint8_t k_p384[] = { 0x2e, 0x44, 0xef, 0x1f, 0x8c, 0x0b, 0xea, 0x83, 0x94, 0xe3, 0xdd, 0xa8, 0x1e, 0xc6, 0xa7, 0x84, 0x2a, 0x45, 0x9b, 0x53, 0x47, 0x01, 0x74, 0x9e, @@ -176,7 +176,7 @@ static const uint8_t K_P384[] = { 0xed, 0xca, 0xe0, 0x6c, 0xc2, 0xf4, 0x3f, 0xef, }; -static const uint8_t K_P521[] = { +static const uint8_t k_p521[] = { 0x00, 0x00, 0xc9, 0x1e, 0x23, 0x49, 0xef, 0x6c, 0xa2, 0x2d, 0x2d, 0xe3, 0x9d, 0xd5, 0x18, 0x19, 0xb6, 0xaa, 0xd9, 0x22, 0xd3, 0xae, 0xcd, 0xea, @@ -188,14 +188,14 @@ static const uint8_t K_P521[] = { 0xd6, 0xbf, }; -static const uint8_t H_P256[] = { +static const uint8_t h_p256[] = { 0xa4, 0x1a, 0x41, 0xa1, 0x2a, 0x79, 0x95, 0x48, 0x21, 0x1c, 0x41, 0x0c, 0x65, 0xd8, 0x13, 0x3a, 0xfd, 0xe3, 0x4d, 0x28, 0xbd, 0xd5, 0x42, 0xe4, 0xb6, 0x80, 0xcf, 0x28, 0x99, 0xc8, 0xa8, 0xc4, }; -static const uint8_t H_P384[] = { +static const uint8_t h_p384[] = { 0x5a, 0xea, 0x18, 0x7d, 0x1c, 0x4f, 0x6e, 0x1b, 0x35, 0x05, 0x7d, 0x20, 0x12, 0x6d, 0x83, 0x6c, 0x6a, 0xdb, 0xbc, 0x70, 0x49, 0xee, 0x02, 0x99, @@ -204,7 +204,7 @@ static const uint8_t H_P384[] = { 0x2b, 0x8a, 0xf7, 0x0e, 0x0a, 0x78, 0x1e, 0x89, }; -static const uint8_t H_P521[] = { +static const uint8_t h_p521[] = { 0x00, 0x00, 0xef, 0x88, 0xfb, 0x5a, 0xc0, 0x1f, 0x35, 0xf5, 0xcb, 0x8a, 0x1b, 0x00, 0x8e, 0x80, 0x11, 0x46, 0xc1, 0x39, 0x83, 0xcf, 0x8c, 0x2c, @@ -219,44 +219,43 @@ static const uint8_t H_P521[] = { static TEE_Result versal_ecc_sign_kat(uint32_t curve) { TEE_Result ret = TEE_SUCCESS; - size_t bytes; - size_t bits; - struct ecc_keypair key; - struct ecc_keypair ephemeral; - - uint32_t algo; - uint8_t *D; - uint8_t *K; - uint8_t *SignR; - uint8_t *SignS; - uint8_t *hash; - uint8_t sig[(TEE_SHA512_HASH_SIZE + 2) * 2]; + size_t bytes = 0; + size_t bits = 0; + struct ecc_keypair key = { }; + struct ecc_keypair ephemeral = { }; + uint32_t algo = 0; + const uint8_t *d = NULL; + const uint8_t *k = NULL; + const uint8_t *sign_r = NULL; + const uint8_t *sign_s = NULL; + const uint8_t *hash = NULL; + uint8_t sig[(TEE_SHA512_HASH_SIZE + 2) * 2] = { }; size_t sig_len = 0; switch (curve) { case TEE_ECC_CURVE_NIST_P256: algo = TEE_ALG_ECDSA_SHA256; - D = (uint8_t *)D_P256; - K = (uint8_t *)K_P256; - SignR = (uint8_t *)SignR_P256; - SignS = (uint8_t *)SignS_P256; - hash = (uint8_t *)H_P256; + d = d_p256; + k = k_p256; + sign_r = sign_r_p256; + sign_s = sign_s_p256; + hash = h_p256; break; case TEE_ECC_CURVE_NIST_P384: algo = TEE_ALG_ECDSA_SHA384; - D = (uint8_t *)D_P384; - K = (uint8_t *)K_P384; - SignR = (uint8_t *)SignR_P384; - SignS = (uint8_t *)SignS_P384; - hash = (uint8_t *)H_P384; + d = d_p384; + k = k_p384; + sign_r = sign_r_p384; + sign_s = sign_s_p384; + hash = h_p384; break; case TEE_ECC_CURVE_NIST_P521: algo = TEE_ALG_ECDSA_SHA512; - D = (uint8_t *)D_P521; - K = (uint8_t *)K_P521; - SignR = (uint8_t *)SignR_P521; - SignS = (uint8_t *)SignS_P521; - hash = (uint8_t *)H_P521; + d = d_p521; + k = k_p521; + sign_r = sign_r_p521; + sign_s = sign_s_p521; + hash = h_p521; break; default: return TEE_ERROR_NOT_SUPPORTED; @@ -272,7 +271,7 @@ static TEE_Result versal_ecc_sign_kat(uint32_t curve) return ret; key.curve = curve; - ret = crypto_bignum_bin2bn(D, bytes, key.d); + ret = crypto_bignum_bin2bn(d, bytes, key.d); if (ret) goto end; @@ -282,7 +281,7 @@ static TEE_Result versal_ecc_sign_kat(uint32_t curve) if (ret) goto end; - ret = crypto_bignum_bin2bn(K, bytes, ephemeral.d); + ret = crypto_bignum_bin2bn(k, bytes, ephemeral.d); if (ret) goto endk; @@ -291,8 +290,8 @@ static TEE_Result versal_ecc_sign_kat(uint32_t curve) bytes, sig, &sig_len); if (ret == TEE_SUCCESS) { /* Check generated signature */ - if ((memcmp((uint8_t *)sig, SignR, bytes) != 0) || - (memcmp((uint8_t *)sig + bytes, SignS, bytes) != 0)) + if ((memcmp((uint8_t *)sig, sign_r, bytes) != 0) || + (memcmp((uint8_t *)sig + bytes, sign_s, bytes) != 0)) ret = TEE_ERROR_SIGNATURE_INVALID; } @@ -311,42 +310,41 @@ static TEE_Result versal_ecc_sign_kat(uint32_t curve) static TEE_Result versal_ecc_verify_kat(uint32_t curve) { TEE_Result ret = TEE_SUCCESS; - size_t bytes; - size_t bits; - struct ecc_public_key pkey; - - uint32_t algo; - uint8_t *Qx; - uint8_t *Qy; - uint8_t *SignR; - uint8_t *SignS; - uint8_t *hash; - uint8_t sig[(TEE_SHA512_HASH_SIZE + 2) * 2]; + size_t bytes = 0; + size_t bits = 0; + struct ecc_public_key pkey = { }; + uint32_t algo = 0; + const uint8_t *qx = NULL; + const uint8_t *qy = NULL; + const uint8_t *sign_r = NULL; + const uint8_t *sign_s = NULL; + const uint8_t *hash = NULL; + uint8_t sig[(TEE_SHA512_HASH_SIZE + 2) * 2] = { }; switch (curve) { case TEE_ECC_CURVE_NIST_P256: algo = TEE_ALG_ECDSA_SHA256; - Qx = (uint8_t *)PubkeyQx_P256; - Qy = (uint8_t *)PubkeyQy_P256; - SignR = (uint8_t *)SignR_P256; - SignS = (uint8_t *)SignS_P256; - hash = (uint8_t *)H_P256; + qx = pubkey_qx_p256; + qy = pubkey_qy_p256; + sign_r = sign_r_p256; + sign_s = sign_s_p256; + hash = h_p256; break; case TEE_ECC_CURVE_NIST_P384: algo = TEE_ALG_ECDSA_SHA384; - Qx = (uint8_t *)PubkeyQx_P384; - Qy = (uint8_t *)PubkeyQy_P384; - SignR = (uint8_t *)SignR_P384; - SignS = (uint8_t *)SignS_P384; - hash = (uint8_t *)H_P384; + qx = pubkey_qx_p384; + qy = pubkey_qy_p384; + sign_r = sign_r_p384; + sign_s = sign_s_p384; + hash = h_p384; break; case TEE_ECC_CURVE_NIST_P521: algo = TEE_ALG_ECDSA_SHA512; - Qx = (uint8_t *)PubkeyQx_P521; - Qy = (uint8_t *)PubkeyQy_P521; - SignR = (uint8_t *)SignR_P521; - SignS = (uint8_t *)SignS_P521; - hash = (uint8_t *)H_P521; + qx = pubkey_qx_p521; + qy = pubkey_qy_p521; + sign_r = sign_r_p521; + sign_s = sign_s_p521; + hash = h_p521; break; default: return TEE_ERROR_NOT_SUPPORTED; @@ -363,16 +361,16 @@ static TEE_Result versal_ecc_verify_kat(uint32_t curve) return ret; pkey.curve = curve; - ret = crypto_bignum_bin2bn(Qx, bytes, pkey.x); + ret = crypto_bignum_bin2bn(qx, bytes, pkey.x); if (ret) goto end; - ret = crypto_bignum_bin2bn(Qy, bytes, pkey.y); + ret = crypto_bignum_bin2bn(qy, bytes, pkey.y); if (ret) goto end; /* Prepare signature to verify */ - memcpy((uint8_t *)sig, SignR, bytes); - memcpy((uint8_t *)sig + bytes, SignS, bytes); + memcpy((uint8_t *)sig, sign_r, bytes); + memcpy((uint8_t *)sig + bytes, sign_s, bytes); /* Call PKI hW */ ret = versal_ecc_verify(algo, &pkey, hash, bytes, sig, 2 * bytes); @@ -383,7 +381,7 @@ static TEE_Result versal_ecc_verify_kat(uint32_t curve) return ret; } -TEE_Result versal_ecc_kat(void) +TEE_Result versal_ecc_kat_test(void) { TEE_Result ret = TEE_SUCCESS; @@ -417,13 +415,12 @@ TEE_Result versal_ecc_kat(void) #ifdef CFG_VERSAL_PKI_PWCT TEE_Result versal_ecc_keypair_pwct(struct ecc_keypair *s) { - struct ecc_public_key pkey; TEE_Result ret = TEE_SUCCESS; - - uint32_t algo; - size_t bytes; - size_t bits; - size_t len; + struct ecc_public_key pkey = { }; + uint32_t algo = 0; + size_t bytes = 0; + size_t bits = 0; + size_t len = 0; uint8_t msg[TEE_SHA512_HASH_SIZE + 2] = { }; uint8_t sig[(TEE_SHA512_HASH_SIZE + 2) * 2] = { }; From 5678e3c56b605835b6cd27a0b4a229ca526bc26e Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Thu, 20 Jun 2024 18:22:58 +0200 Subject: [PATCH 18/43] fixup! drivers: versal: rework mbox driver Signed-off-by: Jeremie Corbier --- core/drivers/versal_mbox.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/drivers/versal_mbox.c b/core/drivers/versal_mbox.c index 326f49a4107..28ddd13ea36 100644 --- a/core/drivers/versal_mbox.c +++ b/core/drivers/versal_mbox.c @@ -176,7 +176,6 @@ static const char *const nvm_id[] = { [33] = "EFUSE_READ_CACHE", [34] = "EFUSE_RELOAD_N_PRGM_PROT_BITS", [35] = "EFUSE_INVALID", - #else [6] = "EFUSE_WRITE", [7] = "EFUSE_WRITE_PUF", @@ -453,8 +452,7 @@ TEE_Result versal_mbox_notify(struct versal_ipi *ipi, } /* Trigger interrupt to remote */ - io_write32(ipi->regs + IPI_TRIG_OFFSET, - IPI_BIT_MASK(ipi->rmt)); + io_write32(ipi->regs + IPI_TRIG_OFFSET, IPI_BIT_MASK(ipi->rmt)); /* Wait for remote to acknowledge the interrupt */ if (IO_READ32_POLL_TIMEOUT(ipi->regs + IPI_OBR_OFFSET, status, @@ -485,7 +483,7 @@ static struct versal_ipi ipi_pmc; TEE_Result versal_mbox_notify_pmc(struct versal_ipi_cmd *cmd, struct versal_ipi_cmd *rsp, uint32_t *err) { - TEE_Result ret; + TEE_Result ret = TEE_SUCCESS; if (IS_ENABLED(CFG_VERSAL_TRACE_MBOX)) versal_mbox_call_trace(cmd->data[0]); From c1c7e6c3ef89c12c99cf1c23d80a84d57e34edee Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Thu, 20 Jun 2024 18:33:02 +0200 Subject: [PATCH 19/43] fixup! core: pta: add Versal FPGA PTA Signed-off-by: Jeremie Corbier --- core/pta/sub.mk | 2 +- core/pta/versal/fpga_pta.c | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/core/pta/sub.mk b/core/pta/sub.mk index f07171043f2..96337b8cac5 100644 --- a/core/pta/sub.mk +++ b/core/pta/sub.mk @@ -28,4 +28,4 @@ depends-rproc_pub_key = $(RPROC_SIGN_KEY) scripts/pem_to_pub_c.py recipe-rproc_pub_key = $(PYTHON3) scripts/pem_to_pub_c.py \ --prefix rproc_pub_key --key $(RPROC_SIGN_KEY) \ --out $(sub-dir-out)/rproc_pub_key.c -endif +endif \ No newline at end of file diff --git a/core/pta/versal/fpga_pta.c b/core/pta/versal/fpga_pta.c index 3fe6c92dd0d..79b2f169a13 100644 --- a/core/pta/versal/fpga_pta.c +++ b/core/pta/versal/fpga_pta.c @@ -15,8 +15,9 @@ static TEE_Result pta_versal_fpga_write(uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]) { - uint8_t *buf; - size_t bufsize; + TEE_Result ret = TEE_SUCCESS; + uint8_t *buf = NULL; + size_t bufsize = 0; uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, @@ -34,7 +35,11 @@ static TEE_Result pta_versal_fpga_write(uint32_t param_types, memcpy(buf, params[0].memref.buffer, bufsize); cache_operation(TEE_CACHEFLUSH, buf, bufsize); - return versal_write_fpga(virt_to_phys(buf)); + ret = versal_write_fpga(virt_to_phys(buf)); + + free(buf); + + return ret; } static TEE_Result invoke_command(void *sess_ctx __unused, From 79bfc5e42535a61ab5f4619603e5fed54b268cb6 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Thu, 20 Jun 2024 19:06:41 +0200 Subject: [PATCH 20/43] fixup! drivers: versal: NVM driver for Versal Net Signed-off-by: Jeremie Corbier --- core/drivers/versal_net_nvm.c | 99 +++++++++++++++++------------------ 1 file changed, 49 insertions(+), 50 deletions(-) diff --git a/core/drivers/versal_net_nvm.c b/core/drivers/versal_net_nvm.c index 667b32a9292..e204a1b3e69 100644 --- a/core/drivers/versal_net_nvm.c +++ b/core/drivers/versal_net_nvm.c @@ -8,21 +8,19 @@ #include #include #include +#include #include #include #include #include #include -#include - -#include "drivers/versal_nvm.h" #define NVM_WORD_LEN 4 /* Protocol API with the remote processor */ #define NVM_MODULE_SHIFT 8 #define NVM_MODULE 11 -#define NVM_API_ID(_id) ((NVM_MODULE << NVM_MODULE_SHIFT) | (_id)) +#define NVM_API_ID(_id) (SHIFT_U32(NVM_MODULE, NVM_MODULE_SHIFT) | (_id)) #define __aligned_efuse __aligned(CACHELINE_LEN) @@ -186,6 +184,7 @@ static void versal_free_read_buffer(struct versal_nvm_read_req *req) { assert(req); free(req->ibuf[0].buf); + req->ibuf[0].buf = NULL; } static void *versal_get_read_buffer(struct versal_nvm_read_req *req) @@ -466,7 +465,7 @@ TEE_Result versal_efuse_read_misc_ctrl(struct versal_efuse_misc_ctrl_bits *buf) return TEE_ERROR_BAD_PARAMETERS; ret = versal_efuse_read_cache(EFUSE_CACHE_MISC_CTRL_OFFSET, 1, - &misc_ctrl, sizeof(uint32_t)); + &misc_ctrl, sizeof(misc_ctrl)); if (ret) return ret; @@ -493,7 +492,7 @@ TEE_Result versal_efuse_read_sec_ctrl(struct versal_efuse_sec_ctrl_bits *buf) return TEE_ERROR_BAD_PARAMETERS; ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_CTRL_OFFSET, 1, - &sec_ctrl, sizeof(uint32_t)); + &sec_ctrl, sizeof(sec_ctrl)); if (ret) return ret; @@ -526,7 +525,7 @@ TEE_Result versal_efuse_read_sec_misc1(struct versal_efuse_sec_misc1_bits *buf) return TEE_ERROR_BAD_PARAMETERS; ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_MISC1_OFFSET, 1, - &sec_misc1, sizeof(uint32_t)); + &sec_misc1, sizeof(sec_misc1)); if (ret) return ret; @@ -549,7 +548,7 @@ versal_efuse_read_boot_env_ctrl(struct versal_efuse_boot_env_ctrl_bits *buf) return TEE_ERROR_BAD_PARAMETERS; ret = versal_efuse_read_cache(EFUSE_CACHE_BOOT_ENV_CTRL_OFFSET, 1, - &boot_env_ctrl, sizeof(uint32_t)); + &boot_env_ctrl, sizeof(boot_env_ctrl)); if (ret) return ret; @@ -585,7 +584,7 @@ TEE_Result versal_efuse_read_dec_only(uint32_t *buf, size_t len) return TEE_ERROR_BAD_PARAMETERS; ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_MISC0_OFFSET, 1, - &sec_misc0, sizeof(uint32_t)); + &sec_misc0, sizeof(sec_misc0)); if (ret) return ret; @@ -607,7 +606,7 @@ TEE_Result versal_efuse_read_puf_sec_ctrl(struct versal_efuse_puf_sec_ctrl_bits return TEE_ERROR_BAD_PARAMETERS; ret = versal_efuse_read_cache(EFUSE_CACHE_PUF_ECC_CTRL_OFFSET, 1, - &puf_ctrl, sizeof(uint32_t)); + &puf_ctrl, sizeof(puf_ctrl)); if (ret) return ret; @@ -615,7 +614,7 @@ TEE_Result versal_efuse_read_puf_sec_ctrl(struct versal_efuse_puf_sec_ctrl_bits * Some fuses have moved from PUF_ECC_CTRL to SECURITY_CTRL */ ret = versal_efuse_read_cache(EFUSE_CACHE_SEC_CTRL_OFFSET, 1, - &sec_ctrl, sizeof(uint32_t)); + &sec_ctrl, sizeof(sec_ctrl)); if (ret) return ret; @@ -877,22 +876,22 @@ TEE_Result versal_efuse_write_sec(struct versal_efuse_sec_ctrl_bits *p) if (!p) return TEE_ERROR_BAD_PARAMETERS; - val = ((p->reg_init_dis & 0x3) << 30) | - ((p->boot_env_wr_lk & 0x1) << 28) | - ((p->sec_lock_dbg_dis & 0x3) << 21) | - ((p->sec_dbg_dis & 0x3) << 19) | - ((p->user_key1_wr_lk & 0x1) << 15) | - ((p->user_key1_crc_lk & 0x1) << 14) | - ((p->user_key0_wr_lk & 0x1) << 13) | - ((p->user_key0_crc_lk & 0x1) << 12) | - ((p->aes_wr_lk & 0x1) << 11) | - ((p->aes_crc_lk & 0x3) << 9) | - ((p->ppk2_wr_lk & 0x1) << 8) | - ((p->ppk1_wr_lk & 0x1) << 7) | - ((p->ppk0_wr_lk & 0x1) << 6) | - ((p->jtag_dis & 0x1) << 2) | - ((p->jtag_err_out_dis & 0x1) << 1) | - (p->aes_dis & 0x1); + val = SHIFT_U32(p->reg_init_dis & 0x3, 30) | + SHIFT_U32(p->boot_env_wr_lk & 0x1, 28) | + SHIFT_U32(p->sec_lock_dbg_dis & 0x3, 21) | + SHIFT_U32(p->sec_dbg_dis & 0x3, 19) | + SHIFT_U32(p->user_key1_wr_lk & 0x1, 15) | + SHIFT_U32(p->user_key1_crc_lk & 0x1, 14) | + SHIFT_U32(p->user_key0_wr_lk & 0x1, 13) | + SHIFT_U32(p->user_key0_crc_lk & 0x1, 12) | + SHIFT_U32(p->aes_wr_lk & 0x1, 11) | + SHIFT_U32(p->aes_crc_lk & 0x3, 9) | + SHIFT_U32(p->ppk2_wr_lk & 0x1, 8) | + SHIFT_U32(p->ppk1_wr_lk & 0x1, 7) | + SHIFT_U32(p->ppk0_wr_lk & 0x1, 6) | + SHIFT_U32(p->jtag_dis & 0x1, 2) | + SHIFT_U32(p->jtag_err_out_dis & 0x1, 1) | + (p->aes_dis & 0x1); return do_write_efuses_value(EFUSE_WRITE_SEC_CTRL_BITS, val); } @@ -904,16 +903,16 @@ TEE_Result versal_efuse_write_misc(struct versal_efuse_misc_ctrl_bits *p) if (!p) return TEE_ERROR_BAD_PARAMETERS; - val = ((p->glitch_det_halt_boot_en & 0x3) << 30) | - ((p->glitch_det_rom_monitor_en & 0x1) << 29) | - ((p->halt_boot_error & 0x3) << 21) | - ((p->halt_boot_env & 0x3) << 19) | - ((p->crypto_kat_en & 0x1) << 15) | - ((p->lbist_en & 0x1) << 14) | - ((p->safety_mission_en & 0x1) << 8) | - ((p->ppk2_invalid & 0x3) << 6) | - ((p->ppk1_invalid & 0x3) << 4) | - ((p->ppk0_invalid & 0x3) << 2); + val = SHIFT_U32(p->glitch_det_halt_boot_en & 0x3, 30) | + SHIFT_U32(p->glitch_det_rom_monitor_en & 0x1, 29) | + SHIFT_U32(p->halt_boot_error & 0x3, 21) | + SHIFT_U32(p->halt_boot_env & 0x3, 19) | + SHIFT_U32(p->crypto_kat_en & 0x1, 15) | + SHIFT_U32(p->lbist_en & 0x1, 14) | + SHIFT_U32(p->safety_mission_en & 0x1, 8) | + SHIFT_U32(p->ppk2_invalid & 0x3, 6) | + SHIFT_U32(p->ppk1_invalid & 0x3, 4) | + SHIFT_U32(p->ppk0_invalid & 0x3, 2); return do_write_efuses_value(EFUSE_WRITE_MISC_CTRL_BITS, val); } @@ -929,7 +928,7 @@ versal_efuse_write_glitch_cfg(struct versal_efuse_glitch_cfg_bits *p) if (!p->prgm_glitch) return TEE_SUCCESS; - val = ((p->glitch_det_wr_lk & 0x1) << 31) | p->glitch_det_trim; + val = SHIFT_U32(p->glitch_det_wr_lk & 0x1, 31) | p->glitch_det_trim; return do_write_efuses_value(EFUSE_WRITE_GLITCH_CONFIG, val); } @@ -942,13 +941,13 @@ versal_efuse_write_boot_env(struct versal_efuse_boot_env_ctrl_bits *p) if (!p) return TEE_ERROR_BAD_PARAMETERS; - val = ((p->sysmon_temp_en & 0x1) << 21) | - ((p->sysmon_volt_en & 0x1) << 20) | - ((p->sysmon_temp_hot & 0x3) << 17) | - ((p->sysmon_volt_pmc & 0x3) << 12) | - ((p->sysmon_volt_pslp & 0x3) << 10) | - ((p->sysmon_volt_soc & 0x3) << 8) | - (p->sysmon_temp_cold & 0x2); + val = SHIFT_U32(p->sysmon_temp_en & 0x1, 21) | + SHIFT_U32(p->sysmon_volt_en & 0x1, 20) | + SHIFT_U32(p->sysmon_temp_hot & 0x3, 17) | + SHIFT_U32(p->sysmon_volt_pmc & 0x3, 12) | + SHIFT_U32(p->sysmon_volt_pslp & 0x3, 10) | + SHIFT_U32(p->sysmon_volt_soc & 0x3, 8) | + (p->sysmon_temp_cold & 0x2); return do_write_efuses_value(EFUSE_WRITE_BOOT_ENV_CTRL_BITS, val); } @@ -960,11 +959,11 @@ TEE_Result versal_efuse_write_sec_misc1(struct versal_efuse_sec_misc1_bits *p) if (!p) return TEE_ERROR_BAD_PARAMETERS; - val = ((p->lpd_mbist_en & 0x7) << 10) | - ((p->pmc_mbist_en & 0x7) << 7) | - ((p->lpd_noc_sc_en & 0x7) << 4) | - ((p->sysmon_volt_mon_en & 0x3) << 2) | - (p->sysmon_temp_mon_en & 0x3); + val = SHIFT_U32(p->lpd_mbist_en & 0x7, 10) | + SHIFT_U32(p->pmc_mbist_en & 0x7, 7) | + SHIFT_U32(p->lpd_noc_sc_en & 0x7, 4) | + SHIFT_U32(p->sysmon_volt_mon_en & 0x3, 2) | + (p->sysmon_temp_mon_en & 0x3); return do_write_efuses_value(EFUSE_WRITE_MISC1_CTRL_BITS, val); } From b43fb2799ba4e3ea6361baf8f0a951433c7a2bb2 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Thu, 20 Jun 2024 19:13:33 +0200 Subject: [PATCH 21/43] fixup! drivers: versal: NVM driver for Versal Net Signed-off-by: Jeremie Corbier --- core/drivers/versal_huk.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/drivers/versal_huk.c b/core/drivers/versal_huk.c index f42866da4d7..1ccc7b1e0e3 100644 --- a/core/drivers/versal_huk.c +++ b/core/drivers/versal_huk.c @@ -333,11 +333,11 @@ TEE_Result tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey) if (huk.ready) goto out; -#ifndef CFG_VERSAL_DUMMY_DNA +#ifdef CFG_VERSAL_DUMMY_DNA + memcpy(dna, dummy_dna, EFUSE_DNA_LEN); +#else if (versal_efuse_read_dna(dna, sizeof(dna))) return TEE_ERROR_GENERIC; -#else - memcpy(dna, dummy_dna, EFUSE_DNA_LEN); #endif if (versal_sha3_384((uint8_t *)dna, sizeof(dna), sha, sizeof(sha))) { From dc39a16cbd2e8932d511210bca8666d1b3cf839d Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Fri, 28 Jun 2024 16:44:59 +0200 Subject: [PATCH 22/43] fixup! drivers: versal: NVM driver for Versal Net Signed-off-by: Jeremie Corbier --- core/drivers/versal_net_nvm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/drivers/versal_net_nvm.c b/core/drivers/versal_net_nvm.c index e204a1b3e69..82755759c5d 100644 --- a/core/drivers/versal_net_nvm.c +++ b/core/drivers/versal_net_nvm.c @@ -970,7 +970,7 @@ TEE_Result versal_efuse_write_sec_misc1(struct versal_efuse_sec_misc1_bits *p) TEE_Result versal_efuse_write_offchip_ids(uint32_t id) { - return do_write_efuses_value(EFUSE_WRITE_OFFCHIP_REVOKE_ID, id); + return do_write_efuses_value(EFUSE_WRITE_OFFCHIP_REVOKE_ID, id + 1); } TEE_Result versal_efuse_write_revoke_ppk(enum versal_nvm_ppk_type type) From 02325face6a51dbf3bdf232893a68b8ebb03a7f7 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 14 Aug 2024 11:57:26 +0200 Subject: [PATCH 23/43] fixup! drivers: versal: PKI engine driver for Versal Net Signed-off-by: Jeremie Corbier --- core/drivers/crypto/versal/ecc.c | 11 ++++-- core/drivers/crypto/versal/ecc_mbox.c | 31 +++++++--------- core/drivers/crypto/versal/include/ecc.h | 4 +- .../crypto/versal/pki/ecc_pki_engine.c | 37 ++++++++++--------- 4 files changed, 43 insertions(+), 40 deletions(-) diff --git a/core/drivers/crypto/versal/ecc.c b/core/drivers/crypto/versal/ecc.c index b2e47b95b9e..43b284459fd 100644 --- a/core/drivers/crypto/versal/ecc.c +++ b/core/drivers/crypto/versal/ecc.c @@ -57,7 +57,7 @@ void memcpy_swp(uint8_t *to, const uint8_t *from, size_t len) } void versal_crypto_bignum_bn2bin_eswap(uint32_t curve, struct bignum *from, - uint8_t *to) + uint8_t *to) { uint8_t pad[66] = { 0 }; size_t len = crypto_bignum_num_bytes(from); @@ -72,7 +72,7 @@ void versal_crypto_bignum_bn2bin_eswap(uint32_t curve, struct bignum *from, } void versal_crypto_bignum_bin2bn_eswap(const uint8_t *from, size_t sz, - struct bignum *to) + struct bignum *to) { uint8_t pad[66] = { 0 }; @@ -146,7 +146,7 @@ static TEE_Result do_sign(struct drvcrypt_sign_data *sdata) static TEE_Result do_verify(struct drvcrypt_sign_data *sdata) { - TEE_Result ret; + TEE_Result ret = TEE_SUCCESS; ret = versal_ecc_verify(sdata->algo, sdata->key, @@ -175,6 +175,9 @@ static TEE_Result do_gen_keypair(struct ecc_keypair *s, size_t size_bits) return pair_ops->generate(s, size_bits); #ifdef CFG_VERSAL_PKI_PWCT + if (ret != TEE_SUCCESS) + return ret; + /* Perform a pairwise consistencty test on the generated key pair */ ret = versal_ecc_keypair_pwct(s); if (ret) @@ -249,7 +252,7 @@ static struct drvcrypt_ecc driver_ecc = { static TEE_Result ecc_init(void) { - TEE_Result ret; + TEE_Result ret = TEE_SUCCESS; /* HW initialization if needed */ ret = versal_ecc_hw_init(); diff --git a/core/drivers/crypto/versal/ecc_mbox.c b/core/drivers/crypto/versal/ecc_mbox.c index 91ba5fe1709..bce5379cca2 100644 --- a/core/drivers/crypto/versal/ecc_mbox.c +++ b/core/drivers/crypto/versal/ecc_mbox.c @@ -4,22 +4,22 @@ * Author: Jorge Ramirez */ +#include +#include #include #include -#include +#include #include #include -#include -#include +#include #include +#include #include #include #include #include #include #include -#include -#include enum versal_ecc_err { KAT_KEY_NOTVALID_ERROR = 0xC0, @@ -207,19 +207,19 @@ TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key, TEE_TYPE_ECDSA_KEYPAIR, bits); if (ret) { EMSG("Versal, can't allocate the ephemeral key"); - goto out1; + goto out; } ephemeral.curve = key->curve; ret = crypto_acipher_gen_ecc_key(&ephemeral, bits); if (ret) { EMSG("Versal, can't generate the ephemeral key"); - goto out1; + goto out; } ret = versal_mbox_alloc(bytes, NULL, &k); if (ret) - goto out1; + goto out; versal_crypto_bignum_bn2bin_eswap(key->curve, ephemeral.d, k.buf); crypto_bignum_free(&ephemeral.d); @@ -229,18 +229,18 @@ TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key, /* Private key*/ ret = versal_mbox_alloc(bytes, NULL, &d); if (ret) - goto out2; + goto out; versal_crypto_bignum_bn2bin_eswap(key->curve, key->d, d.buf); /* Signature */ ret = versal_mbox_alloc(*sig_len, NULL, &s); if (ret) - goto out3; + goto out; /* IPI command */ ret = versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf); if (ret) - goto out4; + goto out; cmd = cmd_buf.buf; cmd->priv_key_addr = virt_to_phys(d.buf); @@ -258,7 +258,7 @@ TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key, if (versal_crypto_request(VERSAL_ELLIPTIC_GENERATE_SIGN, &arg, &err)) { EMSG("Versal ECC: %s", versal_ecc_error(err)); ret = TEE_ERROR_GENERIC; - goto error; + goto out; } *sig_len = 2 * bytes; @@ -267,15 +267,12 @@ TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key, memcpy_swp(sig, s.buf, *sig_len / 2); memcpy_swp(sig + *sig_len / 2, (uint8_t *)s.buf + *sig_len / 2, *sig_len / 2); -error: + +out: versal_mbox_free(&cmd_buf); -out4: versal_mbox_free(&s); -out3: versal_mbox_free(&d); -out2: versal_mbox_free(&k); -out1: versal_mbox_free(&p); return ret; diff --git a/core/drivers/crypto/versal/include/ecc.h b/core/drivers/crypto/versal/include/ecc.h index 4a6f0ca1685..fc9bd515727 100644 --- a/core/drivers/crypto/versal/include/ecc.h +++ b/core/drivers/crypto/versal/include/ecc.h @@ -31,8 +31,8 @@ TEE_Result versal_ecc_sign_ephemeral(uint32_t algo, size_t bytes, void memcpy_swp(uint8_t *to, const uint8_t *from, size_t len); void versal_crypto_bignum_bn2bin_eswap(uint32_t curve, struct bignum *from, - uint8_t *to); + uint8_t *to); void versal_crypto_bignum_bin2bn_eswap(const uint8_t *from, size_t sz, - struct bignum *to); + struct bignum *to); #endif diff --git a/core/drivers/crypto/versal/pki/ecc_pki_engine.c b/core/drivers/crypto/versal/pki/ecc_pki_engine.c index eb55fc23f06..e07cb530e2d 100644 --- a/core/drivers/crypto/versal/pki/ecc_pki_engine.c +++ b/core/drivers/crypto/versal/pki/ecc_pki_engine.c @@ -49,7 +49,7 @@ static TEE_Result versal_ecc_trng_init(void) .predict_en = false, .df_disable = false, .dfmul = CFG_VERSAL_TRNG_DF_MUL, - .iseed_en = false, + .iseed_en = false, .pstr_en = true, }; @@ -159,7 +159,7 @@ static struct versal_pki versal_pki; #define PKI_SIGN_P521_PADD_BYTES 2 #define PKI_VERIFY_P521_PADD_BYTES 6 -#define PKI_DEFAULT_REQID 0xB04EU +#define PKI_DEFAULT_REQID UINT16_C(0xB04EU) #define PKI_EXPECTED_CQ_STATUS 0 #define PKI_EXPECTED_CQ_VALUE (SHIFT_U32(PKI_DEFAULT_REQID, 16) | 0x1) @@ -167,7 +167,7 @@ static struct versal_pki versal_pki; #define PKI_RESET_DELAY_US 10 static TEE_Result pki_get_opsize(uint32_t curve, uint32_t op, size_t *in_sz, - size_t *out_sz) + size_t *out_sz) { TEE_Result ret = TEE_SUCCESS; size_t bits = 0; @@ -250,7 +250,6 @@ static TEE_Result pki_build_descriptors(uint32_t curve, uint32_t op, static TEE_Result pki_start_operation(uint32_t reqval) { - TEE_Result ret = TEE_ERROR_TIMEOUT; uint32_t retries = PKI_MAX_RETRY_COUNT; /* Soft reset */ @@ -294,12 +293,11 @@ static TEE_Result pki_start_operation(uint32_t reqval) io_write64(versal_pki.regs + PKI_CRYPTO_IRQ_RESET_OFFSET, PKI_IRQ_DONE_STATUS_VAL); - ret = TEE_SUCCESS; - break; + return TEE_SUCCESS; } } - return ret; + return TEE_ERROR_TIMEOUT; } static TEE_Result pki_check_status(void) @@ -327,30 +325,31 @@ TEE_Result versal_ecc_verify(uint32_t algo, struct ecc_public_key *key, size_t bits = 0; size_t bytes = 0; size_t len = 0; - uintptr_t addr = (uintptr_t)versal_pki.rq_in; + uint8_t *addr = versal_pki.rq_in; + uint32_t descriptors[8] = { }; ret = versal_ecc_get_key_size(key->curve, &bytes, &bits); if (ret) return ret; /* Copy public key */ - versal_crypto_bignum_bn2bin_eswap(key->curve, key->x, (uint8_t *)addr); + versal_crypto_bignum_bn2bin_eswap(key->curve, key->x, addr); addr += bytes; - versal_crypto_bignum_bn2bin_eswap(key->curve, key->y, (uint8_t *)addr); + versal_crypto_bignum_bn2bin_eswap(key->curve, key->y, addr); addr += bytes; /* Copy signature */ - memcpy_swp((uint8_t *)addr, sig, sig_len / 2); + memcpy_swp(addr, sig, sig_len / 2); addr += sig_len / 2; - memcpy_swp((uint8_t *)addr, sig + sig_len / 2, sig_len / 2); + memcpy_swp(addr, sig + sig_len / 2, sig_len / 2); addr += sig_len / 2; /* Copy hash */ - ret = versal_ecc_prepare_msg(algo, msg, msg_len, &len, (uint8_t *)addr); + ret = versal_ecc_prepare_msg(algo, msg, msg_len, &len, addr); if (ret) return ret; if (len < bytes) - memset((uint8_t *)addr + len, 0, bytes - len); + memset(addr + len, 0, bytes - len); addr += bytes; if (key->curve == TEE_ECC_CURVE_NIST_P521) { @@ -359,12 +358,15 @@ TEE_Result versal_ecc_verify(uint32_t algo, struct ecc_public_key *key, } /* Build descriptors */ + if (!IS_ALIGNED_WITH_TYPE(addr, uint32_t)) + return TEE_ERROR_BAD_PARAMETERS; + ret = pki_build_descriptors(key->curve, PKI_DESC_OPTYPE_ECDSA_VERIFY, - (uint32_t *)addr); + descriptors); if (ret) return ret; - ret = pki_start_operation(PKI_NEW_REQUEST_MASK & (addr + 1)); + ret = pki_start_operation(PKI_NEW_REQUEST_MASK & ((uintptr_t)addr + 1)); if (ret) return ret; @@ -823,7 +825,8 @@ TEE_Result versal_ecc_hw_init(void) return ret; versal_pki.regs = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, - FPD_PKI_CRYPTO_BASEADDR, FPD_PKI_SIZE); + FPD_PKI_CRYPTO_BASEADDR, + FPD_PKI_SIZE); if (!versal_pki.regs) return TEE_ERROR_GENERIC; From 62d55006dc73a978d5028735c91561734f19d12c Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 14 Aug 2024 12:02:16 +0200 Subject: [PATCH 24/43] fixup! drivers: versal: rework mbox driver Signed-off-by: Jeremie Corbier --- core/drivers/versal_mbox.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/drivers/versal_mbox.c b/core/drivers/versal_mbox.c index 28ddd13ea36..356509a2cfd 100644 --- a/core/drivers/versal_mbox.c +++ b/core/drivers/versal_mbox.c @@ -497,8 +497,8 @@ TEE_Result versal_mbox_notify_pmc(struct versal_ipi_cmd *cmd, * detailed information. */ DMSG("PLM: plm status = 0x%" PRIx32 ", lib_status = 0x%" PRIx32, - (*err & 0xFFFF0000) >> 16, - (*err & 0x0000FFFF)); + (*err & 0xFFFF0000) >> 16, + (*err & 0x0000FFFF)); } return ret; @@ -506,7 +506,7 @@ TEE_Result versal_mbox_notify_pmc(struct versal_ipi_cmd *cmd, static TEE_Result versal_mbox_init(void) { - uint32_t lcl; + uint32_t lcl = 0; switch (CFG_VERSAL_MBOX_IPI_ID) { case 0: From a0f749553a4e652757be8a8d6a8e7fcd29856c83 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 14 Aug 2024 12:05:28 +0200 Subject: [PATCH 25/43] fixup! drivers: versal: NVM driver for Versal Net Signed-off-by: Jeremie Corbier --- core/drivers/versal_net_nvm.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/core/drivers/versal_net_nvm.c b/core/drivers/versal_net_nvm.c index 82755759c5d..a992a819598 100644 --- a/core/drivers/versal_net_nvm.c +++ b/core/drivers/versal_net_nvm.c @@ -723,47 +723,47 @@ static TEE_Result do_write_efuses(enum versal_nvm_api_id id) TEE_Result versal_efuse_write_aes_keys(struct versal_efuse_aes_keys *keys) { - TEE_Result ret = TEE_SUCCESS; TEE_Result res = TEE_SUCCESS; + TEE_Result res2 = TEE_SUCCESS; if (!keys) return TEE_ERROR_BAD_PARAMETERS; if (keys->prgm_aes_key) { - res = do_write_efuses_buffer(EFUSE_WRITE_AES_KEY, + res2 = do_write_efuses_buffer(EFUSE_WRITE_AES_KEY, EFUSE_AES_KEY_ID, keys->aes_key, EFUSE_AES_KEY_LEN); - if (res) { - DMSG("Error programming AES key (0x%" PRIx32 ")", res); - ret = TEE_ERROR_GENERIC; + if (res2) { + DMSG("Error programming AES key (0x%" PRIx32 ")", res2); + res = TEE_ERROR_GENERIC; } } if (keys->prgm_user_key0) { - res = do_write_efuses_buffer(EFUSE_WRITE_AES_KEY, + res2 = do_write_efuses_buffer(EFUSE_WRITE_AES_KEY, EFUSE_USER_KEY0_ID, keys->user_key0, EFUSE_AES_KEY_LEN); - if (res) { + if (res2) { DMSG("Error programming User key 0 (0x%" PRIx32 ")", - res); - ret = TEE_ERROR_GENERIC; + res2); + res = TEE_ERROR_GENERIC; } } if (keys->prgm_user_key1) { - res = do_write_efuses_buffer(EFUSE_WRITE_AES_KEY, + res2 = do_write_efuses_buffer(EFUSE_WRITE_AES_KEY, EFUSE_USER_KEY1_ID, keys->user_key1, EFUSE_AES_KEY_LEN); - if (res) { + if (res2) { DMSG("Error programming User key 1 (0x%" PRIx32 ")", - res); - ret = TEE_ERROR_GENERIC; + res2); + res = TEE_ERROR_GENERIC; } } - return ret; + return res; } TEE_Result versal_efuse_write_ppk_hash(struct versal_efuse_ppk_hash *hash) From 76e0faa13b1e2e09d2a010e4887dc403f724dbc9 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 14 Aug 2024 12:10:37 +0200 Subject: [PATCH 26/43] fixup! drivers: versal: use PLM for generic RNG operations Signed-off-by: Jeremie Corbier --- core/drivers/versal_trng.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/drivers/versal_trng.c b/core/drivers/versal_trng.c index 62e812507c5..6d9d18b9c19 100644 --- a/core/drivers/versal_trng.c +++ b/core/drivers/versal_trng.c @@ -1014,8 +1014,8 @@ TEE_Result versal_trng_hw_init(struct versal_trng *trng, struct trng_usr_cfg *usr_cfg) { trng->cfg.addr = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, - trng->cfg.base, - trng->cfg.len); + trng->cfg.base, + trng->cfg.len); if (!trng->cfg.addr) { EMSG("Failed to map TRNG"); panic(); From c3c5971644f8e700fdb1e160f5b34360f43865e4 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 14 Aug 2024 12:14:32 +0200 Subject: [PATCH 27/43] fixup! core: pta: add Versal FPGA PTA Signed-off-by: Jeremie Corbier --- lib/libutee/include/pta_versal_fpga.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/libutee/include/pta_versal_fpga.h b/lib/libutee/include/pta_versal_fpga.h index c5a2ba30643..ed1b3920f47 100644 --- a/lib/libutee/include/pta_versal_fpga.h +++ b/lib/libutee/include/pta_versal_fpga.h @@ -12,8 +12,7 @@ /** * Write FPGA bitstream * - * [in] memref[0].buffer FPGA bitstream buffer - * [in] memref[0].size FPGA bitstream buffer size + * [in] memref[0] FPGA bitstream buffer * * Return codes: * TEE_SUCCESS - Invoke command success From 3c91efca59b215e7ab2fc7af40875ef27f8f0156 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 14 Aug 2024 12:23:57 +0200 Subject: [PATCH 28/43] fixup! drivers: versal: PKI engine driver for Versal Net Signed-off-by: Jeremie Corbier --- core/drivers/crypto/versal/pki/ecc_pki_engine.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/drivers/crypto/versal/pki/ecc_pki_engine.c b/core/drivers/crypto/versal/pki/ecc_pki_engine.c index e07cb530e2d..a75254edd09 100644 --- a/core/drivers/crypto/versal/pki/ecc_pki_engine.c +++ b/core/drivers/crypto/versal/pki/ecc_pki_engine.c @@ -720,7 +720,8 @@ static TEE_Result versal_pki_engine_reset(void) /* Reset the PKI engine */ reset = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, - PSX_CRF_RST_PKI, SMALL_PAGE_SIZE); + PSX_CRF_RST_PKI, + SMALL_PAGE_SIZE); if (!reset) return TEE_ERROR_GENERIC; From 5899f1b971e062e1bf0b5a6fe234254227f05a68 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 14 Aug 2024 17:20:25 +0200 Subject: [PATCH 29/43] fixup! drivers: versal: update to support more recent versions of the PLM Signed-off-by: Jeremie Corbier --- core/drivers/versal_pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/drivers/versal_pm.c b/core/drivers/versal_pm.c index ee43592b0e4..85da5acde63 100644 --- a/core/drivers/versal_pm.c +++ b/core/drivers/versal_pm.c @@ -43,8 +43,8 @@ #define PM_MODULE_SHIFT 8 #define PM_MODULE 2 #define PM_API_ID(x) ((PM_MODULE << PM_MODULE_SHIFT) | (x)) -#define VERSAL_PM_MAJOR 1 -#define VERSAL_PM_MINOR 0 +#define VERSAL_PM_MAJOR 0 +#define VERSAL_PM_MINOR 1 /* PM API ids */ #define PM_GET_API_VERSION 1 From d699e7f52e99cc6f91582c1b5b5d0ad75ed448e9 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 14 Aug 2024 17:32:02 +0200 Subject: [PATCH 30/43] drivers: versal: fix PM ABI check - Make the check stricter ; major and minor versions should match - Fix supported Versal PM version (1.0 rather than 0.1) Signed-off-by: Jeremie Corbier --- core/drivers/versal_pm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/drivers/versal_pm.c b/core/drivers/versal_pm.c index 85da5acde63..c1215da658f 100644 --- a/core/drivers/versal_pm.c +++ b/core/drivers/versal_pm.c @@ -43,8 +43,8 @@ #define PM_MODULE_SHIFT 8 #define PM_MODULE 2 #define PM_API_ID(x) ((PM_MODULE << PM_MODULE_SHIFT) | (x)) -#define VERSAL_PM_MAJOR 0 -#define VERSAL_PM_MINOR 1 +#define VERSAL_PM_MAJOR 1 +#define VERSAL_PM_MINOR 0 /* PM API ids */ #define PM_GET_API_VERSION 1 @@ -211,7 +211,7 @@ static TEE_Result versal_check_pm_abi(void) minor = rsp.data[1] & 0xFFFF; major = rsp.data[1] >> 16; - if (major != VERSAL_PM_MAJOR || minor < VERSAL_PM_MINOR) { + if (major != VERSAL_PM_MAJOR || minor != VERSAL_PM_MINOR) { EMSG("Invalid PM version: Major %d, Minor %d", major, minor); return TEE_ERROR_GENERIC; } From 6e74be927257b8ae65781e9c01da73eaf26d4aa4 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 14 Aug 2024 17:42:42 +0200 Subject: [PATCH 31/43] drivers: versal: free ECC ephemeral key in case of error There were cases whe the ephemeral key needed to perform ECDSA signatures was not properly free'd in case an error happened during the process. Signed-off-by: Jeremie Corbier --- core/drivers/crypto/versal/ecc_mbox.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/drivers/crypto/versal/ecc_mbox.c b/core/drivers/crypto/versal/ecc_mbox.c index bce5379cca2..195a0d3512b 100644 --- a/core/drivers/crypto/versal/ecc_mbox.c +++ b/core/drivers/crypto/versal/ecc_mbox.c @@ -222,9 +222,6 @@ TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key, goto out; versal_crypto_bignum_bn2bin_eswap(key->curve, ephemeral.d, k.buf); - crypto_bignum_free(&ephemeral.d); - crypto_bignum_free(&ephemeral.x); - crypto_bignum_free(&ephemeral.y); /* Private key*/ ret = versal_mbox_alloc(bytes, NULL, &d); @@ -269,6 +266,10 @@ TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key, *sig_len / 2); out: + crypto_bignum_free(&ephemeral.d); + crypto_bignum_free(&ephemeral.x); + crypto_bignum_free(&ephemeral.y); + versal_mbox_free(&cmd_buf); versal_mbox_free(&s); versal_mbox_free(&d); From 41deb61745d07a0fc7efded3c6168b7da32bed68 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 18 Sep 2024 15:37:05 +0200 Subject: [PATCH 32/43] fixup! plat-versal: add support for Versal Net variant Signed-off-by: Jeremie Corbier --- core/arch/arm/plat-versal/conf.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/arch/arm/plat-versal/conf.mk b/core/arch/arm/plat-versal/conf.mk index 6bb69c64a97..799a842e1b2 100644 --- a/core/arch/arm/plat-versal/conf.mk +++ b/core/arch/arm/plat-versal/conf.mk @@ -49,7 +49,7 @@ endif ifeq ($(PLATFORM_FLAVOR),net) CFG_RPMB_FS ?= n CFG_RPMB_TESTKEY ?= y -CFG_RPMB_WRITE_KEY ?=y +CFG_RPMB_WRITE_KEY ?= $(CFG_RPMB_TESTKEY) endif # GPIO From aa36c59bee90a681f2ad9adf0b203d2cc7101002 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 18 Sep 2024 15:54:36 +0200 Subject: [PATCH 33/43] fixup! drivers: versal: PKI engine driver for Versal Net Signed-off-by: Jeremie Corbier --- core/drivers/crypto/versal/ecc.c | 10 +++++----- core/drivers/crypto/versal/ecc_mbox.c | 14 +++++++------- core/drivers/crypto/versal/include/ecc.h | 7 ++++++- core/drivers/crypto/versal/pki/ecc_pki_engine.c | 10 +++++----- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/core/drivers/crypto/versal/ecc.c b/core/drivers/crypto/versal/ecc.c index 43b284459fd..8fd0441209f 100644 --- a/core/drivers/crypto/versal/ecc.c +++ b/core/drivers/crypto/versal/ecc.c @@ -11,8 +11,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -48,7 +48,7 @@ TEE_Result versal_ecc_get_key_size(uint32_t curve, size_t *bytes, size_t *bits) return TEE_SUCCESS; } -void memcpy_swp(uint8_t *to, const uint8_t *from, size_t len) +void versal_memcpy_swp(uint8_t *to, const uint8_t *from, size_t len) { size_t i = 0; @@ -68,7 +68,7 @@ void versal_crypto_bignum_bn2bin_eswap(uint32_t curve, struct bignum *from, panic(); crypto_bignum_bn2bin(from, pad + bytes - len); - memcpy_swp(to, pad, bytes); + versal_memcpy_swp(to, pad, bytes); } void versal_crypto_bignum_bin2bn_eswap(const uint8_t *from, size_t sz, @@ -78,7 +78,7 @@ void versal_crypto_bignum_bin2bn_eswap(const uint8_t *from, size_t sz, assert(sz <= sizeof(pad)); - memcpy_swp(pad, from, sz); + versal_memcpy_swp(pad, from, sz); crypto_bignum_bin2bn(pad, sz, to); } @@ -100,7 +100,7 @@ TEE_Result versal_ecc_prepare_msg(uint32_t algo, const uint8_t *msg, return TEE_ERROR_NOT_SUPPORTED; /* Swap the hash/message and pad if necessary */ - memcpy_swp(buf, msg, msg_len); + versal_memcpy_swp(buf, msg, msg_len); return TEE_SUCCESS; } diff --git a/core/drivers/crypto/versal/ecc_mbox.c b/core/drivers/crypto/versal/ecc_mbox.c index 195a0d3512b..7bdb7e3f299 100644 --- a/core/drivers/crypto/versal/ecc_mbox.c +++ b/core/drivers/crypto/versal/ecc_mbox.c @@ -10,8 +10,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -134,8 +134,8 @@ TEE_Result versal_ecc_verify(uint32_t algo, struct ecc_public_key *key, goto out2; /* Swap the {R,S} components */ - memcpy_swp(s.buf, sig, sig_len / 2); - memcpy_swp((uint8_t *)s.buf + sig_len / 2, sig + sig_len / 2, + versal_memcpy_swp(s.buf, sig, sig_len / 2); + versal_memcpy_swp((uint8_t *)s.buf + sig_len / 2, sig + sig_len / 2, sig_len / 2); ret = versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf); @@ -261,8 +261,8 @@ TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key, *sig_len = 2 * bytes; /* Swap the {R,S} components */ - memcpy_swp(sig, s.buf, *sig_len / 2); - memcpy_swp(sig + *sig_len / 2, (uint8_t *)s.buf + *sig_len / 2, + versal_memcpy_swp(sig, s.buf, *sig_len / 2); + versal_memcpy_swp(sig + *sig_len / 2, (uint8_t *)s.buf + *sig_len / 2, *sig_len / 2); out: @@ -310,8 +310,8 @@ TEE_Result versal_ecc_kat_test(void) TEE_Result versal_ecc_gen_keypair(struct ecc_keypair *s __maybe_unused) { /* - * Versal requires little endian so need to memcpy_swp on Versal IP ops. - * We chose not to do it here because some tests might be using + * Versal requires little endian so need to versal_memcpy_swp on Versal IP + * ops. We chose not to do it here because some tests might be using * their own keys */ diff --git a/core/drivers/crypto/versal/include/ecc.h b/core/drivers/crypto/versal/include/ecc.h index fc9bd515727..dc8afcaeed2 100644 --- a/core/drivers/crypto/versal/include/ecc.h +++ b/core/drivers/crypto/versal/include/ecc.h @@ -6,6 +6,11 @@ #ifndef ECC_H #define ECC_H +#include +#include +#include +#include + TEE_Result versal_ecc_get_key_size(uint32_t curve, size_t *bytes, size_t *bits); TEE_Result versal_ecc_prepare_msg(uint32_t algo, const uint8_t *msg, size_t msg_len, size_t *len, uint8_t *buf); @@ -29,7 +34,7 @@ TEE_Result versal_ecc_sign_ephemeral(uint32_t algo, size_t bytes, const uint8_t *msg, size_t msg_len, uint8_t *sig, size_t *sig_len); -void memcpy_swp(uint8_t *to, const uint8_t *from, size_t len); +void versal_memcpy_swp(uint8_t *to, const uint8_t *from, size_t len); void versal_crypto_bignum_bn2bin_eswap(uint32_t curve, struct bignum *from, uint8_t *to); void versal_crypto_bignum_bin2bn_eswap(const uint8_t *from, size_t sz, diff --git a/core/drivers/crypto/versal/pki/ecc_pki_engine.c b/core/drivers/crypto/versal/pki/ecc_pki_engine.c index a75254edd09..fdf1a1e30cb 100644 --- a/core/drivers/crypto/versal/pki/ecc_pki_engine.c +++ b/core/drivers/crypto/versal/pki/ecc_pki_engine.c @@ -144,7 +144,7 @@ static struct versal_pki versal_pki; #define PKI_DESC_SELCURVE_P521 0x3 #define PKI_DESC_TAG_START_CMD(op, opsize, selcurve, field) \ - ((op) | ((field) << 7) | ((opsize) << 8) | ((selcurve) << 20)) + ((op) | ((field) << 7) | ((opsize) << 8) | ((selcurve) << 20)) #define PKI_SIGN_INPUT_OP_COUNT 3 #define PKI_VERIFY_INPUT_OP_COUNT 5 @@ -339,9 +339,9 @@ TEE_Result versal_ecc_verify(uint32_t algo, struct ecc_public_key *key, addr += bytes; /* Copy signature */ - memcpy_swp(addr, sig, sig_len / 2); + versal_memcpy_swp(addr, sig, sig_len / 2); addr += sig_len / 2; - memcpy_swp(addr, sig + sig_len / 2, sig_len / 2); + versal_memcpy_swp(addr, sig + sig_len / 2, sig_len / 2); addr += sig_len / 2; /* Copy hash */ @@ -471,8 +471,8 @@ TEE_Result versal_ecc_sign_ephemeral(uint32_t algo, size_t bytes, cache_operation(TEE_CACHEFLUSH, versal_pki.rq_out, PKI_QUEUE_BUF_SIZE); - memcpy_swp(sig, versal_pki.rq_out, bytes); - memcpy_swp(sig + bytes, versal_pki.rq_out + bytes, bytes); + versal_memcpy_swp(sig, versal_pki.rq_out, bytes); + versal_memcpy_swp(sig + bytes, versal_pki.rq_out + bytes, bytes); /* Clear memory */ memset(versal_pki.rq_in, 0, PKI_QUEUE_BUF_SIZE); From 8471ab7c227079969a80ef7c9b3e4a7d0a69c1ac Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 18 Sep 2024 16:05:01 +0200 Subject: [PATCH 34/43] fixup! drivers: versal: rework mbox driver Signed-off-by: Jeremie Corbier --- core/drivers/crypto/versal/authenc.c | 10 +++++----- core/drivers/crypto/versal/rsa.c | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/core/drivers/crypto/versal/authenc.c b/core/drivers/crypto/versal/authenc.c index 6e5f183767d..9fc3215aea6 100644 --- a/core/drivers/crypto/versal/authenc.c +++ b/core/drivers/crypto/versal/authenc.c @@ -494,10 +494,10 @@ update_payload(struct drvcrypt_authenc_update_payload *dupdate, bool is_last) return ret; ret = versal_mbox_alloc(dupdate->dst.length, NULL, &q); if (ret) - goto error; + goto out; ret = versal_mbox_alloc(sizeof(*input), NULL, &input_cmd); if (ret) - goto error; + goto out; input = input_cmd.buf; input->input_addr = virt_to_phys(p.buf); @@ -519,7 +519,7 @@ update_payload(struct drvcrypt_authenc_update_payload *dupdate, bool is_last) if (versal_crypto_request(id, &arg, &err)) { EMSG("AES_UPDATE_PAYLOAD error: %s", versal_aes_error(err)); ret = TEE_ERROR_GENERIC; - goto error; + goto out; } if (dupdate->dst.data) @@ -529,7 +529,7 @@ update_payload(struct drvcrypt_authenc_update_payload *dupdate, bool is_last) node = calloc(1, sizeof(*node)); if (!node) { ret = TEE_ERROR_OUT_OF_MEMORY; - goto error; + goto out; } node->is_aad = false; @@ -541,7 +541,7 @@ update_payload(struct drvcrypt_authenc_update_payload *dupdate, bool is_last) return TEE_SUCCESS; } -error: +out: versal_mbox_free(&input_cmd); versal_mbox_free(&q); versal_mbox_free(&p); diff --git a/core/drivers/crypto/versal/rsa.c b/core/drivers/crypto/versal/rsa.c index 2b97017564a..232c0dec62c 100644 --- a/core/drivers/crypto/versal/rsa.c +++ b/core/drivers/crypto/versal/rsa.c @@ -84,13 +84,13 @@ static TEE_Result do_encrypt(struct drvcrypt_rsa_ed *rsa_data) ret = versal_mbox_alloc(rsa_data->message.length, rsa_data->message.data, &msg); if (ret) - goto error; + goto out; ret = versal_mbox_alloc(rsa_data->cipher.length, NULL, &cipher); if (ret) - goto error; + goto out; ret = versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf); if (ret) - goto error; + goto out; cmd = cmd_buf.buf; cmd->key_len = rsa_data->key.n_size; @@ -117,7 +117,7 @@ static TEE_Result do_encrypt(struct drvcrypt_rsa_ed *rsa_data) memcpy(rsa_data->cipher.data, cipher.buf, rsa_data->key.n_size); } -error: +out: versal_mbox_free(&cmd_buf); versal_mbox_free(&cipher); versal_mbox_free(&msg); @@ -184,13 +184,13 @@ static TEE_Result do_decrypt(struct drvcrypt_rsa_ed *rsa_data) ret = versal_mbox_alloc(rsa_data->cipher.length, rsa_data->cipher.data, &cipher); if (ret) - goto error; + goto out; ret = versal_mbox_alloc(rsa_data->message.length, NULL, &msg); if (ret) - goto error; + goto out; ret = versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf); if (ret) - goto error; + goto out; cmd = cmd_buf.buf; cmd->key_len = rsa_data->key.n_size; @@ -213,7 +213,7 @@ static TEE_Result do_decrypt(struct drvcrypt_rsa_ed *rsa_data) memcpy(rsa_data->message.data, msg.buf, rsa_data->key.n_size); } -error: +out: versal_mbox_free(&cmd_buf); versal_mbox_free(&msg); versal_mbox_free(&cipher); From d68d7d42cfe1aeb8240706d828f5160712a832db Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 18 Sep 2024 16:14:42 +0200 Subject: [PATCH 35/43] fixup! drivers: versal: NVM driver for Versal Net Signed-off-by: Jeremie Corbier --- core/drivers/versal_net_nvm.c | 66 +++++++++++++++++------------------ 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/core/drivers/versal_net_nvm.c b/core/drivers/versal_net_nvm.c index a992a819598..2e4817a6256 100644 --- a/core/drivers/versal_net_nvm.c +++ b/core/drivers/versal_net_nvm.c @@ -5,8 +5,8 @@ */ #include -#include #include +#include #include #include #include @@ -768,94 +768,94 @@ TEE_Result versal_efuse_write_aes_keys(struct versal_efuse_aes_keys *keys) TEE_Result versal_efuse_write_ppk_hash(struct versal_efuse_ppk_hash *hash) { - TEE_Result ret = TEE_SUCCESS; TEE_Result res = TEE_SUCCESS; + TEE_Result res2 = TEE_SUCCESS; if (!hash) return TEE_ERROR_BAD_PARAMETERS; if (hash->prgm_ppk0_hash) { - res = do_write_efuses_buffer(EFUSE_WRITE_PPK_HASH, EFUSE_PPK0, + res2 = do_write_efuses_buffer(EFUSE_WRITE_PPK_HASH, EFUSE_PPK0, hash->ppk0_hash, EFUSE_PPK_LEN); - if (res) { + if (res2) { DMSG("Error programming PPK hash 0 (0x%" PRIx32 ")", - res); - ret = TEE_ERROR_GENERIC; + res2); + res = TEE_ERROR_GENERIC; } } if (hash->prgm_ppk1_hash) { - res = do_write_efuses_buffer(EFUSE_WRITE_PPK_HASH, EFUSE_PPK1, + res2 = do_write_efuses_buffer(EFUSE_WRITE_PPK_HASH, EFUSE_PPK1, hash->ppk1_hash, EFUSE_PPK_LEN); - if (res) { + if (res2) { DMSG("Error programming PPK hash 1 (0x%" PRIx32 ")", - res); - ret = TEE_ERROR_GENERIC; + res2); + res = TEE_ERROR_GENERIC; } } if (hash->prgm_ppk2_hash) { - res = do_write_efuses_buffer(EFUSE_WRITE_PPK_HASH, EFUSE_PPK2, + res2 = do_write_efuses_buffer(EFUSE_WRITE_PPK_HASH, EFUSE_PPK2, hash->ppk2_hash, EFUSE_PPK_LEN); - if (res) { + if (res2) { DMSG("Error programming PPK hash 2 (0x%" PRIx32 ")", - res); - ret = TEE_ERROR_GENERIC; + res2); + res = TEE_ERROR_GENERIC; } } - return ret; + return res; } TEE_Result versal_efuse_write_iv(struct versal_efuse_ivs *p) { - TEE_Result ret = TEE_SUCCESS; TEE_Result res = TEE_SUCCESS; + TEE_Result res2 = TEE_SUCCESS; if (!p) return TEE_ERROR_BAD_PARAMETERS; if (p->prgm_meta_header_iv) { - res = do_write_efuses_buffer(EFUSE_WRITE_IV, + res2 = do_write_efuses_buffer(EFUSE_WRITE_IV, EFUSE_META_HEADER_IV_RANGE, p->meta_header_iv, EFUSE_IV_LEN); - if (res) { + if (res2) { DMSG("Error programming meta header IV (0x%" PRIx32 ")", - res); - ret = TEE_ERROR_GENERIC; + res2); + res = TEE_ERROR_GENERIC; } } if (p->prgm_blk_obfus_iv) { - res = do_write_efuses_buffer(EFUSE_WRITE_IV, EFUSE_BLACK_IV, + res2 = do_write_efuses_buffer(EFUSE_WRITE_IV, EFUSE_BLACK_IV, p->blk_obfus_iv, EFUSE_IV_LEN); - if (res) { - DMSG("Error programming black IV (0x%" PRIx32 ")", res); - ret = TEE_ERROR_GENERIC; + if (res2) { + DMSG("Error programming black IV (0x%" PRIx32 ")", res2); + res = TEE_ERROR_GENERIC; } } if (p->prgm_plm_iv) { - res = do_write_efuses_buffer(EFUSE_WRITE_IV, EFUSE_PLM_IV_RANGE, + res2 = do_write_efuses_buffer(EFUSE_WRITE_IV, EFUSE_PLM_IV_RANGE, p->plm_iv, EFUSE_IV_LEN); - if (res) { - DMSG("Error programming plm IV (0x%" PRIx32 ")", res); - ret = TEE_ERROR_GENERIC; + if (res2) { + DMSG("Error programming plm IV (0x%" PRIx32 ")", res2); + res = TEE_ERROR_GENERIC; } } if (p->prgm_data_partition_iv) { - res = do_write_efuses_buffer(EFUSE_WRITE_IV, + res2 = do_write_efuses_buffer(EFUSE_WRITE_IV, EFUSE_DATA_PARTITION_IV_RANGE, p->data_partition_iv, EFUSE_IV_LEN); - if (res) { - DMSG("Error programming data IV (0x%" PRIx32 ")", res); - ret = TEE_ERROR_GENERIC; + if (res2) { + DMSG("Error programming data IV (0x%" PRIx32 ")", res2); + res = TEE_ERROR_GENERIC; } } - return ret; + return res; } TEE_Result versal_efuse_write_dec_only(struct versal_efuse_dec_only *p) From 083edc4f35b502630b0bfea9e82d08e2fad0078b Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 18 Sep 2024 16:19:10 +0200 Subject: [PATCH 36/43] fixup! drivers: versal: rework mbox driver Signed-off-by: Jeremie Corbier --- core/drivers/versal_puf.c | 20 ++++++++++---------- core/include/drivers/versal_mbox.h | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/core/drivers/versal_puf.c b/core/drivers/versal_puf.c index f54f8cfea96..3f4ccf8e57e 100644 --- a/core/drivers/versal_puf.c +++ b/core/drivers/versal_puf.c @@ -117,18 +117,18 @@ TEE_Result versal_puf_register(struct versal_puf_data *buf, return ret; ret = versal_mbox_alloc(sizeof(buf->chash), &buf->chash, &hash_addr); if (ret) - goto error; + goto out; ret = versal_mbox_alloc(sizeof(buf->aux), &buf->aux, &aux_addr); if (ret) - goto error; + goto out; ret = versal_mbox_alloc(sizeof(buf->efuse_syn_data), buf->efuse_syn_data, &efuse_syn_data_addr); if (ret) - goto error; + goto out; ret = versal_mbox_alloc(sizeof(buf->syndrome_data), buf->syndrome_data, &syndrome_data_addr); if (ret) - goto error; + goto out; arg.ibuf[0].mem = request; arg.ibuf[1].mem = syndrome_data_addr; @@ -169,7 +169,7 @@ TEE_Result versal_puf_register(struct versal_puf_data *buf, memcpy(buf->syndrome_data, syndrome_data_addr.buf, sizeof(buf->syndrome_data)); -error: +out: versal_mbox_free(&syndrome_data_addr); versal_mbox_free(&efuse_syn_data_addr); versal_mbox_free(&aux_addr); @@ -208,18 +208,18 @@ TEE_Result versal_puf_regenerate(struct versal_puf_data *buf, return ret; ret = versal_mbox_alloc(sizeof(buf->chash), &buf->chash, &hash_addr); if (ret) - goto error; + goto out; ret = versal_mbox_alloc(sizeof(buf->aux), &buf->aux, &aux_addr); if (ret) - goto error; + goto out; ret = versal_mbox_alloc(sizeof(buf->efuse_syn_data), buf->efuse_syn_data, &efuse_syn_data_addr); if (ret) - goto error; + goto out; ret = versal_mbox_alloc(sizeof(buf->syndrome_data), buf->syndrome_data, &syndrome_data_addr); if (ret) - goto error; + goto out; arg.ibuf[0].mem = request; arg.ibuf[1].mem = syndrome_data_addr; @@ -254,7 +254,7 @@ TEE_Result versal_puf_regenerate(struct versal_puf_data *buf, /* Return the updated PUF_ID */ memcpy(buf->puf_id, puf_id_addr.buf, sizeof(buf->puf_id)); -error: +out: versal_mbox_free(&syndrome_data_addr); versal_mbox_free(&efuse_syn_data_addr); versal_mbox_free(&aux_addr); diff --git a/core/include/drivers/versal_mbox.h b/core/include/drivers/versal_mbox.h index 6067d53c10c..1835f3f8ceb 100644 --- a/core/include/drivers/versal_mbox.h +++ b/core/include/drivers/versal_mbox.h @@ -5,8 +5,8 @@ #ifndef __DRIVERS_VERSAL_MBOX_H #define __DRIVERS_VERSAL_MBOX_H -#include #include +#include #include #include From 3b506e9cd4ef3ed8f4006b3ce8c910dd137c6b6f Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 18 Sep 2024 16:23:03 +0200 Subject: [PATCH 37/43] fixup! drivers: versal: PKI engine driver for Versal Net Signed-off-by: Jeremie Corbier --- core/include/drivers/versal_trng.h | 1 + 1 file changed, 1 insertion(+) diff --git a/core/include/drivers/versal_trng.h b/core/include/drivers/versal_trng.h index 26b75cc111c..d3eff4ee06b 100644 --- a/core/include/drivers/versal_trng.h +++ b/core/include/drivers/versal_trng.h @@ -6,6 +6,7 @@ #ifndef __DRIVERS_VERSAL_TRNG_H #define __DRIVERS_VERSAL_TRNG_H +#include #include #include #include From 8058dd715d3312f48a2ee704ad6d3f89b2ce6ee4 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 18 Sep 2024 16:24:36 +0200 Subject: [PATCH 38/43] fixup! core: pta: add Versal FPGA PTA Signed-off-by: Jeremie Corbier --- core/pta/versal/fpga_pta.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/pta/versal/fpga_pta.c b/core/pta/versal/fpga_pta.c index 79b2f169a13..923ef482304 100644 --- a/core/pta/versal/fpga_pta.c +++ b/core/pta/versal/fpga_pta.c @@ -4,6 +4,7 @@ */ #include #include +#include #include #include #include From b47ed4f6e9af256577ff1ca6a5b4d3a8ca2b8a7f Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 18 Sep 2024 16:33:12 +0200 Subject: [PATCH 39/43] fixup! drivers: versal: NVM driver for Versal Net Signed-off-by: Jeremie Corbier --- core/drivers/versal_net_nvm.c | 36 +++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/core/drivers/versal_net_nvm.c b/core/drivers/versal_net_nvm.c index 2e4817a6256..a67f3112e85 100644 --- a/core/drivers/versal_net_nvm.c +++ b/core/drivers/versal_net_nvm.c @@ -731,8 +731,8 @@ TEE_Result versal_efuse_write_aes_keys(struct versal_efuse_aes_keys *keys) if (keys->prgm_aes_key) { res2 = do_write_efuses_buffer(EFUSE_WRITE_AES_KEY, - EFUSE_AES_KEY_ID, - keys->aes_key, EFUSE_AES_KEY_LEN); + EFUSE_AES_KEY_ID, + keys->aes_key, EFUSE_AES_KEY_LEN); if (res2) { DMSG("Error programming AES key (0x%" PRIx32 ")", res2); res = TEE_ERROR_GENERIC; @@ -741,9 +741,9 @@ TEE_Result versal_efuse_write_aes_keys(struct versal_efuse_aes_keys *keys) if (keys->prgm_user_key0) { res2 = do_write_efuses_buffer(EFUSE_WRITE_AES_KEY, - EFUSE_USER_KEY0_ID, - keys->user_key0, - EFUSE_AES_KEY_LEN); + EFUSE_USER_KEY0_ID, + keys->user_key0, + EFUSE_AES_KEY_LEN); if (res2) { DMSG("Error programming User key 0 (0x%" PRIx32 ")", res2); @@ -753,9 +753,9 @@ TEE_Result versal_efuse_write_aes_keys(struct versal_efuse_aes_keys *keys) if (keys->prgm_user_key1) { res2 = do_write_efuses_buffer(EFUSE_WRITE_AES_KEY, - EFUSE_USER_KEY1_ID, - keys->user_key1, - EFUSE_AES_KEY_LEN); + EFUSE_USER_KEY1_ID, + keys->user_key1, + EFUSE_AES_KEY_LEN); if (res2) { DMSG("Error programming User key 1 (0x%" PRIx32 ")", res2); @@ -776,7 +776,7 @@ TEE_Result versal_efuse_write_ppk_hash(struct versal_efuse_ppk_hash *hash) if (hash->prgm_ppk0_hash) { res2 = do_write_efuses_buffer(EFUSE_WRITE_PPK_HASH, EFUSE_PPK0, - hash->ppk0_hash, EFUSE_PPK_LEN); + hash->ppk0_hash, EFUSE_PPK_LEN); if (res2) { DMSG("Error programming PPK hash 0 (0x%" PRIx32 ")", res2); @@ -786,7 +786,7 @@ TEE_Result versal_efuse_write_ppk_hash(struct versal_efuse_ppk_hash *hash) if (hash->prgm_ppk1_hash) { res2 = do_write_efuses_buffer(EFUSE_WRITE_PPK_HASH, EFUSE_PPK1, - hash->ppk1_hash, EFUSE_PPK_LEN); + hash->ppk1_hash, EFUSE_PPK_LEN); if (res2) { DMSG("Error programming PPK hash 1 (0x%" PRIx32 ")", res2); @@ -796,7 +796,7 @@ TEE_Result versal_efuse_write_ppk_hash(struct versal_efuse_ppk_hash *hash) if (hash->prgm_ppk2_hash) { res2 = do_write_efuses_buffer(EFUSE_WRITE_PPK_HASH, EFUSE_PPK2, - hash->ppk2_hash, EFUSE_PPK_LEN); + hash->ppk2_hash, EFUSE_PPK_LEN); if (res2) { DMSG("Error programming PPK hash 2 (0x%" PRIx32 ")", res2); @@ -817,8 +817,8 @@ TEE_Result versal_efuse_write_iv(struct versal_efuse_ivs *p) if (p->prgm_meta_header_iv) { res2 = do_write_efuses_buffer(EFUSE_WRITE_IV, - EFUSE_META_HEADER_IV_RANGE, - p->meta_header_iv, EFUSE_IV_LEN); + EFUSE_META_HEADER_IV_RANGE, + p->meta_header_iv, EFUSE_IV_LEN); if (res2) { DMSG("Error programming meta header IV (0x%" PRIx32 ")", res2); @@ -828,7 +828,7 @@ TEE_Result versal_efuse_write_iv(struct versal_efuse_ivs *p) if (p->prgm_blk_obfus_iv) { res2 = do_write_efuses_buffer(EFUSE_WRITE_IV, EFUSE_BLACK_IV, - p->blk_obfus_iv, EFUSE_IV_LEN); + p->blk_obfus_iv, EFUSE_IV_LEN); if (res2) { DMSG("Error programming black IV (0x%" PRIx32 ")", res2); res = TEE_ERROR_GENERIC; @@ -837,7 +837,7 @@ TEE_Result versal_efuse_write_iv(struct versal_efuse_ivs *p) if (p->prgm_plm_iv) { res2 = do_write_efuses_buffer(EFUSE_WRITE_IV, EFUSE_PLM_IV_RANGE, - p->plm_iv, EFUSE_IV_LEN); + p->plm_iv, EFUSE_IV_LEN); if (res2) { DMSG("Error programming plm IV (0x%" PRIx32 ")", res2); res = TEE_ERROR_GENERIC; @@ -846,9 +846,9 @@ TEE_Result versal_efuse_write_iv(struct versal_efuse_ivs *p) if (p->prgm_data_partition_iv) { res2 = do_write_efuses_buffer(EFUSE_WRITE_IV, - EFUSE_DATA_PARTITION_IV_RANGE, - p->data_partition_iv, - EFUSE_IV_LEN); + EFUSE_DATA_PARTITION_IV_RANGE, + p->data_partition_iv, + EFUSE_IV_LEN); if (res2) { DMSG("Error programming data IV (0x%" PRIx32 ")", res2); res = TEE_ERROR_GENERIC; From b60b529b34d937cc6b8181ff6c0c73e01106cd93 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 18 Sep 2024 16:38:29 +0200 Subject: [PATCH 40/43] fixup! drivers: versal: PKI engine driver for Versal Net Signed-off-by: Jeremie Corbier --- core/drivers/crypto/versal/ecc_mbox.c | 6 +++--- core/drivers/crypto/versal/pki/ecc_pki_engine.c | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/drivers/crypto/versal/ecc_mbox.c b/core/drivers/crypto/versal/ecc_mbox.c index 7bdb7e3f299..fa2e800210b 100644 --- a/core/drivers/crypto/versal/ecc_mbox.c +++ b/core/drivers/crypto/versal/ecc_mbox.c @@ -116,7 +116,7 @@ TEE_Result versal_ecc_verify(uint32_t algo, struct ecc_public_key *key, versal_crypto_bignum_bn2bin_eswap(key->curve, key->x, x.buf); versal_crypto_bignum_bn2bin_eswap(key->curve, key->y, - (uint8_t *)x.buf + bytes); + (uint8_t *)x.buf + bytes); /* Validate the public key for the curve */ arg.data[0] = key->curve; arg.dlen = 1; @@ -136,7 +136,7 @@ TEE_Result versal_ecc_verify(uint32_t algo, struct ecc_public_key *key, /* Swap the {R,S} components */ versal_memcpy_swp(s.buf, sig, sig_len / 2); versal_memcpy_swp((uint8_t *)s.buf + sig_len / 2, sig + sig_len / 2, - sig_len / 2); + sig_len / 2); ret = versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf); if (ret) @@ -263,7 +263,7 @@ TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key, /* Swap the {R,S} components */ versal_memcpy_swp(sig, s.buf, *sig_len / 2); versal_memcpy_swp(sig + *sig_len / 2, (uint8_t *)s.buf + *sig_len / 2, - *sig_len / 2); + *sig_len / 2); out: crypto_bignum_free(&ephemeral.d); diff --git a/core/drivers/crypto/versal/pki/ecc_pki_engine.c b/core/drivers/crypto/versal/pki/ecc_pki_engine.c index fdf1a1e30cb..dca9696d6d8 100644 --- a/core/drivers/crypto/versal/pki/ecc_pki_engine.c +++ b/core/drivers/crypto/versal/pki/ecc_pki_engine.c @@ -699,7 +699,8 @@ TEE_Result versal_ecc_gen_keypair(struct ecc_keypair *s) /* Copy private and public keys back */ versal_crypto_bignum_bin2bn_eswap(versal_pki.rq_in, bytes, s->d); versal_crypto_bignum_bin2bn_eswap(versal_pki.rq_out, bytes, s->x); - versal_crypto_bignum_bin2bn_eswap(versal_pki.rq_out + bytes, bytes, s->y); + versal_crypto_bignum_bin2bn_eswap(versal_pki.rq_out + bytes, + bytes, s->y); /* Clear memory */ memset(versal_pki.rq_in, 0, PKI_QUEUE_BUF_SIZE); From e67fe833d04b67b8149b5b5f661d242a2cdcc783 Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Wed, 18 Sep 2024 17:31:07 +0200 Subject: [PATCH 41/43] fixup! drivers: versal: NVM driver for Versal Net Signed-off-by: Jeremie Corbier --- core/drivers/versal_net_nvm.c | 46 +++++++++++++++++++++++-------- core/include/drivers/versal_nvm.h | 20 +++++++++++--- 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/core/drivers/versal_net_nvm.c b/core/drivers/versal_net_nvm.c index a67f3112e85..9f8bc10e3fb 100644 --- a/core/drivers/versal_net_nvm.c +++ b/core/drivers/versal_net_nvm.c @@ -105,8 +105,6 @@ struct versal_nvm_buf { struct versal_nvm_read_req { enum versal_nvm_api_id efuse_id; - enum versal_nvm_revocation_id revocation_id; - enum versal_nvm_offchip_id offchip_id; enum versal_nvm_ppk_type ppk_type; enum versal_nvm_iv_type iv_type; struct versal_nvm_buf ibuf[VERSAL_MAX_IPI_BUF]; @@ -447,11 +445,17 @@ TEE_Result versal_efuse_read_ppk(uint32_t *buf, size_t len, buf, len); } -TEE_Result versal_efuse_read_revoke_id(uint32_t *buf, size_t len, - enum versal_nvm_revocation_id id) +TEE_Result versal_efuse_read_revoke_id(uint32_t *buf, size_t len, uint32_t id) { - return versal_efuse_read_cache(EFUSE_CACHE_REVOCATION_ID0_OFFSET + - id * NVM_WORD_LEN, + uint32_t reg = EFUSE_CACHE_REVOCATION_ID0_OFFSET; + + if ((id < VERSAL_NET_REVOKE_EFUSE_MIN) || + (id > VERSAL_NET_REVOKE_EFUSE_MAX)) + return TEE_ERROR_BAD_PARAMETERS; + + reg += (id - 1) / 8; + + return versal_efuse_read_cache(reg, EFUSE_REVOCATION_ID_LEN / NVM_WORD_LEN, buf, len); } @@ -564,13 +568,17 @@ versal_efuse_read_boot_env_ctrl(struct versal_efuse_boot_env_ctrl_bits *buf) } TEE_Result versal_efuse_read_offchip_revoke_id(uint32_t *buf, size_t len, - enum versal_nvm_offchip_id id) + uint32_t id) { - if (id == EFUSE_INVLD) + uint32_t reg = EFUSE_CACHE_OFFCHIP_REVOKE_ID0_OFFSET; + + if ((id < VERSAL_NET_REVOKE_EFUSE_MIN) || + (id > VERSAL_NET_REVOKE_EFUSE_MAX)) return TEE_ERROR_BAD_PARAMETERS; - return versal_efuse_read_cache(EFUSE_CACHE_OFFCHIP_REVOKE_ID0_OFFSET + - id * NVM_WORD_LEN, + reg += (id - 1) / 8; + + return versal_efuse_read_cache(reg, EFUSE_REVOCATION_ID_LEN / NVM_WORD_LEN, buf, len); } @@ -968,9 +976,17 @@ TEE_Result versal_efuse_write_sec_misc1(struct versal_efuse_sec_misc1_bits *p) return do_write_efuses_value(EFUSE_WRITE_MISC1_CTRL_BITS, val); } +/* + * versal_efuse_write_offchip_ids expects an efuse identifier between + * 1 and 256. + */ TEE_Result versal_efuse_write_offchip_ids(uint32_t id) { - return do_write_efuses_value(EFUSE_WRITE_OFFCHIP_REVOKE_ID, id + 1); + if ((id < VERSAL_NET_REVOKE_EFUSE_MIN) || + (id > VERSAL_NET_REVOKE_EFUSE_MAX)) + return TEE_ERROR_BAD_PARAMETERS; + + return do_write_efuses_value(EFUSE_WRITE_OFFCHIP_REVOKE_ID, id); } TEE_Result versal_efuse_write_revoke_ppk(enum versal_nvm_ppk_type type) @@ -994,8 +1010,16 @@ TEE_Result versal_efuse_write_revoke_ppk(enum versal_nvm_ppk_type type) return versal_efuse_write_misc(&misc_ctrl); } +/* + * versal_efuse_write_revoke_id expects an efuse identifier between + * 1 and 256. + */ TEE_Result versal_efuse_write_revoke_id(uint32_t id) { + if ((id < VERSAL_NET_REVOKE_EFUSE_MIN) || + (id > VERSAL_NET_REVOKE_EFUSE_MAX)) + return TEE_ERROR_BAD_PARAMETERS; + return do_write_efuses_value(EFUSE_WRITE_REVOCATION_ID, id); } diff --git a/core/include/drivers/versal_nvm.h b/core/include/drivers/versal_nvm.h index aac8aaf20c7..8ce9fb7254d 100644 --- a/core/include/drivers/versal_nvm.h +++ b/core/include/drivers/versal_nvm.h @@ -42,6 +42,14 @@ enum versal_nvm_ppk_type { EFUSE_PPK2 }; +/* + * The Versal Net PLM API expects efuse values between 1 and 256 rather than + * the enumeration values defined for the original Versal port. + */ +#if defined(PLATFORM_FLAVOR_net) +#define VERSAL_NET_REVOKE_EFUSE_MIN 1 +#define VERSAL_NET_REVOKE_EFUSE_MAX 256 +#else enum versal_nvm_revocation_id { EFUSE_REVOCATION_ID_0 = 0, EFUSE_REVOCATION_ID_1, @@ -64,6 +72,7 @@ enum versal_nvm_offchip_id { EFUSE_OFFCHIP_REVOKE_ID_6, EFUSE_OFFCHIP_REVOKE_ID_7 }; +#endif /* * All structures mapped to the PLM processor must be address_and_size aligned @@ -251,20 +260,23 @@ TEE_Result versal_efuse_write_boot_env(struct versal_efuse_boot_env_ctrl_bits TEE_Result versal_efuse_write_sec_misc1(struct versal_efuse_sec_misc1_bits *p); #if defined(PLATFORM_FLAVOR_net) TEE_Result versal_efuse_write_offchip_ids(uint32_t id); +TEE_Result versal_efuse_read_offchip_revoke_id(uint32_t *buf, size_t len, + uint32_t id); +TEE_Result versal_efuse_read_revoke_id(uint32_t *buf, size_t len, uint32_t id); #else TEE_Result versal_efuse_write_offchip_ids(struct versal_efuse_offchip_ids *p); +TEE_Result versal_efuse_read_offchip_revoke_id(uint32_t *buf, size_t len, + enum versal_nvm_offchip_id id); +TEE_Result versal_efuse_read_revoke_id(uint32_t *buf, size_t len, + enum versal_nvm_revocation_id id); #endif TEE_Result versal_efuse_write_revoke_ppk(enum versal_nvm_ppk_type type); TEE_Result versal_efuse_write_revoke_id(uint32_t id); -TEE_Result versal_efuse_read_revoke_id(uint32_t *buf, size_t len, - enum versal_nvm_revocation_id id); TEE_Result versal_efuse_read_misc_ctrl(struct versal_efuse_misc_ctrl_bits *buf); TEE_Result versal_efuse_read_sec_ctrl(struct versal_efuse_sec_ctrl_bits *buf); TEE_Result versal_efuse_read_sec_misc1(struct versal_efuse_sec_misc1_bits *buf); TEE_Result versal_efuse_read_boot_env_ctrl(struct versal_efuse_boot_env_ctrl_bits *buf); -TEE_Result versal_efuse_read_offchip_revoke_id(uint32_t *buf, size_t len, - enum versal_nvm_offchip_id id); TEE_Result versal_efuse_read_dec_only(uint32_t *buf, size_t len); TEE_Result versal_efuse_read_puf_sec_ctrl(struct versal_efuse_puf_sec_ctrl_bits *buf); From 4fe7b58d9d00f21305342bbf20ca141e01dfd2db Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Thu, 19 Sep 2024 14:13:10 +0200 Subject: [PATCH 42/43] fixup! drivers: versal: PKI engine driver for Versal Net Signed-off-by: Jeremie Corbier --- core/drivers/crypto/versal/ecc_mbox.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/drivers/crypto/versal/ecc_mbox.c b/core/drivers/crypto/versal/ecc_mbox.c index fa2e800210b..bf0a9c3f721 100644 --- a/core/drivers/crypto/versal/ecc_mbox.c +++ b/core/drivers/crypto/versal/ecc_mbox.c @@ -310,8 +310,8 @@ TEE_Result versal_ecc_kat_test(void) TEE_Result versal_ecc_gen_keypair(struct ecc_keypair *s __maybe_unused) { /* - * Versal requires little endian so need to versal_memcpy_swp on Versal IP - * ops. We chose not to do it here because some tests might be using + * Versal requires little endian so need to versal_memcpy_swp on Versal + * IP ops. We chose not to do it here because some tests might be using * their own keys */ From 456e01791973cbd42f96ffc7b8325d712383832c Mon Sep 17 00:00:00 2001 From: Jeremie Corbier Date: Thu, 19 Sep 2024 14:18:46 +0200 Subject: [PATCH 43/43] fixup! drivers: versal: NVM driver for Versal Net Signed-off-by: Jeremie Corbier --- core/drivers/versal_net_nvm.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/core/drivers/versal_net_nvm.c b/core/drivers/versal_net_nvm.c index 9f8bc10e3fb..2b402cf7141 100644 --- a/core/drivers/versal_net_nvm.c +++ b/core/drivers/versal_net_nvm.c @@ -449,8 +449,8 @@ TEE_Result versal_efuse_read_revoke_id(uint32_t *buf, size_t len, uint32_t id) { uint32_t reg = EFUSE_CACHE_REVOCATION_ID0_OFFSET; - if ((id < VERSAL_NET_REVOKE_EFUSE_MIN) || - (id > VERSAL_NET_REVOKE_EFUSE_MAX)) + if (id < VERSAL_NET_REVOKE_EFUSE_MIN || + id > VERSAL_NET_REVOKE_EFUSE_MAX) return TEE_ERROR_BAD_PARAMETERS; reg += (id - 1) / 8; @@ -572,8 +572,8 @@ TEE_Result versal_efuse_read_offchip_revoke_id(uint32_t *buf, size_t len, { uint32_t reg = EFUSE_CACHE_OFFCHIP_REVOKE_ID0_OFFSET; - if ((id < VERSAL_NET_REVOKE_EFUSE_MIN) || - (id > VERSAL_NET_REVOKE_EFUSE_MAX)) + if (id < VERSAL_NET_REVOKE_EFUSE_MIN || + id > VERSAL_NET_REVOKE_EFUSE_MAX) return TEE_ERROR_BAD_PARAMETERS; reg += (id - 1) / 8; @@ -838,13 +838,15 @@ TEE_Result versal_efuse_write_iv(struct versal_efuse_ivs *p) res2 = do_write_efuses_buffer(EFUSE_WRITE_IV, EFUSE_BLACK_IV, p->blk_obfus_iv, EFUSE_IV_LEN); if (res2) { - DMSG("Error programming black IV (0x%" PRIx32 ")", res2); + DMSG("Error programming black IV (0x%" PRIx32 ")", + res2); res = TEE_ERROR_GENERIC; } } if (p->prgm_plm_iv) { - res2 = do_write_efuses_buffer(EFUSE_WRITE_IV, EFUSE_PLM_IV_RANGE, + res2 = do_write_efuses_buffer(EFUSE_WRITE_IV, + EFUSE_PLM_IV_RANGE, p->plm_iv, EFUSE_IV_LEN); if (res2) { DMSG("Error programming plm IV (0x%" PRIx32 ")", res2); @@ -978,12 +980,12 @@ TEE_Result versal_efuse_write_sec_misc1(struct versal_efuse_sec_misc1_bits *p) /* * versal_efuse_write_offchip_ids expects an efuse identifier between - * 1 and 256. + * 1 and 256. */ TEE_Result versal_efuse_write_offchip_ids(uint32_t id) { - if ((id < VERSAL_NET_REVOKE_EFUSE_MIN) || - (id > VERSAL_NET_REVOKE_EFUSE_MAX)) + if (id < VERSAL_NET_REVOKE_EFUSE_MIN || + id > VERSAL_NET_REVOKE_EFUSE_MAX) return TEE_ERROR_BAD_PARAMETERS; return do_write_efuses_value(EFUSE_WRITE_OFFCHIP_REVOKE_ID, id); @@ -1012,12 +1014,12 @@ TEE_Result versal_efuse_write_revoke_ppk(enum versal_nvm_ppk_type type) /* * versal_efuse_write_revoke_id expects an efuse identifier between - * 1 and 256. + * 1 and 256. */ TEE_Result versal_efuse_write_revoke_id(uint32_t id) { - if ((id < VERSAL_NET_REVOKE_EFUSE_MIN) || - (id > VERSAL_NET_REVOKE_EFUSE_MAX)) + if (id < VERSAL_NET_REVOKE_EFUSE_MIN || + id > VERSAL_NET_REVOKE_EFUSE_MAX) return TEE_ERROR_BAD_PARAMETERS; return do_write_efuses_value(EFUSE_WRITE_REVOCATION_ID, id);