diff options
Diffstat (limited to 'meta-arm/meta-arm-bsp/recipes-security')
8 files changed, 777 insertions, 0 deletions
diff --git a/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0001-core-arm-add-MPIDR-affinity-shift-and-mask-for-32-bi.patch b/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0001-core-arm-add-MPIDR-affinity-shift-and-mask-for-32-bi.patch new file mode 100644 index 0000000000..f249e526a8 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0001-core-arm-add-MPIDR-affinity-shift-and-mask-for-32-bi.patch @@ -0,0 +1,29 @@ +Upstream-Status: Pending [Not submitted to upstream yet] +Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com> + +From cf84c933bb7b8a95742d1e723950cb2cde2d5320 Mon Sep 17 00:00:00 2001 +From: Vishnu Banavath <vishnu.banavath@arm.com> +Date: Wed, 20 Jul 2022 16:37:10 +0100 +Subject: [PATCH] core: arm: add MPIDR affinity shift and mask for 32-bit + +This change is to add MPIDR affinity shift and mask for +32-bit + +Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com> + +diff --git a/core/arch/arm/include/arm.h b/core/arch/arm/include/arm.h +index f59478af..2f6f82e7 100644 +--- a/core/arch/arm/include/arm.h ++++ b/core/arch/arm/include/arm.h +@@ -63,6 +63,8 @@ + #define MPIDR_AFF1_MASK (MPIDR_AFFLVL_MASK << MPIDR_AFF1_SHIFT) + #define MPIDR_AFF2_SHIFT U(16) + #define MPIDR_AFF2_MASK (MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT) ++#define MPIDR_AFF3_SHIFT U(32) ++#define MPIDR_AFF3_MASK (MPIDR_AFFLVL_MASK << MPIDR_AFF3_SHIFT) + + #define MPIDR_MT_SHIFT U(24) + #define MPIDR_MT_MASK BIT(MPIDR_MT_SHIFT) +-- +2.17.1 + diff --git a/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0002-plat-n1sdp-add-N1SDP-platform-support.patch b/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0002-plat-n1sdp-add-N1SDP-platform-support.patch new file mode 100644 index 0000000000..db195ab337 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0002-plat-n1sdp-add-N1SDP-platform-support.patch @@ -0,0 +1,233 @@ +Upstream-Status: Pending [Not submitted to upstream yet] +Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com> + +From 22ba7c7789082dbc179921962cdcadece4499c89 Mon Sep 17 00:00:00 2001 +From: Vishnu Banavath <vishnu.banavath@arm.com> +Date: Thu, 30 Jun 2022 18:36:26 +0100 +Subject: [PATCH] plat-n1sdp: add N1SDP platform support + +These changes are to add N1SDP platform to optee-os + +Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com> + +diff --git a/core/arch/arm/plat-n1sdp/conf.mk b/core/arch/arm/plat-n1sdp/conf.mk +new file mode 100644 +index 00000000..06b4975a +--- /dev/null ++++ b/core/arch/arm/plat-n1sdp/conf.mk +@@ -0,0 +1,41 @@ ++include core/arch/arm/cpu/cortex-armv8-0.mk ++ ++CFG_DEBUG_INFO = y ++CFG_TEE_CORE_LOG_LEVEL = 4 ++ ++# Workaround 808870: Unconditional VLDM instructions might cause an ++# alignment fault even though the address is aligned ++# Either hard float must be disabled for AArch32 or strict alignment checks ++# must be disabled ++ifeq ($(CFG_SCTLR_ALIGNMENT_CHECK),y) ++$(call force,CFG_TA_ARM32_NO_HARD_FLOAT_SUPPORT,y) ++else ++$(call force,CFG_SCTLR_ALIGNMENT_CHECK,n) ++endif ++ ++CFG_ARM64_core ?= y ++ ++CFG_ARM_GICV3 = y ++ ++# ARM debugger needs this ++platform-cflags-debug-info = -gdwarf-4 ++platform-aflags-debug-info = -gdwarf-4 ++ ++CFG_CORE_SEL1_SPMC = y ++CFG_WITH_ARM_TRUSTED_FW = y ++ ++$(call force,CFG_GIC,y) ++$(call force,CFG_PL011,y) ++$(call force,CFG_SECURE_TIME_SOURCE_CNTPCT,y) ++ ++CFG_CORE_HEAP_SIZE = 0x32000 # 200kb ++ ++CFG_TEE_CORE_NB_CORE = 4 ++CFG_TZDRAM_START ?= 0x08000000 ++CFG_TZDRAM_SIZE ?= 0x02008000 ++ ++CFG_SHMEM_START ?= 0x83000000 ++CFG_SHMEM_SIZE ?= 0x00210000 ++# DRAM1 is defined above 4G ++$(call force,CFG_CORE_LARGE_PHYS_ADDR,y) ++$(call force,CFG_CORE_ARM64_PA_BITS,36) +diff --git a/core/arch/arm/plat-n1sdp/main.c b/core/arch/arm/plat-n1sdp/main.c +new file mode 100644 +index 00000000..cfb7f19b +--- /dev/null ++++ b/core/arch/arm/plat-n1sdp/main.c +@@ -0,0 +1,63 @@ ++// SPDX-License-Identifier: BSD-2-Clause ++/* ++ * Copyright (c) 2022, Arm Limited. ++ */ ++ ++#include <arm.h> ++#include <console.h> ++#include <drivers/gic.h> ++#include <drivers/pl011.h> ++#include <drivers/tpm2_mmio.h> ++#include <drivers/tpm2_ptp_fifo.h> ++#include <drivers/tzc400.h> ++#include <initcall.h> ++#include <keep.h> ++#include <kernel/boot.h> ++#include <kernel/interrupt.h> ++#include <kernel/misc.h> ++#include <kernel/notif.h> ++#include <kernel/panic.h> ++#include <kernel/spinlock.h> ++#include <kernel/tee_time.h> ++#include <mm/core_memprot.h> ++#include <mm/core_mmu.h> ++#include <platform_config.h> ++#include <sm/psci.h> ++#include <stdint.h> ++#include <string.h> ++#include <trace.h> ++ ++static struct gic_data gic_data __nex_bss; ++static struct pl011_data console_data __nex_bss; ++ ++register_phys_mem_pgdir(MEM_AREA_IO_SEC, CONSOLE_UART_BASE, PL011_REG_SIZE); ++ ++register_ddr(DRAM0_BASE, DRAM0_SIZE); ++ ++register_phys_mem_pgdir(MEM_AREA_IO_SEC, GICD_BASE, GIC_DIST_REG_SIZE); ++register_phys_mem_pgdir(MEM_AREA_IO_SEC, GICC_BASE, GIC_DIST_REG_SIZE); ++register_phys_mem_pgdir(MEM_AREA_IO_SEC, GICR_BASE, GIC_DIST_REG_SIZE); ++ ++void main_init_gic(void) ++{ ++ gic_init_base_addr(&gic_data, GICC_BASE, ++ GICD_BASE); ++ itr_init(&gic_data.chip); ++} ++ ++void main_secondary_init_gic(void) ++{ ++ gic_cpu_init(&gic_data); ++} ++ ++void itr_core_handler(void) ++{ ++ gic_it_handle(&gic_data); ++} ++ ++void console_init(void) ++{ ++ pl011_init(&console_data, CONSOLE_UART_BASE, CONSOLE_UART_CLK_IN_HZ, ++ CONSOLE_BAUDRATE); ++ register_serial_console(&console_data.chip); ++} +diff --git a/core/arch/arm/plat-n1sdp/n1sdp_core_pos.S b/core/arch/arm/plat-n1sdp/n1sdp_core_pos.S +new file mode 100644 +index 00000000..439d4e67 +--- /dev/null ++++ b/core/arch/arm/plat-n1sdp/n1sdp_core_pos.S +@@ -0,0 +1,32 @@ ++/* SPDX-License-Identifier: BSD-2-Clause */ ++/* ++ * Copyright (c) 2022, Arm Limited ++ */ ++ ++#include <asm.S> ++#include <arm.h> ++#include "platform_config.h" ++ ++FUNC get_core_pos_mpidr , : ++ mov x4, x0 ++ ++ /* ++ * The MT bit in MPIDR is always set for n1sdp and the ++ * affinity level 0 corresponds to thread affinity level. ++ */ ++ ++ /* Extract individual affinity fields from MPIDR */ ++ ubfx x0, x4, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS ++ ubfx x1, x4, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS ++ ubfx x2, x4, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS ++ ubfx x3, x4, #MPIDR_AFF3_SHIFT, #MPIDR_AFFINITY_BITS ++ ++ /* Compute linear position */ ++ mov x4, #N1SDP_MAX_CLUSTERS_PER_CHIP ++ madd x2, x3, x4, x2 ++ mov x4, #N1SDP_MAX_CPUS_PER_CLUSTER ++ madd x1, x2, x4, x1 ++ mov x4, #N1SDP_MAX_PE_PER_CPU ++ madd x0, x1, x4, x0 ++ ret ++END_FUNC get_core_pos_mpidr +diff --git a/core/arch/arm/plat-n1sdp/platform_config.h b/core/arch/arm/plat-n1sdp/platform_config.h +new file mode 100644 +index 00000000..81b99409 +--- /dev/null ++++ b/core/arch/arm/plat-n1sdp/platform_config.h +@@ -0,0 +1,49 @@ ++/* SPDX-License-Identifier: BSD-2-Clause */ ++/* ++ * Copyright (c) 2022, Arm Limited ++ */ ++ ++#ifndef PLATFORM_CONFIG_H ++#define PLATFORM_CONFIG_H ++ ++#include <mm/generic_ram_layout.h> ++#include <stdint.h> ++ ++/* Make stacks aligned to data cache line length */ ++#define STACK_ALIGNMENT 64 ++ ++ /* N1SDP topology related constants */ ++#define N1SDP_MAX_CPUS_PER_CLUSTER U(2) ++#define PLAT_ARM_CLUSTER_COUNT U(2) ++#define PLAT_N1SDP_CHIP_COUNT U(2) ++#define N1SDP_MAX_CLUSTERS_PER_CHIP U(2) ++#define N1SDP_MAX_PE_PER_CPU U(1) ++ ++#define PLATFORM_CORE_COUNT (PLAT_N1SDP_CHIP_COUNT * \ ++ PLAT_ARM_CLUSTER_COUNT * \ ++ N1SDP_MAX_CPUS_PER_CLUSTER * \ ++ N1SDP_MAX_PE_PER_CPU) ++ ++#define GIC_BASE 0x2c010000 ++ ++#define UART1_BASE 0x1C0A0000 ++#define UART1_CLK_IN_HZ 24000000 /*24MHz*/ ++ ++#define CONSOLE_UART_BASE UART1_BASE ++#define CONSOLE_UART_CLK_IN_HZ UART1_CLK_IN_HZ ++ ++#define DRAM0_BASE 0x80000000 ++#define DRAM0_SIZE 0x80000000 ++ ++#define GICD_BASE 0x30000000 ++#define GICC_BASE 0x2C000000 ++#define GICR_BASE 0x300C0000 ++ ++#ifndef UART_BAUDRATE ++#define UART_BAUDRATE 115200 ++#endif ++#ifndef CONSOLE_BAUDRATE ++#define CONSOLE_BAUDRATE UART_BAUDRATE ++#endif ++ ++#endif /*PLATFORM_CONFIG_H*/ +diff --git a/core/arch/arm/plat-n1sdp/sub.mk b/core/arch/arm/plat-n1sdp/sub.mk +new file mode 100644 +index 00000000..a0b49da1 +--- /dev/null ++++ b/core/arch/arm/plat-n1sdp/sub.mk +@@ -0,0 +1,3 @@ ++global-incdirs-y += . ++srcs-y += main.c ++srcs-y += n1sdp_core_pos.S +-- +2.17.1 + diff --git a/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0003-HACK-disable-instruction-cache-and-data-cache.patch b/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0003-HACK-disable-instruction-cache-and-data-cache.patch new file mode 100644 index 0000000000..e8f4cc44dc --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0003-HACK-disable-instruction-cache-and-data-cache.patch @@ -0,0 +1,46 @@ +Upstream-Status: Pending [Not submitted to upstream yet] +Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com> + +From 0c3ce4c09cd7d2ff4cd2e62acab899dd88dc9514 Mon Sep 17 00:00:00 2001 +From: Vishnu Banavath <vishnu.banavath@arm.com> +Date: Wed, 20 Jul 2022 16:45:59 +0100 +Subject: [PATCH] HACK: disable instruction cache and data cache. + +For some reason, n1sdp fails to boot with instruction cache and +data cache enabled. This is a temporary change to disable I cache +and D cache until a proper fix is found. + +Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com> + +%% original patch: 0003-HACK-disable-instruction-cache-and-data-cache.patch + +diff --git a/core/arch/arm/kernel/entry_a64.S b/core/arch/arm/kernel/entry_a64.S +index 875b6e69..594d6928 100644 +--- a/core/arch/arm/kernel/entry_a64.S ++++ b/core/arch/arm/kernel/entry_a64.S +@@ -52,7 +52,7 @@ + + .macro set_sctlr_el1 + mrs x0, sctlr_el1 +- orr x0, x0, #SCTLR_I ++ bic x0, x0, #SCTLR_I + orr x0, x0, #SCTLR_SA + orr x0, x0, #SCTLR_SPAN + #if defined(CFG_CORE_RWDATA_NOEXEC) +@@ -490,11 +490,11 @@ LOCAL_FUNC enable_mmu , : , .identity_map + isb + + /* Enable I and D cache */ +- mrs x1, sctlr_el1 ++ /* mrs x1, sctlr_el1 + orr x1, x1, #SCTLR_I + orr x1, x1, #SCTLR_C + msr sctlr_el1, x1 +- isb ++ isb */ + + /* Adjust stack pointers and return address */ + msr spsel, #1 +-- +2.17.1 + diff --git a/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0004-Handle-logging-syscall.patch b/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0004-Handle-logging-syscall.patch new file mode 100644 index 0000000000..356be9e04f --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0004-Handle-logging-syscall.patch @@ -0,0 +1,33 @@ +Upstream-Status: Pending [Not submitted to upstream yet] +Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com> + +From b3fde6c2e1a950214f760ab9f194f3a6572292a8 Mon Sep 17 00:00:00 2001 +From: Balint Dobszay <balint.dobszay@arm.com> +Date: Fri, 15 Jul 2022 13:45:54 +0200 +Subject: [PATCH] Handle logging syscall + +Signed-off-by: Balint Dobszay <balint.dobszay@arm.com> +Change-Id: Ib8151cc9c66aea8bcc8fe8b1ecdc3f9f9c5f14e4 + +%% original patch: 0004-Handle-logging-syscall.patch + +diff --git a/core/arch/arm/kernel/spmc_sp_handler.c b/core/arch/arm/kernel/spmc_sp_handler.c +index e0fa0aa6..c7a45387 100644 +--- a/core/arch/arm/kernel/spmc_sp_handler.c ++++ b/core/arch/arm/kernel/spmc_sp_handler.c +@@ -1004,6 +1004,12 @@ void spmc_sp_msg_handler(struct thread_smc_args *args, + ffa_mem_reclaim(args, caller_sp); + sp_enter(args, caller_sp); + break; ++ case 0xdeadbeef: ++ ts_push_current_session(&caller_sp->ts_sess); ++ IMSG("%s", (char *)args->a1); ++ ts_pop_current_session(); ++ sp_enter(args, caller_sp); ++ break; + default: + EMSG("Unhandled FFA function ID %#"PRIx32, + (uint32_t)args->a0); +-- +2.17.1 + diff --git a/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os-n1sdp.inc b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os-n1sdp.inc new file mode 100644 index 0000000000..219f08bfd7 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os-n1sdp.inc @@ -0,0 +1,22 @@ +# N1 SDP specific configuration for optee-os + +COMPATIBLE_MACHINE:n1sdp = "n1sdp" +OPTEEMACHINE:n1sdp = "n1sdp" + +TS_INSTALL_PREFIX_PATH = "${RECIPE_SYSROOT}/firmware/sp/opteesp" + +FILESEXTRAPATHS:prepend := "${THISDIR}/files/optee-os/n1sdp:" +SRC_URI:append = " \ + file://0001-core-arm-add-MPIDR-affinity-shift-and-mask-for-32-bi.patch \ + file://0002-plat-n1sdp-add-N1SDP-platform-support.patch \ + file://0003-HACK-disable-instruction-cache-and-data-cache.patch \ + file://0004-Handle-logging-syscall.patch \ + " + +EXTRA_OEMAKE += " CFG_TEE_CORE_LOG_LEVEL=4" + +EXTRA_OEMAKE += " CFG_TEE_BENCHMARK=n" + +EXTRA_OEMAKE += " CFG_CORE_SEL1_SPMC=y CFG_CORE_FFA=y" + +EXTRA_OEMAKE += " CFG_WITH_SP=y" diff --git a/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os_3.18.0.bbappend b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os_3.18.0.bbappend new file mode 100644 index 0000000000..f80e09f82d --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os_3.18.0.bbappend @@ -0,0 +1,6 @@ +# Machine specific configurations + +MACHINE_OPTEE_OS_REQUIRE ?= "" +MACHINE_OPTEE_OS_REQUIRE:n1sdp = "optee-os-n1sdp.inc" + +require ${MACHINE_OPTEE_OS_REQUIRE} diff --git a/meta-arm/meta-arm-bsp/recipes-security/trusted-services/secure-partitions/corstone1000/0048-Fix-UEFI-get_variable-with-small-buffer.patch b/meta-arm/meta-arm-bsp/recipes-security/trusted-services/secure-partitions/corstone1000/0048-Fix-UEFI-get_variable-with-small-buffer.patch new file mode 100644 index 0000000000..e4573a5196 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-security/trusted-services/secure-partitions/corstone1000/0048-Fix-UEFI-get_variable-with-small-buffer.patch @@ -0,0 +1,407 @@ +Upstream-Status: Pending +Signed-off-by: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com> + +From 2d975e5ec5df6f81d6c35fe927f72d49181142f8 Mon Sep 17 00:00:00 2001 +From: Julian Hall <julian.hall@arm.com> +Date: Tue, 19 Jul 2022 12:43:30 +0100 +Subject: [PATCH] Fix UEFI get_variable with small buffer + +The handling of the UEFI get_variable operation was incorrect when +a small or zero data length was specified by a requester. A zero +length data length is a legitimate way to discover the size of a +variable without actually retrieving its data. This change adds +test cases that reproduce the problem and a fix. + +Signed-off-by: Julian Hall <julian.hall@arm.com> +Change-Id: Iec087fbf9305746d1438888e871602ec0ce15824 +--- + .../backend/test/variable_store_tests.cpp | 60 ++++++++++++++++-- + .../backend/uefi_variable_store.c | 46 +++++++++++--- + .../client/cpp/smm_variable_client.cpp | 33 +++++----- + .../client/cpp/smm_variable_client.h | 8 ++- + .../provider/smm_variable_provider.c | 2 +- + .../service/smm_variable_service_tests.cpp | 62 +++++++++++++++++++ + 6 files changed, 179 insertions(+), 32 deletions(-) + +diff --git a/components/service/smm_variable/backend/test/variable_store_tests.cpp b/components/service/smm_variable/backend/test/variable_store_tests.cpp +index 235642e6..98faf761 100644 +--- a/components/service/smm_variable/backend/test/variable_store_tests.cpp ++++ b/components/service/smm_variable/backend/test/variable_store_tests.cpp +@@ -128,7 +128,8 @@ TEST_GROUP(UefiVariableStoreTests) + + efi_status_t get_variable( + const std::wstring &name, +- std::string &data) ++ std::string &data, ++ size_t data_len_clamp = VARIABLE_BUFFER_SIZE) + { + std::vector<int16_t> var_name = to_variable_name(name); + size_t name_size = var_name.size() * sizeof(int16_t); +@@ -144,21 +145,40 @@ TEST_GROUP(UefiVariableStoreTests) + access_variable->NameSize = name_size; + memcpy(access_variable->Name, var_name.data(), name_size); + +- access_variable->DataSize = 0; ++ size_t max_data_len = (data_len_clamp == VARIABLE_BUFFER_SIZE) ? ++ VARIABLE_BUFFER_SIZE - ++ SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_DATA_OFFSET(access_variable) : ++ data_len_clamp; ++ ++ access_variable->DataSize = max_data_len; + + efi_status_t status = uefi_variable_store_get_variable( + &m_uefi_variable_store, + access_variable, +- VARIABLE_BUFFER_SIZE - +- SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_DATA_OFFSET(access_variable), ++ max_data_len, + &total_size); + ++ data.clear(); ++ + if (status == EFI_SUCCESS) { + + const char *data_start = (const char*)(msg_buffer + + SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_DATA_OFFSET(access_variable)); + + data = std::string(data_start, access_variable->DataSize); ++ ++ UNSIGNED_LONGLONGS_EQUAL( ++ SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_TOTAL_SIZE(access_variable), ++ total_size); ++ } ++ else if (status == EFI_BUFFER_TOO_SMALL) { ++ ++ /* String length set to reported variable length */ ++ data.insert(0, access_variable->DataSize, '!'); ++ ++ UNSIGNED_LONGLONGS_EQUAL( ++ SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_DATA_OFFSET(access_variable), ++ total_size); + } + + return status; +@@ -336,6 +356,38 @@ TEST(UefiVariableStoreTests, persistentSetGet) + LONGS_EQUAL(0, input_data.compare(output_data)); + } + ++TEST(UefiVariableStoreTests, getWithSmallBuffer) ++{ ++ efi_status_t status = EFI_SUCCESS; ++ std::wstring var_name = L"test_variable"; ++ std::string input_data = "quick brown fox"; ++ std::string output_data; ++ ++ /* A get with a zero length buffer is a legitimate way to ++ * discover the variable size. This test performs GetVariable ++ * operations with various buffer small buffer sizes. */ ++ status = set_variable(var_name, input_data, 0); ++ UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status); ++ ++ /* First get the variable without a constrained buffer */ ++ status = get_variable(var_name, output_data); ++ UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status); ++ ++ /* Expect got variable data to be the same as the set value */ ++ UNSIGNED_LONGLONGS_EQUAL(input_data.size(), output_data.size()); ++ LONGS_EQUAL(0, input_data.compare(output_data)); ++ ++ /* Now try with a zero length buffer */ ++ status = get_variable(var_name, output_data, 0); ++ UNSIGNED_LONGLONGS_EQUAL(EFI_BUFFER_TOO_SMALL, status); ++ UNSIGNED_LONGLONGS_EQUAL(input_data.size(), output_data.size()); ++ ++ /* Try with a non-zero length but too small buffer */ ++ status = get_variable(var_name, output_data, input_data.size() -1); ++ UNSIGNED_LONGLONGS_EQUAL(EFI_BUFFER_TOO_SMALL, status); ++ UNSIGNED_LONGLONGS_EQUAL(input_data.size(), output_data.size()); ++} ++ + TEST(UefiVariableStoreTests, removeVolatile) + { + efi_status_t status = EFI_SUCCESS; +diff --git a/components/service/smm_variable/backend/uefi_variable_store.c b/components/service/smm_variable/backend/uefi_variable_store.c +index e8771c21..90d648de 100644 +--- a/components/service/smm_variable/backend/uefi_variable_store.c ++++ b/components/service/smm_variable/backend/uefi_variable_store.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2021, Arm Limited. All rights reserved. ++ * Copyright (c) 2021-2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * +@@ -294,7 +294,10 @@ efi_status_t uefi_variable_store_get_variable( + + status = load_variable_data(context, info, var, max_data_len); + var->Attributes = info->metadata.attributes; +- *total_length = SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_TOTAL_SIZE(var); ++ ++ *total_length = (status == EFI_SUCCESS) ? ++ SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_TOTAL_SIZE(var) : ++ SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_DATA_OFFSET(var); + } + } + +@@ -682,7 +685,6 @@ static efi_status_t load_variable_data( + { + EMSG("In func %s\n", __func__); + psa_status_t psa_status = PSA_SUCCESS; +- size_t data_len = 0; + uint8_t *data = (uint8_t*)var + + SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_DATA_OFFSET(var); + +@@ -692,17 +694,41 @@ static efi_status_t load_variable_data( + + if (delegate_store->storage_backend) { + +- psa_status = delegate_store->storage_backend->interface->get( ++ struct psa_storage_info_t storage_info; ++ ++ psa_status = delegate_store->storage_backend->interface->get_info( + delegate_store->storage_backend->context, + context->owner_id, + info->metadata.uid, +- 0, +- max_data_len, +- data, +- &data_len); +- EMSG("In func %s get status is %d\n", __func__, psa_status); ++ &storage_info); ++ ++ if (psa_status == PSA_SUCCESS) { + +- var->DataSize = data_len; ++ size_t get_limit = (var->DataSize < max_data_len) ? ++ var->DataSize : ++ max_data_len; ++ ++ if (get_limit >= storage_info.size) { ++ ++ size_t got_len = 0; ++ ++ psa_status = delegate_store->storage_backend->interface->get( ++ delegate_store->storage_backend->context, ++ context->owner_id, ++ info->metadata.uid, ++ 0, ++ max_data_len, ++ data, ++ &got_len); ++ ++ var->DataSize = got_len; ++ } ++ else { ++ ++ var->DataSize = storage_info.size; ++ psa_status = PSA_ERROR_BUFFER_TOO_SMALL; ++ } ++ } + } + + return psa_to_efi_storage_status(psa_status); +diff --git a/components/service/smm_variable/client/cpp/smm_variable_client.cpp b/components/service/smm_variable/client/cpp/smm_variable_client.cpp +index 8438285b..b6b4ed90 100644 +--- a/components/service/smm_variable/client/cpp/smm_variable_client.cpp ++++ b/components/service/smm_variable/client/cpp/smm_variable_client.cpp +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. ++ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -122,21 +122,22 @@ efi_status_t smm_variable_client::get_variable( + guid, + name, + data, +- 0); ++ 0, ++ MAX_VAR_DATA_SIZE); + } + + efi_status_t smm_variable_client::get_variable( + const EFI_GUID &guid, + const std::wstring &name, + std::string &data, +- size_t override_name_size) ++ size_t override_name_size, ++ size_t max_data_size) + { + efi_status_t efi_status = EFI_NOT_READY; + + std::vector<int16_t> var_name = to_variable_name(name); + size_t name_size = var_name.size() * sizeof(int16_t); +- size_t data_size = 0; +- size_t req_len = SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_SIZE(name_size, data_size); ++ size_t req_len = SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_SIZE(name_size, 0); + + rpc_call_handle call_handle; + uint8_t *req_buf; +@@ -154,7 +155,7 @@ efi_status_t smm_variable_client::get_variable( + + access_var->Guid = guid; + access_var->NameSize = name_size; +- access_var->DataSize = data_size; ++ access_var->DataSize = max_data_size; + + memcpy(access_var->Name, var_name.data(), name_size); + +@@ -168,26 +169,28 @@ efi_status_t smm_variable_client::get_variable( + + efi_status = opstatus; + +- if (efi_status == EFI_SUCCESS) { +- +- efi_status = EFI_PROTOCOL_ERROR; ++ if (resp_len >= SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET) { + +- if (resp_len >= SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET) { ++ access_var = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE*)resp_buf; ++ size_t data_size = access_var->DataSize; + +- access_var = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE*)resp_buf; ++ if (resp_len >= ++ SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_TOTAL_SIZE(access_var)) { + +- if (resp_len >= +- SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_TOTAL_SIZE(access_var)) { ++ if (efi_status == EFI_SUCCESS) { + +- data_size = access_var->DataSize; + const char *data_start = (const char*) + &resp_buf[ + SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_DATA_OFFSET(access_var)]; + + data.assign(data_start, data_size); +- efi_status = EFI_SUCCESS; + } + } ++ else if (efi_status == EFI_BUFFER_TOO_SMALL) { ++ ++ data.clear(); ++ data.insert(0, data_size, '!'); ++ } + } + } + else { +diff --git a/components/service/smm_variable/client/cpp/smm_variable_client.h b/components/service/smm_variable/client/cpp/smm_variable_client.h +index c7973916..3d2371a8 100644 +--- a/components/service/smm_variable/client/cpp/smm_variable_client.h ++++ b/components/service/smm_variable/client/cpp/smm_variable_client.h +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. ++ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -56,7 +56,8 @@ public: + const EFI_GUID &guid, + const std::wstring &name, + std::string &data, +- size_t override_name_size); ++ size_t override_name_size, ++ size_t max_data_size = MAX_VAR_DATA_SIZE); + + /* Remove a variable */ + efi_status_t remove_variable( +@@ -113,6 +114,9 @@ public: + + + private: ++ ++ static const size_t MAX_VAR_DATA_SIZE = 65536; ++ + efi_status_t rpc_to_efi_status() const; + + static std::vector<int16_t> to_variable_name(const std::wstring &string); +diff --git a/components/service/smm_variable/provider/smm_variable_provider.c b/components/service/smm_variable/provider/smm_variable_provider.c +index 1f362c17..95c4fdc9 100644 +--- a/components/service/smm_variable/provider/smm_variable_provider.c ++++ b/components/service/smm_variable/provider/smm_variable_provider.c +@@ -165,7 +165,7 @@ static rpc_status_t get_variable_handler(void *context, struct call_req *req) + } + else { + +- /* Reponse buffer not big enough */ ++ /* Response buffer not big enough */ + efi_status = EFI_BAD_BUFFER_SIZE; + } + } +diff --git a/components/service/smm_variable/test/service/smm_variable_service_tests.cpp b/components/service/smm_variable/test/service/smm_variable_service_tests.cpp +index 38c08ebe..989a3e63 100644 +--- a/components/service/smm_variable/test/service/smm_variable_service_tests.cpp ++++ b/components/service/smm_variable/test/service/smm_variable_service_tests.cpp +@@ -284,6 +284,68 @@ TEST(SmmVariableServiceTests, setAndGetNv) + UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status); + } + ++TEST(SmmVariableServiceTests, getVarSize) ++{ ++ efi_status_t efi_status = EFI_SUCCESS; ++ std::wstring var_name = L"test_variable"; ++ std::string set_data = "UEFI variable data string"; ++ std::string get_data; ++ ++ efi_status = m_client->set_variable( ++ m_common_guid, ++ var_name, ++ set_data, ++ 0); ++ ++ UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status); ++ ++ /* Get with the data size set to zero. This is the standard way ++ * to discover the variable size. */ ++ efi_status = m_client->get_variable( ++ m_common_guid, ++ var_name, ++ get_data, ++ 0, 0); ++ ++ UNSIGNED_LONGLONGS_EQUAL(EFI_BUFFER_TOO_SMALL, efi_status); ++ UNSIGNED_LONGS_EQUAL(set_data.size(), get_data.size()); ++ ++ /* Expect remove to be permitted */ ++ efi_status = m_client->remove_variable(m_common_guid, var_name); ++ UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status); ++} ++ ++TEST(SmmVariableServiceTests, getVarSizeNv) ++{ ++ efi_status_t efi_status = EFI_SUCCESS; ++ std::wstring var_name = L"test_variable"; ++ std::string set_data = "UEFI variable data string"; ++ std::string get_data; ++ ++ efi_status = m_client->set_variable( ++ m_common_guid, ++ var_name, ++ set_data, ++ EFI_VARIABLE_NON_VOLATILE); ++ ++ UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status); ++ ++ /* Get with the data size set to zero. This is the standard way ++ * to discover the variable size. */ ++ efi_status = m_client->get_variable( ++ m_common_guid, ++ var_name, ++ get_data, ++ 0, 0); ++ ++ UNSIGNED_LONGLONGS_EQUAL(EFI_BUFFER_TOO_SMALL, efi_status); ++ UNSIGNED_LONGS_EQUAL(set_data.size(), get_data.size()); ++ ++ /* Expect remove to be permitted */ ++ efi_status = m_client->remove_variable(m_common_guid, var_name); ++ UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status); ++} ++ + TEST(SmmVariableServiceTests, enumerateStoreContents) + { + efi_status_t efi_status = EFI_SUCCESS; +-- +2.17.1 + diff --git a/meta-arm/meta-arm-bsp/recipes-security/trusted-services/ts-corstone1000.inc b/meta-arm/meta-arm-bsp/recipes-security/trusted-services/ts-corstone1000.inc index 88c46a74b9..b04863fcfa 100644 --- a/meta-arm/meta-arm-bsp/recipes-security/trusted-services/ts-corstone1000.inc +++ b/meta-arm/meta-arm-bsp/recipes-security/trusted-services/ts-corstone1000.inc @@ -59,6 +59,7 @@ SRC_URI:append = " \ file://0046-Fix-update-psa_set_key_usage_flags-definition-to-the.patch \ file://0047-Fixes-in-AEAD-for-psa-arch-test-54-and-58.patch \ file://0003-corstone1000-port-crypto-config.patch;patchdir=../psa-arch-tests \ + file://0048-Fix-UEFI-get_variable-with-small-buffer.patch \ " SRC_URI_MBEDTLS = "git://github.com/ARMmbed/mbedtls.git;protocol=https;branch=development;name=mbedtls;destsuffix=git/mbedtls" |