Allow alternative backends for crypto provider
The crypto service provider is refactored to make it easy to add
alternative backends. There is still only a single backend that
uses the mbedcrypto library from MbedTLS. However, all dependencies
from the crypto provider on mbedcrypto have been removed, allowing
the crypto provider to be used with alternative implementations
of the PSA Crypto API.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: Ic5d1d9d47d149b634d147712749fdee48f260d85
diff --git a/components/service/crypto/backend/mbedcrypto/component.cmake b/components/service/crypto/backend/mbedcrypto/component.cmake
new file mode 100644
index 0000000..4b531b7
--- /dev/null
+++ b/components/service/crypto/backend/mbedcrypto/component.cmake
@@ -0,0 +1,26 @@
+#-------------------------------------------------------------------------------
+# 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}/mbedcrypto_backend.c"
+ )
+
+# Force use of the mbed crypto configuration required by the crypto service
+# provider. This configuration includes enabling the use of the PSA ITS API
+# for persistent key storage which is realised by the its client adapter
+# for the secure storage service.
+set(MBEDTLS_USER_CONFIG_FILE
+ "${CMAKE_CURRENT_LIST_DIR}/config_mbedtls_user.h"
+ CACHE STRING "Configuration file for Mbed TLS" FORCE)
+
+set(MBEDTLS_EXTRA_INCLUDES
+ "${TS_ROOT}/components/service/common/include"
+ "${TS_ROOT}/components/service/secure_storage/include"
+ CACHE STRING "PSA ITS for Mbed TLS" FORCE)
diff --git a/components/service/crypto/backend/mbedcrypto/config_mbedtls_user.h b/components/service/crypto/backend/mbedcrypto/config_mbedtls_user.h
new file mode 100644
index 0000000..e0700b1
--- /dev/null
+++ b/components/service/crypto/backend/mbedcrypto/config_mbedtls_user.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CONFIG_MBEDTLS_USER_H
+#define CONFIG_MBEDTLS_USER_H
+
+/* Configuration for crypto provider component */
+
+#define MBEDTLS_NO_UDBL_DIVISION
+#undef MBEDTLS_HAVE_TIME
+#undef MBEDTLS_HAVE_TIME_DATE
+#define MBEDTLS_ENTROPY_HARDWARE_ALT
+#undef MBEDTLS_FS_IO
+#define MBEDTLS_NO_PLATFORM_ENTROPY
+#undef MBEDTLS_SELF_TEST
+#undef MBEDTLS_AESNI_C
+#define MBEDTLS_CMAC_C
+#undef MBEDTLS_PADLOCK_C
+#undef MBEDTLS_PLATFORM_C
+#undef MBEDTLS_PSA_ITS_FILE_C
+#undef MBEDTLS_TIMING_C
+
+#endif /* CONFIG_MBEDTLS_USER_H */
diff --git a/components/service/crypto/backend/mbedcrypto/mbedcrypto_backend.c b/components/service/crypto/backend/mbedcrypto/mbedcrypto_backend.c
new file mode 100644
index 0000000..d9596bb
--- /dev/null
+++ b/components/service/crypto/backend/mbedcrypto/mbedcrypto_backend.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <service/crypto/backend/mbedcrypto/trng_adapter/trng_adapter.h>
+#include <service/secure_storage/frontend/psa/its/its_frontend.h>
+#include <psa/crypto.h>
+
+
+psa_status_t mbedcrypto_backend_init(struct storage_backend *storage_backend,
+ int trng_instance_num)
+{
+ psa_status_t status;
+
+ status = trng_adapter_init(trng_instance_num);
+
+ if (status == PSA_SUCCESS)
+ status = psa_its_frontend_init(storage_backend);
+
+ if (status == PSA_SUCCESS)
+ status = psa_crypto_init();
+
+ return status;
+}
+
+void mbedcrypto_backend_deinit(void)
+{
+ trng_adapter_deinit();
+}
diff --git a/components/service/crypto/backend/mbedcrypto/mbedcrypto_backend.h b/components/service/crypto/backend/mbedcrypto/mbedcrypto_backend.h
new file mode 100644
index 0000000..28bd2e9
--- /dev/null
+++ b/components/service/crypto/backend/mbedcrypto/mbedcrypto_backend.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MBEDCRYPTO_BACKEND_H
+#define MBEDCRYPTO_BACKEND_H
+
+#include <stdbool.h>
+#include <psa/error.h>
+#include <service/secure_storage/backend/storage_backend.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Initialize the mbedcrypto based backend
+ *
+ * Initializes a crypto backend that uses the mbedcrypto library built by
+ * MbedTLS to realize the PSA crypto API used by the crypto service proviser.
+ *
+ * \param[in] storage_backend The storage backend to use for persistent keys
+ * \param[in] trng_instance_num The TRNG hardware instance number to use
+ *
+ * \return PSA_SUCCESS if backend initialized successfully
+ */
+psa_status_t mbedcrypto_backend_init(struct storage_backend *storage_backend,
+ int trng_instance_num);
+
+/**
+ * \brief Clean-up to free any resource used by the backend
+ */
+void mbedcrypto_backend_deinit(void);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* MBEDCRYPTO_BACKEND_H */
diff --git a/components/service/crypto/backend/mbedcrypto/trng_adapter/linux/component.cmake b/components/service/crypto/backend/mbedcrypto/trng_adapter/linux/component.cmake
new file mode 100644
index 0000000..89056e2
--- /dev/null
+++ b/components/service/crypto/backend/mbedcrypto/trng_adapter/linux/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# 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}/linux_trng_adapter.c"
+ )
diff --git a/components/service/crypto/backend/mbedcrypto/trng_adapter/linux/linux_trng_adapter.c b/components/service/crypto/backend/mbedcrypto/trng_adapter/linux/linux_trng_adapter.c
new file mode 100644
index 0000000..25aab06
--- /dev/null
+++ b/components/service/crypto/backend/mbedcrypto/trng_adapter/linux/linux_trng_adapter.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <mbedtls/entropy.h>
+#include <mbedtls/entropy_poll.h>
+#include <service/crypto/backend/mbedcrypto/trng_adapter/trng_adapter.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <errno.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+/*
+ * An mbed tls compatibile hardware entropy source that adapts the mbed tls hardware poll
+ * function to the Linux getrandom system call.
+ */
+
+int trng_adapter_init(int instance)
+{
+ (void)instance;
+}
+
+void trng_adapter_deinit()
+{
+
+}
+
+int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen)
+{
+ int status = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
+ *olen = 0;
+
+ int num_output = syscall(SYS_getrandom, output, len, 0);
+
+ if (num_output >= 0) {
+
+ *olen = num_output;
+ status = 0;
+ }
+
+ return status;
+}
diff --git a/components/service/crypto/backend/mbedcrypto/trng_adapter/platform/component.cmake b/components/service/crypto/backend/mbedcrypto/trng_adapter/platform/component.cmake
new file mode 100644
index 0000000..575ac22
--- /dev/null
+++ b/components/service/crypto/backend/mbedcrypto/trng_adapter/platform/component.cmake
@@ -0,0 +1,17 @@
+#-------------------------------------------------------------------------------
+# 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}/platform_trng_adapter.c"
+ )
+
+set_property(TARGET ${TGT} APPEND_STRING PROPERTY TS_PLATFORM_DRIVER_DEPENDENCIES
+ "trng"
+ )
diff --git a/components/service/crypto/backend/mbedcrypto/trng_adapter/platform/platform_trng_adapter.c b/components/service/crypto/backend/mbedcrypto/trng_adapter/platform/platform_trng_adapter.c
new file mode 100644
index 0000000..f05fe63
--- /dev/null
+++ b/components/service/crypto/backend/mbedcrypto/trng_adapter/platform/platform_trng_adapter.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <mbedtls/entropy.h>
+#include <platform/interface/trng.h>
+#include <service/crypto/backend/mbedcrypto/trng_adapter/trng_adapter.h>
+#include <config/interface/config_store.h>
+#include <psa/error.h>
+#include <stddef.h>
+
+/*
+ * An mbed tls compatibile hardware entropy source that adapts the mbed tls hardware poll
+ * function to a platform trng driver. The actual realization of the driver
+ * will depend on the platform selected at build-time.
+ */
+static struct platform_trng_driver driver = {0};
+
+int trng_adapter_init(int instance)
+{
+ int status = PSA_STATUS_HARDWARE_FAILURE;
+ struct device_region device_region;
+
+ if (config_store_query(CONFIG_CLASSIFIER_DEVICE_REGION,
+ "trng", instance,
+ &device_region, sizeof(device_region))) {
+
+ status = platform_trng_create(&driver, &device_region);
+ }
+
+ return status;
+}
+
+void trng_adapter_deinit()
+{
+ platform_trng_destroy(&driver);
+
+ driver.iface = NULL;
+ driver.context = NULL;
+}
+
+int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen)
+{
+ int status = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
+ *olen = 0;
+
+ if (driver.iface) {
+
+ status = driver.iface->poll(driver.context, output, len, olen);
+ }
+
+ return status;
+}
diff --git a/components/service/crypto/backend/mbedcrypto/trng_adapter/test/component.cmake b/components/service/crypto/backend/mbedcrypto/trng_adapter/test/component.cmake
new file mode 100644
index 0000000..4aa4321
--- /dev/null
+++ b/components/service/crypto/backend/mbedcrypto/trng_adapter/test/component.cmake
@@ -0,0 +1,14 @@
+#-------------------------------------------------------------------------------
+# 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}/trng_env_tests.c"
+ )
+
diff --git a/components/service/crypto/backend/mbedcrypto/trng_adapter/test/trng_env_tests.c b/components/service/crypto/backend/mbedcrypto/trng_adapter/test/trng_env_tests.c
new file mode 100644
index 0000000..2b002d8
--- /dev/null
+++ b/components/service/crypto/backend/mbedcrypto/trng_adapter/test/trng_env_tests.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <service/test_runner/provider/backend/simple_c/simple_c_test_runner.h>
+#include <service/crypto/backend/mbedcrypto/trng_adapter/trng_adapter.h>
+#include <string.h>
+#include <stddef.h>
+
+/**
+ * Tests the hw TRNG provided by the environment or underlying platform.
+ */
+
+/* Declaration for mbedtls function to avoid complicated conditional
+ * compilation problems in mbedtls header files.
+ */
+int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen);
+
+/*
+ * Check the trng create/destroy lifecycle
+ */
+static bool check_trng_lifecycle(struct test_failure *failure)
+{
+ int status = trng_adapter_init(0);
+ failure->info = status;
+ trng_adapter_deinit();
+
+ return (status == 0);
+}
+
+/*
+ * Check the trng hardware poll function used by mbedcrypto to
+ * access a hardware entropy source,
+ */
+static bool check_hw_poll(struct test_failure *failure)
+{
+ bool passed;
+ uint8_t output[2][10];
+ size_t expected_len = 10;
+
+ passed = (trng_adapter_init(0) == 0);
+
+ memset(output, 0, sizeof(output));
+
+ for (int round = 0; passed && round < 5; ++round) {
+
+ size_t olen;
+ int status = mbedtls_hardware_poll(NULL, &output[round & 1][0], expected_len, &olen);
+
+ /* Check results of call - expect a different byte stream on each call */
+ passed = passed && (status == 0);
+ passed = passed && (olen == expected_len);
+ passed = passed && (memcmp(&output[round & 1][0], &output[!(round & 1)][0], expected_len) != 0);
+
+ /* capture most recent output in case of failure */
+ memcpy(&failure->info, &output[round & 1][0], sizeof(failure->info));
+ }
+
+ trng_adapter_deinit();
+
+ return passed;
+}
+
+/**
+ * Define an register test group
+ */
+void trng_env_tests_register(void)
+{
+ static const struct simple_c_test_case trng_env_tests[] = {
+ {.name = "TrngLifecycle", .test_func = check_trng_lifecycle},
+ {.name = "TrngHwPoll", .test_func = check_hw_poll}
+ };
+
+ static const struct simple_c_test_group trng_env_test_group =
+ {
+ .group = "TrngEnvTests",
+ .num_test_cases = sizeof(trng_env_tests)/sizeof(struct simple_c_test_case),
+ .test_cases = trng_env_tests
+ };
+
+ simple_c_test_runner_register_group(&trng_env_test_group);
+}
diff --git a/components/service/crypto/backend/mbedcrypto/trng_adapter/test/trng_env_tests.h b/components/service/crypto/backend/mbedcrypto/trng_adapter/test/trng_env_tests.h
new file mode 100644
index 0000000..36c4103
--- /dev/null
+++ b/components/service/crypto/backend/mbedcrypto/trng_adapter/test/trng_env_tests.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TRNG_ENV_TESTS_H
+#define TRNG_ENV_TESTS_H
+
+void trng_env_tests_register(void);
+
+#endif /* TRNG_ENV_TESTS_H */
diff --git a/components/service/crypto/backend/mbedcrypto/trng_adapter/trng_adapter.h b/components/service/crypto/backend/mbedcrypto/trng_adapter/trng_adapter.h
new file mode 100644
index 0000000..f1e7254
--- /dev/null
+++ b/components/service/crypto/backend/mbedcrypto/trng_adapter/trng_adapter.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef MBED_CRYPTO_TRNG_ADAPTER_H
+#define MBED_CRYPTO_TRNG_ADAPTER_H
+
+/*
+ * The build-time configuration of Mbed Crypto creates a dependency on a
+ * hardware-based entropy source that provides an implementation of the
+ * mbedtls_hardware_poll function. Depending on the environment, this
+ * could be realized in different ways e.g. via a native environment
+ * specific service or using a platform specific driver. This header
+ * file defines the common interface for initializing and configuring
+ * the adapter that provides the entropy source.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Initialise the trng adapter
+ *
+ * \param instance Deployment specific trng instance.
+ *
+ * \return 0 if successful.
+ */
+int trng_adapter_init(int instance);
+
+/**
+ * \brief Cleans-up the trng adapter.
+ */
+void trng_adapter_deinit();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* MBED_CRYPTO_TRNG_ADAPTER_H */