Add platform specific TRNG driver
Adds platform specific TRNG driver to Crypto opteesp deployment.
Fetches and builds the TZ-TRNG driver from its external
repo and includes it when the crypto/opteesp is built for
the arm/fvp/fvp_base_revc-2xaemv8a platform. Device region
information provided as external configuration data is
not yet integrated to the TRNG hardware is not yet used.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I8a2946643a279dfcc3aff608427c85e674f0e084
diff --git a/platform/drivers/arm/tztrng/driver.cmake b/platform/drivers/arm/tztrng/driver.cmake
new file mode 100644
index 0000000..58d98c8
--- /dev/null
+++ b/platform/drivers/arm/tztrng/driver.cmake
@@ -0,0 +1,68 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Driver source location and version
+set(ARM_TZTRNG_URL "https://github.com/ARM-software/TZ-TRNG.git" CACHE STRING "Arm TZ-TRNG driver repository URL")
+set(ARM_TZTRNG_REFSPEC "1.0.0" CACHE STRING "Arm TZ-TRNG driver git refspec")
+
+# Fetch driver source code from remote repository
+include(FetchContent)
+
+FetchContent_Declare(
+ arm-tztrng
+ GIT_REPOSITORY ${ARM_TZTRNG_URL}
+ GIT_TAG ${ARM_TZTRNG_REFSPEC}
+ GIT_SHALLOW TRUE
+)
+
+# FetchContent_GetProperties exports arm-tztrng_SOURCE_DIR and arm-tztrng_BINARY_DIR variables
+FetchContent_GetProperties(arm-tztrng)
+if(NOT arm-tztrng_POPULATED)
+ message(STATUS "Fetching arm-tztrng")
+ FetchContent_Populate(arm-tztrng)
+endif()
+
+# The driver has no cmake build support so it is necessary to bridge cmake variables to
+# driver build parameters.
+
+# Determine ARCH parameter
+if (CMAKE_SYSTEM_PROCESSOR STREQUAL "arm")
+ set(_arm-tztrng_ARCH "arm64")
+ set(_arm-tztrng_builddir "build-aarch64-linux-gnu")
+else()
+ message(FATAL_ERROR "Only arm builds of TZ-TRNG supported.")
+endif()
+
+# Determine the full path for the generated library and public header
+set(_arm-tztrng_genlib "${arm-tztrng_SOURCE_DIR}/host/src/tztrng_lib/${_arm-tztrng_builddir}/libcc_tztrng.a")
+set(_arm-tztrng_host_incpath "${arm-tztrng_SOURCE_DIR}/host/src/tztrng_lib/include")
+set(_arm-tztrng_shared_incpath "${arm-tztrng_SOURCE_DIR}/shared/hw/include")
+
+# Set HOST_PROJ_ROOT parameter to use TS provided build defines
+set(_arm-tztrng_HOST_PROJ_ROOT ${CMAKE_CURRENT_LIST_DIR})
+
+# Add custom command to build the driver library using the TZ-TRNG provided makefile
+add_custom_command(
+ OUTPUT ${_arm-tztrng_genlib}
+ COMMAND make ARGS "ARCH=${_arm-tztrng_ARCH}"
+ WORKING_DIRECTORY "${arm-tztrng_SOURCE_DIR}/host/src/tztrng_lib/"
+)
+
+# Define target for the library
+add_custom_target(
+ libcc_tztrng
+ DEPENDS ${_arm-tztrng_genlib}
+)
+
+# Add generated library to build target
+target_include_directories(${TGT} PRIVATE "${_arm-tztrng_host_incpath}")
+target_include_directories(${TGT} PRIVATE "${_arm-tztrng_shared_incpath}")
+target_link_libraries(${TGT} PRIVATE ${_arm-tztrng_genlib})
+add_dependencies(${TGT} libcc_tztrng)
+
+# Add adapter to map platform trng interface to tz-trng driver
+target_sources(${TGT} PRIVATE "${CMAKE_CURRENT_LIST_DIR}/tztrng_trng.c")
diff --git a/platform/drivers/arm/tztrng/tztrng_trng.c b/platform/drivers/arm/tztrng/tztrng_trng.c
new file mode 100644
index 0000000..f52eeaa
--- /dev/null
+++ b/platform/drivers/arm/tztrng/tztrng_trng.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <platform/interface/trng.h>
+#include <platform/interface/device_region.h>
+#include <tztrng.h>
+#include <tztrng_defs.h>
+#include <stdlib.h>
+#include <limits.h>
+
+/*
+ * A platform trng driver that uses the tz-trng driver to provide a
+ * hardware entropy source.
+ */
+struct tztrng_instance
+{
+ struct device_region trng_device_region;
+};
+
+
+static int trng_poll(void *context, unsigned char *output, size_t nbyte, size_t *len)
+{
+ struct tztrng_instance *this_instance = (struct tztrng_instance*)context;
+ int status = 0;
+
+ *len = 0;
+
+ if (nbyte >= sizeof(unsigned char)) {
+
+ if (this_instance) {
+
+ status = CC_TrngGetSource((unsigned long)this_instance->trng_device_region.base_addr,
+ output, len, nbyte * CHAR_BIT);
+ }
+ else {
+ /* No context for TRNG instance */
+ /* status = LLF_RND_STATE_PTR_INVALID_ERROR; @todo mbedcrypto segfaults when an error is returned */
+ *len = sizeof(unsigned char);
+ }
+ }
+
+ return status;
+}
+
+int platform_trng_create(struct platform_trng_driver *driver,
+ const struct device_region *device_region)
+{
+ static const struct platform_trng_iface iface = { .poll = trng_poll };
+
+ /*
+ * Default to leaving the driver in a safe but inoperable state.
+ */
+ driver->iface = &iface;
+ driver->context = NULL;
+
+ if (device_region) {
+
+ /*
+ * A device region has been provided, possibly from an external configuation.
+ * Check that it's a sensible size to defend against a bogus configuration.
+ */
+ struct tztrng_instance *new_instance = malloc(sizeof(struct tztrng_instance));
+
+ if (new_instance) {
+
+ new_instance->trng_device_region = *device_region;
+ driver->context = new_instance;
+ }
+ }
+
+ return 0;
+}
+
+void platform_trng_destroy(struct platform_trng_driver *driver)
+{
+ free(driver->context);
+}
diff --git a/platform/drivers/mock/mock_entropy.c b/platform/drivers/mock/mock_entropy.c
deleted file mode 100644
index 56e9054..0000000
--- a/platform/drivers/mock/mock_entropy.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#include <platform/interface/entropy.h>
-
-/*
- * A platform entropy driver that provides a mock implementation that
- * always returns a fixed value. Intended for test purposes only.
- */
-static int mock_poll(void *context, unsigned char *output, size_t nbyte, size_t *len)
-{
- (void)context;
- (void)output;
-
- *len = 0;
-
- if (nbyte < sizeof(unsigned char) )
- return 0;
-
- *len = sizeof(unsigned char);
-
- return 0;
-}
-
-int ts_plat_entropy_create(struct ts_plat_entropy_driver *driver, void *config)
-{
- static const struct ts_plat_entropy_iface iface = { .poll = mock_poll };
-
- (void)config;
-
- driver->context = NULL;
- driver->iface = &iface;
-
- return 0;
-}
-
-void ts_plat_entropy_destroy(struct ts_plat_entropy_driver *driver)
-{
- (void)driver;
-}
diff --git a/platform/drivers/mock/mock_trng.c b/platform/drivers/mock/mock_trng.c
new file mode 100644
index 0000000..24b14c0
--- /dev/null
+++ b/platform/drivers/mock/mock_trng.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <platform/interface/trng.h>
+
+/*
+ * A platform trng driver that provides a mock implementation that
+ * always returns a fixed value. Intended for test purposes only.
+ */
+static int mock_poll(void *context, unsigned char *output, size_t nbyte, size_t *len)
+{
+ (void)context;
+ (void)output;
+
+ *len = 0;
+
+ if (nbyte < sizeof(unsigned char) )
+ return 0;
+
+ *len = sizeof(unsigned char);
+
+ return 0;
+}
+
+int platform_trng_create(struct platform_trng_driver *driver,
+ const struct device_region *device_region)
+{
+ static const struct platform_trng_iface iface = { .poll = mock_poll };
+
+ (void)device_region;
+
+ driver->context = NULL;
+ driver->iface = &iface;
+
+ return 0;
+}
+
+void platform_trng_destroy(struct platform_trng_driver *driver)
+{
+ (void)driver;
+}
diff --git a/platform/interface/device_region.h b/platform/interface/device_region.h
new file mode 100644
index 0000000..1ad1721
--- /dev/null
+++ b/platform/interface/device_region.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_PLATFORM_INTERFACE_DEVICE_REGION_H
+#define TS_PLATFORM_INTERFACE_DEVICE_REGION_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Defines a structure for describing a contiguous IO memory region
+ * and other configuration information about a peripheral. This may be based on
+ * buildtime or runtime configuration information e.g. from device tree.
+ */
+struct device_region
+{
+ char dev_class[16]; /**< Identifier for class of device e.g. 'trng' */
+ int dev_instance; /**< Instance of the class of device on a platform */
+ uint8_t *base_addr; /**< Base address or region */
+ size_t io_region_size; /**< Size of I/O region in bytes */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TS_PLATFORM_INTERFACE_DEVICE_REGION_H */
diff --git a/platform/interface/entropy.h b/platform/interface/entropy.h
deleted file mode 100644
index d81cd60..0000000
--- a/platform/interface/entropy.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef TS_PLATFORM_INTERFACE_ENTROPY_H
-#define TS_PLATFORM_INTERFACE_ENTROPY_H
-
-/*
- * Interface definintion for a platform entropy driver. A platform provider will
- * provide concrete implementations of this interface for each alternative
- * implementation supported.
- */
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Virtual interface for a platform entropy driver. A platform will provide
- * one or more concrete implementations of this interface.
- */
-struct ts_plat_entropy_iface
-{
- /**
- * \brief Poll for bytes of entropy from a platform entropy source
- *
- * \param context Platform driver context
- * \param output Buffer for output
- * \param nbyte Desired number of bytes
- * \param len The number of bytes returned (could be zero)
- *
- * \return 0 if successful.
- */
- int (*poll)(void *context, unsigned char *output, size_t nbyte, size_t *len);
-};
-
-/*
- * A platform entropy driver instance.
- */
-struct ts_plat_entropy_driver
-{
- void *context; /**< Opaque driver context */
- const struct ts_plat_entropy_iface *iface; /**< Interface methods */
-};
-
-/**
- * \brief Factory method to construct a platform specific entropy driver
- *
- * \param driver Pointer to driver structure to initialize on construction.
- * \param config Driver specific configuration or NULL if none.
- *
- * \return 0 if successful.
- */
-int ts_plat_entropy_create(struct ts_plat_entropy_driver *driver, void *config);
-
-/**
- * \brief Destroy a driver constructed using the factory method
- *
- * \param driver Pointer to driver structure for constructed driver.
- */
-void ts_plat_entropy_destroy(struct ts_plat_entropy_driver *driver);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* TS_PLATFORM_INTERFACE_ENTROPY_H */
diff --git a/platform/interface/trng.h b/platform/interface/trng.h
new file mode 100644
index 0000000..9c24581
--- /dev/null
+++ b/platform/interface/trng.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_PLATFORM_INTERFACE_TRNG_H
+#define TS_PLATFORM_INTERFACE_TRNG_H
+
+/*
+ * Interface definintion for a platform trng driver. A platform provider will
+ * provide concrete implementations of this interface for each alternative
+ * implementation supported.
+ */
+#include <stddef.h>
+#include "device_region.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Virtual interface for a platform trng driver. A platform will provide
+ * one or more concrete implementations of this interface.
+ */
+struct platform_trng_iface
+{
+ /**
+ * \brief Poll for bytes of entropy from a platform trng
+ *
+ * \param context Platform driver context
+ * \param output Buffer for output
+ * \param nbyte Desired number of bytes
+ * \param len The number of bytes returned (could be zero)
+ *
+ * \return 0 if successful.
+ */
+ int (*poll)(void *context, unsigned char *output, size_t nbyte, size_t *len);
+};
+
+/*
+ * A platform trng driver instance.
+ */
+struct platform_trng_driver
+{
+ void *context; /**< Opaque driver context */
+ const struct platform_trng_iface *iface; /**< Interface methods */
+};
+
+/**
+ * \brief Factory method to construct a platform specific trng driver
+ *
+ * \param driver Pointer to driver structure to initialize on construction.
+ * \param device_region Pointer a device region object or NULL if none.
+ *
+ * \return 0 if successful.
+ */
+int platform_trng_create(struct platform_trng_driver *driver,
+ const struct device_region *device_region);
+
+/**
+ * \brief Destroy a driver constructed using the factory method
+ *
+ * \param driver Pointer to driver structure for constructed driver.
+ */
+void platform_trng_destroy(struct platform_trng_driver *driver);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TS_PLATFORM_INTERFACE_TRNG_H */
diff --git a/platform/providers/arm/fvp/fvp_base_revc-2xaemv8a/platform.cmake b/platform/providers/arm/fvp/fvp_base_revc-2xaemv8a/platform.cmake
index 86686e3..cb01389 100644
--- a/platform/providers/arm/fvp/fvp_base_revc-2xaemv8a/platform.cmake
+++ b/platform/providers/arm/fvp/fvp_base_revc-2xaemv8a/platform.cmake
@@ -13,6 +13,10 @@
PROPERTY TS_PLATFORM_DRIVER_DEPENDENCIES
)
-target_sources(${TGT} PRIVATE
- "${TS_ROOT}/platform/drivers/mock/mock_entropy.c"
-)
+#-------------------------------------------------------------------------------
+# Map platform dependencies to suitable drivers for this platform
+#
+#-------------------------------------------------------------------------------
+if ("trng" IN_LIST _platform_driver_dependencies)
+ include(${TS_ROOT}/platform/drivers/arm/tztrng/driver.cmake)
+endif()
diff --git a/platform/providers/ts/mock/platform.cmake b/platform/providers/ts/mock/platform.cmake
index 601974a..a4d8d34 100644
--- a/platform/providers/ts/mock/platform.cmake
+++ b/platform/providers/ts/mock/platform.cmake
@@ -16,6 +16,7 @@
PROPERTY TS_PLATFORM_DRIVER_DEPENDENCIES
)
-target_sources(${TGT} PRIVATE
- "${TS_ROOT}/platform/drivers/mock/mock_entropy.c"
-)
+# Map platform dependencies to suitable drivers for this platform
+if ("trng" IN_LIST _platform_driver_dependencies)
+ target_sources(${TGT} PRIVATE "${TS_ROOT}/platform/drivers/mock/mock_trng.c")
+endif()