Skip to content

PSA Secure partition manager and services #8744

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
Nov 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,6 @@ log

# Icetea related file
test_suite.json

# default delivery dir
DELIVERY/
49 changes: 49 additions & 0 deletions TESTS/mbed_hal/spm/fault_functions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* Copyright (c) 2017-2018 ARM Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* 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 __MBED_HAL_SPM_FAULT_FUNCTIONS__
#define __MBED_HAL_SPM_FAULT_FUNCTIONS__

#include "cmsis_compiler.h"

#ifdef __cplusplus
extern "C" {
#endif

// Retruns the value of the LR register
// Used to determine which stack the exception happend in
__STATIC_FORCEINLINE uint32_t __get_LR(void);

// This function is required as we need a symbol/address
// to jump to from fault handler.
void do_nothing(void);

// Test exception handler
static void hard_fault_handler_test();

// Using naked function as it will not be executed from beginning to the end.
// The execution flow expected to be interrupted by exception and we will
// return to other function.
// compiler will not produce prolog and epilog code for naked function
// and thus will preserve stack in un-corrupted state
__attribute__((naked)) void call_mem(uint32_t addr);

#ifdef __cplusplus
}
#endif

#endif // __MBED_HAL_SPM_FAULT_FUNCTIONS__
156 changes: 156 additions & 0 deletions TESTS/mbed_hal/spm/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/* Copyright (c) 2017-2018 ARM Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* 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.
*/

#if !defined(COMPONENT_PSA_SRV_IPC)
#error [NOT_SUPPORTED] Test supported only on PSA targets
#endif

#if (defined( __CC_ARM ) || defined(__ARMCC_VERSION) || defined( __ICCARM__ ))
#error [NOT_SUPPORTED] this test is supported on GCC only
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What limitations are here that only GCC ARM supported? ) ?

Copy link
Contributor

@alzix alzix Nov 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mainly assembly code included in the test

#endif

#include "utest/utest.h"
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#include "cmsis.h"
#include "spm_api.h"
#include <stdlib.h>
#include "fault_functions.h"

using namespace utest::v1;


#define HARDFAULT_IRQn ((IRQn_Type)-13)
#define EXC_RETURN_RETURN_STACK_MSK ((uint32_t)(0x00000004))
#define PC_INDEX_IN_STACK_FRAME 6

volatile uint32_t fault_occurred;
uint32_t real_hard_fault_handler;

__STATIC_FORCEINLINE uint32_t __get_LR(void)
{
uint32_t result;

__ASM volatile("MOV %0, lr" : "=r"(result));
return (result);
}

void do_nothing(void)
{
__NOP();
}

static void hard_fault_handler_test()
{
fault_occurred++;
// LR is set EXC_RETURN
// lowest bits identify PSP vs MSP stack used for stacking
uint32_t lr = __get_LR();
uint32_t sp;

if (lr & EXC_RETURN_RETURN_STACK_MSK) {
sp = __get_PSP();
} else {
sp = __get_MSP();
}

// Overwrite return address.
// Fake return to a our special function since current
// instruction under test will always fail due to memory protection
((uint32_t *)sp)[PC_INDEX_IN_STACK_FRAME] = (uint32_t)do_nothing;
}

__attribute__((naked)) void call_mem(uint32_t addr)
{
// Only first instruction will be executed in positive flow,
// since exception will be generated for invalid memory access.
// Other instructions are for calling do_nothing function according to AAPCS.
__ASM(
"LDR r1, [r0]\n"
"BX lr\n"
);
}

static void test_memory(uint32_t addr, uint32_t expected_fatal_count)
{
call_mem(addr);
// Although call_mem is a "naked" function, it is called using AAPCS.
// Thus we can assume LR will point to next instruction, and caller save registers are backed up
TEST_ASSERT_EQUAL(expected_fatal_count, fault_occurred);
}

static void secure_ram_fault_test(void)
{
test_memory(PSA_SECURE_RAM_START, 1);
}

static void secure_flash_fault_test(void)
{
test_memory(PSA_SECURE_ROM_START, 1);
}

static void non_secure_ram_fault_test(void)
{
test_memory(PSA_NON_SECURE_RAM_START, 0);
}

static void non_secure_flash_fault_test(void)
{
test_memory(PSA_NON_SECURE_ROM_START, 0);
}

