/* Copyright (c) 2017 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef COMPONENT_PSA_SRV_IPC #error [NOT_SUPPORTED] SPM tests can run only on SPM-enabled targets #endif // COMPONENT_PSA_SRV_IPC #include "mbed.h" #include "greentea-client/test_env.h" #include "unity.h" #include "utest.h" #include "spm_client.h" #include "psa_server_test_part1_ifs.h" #include "server_tests.h" using namespace utest::v1; #define TEST_ROT_SRV_MINOR 12 #define OUT_BUFFER_SIZE 60 psa_handle_t control_handle = 0; char test_str[] = "abcdefghijklmnopqrstuvwxyz"; char cross_part_buf[] = "Hello and welcome SPM"; PSA_TEST_CLIENT(wait_timeout) { osDelay(50); psa_handle_t test_handle = psa_connect(TEST, TEST_ROT_SRV_MINOR); TEST_ASSERT(test_handle > 0); psa_close(test_handle); } PSA_TEST_CLIENT(identity_during_connect) { psa_handle_t test_handle = psa_connect(TEST, TEST_ROT_SRV_MINOR); TEST_ASSERT(test_handle > 0); psa_close(test_handle); } PSA_TEST_CLIENT(identity_during_call) { psa_error_t status = PSA_SUCCESS; psa_handle_t test_handle = psa_connect(TEST, TEST_ROT_SRV_MINOR); TEST_ASSERT(test_handle > 0); status = psa_call(test_handle, NULL, 0, NULL, 0); TEST_ASSERT_EQUAL(PSA_SUCCESS, status); psa_close(test_handle); } PSA_TEST_CLIENT(msg_size_assertion) { psa_error_t status = PSA_SUCCESS; psa_invec_t data[PSA_MAX_IOVEC] = { {test_str, 4}, {test_str + 5, 6}, {test_str + 13, 1}, {NULL, 0} }; psa_handle_t test_handle = psa_connect(TEST, TEST_ROT_SRV_MINOR); TEST_ASSERT(test_handle > 0); status = psa_call(test_handle, data, PSA_MAX_IOVEC, NULL, 0); TEST_ASSERT_EQUAL(PSA_SUCCESS, status); psa_close(test_handle); } PSA_TEST_CLIENT(reject_connection) { psa_handle_t test_handle = psa_connect(TEST, TEST_ROT_SRV_MINOR); TEST_ASSERT_EQUAL(PSA_CONNECTION_REFUSED, test_handle); } PSA_TEST_CLIENT(read_at_outofboud_offset) { psa_error_t status = PSA_SUCCESS; psa_invec_t data = { test_str, sizeof(test_str) }; psa_handle_t test_handle = psa_connect(TEST, TEST_ROT_SRV_MINOR); TEST_ASSERT(test_handle > 0); status = psa_call(test_handle, &data, 1, NULL, 0); TEST_ASSERT_EQUAL(PSA_SUCCESS, status); psa_close(test_handle); } PSA_TEST_CLIENT(msg_read_truncation) { psa_error_t status = PSA_SUCCESS; psa_invec_t data[3] = { {test_str, 4}, {test_str + 5, 6}, {test_str + 13, 1} }; psa_handle_t test_handle = psa_connect(TEST, TEST_ROT_SRV_MINOR); TEST_ASSERT(test_handle > 0); status = psa_call(test_handle, data, 3, NULL, 0); TEST_ASSERT_EQUAL(PSA_SUCCESS, status); psa_close(test_handle); } PSA_TEST_CLIENT(skip_zero) { psa_error_t status = PSA_SUCCESS; psa_invec_t data = { test_str, sizeof(test_str) }; psa_handle_t test_handle = psa_connect(TEST, TEST_ROT_SRV_MINOR); TEST_ASSERT(test_handle > 0); status = psa_call(test_handle, &data, 1, NULL, 0); TEST_ASSERT_EQUAL(PSA_SUCCESS, status); psa_close(test_handle); } PSA_TEST_CLIENT(skip_some) { psa_error_t status = PSA_SUCCESS; psa_invec_t data = { test_str, sizeof(test_str) }; psa_handle_t test_handle = psa_connect(TEST, TEST_ROT_SRV_MINOR); TEST_ASSERT(test_handle > 0); status = psa_call(test_handle, &data, 1, NULL, 0); TEST_ASSERT_EQUAL(PSA_SUCCESS, status); psa_close(test_handle); } PSA_TEST_CLIENT(skip_more_than_left) { psa_error_t status = PSA_SUCCESS; psa_invec_t data = { test_str, 8 }; psa_handle_t test_handle = psa_connect(TEST, TEST_ROT_SRV_MINOR); TEST_ASSERT(test_handle > 0); status = psa_call(test_handle, &data, 1, NULL, 0); TEST_ASSERT_EQUAL(PSA_SUCCESS, status); psa_close(test_handle); } PSA_TEST_CLIENT(rhandle_factorial) { uint32_t secure_value = 0; uint32_t value = 1; psa_error_t status = PSA_SUCCESS; psa_outvec_t resp = { &secure_value, sizeof(secure_value) }; psa_handle_t test_handle = psa_connect(TEST, TEST_ROT_SRV_MINOR); TEST_ASSERT(test_handle > 0); for (uint32_t i = 1; i <= 5; i++) { value *= i; status = psa_call(test_handle, NULL, 0, &resp, 1); TEST_ASSERT_EQUAL(PSA_SUCCESS, status); TEST_ASSERT_EQUAL(value, secure_value); } psa_close(test_handle); } PSA_TEST_CLIENT(cross_partition_call) { psa_handle_t test_handle = psa_connect(TEST, TEST_ROT_SRV_MINOR); size_t in_len = strlen(cross_part_buf); TEST_ASSERT_MESSAGE(test_handle > 0, "psa_connect() failed"); psa_invec_t iovec = { cross_part_buf, in_len }; uint8_t *response_buf = (uint8_t*)malloc(sizeof(uint8_t) * OUT_BUFFER_SIZE); memset(response_buf, 0, OUT_BUFFER_SIZE); psa_outvec_t resp = { response_buf, OUT_BUFFER_SIZE }; psa_error_t status = psa_call(test_handle, &iovec, 1, &resp, 1); TEST_ASSERT_EQUAL(PSA_SUCCESS, status); TEST_ASSERT_EQUAL_STRING_LEN("MPS emoclew dna olleHMPS emoclew dna olleH", response_buf, in_len*2); free(response_buf); psa_close(test_handle); } // Test a common DOORBELL scenario PSA_TEST_CLIENT(doorbell_test) { psa_handle_t test_handle = psa_connect(TEST, TEST_ROT_SRV_MINOR); TEST_ASSERT_MESSAGE(test_handle > 0, "psa_connect() failed"); psa_error_t status = psa_call(test_handle, NULL, 0, NULL, 0); TEST_ASSERT_EQUAL(PSA_SUCCESS, status); psa_close(test_handle); } utest::v1::status_t spm_setup(const size_t number_of_cases) { control_handle = psa_connect(CONTROL, 0); if (control_handle < 0) { error("Could not open a connection with CONTROL ROT_SRV"); } #ifndef NO_GREENTEA GREENTEA_SETUP(60, "default_auto"); #endif return greentea_test_setup_handler(number_of_cases); } void spm_teardown(const size_t passed, const size_t failed, const failure_t failure) { psa_close(control_handle); greentea_test_teardown_handler(passed, failed, failure); } utest::v1::status_t spm_case_setup(const Case *const source, const size_t index_of_case) { psa_error_t status = PSA_SUCCESS; test_action_t action = START_TEST; psa_invec_t data = {&action, sizeof(action)}; status = psa_call(control_handle, &data, 1, NULL, 0); TEST_ASSERT_EQUAL(PSA_SUCCESS, status); osDelay(50); return greentea_case_setup_handler(source, index_of_case); } utest::v1::status_t spm_case_teardown(const Case *const source, const size_t passed, const size_t failed, const failure_t reason) { psa_error_t status = PSA_SUCCESS; psa_error_t test_status = PSA_SUCCESS; test_action_t action = GET_TEST_RESULT; psa_invec_t data = {&action, sizeof(action)}; psa_outvec_t resp = {&test_status, sizeof(test_status)}; // Wait for psa_close to finish on server side osDelay(50); status = psa_call(control_handle, &data, 1, &resp, 1); TEST_ASSERT_EQUAL(PSA_SUCCESS, status); TEST_ASSERT_EQUAL(PSA_SUCCESS, test_status); return greentea_case_teardown_handler(source, passed, failed, reason); } #define SPM_UTEST_CASE(desc, test) Case(desc, spm_case_setup, PSA_TEST_CLIENT_NAME(test), spm_case_teardown) Case cases[] = { SPM_UTEST_CASE("Wait invalid time", wait_timeout), SPM_UTEST_CASE("Get identity during connect", identity_during_connect), SPM_UTEST_CASE("Get identity during call", identity_during_call), SPM_UTEST_CASE("Assert msg size", msg_size_assertion), SPM_UTEST_CASE("Reject on connect", reject_connection), SPM_UTEST_CASE("Read at an out of bound offset", read_at_outofboud_offset), SPM_UTEST_CASE("Read msg with size bigger than message", msg_read_truncation), SPM_UTEST_CASE("Make sure skip with 0 byte number skips nothing", skip_zero), SPM_UTEST_CASE("Skip a few bytes while reading a message", skip_some), SPM_UTEST_CASE("Try to skip more bytes than left while reading", skip_more_than_left), SPM_UTEST_CASE("Test rhandle implementation by calculating the factorial function", rhandle_factorial), SPM_UTEST_CASE("Test a call flow between 2 secure partitions", cross_partition_call), SPM_UTEST_CASE("Test a common DOORBELL scenario", doorbell_test), }; //Declare your test specification with a custom setup handler Specification specification(spm_setup, cases, spm_teardown); int main(int, char**) { Harness::run(specification); return 0; }