summaryrefslogtreecommitdiff
path: root/meta-arm/meta-arm-bsp/recipes-security
diff options
context:
space:
mode:
Diffstat (limited to 'meta-arm/meta-arm-bsp/recipes-security')
-rw-r--r--meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0001-core-arm-add-MPIDR-affinity-shift-and-mask-for-32-bi.patch29
-rw-r--r--meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0002-plat-n1sdp-add-N1SDP-platform-support.patch233
-rw-r--r--meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0003-HACK-disable-instruction-cache-and-data-cache.patch46
-rw-r--r--meta-arm/meta-arm-bsp/recipes-security/optee/files/optee-os/n1sdp/0004-Handle-logging-syscall.patch33
-rw-r--r--meta-arm/meta-arm-bsp/recipes-security/optee/optee-os-n1sdp.inc22
-rw-r--r--meta-arm/meta-arm-bsp/recipes-security/optee/optee-os_3.18.0.bbappend6
-rw-r--r--meta-arm/meta-arm-bsp/recipes-security/trusted-services/secure-partitions/corstone1000/0048-Fix-UEFI-get_variable-with-small-buffer.patch407
-rw-r--r--meta-arm/meta-arm-bsp/recipes-security/trusted-services/ts-corstone1000.inc1
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"