aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/runtime_services/trng.h79
-rw-r--r--lib/trng/trng.c61
-rw-r--r--tftf/framework/framework.mk3
-rw-r--r--tftf/tests/runtime_services/standard_service/trng/api_tests/test_trng.c150
-rw-r--r--tftf/tests/tests-standard.mk3
-rw-r--r--tftf/tests/tests-standard.xml4
-rw-r--r--tftf/tests/tests-trng.mk7
-rw-r--r--tftf/tests/tests-trng.xml25
8 files changed, 329 insertions, 3 deletions
diff --git a/include/runtime_services/trng.h b/include/runtime_services/trng.h
new file mode 100644
index 000000000..010362468
--- /dev/null
+++ b/include/runtime_services/trng.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Definitions related to the True Random Number Generator (TRNG)
+ * as per the SMC Calling Convention.
+ *
+ * TRNG calls are a subset of the Standard Service Calls.
+ */
+
+#ifndef __TRNG_H__
+#define __TRNG_H__
+
+#ifndef __ASSEMBLY__
+#include <platform_def.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <tftf_lib.h>
+#endif
+
+/*******************************************************************************
+ * Macro to create the array entry for trng_functions[]
+ ******************************************************************************/
+#define DEFINE_TRNG_FUNC(_func_id, _mandatory) \
+ { SMC_##_func_id, _mandatory, "SMC_" # _func_id }
+
+/*******************************************************************************
+ * Defines for runtime services function ids
+ ******************************************************************************/
+#define SMC_TRNG_VERSION 0x84000050
+#define SMC_TRNG_FEATURES 0x84000051
+#define SMC_TRNG_UUID 0x84000052
+
+#ifndef __aarch64__
+#define SMC_TRNG_RND 0x84000053
+#else
+#define SMC_TRNG_RND 0xc4000053
+#endif
+
+/*
+ * Number of TRNG calls defined in the TRNG specification.
+ */
+#define TRNG_NUM_CALLS 5
+
+#ifndef __ASSEMBLY__
+typedef struct {
+ uint32_t id;
+ bool mandatory;
+ const char *str;
+} trng_function_t;
+
+extern const trng_function_t trng_functions[TRNG_NUM_CALLS];
+int32_t tftf_trng_version(void);
+bool tftf_trng_feature_implemented(uint32_t id);
+smc_ret_values tftf_trng_uuid(void);
+smc_ret_values tftf_trng_rnd(uint32_t nbits);
+#endif /* __ASSEMBLY__ */
+
+
+/*******************************************************************************
+ * TRNG version
+ ******************************************************************************/
+#define TRNG_MAJOR_VER_SHIFT (16)
+#define TRNG_VERSION(major, minor) ((major << TRNG_MAJOR_VER_SHIFT) \
+ | minor)
+
+/*******************************************************************************
+ * TRNG error codes
+ ******************************************************************************/
+#define TRNG_E_SUCCESS (0)
+#define TRNG_E_NOT_SUPPORTED (-1)
+#define TRNG_E_INVALID_PARAMS (-2)
+#define TRNG_E_NO_ENTOPY (-3)
+#define TRNG_E_NOT_IMPLEMENTED (-4)
+
+#endif /* __TRNG_H__ */
diff --git a/lib/trng/trng.c b/lib/trng/trng.c
new file mode 100644
index 000000000..976d26e22
--- /dev/null
+++ b/lib/trng/trng.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <debug.h>
+#include <drivers/arm/arm_gic.h>
+#include <irq.h>
+#include <platform.h>
+#include <trng.h>
+#include <sgi.h>
+#include <tftf.h>
+#include <tftf_lib.h>
+
+const trng_function_t trng_functions[TRNG_NUM_CALLS] = {
+ DEFINE_TRNG_FUNC(TRNG_VERSION, true),
+ DEFINE_TRNG_FUNC(TRNG_FEATURES, true),
+ DEFINE_TRNG_FUNC(TRNG_UUID, true),
+ DEFINE_TRNG_FUNC(TRNG_RND, true),
+};
+
+int32_t tftf_trng_version(void)
+{
+ smc_args args = { SMC_TRNG_VERSION };
+ smc_ret_values ret_vals;
+
+ ret_vals = tftf_smc(&args);
+ return ret_vals.ret0;
+}
+
+
+bool tftf_trng_feature_implemented(uint32_t id)
+{
+ smc_args args = {
+ SMC_TRNG_FEATURES,
+ id,
+ };
+ smc_ret_values ret_vals;
+
+ ret_vals = tftf_smc(&args);
+ return ret_vals.ret0 == TRNG_E_SUCCESS;
+}
+
+smc_ret_values tftf_trng_uuid(void)
+{
+ smc_args args = { SMC_TRNG_UUID };
+
+ return tftf_smc(&args);
+}
+
+smc_ret_values tftf_trng_rnd(uint32_t nbits)
+{
+ smc_args args = {
+ SMC_TRNG_RND,
+ nbits,
+ };
+
+ return tftf_smc(&args);
+}
diff --git a/tftf/framework/framework.mk b/tftf/framework/framework.mk
index 4ca1d4258..8ec18ea9a 100644
--- a/tftf/framework/framework.mk
+++ b/tftf/framework/framework.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2021, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -62,6 +62,7 @@ FRAMEWORK_SOURCES += \
lib/sdei/sdei.c \
lib/smc/${ARCH}/asm_smc.S \
lib/smc/${ARCH}/smc.c \
+ lib/trng/trng.c \
lib/trusted_os/trusted_os.c \
lib/utils/mp_printf.c \
lib/utils/uuid.c \
diff --git a/tftf/tests/runtime_services/standard_service/trng/api_tests/test_trng.c b/tftf/tests/runtime_services/standard_service/trng/api_tests/test_trng.c
new file mode 100644
index 000000000..f2f46570c
--- /dev/null
+++ b/tftf/tests/runtime_services/standard_service/trng/api_tests/test_trng.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include <platform.h>
+#include <psci.h>
+#include <smccc.h>
+#include <string.h>
+#include <errno.h>
+#include <tftf_lib.h>
+#include <trng.h>
+
+/*
+ * @Test_Aim@ exercise TRNG Version SMC.
+ *
+ * This test should exercise the trng version call. Versions before 1.0 don't
+ * exsit, so should fail. This should also skip if TRNG is not implemented.
+ */
+test_result_t test_trng_version(void)
+{
+ int32_t version = tftf_trng_version();
+
+ if (version > 0 && version < TRNG_VERSION(1, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+ if (version < 0 && version == TRNG_E_NOT_SUPPORTED) {
+ return TEST_RESULT_SKIPPED;
+ }
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * @Test_Aim@ Verify that TRNG reports implemented functions.
+ *
+ * Check that TRNG Fetures reports that the TRNG extension:
+ * - reports implementing functions that we know for sure exist, such as TRNG
+ * Features itself
+ * - reports not implementing functions that are part of other standards
+ */
+test_result_t test_trng_features(void)
+{
+ int32_t version = tftf_trng_version();
+
+ if (version < 0 && version == TRNG_E_NOT_SUPPORTED) {
+ return TEST_RESULT_SKIPPED;
+ }
+ if (!tftf_trng_feature_implemented(SMC_TRNG_FEATURES)) {
+ return TEST_RESULT_FAIL;
+ }
+ if (tftf_trng_feature_implemented(SMC_PSCI_SYSTEM_RESET)) {
+ return TEST_RESULT_FAIL;
+ }
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * @Test_Aim@ TRNG_RND Meets the Zero-fill requirements of the spec
+ */
+#ifndef __aarch64__
+test_result_t test_trng_rnd(void)
+{
+ int32_t version = tftf_trng_version();
+ smc_ret_values rnd_out;
+
+ if (version < 0 && version == TRNG_E_NOT_SUPPORTED) {
+ return TEST_RESULT_SKIPPED;
+ }
+ if (!tftf_trng_feature_implemented(SMC_TRNG_RND)) {
+ return TEST_RESULT_SKIPPED;
+ }
+ rnd_out = tftf_trng_rnd(U(0));
+ if (rnd_out.ret0 != TRNG_E_INVALID_PARAMS) {
+ ERROR("RND 0 returned 0x%x\n", (uint32_t) rnd_out.ret0);
+ return TEST_RESULT_FAIL;
+ }
+ rnd_out = tftf_trng_rnd(U(1024));
+ if (rnd_out.ret0 != TRNG_E_INVALID_PARAMS) {
+ ERROR("RND 1024 returned 0x%x\n", (uint32_t) rnd_out.ret0);
+ return TEST_RESULT_FAIL;
+ }
+ rnd_out = tftf_trng_rnd(U(1));
+ if (rnd_out.ret0 == TRNG_E_NO_ENTOPY) {
+ WARN("There is not a single bit of entropy\n");
+ return TEST_RESULT_SKIPPED;
+ }
+ if ((rnd_out.ret1 & 0xFFFFFFFF) != 0) {
+ ERROR("non-zero w1 value 0x%x\n", (uint32_t) rnd_out.ret1);
+ return TEST_RESULT_FAIL;
+ }
+ if ((rnd_out.ret2 & 0xFFFFFFFF) != 0) {
+ ERROR("non-zero w2 value 0x%x\n", (uint32_t) rnd_out.ret2);
+ return TEST_RESULT_FAIL;
+ }
+ if ((rnd_out.ret3 & 0xFFFFFFFE) != 0) {
+ /* Note: there's an "E" here ^, because we asked for the least
+ * significant bit to be random by passing a "1" to the RND function
+ */
+ ERROR("Unexpected w3 value 0x%x\n", (uint32_t) rnd_out.ret3);
+ return TEST_RESULT_FAIL;
+ }
+ return TEST_RESULT_SUCCESS;
+}
+
+#else
+test_result_t test_trng_rnd(void)
+{
+ int32_t version = tftf_trng_version();
+ smc_ret_values rnd_out;
+
+ if (version < 0 && version == TRNG_E_NOT_SUPPORTED) {
+ return TEST_RESULT_SKIPPED;
+ }
+ if (!tftf_trng_feature_implemented(SMC_TRNG_RND)) {
+ return TEST_RESULT_SKIPPED;
+ }
+ rnd_out = tftf_trng_rnd(U(0));
+ if (rnd_out.ret0 != TRNG_E_INVALID_PARAMS) {
+ ERROR("RND 0 returned 0x%lx\n", rnd_out.ret0);
+ return TEST_RESULT_FAIL;
+ }
+ rnd_out = tftf_trng_rnd(U(1024));
+ if (rnd_out.ret0 != TRNG_E_INVALID_PARAMS) {
+ ERROR("RND 1024 returned 0x%lx\n", rnd_out.ret0);
+ return TEST_RESULT_FAIL;
+ }
+ rnd_out = tftf_trng_rnd(U(1));
+ if (rnd_out.ret0 == TRNG_E_NO_ENTOPY) {
+ WARN("There is not a single bit of entropy\n");
+ return TEST_RESULT_SKIPPED;
+ }
+ if ((rnd_out.ret1 & 0xFFFFFFFFFFFFFFFF) != 0) {
+ ERROR("non-zero x1 value 0x%lx\n", rnd_out.ret1);
+ return TEST_RESULT_FAIL;
+ }
+ if ((rnd_out.ret2 & 0xFFFFFFFFFFFFFFFF) != 0) {
+ ERROR("non-zero x2 value 0x%lx\n", rnd_out.ret2);
+ return TEST_RESULT_FAIL;
+ }
+ if ((rnd_out.ret3 & 0xFFFFFFFFFFFFFFFE) != 0) {
+ ERROR("Unexpected x3 value 0x%lx\n", rnd_out.ret3);
+ return TEST_RESULT_FAIL;
+ }
+ return TEST_RESULT_SUCCESS;
+}
+#endif
diff --git a/tftf/tests/tests-standard.mk b/tftf/tests/tests-standard.mk
index 97d530fdf..c6c9029f3 100644
--- a/tftf/tests/tests-standard.mk
+++ b/tftf/tests/tests-standard.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2021, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -19,6 +19,7 @@ TESTS_MAKEFILE := $(addprefix tftf/tests/, \
tests-spm.mk \
tests-template.mk \
tests-tftf-validation.mk \
+ tests-trng.mk \
tests-tsp.mk \
tests-uncontainable.mk \
tests-debugfs.mk \
diff --git a/tftf/tests/tests-standard.xml b/tftf/tests/tests-standard.xml
index 0bebbef67..8c66cdaf0 100644
--- a/tftf/tests/tests-standard.xml
+++ b/tftf/tests/tests-standard.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ Copyright (c) 2018-2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
-->
@@ -14,6 +14,7 @@
<!ENTITY tests-psci SYSTEM "tests-psci.xml">
<!ENTITY tests-sdei SYSTEM "tests-sdei.xml">
<!ENTITY tests-rt-instr SYSTEM "tests-runtime-instrumentation.xml">
+ <!ENTITY tests-trng SYSTEM "tests-trng.xml">
<!ENTITY tests-tsp SYSTEM "tests-tsp.xml">
<!ENTITY tests-el3-pstate SYSTEM "tests-el3-power-state.xml">
<!ENTITY tests-state-switch SYSTEM "tests-arm-state-switch.xml">
@@ -32,6 +33,7 @@
&tests-psci;
&tests-sdei;
&tests-rt-instr;
+ &tests-trng;
&tests-tsp;
&tests-el3-pstate;
&tests-state-switch;
diff --git a/tftf/tests/tests-trng.mk b/tftf/tests/tests-trng.mk
new file mode 100644
index 000000000..d2842964e
--- /dev/null
+++ b/tftf/tests/tests-trng.mk
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+TESTS_SOURCES += tftf/tests/runtime_services/standard_service/trng/api_tests/test_trng.c
diff --git a/tftf/tests/tests-trng.xml b/tftf/tests/tests-trng.xml
new file mode 100644
index 000000000..72f1fd076
--- /dev/null
+++ b/tftf/tests/tests-trng.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Copyright (c) 2021, Arm Limited. All rights reserved.
+
+ SPDX-License-Identifier: BSD-3-Clause
+-->
+
+<testsuites>
+ <!--
+ The "template" testsuite aims at providing template test code as a
+ starting point for developing new tests. These tests don't do anything
+ useful in terms of testing.
+ -->
+ <testsuite name="TRNG" description="True Random Number Generator">
+ <testcase name="Version" function="test_trng_version" />
+ <testcase name="Features" function="test_trng_features" />
+ <!--
+ Note: the UUID function is not testable, as it's correct if it
+ returns _any_ value in W0-W3.
+ -->
+ <testcase name="RND" function="test_trng_rnd" />
+ </testsuite>
+
+</testsuites>