utest::v1::status_t fault_override_setup(const Case *const source, const size_t index_of_case)
{
// Save old hard fault handler and replace it with a new one
// NOTE: only works when VTOR is set to RAM
real_hard_fault_handler = NVIC_GetVector(HARDFAULT_IRQn);
NVIC_SetVector(HARDFAULT_IRQn, (uint32_t)&hard_fault_handler_test);
fault_occurred = 0;

return greentea_case_setup_handler(source, index_of_case);
}

utest::v1::status_t fault_override_teardown(const Case *const source, const size_t passed, const size_t failed,
const failure_t reason)
{
// Restore real hard fault handler
NVIC_SetVector(HARDFAULT_IRQn, real_hard_fault_handler);

return greentea_case_teardown_handler(source, passed, failed, reason);
}

Case cases[] = {
Case("SPM - Access secure RAM", fault_override_setup, secure_ram_fault_test, fault_override_teardown),
Case("SPM - Access secure Flash", fault_override_setup, secure_flash_fault_test, fault_override_teardown),
Case("SPM - Access non-secure RAM", fault_override_setup, non_secure_ram_fault_test, fault_override_teardown),
Case("SPM - Access non-secure Flash", fault_override_setup, non_secure_flash_fault_test, fault_override_teardown),
};

utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
{
#ifndef NO_GREENTEA
GREENTEA_SETUP(20, "default_auto");
#endif
return greentea_test_setup_handler(number_of_cases);
}

Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);

int main()
{
Harness::run(specification);
}
82 changes: 82 additions & 0 deletions TESTS/psa/prot_internal_storage/COMPONENT_SPE/psa_setup.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/* Copyright (c) 2017-2018 ARM Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* 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.
*/

/***********************************************************************************************************************
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* THIS FILE IS AN AUTO-GENERATED FILE - DO NOT MODIFY IT.
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* Template Version 1.0
* Generated by tools/spm/generate_partition_code.py Version 1.0
**********************************************************************************************************************/

#include "spm_panic.h"
#include "spm_internal.h"
#include "handles_manager.h"
#include "cmsis.h"
#include "psa_test_its_reset_partition.h"
#include "psa_its_partition.h"


spm_partition_t g_partitions[2] = {
{
.partition_id = TEST_ITS_RESET_ID,
.thread_id = 0,
.flags_rot_srv = TEST_ITS_RESET_WAIT_ANY_SID_MSK,
.flags_interrupts = 0,
.rot_services = NULL,
.rot_services_count = TEST_ITS_RESET_ROT_SRV_COUNT,
.extern_sids = NULL,
.extern_sids_count = TEST_ITS_RESET_EXT_ROT_SRV_COUNT,
.irq_mapper = NULL,
},
{
.partition_id = ITS_ID,
.thread_id = 0,
.flags_rot_srv = ITS_WAIT_ANY_SID_MSK,
.flags_interrupts = 0,
.rot_services = NULL,
.rot_services_count = ITS_ROT_SRV_COUNT,
.extern_sids = NULL,
.extern_sids_count = ITS_EXT_ROT_SRV_COUNT,
.irq_mapper = NULL,
},
};

/* Check all the defined memory regions for overlapping. */

/* A list of all the memory regions. */
const mem_region_t *mem_regions = NULL;

const uint32_t mem_region_count = 0;

// forward declaration of partition initializers
void test_its_reset_init(spm_partition_t *partition);
void its_init(spm_partition_t *partition);

uint32_t init_partitions(spm_partition_t **partitions)
{
if (NULL == partitions) {
SPM_PANIC("partitions is NULL!\n");
}

test_its_reset_init(&(g_partitions[0]));
its_init(&(g_partitions[1]));

*partitions = g_partitions;
return 2;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* Copyright (c) 2017-2018 ARM Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* 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.
*/

#include "spm_client.h"
#include "psa_prot_internal_storage.h"
#include "test_pits.h"
#include "psa_test_its_reset_ifs.h"

psa_its_status_t test_psa_its_reset(void)
{
psa_handle_t conn = psa_connect(TEST_PSA_ITS_RESET, 1);
if (conn <= PSA_NULL_HANDLE) {
return PSA_ITS_ERROR_STORAGE_FAILURE;
}

psa_error_t status = psa_call(conn, NULL, 0, NULL, 0);
if (status == PSA_DROP_CONNECTION) {
status = PSA_ITS_ERROR_STORAGE_FAILURE;
}

psa_close(conn);
return status;
}
Loading