1
0
mirror of https://git.yoctoproject.org/meta-arm synced 2026-05-07 16:59:30 +00:00

arm-bsp/trusted-services: corstone1000: add secure partitions support

support for ts-smm-gateway and ts-se-proxy secure partitions

Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
This commit is contained in:
Abdellatif El Khlifi
2022-09-27 14:36:45 +01:00
committed by Jon Mason
parent 56d53d4393
commit 36536b6055
55 changed files with 54 additions and 16019 deletions
@@ -40,6 +40,10 @@ EXTRA_IMAGEDEPENDS += "optee-os"
OPTEE_ARCH = "arm64"
OPTEE_BINARY = "tee-pager_v2.bin"
# Include smm-gateway and se-proxy SPs into optee-os binary
MACHINE_FEATURES += "ts-smm-gateway ts-se-proxy"
TS_PLATFORM = "arm/corstone1000"
# External System(Cortex-M3)
EXTRA_IMAGEDEPENDS += "external-system"
@@ -0,0 +1,36 @@
From d262ab277a87c1cda4f71137f6bb963066ba6997 Mon Sep 17 00:00:00 2001
From: Vishnu Banavath <vishnu.banavath@arm.com>
Date: Tue, 13 Sep 2022 16:46:14 +0100
Subject: [PATCH 26/27] plat: add corstone1000 platform to drivers/arm
This change is to add corstone1000 platform cmake. Smm gateway
uses SE proxy to route the calls for any NV storage.
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
---
platform/providers/arm/corstone1000/platform.cmake | 12 ++++++++++++
1 file changed, 12 insertions(+)
create mode 100644 platform/providers/arm/corstone1000/platform.cmake
diff --git a/platform/providers/arm/corstone1000/platform.cmake b/platform/providers/arm/corstone1000/platform.cmake
new file mode 100644
index 00000000..14a9f6b0
--- /dev/null
+++ b/platform/providers/arm/corstone1000/platform.cmake
@@ -0,0 +1,12 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Platform definition for the corstone1000 platform.
+#-------------------------------------------------------------------------------
+
+target_compile_definitions(${TGT} PRIVATE
+ SMM_GATEWAY_NV_STORE_SN="sn:ffa:46bb39d1-b4d9-45b5-88ff-040027dab249:1"
+)
+
--
2.17.1
@@ -1,33 +0,0 @@
From 73c27b917e15eb04f39eedac9b79e5011e8a754f Mon Sep 17 00:00:00 2001
From: Vishnu Banavath <vishnu.banavath@arm.com>
Date: Sat, 13 Nov 2021 07:47:44 +0000
Subject: [PATCH] tools/cmake/common: applying lowercase project convention
Lowercase convention should only apply on the paths inside TS
source-code.
Host build paths should not be lowercased. Otherwise, builds
with uppercase paths will break.
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
---
tools/cmake/common/AddPlatform.cmake | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/cmake/common/AddPlatform.cmake b/tools/cmake/common/AddPlatform.cmake
index ae34c6e4..31bcd8ca 100644
--- a/tools/cmake/common/AddPlatform.cmake
+++ b/tools/cmake/common/AddPlatform.cmake
@@ -37,8 +37,8 @@ function(add_platform)
set(TGT ${MY_PARAMS_TARGET} CACHE STRING "")
# Ensure file path conforms to lowercase project convention
- string(TOLOWER "${TS_PLATFORM_ROOT}/${TS_PLATFORM}/platform.cmake" _platdef)
- include(${_platdef})
+ string(TOLOWER "${TS_PLATFORM}/platform.cmake" _platdef)
+ include(${TS_PLATFORM_ROOT}/${_platdef})
set(CMAKE_CONFIGURE_DEPENDS ${_platdef})
unset(TGT CACHE)
@@ -1,32 +0,0 @@
From 146f4dfa73aa316d611188f63e3530cffe9200af Mon Sep 17 00:00:00 2001
From: Vishnu Banavath <vishnu.banavath@arm.com>
Date: Sat, 13 Nov 2021 07:51:53 +0000
Subject: [PATCH] fix EARLY_TA_PATHS env variable
Yocto cleans up environment varaibles at build time.
EARLY_TA_PATHS should be set a separate rule for securepartitions
to be included into optee-os image
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
---
environments/opteesp/sp.mk.in | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/environments/opteesp/sp.mk.in b/environments/opteesp/sp.mk.in
index c44ad59e..d67e2dca 100644
--- a/environments/opteesp/sp.mk.in
+++ b/environments/opteesp/sp.mk.in
@@ -14,7 +14,8 @@ ifeq (,${@EXPORT_SP_UUID@-included})
endif
ifeq (embedded,${SP_PACKAGING_METHOD})
-OPTEE_OS_COMMON_EXTRA_FLAGS+=EARLY_TA_PATHS+=${TS_INSTALL_PREFIX}/opteesp/bin/@EXPORT_SP_UUID@.stripped.elf
+EARLY_TA_PATHS+=${TS_INSTALL_PREFIX}/bin/@EXPORT_SP_UUID@.stripped.elf
+OPTEE_OS_COMMON_EXTRA_FLAGS+=${EARLY_TA_PATHS}
TS_SP_DTSI_LIST+="\\n\#include \"${TS_INSTALL_PREFIX}/opteesp/manifest/@EXPORT_SP_UUID@.dtsi\""
else ifeq (fip,${SP_PACKAGING_METHOD})
TS_SP_JSON_LIST+=${TS_INSTALL_PREFIX}/opteesp/json/@EXPORT_SP_NAME@.json
@@ -1,234 +0,0 @@
From f86f5b42d853d2a65f6753362361bbb95aac1800 Mon Sep 17 00:00:00 2001
From: Satish Kumar <satish.kumar01@arm.com>
Date: Sat, 11 Dec 2021 11:06:57 +0000
Subject: [PATCH] corstone1000: port crypto config
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
Signed-off-by: Satish Kumar <satish.kumar01@arm.com>
%% original patch: 0003-corstone1000-port-crypto-config.patch
---
.../nspe/pal_crypto_config.h | 83 +++++++++++++++----
1 file changed, 66 insertions(+), 17 deletions(-)
diff --git a/api-tests/platform/targets/tgt_dev_apis_linux/nspe/pal_crypto_config.h b/api-tests/platform/targets/tgt_dev_apis_linux/nspe/pal_crypto_config.h
index 844cd2e..c936bdd 100755
--- a/api-tests/platform/targets/tgt_dev_apis_linux/nspe/pal_crypto_config.h
+++ b/api-tests/platform/targets/tgt_dev_apis_linux/nspe/pal_crypto_config.h
@@ -1,5 +1,5 @@
/** @file
- * Copyright (c) 2021, Arm Limited or its affiliates. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited or its affiliates. All rights reserved.
* SPDX-License-Identifier : Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -34,10 +34,14 @@
*
* Comment macros to disable the types
*/
+#ifndef TF_M_PROFILE_SMALL
+#ifndef TF_M_PROFILE_MEDIUM
#define ARCH_TEST_RSA
#define ARCH_TEST_RSA_1024
#define ARCH_TEST_RSA_2048
#define ARCH_TEST_RSA_3072
+#endif
+#endif
/**
* \def ARCH_TEST_ECC
@@ -50,11 +54,17 @@
* Requires: ARCH_TEST_ECC
* Comment macros to disable the curve
*/
+#ifndef TF_M_PROFILE_SMALL
#define ARCH_TEST_ECC
#define ARCH_TEST_ECC_CURVE_SECP192R1
+#ifndef TF_M_PROFILE_MEDIUM
#define ARCH_TEST_ECC_CURVE_SECP224R1
+#endif
#define ARCH_TEST_ECC_CURVE_SECP256R1
+#ifndef TF_M_PROFILE_MEDIUM
#define ARCH_TEST_ECC_CURVE_SECP384R1
+#endif
+#endif
/**
* \def ARCH_TEST_AES
@@ -78,10 +88,10 @@
*
* Comment macros to disable the types
*/
-#define ARCH_TEST_DES
-#define ARCH_TEST_DES_1KEY
-#define ARCH_TEST_DES_2KEY
-#define ARCH_TEST_DES_3KEY
+//#define ARCH_TEST_DES
+//#define ARCH_TEST_DES_1KEY
+//#define ARCH_TEST_DES_2KEY
+//#define ARCH_TEST_DES_3KEY
/**
* \def ARCH_TEST_RAW
@@ -104,7 +114,7 @@
*
* Enable the ARC4 key type.
*/
-#define ARCH_TEST_ARC4
+//#define ARCH_TEST_ARC4
/**
* \def ARCH_TEST_CIPHER_MODE_CTR
@@ -113,7 +123,11 @@
*
* Requires: ARCH_TEST_CIPHER
*/
+#ifndef TF_M_PROFILE_SMALL
+#ifndef TF_M_PROFILE_MEDIUM
#define ARCH_TEST_CIPHER_MODE_CTR
+#endif
+#endif
/**
* \def ARCH_TEST_CIPHER_MODE_CFB
@@ -138,7 +152,11 @@
*
* Requires: ARCH_TEST_CIPHER, ARCH_TEST_AES, ARCH_TEST_CIPHER_MODE_CTR
*/
+#ifndef TF_M_PROFILE_SMALL
+#ifndef TF_M_PROFILE_MEDIUM
#define ARCH_TEST_CTR_AES
+#endif
+#endif
/**
* \def ARCH_TEST_CBC_AES
@@ -157,7 +175,11 @@
*
* Comment macros to disable the types
*/
+#ifndef TF_M_PROFILE_SMALL
+#ifndef TF_M_PROFILE_MEDIUM
#define ARCH_TEST_CBC_NO_PADDING
+#endif
+#endif
/**
* \def ARCH_TEST_CFB_AES
@@ -177,11 +199,15 @@
*
* Comment macros to disable the types
*/
+#ifndef TF_M_PROFILE_SMALL
+#ifndef TF_M_PROFILE_MEDIUM
#define ARCH_TEST_PKCS1V15
#define ARCH_TEST_RSA_PKCS1V15_SIGN
#define ARCH_TEST_RSA_PKCS1V15_SIGN_RAW
#define ARCH_TEST_RSA_PKCS1V15_CRYPT
#define ARCH_TEST_RSA_OAEP
+#endif
+#endif
/**
* \def ARCH_TEST_CBC_PKCS7
@@ -190,7 +216,11 @@
*
* Comment macros to disable the types
*/
+#ifndef TF_M_PROFILE_SMALL
+#ifndef TF_M_PROFILE_MEDIUM
#define ARCH_TEST_CBC_PKCS7
+#endif
+#endif
/**
* \def ARCH_TEST_ASYMMETRIC_ENCRYPTION
@@ -227,21 +257,27 @@
*
* Comment macros to disable the types
*/
-// #define ARCH_TEST_MD2
-// #define ARCH_TEST_MD4
-#define ARCH_TEST_MD5
-#define ARCH_TEST_RIPEMD160
-#define ARCH_TEST_SHA1
+//#define ARCH_TEST_MD2
+//#define ARCH_TEST_MD4
+//#define ARCH_TEST_MD5
+//#define ARCH_TEST_RIPEMD160
+//#define ARCH_TEST_SHA1
+#ifndef TF_M_PROFILE_SMALL
#define ARCH_TEST_SHA224
+#endif
#define ARCH_TEST_SHA256
+#ifndef TF_M_PROFILE_SMALL
+#ifndef TF_M_PROFILE_MEDIUM
#define ARCH_TEST_SHA384
#define ARCH_TEST_SHA512
-// #define ARCH_TEST_SHA512_224
-// #define ARCH_TEST_SHA512_256
-// #define ARCH_TEST_SHA3_224
-// #define ARCH_TEST_SHA3_256
-// #define ARCH_TEST_SHA3_384
-// #define ARCH_TEST_SHA3_512
+#endif
+#endif
+//#define ARCH_TEST_SHA512_224
+//#define ARCH_TEST_SHA512_256
+//#define ARCH_TEST_SHA3_224
+//#define ARCH_TEST_SHA3_256
+//#define ARCH_TEST_SHA3_384
+//#define ARCH_TEST_SHA3_512
/**
* \def ARCH_TEST_HKDF
@@ -261,7 +297,12 @@
*
* Comment macros to disable the types
*/
+#ifndef TF_M_PROFILE_SMALL
+#ifndef TF_M_PROFILE_MEDIUM
#define ARCH_TEST_CMAC
+#endif
+#endif
+//#define ARCH_TEST_GMAC
#define ARCH_TEST_HMAC
/**
@@ -281,7 +322,11 @@
* Requires: ARCH_TEST_AES
*
*/
+#ifndef TF_M_PROFILE_SMALL
+#ifndef TF_M_PROFILE_MEDIUM
#define ARCH_TEST_GCM
+#endif
+#endif
/**
* \def ARCH_TEST_TRUNCATED_MAC
@@ -300,7 +345,9 @@
*
* Requires: ARCH_TEST_ECC
*/
+#ifndef TF_M_PROFILE_SMALL
#define ARCH_TEST_ECDH
+#endif
/**
* \def ARCH_TEST_ECDSA
@@ -308,7 +355,9 @@
* Enable the elliptic curve DSA library.
* Requires: ARCH_TEST_ECC
*/
+#ifndef TF_M_PROFILE_SMALL
#define ARCH_TEST_ECDSA
+#endif
/**
* \def ARCH_TEST_DETERMINISTIC_ECDSA
--
2.25.1
@@ -1,46 +0,0 @@
From 0ec1b3d20d612325b9c55baa2539d080eb6a72a8 Mon Sep 17 00:00:00 2001
From: Vishnu Banavath <vishnu.banavath@arm.com>
Date: Sat, 13 Nov 2021 08:34:42 +0000
Subject: [PATCH] se-proxy:dts: add se-proxy as child node
se-proxy sp string should be added for se-proxy node to be
read properly.
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
---
.../se-proxy/opteesp/default_se-proxy.dts.in | 20 ++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/deployments/se-proxy/opteesp/default_se-proxy.dts.in b/deployments/se-proxy/opteesp/default_se-proxy.dts.in
index 961071ad..9f5cf712 100644
--- a/deployments/se-proxy/opteesp/default_se-proxy.dts.in
+++ b/deployments/se-proxy/opteesp/default_se-proxy.dts.in
@@ -7,13 +7,15 @@
@DTS_TAG@
@DTS_NODE@ {
- compatible = "arm,ffa-manifest-1.0";
- ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
- uuid = <@EXPORT_SP_UUID_DT@>;
- description = "SE Proxy";
- execution-ctx-count = <1>;
- exception-level = <1>; /* S-EL0 */
- execution-state = <0>; /* AArch64 */
- xlat-granule = <0>; /* 4KiB */
- messaging-method = <0>; /* Direct messaging only */
+ se-proxy {
+ compatible = "arm,ffa-manifest-1.0";
+ ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+ uuid = <@EXPORT_SP_UUID_DT@>;
+ description = "SE Proxy";
+ execution-ctx-count = <1>;
+ exception-level = <1>; /* S-EL0 */
+ execution-state = <0>; /* AArch64 */
+ xlat-granule = <0>; /* 4KiB */
+ messaging-method = <0>; /* Direct messaging only */
+ };
};
@@ -1,59 +0,0 @@
From 97b4f3cd0216c30c39f6ece4f68d8faf3901fded Mon Sep 17 00:00:00 2001
From: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
Date: Wed, 17 Nov 2021 15:31:09 +0000
Subject: [PATCH] Update mm-comm-buffer region in dts file
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
---
.../opteesp/default_smm-gateway.dts.in | 35 ++++++++++---------
1 file changed, 18 insertions(+), 17 deletions(-)
diff --git a/deployments/smm-gateway/opteesp/default_smm-gateway.dts.in b/deployments/smm-gateway/opteesp/default_smm-gateway.dts.in
index 0ad7878b..183c38a7 100644
--- a/deployments/smm-gateway/opteesp/default_smm-gateway.dts.in
+++ b/deployments/smm-gateway/opteesp/default_smm-gateway.dts.in
@@ -7,23 +7,24 @@
@DTS_TAG@
@DTS_NODE@ {
- compatible = "arm,ffa-manifest-1.0";
- ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
- uuid = <@EXPORT_SP_UUID_DT@>;
- description = "SMM Gateway";
- execution-ctx-count = <1>;
- exception-level = <1>; /* S-EL0 */
- execution-state = <0>; /* AArch64 */
- xlat-granule = <0>; /* 4KiB */
- messaging-method = <0>; /* Direct messaging only */
-
- memory-regions {
- compatible = "arm,ffa-manifest-memory-regions";
-
- mm-comm-buffer {
- base-address = <@MM_COMM_BUFFER_ADDRESS@>;
- pages-count = <@MM_COMM_BUFFER_PAGE_COUNT@>;
- attributes = <0xb>; /* ns access-read-write */
+ smm-gateway{
+ compatible = "arm,ffa-manifest-1.0";
+ ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+ uuid = <@EXPORT_SP_UUID_DT@>;
+ description = "SMM Gateway";
+ execution-ctx-count = <1>;
+ exception-level = <1>; /* S-EL0 */
+ execution-state = <0>; /* AArch64 */
+ xlat-granule = <0>; /* 4KiB */
+ messaging-method = <0>; /* Direct messaging only */
+ device-regions {
+ compatible = "arm,ffa-manifest-device-regions";
+ mm-comm-buffer {
+ /* Armv8 A Foundation Platform values */
+ base-address = <0x00000000 0x02000000>;
+ pages-count = <1>;
+ attributes = <0x3>; /* read-write */
+ };
};
};
};
@@ -1,26 +0,0 @@
From a11b23dd5f0c4124a5c6c2fcab0ea623bc76f4ba Mon Sep 17 00:00:00 2001
From: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
Date: Wed, 17 Nov 2021 15:32:04 +0000
Subject: [PATCH] Configure NV storage macro
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
---
deployments/smm-gateway/smm_gateway.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/deployments/smm-gateway/smm_gateway.c b/deployments/smm-gateway/smm_gateway.c
index 4884a040..7828b3af 100644
--- a/deployments/smm-gateway/smm_gateway.c
+++ b/deployments/smm-gateway/smm_gateway.c
@@ -13,6 +13,8 @@
/* Build-time default configuration */
+#define SMM_GATEWAY_NV_STORE_SN "sn:ffa:46bb39d1-b4d9-45b5-88ff-040027dab249:1"
+
/* Default to using the Protected Storage SP */
#ifndef SMM_GATEWAY_NV_STORE_SN
#define SMM_GATEWAY_NV_STORE_SN "sn:ffa:751bf801-3dde-4768-a514-0f10aeed1790:0"
@@ -1,53 +0,0 @@
From ae22f5077d35e6acf3feb8a84a8ef7f599261b00 Mon Sep 17 00:00:00 2001
From: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
Date: Wed, 17 Nov 2021 15:32:46 +0000
Subject: [PATCH] Use device region
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
---
deployments/smm-gateway/opteesp/smm_gateway_sp.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/deployments/smm-gateway/opteesp/smm_gateway_sp.c b/deployments/smm-gateway/opteesp/smm_gateway_sp.c
index 6f138850..0bc09023 100644
--- a/deployments/smm-gateway/opteesp/smm_gateway_sp.c
+++ b/deployments/smm-gateway/opteesp/smm_gateway_sp.c
@@ -10,7 +10,7 @@
#include <config/loader/sp/sp_config_loader.h>
#include "components/rpc/mm_communicate/endpoint/sp/mm_communicate_call_ep.h"
#include "components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.h"
-#include "platform/interface/memory_region.h"
+#include "platform/interface/device_region.h"
#include <ffa_api.h>
#include <sp_api.h>
#include <sp_messaging.h>
@@ -25,7 +25,7 @@ static int sp_init(uint16_t *own_sp_id);
void __noreturn sp_main(struct ffa_init_info *init_info)
{
- struct memory_region mm_comm_buffer_region = { 0 };
+ struct device_region mm_comm_buffer_region = { 0 };
struct rpc_interface *gateway_iface = NULL;
struct smm_variable_mm_service smm_var_service = { 0 };
struct mm_service_interface *smm_var_service_interface = NULL;
@@ -42,7 +42,7 @@ void __noreturn sp_main(struct ffa_init_info *init_info)
config_ramstore_init();
sp_config_load(init_info);
- if (!config_store_query(CONFIG_CLASSIFIER_MEMORY_REGION, CONFIG_NAME_MM_COMM_BUFFER_REGION,
+ if (!config_store_query(CONFIG_CLASSIFIER_DEVICE_REGION, CONFIG_NAME_MM_COMM_BUFFER_REGION,
0, &mm_comm_buffer_region, sizeof(mm_comm_buffer_region))) {
EMSG(CONFIG_NAME_MM_COMM_BUFFER_REGION " is not set in SP configuration");
goto fatal_error;
@@ -57,7 +57,7 @@ void __noreturn sp_main(struct ffa_init_info *init_info)
/* Initialize MM communication layer */
if (!mm_communicate_call_ep_init(&mm_communicate_call_ep,
(void *)mm_comm_buffer_region.base_addr,
- mm_comm_buffer_region.region_size))
+ mm_comm_buffer_region.io_region_size))
goto fatal_error;
/* Attach SMM variable service to MM communication layer */
@@ -1,259 +0,0 @@
From 90712f624c7b676e5b9a2d95cbe97d2b63fddcc9 Mon Sep 17 00:00:00 2001
From: Vishnu Banavath <vishnu.banavath@arm.com>
Date: Fri, 3 Dec 2021 16:36:51 +0000
Subject: [PATCH] Add openamp to SE proxy deployment
Openamp is required to communicate between secure partitions(running on
Cortex-A) and trusted-firmware-m(running on Cortex-M).
These changes are to fetch libmetal and openamp from github repo's
and build it.
Signed-off-by: Rui Miguel Silva <rui.silva@arm.com>
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
---
deployments/se-proxy/opteesp/CMakeLists.txt | 14 ++++
deployments/se-proxy/opteesp/lse.S | 19 +++++
external/openamp/libmetal.cmake | 81 ++++++++++++++++++++
external/openamp/openamp.cmake | 82 +++++++++++++++++++++
4 files changed, 196 insertions(+)
create mode 100644 deployments/se-proxy/opteesp/lse.S
create mode 100644 external/openamp/libmetal.cmake
create mode 100644 external/openamp/openamp.cmake
diff --git a/deployments/se-proxy/opteesp/CMakeLists.txt b/deployments/se-proxy/opteesp/CMakeLists.txt
index 4e2069a5..248bd7e3 100644
--- a/deployments/se-proxy/opteesp/CMakeLists.txt
+++ b/deployments/se-proxy/opteesp/CMakeLists.txt
@@ -89,6 +89,7 @@ add_components(TARGET "se-proxy"
target_sources(se-proxy PRIVATE
se_proxy_sp.c
service_proxy_factory.c
+ lse.S
)
#-------------------------------------------------------------------------------
@@ -108,6 +109,19 @@ include(../../../external/nanopb/nanopb.cmake)
target_link_libraries(se-proxy PRIVATE nanopb::protobuf-nanopb-static)
protobuf_generate_all(TGT "se-proxy" NAMESPACE "protobuf" BASE_DIR "${TS_ROOT}/protocols")
+# libmetal
+list(APPEND LIBMETAL_EXTERNAL_INCLUDE_PATHS ${SP_DEV_KIT_INCLUDE_DIR})
+set(LIBMETAL_EXTRA_INCLUDE_PATHS ${LIBMETAL_EXTRA_INCLUDE_PATHS}
+ CACHE STRING "" FORCE)
+include(../../../external/openamp/libmetal.cmake)
+
+# OpenAMP
+list(APPEND OPENAMP_EXTERNAL_INCLUDE_PATHS ${SP_DEV_KIT_INCLUDE_DIR})
+set(OPENAMP_EXTRA_INCLUDE_PATHS ${OPENAMP_EXTRA_INCLUDE_PATHS}
+ CACHE STRING "" FORCE)
+include(../../../external/openamp/openamp.cmake)
+target_link_libraries(se-proxy PRIVATE openamp libmetal)
+
#################################################################
target_compile_definitions(se-proxy PRIVATE
diff --git a/deployments/se-proxy/opteesp/lse.S b/deployments/se-proxy/opteesp/lse.S
new file mode 100644
index 00000000..840683a6
--- /dev/null
+++ b/deployments/se-proxy/opteesp/lse.S
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ */
+
+.text
+.globl __aarch64_cas4_acq_rel
+
+__aarch64_cas4_acq_rel:
+ mov w16, w0
+ ldaxr w0, [x2]
+ cmp w0, w16
+0: bne 1f
+
+ stlxr w17, w1, [x2]
+ cbnz w17, 0b
+1: ret
+
+
diff --git a/external/openamp/libmetal.cmake b/external/openamp/libmetal.cmake
new file mode 100644
index 00000000..3a647e69
--- /dev/null
+++ b/external/openamp/libmetal.cmake
@@ -0,0 +1,81 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021 Linaro Limited
+# Copyright (c) 2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+set (LIBMETAL_URL "https://github.com/OpenAMP/libmetal.git" CACHE STRING "libmetal repository URL")
+set (LIBMETAL_INSTALL_PATH "${CMAKE_CURRENT_BINARY_DIR}/libmetal_install" CACHE PATH "libmetal installation directory")
+set (LIBMETAL_PACKAGE_PATH "${LIBMETAL_INSTALL_PATH}/libmetal/cmake" CACHE PATH "libmetal CMake package directory")
+set (LIBMETAL_TARGET_NAME "libmetal")
+set (LIBMETAL_VERSION "f252f0e007fbfb8b3a52b1d5901250ddac96baad" CACHE STRING "The version of libmetal to use")
+
+if(NOT LIBMETAL_DEBUG)
+ set(LIBMETAL_BUILD_TYPE "Release")
+else()
+ set(LIBMETAL_BUILD_TYPE "Debug")
+endif()
+
+include(FetchContent)
+
+# Checking git
+find_program(GIT_COMMAND "git")
+if (NOT GIT_COMMAND)
+ message(FATAL_ERROR "Please install git")
+endif()
+
+FetchContent_Declare(
+ libmetal
+ GIT_REPOSITORY ${LIBMETAL_URL}
+ GIT_TAG ${LIBMETAL_VERSION}
+)
+
+# FetchContent_GetProperties exports libmetal_SOURCE_DIR and libmetal_BINARY_DIR variables
+FetchContent_GetProperties(libmetal)
+if(NOT libmetal_POPULATED)
+ message(STATUS "Fetching libmetal")
+ FetchContent_Populate(libmetal)
+endif()
+
+# Ensure list of include paths is separated correctly
+string(REPLACE ";" "\\;" LIBMETAL_EXTERNAL_INCLUDE_PATHS "${LIBMETAL_EXTERNAL_INCLUDE_PATHS}")
+
+#Configure the library
+execute_process(COMMAND
+ ${CMAKE_COMMAND}
+ -DCMAKE_BUILD_TYPE=${LIBMETAL_BUILD_TYPE}
+ -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
+ -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
+ -DCMAKE_TOOLCHAIN_FILE=${TS_EXTERNAL_LIB_TOOLCHAIN_FILE}
+ -DCMAKE_INSTALL_PREFIX=${LIBMETAL_INSTALL_PATH}
+ -DCMAKE_C_FLAGS_DEBUG=${CMAKE_C_FLAGS_DEBUG}
+ -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
+ -DCMAKE_C_OUTPUT_EXTENSION=.o
+ -DCMAKE_C_COMPILER_WORKS=true
+ -DCMAKE_SYSTEM_PROCESSOR=arm
+ -DWITH_DOC=off
+ -DWITH_TESTS=off
+ -DWITH_EXAMPLES=off
+ -DWITH_DEFAULT_LOGGER=off
+ -DEXTERNAL_INCLUDE_PATHS=${LIBMETAL_EXTERNAL_INCLUDE_PATHS}
+ -DMACHINE=template
+ ${libmetal_SOURCE_DIR}
+ WORKING_DIRECTORY
+ ${libmetal_BINARY_DIR}
+)
+
+# Build the library
+execute_process(COMMAND
+ ${CMAKE_COMMAND} --build ${libmetal_BINARY_DIR} -- install
+ RESULT_VARIABLE _exec_error
+ )
+if (_exec_error)
+ message(FATAL_ERROR "Build step of libmetal failed with ${_exec_error}.")
+endif()
+
+#Create an imported target to have clean abstraction in the build-system.
+add_library(libmetal STATIC IMPORTED)
+set_property(TARGET libmetal PROPERTY IMPORTED_LOCATION "${LIBMETAL_INSTALL_PATH}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}metal${CMAKE_STATIC_LIBRARY_SUFFIX}")
+set_property(TARGET libmetal PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${LIBMETAL_INSTALL_PATH}/include")
diff --git a/external/openamp/openamp.cmake b/external/openamp/openamp.cmake
new file mode 100644
index 00000000..aae13bad
--- /dev/null
+++ b/external/openamp/openamp.cmake
@@ -0,0 +1,82 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021 Linaro Limited
+# Copyright (c) 2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+set (OPENAMP_URL "https://github.com/OpenAMP/open-amp.git" CACHE STRING "OpenAMP repository URL")
+set (OPENAMP_INSTALL_PATH "${CMAKE_CURRENT_BINARY_DIR}/openamp_install" CACHE PATH "OpenAMP installation directory")
+set (OPENAMP_PACKAGE_PATH "${OPENAMP_INSTALL_PATH}/openamp/cmake" CACHE PATH "OpenAMP CMake package directory")
+set (OPENAMP_TARGET_NAME "openamp")
+set (OPENAMP_VERSION "347397decaa43372fc4d00f965640ebde042966d" CACHE STRING "The version of openamp to use")
+
+
+if(NOT OPENAMP_DEBUG)
+ set(OPENAMP_BUILD_TYPE "Release")
+else()
+ set(OPENAMP_BUILD_TYPE "Debug")
+endif()
+
+include(FetchContent)
+
+# Checking git
+find_program(GIT_COMMAND "git")
+if (NOT GIT_COMMAND)
+ message(FATAL_ERROR "Please install git")
+endif()
+
+FetchContent_Declare(
+ openamp
+ GIT_REPOSITORY ${OPENAMP_URL}
+ GIT_TAG ${OPENAMP_VERSION}
+)
+
+# FetchContent_GetProperties exports openamp_SOURCE_DIR and openamp_BINARY_DIR variables
+FetchContent_GetProperties(openamp)
+if(NOT openamp_POPULATED)
+ message(STATUS "Fetching openamp")
+ FetchContent_Populate(openamp)
+endif()
+
+# Ensure list of include paths is separated correctly
+get_target_property(_libmetal_inc libmetal INTERFACE_INCLUDE_DIRECTORIES)
+set (_openam_external_include_paths ${_libmetal_inc} ${OPENAMP_EXTERNAL_INCLUDE_PATHS})
+string(REPLACE ";" "\\;" OPENAMP_EXTERNAL_INCLUDE_PATHS "${_openam_external_include_paths}")
+
+#Configure the library
+execute_process(COMMAND
+ ${CMAKE_COMMAND}
+ -DCMAKE_BUILD_TYPE=${OPENAMP_BUILD_TYPE}
+ -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
+ -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
+ -DCMAKE_TOOLCHAIN_FILE=${TS_EXTERNAL_LIB_TOOLCHAIN_FILE}
+ -DCMAKE_INSTALL_PREFIX=${OPENAMP_INSTALL_PATH}
+ -DCMAKE_C_FLAGS_DEBUG=${CMAKE_C_FLAGS_DEBUG}
+ -DLIBMETAL_INCLUDE_DIR=${CMAKE_CURRENT_BINARY_DIR}/libmetal/lib/include
+ -DLIBMETAL_LIB=${CMAKE_CURRENT_BINARY_DIR}/libmetal/lib
+ -DCMAKE_C_OUTPUT_EXTENSION=.o
+ -DCMAKE_C_COMPILER_WORKS=true
+ -DCMAKE_SYSTEM_PROCESSOR=arm
+ -DEXTERNAL_INCLUDE_PATHS=${OPENAMP_EXTERNAL_INCLUDE_PATHS}
+ -DMACHINE=template
+ -DRPMSG_BUFFER_SIZE=512
+ ${openamp_SOURCE_DIR}
+ WORKING_DIRECTORY
+ ${openamp_BINARY_DIR}
+)
+
+# Build the library
+execute_process(COMMAND
+ ${CMAKE_COMMAND} --build ${openamp_BINARY_DIR} -- install
+ RESULT_VARIABLE _exec_error
+ )
+if (_exec_error)
+ message(FATAL_ERROR "Build step of OpenAMP failed with ${_exec_error}.")
+endif()
+
+#Create an imported target to have clean abstraction in the build-system.
+add_library(openamp STATIC IMPORTED)
+set_property(TARGET openamp PROPERTY IMPORTED_LOCATION "${OPENAMP_INSTALL_PATH}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}open_amp${CMAKE_STATIC_LIBRARY_SUFFIX}")
+set_property(TARGET openamp PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${OPENAMP_INSTALL_PATH}/include")
@@ -1,299 +0,0 @@
From 791a1302d7b779f3aeee7d6f7c9fac00b4244c1b Mon Sep 17 00:00:00 2001
From: Vishnu Banavath <vishnu.banavath@arm.com>
Date: Fri, 3 Dec 2021 19:05:18 +0000
Subject: [PATCH] add psa client definitions for ff-m
Add PSA client definitions in common include to add future
ff-m support.
Signed-off-by: Rui Miguel Silva <rui.silva@arm.com>
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
---
.../service/common/include/psa/client.h | 194 ++++++++++++++++++
components/service/common/include/psa/sid.h | 71 +++++++
2 files changed, 265 insertions(+)
create mode 100644 components/service/common/include/psa/client.h
create mode 100644 components/service/common/include/psa/sid.h
diff --git a/components/service/common/include/psa/client.h b/components/service/common/include/psa/client.h
new file mode 100644
index 00000000..69ccf14f
--- /dev/null
+++ b/components/service/common/include/psa/client.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SERVICE_PSA_IPC_H
+#define SERVICE_PSA_IPC_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <rpc_caller.h>
+#include <psa/error.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef IOVEC_LEN
+#define IOVEC_LEN(arr) ((uint32_t)(sizeof(arr)/sizeof(arr[0])))
+#endif
+
+/*********************** PSA Client Macros and Types *************************/
+
+typedef int32_t psa_handle_t;
+
+/**
+ * The version of the PSA Framework API that is being used to build the calling
+ * firmware. Only part of features of FF-M v1.1 have been implemented. FF-M v1.1
+ * is compatible with v1.0.
+ */
+#define PSA_FRAMEWORK_VERSION (0x0101u)
+
+/**
+ * Return value from psa_version() if the requested RoT Service is not present
+ * in the system.
+ */
+#define PSA_VERSION_NONE (0u)
+
+/**
+ * The zero-value null handle can be assigned to variables used in clients and
+ * RoT Services, indicating that there is no current connection or message.
+ */
+#define PSA_NULL_HANDLE ((psa_handle_t)0)
+
+/**
+ * Tests whether a handle value returned by psa_connect() is valid.
+ */
+#define PSA_HANDLE_IS_VALID(handle) ((psa_handle_t)(handle) > 0)
+
+/**
+ * Converts the handle value returned from a failed call psa_connect() into
+ * an error code.
+ */
+#define PSA_HANDLE_TO_ERROR(handle) ((psa_status_t)(handle))
+
+/**
+ * Maximum number of input and output vectors for a request to psa_call().
+ */
+#define PSA_MAX_IOVEC (4u)
+
+/**
+ * An IPC message type that indicates a generic client request.
+ */
+#define PSA_IPC_CALL (0)
+
+/**
+ * A read-only input memory region provided to an RoT Service.
+ */
+struct __attribute__ ((__packed__)) psa_invec {
+ uint32_t base; /*!< the start address of the memory buffer */
+ uint32_t len; /*!< the size in bytes */
+};
+
+/**
+ * A writable output memory region provided to an RoT Service.
+ */
+struct __attribute__ ((__packed__)) psa_outvec {
+ uint32_t base; /*!< the start address of the memory buffer */
+ uint32_t len; /*!< the size in bytes */
+};
+
+/*************************** PSA Client API **********************************/
+
+/**
+ * \brief Retrieve the version of the PSA Framework API that is implemented.
+ *
+ * \param[in] rpc_caller RPC caller to use
+ * \return version The version of the PSA Framework implementation
+ * that is providing the runtime services to the
+ * caller. The major and minor version are encoded
+ * as follows:
+ * \arg version[15:8] -- major version number.
+ * \arg version[7:0] -- minor version number.
+ */
+uint32_t psa_framework_version(struct rpc_caller *caller);
+
+/**
+ * \brief Retrieve the version of an RoT Service or indicate that it is not
+ * present on this system.
+ *
+ * \param[in] rpc_caller RPC caller to use
+ * \param[in] sid ID of the RoT Service to query.
+ *
+ * \retval PSA_VERSION_NONE The RoT Service is not implemented, or the
+ * caller is not permitted to access the service.
+ * \retval > 0 The version of the implemented RoT Service.
+ */
+uint32_t psa_version(struct rpc_caller *caller, uint32_t sid);
+
+/**
+ * \brief Connect to an RoT Service by its SID.
+ *
+ * \param[in] rpc_caller RPC caller to use
+ * \param[in] sid ID of the RoT Service to connect to.
+ * \param[in] version Requested version of the RoT Service.
+ *
+ * \retval > 0 A handle for the connection.
+ * \retval PSA_ERROR_CONNECTION_REFUSED The SPM or RoT Service has refused the
+ * connection.
+ * \retval PSA_ERROR_CONNECTION_BUSY The SPM or RoT Service cannot make the
+ * connection at the moment.
+ * \retval "PROGRAMMER ERROR" The call is a PROGRAMMER ERROR if one or more
+ * of the following are true:
+ * \arg The RoT Service ID is not present.
+ * \arg The RoT Service version is not supported.
+ * \arg The caller is not allowed to access the RoT
+ * service.
+ */
+psa_handle_t psa_connect(struct rpc_caller *caller, uint32_t sid,
+ uint32_t version);
+
+/**
+ * \brief Call an RoT Service on an established connection.
+ *
+ * \note FF-M 1.0 proposes 6 parameters for psa_call but the secure gateway ABI
+ * support at most 4 parameters. TF-M chooses to encode 'in_len',
+ * 'out_len', and 'type' into a 32-bit integer to improve efficiency.
+ * Compared with struct-based encoding, this method saves extra memory
+ * check and memory copy operation. The disadvantage is that the 'type'
+ * range has to be reduced into a 16-bit integer. So with this encoding,
+ * the valid range for 'type' is 0-32767.
+ *
+ * \param[in] rpc_caller RPC caller to use
+ * \param[in] handle A handle to an established connection.
+ * \param[in] type The request type.
+ * Must be zero( \ref PSA_IPC_CALL) or positive.
+ * \param[in] in_vec Array of input \ref psa_invec structures.
+ * \param[in] in_len Number of input \ref psa_invec structures.
+ * \param[in,out] out_vec Array of output \ref psa_outvec structures.
+ * \param[in] out_len Number of output \ref psa_outvec structures.
+ *
+ * \retval >=0 RoT Service-specific status value.
+ * \retval <0 RoT Service-specific error code.
+ * \retval PSA_ERROR_PROGRAMMER_ERROR The connection has been terminated by the
+ * RoT Service. The call is a PROGRAMMER ERROR if
+ * one or more of the following are true:
+ * \arg An invalid handle was passed.
+ * \arg The connection is already handling a request.
+ * \arg type < 0.
+ * \arg An invalid memory reference was provided.
+ * \arg in_len + out_len > PSA_MAX_IOVEC.
+ * \arg The message is unrecognized by the RoT
+ * Service or incorrectly formatted.
+ */
+psa_status_t psa_call(struct rpc_caller *caller, psa_handle_t handle,
+ int32_t type, const struct psa_invec *in_vec,
+ size_t in_len, struct psa_outvec *out_vec, size_t out_len);
+
+/**
+ * \brief Close a connection to an RoT Service.
+ *
+ * \param[in] rpc_caller RPC caller to use
+ * \param[in] handle A handle to an established connection, or the
+ * null handle.
+ *
+ * \retval void Success.
+ * \retval "PROGRAMMER ERROR" The call is a PROGRAMMER ERROR if one or more
+ * of the following are true:
+ * \arg An invalid handle was provided that is not
+ * the null handle.
+ * \arg The connection is currently handling a
+ * request.
+ */
+void psa_close(struct rpc_caller *caller, psa_handle_t handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SERVICE_PSA_IPC_H */
+
+
diff --git a/components/service/common/include/psa/sid.h b/components/service/common/include/psa/sid.h
new file mode 100644
index 00000000..aaa973c6
--- /dev/null
+++ b/components/service/common/include/psa/sid.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __PSA_MANIFEST_SID_H__
+#define __PSA_MANIFEST_SID_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******** TFM_SP_PS ********/
+#define TFM_PROTECTED_STORAGE_SERVICE_SID (0x00000060U)
+#define TFM_PROTECTED_STORAGE_SERVICE_VERSION (1U)
+#define TFM_PROTECTED_STORAGE_SERVICE_HANDLE (0x40000101U)
+
+/* Invalid UID */
+#define TFM_PS_INVALID_UID 0
+
+/* PS message types that distinguish PS services. */
+#define TFM_PS_SET 1001
+#define TFM_PS_GET 1002
+#define TFM_PS_GET_INFO 1003
+#define TFM_PS_REMOVE 1004
+#define TFM_PS_GET_SUPPORT 1005
+
+/******** TFM_SP_ITS ********/
+#define TFM_INTERNAL_TRUSTED_STORAGE_SERVICE_SID (0x00000070U)
+#define TFM_INTERNAL_TRUSTED_STORAGE_SERVICE_VERSION (1U)
+#define TFM_INTERNAL_TRUSTED_STORAGE_SERVICE_HANDLE (0x40000102U)
+
+/******** TFM_SP_CRYPTO ********/
+#define TFM_CRYPTO_SID (0x00000080U)
+#define TFM_CRYPTO_VERSION (1U)
+#define TFM_CRYPTO_HANDLE (0x40000100U)
+
+/******** TFM_SP_PLATFORM ********/
+#define TFM_SP_PLATFORM_SYSTEM_RESET_SID (0x00000040U)
+#define TFM_SP_PLATFORM_SYSTEM_RESET_VERSION (1U)
+#define TFM_SP_PLATFORM_IOCTL_SID (0x00000041U)
+#define TFM_SP_PLATFORM_IOCTL_VERSION (1U)
+#define TFM_SP_PLATFORM_NV_COUNTER_SID (0x00000042U)
+#define TFM_SP_PLATFORM_NV_COUNTER_VERSION (1U)
+
+/******** TFM_SP_INITIAL_ATTESTATION ********/
+#define TFM_ATTESTATION_SERVICE_SID (0x00000020U)
+#define TFM_ATTESTATION_SERVICE_VERSION (1U)
+#define TFM_ATTESTATION_SERVICE_HANDLE (0x40000103U)
+
+/******** TFM_SP_FWU ********/
+#define TFM_FWU_WRITE_SID (0x000000A0U)
+#define TFM_FWU_WRITE_VERSION (1U)
+#define TFM_FWU_INSTALL_SID (0x000000A1U)
+#define TFM_FWU_INSTALL_VERSION (1U)
+#define TFM_FWU_ABORT_SID (0x000000A2U)
+#define TFM_FWU_ABORT_VERSION (1U)
+#define TFM_FWU_QUERY_SID (0x000000A3U)
+#define TFM_FWU_QUERY_VERSION (1U)
+#define TFM_FWU_REQUEST_REBOOT_SID (0x000000A4U)
+#define TFM_FWU_REQUEST_REBOOT_VERSION (1U)
+#define TFM_FWU_ACCEPT_SID (0x000000A5U)
+#define TFM_FWU_ACCEPT_VERSION (1U)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PSA_MANIFEST_SID_H__ */
@@ -1,295 +0,0 @@
From b7e9e6fc59263f5daf4ae79eb758fa7647058338 Mon Sep 17 00:00:00 2001
From: Vishnu Banavath <vishnu.banavath@arm.com>
Date: Fri, 3 Dec 2021 19:13:03 +0000
Subject: [PATCH] Add common service component to ipc support
Add support for inter processor communication for PSA
including, the openamp client side structures lib.
Signed-off-by: Rui Miguel Silva <rui.silva@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
---
.../service/common/psa_ipc/component.cmake | 13 ++
.../service/common/psa_ipc/service_psa_ipc.c | 97 +++++++++++++
.../psa_ipc/service_psa_ipc_openamp_lib.h | 131 ++++++++++++++++++
deployments/se-proxy/opteesp/CMakeLists.txt | 1 +
4 files changed, 242 insertions(+)
create mode 100644 components/service/common/psa_ipc/component.cmake
create mode 100644 components/service/common/psa_ipc/service_psa_ipc.c
create mode 100644 components/service/common/psa_ipc/service_psa_ipc_openamp_lib.h
diff --git a/components/service/common/psa_ipc/component.cmake b/components/service/common/psa_ipc/component.cmake
new file mode 100644
index 00000000..5a1c9e62
--- /dev/null
+++ b/components/service/common/psa_ipc/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}/service_psa_ipc.c"
+ )
diff --git a/components/service/common/psa_ipc/service_psa_ipc.c b/components/service/common/psa_ipc/service_psa_ipc.c
new file mode 100644
index 00000000..e8093c20
--- /dev/null
+++ b/components/service/common/psa_ipc/service_psa_ipc.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <trace.h>
+
+#include <protocols/rpc/common/packed-c/status.h>
+#include <psa/error.h>
+#include <rpc_caller.h>
+
+#include <psa/client.h>
+#include "service_psa_ipc_openamp_lib.h"
+
+psa_handle_t psa_connect(struct rpc_caller *caller, uint32_t sid,
+ uint32_t version)
+{
+ psa_status_t psa_status = PSA_SUCCESS;
+ struct s_openamp_msg *resp_msg = NULL;
+ struct ns_openamp_msg *req_msg;
+ rpc_call_handle rpc_handle;
+ size_t resp_len;
+ uint8_t *resp;
+ uint8_t *req;
+ int ret;
+
+ rpc_handle = rpc_caller_begin(caller, &req,
+ sizeof(struct ns_openamp_msg));
+ if (!rpc_handle) {
+ EMSG("psa_connect: could not get handle");
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+
+ req_msg = (struct ns_openamp_msg *)req;
+
+ req_msg->call_type = OPENAMP_PSA_CONNECT;
+ req_msg->params.psa_connect_params.sid = sid;
+ req_msg->params.psa_connect_params.version = version;
+
+ ret = rpc_caller_invoke(caller, rpc_handle, 0, &psa_status, &resp,
+ &resp_len);
+ if (ret != TS_RPC_CALL_ACCEPTED) {
+ EMSG("psa_connect: invoke failed: %d", ret);
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+
+ if (psa_status == PSA_SUCCESS)
+ resp_msg = (struct s_openamp_msg *)resp;
+
+ rpc_caller_end(caller, rpc_handle);
+
+ return resp_msg ? (psa_handle_t)resp_msg->reply : PSA_NULL_HANDLE;
+}
+
+psa_status_t psa_call(struct rpc_caller *caller, psa_handle_t handle,
+ int32_t type, const struct psa_invec *in_vec,
+ size_t in_len, struct psa_outvec *out_vec, size_t out_len)
+{
+
+}
+
+void psa_close(struct rpc_caller *caller, psa_handle_t handle)
+{
+ psa_status_t psa_status = PSA_SUCCESS;
+ struct s_openamp_msg *resp_msg = NULL;
+ struct ns_openamp_msg *req_msg;
+ rpc_call_handle rpc_handle;
+ size_t resp_len;
+ uint8_t *resp;
+ uint8_t *req;
+ int ret;
+
+ rpc_handle = rpc_caller_begin(caller, &req,
+ sizeof(struct ns_openamp_msg));
+ if (!rpc_handle) {
+ EMSG("psa_close: could not get handle");
+ return;
+ }
+
+ req_msg = (struct ns_openamp_msg *)req;
+
+ req_msg->call_type = OPENAMP_PSA_CLOSE;
+ req_msg->params.psa_close_params.handle = handle;
+
+ ret = rpc_caller_invoke(caller, rpc_handle, 0, &psa_status, &resp,
+ &resp_len);
+ if (ret != TS_RPC_CALL_ACCEPTED) {
+ EMSG("psa_close: invoke failed: %d", ret);
+ return;
+ }
+
+ rpc_caller_end(caller, rpc_handle);
+}
diff --git a/components/service/common/psa_ipc/service_psa_ipc_openamp_lib.h b/components/service/common/psa_ipc/service_psa_ipc_openamp_lib.h
new file mode 100644
index 00000000..33ea9666
--- /dev/null
+++ b/components/service/common/psa_ipc/service_psa_ipc_openamp_lib.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SERVICE_PSA_IPC_OPENAMP_LIB_H
+#define SERVICE_PSA_IPC_OPENAMP_LIB_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <compiler.h>
+#include <psa/error.h>
+
+#include <stdint.h>
+#include <psa/client.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* PSA client call type value */
+#define OPENAMP_PSA_FRAMEWORK_VERSION (0x1)
+#define OPENAMP_PSA_VERSION (0x2)
+#define OPENAMP_PSA_CONNECT (0x3)
+#define OPENAMP_PSA_CALL (0x4)
+#define OPENAMP_PSA_CLOSE (0x5)
+
+/* Return code of openamp APIs */
+#define OPENAMP_SUCCESS (0)
+#define OPENAMP_MAP_FULL (INT32_MIN + 1)
+#define OPENAMP_MAP_ERROR (INT32_MIN + 2)
+#define OPENAMP_INVAL_PARAMS (INT32_MIN + 3)
+#define OPENAMP_NO_PERMS (INT32_MIN + 4)
+#define OPENAMP_NO_PEND_EVENT (INT32_MIN + 5)
+#define OPENAMP_CHAN_BUSY (INT32_MIN + 6)
+#define OPENAMP_CALLBACK_REG_ERROR (INT32_MIN + 7)
+#define OPENAMP_INIT_ERROR (INT32_MIN + 8)
+
+#define HOLD_INPUT_BUFFER (1) /* IF true, TF-M Library will hold the openamp
+ * buffer so that openamp shared memory buffer
+ * does not get freed.
+ */
+
+/*
+ * This structure holds the parameters used in a PSA client call.
+ */
+typedef struct __packed psa_client_in_params {
+ union {
+ struct __packed {
+ uint32_t sid;
+ } psa_version_params;
+
+ struct __packed {
+ uint32_t sid;
+ uint32_t version;
+ } psa_connect_params;
+
+ struct __packed {
+ psa_handle_t handle;
+ int32_t type;
+ uint32_t in_vec;
+ uint32_t in_len;
+ uint32_t out_vec;
+ uint32_t out_len;
+ } psa_call_params;
+
+ struct __packed {
+ psa_handle_t handle;
+ } psa_close_params;
+ };
+} psa_client_in_params_t;
+
+/* Openamp message passed from NSPE to SPE to deliver a PSA client call */
+struct __packed ns_openamp_msg {
+ uint32_t call_type; /* PSA client call type */
+ struct psa_client_in_params params; /* Contain parameters used in PSA
+ * client call
+ */
+
+ int32_t client_id; /* Optional client ID of the
+ * non-secure caller.
+ * It is required to identify the
+ * non-secure task when NSPE OS
+ * enforces non-secure task
+ * isolation
+ */
+ int32_t request_id; /* This is the unique ID for a
+ * request send to TF-M by the
+ * non-secure core. TF-M forward
+ * the ID back to non-secure on the
+ * reply to a given request. Using
+ * this id, the non-secure library
+ * can identify the request for
+ * which the reply has received.
+ */
+};
+
+/*
+ * This structure holds the location of the out data of the PSA client call.
+ */
+struct __packed psa_client_out_params {
+ uint32_t out_vec;
+ uint32_t out_len;
+};
+
+
+/* Openamp message from SPE to NSPE delivering the reply back for a PSA client
+ * call.
+ */
+struct __packed s_openamp_msg {
+ int32_t request_id; /* Using this id, the non-secure
+ * library identifies the request.
+ * TF-M forwards the same
+ * request-id received on the
+ * initial request.
+ */
+ int32_t reply; /* Reply of the PSA client call */
+ struct psa_client_out_params params; /* Contain out data result of the
+ * PSA client call.
+ */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SERVICE_PSA_IPC_OPENAMP_LIB_H */
+
+
diff --git a/deployments/se-proxy/opteesp/CMakeLists.txt b/deployments/se-proxy/opteesp/CMakeLists.txt
index 1511bbad..e0e0e12b 100644
--- a/deployments/se-proxy/opteesp/CMakeLists.txt
+++ b/deployments/se-proxy/opteesp/CMakeLists.txt
@@ -54,6 +54,7 @@ add_components(TARGET "se-proxy"
"components/service/common/include"
"components/service/common/serializer/protobuf"
"components/service/common/client"
+ "components/service/common/psa_ipc"
"components/service/common/provider"
"components/service/discovery/provider"
"components/service/discovery/provider/serializer/packed-c"
@@ -1,523 +0,0 @@
From 962056a9c8115e9228719d46b09da983678ab024 Mon Sep 17 00:00:00 2001
From: Vishnu Banavath <vishnu.banavath@arm.com>
Date: Fri, 3 Dec 2021 19:19:24 +0000
Subject: [PATCH] Add secure storage ipc backend
Add secure storage ipc ff-m implementation which may use
openamp as rpc to communicate with other processor.
Signed-off-by: Rui Miguel Silva <rui.silva@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
---
.../service/common/psa_ipc/service_psa_ipc.c | 143 +++++++++++-
.../secure_storage_ipc/component.cmake | 14 ++
.../secure_storage_ipc/secure_storage_ipc.c | 214 ++++++++++++++++++
.../secure_storage_ipc/secure_storage_ipc.h | 52 +++++
deployments/se-proxy/opteesp/CMakeLists.txt | 1 +
5 files changed, 420 insertions(+), 4 deletions(-)
create mode 100644 components/service/secure_storage/backend/secure_storage_ipc/component.cmake
create mode 100644 components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c
create mode 100644 components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h
diff --git a/components/service/common/psa_ipc/service_psa_ipc.c b/components/service/common/psa_ipc/service_psa_ipc.c
index e8093c20..95a07c13 100644
--- a/components/service/common/psa_ipc/service_psa_ipc.c
+++ b/components/service/common/psa_ipc/service_psa_ipc.c
@@ -16,6 +16,52 @@
#include <psa/client.h>
#include "service_psa_ipc_openamp_lib.h"
+static struct psa_invec *psa_call_in_vec_param(uint8_t *req)
+{
+ return (struct psa_invec *)(req + sizeof(struct ns_openamp_msg));
+}
+
+static struct psa_outvec *psa_call_out_vec_param(uint8_t *req, size_t in_len)
+{
+ return (struct psa_outvec *)(req + sizeof(struct ns_openamp_msg) +
+ (in_len * sizeof(struct psa_invec)));
+}
+
+static size_t psa_call_header_len(const struct psa_invec *in_vec, size_t in_len,
+ struct psa_outvec *out_vec, size_t out_len)
+{
+ return sizeof(struct ns_openamp_msg) + (in_len * sizeof(*in_vec)) +
+ (out_len * sizeof(*out_vec));
+}
+
+static size_t psa_call_in_vec_len(const struct psa_invec *in_vec, size_t in_len)
+{
+ size_t req_len = 0;
+ int i;
+
+ if (!in_vec || !in_len)
+ return 0;
+
+ for (i = 0; i < in_len; i++)
+ req_len += in_vec[i].len;
+
+ return req_len;
+}
+
+static size_t psa_call_out_vec_len(const struct psa_outvec *out_vec, size_t out_len)
+{
+ size_t resp_len = 0;
+ int i;
+
+ if (!out_vec || !out_len)
+ return 0;
+
+ for (i = 0; i < out_len; i++)
+ resp_len += out_vec[i].len;
+
+ return resp_len;
+}
+
psa_handle_t psa_connect(struct rpc_caller *caller, uint32_t sid,
uint32_t version)
{
@@ -31,7 +77,7 @@ psa_handle_t psa_connect(struct rpc_caller *caller, uint32_t sid,
rpc_handle = rpc_caller_begin(caller, &req,
sizeof(struct ns_openamp_msg));
if (!rpc_handle) {
- EMSG("psa_connect: could not get handle");
+ EMSG("psa_connect: could not get rpc handle");
return PSA_ERROR_GENERIC_ERROR;
}
@@ -56,14 +102,100 @@ psa_handle_t psa_connect(struct rpc_caller *caller, uint32_t sid,
return resp_msg ? (psa_handle_t)resp_msg->reply : PSA_NULL_HANDLE;
}
-psa_status_t psa_call(struct rpc_caller *caller, psa_handle_t handle,
+psa_status_t psa_call(struct rpc_caller *caller, psa_handle_t psa_handle,
int32_t type, const struct psa_invec *in_vec,
size_t in_len, struct psa_outvec *out_vec, size_t out_len)
{
+ psa_status_t psa_status = PSA_SUCCESS;
+ struct s_openamp_msg *resp_msg = NULL;
+ struct psa_outvec *out_vec_param;
+ struct psa_invec *in_vec_param;
+ struct ns_openamp_msg *req_msg;
+ rpc_call_handle rpc_handle;
+ size_t out_vec_len;
+ size_t in_vec_len;
+ size_t header_len;
+ uint8_t *payload;
+ size_t resp_len;
+ uint8_t *resp;
+ uint8_t *req;
+ int ret;
+ int i;
+
+ if ((psa_handle == PSA_NULL_HANDLE) || !caller)
+ return PSA_ERROR_INVALID_ARGUMENT;
+
+ header_len = psa_call_header_len(in_vec, in_len, out_vec, out_len);
+ in_vec_len = psa_call_in_vec_len(in_vec, in_len);
+ out_vec_len = psa_call_out_vec_len(out_vec, out_len);
+ rpc_handle = rpc_caller_begin(caller, &req, header_len + in_vec_len);
+ if (!rpc_handle) {
+ EMSG("psa_call: could not get handle");
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+
+ payload = req + header_len;
+
+ out_vec_param = psa_call_out_vec_param(req, in_len);
+ in_vec_param = psa_call_in_vec_param(req);
+
+ req_msg = (struct ns_openamp_msg *)req;
+
+ req_msg->call_type = OPENAMP_PSA_CALL;
+ req_msg->request_id = 1234;
+ req_msg->params.psa_call_params.handle = psa_handle;
+ req_msg->params.psa_call_params.type = type;
+ req_msg->params.psa_call_params.in_len = in_len;
+ req_msg->params.psa_call_params.in_vec = rpc_caller_virt_to_phys(caller, in_vec_param);
+ req_msg->params.psa_call_params.out_len = out_len;
+ req_msg->params.psa_call_params.out_vec = rpc_caller_virt_to_phys(caller, out_vec_param);
+
+ for (i = 0; i < in_len; i++) {
+ in_vec_param[i].base = rpc_caller_virt_to_phys(caller, payload);
+ in_vec_param[i].len = in_vec[i].len;
+
+ memcpy(payload, in_vec[i].base, in_vec[i].len);
+ payload += in_vec[i].len;
+ }
+
+ for (i = 0; i < out_len; i++) {
+ out_vec_param[i].base = NULL;
+ out_vec_param[i].len = out_vec[i].len;
+ }
+
+ ret = rpc_caller_invoke(caller, rpc_handle, 0, &psa_status, &resp,
+ &resp_len);
+ if (ret != TS_RPC_CALL_ACCEPTED) {
+ EMSG("psa_call: invoke failed: %d", ret);
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+
+ if (psa_status != PSA_SUCCESS) {
+ EMSG("psa_call: psa_status invoke failed: %d", psa_status);
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+
+ resp_msg = (struct s_openamp_msg *)resp;
+
+ if (!resp_msg || !out_len || resp_msg->reply != PSA_SUCCESS)
+ goto caller_end;
+
+ out_vec_param = (struct psa_outvec *)rpc_caller_phys_to_virt(caller,
+ resp_msg->params.out_vec);
+
+ for (i = 0; i < resp_msg->params.out_len; i++) {
+ memcpy(out_vec[i].base, rpc_caller_phys_to_virt(caller, out_vec_param[i].base),
+ out_vec[i].len);
+ }
+
+caller_end:
+ rpc_caller_end(caller, rpc_handle);
+
+ return resp_msg ? resp_msg->reply : PSA_ERROR_COMMUNICATION_FAILURE;
}
-void psa_close(struct rpc_caller *caller, psa_handle_t handle)
+void psa_close(struct rpc_caller *caller, psa_handle_t psa_handle)
{
psa_status_t psa_status = PSA_SUCCESS;
struct s_openamp_msg *resp_msg = NULL;
@@ -74,6 +206,9 @@ void psa_close(struct rpc_caller *caller, psa_handle_t handle)
uint8_t *req;
int ret;
+ if ((psa_handle == PSA_NULL_HANDLE) || !caller)
+ return;
+
rpc_handle = rpc_caller_begin(caller, &req,
sizeof(struct ns_openamp_msg));
if (!rpc_handle) {
@@ -84,7 +219,7 @@ void psa_close(struct rpc_caller *caller, psa_handle_t handle)
req_msg = (struct ns_openamp_msg *)req;
req_msg->call_type = OPENAMP_PSA_CLOSE;
- req_msg->params.psa_close_params.handle = handle;
+ req_msg->params.psa_close_params.handle = psa_handle;
ret = rpc_caller_invoke(caller, rpc_handle, 0, &psa_status, &resp,
&resp_len);
diff --git a/components/service/secure_storage/backend/secure_storage_ipc/component.cmake b/components/service/secure_storage/backend/secure_storage_ipc/component.cmake
new file mode 100644
index 00000000..5d8f6714
--- /dev/null
+++ b/components/service/secure_storage/backend/secure_storage_ipc/component.cmake
@@ -0,0 +1,14 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}/secure_storage_ipc.c"
+ )
+
diff --git a/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c
new file mode 100644
index 00000000..9b55f77d
--- /dev/null
+++ b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <protocols/rpc/common/packed-c/status.h>
+#include "secure_storage_ipc.h"
+#include <psa/client.h>
+#include <psa/sid.h>
+#include <rpc_caller.h>
+#include <string.h>
+#include <trace.h>
+
+
+static psa_status_t secure_storage_ipc_set(void *context, uint32_t client_id,
+ psa_storage_uid_t uid, size_t data_length,
+ const void *p_data, psa_storage_create_flags_t create_flags)
+{
+ struct secure_storage_ipc *ipc = context;
+ struct rpc_caller *caller = ipc->client.caller;
+ psa_handle_t psa_handle;
+ psa_status_t psa_status;
+ struct psa_invec in_vec[] = {
+ { .base = &uid, .len = sizeof(uid) },
+ { .base = p_data, .len = data_length },
+ { .base = &create_flags, .len = sizeof(create_flags) },
+ };
+
+ (void)client_id;
+
+ ipc->client.rpc_status = TS_RPC_CALL_ACCEPTED;
+
+ /* Validating input parameters */
+ if (p_data == NULL)
+ return PSA_ERROR_INVALID_ARGUMENT;
+
+ psa_status = psa_call(caller, TFM_PROTECTED_STORAGE_SERVICE_HANDLE,
+ TFM_PS_SET, in_vec, IOVEC_LEN(in_vec), NULL, 0);
+ if (psa_status < 0)
+ EMSG("ipc_set: psa_call failed: %d", psa_status);
+
+ return psa_status;
+}
+
+static psa_status_t secure_storage_ipc_get(void *context,
+ uint32_t client_id,
+ psa_storage_uid_t uid,
+ size_t data_offset,
+ size_t data_size,
+ void *p_data,
+ size_t *p_data_length)
+{
+ struct secure_storage_ipc *ipc = context;
+ struct rpc_caller *caller = ipc->client.caller;
+ psa_handle_t psa_handle;
+ psa_status_t psa_status;
+ uint32_t offset = (uint32_t)data_offset;
+ struct psa_invec in_vec[] = {
+ { .base = &uid, .len = sizeof(uid) },
+ { .base = &offset, .len = sizeof(offset) },
+ };
+ struct psa_outvec out_vec[] = {
+ { .base = p_data, .len = data_size },
+ };
+
+ if (!p_data_length) {
+ EMSG("ipc_get: p_data_length not defined");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_status = psa_call(caller, TFM_PROTECTED_STORAGE_SERVICE_HANDLE,
+ TFM_PS_GET, in_vec, IOVEC_LEN(in_vec),
+ out_vec, IOVEC_LEN(out_vec));
+ if (psa_status == PSA_SUCCESS)
+ *p_data_length = out_vec[0].len;
+
+ return psa_status;
+}
+
+static psa_status_t secure_storage_ipc_get_info(void *context,
+ uint32_t client_id,
+ psa_storage_uid_t uid,
+ struct psa_storage_info_t *p_info)
+{
+ struct secure_storage_ipc *ipc = context;
+ struct rpc_caller *caller = ipc->client.caller;
+ psa_handle_t psa_handle;
+ psa_status_t psa_status;
+ struct psa_invec in_vec[] = {
+ { .base = &uid, .len = sizeof(uid) },
+ };
+ struct psa_outvec out_vec[] = {
+ { .base = p_info, .len = sizeof(*p_info) },
+ };
+
+ (void)client_id;
+
+ /* Validating input parameters */
+ if (!p_info)
+ return PSA_ERROR_INVALID_ARGUMENT;
+
+ psa_status = psa_call(caller, TFM_PROTECTED_STORAGE_SERVICE_HANDLE,
+ TFM_PS_GET_INFO, in_vec,
+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
+ if (psa_status != PSA_SUCCESS)
+ EMSG("ipc_get_info: failed to psa_call: %d", psa_status);
+
+ return psa_status;
+}
+
+static psa_status_t secure_storage_ipc_remove(void *context,
+ uint32_t client_id,
+ psa_storage_uid_t uid)
+{
+ struct secure_storage_ipc *ipc = context;
+ struct rpc_caller *caller = ipc->client.caller;
+ psa_handle_t psa_handle;
+ psa_status_t psa_status;
+ struct psa_invec in_vec[] = {
+ { .base = &uid, .len = sizeof(uid) },
+ };
+
+ (void)client_id;
+
+ psa_status = psa_call(caller, TFM_PROTECTED_STORAGE_SERVICE_HANDLE,
+ TFM_PS_REMOVE, in_vec,
+ IOVEC_LEN(in_vec), NULL, 0);
+ if (psa_status != PSA_SUCCESS)
+ EMSG("ipc_remove: failed to psa_call: %d", psa_status);
+
+ return psa_status;
+}
+
+static psa_status_t secure_storage_ipc_create(void *context,
+ uint32_t client_id,
+ uint64_t uid,
+ size_t capacity,
+ uint32_t create_flags)
+{
+ (void)context;
+ (void)uid;
+ (void)client_id;
+ (void)capacity;
+ (void)create_flags;
+
+ return PSA_ERROR_NOT_SUPPORTED;
+}
+
+static psa_status_t secure_storage_set_extended(void *context,
+ uint32_t client_id,
+ uint64_t uid,
+ size_t data_offset,
+ size_t data_length,
+ const void *p_data)
+{
+ (void)context;
+ (void)uid;
+ (void)client_id;
+ (void)data_offset;
+ (void)data_length;
+ (void)p_data;
+
+ return PSA_ERROR_NOT_SUPPORTED;
+}
+
+static uint32_t secure_storage_get_support(void *context, uint32_t client_id)
+{
+ struct secure_storage_ipc *ipc = context;
+ struct rpc_caller *caller = ipc->client.caller;
+ psa_handle_t psa_handle;
+ psa_status_t psa_status;
+ uint32_t support_flags;
+ struct psa_outvec out_vec[] = {
+ { .base = &support_flags, .len = sizeof(support_flags) },
+ };
+
+ (void)client_id;
+
+ psa_status = psa_call(caller, TFM_PROTECTED_STORAGE_SERVICE_HANDLE,
+ TFM_PS_GET_SUPPORT, NULL, 0,
+ out_vec, IOVEC_LEN(out_vec));
+ if (psa_status != PSA_SUCCESS)
+ EMSG("ipc_get_support: failed to psa_call: %d", psa_status);
+
+ return psa_status;
+}
+
+struct storage_backend *secure_storage_ipc_init(struct secure_storage_ipc *context,
+ struct rpc_caller *caller)
+{
+ service_client_init(&context->client, caller);
+
+ static const struct storage_backend_interface interface =
+ {
+ .set = secure_storage_ipc_set,
+ .get = secure_storage_ipc_get,
+ .get_info = secure_storage_ipc_get_info,
+ .remove = secure_storage_ipc_remove,
+ .create = secure_storage_ipc_create,
+ .set_extended = secure_storage_set_extended,
+ .get_support = secure_storage_get_support,
+ };
+
+ context->backend.context = context;
+ context->backend.interface = &interface;
+
+ return &context->backend;
+}
+
+void secure_storage_ipc_deinit(struct secure_storage_ipc *context)
+{
+ service_client_deinit(&context->client);
+}
diff --git a/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h
new file mode 100644
index 00000000..e8c1e8fd
--- /dev/null
+++ b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SECURE_STORAGE_IPC_H
+#define SECURE_STORAGE_IPC_H
+
+#include <service/secure_storage/backend/storage_backend.h>
+#include <service/common/client/service_client.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Secure storage ipc instance
+ */
+struct secure_storage_ipc
+{
+ struct storage_backend backend;
+ struct service_client client;
+};
+
+/**
+ * @brief Initialize a secure storage ipc client
+ *
+ * A secure storage client is a storage backend that makes RPC calls
+ * to a remote secure storage provider.
+ *
+ * @param[in] context Instance data
+ * @param[in] rpc_caller RPC caller instance
+ *
+ *
+ * @return Pointer to inialized storage backend or NULL on failure
+ */
+struct storage_backend *secure_storage_ipc_init(struct secure_storage_ipc *context,
+ struct rpc_caller *caller);
+
+/**
+ * @brief Deinitialize a secure storage ipc client
+ *
+ * @param[in] context Instance data
+ */
+void secure_storage_ipc_deinit(struct secure_storage_ipc *context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SECURE_STORAGE_IPC_H */
diff --git a/deployments/se-proxy/opteesp/CMakeLists.txt b/deployments/se-proxy/opteesp/CMakeLists.txt
index e0e0e12b..663177b7 100644
--- a/deployments/se-proxy/opteesp/CMakeLists.txt
+++ b/deployments/se-proxy/opteesp/CMakeLists.txt
@@ -73,6 +73,7 @@ add_components(TARGET "se-proxy"
"components/service/crypto/factory/full"
"components/service/secure_storage/include"
"components/service/secure_storage/frontend/secure_storage_provider"
+ "components/service/secure_storage/backend/secure_storage_ipc"
"components/service/attestation/include"
"components/service/attestation/provider"
"components/service/attestation/provider/serializer/packed-c"
@@ -1,63 +0,0 @@
From 12b8b8bb28c96e6f121122939b7d23e6c7055f0f Mon Sep 17 00:00:00 2001
From: Vishnu Banavath <vishnu.banavath@arm.com>
Date: Fri, 3 Dec 2021 19:25:34 +0000
Subject: [PATCH] Use secure storage ipc and openamp for se_proxy
Remove mock up backend for secure storage in se proxy
deployment and use instead the secure storage ipc backend with
openamp as rpc to secure enclave side.
Signed-off-by: Rui Miguel Silva <rui.silva@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
---
.../se-proxy/opteesp/service_proxy_factory.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/deployments/se-proxy/opteesp/service_proxy_factory.c b/deployments/se-proxy/opteesp/service_proxy_factory.c
index acfb6e88..57290056 100644
--- a/deployments/se-proxy/opteesp/service_proxy_factory.c
+++ b/deployments/se-proxy/opteesp/service_proxy_factory.c
@@ -6,15 +6,20 @@
#include <stddef.h>
#include <rpc/common/endpoint/rpc_interface.h>
+#include <rpc/openamp/caller/sp/openamp_caller.h>
#include <service/attestation/provider/attest_provider.h>
#include <service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.h>
#include <service/crypto/factory/crypto_provider_factory.h>
#include <service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.h>
+#include <trace.h>
/* Stub backends */
#include <service/crypto/backend/stub/stub_crypto_backend.h>
+#include <service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h>
#include <service/secure_storage/backend/mock_store/mock_store.h>
+struct openamp_caller openamp;
+
struct rpc_interface *attest_proxy_create(void)
{
struct rpc_interface *attest_iface;
@@ -47,10 +52,15 @@ struct rpc_interface *crypto_proxy_create(void)
struct rpc_interface *ps_proxy_create(void)
{
- static struct mock_store ps_backend;
static struct secure_storage_provider ps_provider;
-
- struct storage_backend *backend = mock_store_init(&ps_backend);
+ static struct secure_storage_ipc ps_backend;
+ static struct rpc_caller *storage_caller;
+ struct storage_backend *backend;
+
+ storage_caller = openamp_caller_init(&openamp);
+ if (!storage_caller)
+ return NULL;
+ backend = secure_storage_ipc_init(&ps_backend, &openamp.rpc_caller);
return secure_storage_provider_init(&ps_provider, backend);
}
@@ -1,830 +0,0 @@
From c4eaf83548eed4ed6194ff9e1368d6ae65f4ebf9 Mon Sep 17 00:00:00 2001
From: Julian Hall <julian.hall@arm.com>
Date: Thu, 2 Dec 2021 17:27:55 +0000
Subject: [PATCH] Add UEFI variable support for QueryVariableInfo
Adds support for the UEFI QueryVariableInfo operation. The total
store size currently relies on pre-configured values, set for a
particular deployment. Ideally, this information would be read
from the storage backend. This facility is not however yet
supported by the storage backend interface or by any PSA
storage backend storage providers.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I971252831f7e478914d736c672d184a371e64502
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
---
.../backend/test/variable_store_tests.cpp | 89 +++++++-
.../backend/uefi_variable_store.c | 213 ++++++++++++++----
.../backend/uefi_variable_store.h | 39 +++-
.../client/cpp/smm_variable_client.cpp | 66 ++++++
.../client/cpp/smm_variable_client.h | 7 +
.../provider/smm_variable_provider.c | 31 ++-
.../service/smm_variable_service_tests.cpp | 55 ++++-
7 files changed, 445 insertions(+), 55 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 578f118f..e90c1067 100644
--- a/components/service/smm_variable/backend/test/variable_store_tests.cpp
+++ b/components/service/smm_variable/backend/test/variable_store_tests.cpp
@@ -27,6 +27,18 @@ TEST_GROUP(UefiVariableStoreTests)
UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
+ uefi_variable_store_set_storage_limits(
+ &m_uefi_variable_store,
+ EFI_VARIABLE_NON_VOLATILE,
+ STORE_CAPACITY,
+ MAX_VARIABLE_SIZE);
+
+ uefi_variable_store_set_storage_limits(
+ &m_uefi_variable_store,
+ 0,
+ STORE_CAPACITY,
+ MAX_VARIABLE_SIZE);
+
setup_common_guid();
}
@@ -152,6 +164,33 @@ TEST_GROUP(UefiVariableStoreTests)
return status;
}
+ efi_status_t query_variable_info(
+ uint32_t attributes,
+ size_t *max_variable_storage_size,
+ size_t *remaining_variable_storage_size,
+ size_t *max_variable_size)
+ {
+ SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO query;
+
+ query.MaximumVariableStorageSize = 0;
+ query.RemainingVariableStorageSize = 0;
+ query.MaximumVariableSize = 0;
+ query.Attributes = attributes;
+
+ efi_status_t status = uefi_variable_store_query_variable_info(
+ &m_uefi_variable_store,
+ &query);
+
+ if (status == EFI_SUCCESS) {
+
+ *max_variable_storage_size = query.MaximumVariableStorageSize;
+ *remaining_variable_storage_size = query.RemainingVariableStorageSize;
+ *max_variable_size = query.MaximumVariableSize;
+ }
+
+ return status;
+ }
+
efi_status_t set_check_var_property(
const std::wstring &name,
const VAR_CHECK_VARIABLE_PROPERTY &check_property)
@@ -195,7 +234,8 @@ TEST_GROUP(UefiVariableStoreTests)
if (info && (info->metadata.attributes & EFI_VARIABLE_NON_VOLATILE)) {
- struct storage_backend *storage_backend = m_uefi_variable_store.persistent_store;
+ struct storage_backend *storage_backend =
+ m_uefi_variable_store.persistent_store.storage_backend;
storage_backend->interface->remove(
storage_backend->context,
@@ -220,9 +260,24 @@ TEST_GROUP(UefiVariableStoreTests)
m_volatile_backend);
UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
+
+ uefi_variable_store_set_storage_limits(
+ &m_uefi_variable_store,
+ EFI_VARIABLE_NON_VOLATILE,
+ STORE_CAPACITY,
+ MAX_VARIABLE_SIZE);
+
+ uefi_variable_store_set_storage_limits(
+ &m_uefi_variable_store,
+ 0,
+ STORE_CAPACITY,
+ MAX_VARIABLE_SIZE);
}
static const size_t MAX_VARIABLES = 10;
+ static const size_t MAX_VARIABLE_SIZE = 100;
+ static const size_t STORE_CAPACITY = 1000;
+
static const uint32_t OWNER_ID = 100;
static const size_t VARIABLE_BUFFER_SIZE = 1024;
@@ -265,6 +320,22 @@ TEST(UefiVariableStoreTests, setGetRoundtrip)
/* Expect the append write operation to have extended the variable */
UNSIGNED_LONGLONGS_EQUAL(expected_output.size(), output_data.size());
LONGS_EQUAL(0, expected_output.compare(output_data));
+
+ /* Expect query_variable_info to return consistent values */
+ size_t max_variable_storage_size = 0;
+ size_t remaining_variable_storage_size = 0;
+ size_t max_variable_size = 0;
+
+ status = query_variable_info(
+ 0,
+ &max_variable_storage_size,
+ &remaining_variable_storage_size,
+ &max_variable_size);
+ UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
+
+ UNSIGNED_LONGLONGS_EQUAL(STORE_CAPACITY, max_variable_storage_size);
+ UNSIGNED_LONGLONGS_EQUAL(MAX_VARIABLE_SIZE, max_variable_size);
+ UNSIGNED_LONGLONGS_EQUAL(STORE_CAPACITY - expected_output.size(), remaining_variable_storage_size);
}
TEST(UefiVariableStoreTests, persistentSetGet)
@@ -311,6 +382,22 @@ TEST(UefiVariableStoreTests, persistentSetGet)
/* Still expect got variable data to be the same as the set value */
UNSIGNED_LONGLONGS_EQUAL(expected_output.size(), output_data.size());
LONGS_EQUAL(0, expected_output.compare(output_data));
+
+ /* Expect query_variable_info to return consistent values */
+ size_t max_variable_storage_size = 0;
+ size_t remaining_variable_storage_size = 0;
+ size_t max_variable_size = 0;
+
+ status = query_variable_info(
+ EFI_VARIABLE_NON_VOLATILE,
+ &max_variable_storage_size,
+ &remaining_variable_storage_size,
+ &max_variable_size);
+ UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
+
+ UNSIGNED_LONGLONGS_EQUAL(STORE_CAPACITY, max_variable_storage_size);
+ UNSIGNED_LONGLONGS_EQUAL(MAX_VARIABLE_SIZE, max_variable_size);
+ UNSIGNED_LONGLONGS_EQUAL(STORE_CAPACITY - expected_output.size(), remaining_variable_storage_size);
}
TEST(UefiVariableStoreTests, removeVolatile)
diff --git a/components/service/smm_variable/backend/uefi_variable_store.c b/components/service/smm_variable/backend/uefi_variable_store.c
index bcb85995..ed50eaf9 100644
--- a/components/service/smm_variable/backend/uefi_variable_store.c
+++ b/components/service/smm_variable/backend/uefi_variable_store.c
@@ -46,8 +46,15 @@ static efi_status_t load_variable_data(
SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var,
size_t max_data_len);
-static psa_status_t append_write(
- struct storage_backend *storage_backend,
+static psa_status_t store_overwrite(
+ struct delegate_variable_store *delegate_store,
+ uint32_t client_id,
+ uint64_t uid,
+ size_t data_length,
+ const void *data);
+
+static psa_status_t store_append_write(
+ struct delegate_variable_store *delegate_store,
uint32_t client_id,
uint64_t uid,
size_t data_length,
@@ -56,6 +63,15 @@ static psa_status_t append_write(
static void purge_orphan_index_entries(
struct uefi_variable_store *context);
+static struct delegate_variable_store *select_delegate_store(
+ struct uefi_variable_store *context,
+ uint32_t attributes);
+
+static size_t space_used(
+ struct uefi_variable_store *context,
+ uint32_t attributes,
+ struct storage_backend *storage_backend);
+
static efi_status_t psa_to_efi_storage_status(
psa_status_t psa_status);
@@ -66,6 +82,10 @@ static efi_status_t check_name_terminator(
/* Private UID for storing the variable index */
#define VARIABLE_INDEX_STORAGE_UID (1)
+/* Default maximum variable size -
+ * may be overridden using uefi_variable_store_set_storage_limits()
+ */
+#define DEFAULT_MAX_VARIABLE_SIZE (2048)
efi_status_t uefi_variable_store_init(
struct uefi_variable_store *context,
@@ -76,8 +96,17 @@ efi_status_t uefi_variable_store_init(
{
efi_status_t status = EFI_SUCCESS;
- context->persistent_store = persistent_store;
- context->volatile_store = volatile_store;
+ /* Initialise persistent store defaults */
+ context->persistent_store.is_nv = true;
+ context->persistent_store.max_variable_size = DEFAULT_MAX_VARIABLE_SIZE;
+ context->persistent_store.total_capacity = DEFAULT_MAX_VARIABLE_SIZE * max_variables;
+ context->persistent_store.storage_backend = persistent_store;
+
+ /* Initialise volatile store defaults */
+ context->volatile_store.is_nv = false;
+ context->volatile_store.max_variable_size = DEFAULT_MAX_VARIABLE_SIZE;
+ context->volatile_store.total_capacity = DEFAULT_MAX_VARIABLE_SIZE * max_variables;
+ context->volatile_store.storage_backend = volatile_store;
context->owner_id = owner_id;
context->is_boot_service = true;
@@ -116,6 +145,20 @@ void uefi_variable_store_deinit(
context->index_sync_buffer = NULL;
}
+void uefi_variable_store_set_storage_limits(
+ struct uefi_variable_store *context,
+ uint32_t attributes,
+ size_t total_capacity,
+ size_t max_variable_size)
+{
+ struct delegate_variable_store *delegate_store = select_delegate_store(
+ context,
+ attributes);
+
+ delegate_store->total_capacity = total_capacity;
+ delegate_store->max_variable_size = max_variable_size;
+}
+
efi_status_t uefi_variable_store_set_variable(
struct uefi_variable_store *context,
const SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var)
@@ -284,12 +327,24 @@ efi_status_t uefi_variable_store_get_next_variable_name(
efi_status_t uefi_variable_store_query_variable_info(
struct uefi_variable_store *context,
- SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *cur)
+ SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *var_info)
{
- efi_status_t status = EFI_UNSUPPORTED;
+ struct delegate_variable_store *delegate_store = select_delegate_store(
+ context,
+ var_info->Attributes);
+ size_t total_used = space_used(
+ context,
+ var_info->Attributes,
+ delegate_store->storage_backend);
- return status;
+ var_info->MaximumVariableSize = delegate_store->max_variable_size;
+ var_info->MaximumVariableStorageSize = delegate_store->total_capacity;
+ var_info->RemainingVariableStorageSize = (total_used < delegate_store->total_capacity) ?
+ delegate_store->total_capacity - total_used :
+ 0;
+
+ return EFI_SUCCESS;
}
efi_status_t uefi_variable_store_exit_boot_service(
@@ -375,7 +430,7 @@ efi_status_t uefi_variable_store_get_var_check_property(
static void load_variable_index(
struct uefi_variable_store *context)
{
- struct storage_backend *persistent_store = context->persistent_store;
+ struct storage_backend *persistent_store = context->persistent_store.storage_backend;
if (persistent_store) {
@@ -413,7 +468,7 @@ static efi_status_t sync_variable_index(
if (is_dirty) {
- struct storage_backend *persistent_store = context->persistent_store;
+ struct storage_backend *persistent_store = context->persistent_store.storage_backend;
if (persistent_store) {
@@ -501,30 +556,27 @@ static efi_status_t store_variable_data(
const uint8_t *data = (const uint8_t*)var +
SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_DATA_OFFSET(var);
- bool is_nv = (info->metadata.attributes & EFI_VARIABLE_NON_VOLATILE);
-
- struct storage_backend *storage_backend = (is_nv) ?
- context->persistent_store :
- context->volatile_store;
+ struct delegate_variable_store *delegate_store = select_delegate_store(
+ context,
+ info->metadata.attributes);
- if (storage_backend) {
+ if (delegate_store->storage_backend) {
if (!(var->Attributes & EFI_VARIABLE_APPEND_WRITE)) {
/* Create or overwrite variable data */
- psa_status = storage_backend->interface->set(
- storage_backend->context,
+ psa_status = store_overwrite(
+ delegate_store,
context->owner_id,
info->metadata.uid,
data_len,
- data,
- PSA_STORAGE_FLAG_NONE);
+ data);
}
else {
/* Append new data to existing variable data */
- psa_status = append_write(
- storage_backend,
+ psa_status = store_append_write(
+ delegate_store,
context->owner_id,
info->metadata.uid,
data_len,
@@ -532,7 +584,7 @@ static efi_status_t store_variable_data(
}
}
- if ((psa_status != PSA_SUCCESS) && is_nv) {
+ if ((psa_status != PSA_SUCCESS) && delegate_store->is_nv) {
/* A storage failure has occurred so attempt to fix any
* mismatch between the variable index and stored NV variables.
@@ -551,16 +603,14 @@ static efi_status_t remove_variable_data(
if (info->is_variable_set) {
- bool is_nv = (info->metadata.attributes & EFI_VARIABLE_NON_VOLATILE);
+ struct delegate_variable_store *delegate_store = select_delegate_store(
+ context,
+ info->metadata.attributes);
- struct storage_backend *storage_backend = (is_nv) ?
- context->persistent_store :
- context->volatile_store;
+ if (delegate_store->storage_backend) {
- if (storage_backend) {
-
- psa_status = storage_backend->interface->remove(
- storage_backend->context,
+ psa_status = delegate_store->storage_backend->interface->remove(
+ delegate_store->storage_backend->context,
context->owner_id,
info->metadata.uid);
}
@@ -580,16 +630,14 @@ static efi_status_t load_variable_data(
uint8_t *data = (uint8_t*)var +
SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_DATA_OFFSET(var);
- bool is_nv = (info->metadata.attributes & EFI_VARIABLE_NON_VOLATILE);
+ struct delegate_variable_store *delegate_store = select_delegate_store(
+ context,
+ info->metadata.attributes);
- struct storage_backend *storage_backend = (is_nv) ?
- context->persistent_store :
- context->volatile_store;
+ if (delegate_store->storage_backend) {
- if (storage_backend) {
-
- psa_status = storage_backend->interface->get(
- storage_backend->context,
+ psa_status = delegate_store->storage_backend->interface->get(
+ delegate_store->storage_backend->context,
context->owner_id,
info->metadata.uid,
0,
@@ -603,8 +651,29 @@ static efi_status_t load_variable_data(
return psa_to_efi_storage_status(psa_status);
}
-static psa_status_t append_write(
- struct storage_backend *storage_backend,
+static psa_status_t store_overwrite(
+ struct delegate_variable_store *delegate_store,
+ uint32_t client_id,
+ uint64_t uid,
+ size_t data_length,
+ const void *data)
+{
+ /* Police maximum variable size limit */
+ if (data_length > delegate_store->max_variable_size) return PSA_ERROR_INVALID_ARGUMENT;
+
+ psa_status_t psa_status = delegate_store->storage_backend->interface->set(
+ delegate_store->storage_backend->context,
+ client_id,
+ uid,
+ data_length,
+ data,
+ PSA_STORAGE_FLAG_NONE);
+
+ return psa_status;
+}
+
+static psa_status_t store_append_write(
+ struct delegate_variable_store *delegate_store,
uint32_t client_id,
uint64_t uid,
size_t data_length,
@@ -614,8 +683,8 @@ static psa_status_t append_write(
if (data_length == 0) return PSA_SUCCESS;
- psa_status_t psa_status = storage_backend->interface->get_info(
- storage_backend->context,
+ psa_status_t psa_status = delegate_store->storage_backend->interface->get_info(
+ delegate_store->storage_backend->context,
client_id,
uid,
&storage_info);
@@ -628,6 +697,9 @@ static psa_status_t append_write(
/* Defend against integer overflow */
if (new_size < storage_info.size) return PSA_ERROR_INVALID_ARGUMENT;
+ /* Police maximum variable size limit */
+ if (new_size > delegate_store->max_variable_size) return PSA_ERROR_INVALID_ARGUMENT;
+
/* Storage backend doesn't support an append operation so we need
* need to read the current variable data, extend it and write it back.
*/
@@ -635,8 +707,8 @@ static psa_status_t append_write(
if (!rw_buf) return PSA_ERROR_INSUFFICIENT_MEMORY;
size_t old_size = 0;
- psa_status = storage_backend->interface->get(
- storage_backend->context,
+ psa_status = delegate_store->storage_backend->interface->get(
+ delegate_store->storage_backend->context,
client_id,
uid,
0,
@@ -651,8 +723,8 @@ static psa_status_t append_write(
/* Extend the variable data */
memcpy(&rw_buf[old_size], data, data_length);
- psa_status = storage_backend->interface->set(
- storage_backend->context,
+ psa_status = delegate_store->storage_backend->interface->set(
+ delegate_store->storage_backend->context,
client_id,
uid,
old_size + data_length,
@@ -692,7 +764,7 @@ static void purge_orphan_index_entries(
if (info->is_variable_set && (info->metadata.attributes & EFI_VARIABLE_NON_VOLATILE)) {
struct psa_storage_info_t storage_info;
- struct storage_backend *storage_backend = context->persistent_store;
+ struct storage_backend *storage_backend = context->persistent_store.storage_backend;
psa_status_t psa_status = storage_backend->interface->get_info(
storage_backend->context,
@@ -714,6 +786,53 @@ static void purge_orphan_index_entries(
if (any_orphans) sync_variable_index(context);
}
+static struct delegate_variable_store *select_delegate_store(
+ struct uefi_variable_store *context,
+ uint32_t attributes)
+{
+ bool is_nv = (attributes & EFI_VARIABLE_NON_VOLATILE);
+
+ return (is_nv) ?
+ &context->persistent_store :
+ &context->volatile_store;
+}
+
+static size_t space_used(
+ struct uefi_variable_store *context,
+ uint32_t attributes,
+ struct storage_backend *storage_backend)
+{
+ if (!storage_backend) return 0;
+
+ size_t total_used = 0;
+ struct variable_index_iterator iter;
+ variable_index_iterator_first(&iter, &context->variable_index);
+
+ while (!variable_index_iterator_is_done(&iter)) {
+
+ struct variable_info *info = variable_index_iterator_current(&iter);
+
+ if (info->is_variable_set &&
+ ((info->metadata.attributes & EFI_VARIABLE_NON_VOLATILE) ==
+ (attributes & EFI_VARIABLE_NON_VOLATILE))) {
+
+ struct psa_storage_info_t storage_info;
+
+ psa_status_t psa_status = storage_backend->interface->get_info(
+ storage_backend->context,
+ context->owner_id,
+ info->metadata.uid,
+ &storage_info);
+
+ if (psa_status == PSA_SUCCESS) total_used += storage_info.size;
+ }
+
+ variable_index_iterator_next(&iter);
+ }
+
+ return total_used;
+}
+
static efi_status_t psa_to_efi_storage_status(
psa_status_t psa_status)
{
diff --git a/components/service/smm_variable/backend/uefi_variable_store.h b/components/service/smm_variable/backend/uefi_variable_store.h
index fe0f24af..cc992067 100644
--- a/components/service/smm_variable/backend/uefi_variable_store.h
+++ b/components/service/smm_variable/backend/uefi_variable_store.h
@@ -20,6 +20,20 @@
extern "C" {
#endif
+/**
+ * \brief delegate_variable_store structure definition
+ *
+ * A delegate_variable_store combines an association with a concrete
+ * storage backend and a set of limits parameters.
+ */
+struct delegate_variable_store
+{
+ bool is_nv;
+ size_t total_capacity;
+ size_t max_variable_size;
+ struct storage_backend *storage_backend;
+};
+
/**
* \brief uefi_variable_store structure definition
*
@@ -35,8 +49,8 @@ struct uefi_variable_store
uint8_t *index_sync_buffer;
size_t index_sync_buffer_size;
struct variable_index variable_index;
- struct storage_backend *persistent_store;
- struct storage_backend *volatile_store;
+ struct delegate_variable_store persistent_store;
+ struct delegate_variable_store volatile_store;
};
/**
@@ -69,6 +83,23 @@ efi_status_t uefi_variable_store_init(
void uefi_variable_store_deinit(
struct uefi_variable_store *context);
+/**
+ * @brief Set storage limits
+ *
+ * Overrides the default limits for the specified storage space. These
+ * values are reflected in the values returned by QueryVariableInfo.
+ *
+ * @param[in] context uefi_variable_store instance
+ * @param[in] attributes EFI_VARIABLE_NON_VOLATILE or 0
+ * @param[in] total_capacity The total storage capacity in bytes
+ * @param[in] max_variable_size Variable size limit
+ */
+void uefi_variable_store_set_storage_limits(
+ struct uefi_variable_store *context,
+ uint32_t attributes,
+ size_t total_capacity,
+ size_t max_variable_size);
+
/**
* @brief Set variable
*
@@ -123,13 +154,13 @@ efi_status_t uefi_variable_store_get_next_variable_name(
* @brief Query for variable info
*
* @param[in] context uefi_variable_store instance
- * @param[out] info Returns info
+ * @param[inout] var_info Returns info
*
* @return EFI_SUCCESS if succesful
*/
efi_status_t uefi_variable_store_query_variable_info(
struct uefi_variable_store *context,
- SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *cur);
+ SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *var_info);
/**
* @brief Exit boot service
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 a68b7ace..8438285b 100644
--- a/components/service/smm_variable/client/cpp/smm_variable_client.cpp
+++ b/components/service/smm_variable/client/cpp/smm_variable_client.cpp
@@ -219,6 +219,72 @@ efi_status_t smm_variable_client::get_next_variable_name(
0);
}
+efi_status_t smm_variable_client::query_variable_info(
+ uint32_t attributes,
+ size_t *max_variable_storage_size,
+ size_t *remaining_variable_storage_size,
+ size_t *max_variable_size)
+{
+ efi_status_t efi_status = EFI_NOT_READY;
+
+ size_t req_len = sizeof(SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO);
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
+
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+
+ if (call_handle) {
+
+ uint8_t *resp_buf;
+ size_t resp_len;
+ rpc_opstatus_t opstatus;
+
+ SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *query =
+ (SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO*)req_buf;
+
+ query->Attributes = attributes;
+ query->MaximumVariableSize = 0;
+ query->MaximumVariableStorageSize = 0;
+ query->RemainingVariableStorageSize = 0;
+
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO, &opstatus, &resp_buf, &resp_len);
+
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+
+ efi_status = opstatus;
+
+ if (efi_status == EFI_SUCCESS) {
+
+ if (resp_len >= sizeof(SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO)) {
+
+ query = (SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO*)resp_buf;
+
+ *max_variable_storage_size = query->MaximumVariableStorageSize;
+ *remaining_variable_storage_size = query->RemainingVariableStorageSize;
+ *max_variable_size = query->MaximumVariableSize;
+ }
+ else {
+
+ efi_status = EFI_PROTOCOL_ERROR;
+ }
+ }
+ else {
+
+ efi_status = EFI_PROTOCOL_ERROR;
+ }
+ }
+ else {
+
+ efi_status = rpc_to_efi_status();
+ }
+
+ rpc_caller_end(m_caller, call_handle);
+ }
+
+ return efi_status;
+}
+
efi_status_t smm_variable_client::get_next_variable_name(
EFI_GUID &guid,
std::wstring &name,
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 9c36c4eb..c7973916 100644
--- a/components/service/smm_variable/client/cpp/smm_variable_client.h
+++ b/components/service/smm_variable/client/cpp/smm_variable_client.h
@@ -63,6 +63,13 @@ public:
const EFI_GUID &guid,
const std::wstring &name);
+ /* Query variable info */
+ efi_status_t query_variable_info(
+ uint32_t attributes,
+ size_t *max_variable_storage_size,
+ size_t *remaining_variable_storage_size,
+ size_t *max_variable_size);
+
/* Get the next variable name - for enumerating store contents */
efi_status_t get_next_variable_name(
EFI_GUID &guid,
diff --git a/components/service/smm_variable/provider/smm_variable_provider.c b/components/service/smm_variable/provider/smm_variable_provider.c
index d239a428..52e68d09 100644
--- a/components/service/smm_variable/provider/smm_variable_provider.c
+++ b/components/service/smm_variable/provider/smm_variable_provider.c
@@ -252,11 +252,38 @@ static rpc_status_t set_variable_handler(void *context, struct call_req* req)
static rpc_status_t query_variable_info_handler(void *context, struct call_req* req)
{
+ efi_status_t efi_status = EFI_INVALID_PARAMETER;
struct smm_variable_provider *this_instance = (struct smm_variable_provider*)context;
- /* todo */
+ const struct call_param_buf *req_buf = call_req_get_req_buf(req);
+
+ if (req_buf->data_len >= sizeof(SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO)) {
+
+ struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+
+ if (resp_buf->size >= req_buf->data_len) {
- return TS_RPC_ERROR_NOT_READY;
+ memmove(resp_buf->data, req_buf->data, req_buf->data_len);
+
+ efi_status = uefi_variable_store_query_variable_info(
+ &this_instance->variable_store,
+ (SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO*)resp_buf->data);
+
+ if (efi_status == EFI_SUCCESS) {
+
+ resp_buf->data_len = sizeof(SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO);
+ }
+ }
+ else {
+
+ /* Reponse buffer not big enough */
+ efi_status = EFI_BAD_BUFFER_SIZE;
+ }
+ }
+
+ call_req_set_opstatus(req, efi_status);
+
+ return TS_RPC_CALL_ACCEPTED;
}
static rpc_status_t exit_boot_service_handler(void *context, struct call_req* req)
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 088940a8..15556e9d 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
@@ -335,12 +335,38 @@ TEST(SmmVariableServiceTests, setAndGetNv)
TEST(SmmVariableServiceTests, enumerateStoreContents)
{
efi_status_t efi_status = EFI_SUCCESS;
+
+ /* Query information about the empty variable store */
+ size_t nv_max_variable_storage_size = 0;
+ size_t nv_max_variable_size = 0;
+ size_t nv_remaining_variable_storage_size = 0;
+
+ efi_status = m_client->query_variable_info(
+ EFI_VARIABLE_NON_VOLATILE,
+ &nv_max_variable_storage_size,
+ &nv_remaining_variable_storage_size,
+ &nv_max_variable_size);
+ UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
+ UNSIGNED_LONGLONGS_EQUAL(nv_max_variable_storage_size, nv_remaining_variable_storage_size);
+
+ size_t v_max_variable_storage_size = 0;
+ size_t v_max_variable_size = 0;
+ size_t v_remaining_variable_storage_size = 0;
+
+ efi_status = m_client->query_variable_info(
+ 0,
+ &v_max_variable_storage_size,
+ &v_remaining_variable_storage_size,
+ &v_max_variable_size);
+ UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
+ UNSIGNED_LONGLONGS_EQUAL(v_max_variable_storage_size, v_remaining_variable_storage_size);
+
+ /* Add some variables to the store */
std::wstring var_name_1 = L"varibale_1";
std::wstring var_name_2 = L"varibale_2";
std::wstring var_name_3 = L"varibale_3";
std::string set_data = "Some variable data";
- /* Add some variables to the store */
efi_status = m_client->set_variable(
m_common_guid,
var_name_1,
@@ -365,6 +391,33 @@ TEST(SmmVariableServiceTests, enumerateStoreContents)
UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
+ /* Query variable info again and check it's as expected */
+ size_t max_variable_storage_size = 0;
+ size_t max_variable_size = 0;
+ size_t remaining_variable_storage_size = 0;
+
+ /* Check non-volatile - two variables have been added */
+ efi_status = m_client->query_variable_info(
+ EFI_VARIABLE_NON_VOLATILE,
+ &max_variable_storage_size,
+ &remaining_variable_storage_size,
+ &max_variable_size);
+ UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
+ UNSIGNED_LONGLONGS_EQUAL(
+ (nv_remaining_variable_storage_size - set_data.size() * 2),
+ remaining_variable_storage_size);
+
+ /* Check volatile - one variables have been added */
+ efi_status = m_client->query_variable_info(
+ 0,
+ &max_variable_storage_size,
+ &remaining_variable_storage_size,
+ &max_variable_size);
+ UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
+ UNSIGNED_LONGLONGS_EQUAL(
+ (v_remaining_variable_storage_size - set_data.size() * 1),
+ remaining_variable_storage_size);
+
/* Enumerate store contents - expect the values we added */
std::wstring var_name;
EFI_GUID guid = {0};
@@ -1,248 +0,0 @@
From 22120b4bd64da232e5a4e04a9a15376f34a933a3 Mon Sep 17 00:00:00 2001
From: Julian Hall <julian.hall@arm.com>
Date: Mon, 6 Dec 2021 15:20:12 +0000
Subject: [PATCH] Add uefi-test deployment
Adds a new deployment for building and running service level tests
for UEFI SMM services. Tests may be run against StMM, smm-gateway
or any other similar secure-world uefi service provider.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: Ic0e16dff51ef76ddd1f4dea37a4a55b029edd696
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
---
.../ts-service-test/arm-linux/CMakeLists.txt | 3 -
.../uefi-test/arm-linux/CMakeLists.txt | 43 +++++++++++
deployments/uefi-test/linux-pc/CMakeLists.txt | 76 +++++++++++++++++++
deployments/uefi-test/uefi-test.cmake | 52 +++++++++++++
tools/b-test/test_data.yaml | 10 +++
5 files changed, 181 insertions(+), 3 deletions(-)
create mode 100644 deployments/uefi-test/arm-linux/CMakeLists.txt
create mode 100644 deployments/uefi-test/linux-pc/CMakeLists.txt
create mode 100644 deployments/uefi-test/uefi-test.cmake
diff --git a/deployments/ts-service-test/arm-linux/CMakeLists.txt b/deployments/ts-service-test/arm-linux/CMakeLists.txt
index 6a01d38a..e902cd2f 100644
--- a/deployments/ts-service-test/arm-linux/CMakeLists.txt
+++ b/deployments/ts-service-test/arm-linux/CMakeLists.txt
@@ -23,9 +23,6 @@ add_components(
BASE_DIR ${TS_ROOT}
COMPONENTS
"components/app/test-runner"
-# Running smm_variable tests currently requires kernel built with CONFIG_STRICT_DEVMEM=n
-# "components/service/smm_variable/client/cpp"
-# "components/service/smm_variable/test/service"
)
include(${TS_ROOT}/external/CppUTest/CppUTest.cmake)
diff --git a/deployments/uefi-test/arm-linux/CMakeLists.txt b/deployments/uefi-test/arm-linux/CMakeLists.txt
new file mode 100644
index 00000000..053041ad
--- /dev/null
+++ b/deployments/uefi-test/arm-linux/CMakeLists.txt
@@ -0,0 +1,43 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+cmake_minimum_required(VERSION 3.16)
+include(../../deployment.cmake REQUIRED)
+
+#-------------------------------------------------------------------------------
+# The CMakeLists.txt for building the uefi-test deployment for arm-linux
+#
+# Used for building and running service level tests from Linux user-space
+# on an Arm platform with real deployments of UEFI SMM services
+#-------------------------------------------------------------------------------
+include(${TS_ROOT}/environments/arm-linux/env.cmake)
+project(trusted-services LANGUAGES CXX C)
+add_executable(uefi-test)
+target_include_directories(uefi-test PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
+
+add_components(
+ TARGET "uefi-test"
+ BASE_DIR ${TS_ROOT}
+ COMPONENTS
+ "components/app/test-runner"
+ )
+
+include(${TS_ROOT}/external/CppUTest/CppUTest.cmake)
+target_link_libraries(uefi-test PRIVATE CppUTest)
+
+#-------------------------------------------------------------------------------
+# Extend with components that are common across all deployments of
+# uefi-test
+#
+#-------------------------------------------------------------------------------
+include(../uefi-test.cmake REQUIRED)
+
+#-------------------------------------------------------------------------------
+# Define library options and dependencies.
+#
+#-------------------------------------------------------------------------------
+env_set_link_options(TGT uefi-test)
+target_link_libraries(uefi-test PRIVATE stdc++ gcc m)
diff --git a/deployments/uefi-test/linux-pc/CMakeLists.txt b/deployments/uefi-test/linux-pc/CMakeLists.txt
new file mode 100644
index 00000000..be6e9840
--- /dev/null
+++ b/deployments/uefi-test/linux-pc/CMakeLists.txt
@@ -0,0 +1,76 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+cmake_minimum_required(VERSION 3.16)
+include(../../deployment.cmake REQUIRED)
+
+#-------------------------------------------------------------------------------
+# The CMakeLists.txt for building the uefi-test deployment for linux-pc
+#
+# Used for building and running service level tests in a native PC enviroment.
+# Tests can be run by running the built executable called "uefi-test"
+#-------------------------------------------------------------------------------
+include(${TS_ROOT}/environments/linux-pc/env.cmake)
+project(trusted-services LANGUAGES CXX C)
+
+# Prevents symbols in the uefi-test executable overriding symbols with
+# with same name in libts during dynamic linking performed by the program
+# loader.
+set(CMAKE_C_VISIBILITY_PRESET hidden)
+
+# Preparing firmware-test-build by including it
+include(${TS_ROOT}/external/firmware_test_builder/FirmwareTestBuilder.cmake)
+
+include(CTest)
+include(UnitTest)
+
+set(COVERAGE FALSE CACHE BOOL "Enable code coverage measurement")
+set(UNIT_TEST_PROJECT_PATH ${TS_ROOT} CACHE PATH "Path of the project directory")
+set(CMAKE_CXX_STANDARD 11)
+
+unit_test_init_cpputest()
+
+if (COVERAGE)
+ include(Coverage)
+
+ set(COVERAGE_FILE "coverage.info")
+ set(TS_SERVICE_TEST_COVERAGE_FILE "uefi-test-coverage.info" CACHE PATH "Path of coverage info file")
+ set(TS_SERVICE_TEST_COVERAGE_REPORT_DIR "${CMAKE_CURRENT_BINARY_DIR}/ts-service-coverage-report" CACHE PATH "Directory of coverage report")
+
+ # Collecting coverage
+ coverage_generate(
+ NAME "ts-service test"
+ SOURCE_DIR ${TS_ROOT}
+ BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}
+ OUTPUT_FILE ${COVERAGE_FILE}
+ )
+
+ # Filtering project file coverage
+ coverage_filter(
+ INPUT_FILE ${COVERAGE_FILE}
+ OUTPUT_FILE ${TS_SERVICE_TEST_COVERAGE_FILE}
+ INCLUDE_DIRECTORY ${UNIT_TEST_PROJECT_PATH}/components
+ )
+
+ # Coverage report
+ coverage_generate_report(
+ INPUT_FILE ${TS_SERVICE_TEST_COVERAGE_FILE}
+ OUTPUT_DIRECTORY ${TS_SERVICE_TEST_COVERAGE_REPORT_DIR}
+ )
+endif()
+
+unit_test_add_suite(
+ NAME uefi-test
+)
+
+target_include_directories(uefi-test PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
+
+#-------------------------------------------------------------------------------
+# Extend with components that are common across all deployments of
+# uefi-test
+#
+#-------------------------------------------------------------------------------
+include(../uefi-test.cmake REQUIRED)
diff --git a/deployments/uefi-test/uefi-test.cmake b/deployments/uefi-test/uefi-test.cmake
new file mode 100644
index 00000000..ea678d0e
--- /dev/null
+++ b/deployments/uefi-test/uefi-test.cmake
@@ -0,0 +1,52 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------------
+# The base build file shared between deployments of 'uefi-test' for
+# different environments. Used for running end-to-end service-level tests
+# against SMM service providers that implement UEFI services such as smm
+# variable.
+#-------------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------------
+# Use libts for locating and accessing services. An appropriate version of
+# libts will be imported for the enviroment in which service tests are
+# deployed.
+#-------------------------------------------------------------------------------
+include(${TS_ROOT}/deployments/libts/libts-import.cmake)
+target_link_libraries(uefi-test PRIVATE libts)
+
+#-------------------------------------------------------------------------------
+# Components that are common accross all deployments
+#
+#-------------------------------------------------------------------------------
+add_components(
+ TARGET "uefi-test"
+ BASE_DIR ${TS_ROOT}
+ COMPONENTS
+ "components/service/smm_variable/client/cpp"
+ "components/service/smm_variable/test/service"
+)
+
+#-------------------------------------------------------------------------------
+# Components used from external projects
+#
+#-------------------------------------------------------------------------------
+
+# Nanopb
+include(${TS_ROOT}/external/nanopb/nanopb.cmake)
+target_link_libraries(uefi-test PRIVATE nanopb::protobuf-nanopb-static)
+protobuf_generate_all(TGT "uefi-test" NAMESPACE "protobuf" BASE_DIR "${TS_ROOT}/protocols")
+
+#-------------------------------------------------------------------------------
+# Define install content.
+#
+#-------------------------------------------------------------------------------
+if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+ set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
+endif()
+install(TARGETS uefi-test RUNTIME DESTINATION ${TS_ENV}/bin)
diff --git a/tools/b-test/test_data.yaml b/tools/b-test/test_data.yaml
index 11f8f633..33a85b12 100644
--- a/tools/b-test/test_data.yaml
+++ b/tools/b-test/test_data.yaml
@@ -163,3 +163,13 @@ data:
os_id : "GNU/Linux"
params:
- "-GUnix Makefiles"
+ - name: "uefi-test-pc-linux"
+ src: "$TS_ROOT/deployments/uefi-test/linux-pc"
+ os_id : "GNU/Linux"
+ params:
+ - "-GUnix Makefiles"
+ - name: "uefi-test-arm-linux"
+ src: "$TS_ROOT/deployments/uefi-test/arm-linux"
+ os_id : "GNU/Linux"
+ params:
+ - "-GUnix Makefiles"
@@ -1,33 +0,0 @@
From 289bec4cacac80cb43c19e4ca7b2c50fc932712e Mon Sep 17 00:00:00 2001
From: Julian Hall <julian.hall@arm.com>
Date: Wed, 8 Dec 2021 11:48:28 +0000
Subject: [PATCH] Fix interface ID parameter setting in sp/ffarpc_caller
When making FFA based RPC calls from one SP to another, the
destination interface ID parameter was not being set correctly.
This change fixes this issue.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: Iab520e4c7dc63ee1f5d3bf1bd1de702e4cc6f093
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
---
components/rpc/ffarpc/caller/sp/ffarpc_caller.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/components/rpc/ffarpc/caller/sp/ffarpc_caller.c b/components/rpc/ffarpc/caller/sp/ffarpc_caller.c
index 250b1781..dabcd90c 100644
--- a/components/rpc/ffarpc/caller/sp/ffarpc_caller.c
+++ b/components/rpc/ffarpc/caller/sp/ffarpc_caller.c
@@ -81,7 +81,7 @@ static rpc_status_t call_invoke(void *context, rpc_call_handle handle, uint32_t
req.destination_id = this_context->dest_partition_id;
req.source_id = own_id;
req.args[SP_CALL_ARGS_IFACE_ID_OPCODE] =
- FFA_CALL_ARGS_COMBINE_IFACE_ID_OPCODE(this_context->dest_partition_id, opcode);
+ FFA_CALL_ARGS_COMBINE_IFACE_ID_OPCODE(this_context->dest_iface_id, opcode);
//TODO: downcast problem?
req.args[SP_CALL_ARGS_REQ_DATA_LEN] = (uint32_t)this_context->req_len;
req.args[SP_CALL_ARGS_ENCODING] = this_context->rpc_caller.encoding;
@@ -1,109 +0,0 @@
From 18b20dea7cf7e8afc26c5d49d5368d3180bd54d7 Mon Sep 17 00:00:00 2001
From: Julian Hall <julian.hall@arm.com>
Date: Wed, 8 Dec 2021 16:05:22 +0000
Subject: [PATCH] Support FFARPC call requests with no shared buffer
To allow simple clients to make RPC calls for service operations
that take no request parameters and return no response parameters,
the ffarpc_call_ep.c has been modified to accept call requests
when no shared buffer exists, as long as there is no request data.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I83b1bfb719a005922d6394887492d2d272b74907
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
---
.../rpc/ffarpc/endpoint/ffarpc_call_ep.c | 52 ++++++++++---------
1 file changed, 27 insertions(+), 25 deletions(-)
diff --git a/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c b/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c
index 17f957c2..a08a250c 100644
--- a/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c
+++ b/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c
@@ -150,29 +150,43 @@ out:
static void handle_service_msg(struct ffa_call_ep *call_ep, uint16_t source_id,
const uint32_t *req_args, uint32_t *resp_args)
{
- rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_PARAMETER;
struct call_req call_req;
uint32_t ifaceid_opcode = req_args[SP_CALL_ARGS_IFACE_ID_OPCODE];
int idx = find_shm(call_ep, source_id);
- if (idx < 0) {
- EMSG("handle service msg error");
- goto out;
- }
-
call_req.caller_id = source_id;
call_req.interface_id = FFA_CALL_ARGS_EXTRACT_IFACE(ifaceid_opcode);
call_req.opcode = FFA_CALL_ARGS_EXTRACT_OPCODE(ifaceid_opcode);
call_req.encoding = req_args[SP_CALL_ARGS_ENCODING];
- call_req.req_buf.data = call_ep->shmem_buf[idx];
call_req.req_buf.data_len = req_args[SP_CALL_ARGS_REQ_DATA_LEN];
- call_req.req_buf.size = call_ep->shmem_buf_size[idx];
-
- call_req.resp_buf.data = call_ep->shmem_buf[idx];
call_req.resp_buf.data_len = 0;
- call_req.resp_buf.size = call_ep->shmem_buf_size[idx];
+
+ if (idx >= 0 && call_ep->shmem_buf[idx]) {
+ /* A shared buffer is available for call parameters */
+ call_req.req_buf.data = call_ep->shmem_buf[idx];
+ call_req.req_buf.size = call_ep->shmem_buf_size[idx];
+
+ call_req.resp_buf.data = call_ep->shmem_buf[idx];
+ call_req.resp_buf.size = call_ep->shmem_buf_size[idx];
+ }
+ else if (call_req.req_buf.data_len == 0) {
+ /* No shared buffer so only allow calls with no request data */
+ call_req.req_buf.data = NULL;
+ call_req.req_buf.size = 0;
+
+ call_req.resp_buf.data = NULL;
+ call_req.resp_buf.size = 0;
+ }
+ else {
+ /*
+ * Caller has specified non-zero length request data but there is
+ * no shared buffer to carry the request data.
+ */
+ goto out;
+ }
rpc_status = rpc_interface_receive(call_ep->iface, &call_req);
@@ -223,7 +237,6 @@ void ffa_call_ep_receive(struct ffa_call_ep *call_ep,
{
const uint32_t *req_args = req_msg->args;
uint32_t *resp_args = resp_msg->args;
- int idx;
uint16_t source_id = req_msg->source_id;
uint32_t ifaceid_opcode = req_args[SP_CALL_ARGS_IFACE_ID_OPCODE];
@@ -232,18 +245,7 @@ void ffa_call_ep_receive(struct ffa_call_ep *call_ep,
/* It's an RPC layer management request */
handle_mgmt_msg(call_ep, source_id, req_args, resp_args);
} else {
- /*
- * Assume anything else is a service request. Service requests
- * rely on a buffer being shared from the requesting client.
- * If it hasn't been set-up, fail the request.
- */
- idx = find_shm(call_ep, source_id);
-
- if (idx >= 0 && call_ep->shmem_buf[idx]) {
- handle_service_msg(call_ep, source_id, req_args, resp_args);
- } else {
- EMSG("shared buffer not found or NULL");
- set_mgmt_resp_args(resp_args, ifaceid_opcode, TS_RPC_ERROR_NOT_READY);
- }
+ /* Assume anything else is a service request */
+ handle_service_msg(call_ep, source_id, req_args, resp_args);
}
}
@@ -1,86 +0,0 @@
From a496978dcf82494c69e600f65adf061f15e565f4 Mon Sep 17 00:00:00 2001
From: Satish Kumar <satish.kumar01@arm.com>
Date: Sun, 12 Dec 2021 10:43:48 +0000
Subject: [PATCH] Run psa-arch-test
Fixes needed to run psa-arch-test
Signed-off-by: Satish Kumar <satish.kumar01@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Satish Kumar <satish.kumar01@arm.com>
---
components/service/common/psa_ipc/service_psa_ipc.c | 1 +
.../backend/secure_storage_ipc/secure_storage_ipc.c | 8 --------
.../service/secure_storage/include/psa/storage_common.h | 4 ++--
external/openamp/openamp.cmake | 2 +-
4 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/components/service/common/psa_ipc/service_psa_ipc.c b/components/service/common/psa_ipc/service_psa_ipc.c
index 95a07c13..5e5815db 100644
--- a/components/service/common/psa_ipc/service_psa_ipc.c
+++ b/components/service/common/psa_ipc/service_psa_ipc.c
@@ -185,6 +185,7 @@ psa_status_t psa_call(struct rpc_caller *caller, psa_handle_t psa_handle,
resp_msg->params.out_vec);
for (i = 0; i < resp_msg->params.out_len; i++) {
+ out_vec[i].len = out_vec_param[i].len;
memcpy(out_vec[i].base, rpc_caller_phys_to_virt(caller, out_vec_param[i].base),
out_vec[i].len);
}
diff --git a/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c
index 9b55f77d..a1f369db 100644
--- a/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c
+++ b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c
@@ -31,10 +31,6 @@ static psa_status_t secure_storage_ipc_set(void *context, uint32_t client_id,
ipc->client.rpc_status = TS_RPC_CALL_ACCEPTED;
- /* Validating input parameters */
- if (p_data == NULL)
- return PSA_ERROR_INVALID_ARGUMENT;
-
psa_status = psa_call(caller, TFM_PROTECTED_STORAGE_SERVICE_HANDLE,
TFM_PS_SET, in_vec, IOVEC_LEN(in_vec), NULL, 0);
if (psa_status < 0)
@@ -96,10 +92,6 @@ static psa_status_t secure_storage_ipc_get_info(void *context,
(void)client_id;
- /* Validating input parameters */
- if (!p_info)
- return PSA_ERROR_INVALID_ARGUMENT;
-
psa_status = psa_call(caller, TFM_PROTECTED_STORAGE_SERVICE_HANDLE,
TFM_PS_GET_INFO, in_vec,
IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
diff --git a/components/service/secure_storage/include/psa/storage_common.h b/components/service/secure_storage/include/psa/storage_common.h
index 4f6ba2a7..1fd6b40d 100644
--- a/components/service/secure_storage/include/psa/storage_common.h
+++ b/components/service/secure_storage/include/psa/storage_common.h
@@ -20,8 +20,8 @@ typedef uint64_t psa_storage_uid_t;
typedef uint32_t psa_storage_create_flags_t;
struct psa_storage_info_t {
- size_t capacity;
- size_t size;
+ uint32_t capacity;
+ uint32_t size;
psa_storage_create_flags_t flags;
};
diff --git a/external/openamp/openamp.cmake b/external/openamp/openamp.cmake
index aae13bad..75ab2290 100644
--- a/external/openamp/openamp.cmake
+++ b/external/openamp/openamp.cmake
@@ -61,7 +61,7 @@ execute_process(COMMAND
-DCMAKE_SYSTEM_PROCESSOR=arm
-DEXTERNAL_INCLUDE_PATHS=${OPENAMP_EXTERNAL_INCLUDE_PATHS}
-DMACHINE=template
- -DRPMSG_BUFFER_SIZE=512
+ -DRPMSG_BUFFER_SIZE=8192
${openamp_SOURCE_DIR}
WORKING_DIRECTORY
${openamp_BINARY_DIR}
@@ -1,169 +0,0 @@
From b417c1124af9d4569ba8871dfd1e43e626dddf12 Mon Sep 17 00:00:00 2001
From: Satish Kumar <satish.kumar01@arm.com>
Date: Sun, 12 Dec 2021 10:57:17 +0000
Subject: [PATCH] Use address instead of pointers
Since secure enclave is 32bit and we 64bit there is an issue
in the protocol communication design that force us to handle
on our side the manipulation of address and pointers to make
this work.
Signed-off-by: Rui Miguel Silva <rui.silva@arm.com>
Signed-off-by: Satish Kumar <satish.kumar01@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Satish Kumar <satish.kumar01@arm.com>
---
.../service/common/include/psa/client.h | 15 ++++++++++++++
.../service/common/psa_ipc/service_psa_ipc.c | 20 ++++++++++++-------
.../secure_storage_ipc/secure_storage_ipc.c | 20 +++++++++----------
3 files changed, 38 insertions(+), 17 deletions(-)
diff --git a/components/service/common/include/psa/client.h b/components/service/common/include/psa/client.h
index 69ccf14f..12dcd68f 100644
--- a/components/service/common/include/psa/client.h
+++ b/components/service/common/include/psa/client.h
@@ -81,6 +81,21 @@ struct __attribute__ ((__packed__)) psa_outvec {
uint32_t len; /*!< the size in bytes */
};
+static void *psa_u32_to_ptr(uint32_t addr)
+{
+ return (void *)(uintptr_t)addr;
+}
+
+static uint32_t psa_ptr_to_u32(void *ptr)
+{
+ return (uintptr_t)ptr;
+}
+
+static uint32_t psa_ptr_const_to_u32(const void *ptr)
+{
+ return (uintptr_t)ptr;
+}
+
/*************************** PSA Client API **********************************/
/**
diff --git a/components/service/common/psa_ipc/service_psa_ipc.c b/components/service/common/psa_ipc/service_psa_ipc.c
index 5e5815db..435c6c0a 100644
--- a/components/service/common/psa_ipc/service_psa_ipc.c
+++ b/components/service/common/psa_ipc/service_psa_ipc.c
@@ -62,6 +62,11 @@ static size_t psa_call_out_vec_len(const struct psa_outvec *out_vec, size_t out_
return resp_len;
}
+static uint32_t psa_virt_to_phys_u32(struct rpc_caller *caller, void *va)
+{
+ return (uintptr_t)rpc_caller_virt_to_phys(caller, va);
+}
+
psa_handle_t psa_connect(struct rpc_caller *caller, uint32_t sid,
uint32_t version)
{
@@ -147,20 +152,20 @@ psa_status_t psa_call(struct rpc_caller *caller, psa_handle_t psa_handle,
req_msg->params.psa_call_params.handle = psa_handle;
req_msg->params.psa_call_params.type = type;
req_msg->params.psa_call_params.in_len = in_len;
- req_msg->params.psa_call_params.in_vec = rpc_caller_virt_to_phys(caller, in_vec_param);
+ req_msg->params.psa_call_params.in_vec = psa_virt_to_phys_u32(caller, in_vec_param);
req_msg->params.psa_call_params.out_len = out_len;
- req_msg->params.psa_call_params.out_vec = rpc_caller_virt_to_phys(caller, out_vec_param);
+ req_msg->params.psa_call_params.out_vec = psa_virt_to_phys_u32(caller, out_vec_param);
for (i = 0; i < in_len; i++) {
- in_vec_param[i].base = rpc_caller_virt_to_phys(caller, payload);
+ in_vec_param[i].base = psa_virt_to_phys_u32(caller, payload);
in_vec_param[i].len = in_vec[i].len;
- memcpy(payload, in_vec[i].base, in_vec[i].len);
+ memcpy(payload, psa_u32_to_ptr(in_vec[i].base), in_vec[i].len);
payload += in_vec[i].len;
}
for (i = 0; i < out_len; i++) {
- out_vec_param[i].base = NULL;
+ out_vec_param[i].base = 0;
out_vec_param[i].len = out_vec[i].len;
}
@@ -182,11 +187,12 @@ psa_status_t psa_call(struct rpc_caller *caller, psa_handle_t psa_handle,
goto caller_end;
out_vec_param = (struct psa_outvec *)rpc_caller_phys_to_virt(caller,
- resp_msg->params.out_vec);
+ psa_u32_to_ptr(resp_msg->params.out_vec));
for (i = 0; i < resp_msg->params.out_len; i++) {
out_vec[i].len = out_vec_param[i].len;
- memcpy(out_vec[i].base, rpc_caller_phys_to_virt(caller, out_vec_param[i].base),
+ memcpy(psa_u32_to_ptr(out_vec[i].base),
+ rpc_caller_phys_to_virt(caller, psa_u32_to_ptr(out_vec_param[i].base)),
out_vec[i].len);
}
diff --git a/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c
index a1f369db..bda442a6 100644
--- a/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c
+++ b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c
@@ -22,9 +22,9 @@ static psa_status_t secure_storage_ipc_set(void *context, uint32_t client_id,
psa_handle_t psa_handle;
psa_status_t psa_status;
struct psa_invec in_vec[] = {
- { .base = &uid, .len = sizeof(uid) },
- { .base = p_data, .len = data_length },
- { .base = &create_flags, .len = sizeof(create_flags) },
+ { .base = psa_ptr_to_u32(&uid), .len = sizeof(uid) },
+ { .base = psa_ptr_const_to_u32(p_data), .len = data_length },
+ { .base = psa_ptr_to_u32(&create_flags), .len = sizeof(create_flags) },
};
(void)client_id;
@@ -53,11 +53,11 @@ static psa_status_t secure_storage_ipc_get(void *context,
psa_status_t psa_status;
uint32_t offset = (uint32_t)data_offset;
struct psa_invec in_vec[] = {
- { .base = &uid, .len = sizeof(uid) },
- { .base = &offset, .len = sizeof(offset) },
+ { .base = psa_ptr_to_u32(&uid), .len = sizeof(uid) },
+ { .base = psa_ptr_to_u32(&offset), .len = sizeof(offset) },
};
struct psa_outvec out_vec[] = {
- { .base = p_data, .len = data_size },
+ { .base = psa_ptr_to_u32(p_data), .len = data_size },
};
if (!p_data_length) {
@@ -84,10 +84,10 @@ static psa_status_t secure_storage_ipc_get_info(void *context,
psa_handle_t psa_handle;
psa_status_t psa_status;
struct psa_invec in_vec[] = {
- { .base = &uid, .len = sizeof(uid) },
+ { .base = psa_ptr_to_u32(&uid), .len = sizeof(uid) },
};
struct psa_outvec out_vec[] = {
- { .base = p_info, .len = sizeof(*p_info) },
+ { .base = psa_ptr_to_u32(p_info), .len = sizeof(*p_info) },
};
(void)client_id;
@@ -110,7 +110,7 @@ static psa_status_t secure_storage_ipc_remove(void *context,
psa_handle_t psa_handle;
psa_status_t psa_status;
struct psa_invec in_vec[] = {
- { .base = &uid, .len = sizeof(uid) },
+ { .base = psa_ptr_to_u32(&uid), .len = sizeof(uid) },
};
(void)client_id;
@@ -164,7 +164,7 @@ static uint32_t secure_storage_get_support(void *context, uint32_t client_id)
psa_status_t psa_status;
uint32_t support_flags;
struct psa_outvec out_vec[] = {
- { .base = &support_flags, .len = sizeof(support_flags) },
+ { .base = psa_ptr_to_u32(&support_flags), .len = sizeof(support_flags) },
};
(void)client_id;
@@ -1,267 +0,0 @@
From 259300dc81b95ff65cd2e95e0fecd140d76e4b5e Mon Sep 17 00:00:00 2001
From: Rui Miguel Silva <rui.silva@linaro.org>
Date: Tue, 7 Dec 2021 11:50:00 +0000
Subject: [PATCH] Add psa ipc attestation to se proxy
Implement attestation client API as psa ipc and include it to
se proxy deployment.
Signed-off-by: Rui Miguel Silva <rui.silva@arm.com>
Signed-off-by: Satish Kumar <satish.kumar01@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
---
.../client/psa_ipc/component.cmake | 13 +++
.../client/psa_ipc/iat_ipc_client.c | 86 +++++++++++++++++++
.../reporter/psa_ipc/component.cmake | 13 +++
.../reporter/psa_ipc/psa_ipc_attest_report.c | 45 ++++++++++
components/service/common/include/psa/sid.h | 4 +
deployments/se-proxy/opteesp/CMakeLists.txt | 3 +-
.../se-proxy/opteesp/service_proxy_factory.c | 6 ++
7 files changed, 169 insertions(+), 1 deletion(-)
create mode 100644 components/service/attestation/client/psa_ipc/component.cmake
create mode 100644 components/service/attestation/client/psa_ipc/iat_ipc_client.c
create mode 100644 components/service/attestation/reporter/psa_ipc/component.cmake
create mode 100644 components/service/attestation/reporter/psa_ipc/psa_ipc_attest_report.c
diff --git a/components/service/attestation/client/psa_ipc/component.cmake b/components/service/attestation/client/psa_ipc/component.cmake
new file mode 100644
index 00000000..a5bc6b4a
--- /dev/null
+++ b/components/service/attestation/client/psa_ipc/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}/iat_ipc_client.c"
+ )
diff --git a/components/service/attestation/client/psa_ipc/iat_ipc_client.c b/components/service/attestation/client/psa_ipc/iat_ipc_client.c
new file mode 100644
index 00000000..30bd0a13
--- /dev/null
+++ b/components/service/attestation/client/psa_ipc/iat_ipc_client.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+#include "../psa/iat_client.h"
+#include <protocols/rpc/common/packed-c/status.h>
+#include <psa/initial_attestation.h>
+#include <psa/client.h>
+#include <psa/sid.h>
+#include <service/common/client/service_client.h>
+
+/**
+ * @brief The singleton psa_iat_client instance
+ *
+ * The psa attestation C API assumes a single backend service provider.
+ */
+static struct service_client instance;
+
+
+psa_status_t psa_iat_client_init(struct rpc_caller *caller)
+{
+ return service_client_init(&instance, caller);
+}
+
+void psa_iat_client_deinit(void)
+{
+ service_client_deinit(&instance);
+}
+
+int psa_iat_client_rpc_status(void)
+{
+ return instance.rpc_status;
+}
+
+psa_status_t psa_initial_attest_get_token(const uint8_t *auth_challenge,
+ size_t challenge_size,
+ uint8_t *token_buf,
+ size_t token_buf_size,
+ size_t *token_size)
+{
+ psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
+ struct rpc_caller *caller = instance.caller;
+ struct psa_invec in_vec[] = {
+ { .base = psa_ptr_const_to_u32(auth_challenge), .len = challenge_size},
+ };
+ struct psa_outvec out_vec[] = {
+ { .base = psa_ptr_to_u32(token_buf), .len = token_buf_size},
+ };
+
+ if (!token_buf || !token_buf_size)
+ return PSA_ERROR_INVALID_ARGUMENT;
+
+ status = psa_call(caller, TFM_ATTESTATION_SERVICE_HANDLE,
+ TFM_ATTEST_GET_TOKEN, in_vec, IOVEC_LEN(in_vec),
+ out_vec, IOVEC_LEN(out_vec));
+ if (status == PSA_SUCCESS) {
+ *token_size = out_vec[0].len;
+ }
+
+ return status;
+}
+
+psa_status_t psa_initial_attest_get_token_size(size_t challenge_size,
+ size_t *token_size)
+{
+ struct rpc_caller *caller = instance.caller;
+ psa_status_t status;
+ struct psa_invec in_vec[] = {
+ { .base = psa_ptr_to_u32(&challenge_size), .len = sizeof(uint32_t)}
+ };
+ struct psa_outvec out_vec[] = {
+ { .base = psa_ptr_to_u32(token_size), .len = sizeof(uint32_t)}
+ };
+
+ status = psa_call(caller, TFM_ATTESTATION_SERVICE_HANDLE,
+ TFM_ATTEST_GET_TOKEN_SIZE,
+ in_vec, IOVEC_LEN(in_vec),
+ out_vec, IOVEC_LEN(out_vec));
+
+ return status;
+}
diff --git a/components/service/attestation/reporter/psa_ipc/component.cmake b/components/service/attestation/reporter/psa_ipc/component.cmake
new file mode 100644
index 00000000..b37830c6
--- /dev/null
+++ b/components/service/attestation/reporter/psa_ipc/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}/psa_ipc_attest_report.c"
+ )
diff --git a/components/service/attestation/reporter/psa_ipc/psa_ipc_attest_report.c b/components/service/attestation/reporter/psa_ipc/psa_ipc_attest_report.c
new file mode 100644
index 00000000..15805e8e
--- /dev/null
+++ b/components/service/attestation/reporter/psa_ipc/psa_ipc_attest_report.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * A attestation reporter for psa ipc
+ */
+
+#include <stddef.h>
+#include <psa/error.h>
+#include <service/attestation/reporter/attest_report.h>
+#include <psa/initial_attestation.h>
+
+#define TOKEN_BUF_SIZE 1024
+
+static uint8_t token_buf[TOKEN_BUF_SIZE];
+
+int attest_report_create(int32_t client_id, const uint8_t *auth_challenge_data,
+ size_t auth_challenge_len, const uint8_t **report,
+ size_t *report_len)
+{
+ *report = token_buf;
+ psa_status_t ret;
+ size_t token_size = 0;
+
+ ret = psa_initial_attest_get_token(auth_challenge_data,
+ auth_challenge_len, token_buf,
+ TOKEN_BUF_SIZE, &token_size);
+ if (ret != PSA_SUCCESS) {
+ *report = NULL;
+ *report_len = 0;
+ return ret;
+ }
+
+ *report_len = token_size;
+
+ return PSA_SUCCESS;
+}
+
+void attest_report_destroy(const uint8_t *report)
+{
+ (void)report;
+}
diff --git a/components/service/common/include/psa/sid.h b/components/service/common/include/psa/sid.h
index aaa973c6..833f5039 100644
--- a/components/service/common/include/psa/sid.h
+++ b/components/service/common/include/psa/sid.h
@@ -50,6 +50,10 @@ extern "C" {
#define TFM_ATTESTATION_SERVICE_VERSION (1U)
#define TFM_ATTESTATION_SERVICE_HANDLE (0x40000103U)
+/* Initial Attestation message types that distinguish Attest services. */
+#define TFM_ATTEST_GET_TOKEN 1001
+#define TFM_ATTEST_GET_TOKEN_SIZE 1002
+
/******** TFM_SP_FWU ********/
#define TFM_FWU_WRITE_SID (0x000000A0U)
#define TFM_FWU_WRITE_VERSION (1U)
diff --git a/deployments/se-proxy/opteesp/CMakeLists.txt b/deployments/se-proxy/opteesp/CMakeLists.txt
index 663177b7..af2225e7 100644
--- a/deployments/se-proxy/opteesp/CMakeLists.txt
+++ b/deployments/se-proxy/opteesp/CMakeLists.txt
@@ -77,12 +77,13 @@ add_components(TARGET "se-proxy"
"components/service/attestation/include"
"components/service/attestation/provider"
"components/service/attestation/provider/serializer/packed-c"
+ "components/service/attestation/reporter/psa_ipc"
+ "components/service/attestation/client/psa_ipc"
"components/rpc/openamp/caller/sp"
# Stub service provider backends
"components/rpc/dummy"
"components/rpc/common/caller"
- "components/service/attestation/reporter/stub"
"components/service/attestation/key_mngr/stub"
"components/service/crypto/backend/stub"
"components/service/crypto/client/psa"
diff --git a/deployments/se-proxy/opteesp/service_proxy_factory.c b/deployments/se-proxy/opteesp/service_proxy_factory.c
index 57290056..4b8ccecc 100644
--- a/deployments/se-proxy/opteesp/service_proxy_factory.c
+++ b/deployments/se-proxy/opteesp/service_proxy_factory.c
@@ -23,12 +23,18 @@ struct openamp_caller openamp;
struct rpc_interface *attest_proxy_create(void)
{
struct rpc_interface *attest_iface;
+ struct rpc_caller *attest_caller;
/* Static objects for proxy instance */
static struct attest_provider attest_provider;
+ attest_caller = openamp_caller_init(&openamp);
+ if (!attest_caller)
+ return NULL;
+
/* Initialize the service provider */
attest_iface = attest_provider_init(&attest_provider);
+ psa_iat_client_init(&openamp.rpc_caller);
attest_provider_register_serializer(&attest_provider,
TS_RPC_ENCODING_PACKED_C, packedc_attest_provider_serializer_instance());
@@ -1,164 +0,0 @@
From 90006cecbbba58afee5f51e6bd72f7027a257b5e Mon Sep 17 00:00:00 2001
From: Satish Kumar <satish.kumar01@arm.com>
Date: Thu, 9 Dec 2021 14:11:06 +0000
Subject: [PATCH] Setup its backend as openamp rpc using secure storage ipc
implementation.
Signed-off-by: Rui Miguel Silva <rui.silva@arm.com>
Signed-off-by: Satish Kumar <satish.kumar01@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Satish Kumar <satish.kumar01@arm.com>
---
components/service/common/include/psa/sid.h | 12 +++++-----
.../secure_storage_ipc/secure_storage_ipc.c | 20 ++++++++---------
.../secure_storage_ipc/secure_storage_ipc.h | 1 +
.../se-proxy/opteesp/service_proxy_factory.c | 22 +++++++++++++------
4 files changed, 32 insertions(+), 23 deletions(-)
diff --git a/components/service/common/include/psa/sid.h b/components/service/common/include/psa/sid.h
index 833f5039..4a951d4a 100644
--- a/components/service/common/include/psa/sid.h
+++ b/components/service/common/include/psa/sid.h
@@ -20,12 +20,12 @@ extern "C" {
/* Invalid UID */
#define TFM_PS_INVALID_UID 0
-/* PS message types that distinguish PS services. */
-#define TFM_PS_SET 1001
-#define TFM_PS_GET 1002
-#define TFM_PS_GET_INFO 1003
-#define TFM_PS_REMOVE 1004
-#define TFM_PS_GET_SUPPORT 1005
+/* PS / ITS message types that distinguish PS services. */
+#define TFM_PS_ITS_SET 1001
+#define TFM_PS_ITS_GET 1002
+#define TFM_PS_ITS_GET_INFO 1003
+#define TFM_PS_ITS_REMOVE 1004
+#define TFM_PS_ITS_GET_SUPPORT 1005
/******** TFM_SP_ITS ********/
#define TFM_INTERNAL_TRUSTED_STORAGE_SERVICE_SID (0x00000070U)
diff --git a/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c
index bda442a6..0e1b48c0 100644
--- a/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c
+++ b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c
@@ -31,8 +31,8 @@ static psa_status_t secure_storage_ipc_set(void *context, uint32_t client_id,
ipc->client.rpc_status = TS_RPC_CALL_ACCEPTED;
- psa_status = psa_call(caller, TFM_PROTECTED_STORAGE_SERVICE_HANDLE,
- TFM_PS_SET, in_vec, IOVEC_LEN(in_vec), NULL, 0);
+ psa_status = psa_call(caller, ipc->service_handle, TFM_PS_ITS_SET,
+ in_vec, IOVEC_LEN(in_vec), NULL, 0);
if (psa_status < 0)
EMSG("ipc_set: psa_call failed: %d", psa_status);
@@ -65,8 +65,8 @@ static psa_status_t secure_storage_ipc_get(void *context,
return PSA_ERROR_INVALID_ARGUMENT;
}
- psa_status = psa_call(caller, TFM_PROTECTED_STORAGE_SERVICE_HANDLE,
- TFM_PS_GET, in_vec, IOVEC_LEN(in_vec),
+ psa_status = psa_call(caller, ipc->service_handle,
+ TFM_PS_ITS_GET, in_vec, IOVEC_LEN(in_vec),
out_vec, IOVEC_LEN(out_vec));
if (psa_status == PSA_SUCCESS)
*p_data_length = out_vec[0].len;
@@ -92,8 +92,8 @@ static psa_status_t secure_storage_ipc_get_info(void *context,
(void)client_id;
- psa_status = psa_call(caller, TFM_PROTECTED_STORAGE_SERVICE_HANDLE,
- TFM_PS_GET_INFO, in_vec,
+ psa_status = psa_call(caller, ipc->service_handle,
+ TFM_PS_ITS_GET_INFO, in_vec,
IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
if (psa_status != PSA_SUCCESS)
EMSG("ipc_get_info: failed to psa_call: %d", psa_status);
@@ -115,8 +115,8 @@ static psa_status_t secure_storage_ipc_remove(void *context,
(void)client_id;
- psa_status = psa_call(caller, TFM_PROTECTED_STORAGE_SERVICE_HANDLE,
- TFM_PS_REMOVE, in_vec,
+ psa_status = psa_call(caller, ipc->service_handle,
+ TFM_PS_ITS_REMOVE, in_vec,
IOVEC_LEN(in_vec), NULL, 0);
if (psa_status != PSA_SUCCESS)
EMSG("ipc_remove: failed to psa_call: %d", psa_status);
@@ -169,8 +169,8 @@ static uint32_t secure_storage_get_support(void *context, uint32_t client_id)
(void)client_id;
- psa_status = psa_call(caller, TFM_PROTECTED_STORAGE_SERVICE_HANDLE,
- TFM_PS_GET_SUPPORT, NULL, 0,
+ psa_status = psa_call(caller, ipc->service_handle,
+ TFM_PS_ITS_GET_SUPPORT, NULL, 0,
out_vec, IOVEC_LEN(out_vec));
if (psa_status != PSA_SUCCESS)
EMSG("ipc_get_support: failed to psa_call: %d", psa_status);
diff --git a/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h
index e8c1e8fd..d9949f6a 100644
--- a/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h
+++ b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h
@@ -21,6 +21,7 @@ struct secure_storage_ipc
{
struct storage_backend backend;
struct service_client client;
+ int32_t service_handle;
};
/**
diff --git a/deployments/se-proxy/opteesp/service_proxy_factory.c b/deployments/se-proxy/opteesp/service_proxy_factory.c
index 4b8ccecc..1110ac46 100644
--- a/deployments/se-proxy/opteesp/service_proxy_factory.c
+++ b/deployments/se-proxy/opteesp/service_proxy_factory.c
@@ -5,6 +5,7 @@
*/
#include <stddef.h>
+#include <psa/sid.h>
#include <rpc/common/endpoint/rpc_interface.h>
#include <rpc/openamp/caller/sp/openamp_caller.h>
#include <service/attestation/provider/attest_provider.h>
@@ -60,23 +61,30 @@ struct rpc_interface *ps_proxy_create(void)
{
static struct secure_storage_provider ps_provider;
static struct secure_storage_ipc ps_backend;
- static struct rpc_caller *storage_caller;
+ struct rpc_caller *storage_caller;
struct storage_backend *backend;
storage_caller = openamp_caller_init(&openamp);
if (!storage_caller)
return NULL;
backend = secure_storage_ipc_init(&ps_backend, &openamp.rpc_caller);
+ ps_backend.service_handle = TFM_PROTECTED_STORAGE_SERVICE_HANDLE;
return secure_storage_provider_init(&ps_provider, backend);
}
struct rpc_interface *its_proxy_create(void)
{
- static struct mock_store its_backend;
- static struct secure_storage_provider its_provider;
-
- struct storage_backend *backend = mock_store_init(&its_backend);
-
- return secure_storage_provider_init(&its_provider, backend);
+ static struct secure_storage_provider its_provider;
+ static struct secure_storage_ipc its_backend;
+ struct rpc_caller *storage_caller;
+ struct storage_backend *backend;
+
+ storage_caller = openamp_caller_init(&openamp);
+ if (!storage_caller)
+ return NULL;
+ backend = secure_storage_ipc_init(&its_backend, &openamp.rpc_caller);
+ its_backend.service_handle = TFM_INTERNAL_TRUSTED_STORAGE_SERVICE_HANDLE;
+
+ return secure_storage_provider_init(&its_provider, backend);
}
@@ -1,34 +0,0 @@
From 8fca2a8eed6ebc1cbf9f7972c6a9bb137ebafe1a Mon Sep 17 00:00:00 2001
From: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
Date: Sun, 12 Dec 2021 17:07:03 +0000
Subject: [PATCH] Increase SMM gateway UEFI variable macro value
The maximum number of UEFI variables that be supported by SMM
gateway is currently 40. When more than 40 variables are written,
or read SMM gateway returns error code. Currently this value is
increased to 100 to support more UEFI variables.
Signed-off-by: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
---
deployments/smm-gateway/smm_gateway.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/deployments/smm-gateway/smm_gateway.c b/deployments/smm-gateway/smm_gateway.c
index 7828b3af..7e6729ee 100644
--- a/deployments/smm-gateway/smm_gateway.c
+++ b/deployments/smm-gateway/smm_gateway.c
@@ -20,6 +20,9 @@
#define SMM_GATEWAY_NV_STORE_SN "sn:ffa:751bf801-3dde-4768-a514-0f10aeed1790:0"
#endif
+/* Maximum number of UEFI variables set to 100 */
+#define SMM_GATEWAY_MAX_UEFI_VARIABLES (100)
+
/* Default maximum number of UEFI variables */
#ifndef SMM_GATEWAY_MAX_UEFI_VARIABLES
#define SMM_GATEWAY_MAX_UEFI_VARIABLES (40)
@@ -1,436 +0,0 @@
From eb1beb0f4f3a0d97a1ee941b068fb1f3b7ba7d7b Mon Sep 17 00:00:00 2001
From: Julian Hall <julian.hall@arm.com>
Date: Tue, 12 Oct 2021 15:45:41 +0100
Subject: [PATCH] Add stub capsule update service components
To facilitate development of a capsule update service provider,
stub components are added to provide a starting point for an
implementation. The capsule update service provider is integrated
into the se-proxy/opteesp deployment.
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I0d4049bb4de5af7ca80806403301692507085d28
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
---
.../backend/capsule_update_backend.h | 24 ++++
.../provider/capsule_update_provider.c | 133 ++++++++++++++++++
.../provider/capsule_update_provider.h | 51 +++++++
.../capsule_update/provider/component.cmake | 13 ++
deployments/se-proxy/opteesp/CMakeLists.txt | 1 +
deployments/se-proxy/opteesp/se_proxy_sp.c | 3 +
.../se-proxy/opteesp/service_proxy_factory.c | 16 +++
.../se-proxy/opteesp/service_proxy_factory.h | 1 +
deployments/se-proxy/se_proxy_interfaces.h | 9 +-
.../capsule_update/capsule_update_proto.h | 13 ++
protocols/service/capsule_update/opcodes.h | 17 +++
protocols/service/capsule_update/parameters.h | 15 ++
12 files changed, 292 insertions(+), 4 deletions(-)
create mode 100644 components/service/capsule_update/backend/capsule_update_backend.h
create mode 100644 components/service/capsule_update/provider/capsule_update_provider.c
create mode 100644 components/service/capsule_update/provider/capsule_update_provider.h
create mode 100644 components/service/capsule_update/provider/component.cmake
create mode 100644 protocols/service/capsule_update/capsule_update_proto.h
create mode 100644 protocols/service/capsule_update/opcodes.h
create mode 100644 protocols/service/capsule_update/parameters.h
diff --git a/components/service/capsule_update/backend/capsule_update_backend.h b/components/service/capsule_update/backend/capsule_update_backend.h
new file mode 100644
index 00000000..f3144ff1
--- /dev/null
+++ b/components/service/capsule_update/backend/capsule_update_backend.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CAPSULE_UPDATE_BACKEND_H
+#define CAPSULE_UPDATE_BACKEND_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Defines the common capsule update backend interface. Concrete backends
+ * implement this interface for different types of platform.
+ */
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CAPSULE_UPDATE_BACKEND_H */
diff --git a/components/service/capsule_update/provider/capsule_update_provider.c b/components/service/capsule_update/provider/capsule_update_provider.c
new file mode 100644
index 00000000..9bbd7abc
--- /dev/null
+++ b/components/service/capsule_update/provider/capsule_update_provider.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <psa/client.h>
+#include <psa/sid.h>
+#include <trace.h>
+
+#include <protocols/service/capsule_update/capsule_update_proto.h>
+#include <protocols/rpc/common/packed-c/status.h>
+#include "capsule_update_provider.h"
+
+
+#define CAPSULE_UPDATE_REQUEST (0x1)
+#define KERNEL_STARTED_EVENT (0x2)
+
+enum corstone1000_ioctl_id_t {
+ IOCTL_CORSTONE1000_FWU_FLASH_IMAGES = 0,
+ IOCTL_CORSTONE1000_FWU_HOST_ACK,
+};
+
+/* Service request handlers */
+static rpc_status_t update_capsule_handler(void *context, struct call_req *req);
+static rpc_status_t boot_confirmed_handler(void *context, struct call_req *req);
+
+/* Handler mapping table for service */
+static const struct service_handler handler_table[] = {
+ {CAPSULE_UPDATE_OPCODE_UPDATE_CAPSULE, update_capsule_handler},
+ {CAPSULE_UPDATE_OPCODE_BOOT_CONFIRMED, boot_confirmed_handler}
+};
+
+struct rpc_interface *capsule_update_provider_init(
+ struct capsule_update_provider *context)
+{
+ struct rpc_interface *rpc_interface = NULL;
+
+ if (context) {
+
+ service_provider_init(
+ &context->base_provider,
+ context,
+ handler_table,
+ sizeof(handler_table)/sizeof(struct service_handler));
+
+ rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
+ }
+
+ return rpc_interface;
+}
+
+void capsule_update_provider_deinit(struct capsule_update_provider *context)
+{
+ (void)context;
+}
+
+static rpc_status_t event_handler(uint32_t opcode, struct rpc_caller *caller)
+{
+ uint32_t ioctl_id;
+ psa_handle_t handle;
+ rpc_status_t rpc_status = TS_RPC_CALL_ACCEPTED;
+
+ struct psa_invec in_vec[] = {
+ { .base = &ioctl_id, .len = sizeof(ioctl_id) }
+ };
+
+ if(!caller) {
+ EMSG("event_handler rpc_caller is NULL");
+ rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+ return rpc_status;
+ }
+
+ MSG("event handler opcode %x", opcode);
+ switch(opcode) {
+ case CAPSULE_UPDATE_REQUEST:
+ /* Openamp call with IOCTL for firmware update*/
+ ioctl_id = IOCTL_CORSTONE1000_FWU_FLASH_IMAGES;
+ handle = psa_connect(caller, TFM_SP_PLATFORM_IOCTL_SID,
+ TFM_SP_PLATFORM_IOCTL_VERSION);
+ if (handle <= 0) {
+ EMSG("%s Invalid handle", __func__);
+ rpc_status = TS_RPC_ERROR_INVALID_PARAMETER;
+ return rpc_status;
+ }
+ psa_call(caller,handle, PSA_IPC_CALL,
+ in_vec,IOVEC_LEN(in_vec), NULL, 0);
+ break;
+
+ case KERNEL_STARTED_EVENT:
+ ioctl_id = IOCTL_CORSTONE1000_FWU_HOST_ACK;
+ /*openamp call with IOCTL for kernel start*/
+ handle = psa_connect(caller, TFM_SP_PLATFORM_IOCTL_SID,
+ TFM_SP_PLATFORM_IOCTL_VERSION);
+ if (handle <= 0) {
+ EMSG("%s Invalid handle", __func__);
+ rpc_status = TS_RPC_ERROR_INVALID_PARAMETER;
+ return rpc_status;
+ }
+ psa_call(caller,handle, PSA_IPC_CALL,
+ in_vec,IOVEC_LEN(in_vec), NULL, 0);
+ break;
+ default:
+ EMSG("%s unsupported opcode", __func__);
+ rpc_status = TS_RPC_ERROR_INVALID_PARAMETER;
+ return rpc_status;
+ }
+ return rpc_status;
+
+}
+
+static rpc_status_t update_capsule_handler(void *context, struct call_req *req)
+{
+ struct capsule_update_provider *this_instance = (struct capsule_update_provider*)context;
+ struct rpc_caller *caller = this_instance->client.caller;
+ uint32_t opcode = req->opcode;
+ rpc_status_t rpc_status = TS_RPC_ERROR_NOT_READY;
+
+ rpc_status = event_handler(opcode, caller);
+ return rpc_status;
+}
+
+static rpc_status_t boot_confirmed_handler(void *context, struct call_req *req)
+{
+ struct capsule_update_provider *this_instance = (struct capsule_update_provider*)context;
+ struct rpc_caller *caller = this_instance->client.caller;
+ uint32_t opcode = req->opcode;
+ rpc_status_t rpc_status = TS_RPC_ERROR_NOT_READY;
+
+ rpc_status = event_handler(opcode, caller);
+
+ return rpc_status;
+}
diff --git a/components/service/capsule_update/provider/capsule_update_provider.h b/components/service/capsule_update/provider/capsule_update_provider.h
new file mode 100644
index 00000000..3de49854
--- /dev/null
+++ b/components/service/capsule_update/provider/capsule_update_provider.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CAPSULE_UPDATE_PROVIDER_H
+#define CAPSULE_UPDATE_PROVIDER_H
+
+#include <rpc/common/endpoint/rpc_interface.h>
+#include <service/common/provider/service_provider.h>
+#include <service/common/client/service_client.h>
+#include <service/capsule_update/backend/capsule_update_backend.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The capsule_update_provider is a service provider that accepts update capsule
+ * requests and delegates them to a suitable backend that applies the update.
+ */
+struct capsule_update_provider
+{
+ struct service_provider base_provider;
+ struct service_client client;
+};
+
+/**
+ * \brief Initialize an instance of the capsule update service provider
+ *
+ * @param[in] context The instance to initialize
+ *
+ * \return An rpc_interface or NULL on failure
+ */
+struct rpc_interface *capsule_update_provider_init(
+ struct capsule_update_provider *context);
+
+/**
+ * \brief Cleans up when the instance is no longer needed
+ *
+ * \param[in] context The instance to de-initialize
+ */
+void capsule_update_provider_deinit(
+ struct capsule_update_provider *context);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CAPSULE_UPDATE_PROVIDER_H */
diff --git a/components/service/capsule_update/provider/component.cmake b/components/service/capsule_update/provider/component.cmake
new file mode 100644
index 00000000..1d412eb2
--- /dev/null
+++ b/components/service/capsule_update/provider/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}/capsule_update_provider.c"
+ )
diff --git a/deployments/se-proxy/opteesp/CMakeLists.txt b/deployments/se-proxy/opteesp/CMakeLists.txt
index 21904283..953bb716 100644
--- a/deployments/se-proxy/opteesp/CMakeLists.txt
+++ b/deployments/se-proxy/opteesp/CMakeLists.txt
@@ -80,6 +80,7 @@ add_components(TARGET "se-proxy"
"components/service/attestation/reporter/psa_ipc"
"components/service/attestation/client/psa_ipc"
"components/rpc/openamp/caller/sp"
+ "components/service/capsule_update/provider"
# Stub service provider backends
"components/rpc/dummy"
diff --git a/deployments/se-proxy/opteesp/se_proxy_sp.c b/deployments/se-proxy/opteesp/se_proxy_sp.c
index ef90d9ee..11b014b2 100644
--- a/deployments/se-proxy/opteesp/se_proxy_sp.c
+++ b/deployments/se-proxy/opteesp/se_proxy_sp.c
@@ -48,6 +48,9 @@ void __noreturn sp_main(struct ffa_init_info *init_info)
rpc_iface = attest_proxy_create();
rpc_demux_attach(&rpc_demux, SE_PROXY_INTERFACE_ID_ATTEST, rpc_iface);
+ rpc_iface = capsule_update_proxy_create();
+ rpc_demux_attach(&rpc_demux, SE_PROXY_INTERFACE_ID_CAPSULE_UPDATE, rpc_iface);
+
/* End of boot phase */
sp_msg_wait(&req_msg);
diff --git a/deployments/se-proxy/opteesp/service_proxy_factory.c b/deployments/se-proxy/opteesp/service_proxy_factory.c
index 7edeef8b..591cc9ee 100644
--- a/deployments/se-proxy/opteesp/service_proxy_factory.c
+++ b/deployments/se-proxy/opteesp/service_proxy_factory.c
@@ -13,6 +13,7 @@
#include <service/crypto/factory/crypto_provider_factory.h>
#include <service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.h>
#include <trace.h>
+#include <service/capsule_update/provider/capsule_update_provider.h>
/* Stub backends */
#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
@@ -93,3 +94,18 @@ struct rpc_interface *its_proxy_create(void)
return secure_storage_provider_init(&its_provider, backend);
}
+
+struct rpc_interface *capsule_update_proxy_create(void)
+{
+ static struct capsule_update_provider capsule_update_provider;
+ static struct rpc_caller *capsule_update_caller;
+
+ capsule_update_caller = openamp_caller_init(&openamp);
+
+ if (!capsule_update_caller)
+ return NULL;
+
+ capsule_update_provider.client.caller = capsule_update_caller;
+
+ return capsule_update_provider_init(&capsule_update_provider);
+}
diff --git a/deployments/se-proxy/opteesp/service_proxy_factory.h b/deployments/se-proxy/opteesp/service_proxy_factory.h
index 298d407a..02aa7fe2 100644
--- a/deployments/se-proxy/opteesp/service_proxy_factory.h
+++ b/deployments/se-proxy/opteesp/service_proxy_factory.h
@@ -17,6 +17,7 @@ struct rpc_interface *attest_proxy_create(void);
struct rpc_interface *crypto_proxy_create(void);
struct rpc_interface *ps_proxy_create(void);
struct rpc_interface *its_proxy_create(void);
+struct rpc_interface *capsule_update_proxy_create(void);
#ifdef __cplusplus
}
diff --git a/deployments/se-proxy/se_proxy_interfaces.h b/deployments/se-proxy/se_proxy_interfaces.h
index 48908f84..3d4a7c20 100644
--- a/deployments/se-proxy/se_proxy_interfaces.h
+++ b/deployments/se-proxy/se_proxy_interfaces.h
@@ -8,9 +8,10 @@
#define SE_PROXY_INTERFACES_H
/* Interface IDs from service endpoints available from an se-proxy deployment */
-#define SE_PROXY_INTERFACE_ID_ITS (0)
-#define SE_PROXY_INTERFACE_ID_PS (1)
-#define SE_PROXY_INTERFACE_ID_CRYPTO (2)
-#define SE_PROXY_INTERFACE_ID_ATTEST (3)
+#define SE_PROXY_INTERFACE_ID_ITS (0)
+#define SE_PROXY_INTERFACE_ID_PS (1)
+#define SE_PROXY_INTERFACE_ID_CRYPTO (2)
+#define SE_PROXY_INTERFACE_ID_ATTEST (3)
+#define SE_PROXY_INTERFACE_ID_CAPSULE_UPDATE (4)
#endif /* SE_PROXY_INTERFACES_H */
diff --git a/protocols/service/capsule_update/capsule_update_proto.h b/protocols/service/capsule_update/capsule_update_proto.h
new file mode 100644
index 00000000..8f326cd3
--- /dev/null
+++ b/protocols/service/capsule_update/capsule_update_proto.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CAPSULE_UPDATE_PROTO_H
+#define CAPSULE_UPDATE_PROTO_H
+
+#include <protocols/service/capsule_update/opcodes.h>
+#include <protocols/service/capsule_update/parameters.h>
+
+#endif /* CAPSULE_UPDATE_PROTO_H */
diff --git a/protocols/service/capsule_update/opcodes.h b/protocols/service/capsule_update/opcodes.h
new file mode 100644
index 00000000..8185a090
--- /dev/null
+++ b/protocols/service/capsule_update/opcodes.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CAPSULE_UPDATE_OPCODES_H
+#define CAPSULE_UPDATE_OPCODES_H
+
+/**
+ * Opcode definitions for the capsule update service
+ */
+
+#define CAPSULE_UPDATE_OPCODE_UPDATE_CAPSULE 1
+#define CAPSULE_UPDATE_OPCODE_BOOT_CONFIRMED 2
+
+#endif /* CAPSULE_UPDATE_OPCODES_H */
diff --git a/protocols/service/capsule_update/parameters.h b/protocols/service/capsule_update/parameters.h
new file mode 100644
index 00000000..285d9241
--- /dev/null
+++ b/protocols/service/capsule_update/parameters.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CAPSULE_UPDATE_PARAMETERS_H
+#define CAPSULE_UPDATE_PARAMETERS_H
+
+/**
+ * Operation parameter definitions for the capsule update service access protocol.
+ */
+
+
+#endif /* CAPSULE_UPDATE_PARAMETERS_H */
@@ -1,248 +0,0 @@
From c9188e59fd27d208a975187da285a9b5938bb00d Mon Sep 17 00:00:00 2001
From: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
Date: Thu, 16 Dec 2021 13:29:58 +0000
Subject: [PATCH] Add logs to functions in SMM gateway SP
Signed-off-by: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
---
.../backend/uefi_variable_store.c | 29 +++++++++++++++++--
.../provider/smm_variable_provider.c | 7 +++--
2 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/components/service/smm_variable/backend/uefi_variable_store.c b/components/service/smm_variable/backend/uefi_variable_store.c
index ed50eaf9..0c371e94 100644
--- a/components/service/smm_variable/backend/uefi_variable_store.c
+++ b/components/service/smm_variable/backend/uefi_variable_store.c
@@ -11,6 +11,7 @@
#include "uefi_variable_store.h"
#include "variable_index_iterator.h"
#include "variable_checker.h"
+#include <trace.h>
/* Private functions */
static void load_variable_index(
@@ -151,12 +152,15 @@ void uefi_variable_store_set_storage_limits(
size_t total_capacity,
size_t max_variable_size)
{
+ EMSG("In func %s\n", __func__);
struct delegate_variable_store *delegate_store = select_delegate_store(
context,
attributes);
delegate_store->total_capacity = total_capacity;
delegate_store->max_variable_size = max_variable_size;
+ EMSG("In func %s total_capacity is %d\n", __func__, total_capacity);
+ EMSG("In func %s max_variable_size is %d\n", __func__, max_variable_size);
}
efi_status_t uefi_variable_store_set_variable(
@@ -265,6 +269,7 @@ efi_status_t uefi_variable_store_get_variable(
size_t max_data_len,
size_t *total_length)
{
+ EMSG("In func %s\n", __func__);
efi_status_t status = check_name_terminator(var->Name, var->NameSize);
if (status != EFI_SUCCESS) return status;
@@ -299,6 +304,7 @@ efi_status_t uefi_variable_store_get_next_variable_name(
size_t max_name_len,
size_t *total_length)
{
+ EMSG("In func %s\n", __func__);
efi_status_t status = check_name_terminator(cur->Name, cur->NameSize);
if (status != EFI_SUCCESS) return status;
@@ -329,6 +335,8 @@ efi_status_t uefi_variable_store_query_variable_info(
struct uefi_variable_store *context,
SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *var_info)
{
+
+ EMSG("In func %s\n", __func__);
struct delegate_variable_store *delegate_store = select_delegate_store(
context,
var_info->Attributes);
@@ -337,13 +345,15 @@ efi_status_t uefi_variable_store_query_variable_info(
context,
var_info->Attributes,
delegate_store->storage_backend);
-
+ EMSG("In func %s total_used is %d\n", __func__, total_used);
var_info->MaximumVariableSize = delegate_store->max_variable_size;
var_info->MaximumVariableStorageSize = delegate_store->total_capacity;
var_info->RemainingVariableStorageSize = (total_used < delegate_store->total_capacity) ?
delegate_store->total_capacity - total_used :
0;
-
+ EMSG("In func %s var_info->MaximumVariableSize is %d\n", __func__, var_info->MaximumVariableSize);
+ EMSG("In func %s var_info->MaximumVariableStorageSize is %d\n", __func__, var_info->MaximumVariableStorageSize);
+ EMSG("In func %s var_info->RemainingVariableStorageSize is %d\n", __func__, var_info->RemainingVariableStorageSize);
return EFI_SUCCESS;
}
@@ -358,6 +368,7 @@ efi_status_t uefi_variable_store_set_var_check_property(
struct uefi_variable_store *context,
const SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *property)
{
+ EMSG("In func %s\n", __func__);
efi_status_t status = check_name_terminator(property->Name, property->NameSize);
if (status != EFI_SUCCESS) return status;
@@ -404,6 +415,7 @@ efi_status_t uefi_variable_store_get_var_check_property(
struct uefi_variable_store *context,
SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *property)
{
+ EMSG("In func %s\n", __func__);
efi_status_t status = check_name_terminator(property->Name, property->NameSize);
if (status != EFI_SUCCESS) return status;
@@ -430,6 +442,7 @@ efi_status_t uefi_variable_store_get_var_check_property(
static void load_variable_index(
struct uefi_variable_store *context)
{
+ EMSG("In func %s\n", __func__);
struct storage_backend *persistent_store = context->persistent_store.storage_backend;
if (persistent_store) {
@@ -444,6 +457,7 @@ static void load_variable_index(
context->index_sync_buffer_size,
context->index_sync_buffer,
&data_len);
+ EMSG("In func %s get status is %d\n", __func__, psa_status);
if (psa_status == PSA_SUCCESS) {
@@ -455,6 +469,7 @@ static void load_variable_index(
static efi_status_t sync_variable_index(
struct uefi_variable_store *context)
{
+ EMSG("In func %s\n", __func__);
efi_status_t status = EFI_SUCCESS;
/* Sync the varibale index to storage if anything is dirty */
@@ -479,6 +494,7 @@ static efi_status_t sync_variable_index(
data_len,
context->index_sync_buffer,
PSA_STORAGE_FLAG_NONE);
+ EMSG("In func %s set status is %d\n", __func__, psa_status);
status = psa_to_efi_storage_status(psa_status);
}
@@ -490,6 +506,7 @@ static efi_status_t sync_variable_index(
static efi_status_t check_capabilities(
const SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var)
{
+ EMSG("In func %s\n", __func__);
efi_status_t status = EFI_SUCCESS;
/* Check if any unsupported variable attributes have been requested */
@@ -551,6 +568,7 @@ static efi_status_t store_variable_data(
const struct variable_info *info,
const SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var)
{
+ EMSG("In func %s\n", __func__);
psa_status_t psa_status = PSA_SUCCESS;
size_t data_len = var->DataSize;
const uint8_t *data = (const uint8_t*)var +
@@ -599,6 +617,7 @@ static efi_status_t remove_variable_data(
struct uefi_variable_store *context,
const struct variable_info *info)
{
+ EMSG("In func %s\n", __func__);
psa_status_t psa_status = PSA_SUCCESS;
if (info->is_variable_set) {
@@ -613,6 +632,7 @@ static efi_status_t remove_variable_data(
delegate_store->storage_backend->context,
context->owner_id,
info->metadata.uid);
+ EMSG("In func %s status is %d\n", __func__, psa_status);
}
}
@@ -625,6 +645,7 @@ static efi_status_t load_variable_data(
SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var,
size_t max_data_len)
{
+ EMSG("In func %s\n", __func__);
psa_status_t psa_status = PSA_SUCCESS;
size_t data_len = 0;
uint8_t *data = (uint8_t*)var +
@@ -644,6 +665,7 @@ static efi_status_t load_variable_data(
max_data_len,
data,
&data_len);
+ EMSG("In func %s get status is %d\n", __func__, psa_status);
var->DataSize = data_len;
}
@@ -771,6 +793,7 @@ static void purge_orphan_index_entries(
context->owner_id,
info->metadata.uid,
&storage_info);
+ EMSG("In func %s get status is %d\n", __func__, psa_status);
if (psa_status != PSA_SUCCESS) {
@@ -802,6 +825,7 @@ static size_t space_used(
uint32_t attributes,
struct storage_backend *storage_backend)
{
+ EMSG("In func %s\n", __func__);
if (!storage_backend) return 0;
size_t total_used = 0;
@@ -823,6 +847,7 @@ static size_t space_used(
context->owner_id,
info->metadata.uid,
&storage_info);
+ EMSG("In func %s get status is %d\n", __func__, psa_status);
if (psa_status == PSA_SUCCESS) total_used += storage_info.size;
}
diff --git a/components/service/smm_variable/provider/smm_variable_provider.c b/components/service/smm_variable/provider/smm_variable_provider.c
index 52e68d09..1f362c17 100644
--- a/components/service/smm_variable/provider/smm_variable_provider.c
+++ b/components/service/smm_variable/provider/smm_variable_provider.c
@@ -9,6 +9,7 @@
#include <protocols/service/smm_variable/smm_variable_proto.h>
#include <protocols/rpc/common/packed-c/status.h>
#include "smm_variable_provider.h"
+#include <trace.h>
/* Service request handlers */
static rpc_status_t get_variable_handler(void *context, struct call_req *req);
@@ -252,17 +253,18 @@ static rpc_status_t set_variable_handler(void *context, struct call_req* req)
static rpc_status_t query_variable_info_handler(void *context, struct call_req* req)
{
+ EMSG("In func %s \n", __func__);
efi_status_t efi_status = EFI_INVALID_PARAMETER;
struct smm_variable_provider *this_instance = (struct smm_variable_provider*)context;
const struct call_param_buf *req_buf = call_req_get_req_buf(req);
-
+ EMSG("In func %s sizeof(SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO) is %d\n", __func__, sizeof(SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO));
if (req_buf->data_len >= sizeof(SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO)) {
struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
if (resp_buf->size >= req_buf->data_len) {
-
+
memmove(resp_buf->data, req_buf->data, req_buf->data_len);
efi_status = uefi_variable_store_query_variable_info(
@@ -272,6 +274,7 @@ static rpc_status_t query_variable_info_handler(void *context, struct call_req*
if (efi_status == EFI_SUCCESS) {
resp_buf->data_len = sizeof(SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO);
+ EMSG("In func %s resp_buf->data_len is %d\n", __func__, resp_buf->data_len);
}
}
else {
@@ -1,41 +0,0 @@
From 3e472452bca64ed90071b61416460f1a69382293 Mon Sep 17 00:00:00 2001
From: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
Date: Thu, 16 Dec 2021 21:31:40 +0000
Subject: [PATCH] Configure storage size
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
---
.../service/smm_variable/backend/uefi_variable_store.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/components/service/smm_variable/backend/uefi_variable_store.c b/components/service/smm_variable/backend/uefi_variable_store.c
index 0c371e94..b7cfff40 100644
--- a/components/service/smm_variable/backend/uefi_variable_store.c
+++ b/components/service/smm_variable/backend/uefi_variable_store.c
@@ -87,6 +87,7 @@ static efi_status_t check_name_terminator(
* may be overridden using uefi_variable_store_set_storage_limits()
*/
#define DEFAULT_MAX_VARIABLE_SIZE (2048)
+#define CONFIGURE_STORAGE_SIZE (50)
efi_status_t uefi_variable_store_init(
struct uefi_variable_store *context,
@@ -100,13 +101,13 @@ efi_status_t uefi_variable_store_init(
/* Initialise persistent store defaults */
context->persistent_store.is_nv = true;
context->persistent_store.max_variable_size = DEFAULT_MAX_VARIABLE_SIZE;
- context->persistent_store.total_capacity = DEFAULT_MAX_VARIABLE_SIZE * max_variables;
+ context->persistent_store.total_capacity = CONFIGURE_STORAGE_SIZE * max_variables;
context->persistent_store.storage_backend = persistent_store;
/* Initialise volatile store defaults */
context->volatile_store.is_nv = false;
context->volatile_store.max_variable_size = DEFAULT_MAX_VARIABLE_SIZE;
- context->volatile_store.total_capacity = DEFAULT_MAX_VARIABLE_SIZE * max_variables;
+ context->volatile_store.total_capacity = CONFIGURE_STORAGE_SIZE * max_variables;
context->volatile_store.storage_backend = volatile_store;
context->owner_id = owner_id;
@@ -1,31 +0,0 @@
From 12e9b977e4c7515ce90fecc62630be394fd7da62 Mon Sep 17 00:00:00 2001
From: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
Date: Mon, 20 Dec 2021 19:54:39 +0000
Subject: [PATCH] Change UID of variable index in SMM
This patch fixes the os_indications setVariable() failure. The variable
index UID in SMM gateway which was 1 is changed in this patch. TFM has a
special usage for variable with UID 1, which makes it write once only.
This is not required for SMM variable index.
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
---
components/service/smm_variable/backend/uefi_variable_store.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/components/service/smm_variable/backend/uefi_variable_store.c b/components/service/smm_variable/backend/uefi_variable_store.c
index 6a90f46a..1bb869ae 100644
--- a/components/service/smm_variable/backend/uefi_variable_store.c
+++ b/components/service/smm_variable/backend/uefi_variable_store.c
@@ -67,7 +67,7 @@ static efi_status_t check_name_terminator(
size_t name_size);
/* Private UID for storing the variable index */
-#define VARIABLE_INDEX_STORAGE_UID (1)
+#define VARIABLE_INDEX_STORAGE_UID (0x787)
/* Default maximum variable size -
* may be overridden using uefi_variable_store_set_storage_limits()
@@ -1,73 +0,0 @@
From 55fc3dbfb0ec21b1239808d0dddae14fbb8bb5f3 Mon Sep 17 00:00:00 2001
From: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
Date: Mon, 20 Dec 2021 19:56:30 +0000
Subject: [PATCH] Add missing features to setVariable()
This patch resolves the failing tests in SCT related to
setVariable() function. The existing implementation is
missing few cases where error codes are returned when called
with certain paramters. These conditions are implemented in
this patch based on the explanation provided in uefi spec.
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
---
.../backend/uefi_variable_store.c | 29 ++++++++++++++++---
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/components/service/smm_variable/backend/uefi_variable_store.c b/components/service/smm_variable/backend/uefi_variable_store.c
index 1bb869ae..a1671074 100644
--- a/components/service/smm_variable/backend/uefi_variable_store.c
+++ b/components/service/smm_variable/backend/uefi_variable_store.c
@@ -161,6 +161,17 @@ efi_status_t uefi_variable_store_set_variable(
bool should_sync_index = false;
if (status != EFI_SUCCESS) return status;
+
+ /*
+ * Runtime access to a data variable implies boot service access. Attributes that have
+ * EFI_VARIABLE_RUNTIME_ACCESS set must also have EFI_VARIABLE_BOOTSERVICE_ACCESS set.
+ * The caller is responsible for following this rule.
+ */
+ if((var->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))
+ {
+ if((var->Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS) != EFI_VARIABLE_BOOTSERVICE_ACCESS )
+ return EFI_INVALID_PARAMETER;
+ }
/* Find in index */
const struct variable_info *info = variable_index_find(
@@ -221,6 +232,13 @@ efi_status_t uefi_variable_store_set_variable(
if (!info) status = EFI_OUT_OF_RESOURCES;
should_sync_index = info && (info->metadata.attributes & EFI_VARIABLE_NON_VOLATILE);
}
+ else
+ {
+ /* Return EFI_NOT_FOUND when a remove operation is performed
+ * on variable that is not existing.
+ */
+ status = EFI_NOT_FOUND;
+ }
/* The order of these operations is important. For an update
* or create operation, The variable index is always synchronized
@@ -555,10 +573,13 @@ static efi_status_t check_access_permitted_on_set(
if ((status == EFI_SUCCESS) && var->DataSize) {
/* Restrict which attributes can be modified for an existing variable */
- if ((var->Attributes & EFI_VARIABLE_NON_VOLATILE) !=
- (info->metadata.attributes & EFI_VARIABLE_NON_VOLATILE)) {
-
- /* Don't permit change of storage class */
+ if (((var->Attributes & EFI_VARIABLE_NON_VOLATILE) !=
+ (info->metadata.attributes & EFI_VARIABLE_NON_VOLATILE)) ||
+ ((var->Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS) !=
+ (info->metadata.attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS)) ||
+ ((var->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) !=
+ (info->metadata.attributes & EFI_VARIABLE_RUNTIME_ACCESS))) {
+ /* Don't permit change of attributes */
status = EFI_INVALID_PARAMETER;
}
}
@@ -1,55 +0,0 @@
From dc3f134436ad6852f1bad9542232e84166843a7e Mon Sep 17 00:00:00 2001
From: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
Date: Mon, 20 Dec 2021 20:01:10 +0000
Subject: [PATCH] Add invalid parameter check in getNextVariableName()
This patch resolves the failing tests in SCT related to
getNextVariableName() function. The existing implementation is
missing few cases where error codes are returned when called
with certain paramters. These conditions are implemented in
this patch based on the explanation provided in uefi spec.
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
---
.../smm_variable/backend/uefi_variable_store.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/components/service/smm_variable/backend/uefi_variable_store.c b/components/service/smm_variable/backend/uefi_variable_store.c
index a1671074..a57b3346 100644
--- a/components/service/smm_variable/backend/uefi_variable_store.c
+++ b/components/service/smm_variable/backend/uefi_variable_store.c
@@ -161,7 +161,7 @@ efi_status_t uefi_variable_store_set_variable(
bool should_sync_index = false;
if (status != EFI_SUCCESS) return status;
-
+
/*
* Runtime access to a data variable implies boot service access. Attributes that have
* EFI_VARIABLE_RUNTIME_ACCESS set must also have EFI_VARIABLE_BOOTSERVICE_ACCESS set.
@@ -310,6 +310,22 @@ efi_status_t uefi_variable_store_get_next_variable_name(
status = EFI_NOT_FOUND;
*total_length = 0;
+ /*
+ * If input values of VariableName and VendorGuid are not a name and GUID of an
+ * existing variable, EFI_INVALID_PARAMETER is returned.
+ */
+ if (cur->NameSize >= sizeof(int16_t)) {
+ /*
+ * Name must be at least one character long to accommodate
+ * the mandatory null terminator.
+ */
+ if (cur->Name[0] != 0) {
+ const struct variable_info *var_info = variable_index_find(&context->variable_index,&cur->Guid,cur->NameSize,cur->Name);
+ if(var_info == NULL)
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
const struct variable_info *info = variable_index_find_next(
&context->variable_index,
&cur->Guid,
@@ -1,81 +0,0 @@
From 571ddac16048dfba4b25b04fe5cbd706c392b5ba Mon Sep 17 00:00:00 2001
From: Vishnu Banavath <vishnu.banavath@arm.com>
Date: Fri, 24 Dec 2021 19:17:17 +0000
Subject: [PATCH] smm_gateway: add checks for null attributes
As par EDK-2 and EDK-2 test code, when a user issue's
setVariable() with 0 in attributes field, it means a variable
delete request. Currently, smm gatway doesn't handle this scenario.
This change is to add that support
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
---
.../backend/uefi_variable_store.c | 28 ++++++++++++-------
1 file changed, 18 insertions(+), 10 deletions(-)
diff --git a/components/service/smm_variable/backend/uefi_variable_store.c b/components/service/smm_variable/backend/uefi_variable_store.c
index a57b3346..e8771c21 100644
--- a/components/service/smm_variable/backend/uefi_variable_store.c
+++ b/components/service/smm_variable/backend/uefi_variable_store.c
@@ -167,7 +167,9 @@ efi_status_t uefi_variable_store_set_variable(
* EFI_VARIABLE_RUNTIME_ACCESS set must also have EFI_VARIABLE_BOOTSERVICE_ACCESS set.
* The caller is responsible for following this rule.
*/
- if((var->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))
+ if (!var->Attributes)
+ EMSG("It might be a delete variable request\n");
+ else if((var->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))
{
if((var->Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS) != EFI_VARIABLE_BOOTSERVICE_ACCESS )
return EFI_INVALID_PARAMETER;
@@ -191,7 +193,7 @@ efi_status_t uefi_variable_store_set_variable(
(var->Attributes & EFI_VARIABLE_NON_VOLATILE) ||
(info->is_variable_set && (info->metadata.attributes & EFI_VARIABLE_NON_VOLATILE));
- if (var->DataSize) {
+ if (var->DataSize && var->Attributes) {
/* It's a set rather than a remove operation */
variable_index_update_variable(
@@ -206,7 +208,9 @@ efi_status_t uefi_variable_store_set_variable(
* that it's never possible for an object to exist within
* the storage backend without a corresponding index entry.
*/
- remove_variable_data(context, info);
+ EMSG(" deleting variable %s \n",var->Name);
+ if (remove_variable_data(context, info) != PSA_SUCCESS)
+ EMSG(" deleting variable %s FAILED\n",var->Name);
variable_index_remove_variable(&context->variable_index, info);
/* Variable info no longer valid */
@@ -587,14 +591,18 @@ static efi_status_t check_access_permitted_on_set(
}
if ((status == EFI_SUCCESS) && var->DataSize) {
-
+ /* Delete the variable with Attributes is 0 */
+ if (!var->Attributes) {
+ EMSG("Null attributes, may be a delete variable request\n");
+ status = EFI_SUCCESS;
+ }
/* Restrict which attributes can be modified for an existing variable */
- if (((var->Attributes & EFI_VARIABLE_NON_VOLATILE) !=
- (info->metadata.attributes & EFI_VARIABLE_NON_VOLATILE)) ||
- ((var->Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS) !=
- (info->metadata.attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS)) ||
- ((var->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) !=
- (info->metadata.attributes & EFI_VARIABLE_RUNTIME_ACCESS))) {
+ else if (((var->Attributes & EFI_VARIABLE_NON_VOLATILE) !=
+ (info->metadata.attributes & EFI_VARIABLE_NON_VOLATILE)) ||
+ ((var->Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS) !=
+ (info->metadata.attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS)) ||
+ ((var->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) !=
+ (info->metadata.attributes & EFI_VARIABLE_RUNTIME_ACCESS))) {
/* Don't permit change of attributes */
status = EFI_INVALID_PARAMETER;
}
@@ -1,258 +0,0 @@
From 47db072e9ec749c6be7c0a27d64d7fbd75748d60 Mon Sep 17 00:00:00 2001
From: Gyorgy Szing <Gyorgy.Szing@arm.com>
Date: Wed, 8 Dec 2021 04:20:34 +0100
Subject: [PATCH] Enhance mbedtls fetch process
Update management of MbedTLS external component to be optimized
for download speed insted of availability.
The updated process is:
- check if binary is available. If yes configure build to use it
and stop.
- if not, check is source is available. If yes, build it and use
the resulting binary.
- if not, then download the source using git, compile it and use
the resulting binary
The following variables can be set on the command line to alter the
behavior of the module:
- MBEDTLS_URL git repo URL to fetch from.
- MBEDTLS_REFSPEC revision to fetch
- MBEDTLS_SOURCE_DIR to specify location of source code in
local file syetem.
- MBEDTLS_INSTALL_DIR to specify location of binary.
I.e. cmake -S <...> -B <...> -DMBEDTLS_INSTALL_DIR=~/mbedtls
will make the resulting binary installed to ~/mbedtls. This can be
used later to speed up a clean build an use the prebuilt binary.
Change-Id: I8a9ad8b3303e6dfa0a7c9c3d7e4b4787b94d925a
Signed-off-by: Gyorgy Szing <Gyorgy.Szing@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
---
external/MbedTLS/MbedTLS.cmake | 192 ++++++++++++++++++++-------------
1 file changed, 119 insertions(+), 73 deletions(-)
diff --git a/external/MbedTLS/MbedTLS.cmake b/external/MbedTLS/MbedTLS.cmake
index 3cbaed15..935be765 100644
--- a/external/MbedTLS/MbedTLS.cmake
+++ b/external/MbedTLS/MbedTLS.cmake
@@ -1,96 +1,142 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
#-------------------------------------------------------------------------------
-# Determine the number of processes to run while running parallel builds.
-# Pass -DPROCESSOR_COUNT=<n> to cmake to override.
-if(NOT DEFINED PROCESSOR_COUNT)
- include(ProcessorCount)
- ProcessorCount(PROCESSOR_COUNT)
- set(PROCESSOR_COUNT ${PROCESSOR_COUNT} CACHE STRING "Number of cores to use for parallel builds.")
-endif()
+set(MBEDTLS_URL "https://github.com/ARMmbed/mbedtls.git"
+ CACHE STRING "Mbed TLS repository URL")
+set(MBEDTLS_REFSPEC "mbedtls-3.0.0"
+ CACHE STRING "Mbed TLS git refspec")
+set(MBEDTLS_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_deps/mbedtls-src"
+ CACHE PATH "MbedTLS source directory")
+set(MBEDTLS_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/mbedtls_install"
+ CACHE PATH "Mbed TLS installation directory")
-set(MBEDTLS_URL "https://github.com/ARMmbed/mbedtls.git" CACHE STRING "Mbed TLS repository URL")
-set(MBEDTLS_REFSPEC "mbedtls-3.0.0" CACHE STRING "Mbed TLS git refspec")
-set(MBEDTLS_INSTALL_PATH "${CMAKE_CURRENT_BINARY_DIR}/mbedtls_install" CACHE PATH "Mbed TLS installation directory")
-set(MBEDTLS_PACKAGE_PATH "${MBEDTLS_INSTALL_PATH}/lib/mbedtls/cmake" CACHE PATH "Mbed TLS CMake package directory")
+find_library(MBEDCRYPTO_LIB_FILE
+ NAMES libmbedcrypto.a mbedcrypto.a libmbedcrypto.lib mbedcrypto.lib
+ PATHS ${MBEDTLS_INSTALL_DIR}
+ PATH_SUFFIXES "lib"
+ DOC "Location of mberdrypto library."
+ NO_DEFAULT_PATH
+)
-include(FetchContent)
+set(MBEDCRYPTO_LIB_FILE ${MBEDCRYPTO_LIB_FILE})
+unset(MBEDCRYPTO_LIB_FILE CACHE)
-# Checking git
-find_program(GIT_COMMAND "git")
-if (NOT GIT_COMMAND)
- message(FATAL_ERROR "Please install git")
-endif()
+set(MBEDTLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/_deps/mbedtls-build")
-# Fetching Mbed TLS
-FetchContent_Declare(
- mbedtls
- GIT_REPOSITORY ${MBEDTLS_URL}
- GIT_TAG ${MBEDTLS_REFSPEC}
- GIT_SHALLOW TRUE
-)
+# Binary not found and it needs to be built.
+if (NOT MBEDCRYPTO_LIB_FILE)
+ # Determine the number of processes to run while running parallel builds.
+ # Pass -DPROCESSOR_COUNT=<n> to cmake to override.
+ if(NOT DEFINED PROCESSOR_COUNT)
+ include(ProcessorCount)
+ ProcessorCount(PROCESSOR_COUNT)
+ set(PROCESSOR_COUNT ${PROCESSOR_COUNT}
+ CACHE STRING "Number of cores to use for parallel builds.")
+ endif()
-# FetchContent_GetProperties exports mbedtls_SOURCE_DIR and mbedtls_BINARY_DIR variables
-FetchContent_GetProperties(mbedtls)
-if(NOT mbedtls_POPULATED)
- message(STATUS "Fetching Mbed TLS")
- FetchContent_Populate(mbedtls)
-endif()
+ # See if the source is available locally
+ find_file(MBEDCRYPTO_HEADER_FILE
+ NAMES crypto.h
+ PATHS ${MBEDTLS_SOURCE_DIR}
+ PATH_SUFFIXES "include/psa"
+ NO_DEFAULT_PATH
+ )
+ set(MBEDCRYPTO_HEADER_FILE ${MBEDCRYPTO_HEADER_FILE})
+ unset(MBEDCRYPTO_HEADER_FILE CACHE)
-# Convert the include path list to a string. Needed to make parameter passing to
-# Mbed TLS build work fine.
-string(REPLACE ";" "\\;" MBEDTLS_EXTRA_INCLUDES "${MBEDTLS_EXTRA_INCLUDES}")
+ # Source not found, fetch it.
+ if (NOT MBEDCRYPTO_HEADER_FILE)
+ include(FetchContent)
-find_package(Python3 COMPONENTS Interpreter)
-if (NOT Python3_Interpreter_FOUND)
- message(FATAL_ERROR "Python 3 interpreter not found.")
-endif()
+ # Checking git
+ find_program(GIT_COMMAND "git")
+ if (NOT GIT_COMMAND)
+ message(FATAL_ERROR "Please install git")
+ endif()
-#Configure Mbed TLS to build only mbedcrypto lib
-execute_process(COMMAND ${Python3_EXECUTABLE} scripts/config.py crypto WORKING_DIRECTORY ${mbedtls_SOURCE_DIR})
-
-# Advertise Mbed TLS as the provider of the psa crypto API
-set(PSA_CRYPTO_API_INCLUDE "${MBEDTLS_INSTALL_PATH}/include" CACHE STRING "PSA Crypto API include path")
-
-#Configure the library
-execute_process(COMMAND
- ${CMAKE_COMMAND}
- -DENABLE_PROGRAMS=OFF
- -DENABLE_TESTING=OFF
- -DUNSAFE_BUILD=ON
- -DCMAKE_INSTALL_PREFIX=${MBEDTLS_INSTALL_PATH}
- -DCMAKE_TOOLCHAIN_FILE=${TS_EXTERNAL_LIB_TOOLCHAIN_FILE}
- -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY
- -DEXTERNAL_DEFINITIONS=-DMBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}"
- -DEXTERNAL_INCLUDE_PATHS=${MBEDTLS_EXTRA_INCLUDES}
- -GUnix\ Makefiles
- ${mbedtls_SOURCE_DIR}
- WORKING_DIRECTORY
- ${mbedtls_BINARY_DIR}
- RESULT_VARIABLE _exec_error
-)
+ # Fetching Mbed TLS
+ FetchContent_Declare(
+ mbedtls
+ SOURCE_DIR ${MBEDTLS_SOURCE_DIR}
+ BINARY_DIR ${MBEDTLS_BINARY_DIR}
+ GIT_REPOSITORY ${MBEDTLS_URL}
+ GIT_TAG ${MBEDTLS_REFSPEC}
+ GIT_SHALLOW TRUE
+ )
-if (_exec_error)
- message(FATAL_ERROR "Configuration step of Mbed TLS failed with ${_exec_error}.")
-endif()
+ # FetchContent_GetProperties exports mbedtls_SOURCE_DIR and mbedtls_BINARY_DIR variables
+ FetchContent_GetProperties(mbedtls)
+ # FetchContent_Populate will fail if the source directory is removed since it will try to
+ # do an "update" and not a "populate" action. As a workaround, remove the subbuild directory.
+ # Note: this fix assumes, the default subbuild location is used.
+ file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/_deps/mbedtls-subbuild")
+
+ # If the source directory has been moved, the binary dir must be regenerated from scratch.
+ file(REMOVE_RECURSE "${MBEDTLS_BINARY_DIR}")
-#TODO: add dependency to generated project on this file!
-#TODO: add custom target to rebuild Mbed TLS
+ if (NOT mbedtls_POPULATED)
+ message(STATUS "Fetching Mbed TLS")
+ FetchContent_Populate(mbedtls)
+ endif()
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${MBEDTLS_SOURCE_DIR})
+ endif()
-#Build the library
-execute_process(COMMAND
- ${CMAKE_COMMAND} --build ${mbedtls_BINARY_DIR} --parallel ${PROCESSOR_COUNT} --target install
+ # Build mbedcrypto library
+
+ # Convert the include path list to a string. Needed to make parameter passing to
+ # Mbed TLS build work fine.
+ string(REPLACE ";" "\\;" MBEDTLS_EXTRA_INCLUDES "${MBEDTLS_EXTRA_INCLUDES}")
+
+ find_package(Python3 REQUIRED COMPONENTS Interpreter)
+
+ #Configure Mbed TLS to build only mbedcrypto lib
+ execute_process(COMMAND ${Python3_EXECUTABLE} scripts/config.py crypto WORKING_DIRECTORY ${MBEDTLS_SOURCE_DIR})
+
+ # Advertise Mbed TLS as the provider of the psa crypto API
+ set(PSA_CRYPTO_API_INCLUDE "${MBEDTLS_INSTALL_DIR}/include" CACHE STRING "PSA Crypto API include path")
+
+ #Configure the library
+ execute_process(COMMAND
+ ${CMAKE_COMMAND} -E env CROSS_COMPILE=${CROSS_COMPILE}
+ ${CMAKE_COMMAND}
+ -DENABLE_PROGRAMS=OFF
+ -DENABLE_TESTING=OFF
+ -DUNSAFE_BUILD=ON
+ -DCMAKE_INSTALL_PREFIX=${MBEDTLS_INSTALL_DIR}
+ -DCMAKE_TOOLCHAIN_FILE=${TS_EXTERNAL_LIB_TOOLCHAIN_FILE}
+ -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY
+ -DEXTERNAL_DEFINITIONS=-DMBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}"
+ -DEXTERNAL_INCLUDE_PATHS=${MBEDTLS_EXTRA_INCLUDES}
+ -GUnix\ Makefiles
+ ${MBEDTLS_SOURCE_DIR}
+ WORKING_DIRECTORY
+ ${MBEDTLS_BINARY_DIR}
RESULT_VARIABLE _exec_error
)
-if (_exec_error)
- message(FATAL_ERROR "Build step of Mbed TLS failed with ${_exec_error}.")
+
+ if (_exec_error)
+ message(FATAL_ERROR "Configuration step of Mbed TLS failed with ${_exec_error}.")
+ endif()
+
+ #Build the library
+ execute_process(COMMAND
+ ${CMAKE_COMMAND} --build ${MBEDTLS_BINARY_DIR} --parallel ${PROCESSOR_COUNT} --target install
+ RESULT_VARIABLE _exec_error
+ )
+
+ if (_exec_error)
+ message(FATAL_ERROR "Build step of Mbed TLS failed with ${_exec_error}.")
+ endif()
+
+ set(MBEDCRYPTO_LIB_FILE "${MBEDTLS_INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}mbedcrypto${CMAKE_STATIC_LIBRARY_SUFFIX}")
endif()
#Create an imported target to have clean abstraction in the build-system.
add_library(mbedcrypto STATIC IMPORTED)
-set_property(TARGET mbedcrypto PROPERTY IMPORTED_LOCATION "${MBEDTLS_INSTALL_PATH}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}mbedcrypto${CMAKE_STATIC_LIBRARY_SUFFIX}")
-set_property(TARGET mbedcrypto PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${MBEDTLS_INSTALL_PATH}/include")
+set_property(DIRECTORY ${CMAKE_SOURCE_DIR} APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${MBEDCRYPTO_LIB_FILE})
+set_property(TARGET mbedcrypto PROPERTY IMPORTED_LOCATION ${MBEDCRYPTO_LIB_FILE})
+set_property(TARGET mbedcrypto PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${MBEDTLS_INSTALL_DIR}/include")
@@ -1,41 +0,0 @@
From 131bb3c577fff93ff9ba6f5e7d450f727fec0e62 Mon Sep 17 00:00:00 2001
From: Julian Hall <julian.hall@arm.com>
Date: Fri, 11 Feb 2022 12:30:45 +0000
Subject: [PATCH] Fix format specifier in logging_caller
A previous change increased the width of the opstatus value
returned by an rpc endpoint from 32 to 64 bits. This change
corrects the printf format specifier in the rpc logging_caller
that corresponds to logging the opstatus value.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: Ie695a6bf8cf8014317b85196d7b933d344782b2c
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
---
components/rpc/common/logging/logging_caller.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/components/rpc/common/logging/logging_caller.c b/components/rpc/common/logging/logging_caller.c
index 07c33de5..cac03f2f 100644
--- a/components/rpc/common/logging/logging_caller.c
+++ b/components/rpc/common/logging/logging_caller.c
@@ -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
*/
@@ -87,7 +87,7 @@ static rpc_status_t call_invoke(void *context, rpc_call_handle handle, uint32_t
if (status == TS_RPC_CALL_ACCEPTED) {
- fprintf(this_instance->log_file, "op_status: %d\n", *opstatus);
+ fprintf(this_instance->log_file, "op_status: %ld\n", *opstatus);
fprintf(this_instance->log_file, "resp_len: %ld\n", *resp_len);
}
@@ -1,64 +0,0 @@
From 7aa9796020487ce32746c25934ce20829acc462c Mon Sep 17 00:00:00 2001
From: Julian Hall <julian.hall@arm.com>
Date: Fri, 11 Feb 2022 13:42:59 +0000
Subject: [PATCH] Update refspecs for mbedtls and psa-arch-tests for v3.1.0
Updates external component refspecs to use mbedtls 3.1.0 and
compatible API tests from psa-arch-test.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I1b5cebd7de3c1885f5f8a8ea21ba5e4c52aefaf4
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
---
external/MbedTLS/MbedTLS.cmake | 2 +-
external/psa_arch_tests/psa_arch_tests.cmake | 17 ++++++-----------
2 files changed, 7 insertions(+), 12 deletions(-)
diff --git a/external/MbedTLS/MbedTLS.cmake b/external/MbedTLS/MbedTLS.cmake
index 935be765..3350d8a0 100644
--- a/external/MbedTLS/MbedTLS.cmake
+++ b/external/MbedTLS/MbedTLS.cmake
@@ -7,7 +7,7 @@
set(MBEDTLS_URL "https://github.com/ARMmbed/mbedtls.git"
CACHE STRING "Mbed TLS repository URL")
-set(MBEDTLS_REFSPEC "mbedtls-3.0.0"
+set(MBEDTLS_REFSPEC "mbedtls-3.1.0"
CACHE STRING "Mbed TLS git refspec")
set(MBEDTLS_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_deps/mbedtls-src"
CACHE PATH "MbedTLS source directory")
diff --git a/external/psa_arch_tests/psa_arch_tests.cmake b/external/psa_arch_tests/psa_arch_tests.cmake
index e6ab73f7..f6d2fb9f 100644
--- a/external/psa_arch_tests/psa_arch_tests.cmake
+++ b/external/psa_arch_tests/psa_arch_tests.cmake
@@ -5,20 +5,15 @@
#
#-------------------------------------------------------------------------------
-# Determine the number of processes to run while running parallel builds.
-# Pass -DPROCESSOR_COUNT=<n> to cmake to override.
-if(NOT DEFINED PROCESSOR_COUNT)
- include(ProcessorCount)
- ProcessorCount(PROCESSOR_COUNT)
- set(PROCESSOR_COUNT ${PROCESSOR_COUNT} CACHE STRING "Number of cores to use for parallel builds.")
-endif()
+# Temporarily using modified tests used for tf-m verification
+set(PSA_ARCH_TESTS_URL "https://github.com/bensze01/psa-arch-tests.git" CACHE STRING "psa-arch-tests repository URL")
+set(PSA_ARCH_TESTS_REFSPEC "fix-multipart-aead" CACHE STRING "psa-arch-tests git refspec")
-set(PSA_ARCH_TESTS_URL "https://github.com/ARM-software/psa-arch-tests.git" CACHE STRING "psa-arch-tests repository URL")
-set(PSA_ARCH_TESTS_REFSPEC "master" CACHE STRING "psa-arch-tests git refspec")
+#set(PSA_ARCH_TESTS_URL "https://github.com/ARM-software/psa-arch-tests.git" CACHE STRING "psa-arch-tests repository URL")
+#set(PSA_ARCH_TESTS_REFSPEC "2a1852252a9b9af655cbe02d5d3c930952d0d798" CACHE STRING "psa-arch-tests v22.01_API1.4_ADAC_BETA")
set(PSA_ARCH_TESTS_INSTALL_PATH "${CMAKE_CURRENT_BINARY_DIR}/psa-arch-tests_install" CACHE PATH "psa-arch-tests installation directory")
set(PSA_ARCH_TESTS_PACKAGE_PATH "${PSA_ARCH_TESTS_INSTALL_PATH}/libpsa-arch-tests/cmake" CACHE PATH "psa-arch-tests CMake package directory")
-
-include(FetchContent)
+set(PSA_ARCH_TESTS_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_deps/psa_arch_tests-src" CACHE PATH "psa-arch-tests source.")
# Checking git
find_program(GIT_COMMAND "git")
@@ -1,123 +0,0 @@
From 9a83c32964ee2b1ecb7b36b4c08466202efd3bf2 Mon Sep 17 00:00:00 2001
From: Julian Hall <julian.hall@arm.com>
Date: Fri, 11 Feb 2022 14:19:26 +0000
Subject: [PATCH] Add defence against uninitialised multi-part transaction
Adds checks for the condition where there is an attempt to
setup a multi-part transaction without first initialising
transaction state.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I754479260fed0490d8f32b41a077d26028dc9903
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
---
components/service/crypto/client/psa/psa_cipher.c | 14 +++++++++++++-
components/service/crypto/client/psa/psa_hash.c | 8 +++++++-
components/service/crypto/client/psa/psa_mac.c | 10 ++++++++--
3 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/components/service/crypto/client/psa/psa_cipher.c b/components/service/crypto/client/psa/psa_cipher.c
index 70836ea6..3ab8ea21 100644
--- a/components/service/crypto/client/psa/psa_cipher.c
+++ b/components/service/crypto/client/psa/psa_cipher.c
@@ -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
*/
@@ -13,6 +13,12 @@ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation,
psa_key_id_t key,
psa_algorithm_t alg)
{
+ if (psa_crypto_client_instance.init_status != PSA_SUCCESS)
+ return psa_crypto_client_instance.init_status;
+
+ if (operation->handle)
+ return PSA_ERROR_BAD_STATE;
+
return crypto_caller_cipher_encrypt_setup(&psa_crypto_client_instance.base,
&operation->handle,
key, alg);
@@ -22,6 +28,12 @@ psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation,
psa_key_id_t key,
psa_algorithm_t alg)
{
+ if (psa_crypto_client_instance.init_status != PSA_SUCCESS)
+ return psa_crypto_client_instance.init_status;
+
+ if (operation->handle)
+ return PSA_ERROR_BAD_STATE;
+
return crypto_caller_cipher_decrypt_setup(&psa_crypto_client_instance.base,
&operation->handle,
key, alg);
diff --git a/components/service/crypto/client/psa/psa_hash.c b/components/service/crypto/client/psa/psa_hash.c
index 7005c390..83278de6 100644
--- a/components/service/crypto/client/psa/psa_hash.c
+++ b/components/service/crypto/client/psa/psa_hash.c
@@ -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
*/
@@ -14,6 +14,9 @@ psa_status_t psa_hash_setup(psa_hash_operation_t *operation,
if (psa_crypto_client_instance.init_status != PSA_SUCCESS)
return psa_crypto_client_instance.init_status;
+ if (operation->handle)
+ return PSA_ERROR_BAD_STATE;
+
return crypto_caller_hash_setup(&psa_crypto_client_instance.base,
&operation->handle, alg);
}
@@ -55,6 +58,9 @@ psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
psa_hash_operation_t *target_operation)
{
+ if (target_operation->handle)
+ return PSA_ERROR_BAD_STATE;
+
return crypto_caller_hash_clone(&psa_crypto_client_instance.base,
source_operation->handle,
&target_operation->handle);
diff --git a/components/service/crypto/client/psa/psa_mac.c b/components/service/crypto/client/psa/psa_mac.c
index 5efa1c4d..5c5eb32a 100644
--- a/components/service/crypto/client/psa/psa_mac.c
+++ b/components/service/crypto/client/psa/psa_mac.c
@@ -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
*/
@@ -16,6 +16,9 @@ psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation,
if (psa_crypto_client_instance.init_status != PSA_SUCCESS)
return psa_crypto_client_instance.init_status;
+ if (operation->handle)
+ return PSA_ERROR_BAD_STATE;
+
return crypto_caller_mac_sign_setup(&psa_crypto_client_instance.base,
&operation->handle,
key, alg);
@@ -28,7 +31,10 @@ psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation,
if (psa_crypto_client_instance.init_status != PSA_SUCCESS)
return psa_crypto_client_instance.init_status;
- return crypto_caller_mac_sign_setup(&psa_crypto_client_instance.base,
+ if (operation->handle)
+ return PSA_ERROR_BAD_STATE;
+
+ return crypto_caller_mac_verify_setup(&psa_crypto_client_instance.base,
&operation->handle,
key, alg);
}
@@ -1,521 +0,0 @@
From 00b4f777b377c69f948f5a9d68cbfc8fa8c38a86 Mon Sep 17 00:00:00 2001
From: Julian Hall <julian.hall@arm.com>
Date: Fri, 11 Feb 2022 14:24:53 +0000
Subject: [PATCH] Integrate AEAD operation support
Resolves issues and integrates AEAD support into the crypto service
provider and clients.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I5fbe78a2dd825f592e26fd665f60c18b576f9de9
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
---
.../caller/packed-c/crypto_caller_aead.h | 70 +++---
.../client/caller/stub/crypto_caller_aead.h | 12 +-
.../service/crypto/client/psa/psa_aead.c | 221 +++++++++++++++---
.../factory/full/crypto_provider_factory.c | 16 +-
.../component-test/component-test.cmake | 4 +-
deployments/crypto/opteesp/CMakeLists.txt | 4 +-
deployments/libts/linux-pc/CMakeLists.txt | 4 +-
deployments/se-proxy/opteesp/CMakeLists.txt | 4 +-
8 files changed, 263 insertions(+), 72 deletions(-)
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h b/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h
index 3d9947d5..c4ffb20c 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_aead.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
*/
@@ -20,38 +20,6 @@
extern "C" {
#endif
-static inline psa_status_t crypto_caller_aead_encrypt(struct service_client *context,
- psa_key_id_t key,
- psa_algorithm_t alg,
- const uint8_t *nonce,
- size_t nonce_length,
- const uint8_t *additional_data,
- size_t additional_data_length,
- const uint8_t *plaintext,
- size_t plaintext_length,
- uint8_t *aeadtext,
- size_t aeadtext_size,
- size_t *aeadtext_length)
-{
- return PSA_ERROR_NOT_SUPPORTED;
-}
-
-static inline psa_status_t crypto_caller_aead_decrypt(struct service_client *context,
- psa_key_id_t key,
- psa_algorithm_t alg,
- const uint8_t *nonce,
- size_t nonce_length,
- const uint8_t *additional_data,
- size_t additional_data_length,
- const uint8_t *aeadtext,
- size_t aeadtext_length,
- uint8_t *plaintext,
- size_t plaintext_size,
- size_t *plaintext_length)
-{
- return PSA_ERROR_NOT_SUPPORTED;
-}
-
static inline psa_status_t common_aead_setup(struct service_client *context,
uint32_t *op_handle,
psa_key_id_t key,
@@ -247,7 +215,7 @@ static inline psa_status_t crypto_caller_aead_set_lengths(struct service_client
{
psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
struct ts_crypto_aead_set_lengths_in req_msg;
- size_t req_fixed_len = sizeof(struct ts_crypto_aead_abort_in);
+ size_t req_fixed_len = sizeof(struct ts_crypto_aead_set_lengths_in);
size_t req_len = req_fixed_len;
req_msg.op_handle = op_handle;
@@ -611,6 +579,40 @@ static inline psa_status_t crypto_caller_aead_abort(struct service_client *conte
return psa_status;
}
+/**
+ * The maximum data length that may be carried in an update operation will be
+ * constrained by the maximum call payload capacity imposed by the end-to-end
+ * RPC call path. These functions return the maximum update size when serialization
+ * overheads are considered. This allows large paylaods to be processed in
+ * maximum size chunks.
+ */
+static inline size_t crypto_caller_aead_max_update_ad_size(const struct service_client *context)
+{
+ /* Returns the maximum number of bytes of additional data that may be
+ * carried as a parameter of the aead_update_ad operation
+ * using the packed-c encoding.
+ */
+ size_t payload_space = context->service_info.max_payload;
+ size_t overhead = sizeof(struct ts_crypto_aead_update_ad_in) + TLV_HDR_LEN;
+
+ return (payload_space > overhead) ? payload_space - overhead : 0;
+}
+
+static inline size_t crypto_caller_aead_max_update_size(const struct service_client *context)
+{
+ /* Returns the maximum number of bytes that may be
+ * carried as a parameter of the aead_update operation
+ * using the packed-c encoding.
+ */
+ size_t payload_space = context->service_info.max_payload;
+ size_t overhead = sizeof(struct ts_crypto_aead_update_in) + TLV_HDR_LEN;
+
+ /* Allow for output to be a whole number of blocks */
+ overhead += PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE;
+
+ return (payload_space > overhead) ? payload_space - overhead : 0;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/components/service/crypto/client/caller/stub/crypto_caller_aead.h b/components/service/crypto/client/caller/stub/crypto_caller_aead.h
index 18aa8cec..455e7ac1 100644
--- a/components/service/crypto/client/caller/stub/crypto_caller_aead.h
+++ b/components/service/crypto/client/caller/stub/crypto_caller_aead.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
*/
@@ -135,6 +135,16 @@ static inline psa_status_t crypto_caller_aead_abort(struct service_client *conte
return PSA_ERROR_NOT_SUPPORTED;
}
+static inline size_t crypto_caller_aead_max_update_ad_size(const struct service_client *context)
+{
+ return 0;
+}
+
+static inline size_t crypto_caller_aead_max_update_size(const struct service_client *context)
+{
+ return 0;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/components/service/crypto/client/psa/psa_aead.c b/components/service/crypto/client/psa/psa_aead.c
index 22fd3da1..e4579e63 100644
--- a/components/service/crypto/client/psa/psa_aead.c
+++ b/components/service/crypto/client/psa/psa_aead.c
@@ -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
*/
@@ -8,37 +8,6 @@
#include "psa_crypto_client.h"
#include "crypto_caller_selector.h"
-
-psa_status_t psa_aead_encrypt(psa_key_id_t key,
- psa_algorithm_t alg,
- const uint8_t *nonce,
- size_t nonce_length,
- const uint8_t *additional_data,
- size_t additional_data_length,
- const uint8_t *plaintext,
- size_t plaintext_length,
- uint8_t *aeadtext,
- size_t aeadtext_size,
- size_t *aeadtext_length)
-{
- return PSA_ERROR_NOT_SUPPORTED;
-}
-
-psa_status_t psa_aead_decrypt(psa_key_id_t key,
- psa_algorithm_t alg,
- const uint8_t *nonce,
- size_t nonce_length,
- const uint8_t *additional_data,
- size_t additional_data_length,
- const uint8_t *aeadtext,
- size_t aeadtext_length,
- uint8_t *plaintext,
- size_t plaintext_size,
- size_t *plaintext_length)
-{
- return PSA_ERROR_NOT_SUPPORTED;
-}
-
psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation,
psa_key_id_t key,
psa_algorithm_t alg)
@@ -143,3 +112,191 @@ psa_status_t psa_aead_abort(psa_aead_operation_t *operation)
return crypto_caller_aead_abort(&psa_crypto_client_instance.base,
operation->handle);
}
+
+static psa_status_t multi_aead_update_ad(psa_aead_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length)
+{
+ psa_status_t psa_status = PSA_SUCCESS;
+ size_t max_update_size =
+ crypto_caller_aead_max_update_ad_size(&psa_crypto_client_instance.base);
+ size_t bytes_input = 0;
+
+ if (!max_update_size) {
+
+ /* Don't know the max update size so assume that the entire
+ * input and output can be handled in a single update. If
+ * this isn't true, the first aead update operation will fail
+ * safely.
+ */
+ max_update_size = input_length;
+ }
+
+ while (bytes_input < input_length) {
+
+ size_t bytes_remaining = input_length - bytes_input;
+ size_t update_len = (bytes_remaining < max_update_size) ?
+ bytes_remaining :
+ max_update_size;
+
+ psa_status = psa_aead_update_ad(operation,
+ &input[bytes_input], update_len);
+
+ if (psa_status != PSA_SUCCESS) break;
+
+ bytes_input += update_len;
+ }
+
+ return psa_status;
+}
+
+static psa_status_t multi_aead_update(psa_aead_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t psa_status = PSA_SUCCESS;
+ size_t max_update_size =
+ crypto_caller_aead_max_update_size(&psa_crypto_client_instance.base);
+ size_t bytes_input = 0;
+ size_t bytes_output = 0;
+
+ *output_length = 0;
+
+ if (!max_update_size) {
+
+ /* Don't know the max update size so assume that the entire
+ * input and output can be handled in a single update. If
+ * this isn't true, the first aead update operation will fail
+ * safely.
+ */
+ max_update_size = input_length;
+ }
+
+ while ((bytes_input < input_length) && (bytes_output < output_size)) {
+
+ size_t update_output_len = 0;
+ size_t bytes_remaining = input_length - bytes_input;
+ size_t update_len = (bytes_remaining < max_update_size) ?
+ bytes_remaining :
+ max_update_size;
+
+ psa_status = psa_aead_update(operation,
+ &input[bytes_input], update_len,
+ &output[bytes_output], output_size - bytes_output, &update_output_len);
+
+ if (psa_status != PSA_SUCCESS) break;
+
+ bytes_input += update_len;
+ bytes_output += update_output_len;
+ }
+
+ if (psa_status == PSA_SUCCESS) {
+
+ *output_length = bytes_output;
+ }
+
+ return psa_status;
+}
+
+psa_status_t psa_aead_encrypt(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *nonce,
+ size_t nonce_length,
+ const uint8_t *additional_data,
+ size_t additional_data_length,
+ const uint8_t *plaintext,
+ size_t plaintext_length,
+ uint8_t *aeadtext,
+ size_t aeadtext_size,
+ size_t *aeadtext_length)
+{
+ psa_aead_operation_t operation = psa_aead_operation_init();
+ size_t bytes_output = 0;
+ *aeadtext_length = 0;
+
+ psa_status_t psa_status = psa_aead_encrypt_setup(&operation, key, alg);
+ if (psa_status != PSA_SUCCESS) return psa_status;
+
+ if ((psa_status = psa_aead_set_lengths(&operation, additional_data_length, plaintext_length),
+ psa_status == PSA_SUCCESS) &&
+ (psa_status = psa_aead_set_nonce(&operation, nonce, nonce_length),
+ psa_status == PSA_SUCCESS) &&
+ (psa_status = multi_aead_update_ad(&operation, additional_data, additional_data_length),
+ psa_status == PSA_SUCCESS) &&
+ (psa_status = multi_aead_update(&operation, plaintext, plaintext_length,
+ aeadtext, aeadtext_size, &bytes_output),
+ psa_status == PSA_SUCCESS))
+ {
+ size_t remaining_aead_len = 0;
+ size_t tag_len = 0;
+
+ psa_status = psa_aead_finish(&operation,
+ NULL, 0, &remaining_aead_len,
+ &aeadtext[bytes_output], aeadtext_size - bytes_output, &tag_len);
+
+ if (psa_status == PSA_SUCCESS) {
+
+ *aeadtext_length = bytes_output + remaining_aead_len + tag_len;
+ }
+ }
+ else {
+
+ psa_aead_abort(&operation);
+ }
+
+ return psa_status;
+}
+
+psa_status_t psa_aead_decrypt(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *nonce,
+ size_t nonce_length,
+ const uint8_t *additional_data,
+ size_t additional_data_length,
+ const uint8_t *aeadtext,
+ size_t aeadtext_length,
+ uint8_t *plaintext,
+ size_t plaintext_size,
+ size_t *plaintext_length)
+{
+ psa_aead_operation_t operation = psa_aead_operation_init();
+ size_t bytes_output = 0;
+ *plaintext_length = 0;
+
+ psa_status_t psa_status = psa_aead_decrypt_setup(&operation, key, alg);
+ if (psa_status != PSA_SUCCESS) return psa_status;
+
+ size_t tag_len = PSA_ALG_AEAD_GET_TAG_LENGTH(alg);
+ size_t ciphertext_len = (aeadtext_length > tag_len) ? aeadtext_length - tag_len : 0;
+
+ if ((psa_status = psa_aead_set_lengths(&operation, additional_data_length, ciphertext_len),
+ psa_status == PSA_SUCCESS) &&
+ (psa_status = psa_aead_set_nonce(&operation, nonce, nonce_length),
+ psa_status == PSA_SUCCESS) &&
+ (psa_status = multi_aead_update_ad(&operation, additional_data, additional_data_length),
+ psa_status == PSA_SUCCESS) &&
+ (psa_status = multi_aead_update(&operation, aeadtext, ciphertext_len,
+ plaintext, plaintext_size, &bytes_output),
+ psa_status == PSA_SUCCESS))
+ {
+ size_t remaining_plaintext_len = 0;
+
+ psa_status = psa_aead_verify(&operation,
+ NULL, 0, &remaining_plaintext_len,
+ &aeadtext[bytes_output], aeadtext_length - bytes_output);
+
+ if (psa_status == PSA_SUCCESS) {
+
+ *plaintext_length = bytes_output + remaining_plaintext_len;
+ }
+ }
+ else {
+
+ psa_aead_abort(&operation);
+ }
+
+ return psa_status;
+}
diff --git a/components/service/crypto/factory/full/crypto_provider_factory.c b/components/service/crypto/factory/full/crypto_provider_factory.c
index 2d926eb6..ee2b4473 100644
--- a/components/service/crypto/factory/full/crypto_provider_factory.c
+++ b/components/service/crypto/factory/full/crypto_provider_factory.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
*
@@ -17,6 +17,8 @@
#include <service/crypto/provider/extension/key_derivation/serializer/packed-c/packedc_key_derivation_provider_serializer.h>
#include <service/crypto/provider/extension/mac/mac_provider.h>
#include <service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.h>
+#include <service/crypto/provider/extension/aead/aead_provider.h>
+#include <service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.h>
#include <service/discovery/provider/discovery_provider.h>
#include <service/discovery/provider/serializer/packed-c/packedc_discovery_provider_serializer.h>
@@ -34,6 +36,7 @@ static struct full_crypto_provider
struct cipher_provider cipher_provider;
struct key_derivation_provider key_derivation_provider;
struct mac_provider mac_provider;
+ struct aead_provider aead_provider;
} instance;
@@ -98,6 +101,17 @@ struct crypto_provider *crypto_provider_factory_create(void)
crypto_provider_extend(&instance.crypto_provider,
&instance.mac_provider.base_provider);
+ /**
+ * Extend with aead operations
+ */
+ aead_provider_init(&instance.aead_provider);
+
+ aead_provider_register_serializer(&instance.aead_provider,
+ TS_RPC_ENCODING_PACKED_C, packedc_aead_provider_serializer_instance());
+
+ crypto_provider_extend(&instance.crypto_provider,
+ &instance.aead_provider.base_provider);
+
return &instance.crypto_provider;
}
diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake
index a0233c34..c3b015ab 100644
--- a/deployments/component-test/component-test.cmake
+++ b/deployments/component-test/component-test.cmake
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -85,6 +85,8 @@ add_components(
"components/service/crypto/provider/extension/key_derivation/serializer/packed-c"
"components/service/crypto/provider/extension/mac"
"components/service/crypto/provider/extension/mac/serializer/packed-c"
+ "components/service/crypto/provider/extension/aead"
+ "components/service/crypto/provider/extension/aead/serializer/packed-c"
"components/service/crypto/provider/test"
"components/service/crypto/backend/mbedcrypto"
"components/service/crypto/factory/full"
diff --git a/deployments/crypto/opteesp/CMakeLists.txt b/deployments/crypto/opteesp/CMakeLists.txt
index 8ada74e9..eb5d0847 100644
--- a/deployments/crypto/opteesp/CMakeLists.txt
+++ b/deployments/crypto/opteesp/CMakeLists.txt
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -62,6 +62,8 @@ add_components(TARGET "crypto-sp"
"components/service/crypto/provider/extension/key_derivation/serializer/packed-c"
"components/service/crypto/provider/extension/mac"
"components/service/crypto/provider/extension/mac/serializer/packed-c"
+ "components/service/crypto/provider/extension/aead"
+ "components/service/crypto/provider/extension/aead/serializer/packed-c"
"components/service/crypto/factory/full"
"components/service/crypto/backend/mbedcrypto"
"components/service/crypto/backend/mbedcrypto/trng_adapter/platform"
diff --git a/deployments/libts/linux-pc/CMakeLists.txt b/deployments/libts/linux-pc/CMakeLists.txt
index fc98407c..97eaaa73 100644
--- a/deployments/libts/linux-pc/CMakeLists.txt
+++ b/deployments/libts/linux-pc/CMakeLists.txt
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -71,6 +71,8 @@ add_components(
"components/service/crypto/provider/extension/key_derivation/serializer/packed-c"
"components/service/crypto/provider/extension/mac"
"components/service/crypto/provider/extension/mac/serializer/packed-c"
+ "components/service/crypto/provider/extension/aead"
+ "components/service/crypto/provider/extension/aead/serializer/packed-c"
"components/service/crypto/factory/full"
"components/service/crypto/backend/mbedcrypto"
"components/service/crypto/backend/mbedcrypto/trng_adapter/linux"
diff --git a/deployments/se-proxy/opteesp/CMakeLists.txt b/deployments/se-proxy/opteesp/CMakeLists.txt
index 953bb716..24a8ca65 100644
--- a/deployments/se-proxy/opteesp/CMakeLists.txt
+++ b/deployments/se-proxy/opteesp/CMakeLists.txt
@@ -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
#
@@ -70,6 +70,8 @@ add_components(TARGET "se-proxy"
"components/service/crypto/provider/extension/key_derivation/serializer/packed-c"
"components/service/crypto/provider/extension/mac"
"components/service/crypto/provider/extension/mac/serializer/packed-c"
+ "components/service/crypto/provider/extension/aead"
+ "components/service/crypto/provider/extension/aead/serializer/packed-c"
"components/service/crypto/factory/full"
"components/service/secure_storage/include"
"components/service/secure_storage/frontend/secure_storage_provider"
@@ -1,96 +0,0 @@
From 43388a8e071980d9146f935f486a859d0a04322b Mon Sep 17 00:00:00 2001
From: Julian Hall <julian.hall@arm.com>
Date: Tue, 15 Feb 2022 15:46:58 +0000
Subject: [PATCH] Add IV generation to one-shot cipher operation
The functions psa_cipher_encrypt and psa_cipher_decrypt are
one-shot operations that can take an arbitrary sized input.
These operations are implemented as client-side functions
that use multi-part cipher operations to allow large inputs
to be handled. The existing implementations were missing the
generation and setting of the IV at the start of the data.
This was leading to PSA Arch test failures (248 & 249). This
commit adds the missing IV handling and resolves the test
failures.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I4afb555ee7062ebb387e5bb27fb1e082288ad8c7
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
---
.../service/crypto/client/psa/psa_cipher.c | 40 +++++++++++++++----
1 file changed, 33 insertions(+), 7 deletions(-)
diff --git a/components/service/crypto/client/psa/psa_cipher.c b/components/service/crypto/client/psa/psa_cipher.c
index 3ab8ea21..111af829 100644
--- a/components/service/crypto/client/psa/psa_cipher.c
+++ b/components/service/crypto/client/psa/psa_cipher.c
@@ -8,7 +8,6 @@
#include "psa_crypto_client.h"
#include "crypto_caller_selector.h"
-
psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation,
psa_key_id_t key,
psa_algorithm_t alg)
@@ -171,9 +170,16 @@ psa_status_t psa_cipher_encrypt(psa_key_id_t key,
if (psa_status == PSA_SUCCESS) {
+ size_t ciphertext_len = 0;
+ size_t iv_len = 0;
+
+ psa_cipher_generate_iv(&operation, output, output_size, &iv_len);
+
psa_status = multi_cipher_update(&operation,
input, input_length,
- output, output_size, output_length);
+ &output[iv_len], output_size - iv_len, &ciphertext_len);
+
+ *output_length = iv_len + ciphertext_len;
}
return psa_status;
@@ -187,14 +193,34 @@ psa_status_t psa_cipher_decrypt(psa_key_id_t key,
size_t output_size,
size_t *output_length)
{
- psa_cipher_operation_t operation = psa_cipher_operation_init();
- psa_status_t psa_status = psa_cipher_decrypt_setup(&operation, key, alg);
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_status_t psa_status = psa_get_key_attributes(key, &attributes);
if (psa_status == PSA_SUCCESS) {
- psa_status = multi_cipher_update(&operation,
- input, input_length,
- output, output_size, output_length);
+ psa_cipher_operation_t operation = psa_cipher_operation_init();
+ psa_status = psa_cipher_decrypt_setup(&operation, key, alg);
+
+ if (psa_status == PSA_SUCCESS) {
+
+ size_t iv_len = PSA_CIPHER_IV_LENGTH(psa_get_key_type(&attributes), alg);
+
+ if (input_length >= iv_len) {
+
+ psa_cipher_set_iv(&operation, input, iv_len);
+
+ psa_status = multi_cipher_update(&operation,
+ &input[iv_len], input_length - iv_len,
+ output, output_size, output_length);
+ }
+ else {
+
+ psa_cipher_abort(&operation);
+ psa_status = PSA_ERROR_INVALID_ARGUMENT;
+ }
+ }
+
+ psa_reset_key_attributes(&attributes);
}
return psa_status;
@@ -1,241 +0,0 @@
From 07277e2ab4b54e5844c28f0cb33e64a91aa5f492 Mon Sep 17 00:00:00 2001
From: Julian Hall <julian.hall@arm.com>
Date: Wed, 16 Feb 2022 10:37:04 +0000
Subject: [PATCH] Fix multi-part termination on error
For multi-part operations, the PSA Crypto API specifies that if
the final operation does not return PSA_SUCCESS, the abort
operaion must be called by a client to clean-up the operation.
This change modifies behaviour in-line with the API definition.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: Ia3d3ec004164647a7ab5988cac45c39c22e76e9a
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
---
components/service/crypto/client/psa/psa_aead.c | 8 ++++++++
components/service/crypto/client/psa/psa_cipher.c | 4 ++++
components/service/crypto/client/psa/psa_hash.c | 10 ++++++++++
components/service/crypto/client/psa/psa_mac.c | 10 ++++++++++
.../crypto/provider/extension/aead/aead_provider.c | 10 +++++-----
.../provider/extension/cipher/cipher_provider.c | 6 +++---
.../crypto/provider/extension/hash/hash_provider.c | 6 +++---
.../crypto/provider/extension/mac/mac_provider.c | 11 +++++++----
8 files changed, 50 insertions(+), 15 deletions(-)
diff --git a/components/service/crypto/client/psa/psa_aead.c b/components/service/crypto/client/psa/psa_aead.c
index e4579e63..559eb6a3 100644
--- a/components/service/crypto/client/psa/psa_aead.c
+++ b/components/service/crypto/client/psa/psa_aead.c
@@ -241,6 +241,10 @@ psa_status_t psa_aead_encrypt(psa_key_id_t key,
*aeadtext_length = bytes_output + remaining_aead_len + tag_len;
}
+ else {
+
+ psa_aead_abort(&operation);
+ }
}
else {
@@ -292,6 +296,10 @@ psa_status_t psa_aead_decrypt(psa_key_id_t key,
*plaintext_length = bytes_output + remaining_plaintext_len;
}
+ else {
+
+ psa_aead_abort(&operation);
+ }
}
else {
diff --git a/components/service/crypto/client/psa/psa_cipher.c b/components/service/crypto/client/psa/psa_cipher.c
index 111af829..4e4264b6 100644
--- a/components/service/crypto/client/psa/psa_cipher.c
+++ b/components/service/crypto/client/psa/psa_cipher.c
@@ -146,6 +146,10 @@ static psa_status_t multi_cipher_update(psa_cipher_operation_t *operation,
*output_length = bytes_output + finish_output_len;
}
+ else {
+
+ psa_cipher_abort(operation);
+ }
}
else {
diff --git a/components/service/crypto/client/psa/psa_hash.c b/components/service/crypto/client/psa/psa_hash.c
index 83278de6..e5dd0030 100644
--- a/components/service/crypto/client/psa/psa_hash.c
+++ b/components/service/crypto/client/psa/psa_hash.c
@@ -137,6 +137,11 @@ psa_status_t psa_hash_compare(psa_algorithm_t alg,
if (psa_status == PSA_SUCCESS) {
psa_status = psa_hash_verify(&operation, hash, hash_length);
+
+ if (psa_status != PSA_SUCCESS) {
+
+ psa_hash_abort(&operation);
+ }
}
return psa_status;
@@ -155,6 +160,11 @@ psa_status_t psa_hash_compute(psa_algorithm_t alg,
if (psa_status == PSA_SUCCESS) {
psa_status = psa_hash_finish(&operation, hash, hash_size, hash_length);
+
+ if (psa_status != PSA_SUCCESS) {
+
+ psa_hash_abort(&operation);
+ }
}
return psa_status;
diff --git a/components/service/crypto/client/psa/psa_mac.c b/components/service/crypto/client/psa/psa_mac.c
index 5c5eb32a..a3db8644 100644
--- a/components/service/crypto/client/psa/psa_mac.c
+++ b/components/service/crypto/client/psa/psa_mac.c
@@ -129,6 +129,11 @@ psa_status_t psa_mac_verify(psa_key_id_t key,
if (psa_status == PSA_SUCCESS) {
psa_status = psa_mac_verify_finish(&operation, mac, mac_length);
+
+ if (psa_status != PSA_SUCCESS) {
+
+ psa_mac_abort(&operation);
+ }
}
return psa_status;
@@ -153,6 +158,11 @@ psa_status_t psa_mac_compute(psa_key_id_t key,
if (psa_status == PSA_SUCCESS) {
psa_status = psa_mac_sign_finish(&operation, mac, mac_size, mac_length);
+
+ if (psa_status != PSA_SUCCESS) {
+
+ psa_mac_abort(&operation);
+ }
}
return psa_status;
diff --git a/components/service/crypto/provider/extension/aead/aead_provider.c b/components/service/crypto/provider/extension/aead/aead_provider.c
index f4e81a03..14a25436 100644
--- a/components/service/crypto/provider/extension/aead/aead_provider.c
+++ b/components/service/crypto/provider/extension/aead/aead_provider.c
@@ -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
*/
@@ -369,9 +369,9 @@ static rpc_status_t aead_finish_handler(void *context, struct call_req *req)
rpc_status = serializer->serialize_aead_finish_resp(resp_buf,
ciphertext, ciphertext_len,
tag, tag_len);
- }
- crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ }
}
call_req_set_opstatus(req, psa_status);
@@ -418,9 +418,9 @@ static rpc_status_t aead_verify_handler(void *context, struct call_req *req)
struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
rpc_status = serializer->serialize_aead_verify_resp(resp_buf,
plaintext, plaintext_len);
- }
- crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ }
}
call_req_set_opstatus(req, psa_status);
diff --git a/components/service/crypto/provider/extension/cipher/cipher_provider.c b/components/service/crypto/provider/extension/cipher/cipher_provider.c
index 8e7a86de..a5dd0371 100644
--- a/components/service/crypto/provider/extension/cipher/cipher_provider.c
+++ b/components/service/crypto/provider/extension/cipher/cipher_provider.c
@@ -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
*/
@@ -283,9 +283,9 @@ static rpc_status_t cipher_finish_handler(void *context, struct call_req* req)
struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
rpc_status = serializer->serialize_cipher_finish_resp(resp_buf, output, output_len);
- }
- crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ }
}
call_req_set_opstatus(req, psa_status);
diff --git a/components/service/crypto/provider/extension/hash/hash_provider.c b/components/service/crypto/provider/extension/hash/hash_provider.c
index 2c560513..fd39d440 100644
--- a/components/service/crypto/provider/extension/hash/hash_provider.c
+++ b/components/service/crypto/provider/extension/hash/hash_provider.c
@@ -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
*/
@@ -179,9 +179,9 @@ static rpc_status_t hash_finish_handler(void *context, struct call_req* req)
struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
rpc_status = serializer->serialize_hash_finish_resp(resp_buf, hash, hash_len);
- }
- crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ }
}
call_req_set_opstatus(req, psa_status);
diff --git a/components/service/crypto/provider/extension/mac/mac_provider.c b/components/service/crypto/provider/extension/mac/mac_provider.c
index 96fe4cf3..eef55586 100644
--- a/components/service/crypto/provider/extension/mac/mac_provider.c
+++ b/components/service/crypto/provider/extension/mac/mac_provider.c
@@ -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
*/
@@ -181,9 +181,9 @@ static rpc_status_t mac_sign_finish_handler(void *context, struct call_req* req)
struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
rpc_status = serializer->serialize_mac_sign_finish_resp(resp_buf, mac, mac_len);
- }
- crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ }
}
call_req_set_opstatus(req, psa_status);
@@ -220,7 +220,10 @@ static rpc_status_t mac_verify_finish_handler(void *context, struct call_req* re
psa_status = psa_mac_verify_finish(&crypto_context->op.mac, mac, mac_len);
- crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ if (psa_status == PSA_SUCCESS) {
+
+ crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ }
}
call_req_set_opstatus(req, psa_status);
@@ -1,49 +0,0 @@
From 92987ec20beedb44d08d429947958c1c068d815c Mon Sep 17 00:00:00 2001
From: Julian Hall <julian.hall@arm.com>
Date: Wed, 16 Feb 2022 11:36:09 +0000
Subject: [PATCH] Abort AEAD operation if client provided buffer is too small
To enable PSA Arch test c258 to pass, handling is added in the
PSA API client adaptor for AEAD (psa_aead.c) to abort an AEAD
operation if an update operation is performed but the client
provided buffer for the output is too small.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: Ib4b26ebc0a83a8928e1b643fba4becd935f6deb0
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
---
components/service/crypto/client/psa/psa_aead.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/components/service/crypto/client/psa/psa_aead.c b/components/service/crypto/client/psa/psa_aead.c
index 559eb6a3..c820d222 100644
--- a/components/service/crypto/client/psa/psa_aead.c
+++ b/components/service/crypto/client/psa/psa_aead.c
@@ -74,10 +74,22 @@ psa_status_t psa_aead_update(psa_aead_operation_t *operation,
size_t output_size,
size_t *output_length)
{
- return crypto_caller_aead_update(&psa_crypto_client_instance.base,
+ psa_status_t status = crypto_caller_aead_update(&psa_crypto_client_instance.base,
operation->handle,
input, input_length,
output, output_size, output_length);
+
+ /*
+ * If too small a buffer has been provided for the output, the operation
+ * state will have been updated but the result can't be put anywhere. This
+ * is an unrecoveral condition so abort the operation.
+ */
+ if (status == PSA_ERROR_BUFFER_TOO_SMALL) {
+
+ psa_aead_abort(operation);
+ }
+
+ return status;
}
psa_status_t psa_aead_finish(psa_aead_operation_t *operation,
@@ -1,94 +0,0 @@
From 75c0689513e7da7fb26bf23c1da4e1aa49783d46 Mon Sep 17 00:00:00 2001
From: Julian Hall <julian.hall@arm.com>
Date: Tue, 11 Jan 2022 09:43:52 +0000
Subject: [PATCH] Peg to updated t_cose version fc3a4b2c
The current version of TS fails to build due to a regression introduced
by a new t_cose version in the upstream project.
The issue is caused by the t_cose external component incorrectly using
tip of master as the upstream version id, which makes strict dependency
control impossible. Change the upstream version id to an SHA, to enable
controlling compatibility issues introduced by future upstream updates.
At the same time update the dependency to the current latest version.
The upstream project is now compatile with mbedtls 3.0.0 API changes
so the previously required compatibility patch has been removed.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I9491a5210904cc369846da2af45b0f7e5913bed8
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
---
.../0002-add-tls3_0_0-compatibility.patch | 31 -------------------
external/t_cose/t_cose.cmake | 5 ++-
2 files changed, 2 insertions(+), 34 deletions(-)
delete mode 100644 external/t_cose/0002-add-tls3_0_0-compatibility.patch
diff --git a/external/t_cose/0002-add-tls3_0_0-compatibility.patch b/external/t_cose/0002-add-tls3_0_0-compatibility.patch
deleted file mode 100644
index 20a7d131..00000000
--- a/external/t_cose/0002-add-tls3_0_0-compatibility.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-diff --git a/crypto_adapters/t_cose_psa_crypto.c b/crypto_adapters/t_cose_psa_crypto.c
-index 49c5b60..3aa7b58 100644
---- a/crypto_adapters/t_cose_psa_crypto.c
-+++ b/crypto_adapters/t_cose_psa_crypto.c
-@@ -99,7 +99,7 @@ static enum t_cose_err_t psa_status_to_t_cose_error_signing(psa_status_t err)
- err == PSA_ERROR_INVALID_SIGNATURE ? T_COSE_ERR_SIG_VERIFY :
- err == PSA_ERROR_NOT_SUPPORTED ? T_COSE_ERR_UNSUPPORTED_SIGNING_ALG:
- err == PSA_ERROR_INSUFFICIENT_MEMORY ? T_COSE_ERR_INSUFFICIENT_MEMORY :
-- err == PSA_ERROR_TAMPERING_DETECTED ? T_COSE_ERR_TAMPERING_DETECTED :
-+ err == PSA_ERROR_CORRUPTION_DETECTED ? T_COSE_ERR_TAMPERING_DETECTED :
- T_COSE_ERR_SIG_FAIL;
- }
-
-@@ -152,7 +152,7 @@ t_cose_crypto_pub_key_verify(int32_t cose_algorithm_id,
- * Crypto ceases providing backwards compatibility then this code
- * has to be changed to use psa_verify_hash().
- */
-- psa_result = psa_asymmetric_verify(verification_key_psa,
-+ psa_result = psa_verify_hash(verification_key_psa,
- psa_alg_id,
- hash_to_verify.ptr,
- hash_to_verify.len,
-@@ -212,7 +212,7 @@ t_cose_crypto_pub_key_sign(int32_t cose_algorithm_id,
- * providing backwards compatibility then this code has to be
- * changed to use psa_sign_hash().
- */
-- psa_result = psa_asymmetric_sign(signing_key_psa,
-+ psa_result = psa_sign_hash(signing_key_psa,
- psa_alg_id,
- hash_to_sign.ptr,
- hash_to_sign.len,
diff --git a/external/t_cose/t_cose.cmake b/external/t_cose/t_cose.cmake
index 660824bd..9321466f 100644
--- a/external/t_cose/t_cose.cmake
+++ b/external/t_cose/t_cose.cmake
@@ -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
#
@@ -16,7 +16,7 @@ endif()
# External component details
set(T_COSE_URL "https://github.com/laurencelundblade/t_cose.git" CACHE STRING "t_cose repository URL")
-set(T_COSE_REFSPEC "master" CACHE STRING "t_cose git refspec")
+set(T_COSE_REFSPEC "fc3a4b2c7196ff582e8242de8bd4a1bc4eec577f" CACHE STRING "t_cose git refspec")
set(T_COSE_INSTALL_PATH "${CMAKE_CURRENT_BINARY_DIR}/t_cose_install" CACHE PATH "t_cose installation directory")
set(T_COSE_PACKAGE_PATH "${T_COSE_INSTALL_PATH}/libt_cose/cmake" CACHE PATH "t_cose CMake package directory")
@@ -37,7 +37,6 @@ FetchContent_Declare(
PATCH_COMMAND git stash
COMMAND git am ${CMAKE_CURRENT_LIST_DIR}/0001-add-install-definition.patch
- COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/0002-add-tls3_0_0-compatibility.patch
COMMAND git reset HEAD~1
)
@@ -1,110 +0,0 @@
From 24436d459ddde697c89ff947c821cec9c5e0906e Mon Sep 17 00:00:00 2001
From: Vishnu Banavath <vishnu.banavath@arm.com>
Date: Wed, 16 Feb 2022 15:55:55 +0000
Subject: [PATCH] pass sysroot_yocto
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
---
deployments/libts/libts-import.cmake | 3 +++
external/MbedTLS/MbedTLS.cmake | 1 +
external/psa_arch_tests/psa_arch_tests.cmake | 25 +++++++++++++-------
3 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/deployments/libts/libts-import.cmake b/deployments/libts/libts-import.cmake
index 792ba86c..b900ce3f 100644
--- a/deployments/libts/libts-import.cmake
+++ b/deployments/libts/libts-import.cmake
@@ -27,9 +27,12 @@ set(LIBTS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/_deps/libts-build" CACHE PATH
file(MAKE_DIRECTORY ${LIBTS_BINARY_DIR})
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --sysroot=${SYSROOT_YOCTO}")
+
#Configure the library
execute_process(COMMAND
${CMAKE_COMMAND}
+ -DCMAKE_SYSROOT=${SYSROOT_YOCTO}
-DCMAKE_INSTALL_PREFIX=${LIBTS_INSTALL_PATH}
-GUnix\ Makefiles
${LIBTS_SOURCE_DIR}
diff --git a/external/MbedTLS/MbedTLS.cmake b/external/MbedTLS/MbedTLS.cmake
index 3350d8a0..33467cf0 100644
--- a/external/MbedTLS/MbedTLS.cmake
+++ b/external/MbedTLS/MbedTLS.cmake
@@ -103,6 +103,7 @@ if (NOT MBEDCRYPTO_LIB_FILE)
execute_process(COMMAND
${CMAKE_COMMAND} -E env CROSS_COMPILE=${CROSS_COMPILE}
${CMAKE_COMMAND}
+ -DCMAKE_SYSROOT=${SYSROOT_YOCTO}
-DENABLE_PROGRAMS=OFF
-DENABLE_TESTING=OFF
-DUNSAFE_BUILD=ON
diff --git a/external/psa_arch_tests/psa_arch_tests.cmake b/external/psa_arch_tests/psa_arch_tests.cmake
index f6d2fb9f..42f73a37 100644
--- a/external/psa_arch_tests/psa_arch_tests.cmake
+++ b/external/psa_arch_tests/psa_arch_tests.cmake
@@ -5,30 +5,33 @@
#
#-------------------------------------------------------------------------------
-# Temporarily using modified tests used for tf-m verification
+# Determine the number of processes to run while running parallel builds.
+# Pass -DPROCESSOR_COUNT=<n> to cmake to override.
+if(NOT DEFINED PROCESSOR_COUNT)
+ include(ProcessorCount)
+ ProcessorCount(PROCESSOR_COUNT)
+ set(PROCESSOR_COUNT ${PROCESSOR_COUNT} CACHE STRING "Number of cores to use for parallel builds.")
+endif()
+
set(PSA_ARCH_TESTS_URL "https://github.com/bensze01/psa-arch-tests.git" CACHE STRING "psa-arch-tests repository URL")
set(PSA_ARCH_TESTS_REFSPEC "fix-multipart-aead" CACHE STRING "psa-arch-tests git refspec")
-
-#set(PSA_ARCH_TESTS_URL "https://github.com/ARM-software/psa-arch-tests.git" CACHE STRING "psa-arch-tests repository URL")
-#set(PSA_ARCH_TESTS_REFSPEC "2a1852252a9b9af655cbe02d5d3c930952d0d798" CACHE STRING "psa-arch-tests v22.01_API1.4_ADAC_BETA")
set(PSA_ARCH_TESTS_INSTALL_PATH "${CMAKE_CURRENT_BINARY_DIR}/psa-arch-tests_install" CACHE PATH "psa-arch-tests installation directory")
set(PSA_ARCH_TESTS_PACKAGE_PATH "${PSA_ARCH_TESTS_INSTALL_PATH}/libpsa-arch-tests/cmake" CACHE PATH "psa-arch-tests CMake package directory")
-set(PSA_ARCH_TESTS_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_deps/psa_arch_tests-src" CACHE PATH "psa-arch-tests source.")
+
+include(FetchContent)
# Checking git
find_program(GIT_COMMAND "git")
if (NOT GIT_COMMAND)
message(FATAL_ERROR "Please install git")
endif()
-
+if ("${PSA_ARCH_TESTS_PATH}" STREQUAL "DOWNLOAD")
# Fetching psa-arch-tests
FetchContent_Declare(
psa-arch-tests
GIT_REPOSITORY ${PSA_ARCH_TESTS_URL}
GIT_TAG ${PSA_ARCH_TESTS_REFSPEC}
GIT_SHALLOW TRUE
- PATCH_COMMAND git stash
- COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/modify_attest_config.patch
)
# FetchContent_GetProperties exports psa-arch-tests_SOURCE_DIR and psa-arch-tests_BINARY_DIR variables
@@ -37,7 +40,10 @@ if(NOT psa-arch-tests_POPULATED)
message(STATUS "Fetching psa-arch-tests")
FetchContent_Populate(psa-arch-tests)
endif()
-
+else()
+ set(psa-arch-tests_SOURCE_DIR "${TS_ROOT}/../psa-arch-tests")
+ set(psa-arch-tests_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+endif()
# Ensure list of include paths is separated correctly
string(REPLACE ";" "\\;" PSA_ARCH_TESTS_EXTERNAL_INCLUDE_PATHS "${PSA_ARCH_TESTS_EXTERNAL_INCLUDE_PATHS}")
@@ -47,6 +53,7 @@ string(REPLACE ";" " " PSA_ARCH_TEST_EXTERNAL_DEFS "${PSA_ARCH_TEST_EXTERNAL_DEF
# Configure the psa-arch-test library
execute_process(COMMAND
${CMAKE_COMMAND}
+ -DCMAKE_SYSROOT=${SYSROOT_YOCTO}
-DTOOLCHAIN=INHERIT
-DCMAKE_TOOLCHAIN_FILE=${TS_EXTERNAL_LIB_TOOLCHAIN_FILE}
-DPSA_INCLUDE_PATHS=${PSA_ARCH_TESTS_EXTERNAL_INCLUDE_PATHS}
@@ -1,29 +0,0 @@
From 0a0007d594db2fceed413cd73e7f08dd8d8ddd57 Mon Sep 17 00:00:00 2001
From: Satish Kumar <satish.kumar01@arm.com>
Date: Sun, 13 Feb 2022 09:01:10 +0000
Subject: [PATCH] Fix: Crypto interface structure aligned with tf-m change.
NO NEED TO RAISE PR: The PR for this FIX is raied by Emek.
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
---
components/service/crypto/backend/psa_ipc/crypto_ipc_backend.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.h b/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.h
index c13c20e8..ec25eaf8 100644
--- a/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.h
+++ b/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.h
@@ -38,7 +38,8 @@ struct psa_ipc_crypto_pack_iovec {
* multipart operation
*/
uint32_t capacity; /*!< Key derivation capacity */
-
+ uint32_t ad_length; /*!< Additional Data length for multipart AEAD */
+ uint32_t plaintext_length; /*!< Plaintext length for multipart AEAD */
struct psa_ipc_crypto_aead_pack_input aead_in; /*!< FixMe: Temporarily used for
* AEAD until the API is
* restructured
@@ -1,494 +0,0 @@
From b8060d9e15b1b910cf9b466a3f43088c71d7a38f Mon Sep 17 00:00:00 2001
From: Satish Kumar <satish.kumar01@arm.com>
Date: Sun, 13 Feb 2022 09:49:51 +0000
Subject: [PATCH] Integrate remaining psa-ipc client APIs.
Signed-off-by: Satish Kumar <satish.kumar01@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
---
.../caller/psa_ipc/crypto_caller_aead.h | 297 +++++++++++++++++-
.../caller/psa_ipc/crypto_caller_sign_hash.h | 35 +++
.../psa_ipc/crypto_caller_verify_hash.h | 33 +-
3 files changed, 352 insertions(+), 13 deletions(-)
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_aead.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_aead.h
index 78517fe3..f6aadd8b 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_aead.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_aead.h
@@ -152,7 +152,27 @@ static inline psa_status_t crypto_caller_aead_encrypt_setup(
psa_key_id_t key,
psa_algorithm_t alg)
{
- return PSA_ERROR_NOT_SUPPORTED;
+ struct service_client *ipc = context;
+ struct rpc_caller *caller = ipc->caller;
+ psa_status_t status;
+ struct psa_ipc_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_ENCRYPT_SETUP_SID,
+ .key_id = key,
+ .alg = alg,
+ .op_handle = (*op_handle),
+ };
+
+ struct psa_invec in_vec[] = {
+ {.base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec)}
+ };
+ struct psa_outvec out_vec[] = {
+ {.base = psa_ptr_to_u32(op_handle), .len = sizeof(uint32_t)}
+ };
+
+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
+
+ return status;
}
static inline psa_status_t crypto_caller_aead_decrypt_setup(
@@ -161,7 +181,26 @@ static inline psa_status_t crypto_caller_aead_decrypt_setup(
psa_key_id_t key,
psa_algorithm_t alg)
{
- return PSA_ERROR_NOT_SUPPORTED;
+ struct service_client *ipc = context;
+ struct rpc_caller *caller = ipc->caller;
+ psa_status_t status;
+ struct psa_ipc_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_DECRYPT_SETUP_SID,
+ .key_id = key,
+ .alg = alg,
+ .op_handle = (*op_handle),
+ };
+
+ struct psa_invec in_vec[] = {
+ {.base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec)}
+ };
+ struct psa_outvec out_vec[] = {
+ {.base = psa_ptr_to_u32(op_handle), .len = sizeof(uint32_t)}
+ };
+
+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
+ return status;
}
static inline psa_status_t crypto_caller_aead_generate_nonce(
@@ -171,7 +210,27 @@ static inline psa_status_t crypto_caller_aead_generate_nonce(
size_t nonce_size,
size_t *nonce_length)
{
- return PSA_ERROR_NOT_SUPPORTED;
+ struct service_client *ipc = context;
+ struct rpc_caller *caller = ipc->caller;
+ psa_status_t status;
+ struct psa_ipc_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_GENERATE_NONCE_SID,
+ .op_handle = op_handle,
+ };
+
+ struct psa_invec in_vec[] = {
+ {.base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec)},
+ };
+ struct psa_outvec out_vec[] = {
+ {.base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t)},
+ {.base = psa_ptr_to_u32(nonce), .len = nonce_size}
+ };
+
+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
+
+ *nonce_length = out_vec[1].len;
+ return status;
}
static inline psa_status_t crypto_caller_aead_set_nonce(
@@ -180,7 +239,25 @@ static inline psa_status_t crypto_caller_aead_set_nonce(
const uint8_t *nonce,
size_t nonce_length)
{
- return PSA_ERROR_NOT_SUPPORTED;
+ struct service_client *ipc = context;
+ struct rpc_caller *caller = ipc->caller;
+ psa_status_t status;
+ struct psa_ipc_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_SET_NONCE_SID,
+ .op_handle = op_handle,
+ };
+
+ struct psa_invec in_vec[] = {
+ {.base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec)},
+ {.base = psa_ptr_to_u32(nonce), .len = nonce_length}
+ };
+ struct psa_outvec out_vec[] = {
+ {.base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t)}
+ };
+
+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
+ return status;
}
static inline psa_status_t crypto_caller_aead_set_lengths(
@@ -189,7 +266,27 @@ static inline psa_status_t crypto_caller_aead_set_lengths(
size_t ad_length,
size_t plaintext_length)
{
- return PSA_ERROR_NOT_SUPPORTED;
+ struct service_client *ipc = context;
+ struct rpc_caller *caller = ipc->caller;
+ psa_status_t status;
+ struct psa_ipc_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_SET_LENGTHS_SID,
+ .ad_length = ad_length,
+ .plaintext_length = plaintext_length,
+ .op_handle = op_handle,
+ };
+
+ struct psa_invec in_vec[] = {
+ {.base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec)},
+ };
+ struct psa_outvec out_vec[] = {
+ {.base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t)}
+ };
+
+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
+
+ return status;
}
static inline psa_status_t crypto_caller_aead_update_ad(
@@ -198,7 +295,35 @@ static inline psa_status_t crypto_caller_aead_update_ad(
const uint8_t *input,
size_t input_length)
{
- return PSA_ERROR_NOT_SUPPORTED;
+ struct service_client *ipc = context;
+ struct rpc_caller *caller = ipc->caller;
+ psa_status_t status;
+ struct psa_ipc_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_UPDATE_AD_SID,
+ .op_handle = op_handle,
+ };
+
+ /* Sanitize the optional input */
+ if ((input == NULL) && (input_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ struct psa_invec in_vec[] = {
+ {.base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec)},
+ {.base = psa_ptr_const_to_u32(input), .len = input_length}
+ };
+ struct psa_outvec out_vec[] = {
+ {.base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t)}
+ };
+
+ size_t in_len = IOVEC_LEN(in_vec);
+
+ if (input == NULL) {
+ in_len--;
+ }
+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
+ in_len, out_vec, IOVEC_LEN(out_vec));
+ return status;
}
static inline psa_status_t crypto_caller_aead_update(
@@ -210,7 +335,38 @@ static inline psa_status_t crypto_caller_aead_update(
size_t output_size,
size_t *output_length)
{
- return PSA_ERROR_NOT_SUPPORTED;
+ struct service_client *ipc = context;
+ struct rpc_caller *caller = ipc->caller;
+ psa_status_t status;
+ struct psa_ipc_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_UPDATE_SID,
+ .op_handle = op_handle,
+ };
+
+ /* Sanitize the optional input */
+ if ((input == NULL) && (input_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ struct psa_invec in_vec[] = {
+ {.base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec)},
+ {.base = psa_ptr_const_to_u32(input), .len = input_length}
+ };
+ struct psa_outvec out_vec[] = {
+ {.base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t)},
+ {.base = psa_ptr_const_to_u32(output), .len = output_size},
+ };
+
+ size_t in_len = IOVEC_LEN(in_vec);
+
+ if (input == NULL) {
+ in_len--;
+ }
+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
+ in_len, out_vec, IOVEC_LEN(out_vec));
+
+ *output_length = out_vec[1].len;
+ return status;
}
static inline psa_status_t crypto_caller_aead_finish(
@@ -223,7 +379,48 @@ static inline psa_status_t crypto_caller_aead_finish(
size_t tag_size,
size_t *tag_length)
{
- return PSA_ERROR_NOT_SUPPORTED;
+ struct service_client *ipc = context;
+ struct rpc_caller *caller = ipc->caller;
+ psa_status_t status;
+ struct psa_ipc_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_FINISH_SID,
+ .op_handle = op_handle,
+ };
+
+ /* Sanitize the optional output */
+ if ((aeadtext == NULL) && (aeadtext_size != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ struct psa_invec in_vec[] = {
+ {.base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec)},
+ };
+ struct psa_outvec out_vec[] = {
+ {.base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t)},
+ {.base = psa_ptr_const_to_u32(tag), .len = tag_size},
+ {.base = psa_ptr_const_to_u32(aeadtext), .len = aeadtext_size}
+ };
+
+ size_t out_len = IOVEC_LEN(out_vec);
+
+ if (aeadtext == NULL || aeadtext_size == 0) {
+ out_len--;
+ }
+ if ((out_len == 3) && (aeadtext_length == NULL)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
+ IOVEC_LEN(in_vec), out_vec, out_len);
+
+ *tag_length = out_vec[1].len;
+
+ if (out_len == 3) {
+ *aeadtext_length = out_vec[2].len;
+ } else {
+ *aeadtext_length = 0;
+ }
+ return status;
}
static inline psa_status_t crypto_caller_aead_verify(
@@ -235,14 +432,94 @@ static inline psa_status_t crypto_caller_aead_verify(
const uint8_t *tag,
size_t tag_length)
{
- return PSA_ERROR_NOT_SUPPORTED;
+ struct service_client *ipc = context;
+ struct rpc_caller *caller = ipc->caller;
+ psa_status_t status;
+ struct psa_ipc_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_VERIFY_SID,
+ .op_handle = op_handle,
+ };
+
+ /* Sanitize the optional output */
+ if ((plaintext == NULL) && (plaintext_size != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ struct psa_invec in_vec[] = {
+ {.base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec)},
+ {.base = psa_ptr_const_to_u32(tag), .len = tag_length}
+ };
+ struct psa_outvec out_vec[] = {
+ {.base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t)},
+ {.base = psa_ptr_const_to_u32(plaintext), .len = plaintext_size},
+ };
+
+ size_t out_len = IOVEC_LEN(out_vec);
+
+ if (plaintext == NULL || plaintext_size == 0) {
+ out_len--;
+ }
+ if ((out_len == 2) && (plaintext_length == NULL)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
+ IOVEC_LEN(in_vec), out_vec, out_len);
+
+ if (out_len == 2) {
+ *plaintext_length = out_vec[1].len;
+ } else {
+ *plaintext_length = 0;
+ }
+ return status;
}
static inline psa_status_t crypto_caller_aead_abort(
struct service_client *context,
uint32_t op_handle)
{
- return PSA_ERROR_NOT_SUPPORTED;
+ struct service_client *ipc = context;
+ struct rpc_caller *caller = ipc->caller;
+ psa_status_t status;
+ struct psa_ipc_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_ABORT_SID,
+ .op_handle = op_handle,
+ };
+
+ struct psa_invec in_vec[] = {
+ {.base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec)},
+ };
+ struct psa_outvec out_vec[] = {
+ {.base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t)},
+ };
+
+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
+ return status;
+}
+
+static inline size_t crypto_caller_aead_max_update_size(const struct service_client *context)
+{
+ /* Returns the maximum number of bytes that may be
+ * carried as a parameter of the mac_update operation
+ * using the packed-c encoding.
+ */
+ size_t payload_space = context->service_info.max_payload;
+ size_t overhead = iov_size;
+
+ return (payload_space > overhead) ? payload_space - overhead : 0;
+}
+
+static inline size_t crypto_caller_aead_max_update_ad_size(const struct service_client *context)
+{
+ /* Returns the maximum number of bytes that may be
+ * carried as a parameter of the mac_update operation
+ * using the packed-c encoding.
+ */
+ size_t payload_space = context->service_info.max_payload;
+ size_t overhead = iov_size;
+
+ return (payload_space > overhead) ? payload_space - overhead : 0;
}
#ifdef __cplusplus
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_sign_hash.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_sign_hash.h
index 71d88ced..e4a2b167 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_sign_hash.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_sign_hash.h
@@ -57,6 +57,41 @@ static inline psa_status_t crypto_caller_sign_hash(struct service_client *contex
return status;
}
+static inline psa_status_t crypto_caller_sign_message(struct service_client *context,
+ psa_key_id_t id,
+ psa_algorithm_t alg,
+ const uint8_t *hash,
+ size_t hash_length,
+ uint8_t *signature,
+ size_t signature_size,
+ size_t *signature_length)
+{
+ struct service_client *ipc = context;
+ struct rpc_caller *caller = ipc->caller;
+ psa_status_t status;
+ struct psa_ipc_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_SIGN_MESSAGE_SID,
+ .key_id = id,
+ .alg = alg,
+ };
+ struct psa_invec in_vec[] = {
+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
+ { .base = psa_ptr_const_to_u32(hash), .len = hash_length },
+ };
+ struct psa_outvec out_vec[] = {
+ { .base = psa_ptr_to_u32(signature), .len = signature_size },
+ };
+
+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
+
+ *signature_length = out_vec[0].len;
+
+ return status;
+}
+
+
+
#ifdef __cplusplus
}
#endif
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_verify_hash.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_verify_hash.h
index e16f6e54..cc9279ee 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_verify_hash.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_verify_hash.h
@@ -24,19 +24,20 @@
extern "C" {
#endif
-static inline psa_status_t crypto_caller_verify_hash(struct service_client *context,
+static inline psa_status_t crypto_caller_common(struct service_client *context,
psa_key_id_t id,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
const uint8_t *signature,
- size_t signature_length)
+ size_t signature_length,
+ uint32_t sfn_id)
{
struct service_client *ipc = context;
struct rpc_caller *caller = ipc->caller;
psa_status_t status;
struct psa_ipc_crypto_pack_iovec iov = {
- .sfn_id = TFM_CRYPTO_VERIFY_HASH_SID,
+ .sfn_id = sfn_id,
.key_id = id,
.alg = alg,
};
@@ -52,6 +53,32 @@ static inline psa_status_t crypto_caller_verify_hash(struct service_client *cont
return status;
}
+static inline psa_status_t crypto_caller_verify_hash(struct service_client *context,
+ psa_key_id_t id,
+ psa_algorithm_t alg,
+ const uint8_t *hash,
+ size_t hash_length,
+ const uint8_t *signature,
+ size_t signature_length)
+{
+
+ return crypto_caller_common(context,id,alg,hash,hash_length,
+ signature,signature_length, TFM_CRYPTO_VERIFY_HASH_SID);
+}
+
+static inline psa_status_t crypto_caller_verify_message(struct service_client *context,
+ psa_key_id_t id,
+ psa_algorithm_t alg,
+ const uint8_t *hash,
+ size_t hash_length,
+ const uint8_t *signature,
+ size_t signature_length)
+{
+
+ return crypto_caller_common(context,id,alg,hash,hash_length,
+ signature,signature_length, TFM_CRYPTO_VERIFY_MESSAGE_SID);
+}
+
#ifdef __cplusplus
}
#endif
@@ -1,40 +0,0 @@
From a037ef21c0334117ad0741776a4b7b6e1a428d19 Mon Sep 17 00:00:00 2001
From: Satish Kumar <satish.kumar01@arm.com>
Date: Mon, 14 Feb 2022 17:52:00 +0000
Subject: [PATCH] Fix : update psa_set_key_usage_flags definition to the latest
from the tf-m
Signed-off-by: Satish Kumar <satish.kumar01@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
---
components/service/crypto/include/psa/crypto_struct.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/components/service/crypto/include/psa/crypto_struct.h b/components/service/crypto/include/psa/crypto_struct.h
index 1bc55e37..b4a7ed4b 100644
--- a/components/service/crypto/include/psa/crypto_struct.h
+++ b/components/service/crypto/include/psa/crypto_struct.h
@@ -155,9 +155,19 @@ static inline psa_key_lifetime_t psa_get_key_lifetime(
return( attributes->lifetime );
}
+static inline void psa_extend_key_usage_flags( psa_key_usage_t *usage_flags )
+{
+ if( *usage_flags & PSA_KEY_USAGE_SIGN_HASH )
+ *usage_flags |= PSA_KEY_USAGE_SIGN_MESSAGE;
+
+ if( *usage_flags & PSA_KEY_USAGE_VERIFY_HASH )
+ *usage_flags |= PSA_KEY_USAGE_VERIFY_MESSAGE;
+}
+
static inline void psa_set_key_usage_flags(psa_key_attributes_t *attributes,
psa_key_usage_t usage_flags)
{
+ psa_extend_key_usage_flags( &usage_flags );
attributes->usage = usage_flags;
}
@@ -1,120 +0,0 @@
From 55463b12cca39d2c6a3fd18bbd3d28ae95dff8cf Mon Sep 17 00:00:00 2001
From: Satish Kumar <satish.kumar01@arm.com>
Date: Mon, 14 Feb 2022 08:22:25 +0000
Subject: [PATCH] Fixes in AEAD for psa-arch test 54 and 58.
Signed-off-by: Satish Kumar <satish.kumar01@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
---
.../crypto/client/caller/packed-c/crypto_caller_aead.h | 1 +
components/service/crypto/include/psa/crypto_sizes.h | 2 +-
.../crypto/provider/extension/aead/aead_provider.c | 8 ++++++--
.../extension/aead/serializer/aead_provider_serializer.h | 1 +
.../packed-c/packedc_aead_provider_serializer.c | 2 ++
protocols/service/crypto/packed-c/aead.h | 1 +
6 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h b/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h
index c4ffb20c..a91f66c1 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h
@@ -309,6 +309,7 @@ static inline psa_status_t crypto_caller_aead_update(struct service_client *cont
size_t req_len = req_fixed_len;
*output_length = 0;
+ req_msg.output_size = output_size;
req_msg.op_handle = op_handle;
/* Mandatory input data parameter */
diff --git a/components/service/crypto/include/psa/crypto_sizes.h b/components/service/crypto/include/psa/crypto_sizes.h
index 4d7bf6e9..e3c4df29 100644
--- a/components/service/crypto/include/psa/crypto_sizes.h
+++ b/components/service/crypto/include/psa/crypto_sizes.h
@@ -351,7 +351,7 @@
* just the largest size that may be generated by
* #psa_aead_generate_nonce().
*/
-#define PSA_AEAD_NONCE_MAX_SIZE 12
+#define PSA_AEAD_NONCE_MAX_SIZE 16
/** A sufficient output buffer size for psa_aead_update().
*
diff --git a/components/service/crypto/provider/extension/aead/aead_provider.c b/components/service/crypto/provider/extension/aead/aead_provider.c
index 14a25436..6b144db8 100644
--- a/components/service/crypto/provider/extension/aead/aead_provider.c
+++ b/components/service/crypto/provider/extension/aead/aead_provider.c
@@ -283,10 +283,11 @@ static rpc_status_t aead_update_handler(void *context, struct call_req *req)
uint32_t op_handle;
const uint8_t *input;
size_t input_len;
+ uint32_t recv_output_size;
if (serializer)
rpc_status = serializer->deserialize_aead_update_req(req_buf, &op_handle,
- &input, &input_len);
+ &recv_output_size, &input, &input_len);
if (rpc_status == TS_RPC_CALL_ACCEPTED) {
@@ -300,9 +301,12 @@ static rpc_status_t aead_update_handler(void *context, struct call_req *req)
if (crypto_context) {
size_t output_len = 0;
- size_t output_size = PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(input_len);
+ size_t output_size = PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(24);
uint8_t *output = malloc(output_size);
+ if (recv_output_size < output_size) {
+ output_size = recv_output_size;
+ }
if (output) {
psa_status = psa_aead_update(&crypto_context->op.aead,
diff --git a/components/service/crypto/provider/extension/aead/serializer/aead_provider_serializer.h b/components/service/crypto/provider/extension/aead/serializer/aead_provider_serializer.h
index bb1a2a97..0156aaba 100644
--- a/components/service/crypto/provider/extension/aead/serializer/aead_provider_serializer.h
+++ b/components/service/crypto/provider/extension/aead/serializer/aead_provider_serializer.h
@@ -51,6 +51,7 @@ struct aead_provider_serializer {
/* Operation: aead_update */
rpc_status_t (*deserialize_aead_update_req)(const struct call_param_buf *req_buf,
uint32_t *op_handle,
+ uint32_t *output_size,
const uint8_t **input, size_t *input_len);
rpc_status_t (*serialize_aead_update_resp)(struct call_param_buf *resp_buf,
diff --git a/components/service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.c b/components/service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.c
index 6f00b3e3..45c739ab 100644
--- a/components/service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.c
+++ b/components/service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.c
@@ -192,6 +192,7 @@ static rpc_status_t deserialize_aead_update_ad_req(const struct call_param_buf *
/* Operation: aead_update */
static rpc_status_t deserialize_aead_update_req(const struct call_param_buf *req_buf,
uint32_t *op_handle,
+ uint32_t *output_size,
const uint8_t **input, size_t *input_len)
{
rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
@@ -208,6 +209,7 @@ static rpc_status_t deserialize_aead_update_req(const struct call_param_buf *req
memcpy(&recv_msg, req_buf->data, expected_fixed_len);
*op_handle = recv_msg.op_handle;
+ *output_size = recv_msg.output_size;
tlv_const_iterator_begin(&req_iter,
(uint8_t*)req_buf->data + expected_fixed_len,
diff --git a/protocols/service/crypto/packed-c/aead.h b/protocols/service/crypto/packed-c/aead.h
index 0be266b5..435fd3b5 100644
--- a/protocols/service/crypto/packed-c/aead.h
+++ b/protocols/service/crypto/packed-c/aead.h
@@ -98,6 +98,7 @@ enum
struct __attribute__ ((__packed__)) ts_crypto_aead_update_in
{
uint32_t op_handle;
+ uint32_t output_size;
};
/* Variable length input parameter tags */
@@ -1,407 +0,0 @@
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
@@ -1,44 +0,0 @@
From 0d8394ee5c52e97e82ebe4641cf0d9ebcbe147ff Mon Sep 17 00:00:00 2001
From: Rui Miguel Silva <rui.silva@linaro.org>
Date: Tue, 6 Sep 2022 16:47:06 +0100
Subject: [PATCH] Add atomic outline to fix build for opemamp
Add memory model 5 atomic ouline support (_sync) to fix
missing symbol when compiling with recent gcc (12.2).
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Rui Miguel Silva <rui.silva@arm.com>
---
deployments/se-proxy/opteesp/lse.S | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/deployments/se-proxy/opteesp/lse.S b/deployments/se-proxy/opteesp/lse.S
index 840683a6671a..8e466d65fc2b 100644
--- a/deployments/se-proxy/opteesp/lse.S
+++ b/deployments/se-proxy/opteesp/lse.S
@@ -5,6 +5,7 @@
.text
.globl __aarch64_cas4_acq_rel
+.globl __aarch64_cas4_sync
__aarch64_cas4_acq_rel:
mov w16, w0
@@ -16,4 +17,12 @@ __aarch64_cas4_acq_rel:
cbnz w17, 0b
1: ret
+__aarch64_cas4_sync:
+ mov w16, w0
+ ldxr w0, [x2]
+ cmp w0, w16
+0: bne 1f
+ stlxr w17, w1, [x2]
+ cbnz w17, 0b
+1: ret
--
2.37.3
@@ -1,128 +1,10 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/secure-partitions/corstone1000:"
COMPATIBLE_MACHINE = "corstone1000"
LIC_FILES_CHKSUM += "file://../mbedtls/LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57 \
file://../nanopb/LICENSE.txt;md5=9db4b73a55a3994384112efcdb37c01f \
file://../openamp/LICENSE.md;md5=a8d8cf662ef6bf9936a1e1413585ecbf \
file://../libmetal/LICENSE.md;md5=fe0b8a4beea8f0813b606d15a3df3d3c \
file://../psa-arch-tests/LICENSE.md;md5=2a944942e1496af1886903d274dedb13 \
"
FILESEXTRAPATHS:prepend := "${THISDIR}/corstone1000:"
SRC_URI:append = " \
${SRC_URI_MBEDTLS} ${SRC_URI_NANOPB} ${SRC_URI_OPENAMP} ${SRC_URI_LIBMETAL} ${SRC_URI_ARCH-TESTS}\
file://0001-tools-cmake-common-applying-lowercase-project-conven.patch \
file://0002-fix-EARLY_TA_PATHS-env-variable.patch \
file://0003-se-proxy-dts-add-se-proxy-as-child-node.patch \
file://0004-Update-mm-comm-buffer-region-in-dts-file.patch \
file://0005-Configure-NV-storage-macro.patch \
file://0006-Use-device-region.patch \
file://0007-Add-openamp-to-SE-proxy-deployment.patch \
file://0008-Implement-mhu-driver-and-the-OpenAmp-conversion-laye.patch \
file://0009-Add-openamp-rpc-caller.patch \
file://0010-add-psa-client-definitions-for-ff-m.patch \
file://0011-Add-common-service-component-to-ipc-support.patch \
file://0012-Add-secure-storage-ipc-backend.patch \
file://0013-Use-secure-storage-ipc-and-openamp-for-se_proxy.patch \
file://0014-Add-uefi-variable-append-write-support.patch \
file://0015-Add-UEFI-variable-support-for-QueryVariableInfo.patch \
file://0016-Add-uefi-test-deployment.patch \
file://0017-Fix-interface-ID-parameter-setting-in-sp-ffarpc_call.patch \
file://0018-Support-FFARPC-call-requests-with-no-shared-buffer.patch \
file://0019-Run-psa-arch-test.patch \
file://0020-Use-address-instead-of-pointers.patch \
file://0021-Add-psa-ipc-attestation-to-se-proxy.patch \
file://0022-Setup-its-backend-as-openamp-rpc-using-secure-storag.patch \
file://0023-add-psa-ipc-crypto-backend.patch \
file://0024-Increase-SMM-gateway-UEFI-variable-macro-value.patch \
file://0025-Add-stub-capsule-update-service-components.patch \
file://0026-Add-logs-to-functions-in-SMM-gateway-SP.patch \
file://0027-Configure-storage-size.patch \
file://0028-Revert-Add-uefi-variable-append-write-support.patch \
file://0029-Change-UID-of-variable-index-in-SMM.patch \
file://0030-Add-missing-features-to-setVariable.patch \
file://0031-Add-invalid-parameter-check-in-getNextVariableName.patch \
file://0032-smm_gateway-add-checks-for-null-attributes.patch \
file://0033-Enhance-mbedtls-fetch-process.patch \
file://0034-Fix-format-specifier-in-logging_caller.patch \
file://0035-Update-refspecs-for-mbedtls-and-psa-arch-tests-for-v.patch \
file://0036-Separate-sign-verify-message-and-hash-operations.patch \
file://0037-Add-defence-against-uninitialised-multi-part-transac.patch \
file://0038-Integrate-AEAD-operation-support.patch \
file://0039-Add-IV-generation-to-one-shot-cipher-operation.patch \
file://0040-Fix-multi-part-termination-on-error.patch \
file://0041-Abort-AEAD-operation-if-client-provided-buffer-is-to.patch \
file://0042-Peg-to-updated-t_cose-version-fc3a4b2c.patch \
file://0043-pass-sysroot_yocto.patch \
file://0044-Fix-Crypto-interface-structure-aligned-with-tf-m-cha.patch \
file://0045-Integrate-remaining-psa-ipc-client-APIs.patch \
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 \
file://0049-Add-atomic-outline-to-fix-build-for-opemamp.patch \
"
file://0026-plat-add-corstone1000-platform-to-drivers-arm.patch \
"
SRC_URI_MBEDTLS = "git://github.com/ARMmbed/mbedtls.git;protocol=https;branch=development;name=mbedtls;destsuffix=git/mbedtls"
SRCREV_mbedtls = "d65aeb37349ad1a50e0f6c9b694d4b5290d60e49"
SRC_URI_NANOPB = "git://github.com/nanopb/nanopb.git;name=nanopb;protocol=https;branch=master;destsuffix=git/nanopb"
SRCREV_nanopb = "df0e92f474f9cca704fe2b31483f0b4d1b1715a4"
SRC_URI_OPENAMP = "git://github.com/OpenAMP/open-amp.git;name=openamp;protocol=https;branch=main;destsuffix=git/openamp"
SRCREV_openamp = "347397decaa43372fc4d00f965640ebde042966d"
SRC_URI_LIBMETAL = "git://github.com/OpenAMP/libmetal.git;name=libmetal;protocol=https;branch=main;destsuffix=git/libmetal"
SRCREV_libmetal = "f252f0e007fbfb8b3a52b1d5901250ddac96baad"
SRC_URI_ARCH-TESTS = "git://github.com/bensze01/psa-arch-tests.git;name=psa-arch-tests;protocol=https;nobranch=1;destsuffix=git/psa-arch-tests"
SRCREV_psa-arch-tests = "5d1a87f9c0a82e1632a3145687b4c8d7cbbeed2d"
TS_ENVIRONMENT_LINUX = "arm-linux"
TS_PLATFORM = "arm/corstone1000"
TS_ENVIRONMENT = "opteesp"
SP_PACKAGING_METHOD = "embedded"
# Secure Enclave proxy secure partition
TS_DEPLOYMENTS += "'deployments/se-proxy/${TS_ENVIRONMENT}'"
# smm-gateway secure partition
TS_DEPLOYMENTS += "'deployments/smm-gateway/${TS_ENVIRONMENT}'"
PSA_API_TESTS = "deployments/psa-api-test/protected_storage/${TS_ENVIRONMENT_LINUX}"
PSA_API_TESTS += "deployments/psa-api-test/internal_trusted_storage/${TS_ENVIRONMENT_LINUX}"
PSA_API_TESTS += "deployments/psa-api-test/initial_attestation/${TS_ENVIRONMENT_LINUX}"
PSA_API_TESTS += "deployments/psa-api-test/crypto/${TS_ENVIRONMENT_LINUX}"
# ffa-debugfs-mod provides arm_ffa_user.h needed by psa-arch-tests source-code
DEPENDS += "ffa-debugfs-mod"
do_configure:append() {
for PSA_API_TEST in ${PSA_API_TESTS}; do
cmake \
-DSYSROOT_YOCTO=${RECIPE_SYSROOT} \
-S ${S}/$PSA_API_TEST -B "${B}/$PSA_API_TEST"
done
}
do_compile:append() {
for PSA_API_TEST in ${PSA_API_TESTS}; do
cmake --build "${B}/$PSA_API_TEST"
done
}
do_install:append() {
for PSA_API_TEST in ${PSA_API_TESTS}; do
install -d -m 0755 ${D}${libdir}/${PSA_API_TEST}
install -d -m 0755 ${D}${includedir}/${PSA_API_TEST}
psafile_fullpath=`ls ${B}/${PSA_API_TEST}/psa-*`
psafile_filename="`basename -s .bin ${psafile_fullpath}`"
install -D -p -m 0755 ${psafile_fullpath} ${D}/${bindir}/${psafile_filename}
done
cp -rf ${B}/${PSA_API_TEST}/libts_install/arm-linux/lib/*.so* ${D}/${libdir}
}
FILES:${PN}-dev = "${includedir}/deployments/psa-api-test/"
INSANE_SKIP:${PN}-psa-api-tests += "rpaths dev-so buildpaths"
PACKAGES += "${PN}-psa-api-tests"
FILES:${PN}-psa-api-tests = "${libdir} ${bindir}"
EXTRA_OECMAKE:append = "-DMM_COMM_BUFFER_ADDRESS="0x00000000 0x02000000" \
-DMM_COMM_BUFFER_PAGE_COUNT="1" \
"
@@ -0,0 +1,4 @@
MACHINE_TS_REQUIRE ?= ""
MACHINE_TS_REQUIRE:corstone1000 = "ts-corstone1000.inc"
require ${MACHINE_TS_REQUIRE}
@@ -0,0 +1,4 @@
MACHINE_TS_REQUIRE ?= ""
MACHINE_TS_REQUIRE:corstone1000 = "ts-corstone1000.inc"
require ${MACHINE_TS_REQUIRE}