mbed-os5 only for TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Committer:
kenjiArai
Date:
Tue Dec 31 06:02:27 2019 +0000
Revision:
1:9db0e321a9f4
Parent:
0:5b88d5760320
updated based on mbed-os5.15.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:5b88d5760320 1 /*
kenjiArai 0:5b88d5760320 2 * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
kenjiArai 0:5b88d5760320 3 *
kenjiArai 0:5b88d5760320 4 * SPDX-License-Identifier: BSD-3-Clause
kenjiArai 0:5b88d5760320 5 *
kenjiArai 0:5b88d5760320 6 */
kenjiArai 0:5b88d5760320 7
kenjiArai 0:5b88d5760320 8 #include <stdint.h>
kenjiArai 0:5b88d5760320 9 #include "bl2/include/tfm_boot_status.h"
kenjiArai 0:5b88d5760320 10 #include "tfm_memory_utils.h"
kenjiArai 0:5b88d5760320 11 #include "tfm_internal.h"
kenjiArai 0:5b88d5760320 12 #include "tfm_api.h"
kenjiArai 0:5b88d5760320 13 #include "flash_layout.h"
kenjiArai 0:5b88d5760320 14 #include "secure_fw/spm/spm_api.h"
kenjiArai 0:5b88d5760320 15 #ifdef TFM_PSA_API
kenjiArai 0:5b88d5760320 16 #include "tfm_internal_defines.h"
kenjiArai 0:5b88d5760320 17 #include "tfm_utils.h"
kenjiArai 0:5b88d5760320 18 #include "psa_service.h"
kenjiArai 0:5b88d5760320 19 #include "tfm_thread.h"
kenjiArai 0:5b88d5760320 20 #include "tfm_wait.h"
kenjiArai 0:5b88d5760320 21 #include "tfm_message_queue.h"
kenjiArai 0:5b88d5760320 22 #include "tfm_spm.h"
kenjiArai 0:5b88d5760320 23 #endif
kenjiArai 0:5b88d5760320 24
kenjiArai 0:5b88d5760320 25 /*!
kenjiArai 0:5b88d5760320 26 * \def BOOT_DATA_VALID
kenjiArai 0:5b88d5760320 27 *
kenjiArai 0:5b88d5760320 28 * \brief Indicates that shared data between bootloader and runtime firmware was
kenjiArai 0:5b88d5760320 29 * passed the sanity check with success.
kenjiArai 0:5b88d5760320 30 */
kenjiArai 0:5b88d5760320 31 #define BOOT_DATA_VALID (1u)
kenjiArai 0:5b88d5760320 32
kenjiArai 0:5b88d5760320 33 /*!
kenjiArai 0:5b88d5760320 34 * \def BOOT_DATA_INVALID
kenjiArai 0:5b88d5760320 35 *
kenjiArai 0:5b88d5760320 36 * \brief Indicates that shared data between bootloader and runtime firmware was
kenjiArai 0:5b88d5760320 37 * failed on sanity check.
kenjiArai 0:5b88d5760320 38 */
kenjiArai 0:5b88d5760320 39 #define BOOT_DATA_INVALID (0u)
kenjiArai 0:5b88d5760320 40
kenjiArai 0:5b88d5760320 41 /*!
kenjiArai 0:5b88d5760320 42 * \var is_boot_data_valid
kenjiArai 0:5b88d5760320 43 *
kenjiArai 0:5b88d5760320 44 * \brief Indicates the status of shared data between bootloader and runtime
kenjiArai 0:5b88d5760320 45 * firmware
kenjiArai 0:5b88d5760320 46 */
kenjiArai 0:5b88d5760320 47 static uint32_t is_boot_data_valid = BOOT_DATA_INVALID;
kenjiArai 0:5b88d5760320 48
kenjiArai 0:5b88d5760320 49 void tfm_core_validate_boot_data(void)
kenjiArai 0:5b88d5760320 50 {
kenjiArai 0:5b88d5760320 51 struct tfm_boot_data *boot_data;
kenjiArai 0:5b88d5760320 52
kenjiArai 0:5b88d5760320 53 boot_data = (struct tfm_boot_data *)BOOT_TFM_SHARED_DATA_BASE;
kenjiArai 0:5b88d5760320 54
kenjiArai 0:5b88d5760320 55 /* FixMe: Enhance sanity check of shared memory area, it might be invalid:
kenjiArai 0:5b88d5760320 56 * - temporal exposure of RAM to non-secure actors
kenjiArai 0:5b88d5760320 57 * - mismatched addresses
kenjiArai 0:5b88d5760320 58 * - version mismatch between bootloader and runtime binary
kenjiArai 0:5b88d5760320 59 * - etc.
kenjiArai 0:5b88d5760320 60 */
kenjiArai 0:5b88d5760320 61 if (boot_data->header.tlv_magic == SHARED_DATA_TLV_INFO_MAGIC) {
kenjiArai 0:5b88d5760320 62 is_boot_data_valid = BOOT_DATA_VALID;
kenjiArai 0:5b88d5760320 63 }
kenjiArai 0:5b88d5760320 64 }
kenjiArai 0:5b88d5760320 65
kenjiArai 0:5b88d5760320 66 void tfm_core_get_boot_data_handler(uint32_t args[])
kenjiArai 0:5b88d5760320 67 {
kenjiArai 0:5b88d5760320 68 uint8_t tlv_major = (uint8_t)args[0];
kenjiArai 0:5b88d5760320 69 uint8_t *buf_start = (uint8_t *)args[1];
kenjiArai 0:5b88d5760320 70 uint16_t buf_size = (uint16_t)args[2];
kenjiArai 0:5b88d5760320 71 uint8_t *ptr;
kenjiArai 0:5b88d5760320 72 struct tfm_boot_data *boot_data;
kenjiArai 0:5b88d5760320 73 struct shared_data_tlv_entry tlv_entry;
kenjiArai 0:5b88d5760320 74 uintptr_t tlv_end, offset;
kenjiArai 0:5b88d5760320 75 #ifndef TFM_PSA_API
kenjiArai 0:5b88d5760320 76 uint32_t running_partition_idx =
kenjiArai 0:5b88d5760320 77 tfm_spm_partition_get_running_partition_idx();
kenjiArai 0:5b88d5760320 78 uint32_t res;
kenjiArai 0:5b88d5760320 79 #else
kenjiArai 0:5b88d5760320 80 struct tfm_spm_ipc_partition_t *partition = NULL;
kenjiArai 0:5b88d5760320 81 uint32_t privileged;
kenjiArai 0:5b88d5760320 82 #endif
kenjiArai 0:5b88d5760320 83
kenjiArai 0:5b88d5760320 84 #ifndef TFM_PSA_API
kenjiArai 0:5b88d5760320 85 /* Make sure that the output pointer points to a memory area that is owned
kenjiArai 0:5b88d5760320 86 * by the partition
kenjiArai 0:5b88d5760320 87 */
kenjiArai 0:5b88d5760320 88 res = tfm_core_check_buffer_access(running_partition_idx,
kenjiArai 0:5b88d5760320 89 (void *)buf_start,
kenjiArai 0:5b88d5760320 90 buf_size,
kenjiArai 0:5b88d5760320 91 2); /* Check 4 bytes alignment */
kenjiArai 0:5b88d5760320 92 if (!res) {
kenjiArai 0:5b88d5760320 93 /* Not in accessible range, return error */
kenjiArai 0:5b88d5760320 94 args[0] = TFM_ERROR_INVALID_PARAMETER;
kenjiArai 0:5b88d5760320 95 return;
kenjiArai 0:5b88d5760320 96 }
kenjiArai 0:5b88d5760320 97 #else
kenjiArai 0:5b88d5760320 98 partition = tfm_spm_get_running_partition();
kenjiArai 0:5b88d5760320 99 if (!partition) {
kenjiArai 0:5b88d5760320 100 tfm_panic();
kenjiArai 0:5b88d5760320 101 }
kenjiArai 0:5b88d5760320 102 privileged = tfm_spm_partition_get_privileged_mode(partition->index);
kenjiArai 0:5b88d5760320 103
kenjiArai 0:5b88d5760320 104 if (tfm_memory_check(buf_start, buf_size, false, TFM_MEMORY_ACCESS_RW,
kenjiArai 0:5b88d5760320 105 privileged) != IPC_SUCCESS) {
kenjiArai 0:5b88d5760320 106 /* Not in accessible range, return error */
kenjiArai 0:5b88d5760320 107 args[0] = TFM_ERROR_INVALID_PARAMETER;
kenjiArai 0:5b88d5760320 108 return;
kenjiArai 0:5b88d5760320 109 }
kenjiArai 0:5b88d5760320 110 #endif
kenjiArai 0:5b88d5760320 111
kenjiArai 0:5b88d5760320 112 /* FixMe: Check whether caller has access right to given tlv_major_type */
kenjiArai 0:5b88d5760320 113
kenjiArai 0:5b88d5760320 114 if (is_boot_data_valid != BOOT_DATA_VALID) {
kenjiArai 0:5b88d5760320 115 args[0] = TFM_ERROR_INVALID_PARAMETER;
kenjiArai 0:5b88d5760320 116 return;
kenjiArai 0:5b88d5760320 117 }
kenjiArai 0:5b88d5760320 118
kenjiArai 0:5b88d5760320 119 /* Get the boundaries of TLV section */
kenjiArai 0:5b88d5760320 120 boot_data = (struct tfm_boot_data *)BOOT_TFM_SHARED_DATA_BASE;
kenjiArai 0:5b88d5760320 121 tlv_end = BOOT_TFM_SHARED_DATA_BASE + boot_data->header.tlv_tot_len;
kenjiArai 0:5b88d5760320 122 offset = BOOT_TFM_SHARED_DATA_BASE + SHARED_DATA_HEADER_SIZE;
kenjiArai 0:5b88d5760320 123
kenjiArai 0:5b88d5760320 124 /* Add header to output buffer as well */
kenjiArai 0:5b88d5760320 125 if (buf_size < SHARED_DATA_HEADER_SIZE) {
kenjiArai 0:5b88d5760320 126 args[0] = TFM_ERROR_INVALID_PARAMETER;
kenjiArai 0:5b88d5760320 127 return;
kenjiArai 0:5b88d5760320 128 } else {
kenjiArai 0:5b88d5760320 129 boot_data = (struct tfm_boot_data *)buf_start;
kenjiArai 0:5b88d5760320 130 boot_data->header.tlv_magic = SHARED_DATA_TLV_INFO_MAGIC;
kenjiArai 0:5b88d5760320 131 boot_data->header.tlv_tot_len = SHARED_DATA_HEADER_SIZE;
kenjiArai 0:5b88d5760320 132 ptr = boot_data->data;
kenjiArai 0:5b88d5760320 133 }
kenjiArai 0:5b88d5760320 134
kenjiArai 0:5b88d5760320 135 /* Iterates over the TLV section and copy TLVs with requested major
kenjiArai 0:5b88d5760320 136 * type to the provided buffer.
kenjiArai 0:5b88d5760320 137 */
kenjiArai 0:5b88d5760320 138 for (; offset < tlv_end; offset += tlv_entry.tlv_len) {
kenjiArai 0:5b88d5760320 139 /* Create local copy to avoid unaligned access */
kenjiArai 0:5b88d5760320 140 tfm_memcpy(&tlv_entry,
kenjiArai 0:5b88d5760320 141 (const void *)offset,
kenjiArai 0:5b88d5760320 142 SHARED_DATA_ENTRY_HEADER_SIZE);
kenjiArai 0:5b88d5760320 143 if (GET_MAJOR(tlv_entry.tlv_type) == tlv_major) {
kenjiArai 0:5b88d5760320 144 /* Check buffer overflow */
kenjiArai 0:5b88d5760320 145 if (((ptr - buf_start) + tlv_entry.tlv_len) > buf_size) {
kenjiArai 0:5b88d5760320 146 args[0] = TFM_ERROR_INVALID_PARAMETER;
kenjiArai 0:5b88d5760320 147 return;
kenjiArai 0:5b88d5760320 148 }
kenjiArai 0:5b88d5760320 149
kenjiArai 0:5b88d5760320 150 tfm_memcpy(ptr, (const void *)offset, tlv_entry.tlv_len);
kenjiArai 0:5b88d5760320 151
kenjiArai 0:5b88d5760320 152 ptr += tlv_entry.tlv_len;
kenjiArai 0:5b88d5760320 153 boot_data->header.tlv_tot_len += tlv_entry.tlv_len;
kenjiArai 0:5b88d5760320 154 }
kenjiArai 0:5b88d5760320 155 }
kenjiArai 0:5b88d5760320 156 args[0] = TFM_SUCCESS;
kenjiArai 0:5b88d5760320 157 return;
kenjiArai 0:5b88d5760320 158 }