diff options
41 files changed, 783 insertions, 80 deletions
diff --git a/components/app/remote-test-runner/remote_test_runner.cpp b/components/app/remote-test-runner/remote_test_runner.cpp index 681c7467f..b819779b5 100644 --- a/components/app/remote-test-runner/remote_test_runner.cpp +++ b/components/app/remote-test-runner/remote_test_runner.cpp @@ -136,6 +136,8 @@ void remote_test_runner::output_results(const struct test_summary &summary, else if (results[i].run_state == TEST_RUN_STATE_FAILED) { printf("error\n"); + printf("\tline number: %d\n", results[i].failure.line_num); + printf("\tinfo: 0x%016lx\n", results[i].failure.info); } else { diff --git a/components/config/interface/platform_config.h b/components/config/interface/platform_config.h index d11f0eb80..3f7eb941e 100644 --- a/components/config/interface/platform_config.h +++ b/components/config/interface/platform_config.h @@ -46,6 +46,13 @@ void platform_config_device_query_free(struct device_region *device_region); */ int platform_config_device_add(const struct device_region *device_region); +/** + * \brief Returns a count of the number of device regions + * + * \return 0 if successful + */ +unsigned int platform_config_device_region_count(void); + #ifdef __cplusplus } diff --git a/components/config/loader/sp/component.cmake b/components/config/loader/sp/component.cmake new file mode 100644 index 000000000..82b9fbd12 --- /dev/null +++ b/components/config/loader/sp/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}/sp_config_loader.c" + ) + diff --git a/components/config/loader/sp/sp_config_loader.c b/components/config/loader/sp/sp_config_loader.c new file mode 100644 index 000000000..a1c88042e --- /dev/null +++ b/components/config/loader/sp/sp_config_loader.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + */ + +#include <string.h> +#include <config/interface/platform_config.h> +#include <platform/interface/device_region.h> +#include "sp_config_loader.h" + + +struct sp_param_device_region +{ + char name[16]; + uintptr_t location; + size_t size; +}; + +/** + * Loads externally provided configuration data originating from + * theh SP manifest. + */ +void sp_config_load(struct ffa_init_info *init_info) +{ + /* Load deployment specific configuration */ + for (size_t param_index = 0; param_index < init_info->count; param_index++) { + + if (!strcmp((const char *)init_info->nvp[param_index].name,"DEVICE_REGIONS")) { + + struct sp_param_device_region *d = (struct sp_param_device_region *)init_info->nvp[param_index].value; + + /*Iterate over the device regions*/ + while ((uintptr_t)d < (init_info->nvp[param_index].value + init_info->nvp[param_index].size)) { + + struct device_region device_region; + + strcpy(device_region.dev_class, d->name); + device_region.dev_instance = 0; + device_region.base_addr = d->location; + device_region.io_region_size = d->size; + + platform_config_device_add(&device_region); + + ++d; + } + } + } +} diff --git a/components/config/loader/sp/sp_config_loader.h b/components/config/loader/sp/sp_config_loader.h new file mode 100644 index 000000000..a1c8bf0a1 --- /dev/null +++ b/components/config/loader/sp/sp_config_loader.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SP_CONFIG_LOADER_H +#define SP_CONFIG_LOADER_H + +#include <ffa_api.h> + +/** + * Loads the secure partition specific configuration passed as + * SP initialization parameters. + */ +void sp_config_load(struct ffa_init_info *init_info); + + +#endif /* SP_CONFIG_LOADER_H */ diff --git a/components/config/ramstore/config_ramstore.c b/components/config/ramstore/config_ramstore.c index 548ba4b02..2e2464547 100644 --- a/components/config/ramstore/config_ramstore.c +++ b/components/config/ramstore/config_ramstore.c @@ -114,3 +114,18 @@ void platform_config_device_query_free(struct device_region *device_region) { free(device_region); } + +unsigned int platform_config_device_region_count(void) +{ + unsigned int count = 0; + + const struct config_container *container = ramstore.device_region_list; + + while (container) { + + ++count; + container = container->next; + } + + return count; +} diff --git a/components/config/ramstore/test/ramstore_tests.cpp b/components/config/ramstore/test/ramstore_tests.cpp index c597b571a..aadb62b03 100644 --- a/components/config/ramstore/test/ramstore_tests.cpp +++ b/components/config/ramstore/test/ramstore_tests.cpp @@ -38,7 +38,7 @@ TEST(ConfigRamstoreTests, checkSingleConfig) /* This would be external configuration, obtained say from device tree */ strcpy(config.dev_class, "fs"); config.dev_instance = 2; - config.base_addr = (uint8_t*)0x0f000010; + config.base_addr = (uintptr_t)0x0f000010; config.io_region_size = 0x100; /* Add the configuration object */ @@ -65,7 +65,7 @@ TEST(ConfigRamstoreTests, checkMultipleConfig) strcpy(config1.dev_class, "flash"); config1.dev_instance = 0; - config1.base_addr = (uint8_t*)0x0f000010; + config1.base_addr = (uintptr_t)0x0f000010; config1.io_region_size = 0x100; status = platform_config_device_add(&config1); @@ -76,12 +76,14 @@ TEST(ConfigRamstoreTests, checkMultipleConfig) strcpy(config2.dev_class, "flash"); config2.dev_instance = 1; - config2.base_addr = (uint8_t*)0x0f000010; + config2.base_addr = (uintptr_t)0x0f000010; config2.io_region_size = 0x100; status = platform_config_device_add(&config2); CHECK_EQUAL(0, status); + CHECK_EQUAL(2, platform_config_device_region_count()); + /* Expect queries for both objects to work */ struct device_region *query1_result = platform_config_device_query(config1.dev_class, config1.dev_instance); CHECK(query1_result); diff --git a/components/config/test/sp/component.cmake b/components/config/test/sp/component.cmake new file mode 100644 index 000000000..9869e73c1 --- /dev/null +++ b/components/config/test/sp/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}/sp_config_tests.c" + ) + diff --git a/components/config/test/sp/sp_config_tests.c b/components/config/test/sp/sp_config_tests.c new file mode 100644 index 000000000..94ba26866 --- /dev/null +++ b/components/config/test/sp/sp_config_tests.c @@ -0,0 +1,102 @@ +/* + * 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 <config/interface/platform_config.h> +#include <stdint.h> + +/** + * Secure Partition configuration tests for checking configuartion + * data passed to an SP at initialisation. These tests assume + * use of the FFA manifest for any SP deployments of + * deployments/env_test. + */ + +/* + * Check that the loaded configuration includes one or more + * device regions. + */ +static bool check_device_region_loaded(struct test_failure *failure) +{ + return platform_config_device_region_count() > 0; +} + +/* + * Check that a device region for a 'trng' device has been loaded + * and that values are as expected. + */ +static bool check_trng_device_region_loaded(struct test_failure *failure) +{ + bool passed = false; + struct device_region *dev_region = platform_config_device_query("trng", 0); + + if (dev_region) { + + passed = + (dev_region->dev_instance == 0) && + (dev_region->io_region_size == 0x1000); + } + + platform_config_device_query_free(dev_region); + + return passed; +} + +/* + * Check access to some trng registers + */ +static bool check_trng_register_access(struct test_failure *failure) +{ + bool passed = false; + + struct device_region *dev_region = platform_config_device_query("trng", 0); + + if (dev_region) { + + /* Expect reset values to be read from a selection of TRNG registers */ + uint32_t reg_val; + passed = true; + + /* PID4 */ + if (passed) { + reg_val = *((volatile uint32_t*)((uint8_t*)dev_region->base_addr + 0xfd0)); + passed = (reg_val == 0x00000004); + failure->line_num = __LINE__; + failure->info = reg_val; + } + + /* PID0 */ + if (passed) { + reg_val = *((volatile uint32_t*)((uint8_t*)dev_region->base_addr + 0xfe0)); + passed = (reg_val == 0x000000aa); + failure->line_num = __LINE__; + failure->info = reg_val; + } + } + + return passed; +} + + +/** + * Define an register test group + */ +void sp_config_tests_register(void) +{ + static const struct simple_c_test_case sp_config_tests[] = { + {.name = "DevRegionLoaded", .test_func = check_device_region_loaded}, + {.name = "TrngDevRegionLoaded", .test_func = check_trng_device_region_loaded}, + {.name = "TrngRegAccess", .test_func = check_trng_register_access} + }; + + static const struct simple_c_test_group sp_config_test_group = + { + .group = "SpConfigTests", + .num_test_cases = sizeof(sp_config_tests)/sizeof(struct simple_c_test_case), + .test_cases = sp_config_tests + }; + + simple_c_test_runner_register_group(&sp_config_test_group); +}
\ No newline at end of file diff --git a/components/config/test/sp/sp_config_tests.h b/components/config/test/sp/sp_config_tests.h new file mode 100644 index 000000000..516d2b1e6 --- /dev/null +++ b/components/config/test/sp/sp_config_tests.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SP_CONFIG_TESTS_H +#define SP_CONFIG_TESTS_H + +void sp_config_tests_register(void); + +#endif /* SP_CONFIG_TESTS_H */ diff --git a/components/service/crypto/provider/mbedcrypto/trng_adapter/platform/platform_trng_adapter.c b/components/service/crypto/provider/mbedcrypto/trng_adapter/platform/platform_trng_adapter.c index 29628d11a..1b9f1d2c2 100644 --- a/components/service/crypto/provider/mbedcrypto/trng_adapter/platform/platform_trng_adapter.c +++ b/components/service/crypto/provider/mbedcrypto/trng_adapter/platform/platform_trng_adapter.c @@ -4,7 +4,6 @@ * SPDX-License-Identifier: BSD-3-Clause */ #include <mbedtls/entropy.h> -#include <mbedtls/entropy_poll.h> #include <platform/interface/trng.h> #include <service/crypto/provider/mbedcrypto/trng_adapter/trng_adapter.h> #include <config/interface/platform_config.h> diff --git a/components/service/crypto/provider/mbedcrypto/trng_adapter/test/component.cmake b/components/service/crypto/provider/mbedcrypto/trng_adapter/test/component.cmake new file mode 100644 index 000000000..4aa4321d1 --- /dev/null +++ b/components/service/crypto/provider/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/provider/mbedcrypto/trng_adapter/test/trng_env_tests.c b/components/service/crypto/provider/mbedcrypto/trng_adapter/test/trng_env_tests.c new file mode 100644 index 000000000..d297821b4 --- /dev/null +++ b/components/service/crypto/provider/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/provider/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); +}
\ No newline at end of file diff --git a/components/service/crypto/provider/mbedcrypto/trng_adapter/test/trng_env_tests.h b/components/service/crypto/provider/mbedcrypto/trng_adapter/test/trng_env_tests.h new file mode 100644 index 000000000..36c4103ba --- /dev/null +++ b/components/service/crypto/provider/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/test_runner/client/cpp/test_runner_client.cpp b/components/service/test_runner/client/cpp/test_runner_client.cpp index a78000255..b1b2784ed 100644 --- a/components/service/test_runner/client/cpp/test_runner_client.cpp +++ b/components/service/test_runner/client/cpp/test_runner_client.cpp @@ -211,9 +211,9 @@ int test_runner_client::deserialize_result( memcpy(&packed_result, value_buf, fixed_size); result.run_state = (enum test_run_state)packed_result.run_state; - result.fail_line = packed_result.fail_line; result.name[0] = 0; result.group[0] = 0; + result.failure = {0}; /* Deserialize name and group if present */ struct tlv_const_iterator req_iter; @@ -238,6 +238,17 @@ int test_runner_client::deserialize_result( result.group[decoded_record.length] = 0; } } + + if (tlv_find_decode(&req_iter, TS_TEST_RUNNER_TEST_RESULT_TAG_FAILURE, &decoded_record)) { + + if (decoded_record.length == sizeof(ts_test_runner_test_failure)) { + + struct ts_test_runner_test_failure deserialized_failure; + memcpy(&deserialized_failure, decoded_record.value, decoded_record.length); + result.failure.line_num = deserialized_failure.line_num; + result.failure.info = deserialized_failure.info; + } + } } else { /* Invalid test result */ diff --git a/components/service/test_runner/common/test_runner.h b/components/service/test_runner/common/test_runner.h index c891918cb..ffc62430b 100644 --- a/components/service/test_runner/common/test_runner.h +++ b/components/service/test_runner/common/test_runner.h @@ -4,10 +4,11 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef CPPUTEST_TEST_RUNNER_H -#define CPPUTEST_TEST_RUNNER_H +#ifndef TEST_RUNNER_H +#define TEST_RUNNER_H #include <protocols/service/test_runner/packed-c/test_result.h> +#include <stdint.h> #ifdef __cplusplus extern "C" { @@ -33,10 +34,10 @@ struct test_spec */ struct test_summary { - int num_tests; /* Number of qualifying tests */ - int num_results; /* Number of available test result objects */ - int num_passed; /* Number that ran and passed */ - int num_failed; /* Number that ran and failed */ + unsigned int num_tests; /* Number of qualifying tests */ + unsigned int num_results; /* Number of available test result objects */ + unsigned int num_passed; /* Number that ran and passed */ + unsigned int num_failed; /* Number that ran and failed */ }; /** @@ -50,6 +51,15 @@ enum test_run_state }; /** + * Test failue to describe a failure + */ +struct test_failure +{ + unsigned int line_num; /* Source line where test assertion failed */ + uint64_t info; /* Provides test specific information about the failure */ +}; + +/** * The result for a particular test case. */ struct test_result @@ -57,11 +67,11 @@ struct test_result char name[TEST_NAME_MAX_LEN]; char group[TEST_GROUP_MAX_LEN]; enum test_run_state run_state; - unsigned int fail_line; + struct test_failure failure; }; #ifdef __cplusplus } /* extern "C" */ #endif -#endif /* CPPUTEST_TEST_RUNNER_H */ +#endif /* TEST_RUNNER_H */ diff --git a/components/service/test_runner/provider/backend/mock/mock_test_runner.c b/components/service/test_runner/provider/backend/mock/mock_test_runner.c index 4b6cde851..275457d27 100644 --- a/components/service/test_runner/provider/backend/mock/mock_test_runner.c +++ b/components/service/test_runner/provider/backend/mock/mock_test_runner.c @@ -8,8 +8,18 @@ #include <string.h> /* Mock test test functions */ -static bool test_that_passes(void) { return true; } -static bool test_that_fails(void) { return false; } +static bool test_that_passes(struct test_failure *failure) +{ + (void)failure; + return true; +} + +static bool test_that_fails(struct test_failure *failure) +{ + failure->line_num = __LINE__; + failure->info = 27; + return false; +} /** * The mock backend is a test_runner that provides some mock test cases diff --git a/components/service/test_runner/provider/backend/simple_c/simple_c_test_runner.c b/components/service/test_runner/provider/backend/simple_c/simple_c_test_runner.c index 0ab190c5d..fb66d752d 100644 --- a/components/service/test_runner/provider/backend/simple_c/simple_c_test_runner.c +++ b/components/service/test_runner/provider/backend/simple_c/simple_c_test_runner.c @@ -80,11 +80,12 @@ static int test_iterate(const struct test_spec *spec, bool list_only, if (does_qualify(spec->name, test_case->name)) { enum test_run_state run_state = TEST_RUN_STATE_NOT_RUN; + struct test_failure failure = {0}; /* Run the qualifying test case if we're not just listing tests */ if (!list_only) { - if (test_case->test_func()) { + if (test_case->test_func(&failure)) { run_state = TEST_RUN_STATE_PASSED; ++summary->num_passed; @@ -102,7 +103,7 @@ static int test_iterate(const struct test_spec *spec, bool list_only, struct test_result *new_result = &results[summary->num_results]; new_result->run_state = run_state; - new_result->fail_line = 0; + new_result->failure = failure; strcpy(new_result->group, test_group->group); strcpy(new_result->name, test_case->name); diff --git a/components/service/test_runner/provider/backend/simple_c/simple_c_test_runner.h b/components/service/test_runner/provider/backend/simple_c/simple_c_test_runner.h index 3875c4276..129254775 100644 --- a/components/service/test_runner/provider/backend/simple_c/simple_c_test_runner.h +++ b/components/service/test_runner/provider/backend/simple_c/simple_c_test_runner.h @@ -7,6 +7,7 @@ #ifndef SIMPLE_C_TEST_RUNNER_H #define SIMPLE_C_TEST_RUNNER_H +#include <service/test_runner/common/test_runner.h> #include <stdbool.h> #include <stddef.h> @@ -30,7 +31,7 @@ struct simple_c_test_case const char *name; /* The test function that results true for a pass, false for a fail. */ - bool (*test_func)(void); + bool (*test_func)(struct test_failure *test_failure); }; /** diff --git a/components/service/test_runner/provider/serializer/packed-c/packedc_test_runner_provider_serializer.c b/components/service/test_runner/provider/serializer/packed-c/packedc_test_runner_provider_serializer.c index 577bfdc8f..5892502b5 100644 --- a/components/service/test_runner/provider/serializer/packed-c/packedc_test_runner_provider_serializer.c +++ b/components/service/test_runner/provider/serializer/packed-c/packedc_test_runner_provider_serializer.c @@ -55,6 +55,8 @@ static uint8_t *serialize_test_result(const struct test_result *result, size_t * if (name_len) required_space += tlv_required_space(name_len); if (group_len) required_space += tlv_required_space(group_len); + if (result->run_state == TEST_RUN_STATE_FAILED) + required_space += tlv_required_space(sizeof(struct ts_test_runner_test_failure)); *serialized_len = required_space; @@ -64,7 +66,6 @@ static uint8_t *serialize_test_result(const struct test_result *result, size_t * struct ts_test_runner_test_result result_msg; result_msg.run_state = result->run_state; - result_msg.fail_line = result->fail_line; memcpy(out_buf, &result_msg, fixed_len); @@ -88,6 +89,19 @@ static uint8_t *serialize_test_result(const struct test_result *result, size_t * record.value = result->group; tlv_encode(&tlv_iter, &record); } + + if (result->run_state == TEST_RUN_STATE_FAILED) { + + struct ts_test_runner_test_failure serialized_failure; + serialized_failure.line_num = result->failure.line_num; + serialized_failure.info = result->failure.info; + + struct tlv_record record; + record.tag = TS_TEST_RUNNER_TEST_RESULT_TAG_FAILURE; + record.length = sizeof(serialized_failure); + record.value = (const uint8_t*)&serialized_failure; + tlv_encode(&tlv_iter, &record); + } } return out_buf; diff --git a/components/service/test_runner/test/service/test_runner_service_tests.cpp b/components/service/test_runner/test/service/test_runner_service_tests.cpp index c4ba0e07f..8d68bca05 100644 --- a/components/service/test_runner/test/service/test_runner_service_tests.cpp +++ b/components/service/test_runner/test/service/test_runner_service_tests.cpp @@ -128,6 +128,7 @@ TEST(TestRunnerServiceTests, runAllTests) CHECK(strcmp(results[2].group, "ConfigTests") == 0); CHECK(strcmp(results[2].name, "ValidateConfig") == 0); CHECK_EQUAL(TEST_RUN_STATE_FAILED, results[2].run_state); + CHECK_EQUAL(27, results[2].failure.info); CHECK(strcmp(results[3].group, "ConfigTests") == 0); CHECK(strcmp(results[3].name, "ApplyConfig") == 0); diff --git a/deployments/crypto/opteesp/CMakeLists.txt b/deployments/crypto/opteesp/CMakeLists.txt index 356d0d366..9441ecf01 100644 --- a/deployments/crypto/opteesp/CMakeLists.txt +++ b/deployments/crypto/opteesp/CMakeLists.txt @@ -36,6 +36,7 @@ add_components(TARGET "crypto-sp" COMPONENTS "components/common/tlv" "components/config/ramstore" + "components/config/loader/sp" "components/messaging/ffa/libsp" "components/rpc/ffarpc/endpoint" "components/rpc/ffarpc/caller/sp" diff --git a/deployments/crypto/opteesp/crypto_sp.c b/deployments/crypto/opteesp/crypto_sp.c index 6b376b792..594fa89b8 100644 --- a/deployments/crypto/opteesp/crypto_sp.c +++ b/deployments/crypto/opteesp/crypto_sp.c @@ -3,7 +3,6 @@ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved. */ -#include <config/ramstore/config_ramstore.h> #include <rpc/ffarpc/caller/sp/ffarpc_caller.h> #include <rpc/ffarpc/endpoint/ffarpc_call_ep.h> #include <rpc/dummy/dummy_caller.h> @@ -12,6 +11,8 @@ #include <service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.h> #include <service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.h> #include <protocols/rpc/common/packed-c/status.h> +#include <config/ramstore/config_ramstore.h> +#include <config/loader/sp/sp_config_loader.h> #include <ffa_api.h> #include <sp_api.h> #include <sp_rxtx.h> @@ -44,9 +45,8 @@ void __noreturn sp_main(struct ffa_init_info *init_info) if (sp_init(&own_id) != 0) goto fatal_error; - /* Read config data */ config_ramstore_init(); - // ~ read here + sp_config_load(init_info); /* Establish RPC session with secure storage SP */ storage_caller = ffarpc_caller_init(&ffarpc_caller); diff --git a/deployments/env-test/env_test.cmake b/deployments/env-test/env_test.cmake new file mode 100644 index 000000000..bf2b5098f --- /dev/null +++ b/deployments/env-test/env_test.cmake @@ -0,0 +1,46 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- + +#------------------------------------------------------------------------------- +# The base build file shared between deployments of 'env-test' for +# different environments. Used for running tests that validate hardwarw +# backed services available from within a secure execution environment. +#------------------------------------------------------------------------------- + +#------------------------------------------------------------------------------- +# Components that are common accross all deployments +# +#------------------------------------------------------------------------------- +add_components( + TARGET "env_test" + BASE_DIR ${TS_ROOT} + COMPONENTS + "components/common/tlv" + "components/config/ramstore" + "components/rpc/common/interface" + "components/rpc/common/caller" + "components/service/common" + "components/service/common/provider" + "components/service/test_runner/provider" + "components/service/test_runner/provider/serializer/packed-c" + "components/service/test_runner/provider/backend/null" + "components/service/test_runner/provider/backend/simple_c" + "components/service/crypto/provider/mbedcrypto" + "components/service/crypto/provider/mbedcrypto/trng_adapter/platform" + "components/service/crypto/provider/mbedcrypto/trng_adapter/test" + "components/service/secure_storage/client/psa" + "protocols/rpc/common/packed-c" +) + +#------------------------------------------------------------------------------- +# Components used from external projects +# +#------------------------------------------------------------------------------- + +# Mbedcrypto +include(${TS_ROOT}/external/mbed-crypto/mbedcrypto.cmake) +target_link_libraries(env_test PRIVATE mbedcrypto) diff --git a/deployments/env-test/opteesp/CMakeLists.txt b/deployments/env-test/opteesp/CMakeLists.txt index bf735a6f5..3149ecd3d 100644 --- a/deployments/env-test/opteesp/CMakeLists.txt +++ b/deployments/env-test/opteesp/CMakeLists.txt @@ -15,7 +15,7 @@ include(../../deployment.cmake REQUIRED) # test cases. #------------------------------------------------------------------------------- include(${TS_ROOT}/environments/opteesp/env.cmake) -project(trusted-services LANGUAGES C CXX ASM) +project(trusted-services LANGUAGES C ASM) add_executable(env_test) target_include_directories(env_test PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}") set(SP_UUID "33c75baf-ac6a-4fe4-8ac7-e9909bee2d17") @@ -35,23 +35,26 @@ target_link_libraries(env_test PRIVATE ${SP_DEV_KIT_LIBRARIES}) add_components(TARGET "env_test" BASE_DIR ${TS_ROOT} COMPONENTS - "components/common/tlv" - "components/config/ramstore" + "components/config/loader/sp" "components/messaging/ffa/libsp" "components/rpc/ffarpc/endpoint" - "components/rpc/common/interface" - "components/service/common" - "components/service/common/provider" - "components/service/test_runner/provider" - "components/service/test_runner/provider/serializer/packed-c" - "components/service/test_runner/provider/backend/null" - "protocols/rpc/common/packed-c" + "components/config/test/sp" "environments/opteesp" ) +#------------------------------------------------------------------------------- +# Extend with components that are common across all deployments of +# env_test +# +#------------------------------------------------------------------------------- +include(../env_test.cmake REQUIRED) + +#------------------------------------------------------------------------------- +# Deployment specific source files +#------------------------------------------------------------------------------- target_sources(env_test PRIVATE env_test.c - env_test_config.c + env_test_tests.c ) #------------------------------------------------------------------------------- @@ -63,11 +66,6 @@ set(TS_PLATFORM "arm/fvp/fvp_base_revc-2xaemv8a" CACHE STRING "Overridden" FORCE add_platform(TARGET "env_test") -#------------------------------------------------------------------------------- -# Components used from external projects -# -#------------------------------------------------------------------------------- - if(CMAKE_CROSSCOMPILING) target_link_libraries(env_test PRIVATE stdc++ gcc m) endif() diff --git a/deployments/env-test/opteesp/env_test.c b/deployments/env-test/opteesp/env_test.c index 0bb523ffd..3df4c1adb 100644 --- a/deployments/env-test/opteesp/env_test.c +++ b/deployments/env-test/opteesp/env_test.c @@ -8,11 +8,13 @@ #include <service/test_runner/provider/test_runner_provider.h> #include <service/test_runner/provider/serializer/packed-c/packedc_test_runner_provider_serializer.h> #include <protocols/rpc/common/packed-c/status.h> +#include <config/ramstore/config_ramstore.h> +#include <config/loader/sp/sp_config_loader.h> #include <ffa_api.h> #include <sp_api.h> #include <sp_rxtx.h> #include <trace.h> -#include "env_test_config.h" +#include "env_test_tests.h" uint16_t own_id = 0; /* !!Needs refactoring as parameter to ffarpc_caller_init */ @@ -33,7 +35,8 @@ void __noreturn sp_main(struct ffa_init_info *init_info) if (sp_init(&own_id) != 0) goto fatal_error; - load_sp_config(init_info); + config_ramstore_init(); + sp_config_load(init_info); /* Initialize the test_runner service */ test_runner_iface = test_runner_provider_init(&test_runner_provider); @@ -41,6 +44,8 @@ void __noreturn sp_main(struct ffa_init_info *init_info) test_runner_provider_register_serializer(&test_runner_provider, TS_RPC_ENCODING_PACKED_C, packedc_test_runner_provider_serializer_instance()); + env_test_register_tests(&test_runner_provider); + ffa_call_ep_init(&ffarpc_call_ep, test_runner_iface); /* End of boot phase */ diff --git a/deployments/env-test/opteesp/env_test_config.c b/deployments/env-test/opteesp/env_test_config.c deleted file mode 100644 index 14a1e53e6..000000000 --- a/deployments/env-test/opteesp/env_test_config.c +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -/* - * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. - */ - -#include <config/ramstore/config_ramstore.h> -#include "env_test_config.h" - - -void load_sp_config(struct ffa_init_info *init_info) -{ - config_ramstore_init(); - - /* Load deployment specific configuration */ - (void)init_info; -}
\ No newline at end of file diff --git a/deployments/env-test/opteesp/env_test_config.h b/deployments/env-test/opteesp/env_test_config.h deleted file mode 100644 index 8ed4a7ea3..000000000 --- a/deployments/env-test/opteesp/env_test_config.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef ENV_TEST_CONFIG_H -#define ENV_TEST_CONFIG_H - -#include <ffa_api.h> - -/** - * Loads the SP specific configuration passed as SP initialization parameters. - */ -void load_sp_config(struct ffa_init_info *init_info); - - -#endif /* ENV_TEST_CONFIG_H */ diff --git a/deployments/env-test/opteesp/env_test_tests.c b/deployments/env-test/opteesp/env_test_tests.c new file mode 100644 index 000000000..beb9cbfb8 --- /dev/null +++ b/deployments/env-test/opteesp/env_test_tests.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + */ + +#include <service/test_runner/provider/backend/simple_c/simple_c_test_runner.h> +#include <config/test/sp/sp_config_tests.h> +#include <service/crypto/provider/mbedcrypto/trng_adapter/test/trng_env_tests.h> + +void env_test_register_tests(struct test_runner_provider *context) +{ + simple_c_test_runner_init(context); + + sp_config_tests_register(); + trng_env_tests_register(); +}
\ No newline at end of file diff --git a/deployments/env-test/opteesp/env_test_tests.h b/deployments/env-test/opteesp/env_test_tests.h new file mode 100644 index 000000000..305fc4547 --- /dev/null +++ b/deployments/env-test/opteesp/env_test_tests.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ENV_TEST_TESTS_H +#define ENV_TEST_TESTS_H + +struct test_runner_provider; + +/** + * Registers test cases for this deployment + */ +void env_test_register_tests(struct test_runner_provider *context); + + +#endif /* ENV_TEST_TESTS_H */ diff --git a/platform/drivers/arm/juno_trng/driver.cmake b/platform/drivers/arm/juno_trng/driver.cmake new file mode 100644 index 000000000..6d5100994 --- /dev/null +++ b/platform/drivers/arm/juno_trng/driver.cmake @@ -0,0 +1,13 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- + +# Add source files for using juno_trng and adapting it to the platform +# trng interface. +target_sources(${TGT} PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/juno_trng.c" + "${CMAKE_CURRENT_LIST_DIR}/juno_trng_adapter.c" +) diff --git a/platform/drivers/arm/juno_trng/juno_decl.h b/platform/drivers/arm/juno_trng/juno_decl.h new file mode 100644 index 000000000..07f2e196a --- /dev/null +++ b/platform/drivers/arm/juno_trng/juno_decl.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * This is a modified version of the juno trng platform driver from trusted-firmware-a. + * The code has been modified to allow the peripheral to be accessed by S-EL0 at + * an arbitrary virtual address. + */ + +#ifndef JUNO_DECL_H +#define JUNO_DECL_H + +#include <stdint.h> + +void juno_trng_set_base_addr(uintptr_t addr); +int juno_getentropy(void *buf, size_t len); + +#endif /* JUNO_DECL_H */ diff --git a/platform/drivers/arm/juno_trng/juno_def.h b/platform/drivers/arm/juno_trng/juno_def.h new file mode 100644 index 000000000..97d1e3cf7 --- /dev/null +++ b/platform/drivers/arm/juno_trng/juno_def.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * + * Based on the the trustedfirmware-a file with the same name. All but the + * TRNG defines are stripped out. + */ + +#ifndef JUNO_DEF_H +#define JUNO_DEF_H + +/******************************************************************************* + * TRNG related constants + ******************************************************************************/ +#define TRNG_NOUTPUTS 4 +#define TRNG_STATUS UL(0x10) +#define TRNG_INTMASK UL(0x14) +#define TRNG_CONFIG UL(0x18) +#define TRNG_CONTROL UL(0x1C) +#define TRNG_NBYTES 16 /* Number of bytes generated per round. */ + + + +#endif /* JUNO_DEF_H */ diff --git a/platform/drivers/arm/juno_trng/juno_trng.c b/platform/drivers/arm/juno_trng/juno_trng.c new file mode 100644 index 000000000..b520dbac7 --- /dev/null +++ b/platform/drivers/arm/juno_trng/juno_trng.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * This is a modified version of the juno trng platform driver from trusted-firmware-a. + * The code has been modified to allow the peripheral to be accessed by S-EL0 at + * an arbitrary virtual address. + */ + +#include <assert.h> +#include <string.h> + +#include <util.h> +#include "mmio.h" +#include "juno_def.h" +#include "juno_decl.h" + +/* The TRNG base address */ +static uintptr_t trng_base = 0; + +#define TRNG_BASE trng_base +#define NSAMPLE_CLOCKS 1 /* min 1 cycle, max 231 cycles */ +#define NRETRIES 5 + +/* + * Sets the base address used to access the peripheral. For + * S-EL0 operation, this will be a virtual address. + */ +void juno_trng_set_base_addr(uintptr_t addr) +{ + trng_base = addr; +} + +static inline int output_valid(void) +{ + int i; + + for (i = 0; i < NRETRIES; i++) { + uint32_t val; + + val = mmio_read_32(TRNG_BASE + TRNG_STATUS); + if (val & 1U) + break; + } + if (i >= NRETRIES) + return 0; /* No output data available. */ + return 1; +} + +/* + * This function fills `buf` with `len` bytes of entropy. + * It uses the Trusted Entropy Source peripheral on Juno. + * Returns 0 when the buffer has been filled with entropy + * successfully and -1 otherwise. + */ +int juno_getentropy(void *buf, size_t len) +{ + uint8_t *bp = buf; + + assert(buf); + assert(len); + + /* Check for a valid base address */ + if (!TRNG_BASE) return -1; + + /* Disable interrupt mode. */ + mmio_write_32(TRNG_BASE + TRNG_INTMASK, 0); + /* Program TRNG to sample for `NSAMPLE_CLOCKS`. */ + mmio_write_32(TRNG_BASE + TRNG_CONFIG, NSAMPLE_CLOCKS); + + while (len > 0) { + int i; + + /* Start TRNG. */ + mmio_write_32(TRNG_BASE + TRNG_CONTROL, 1); + + /* Check if output is valid. */ + if (!output_valid()) + return -1; + + /* Fill entropy buffer. */ + for (i = 0; i < TRNG_NOUTPUTS; i++) { + size_t n; + uint32_t val; + + val = mmio_read_32(TRNG_BASE + i * sizeof(uint32_t)); + n = MIN(len, sizeof(uint32_t)); + memcpy(bp, &val, n); + bp += n; + len -= n; + if (len == 0) + break; + } + + /* Reset TRNG outputs. */ + mmio_write_32(TRNG_BASE + TRNG_STATUS, 1); + } + + return 0; +} diff --git a/platform/drivers/arm/juno_trng/juno_trng_adapter.c b/platform/drivers/arm/juno_trng/juno_trng_adapter.c new file mode 100644 index 000000000..3ad8b0427 --- /dev/null +++ b/platform/drivers/arm/juno_trng/juno_trng_adapter.c @@ -0,0 +1,67 @@ +/* + * 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 "juno_decl.h" + +/* + * A platform trng driver that uses the juno_trng driver from TF-A to provide a + * hardware entropy source. + */ + +static int trng_poll(void *context, unsigned char *output, size_t nbyte, size_t *len) +{ + int status = 0; + + *len = 0; + + if (nbyte >= sizeof(unsigned char)) { + + status = juno_getentropy(output, nbyte); + + if (status == 0) { + *len = nbyte; + } + else { + /* Mbedtls currently crashes when a failure status is returned. + * This workaround prevents the crash for cases where no + * configuration has been provided for the trng. + */ + status = 0; + *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. + */ + juno_trng_set_base_addr(device_region->base_addr); + } + + return 0; +} + +void platform_trng_destroy(struct platform_trng_driver *driver) +{ + (void)driver; + juno_trng_set_base_addr(0); +} diff --git a/platform/drivers/arm/juno_trng/mmio.h b/platform/drivers/arm/juno_trng/mmio.h new file mode 100644 index 000000000..da8d82fde --- /dev/null +++ b/platform/drivers/arm/juno_trng/mmio.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Copied from trustedfirmware-a and stripped down to only provide functions + * used by juno_trng.c. + */ + +#ifndef MMIO_H +#define MMIO_H + +#include <stdint.h> + + +static inline void mmio_write_32(uintptr_t addr, uint32_t value) +{ + *(volatile uint32_t*)addr = value; +} + +static inline uint32_t mmio_read_32(uintptr_t addr) +{ + return *(volatile uint32_t*)addr; +} + +#endif /* MMIO_H */ diff --git a/platform/drivers/arm/tztrng/driver.cmake b/platform/drivers/arm/tztrng/driver.cmake index 58d98c88a..6a7f93625 100644 --- a/platform/drivers/arm/tztrng/driver.cmake +++ b/platform/drivers/arm/tztrng/driver.cmake @@ -65,4 +65,4 @@ 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") +target_sources(${TGT} PRIVATE "${CMAKE_CURRENT_LIST_DIR}/tztrng_adapter.c") diff --git a/platform/drivers/arm/tztrng/tztrng_trng.c b/platform/drivers/arm/tztrng/tztrng_adapter.c index f52eeaa56..f52eeaa56 100644 --- a/platform/drivers/arm/tztrng/tztrng_trng.c +++ b/platform/drivers/arm/tztrng/tztrng_adapter.c diff --git a/platform/interface/device_region.h b/platform/interface/device_region.h index 1ad1721bc..8bbf20352 100644 --- a/platform/interface/device_region.h +++ b/platform/interface/device_region.h @@ -23,7 +23,7 @@ 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 */ + uintptr_t base_addr; /**< Base address or region */ size_t io_region_size; /**< Size of I/O region in bytes */ }; 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 cb0138990..ff7c0492b 100644 --- a/platform/providers/arm/fvp/fvp_base_revc-2xaemv8a/platform.cmake +++ b/platform/providers/arm/fvp/fvp_base_revc-2xaemv8a/platform.cmake @@ -18,5 +18,5 @@ get_property(_platform_driver_dependencies TARGET ${TGT} # #------------------------------------------------------------------------------- if ("trng" IN_LIST _platform_driver_dependencies) - include(${TS_ROOT}/platform/drivers/arm/tztrng/driver.cmake) + include(${TS_ROOT}/platform/drivers/arm/juno_trng/driver.cmake) endif() diff --git a/protocols/service/test_runner/packed-c/test_result.h b/protocols/service/test_runner/packed-c/test_result.h index 888d2ece1..7fe9d2616 100644 --- a/protocols/service/test_runner/packed-c/test_result.h +++ b/protocols/service/test_runner/packed-c/test_result.h @@ -42,17 +42,27 @@ enum struct __attribute__ ((__packed__)) ts_test_runner_test_result { uint32_t run_state; - uint32_t fail_line; }; /* Variable length output parameter tags */ enum { /* The name of the test */ - TS_TEST_RUNNER_TEST_RESULT_TAG_NAME = 1, + TS_TEST_RUNNER_TEST_RESULT_TAG_NAME = 1, /* The group the test belongs to */ - TS_TEST_RUNNER_TEST_RESULT_TAG_GROUP = 2 + TS_TEST_RUNNER_TEST_RESULT_TAG_GROUP = 2, + + /* Test failure recorded, optionally included on failure */ + TS_TEST_RUNNER_TEST_RESULT_TAG_FAILURE = 3 }; +/* Test failure fixed sized structure */ +struct __attribute__ ((__packed__)) ts_test_runner_test_failure +{ + uint32_t line_num; + uint64_t info; +}; + + #endif /* TS_TEST_RUNNER_TEST_RESULT */ |