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/components/common/libpsa/component.cmake b/components/common/libpsa/component.cmake
new file mode 100644
index 0000000..08e4748
--- /dev/null
+++ b/components/common/libpsa/component.cmake
@@ -0,0 +1,16 @@
+#-------------------------------------------------------------------------------
+# 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}/libpsa-attestation.c"
+ "${CMAKE_CURRENT_LIST_DIR}/libpsa-crypto.c"
+ "${CMAKE_CURRENT_LIST_DIR}/libpsa-its.c"
+ "${CMAKE_CURRENT_LIST_DIR}/libpsa-ps.c"
+ )
diff --git a/components/common/libpsa/libpsa-attestation.c b/components/common/libpsa/libpsa-attestation.c
new file mode 100644
index 0000000..9e795a6
--- /dev/null
+++ b/components/common/libpsa/libpsa-attestation.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <protocols/rpc/common/packed-c/encoding.h>
+#include <psa/initial_attestation.h>
+#include <service/attestation/client/provision/attest_provision_client.h>
+#include <service/attestation/client/psa/iat_client.h>
+#include <service_locator.h>
+#include <stdio.h>
+
+#include "libpsa.h"
+#include "trace.h"
+
+static struct rpc_caller_session *rpc_session;
+static struct service_context *attestation_service_context;
+
+LIBPSA_EXPORTED psa_status_t libpsa_init_attestation_context(const char *service_name)
+{
+ psa_status_t result = PSA_ERROR_GENERIC_ERROR;
+ psa_status_t provision_result = PSA_ERROR_GENERIC_ERROR;
+
+ if (rpc_session || attestation_service_context) {
+ EMSG("The client is already initialized\n");
+ return result;
+ }
+
+ service_locator_init();
+
+ attestation_service_context = service_locator_query(service_name);
+
+ if (!attestation_service_context) {
+ EMSG("Failed to discover service\n");
+ return result;
+ }
+
+ rpc_session = service_context_open(attestation_service_context);
+
+ if (!rpc_session) {
+ EMSG("Failed to open rpc session\n");
+ libpsa_deinit_attestation_context();
+ return result;
+ }
+
+ result = psa_iat_client_init(rpc_session);
+
+ if (result) {
+ EMSG("psa_iat_client_init failed\n");
+ return result;
+ }
+
+ provision_result = attest_provision_client_init(rpc_session);
+
+ /* If external IAK is used this call can fail */
+ if (provision_result)
+ EMSG(
+ "attest_provision_client_init failed. Are you using external IAK key?\n");
+
+ return result;
+}
+
+LIBPSA_EXPORTED void libpsa_deinit_attestation_context(void)
+{
+ psa_iat_client_deinit();
+ attest_provision_client_deinit();
+
+ if (attestation_service_context && rpc_session) {
+ service_context_close(attestation_service_context, rpc_session);
+ rpc_session = NULL;
+ }
+
+ if (attestation_service_context) {
+ service_context_relinquish(attestation_service_context);
+ attestation_service_context = NULL;
+ }
+}
diff --git a/components/common/libpsa/libpsa-crypto.c b/components/common/libpsa/libpsa-crypto.c
new file mode 100644
index 0000000..4a3a10e
--- /dev/null
+++ b/components/common/libpsa/libpsa-crypto.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <protocols/rpc/common/packed-c/encoding.h>
+#include <service/crypto/client/psa/psa_crypto_client.h>
+#include <service_locator.h>
+#include <stdio.h>
+
+#include "libpsa.h"
+#include "trace.h"
+
+static struct rpc_caller_session *rpc_session;
+static struct service_context *crypto_service_context;
+
+LIBPSA_EXPORTED psa_status_t libpsa_init_crypto_context(const char *service_name)
+{
+ psa_status_t result = PSA_ERROR_GENERIC_ERROR;
+
+ if (rpc_session || crypto_service_context) {
+ EMSG("The client is already initialized\n");
+ return result;
+ }
+
+ service_locator_init();
+
+ crypto_service_context = service_locator_query(service_name);
+
+ if (!crypto_service_context) {
+ EMSG("Failed to discover service\n");
+ return result;
+ }
+
+ rpc_session = service_context_open(crypto_service_context);
+
+ if (!rpc_session) {
+ EMSG("Failed to open rpc session\n");
+ libpsa_deinit_crypto_context();
+ return result;
+ }
+
+ result = psa_crypto_client_init(rpc_session);
+
+ if (result)
+ EMSG("psa_crypto_client_init failed\n");
+
+ return result;
+}
+
+LIBPSA_EXPORTED void libpsa_deinit_crypto_context(void)
+{
+ psa_crypto_client_deinit();
+
+ if (crypto_service_context && rpc_session) {
+ service_context_close(crypto_service_context, rpc_session);
+ rpc_session = NULL;
+ }
+
+ if (crypto_service_context) {
+ service_context_relinquish(crypto_service_context);
+ crypto_service_context = NULL;
+ }
+}
diff --git a/components/common/libpsa/libpsa-its.c b/components/common/libpsa/libpsa-its.c
new file mode 100644
index 0000000..3915bfc
--- /dev/null
+++ b/components/common/libpsa/libpsa-its.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <protocols/rpc/common/packed-c/encoding.h>
+#include <service/secure_storage/backend/secure_storage_client/secure_storage_client.h>
+#include <service/secure_storage/frontend/psa/its/its_frontend.h>
+#include <service_locator.h>
+#include <stdio.h>
+
+#include "libpsa.h"
+#include "trace.h"
+
+static struct rpc_caller_session *rpc_session;
+static struct service_context *its_service_context;
+static struct secure_storage_client its_storage_client;
+
+LIBPSA_EXPORTED psa_status_t libpsa_init_its_context(const char *service_name)
+{
+ psa_status_t result = PSA_ERROR_GENERIC_ERROR;
+
+ if (rpc_session || its_service_context) {
+ EMSG("The client is already initialized\n");
+ return result;
+ }
+
+ service_locator_init();
+
+ its_service_context = service_locator_query(service_name);
+
+ if (!its_service_context) {
+ EMSG("Failed to discover service\n");
+ return result;
+ }
+
+ rpc_session = service_context_open(its_service_context);
+
+ if (!rpc_session) {
+ EMSG("Failed to open rpc session\n");
+ libpsa_deinit_its_context();
+ return result;
+ }
+
+ struct storage_backend *its_storage_backend =
+ secure_storage_client_init(&its_storage_client, rpc_session);
+
+ if (!its_storage_backend) {
+ EMSG("Failed to initialize storage backend\n");
+ libpsa_deinit_its_context();
+ return result;
+ }
+
+ result = psa_its_frontend_init(its_storage_backend);
+
+ return result;
+}
+
+LIBPSA_EXPORTED void libpsa_deinit_its_context(void)
+{
+ psa_its_frontend_init(NULL);
+ secure_storage_client_deinit(&its_storage_client);
+
+ if (its_service_context && rpc_session) {
+ service_context_close(its_service_context, rpc_session);
+ rpc_session = NULL;
+ }
+
+ if (its_service_context) {
+ service_context_relinquish(its_service_context);
+ its_service_context = NULL;
+ }
+}
diff --git a/components/common/libpsa/libpsa-ps.c b/components/common/libpsa/libpsa-ps.c
new file mode 100644
index 0000000..01d41d1
--- /dev/null
+++ b/components/common/libpsa/libpsa-ps.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <protocols/rpc/common/packed-c/encoding.h>
+#include <service/secure_storage/backend/secure_storage_client/secure_storage_client.h>
+#include <service/secure_storage/frontend/psa/ps/ps_frontend.h>
+#include <service_locator.h>
+#include <stdio.h>
+
+#include "libpsa.h"
+#include "trace.h"
+
+static struct rpc_caller_session *rpc_session;
+static struct service_context *ps_service_context;
+static struct secure_storage_client ps_storage_client;
+
+LIBPSA_EXPORTED psa_status_t libpsa_init_ps_context(const char *service_name)
+{
+ psa_status_t result = PSA_ERROR_GENERIC_ERROR;
+
+ if (rpc_session || ps_service_context) {
+ EMSG("The client is already initialized\n");
+ return result;
+ }
+
+ service_locator_init();
+
+ ps_service_context = service_locator_query(service_name);
+
+ if (!ps_service_context) {
+ EMSG("Failed to discover service\n");
+ return result;
+ }
+
+ rpc_session = service_context_open(ps_service_context);
+
+ if (!rpc_session) {
+ EMSG("Failed to open rpc session\n");
+ libpsa_deinit_ps_context();
+ return result;
+ }
+
+ struct storage_backend *ps_storage_backend =
+ secure_storage_client_init(&ps_storage_client, rpc_session);
+
+ if (!ps_storage_backend) {
+ EMSG("Failed to initialize storage backend\n");
+ libpsa_deinit_ps_context();
+ return result;
+ }
+
+ result = psa_ps_frontend_init(ps_storage_backend);
+
+ return result;
+}
+
+LIBPSA_EXPORTED void libpsa_deinit_ps_context(void)
+{
+ psa_ps_frontend_init(NULL);
+ secure_storage_client_deinit(&ps_storage_client);
+
+ if (ps_service_context && rpc_session) {
+ service_context_close(ps_service_context, rpc_session);
+ rpc_session = NULL;
+ }
+
+ if (ps_service_context) {
+ service_context_relinquish(ps_service_context);
+ ps_service_context = NULL;
+ }
+}
diff --git a/components/common/libpsa/libpsa.h b/components/common/libpsa/libpsa.h
new file mode 100644
index 0000000..e5a6fa0
--- /dev/null
+++ b/components/common/libpsa/libpsa.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "psa/crypto_types.h"
+#include "psa/initial_attestation.h"
+#include "psa/internal_trusted_storage.h"
+#include "psa/protected_storage.h"
+
+#ifndef LIBPSA_H
+#define LIBPSA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The functions may be exported as a public interface to
+ * a shared library.
+ */
+#ifdef EXPORT_PUBLIC_INTERFACE_LIBPSA
+#define LIBPSA_EXPORTED __attribute__((__visibility__("default")))
+#else
+#define LIBPSA_EXPORTED
+#endif
+
+LIBPSA_EXPORTED psa_status_t libpsa_init_crypto_context(const char *service_name);
+LIBPSA_EXPORTED void libpsa_deinit_crypto_context(void);
+
+LIBPSA_EXPORTED psa_status_t libpsa_init_attestation_context(const char *service_name);
+LIBPSA_EXPORTED void libpsa_deinit_attestation_context(void);
+
+LIBPSA_EXPORTED psa_status_t libpsa_init_its_context(const char *service_name);
+LIBPSA_EXPORTED void libpsa_deinit_its_context(void);
+
+LIBPSA_EXPORTED psa_status_t libpsa_init_ps_context(const char *service_name);
+LIBPSA_EXPORTED void libpsa_deinit_ps_context(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBPSA_H */