Create libpsa deployments

Currently we have libts to encapsulate the lower layers (RPC, driver
access). libts only provides low level APIs for accessing the
services and the users have to add a lot of code on top of the libts
APIs to actually use e.g. a PSA crypto service. This commit
encapsulates this code into a reusable library called libpsa in order
to make integration easier for users. It should be used on top of
libts and it provides convenient APIs to access PSA services.

Signed-off-by: Gabor Toth <gabor.toth2@arm.com>
Change-Id: Id6a16fbf4fbd8c9c9af036d06cfbd934b9ae95cf
diff --git a/deployments/libpsa/arm-linux/CMakeLists.txt b/deployments/libpsa/arm-linux/CMakeLists.txt
new file mode 100644
index 0000000..5fb9f4a
--- /dev/null
+++ b/deployments/libpsa/arm-linux/CMakeLists.txt
@@ -0,0 +1,44 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
+include(../../deployment.cmake REQUIRED)
+
+#-------------------------------------------------------------------------------
+#  Options and variables
+#-------------------------------------------------------------------------------
+set(BUILD_SHARED_LIBS On CACHE BOOL "Determine if a shared library is being built.")
+if(NOT BUILD_SHARED_LIBS)
+	message(FATAL_ERROR "Building static library is not yet supported. Call cmake with -DBUILD_SHARED_LIBS=1")
+endif()
+
+#-------------------------------------------------------------------------------
+#  The CMakeLists.txt for building the libpsa deployment for arm-linux
+#
+#  Used for building the libpsa library for the arm-linux environment. Used for
+#  locating and accessing services from a Linux userspace client. Service
+#  instances can be located in any supported secure processing environment.
+#-------------------------------------------------------------------------------
+include(${TS_ROOT}/environments/arm-linux/env_shared_lib.cmake)
+project(psa LANGUAGES CXX C)
+
+add_library(psa)
+
+target_include_directories(psa PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
+
+#-------------------------------------------------------------------------------
+#  For user-specific tracing set to TRACE_LEVEL_NONE and implement:
+#  void trace_puts(const char *str)
+#-------------------------------------------------------------------------------
+
+set(TRACE_PREFIX "LIBPSA" CACHE STRING "Trace prefix")
+set(TRACE_LEVEL "TRACE_LEVEL_DEBUG" CACHE STRING "Trace level")
+#-------------------------------------------------------------------------------
+#  Extend with components that are common across all deployments of
+#  libpsa
+#
+#-------------------------------------------------------------------------------
+include(../libpsa.cmake REQUIRED)
diff --git a/deployments/libpsa/libpsa-import.cmake b/deployments/libpsa/libpsa-import.cmake
new file mode 100644
index 0000000..661b40d
--- /dev/null
+++ b/deployments/libpsa/libpsa-import.cmake
@@ -0,0 +1,114 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------------
+# Import libpsa into a dependent in-tree deployment build.  Where another
+# deployment uses libpsa, including this file in the dependent deployment
+# CMake build file allows libpsa to be built and installed into the binary
+# directory of the dependent.
+#-------------------------------------------------------------------------------
+option(CFG_FORCE_PREBUILT_LIBPSA Off)
+# Try to find a pre-build package.
+version_semver_read(FILE "${CMAKE_CURRENT_LIST_DIR}/version.txt" MAJOR _major MINOR _minor PATCH _patch)
+set(_verstring "${_major}.${_minor}.${_patch}")
+
+if (COVERAGE)
+	set(LIBPSA_BUILD_TYPE "DebugCoverage" CACHE STRING "Build type." FORCE)
+endif()
+
+find_package(libpsa "${_verstring}" QUIET PATHS ${CMAKE_CURRENT_BINARY_DIR}/libpsa_install/${TS_ENV}/lib/cmake/libpsa)
+if(NOT libpsa_FOUND)
+	if (CFG_FORCE_PREBUILT_LIBPSA)
+		string(CONCAT _msg "find_package() failed to find the \"libpsa\" package. Please pass -Dlibpsa_ROOT=<full path>"
+							" to cmake, where <full path> is the directory of the libpsaConfig.cmake file, or "
+							" pass -DCMAKE_FIND_ROOT_PATH=<path>, where <path> is the INSTALL_PREFIX used"
+							" when building libpsa. libpsa_ROOT can be set in the environment too."
+						   "If you wish to debug the search process pass -DCMAKE_FIND_DEBUG_MODE=ON to cmake.")
+		message(FATAL_ERROR ${_msg})
+	endif()
+	# Set build type, if a specific value is required. This leaves the default value in the hands of the
+	# libpsa deployment being built.
+	if (DEFINED LIBPSA_BUILD_TYPE)
+		set(_libpsa_build_type_arg "-DCMAKE_BUILD_TYPE=${LIBPSA_BUILD_TYPE}")
+	endif()
+
+	# If not successful, build libpsa as a sub-project.
+	execute_process(COMMAND
+		${CMAKE_COMMAND} -E env "CROSS_COMPILE=${CROSS_COMPILE}"
+		${CMAKE_COMMAND}
+			${_libpsa_build_type_arg}
+			-S ${TS_ROOT}/deployments/libpsa/${TS_ENV}
+			-B ${CMAKE_CURRENT_BINARY_DIR}/libpsa
+		RESULT_VARIABLE
+			_exec_error
+		)
+	unset(_libpsa_build_type_arg)
+	if (NOT _exec_error EQUAL 0)
+		message(FATAL_ERROR "Configuring libpsa failed. ${_exec_error}")
+	endif()
+	execute_process(COMMAND
+		${CMAKE_COMMAND} -E env "CROSS_COMPILE=${CROSS_COMPILE}"
+		${CMAKE_COMMAND}
+			--build ${CMAKE_CURRENT_BINARY_DIR}/libpsa
+			--parallel ${PROCESSOR_COUNT}
+		RESULT_VARIABLE
+			_exec_error
+		)
+	if (NOT _exec_error EQUAL 0)
+		message(FATAL_ERROR "Installing libpsa failed. ${_exec_error}")
+	endif()
+	execute_process(COMMAND
+		${CMAKE_COMMAND} -E env "CROSS_COMPILE=${CROSS_COMPILE}"
+		${CMAKE_COMMAND}
+			--install ${CMAKE_CURRENT_BINARY_DIR}/libpsa
+			--prefix ${CMAKE_CURRENT_BINARY_DIR}/libpsa_install
+		RESULT_VARIABLE
+			_exec_error
+		)
+	if (NOT _exec_error EQUAL 0)
+		message(FATAL_ERROR "Installing libpsa failed. ${_exec_error}")
+	endif()
+
+	install(SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/libpsa/cmake_install.cmake)
+
+	find_package(libpsa "${_verstring}" QUIET REQUIRED PATHS ${CMAKE_CURRENT_BINARY_DIR}/libpsa_install/${TS_ENV}/lib/cmake/libpsa)
+else()
+	message(STATUS "Using prebuilt libpsa from ${libpsa_DIR}")
+endif()
+
+# Cmake will use the same build type of the imported target as used by the main project. If no mapping is configured and
+# the matching build type is not found, cmake will fall back to any build type. Details of the fall back mechanism are not
+# documented.
+# If a mapping is defined, and the imported target does not define the mapped build type, cmake will treat the library
+# as not found.
+#
+# If LIBPSA_BUILD_TYPE is set and the main project wants to use a specific build type, configure build type mapping to
+# only allow using the requested build type.
+if (DEFINED LIBPSA_BUILD_TYPE)
+	set_target_properties(libpsa::psa PROPERTIES
+		MAP_IMPORTED_CONFIG_DEBUG				${LIBPSA_BUILD_TYPE}
+		MAP_IMPORTED_CONFIG_MINSIZEREL			${LIBPSA_BUILD_TYPE}
+		MAP_IMPORTED_CONFIG_MINSIZWITHDEBINFO	${LIBPSA_BUILD_TYPE}
+		MAP_IMPORTED_CONFIG_RELEASE				${LIBPSA_BUILD_TYPE}
+		MAP_IMPORTED_CONFIG_RELWITHDEBINFO		${LIBPSA_BUILD_TYPE}
+		MAP_IMPORTED_CONFIG_DEBUGCOVERAGE		${LIBPSA_BUILD_TYPE}
+	)
+
+	# Do a manual check and issue a better message than the default one.
+	get_property(_libpsa_build_type TARGET libpsa::psa PROPERTY IMPORTED_CONFIGURATIONS)
+	string(TOUPPER ${LIBPSA_BUILD_TYPE} _uc_libpsa_build_type)
+	if(${_uc_libpsa_build_type} IN_LIST _libpsa_build_type)
+	else()
+		message(FATAL_ERROR "Installed libpsa package does not supports required build type ${LIBPSA_BUILD_TYPE}.")
+	endif()
+	unset(_libpsa_build_type)
+	unset(_uc_libpsa_build_type)
+endif()
+
+# libpsa can not be used without libts, so add the needed dependency.
+include(${TS_ROOT}/deployments/libts/libts-import.cmake)
+target_link_libraries(libpsa::psa INTERFACE libts::ts)
diff --git a/deployments/libpsa/libpsa.cmake b/deployments/libpsa/libpsa.cmake
new file mode 100644
index 0000000..d5ca8e5
--- /dev/null
+++ b/deployments/libpsa/libpsa.cmake
@@ -0,0 +1,107 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------------
+#  The base build file shared between deployments of 'libpsa' for different
+#  environments.  libpsa provides an interface for accessing PSA API-s.
+#  Building with each build type results in different postfix for the library.
+#  For details, please refer to deployment.cmake.
+#-------------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------------
+#  Common API version implemented by all libpsa deployments
+#-------------------------------------------------------------------------------
+version_semver_read(FILE "${CMAKE_CURRENT_LIST_DIR}/version.txt"
+					MAJOR _major MINOR _minor PATCH _patch)
+set_target_properties(psa PROPERTIES VERSION "${_major}.${_minor}.${_patch}")
+set_target_properties(psa PROPERTIES SOVERSION "${_major}")
+unset(_major)
+unset(_minor)
+unset(_patch)
+
+add_library(libpsa::psa ALIAS psa)
+
+if (COVERAGE)
+	set(LIBPSA_BUILD_TYPE "DebugCoverage" CACHE STRING "Build type." FORCE)
+endif()
+
+#-------------------------------------------------------------------------------
+#  Use libts for locating and accessing services. An appropriate version of
+#  libts will be imported for the environment in which service tests are
+#  deployed.
+#-------------------------------------------------------------------------------
+include(${TS_ROOT}/deployments/libts/libts-import.cmake)
+target_link_libraries(psa PUBLIC libts::ts)
+
+#-------------------------------------------------------------------------------
+#  Components that are common across all deployments
+#
+#-------------------------------------------------------------------------------
+
+add_components(
+	TARGET "psa"
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS
+		"environments/${TS_ENV}"
+		"components/common/utils"
+		"components/common/trace"
+		"components/common/libpsa"
+		"components/common/tlv"
+		"components/service/common/include"
+		"components/service/common/client"
+		"components/service/crypto/include"
+		"components/service/crypto/client/psa"
+		"components/service/attestation/include"
+		"components/service/attestation/client/psa"
+		"components/service/attestation/client/provision"
+		"components/service/secure_storage/include"
+		"components/service/secure_storage/frontend/psa/its"
+		"components/service/secure_storage/frontend/psa/ps"
+		"components/service/secure_storage/backend/secure_storage_client"
+)
+
+#-------------------------------------------------------------------------------
+#  Define public interfaces for library
+#
+#-------------------------------------------------------------------------------
+
+# Enable exporting interface symbols for library public interface
+target_compile_definitions(psa PRIVATE
+	EXPORT_PUBLIC_INTERFACE_LIBPSA
+	EXPORT_PUBLIC_INTERFACE_PSA_CRYPTO
+	EXPORT_PUBLIC_INTERFACE_PSA_ATTEST
+	EXPORT_PUBLIC_INTERFACE_PSA_ITS
+	EXPORT_PUBLIC_INTERFACE_PSA_PS
+)
+
+#-------------------------------------------------------------------------------
+#  Export the library and the corresponding public interface header files
+#
+#-------------------------------------------------------------------------------
+include(${TS_ROOT}/tools/cmake/common/ExportLibrary.cmake REQUIRED)
+
+# Exports library information in preparation for install
+export_library(
+	TARGET "psa"
+	LIB_NAME "libpsa"
+	PKG_CONFIG_FILE "${CMAKE_CURRENT_LIST_DIR}/libpsaConfig.cmake.in"
+)
+
+install(DIRECTORY "${TS_ROOT}/components/service/crypto/include"
+		DIRECTORY "${TS_ROOT}/components/service/attestation/include"
+		DIRECTORY "${TS_ROOT}/components/service/secure_storage/include"
+		DESTINATION "${TS_ENV}"
+		FILES_MATCHING PATTERN "*.h"
+)
+
+install(FILES "${TS_ROOT}/components/service/common/include/psa/error.h"
+		DESTINATION ${TS_ENV}/include/psa
+)
+
+install(FILES "${TS_ROOT}/components/common/libpsa/libpsa.h"
+		DESTINATION ${TS_ENV}/include
+)
diff --git a/deployments/libpsa/libpsaConfig.cmake.in b/deployments/libpsa/libpsaConfig.cmake.in
new file mode 100644
index 0000000..710411b
--- /dev/null
+++ b/deployments/libpsa/libpsaConfig.cmake.in
@@ -0,0 +1,9 @@
+#
+# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+@PACKAGE_INIT@
+
+include("${CMAKE_CURRENT_LIST_DIR}/libpsaTargets.cmake")
diff --git a/deployments/libpsa/linux-pc/CMakeLists.txt b/deployments/libpsa/linux-pc/CMakeLists.txt
new file mode 100644
index 0000000..7d45a36
--- /dev/null
+++ b/deployments/libpsa/linux-pc/CMakeLists.txt
@@ -0,0 +1,44 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
+include(../../deployment.cmake REQUIRED)
+
+#-------------------------------------------------------------------------------
+#  Options and variables
+#-------------------------------------------------------------------------------
+set(BUILD_SHARED_LIBS On CACHE BOOL "Determine if a shared library is being built.")
+if(NOT BUILD_SHARED_LIBS)
+	message(FATAL_ERROR "Building static library is not yet supported. Call cmake with -DBUILD_SHARED_LIBS=1")
+endif()
+
+#-------------------------------------------------------------------------------
+#  The CMakeLists.txt for building the libpsa deployment for arm-linux
+#
+#  Used for building the libpsa library for the arm-linux environment. Used for
+#  locating and accessing services from a Linux userspace client. Service
+#  instances can be located in any supported secure processing environment.
+#-------------------------------------------------------------------------------
+include(${TS_ROOT}/environments/linux-pc/env_shared_lib.cmake)
+project(psa LANGUAGES CXX C)
+
+add_library(psa)
+
+target_include_directories(psa PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
+
+#-------------------------------------------------------------------------------
+#  For user-specific tracing set to TRACE_LEVEL_NONE and implement:
+#  void trace_puts(const char *str)
+#-------------------------------------------------------------------------------
+
+set(TRACE_PREFIX "LIBPSA" CACHE STRING "Trace prefix")
+set(TRACE_LEVEL "TRACE_LEVEL_DEBUG" CACHE STRING "Trace level")
+#-------------------------------------------------------------------------------
+#  Extend with components that are common across all deployments of
+#  libpsa
+#
+#-------------------------------------------------------------------------------
+include(../libpsa.cmake REQUIRED)
diff --git a/deployments/libpsa/version.txt b/deployments/libpsa/version.txt
new file mode 100644
index 0000000..afaf360
--- /dev/null
+++ b/deployments/libpsa/version.txt
@@ -0,0 +1 @@
+1.0.0
\ No newline at end of file