1 /* 2 * Copyright (c) 2018-2023, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 8 #ifndef __TFM_BOOT_STATUS_H__ 9 #define __TFM_BOOT_STATUS_H__ 10 11 #include <stdint.h> 12 #include <stddef.h> 13 14 15 #ifdef __cplusplus 16 extern "C" { 17 #endif 18 19 /* Major numbers (4 bit) to identify 20 * the consumer of shared data in runtime SW 21 */ 22 #define TLV_MAJOR_CORE 0x0 23 #define TLV_MAJOR_IAS 0x1 24 #define TLV_MAJOR_FWU 0x2 25 #define TLV_MAJOR_MBS 0x3 26 #define TLV_MAJOR_INVALID 0xF 27 28 /** 29 * The shared data between boot loader and runtime SW is TLV encoded. The 30 * shared data is stored in a well known location in secure memory and this is 31 * a contract between boot loader and runtime SW. 32 * 33 * The structure of shared data must be the following: 34 * - At the beginning there must be a header: struct shared_data_tlv_header 35 * This contains a magic number and a size field which covers the entire 36 * size of the shared data area including this header. 37 * - After the header there come the entries which are composed from an entry 38 * header structure: struct shared_data_tlv_entry and the data. In the entry 39 * header is a type field (tlv_type) which identify the consumer of the 40 * entry in the runtime SW and specify the subtype of that data item. There 41 * is a size field (tlv_len) which covers the length of the data 42 * (not including the entry header structure). After this structure comes 43 * the actual data. 44 * - Arbitrary number and size of data entry can be in the shared memory area. 45 * 46 * This table gives of overview about the tlv_type field in the entry header. 47 * The tlv_type always composed from a major and minor number. Major number 48 * identifies the addressee in runtime SW, who should process the data entry. 49 * Minor number used to encode more info about the data entry. The actual 50 * definition of minor number could change per major number. In case of boot 51 * status data, which is going to be processed by initial attestation service 52 * the minor number is split further to two part: sw_module and claim. The 53 * sw_module identifies the SW component in the system which the data item 54 * belongs to and the claim part identifies the exact type of the data. 55 * 56 * |---------------------------------------| 57 * | tlv_type (16) | 58 * |---------------------------------------| 59 * | tlv_major(4)| tlv_minor(12) | 60 * |---------------------------------------| 61 * | MAJOR_IAS | sw_module(6) | claim(6) | 62 * |---------------------------------------| 63 * | MAJOR_MBS | slot ID (6) | claim(6) | 64 * |---------------------------------------| 65 * | MAJOR_CORE | TBD | 66 * |---------------------------------------| 67 */ 68 69 /* Initial attestation: SW components / SW modules 70 * This list is intended to be adjusted per device. It contains more SW 71 * components than currently available in TF-M project. It serves as an example, 72 * what kind of SW components might be available. 73 */ 74 #define SW_GENERAL 0x00 75 #define SW_BL2 0x01 76 #define SW_PROT 0x02 77 #define SW_AROT 0x03 78 #define SW_SPE 0x04 79 #define SW_NSPE 0x05 80 #define SW_S_NS 0x06 81 #define SW_MAX 0x07 82 83 /* Initial attestation and Measured boot service: claim per SW components. */ 84 /* Bits: 0-2 */ 85 #define SW_VERSION 0x00 86 #define SW_SIGNER_ID 0x01 87 /* Reserved 0x02 */ 88 #define SW_TYPE 0x03 89 /* Bits: 3-5 */ 90 #define SW_MEASURE_VALUE 0x08 91 #define SW_MEASURE_TYPE 0x09 92 #define SW_MEASURE_METADATA 0x0A 93 #define SW_MEASURE_VALUE_NON_EXTENDABLE 0x0B 94 #define SW_BOOT_RECORD 0x3F 95 96 /* General macros to handle TLV type */ 97 #define MAJOR_MASK 0xF /* 4 bit */ 98 #define MAJOR_POS 12 /* 12 bit */ 99 #define MINOR_MASK 0xFFF /* 12 bit */ 100 #define MINOR_POS 0 101 102 #define MASK_LEFT_SHIFT(data, mask, position) \ 103 (((data) & (mask)) << (position)) 104 #define MASK_RIGHT_SHIFT(data, mask, position) \ 105 ((uint16_t)((data) & (mask)) >> (position)) 106 107 #define SET_TLV_TYPE(major, minor) \ 108 (MASK_LEFT_SHIFT(major, MAJOR_MASK, MAJOR_POS) | \ 109 MASK_LEFT_SHIFT(minor, MINOR_MASK, MINOR_POS)) 110 #define GET_MAJOR(tlv_type) ((tlv_type) >> MAJOR_POS) 111 #define GET_MINOR(tlv_type) ((tlv_type) & MINOR_MASK) 112 113 /* Initial attestation, Measured boot and Firmware Update common macros */ 114 #define MODULE_POS 6 /* 6 bit */ 115 #define MODULE_MASK 0x3F /* 6 bit */ 116 #define CLAIM_POS 0 117 #define CLAIM_MASK 0x3F /* 6 bit */ 118 119 /* Initial attestation specific macros */ 120 #define MEASUREMENT_CLAIM_POS 3 /* 3 bit */ 121 122 #define GET_IAS_MODULE(tlv_type) \ 123 MASK_RIGHT_SHIFT(tlv_type, MINOR_MASK, MODULE_POS) 124 #define GET_IAS_CLAIM(tlv_type) \ 125 MASK_RIGHT_SHIFT(tlv_type, CLAIM_MASK, CLAIM_POS) 126 #define GET_IAS_MEASUREMENT_CLAIM(ias_claim) \ 127 MASK_RIGHT_SHIFT(ias_claim, CLAIM_MASK, MEASUREMENT_CLAIM_POS) 128 #define SET_IAS_MINOR(sw_module, claim) \ 129 (MASK_LEFT_SHIFT(sw_module, MODULE_MASK, MODULE_POS) | \ 130 MASK_LEFT_SHIFT(claim, CLAIM_MASK, CLAIM_POS)) 131 132 /* Measured boot specific macros */ 133 #define SLOT_ID_POS 6 134 #define SLOT_ID_MASK 0x3F /* 6 bit */ 135 136 #define GET_MBS_SLOT(tlv_type) \ 137 MASK_RIGHT_SHIFT(tlv_type, MINOR_MASK, SLOT_ID_POS) 138 #define GET_MBS_CLAIM(tlv_type) \ 139 MASK_RIGHT_SHIFT(tlv_type, CLAIM_MASK, CLAIM_POS) 140 #define SET_MBS_MINOR(slot_index, claim) \ 141 (MASK_LEFT_SHIFT(slot_index, SLOT_ID_MASK, SLOT_ID_POS) | \ 142 MASK_LEFT_SHIFT(claim, CLAIM_MASK, CLAIM_POS)) 143 144 /* Firmware Update specific macros */ 145 #define GET_FWU_MODULE(tlv_type) \ 146 MASK_RIGHT_SHIFT(tlv_type, MINOR_MASK, MODULE_POS) 147 #define GET_FWU_CLAIM(tlv_type) \ 148 MASK_RIGHT_SHIFT(tlv_type, CLAIM_MASK, CLAIM_POS) 149 #define SET_FWU_MINOR(sw_module, claim) \ 150 (MASK_LEFT_SHIFT(sw_module, MODULE_MASK, MODULE_POS) | \ 151 MASK_LEFT_SHIFT(claim, CLAIM_MASK, CLAIM_POS)) 152 153 /* Magic value which marks the beginning of shared data area in memory */ 154 #define SHARED_DATA_TLV_INFO_MAGIC 0x2016 155 156 /** 157 * Shared data TLV header. All fields in little endian. 158 * 159 * ----------------------------------- 160 * | tlv_magic(16) | tlv_tot_len(16) | 161 * ----------------------------------- 162 */ 163 struct shared_data_tlv_header { 164 uint16_t tlv_magic; 165 uint16_t tlv_tot_len; /* size of whole TLV area (including this header) */ 166 }; 167 168 #define SHARED_DATA_HEADER_SIZE sizeof(struct shared_data_tlv_header) 169 170 /** 171 * Shared data TLV entry header format. All fields in little endian. 172 * 173 * ------------------------------- 174 * | tlv_type(16) | tlv_len(16) | 175 * ------------------------------- 176 * | Raw data | 177 * ------------------------------- 178 */ 179 struct shared_data_tlv_entry { 180 uint16_t tlv_type; 181 uint16_t tlv_len; /* size of single TLV entry (not including this header) */ 182 }; 183 184 /** 185 * \struct tfm_boot_data 186 * 187 * \brief Store the data for the runtime SW 188 */ 189 struct tfm_boot_data { 190 struct shared_data_tlv_header header; 191 uint8_t data[]; 192 }; 193 194 #define SHARED_DATA_ENTRY_HEADER_SIZE sizeof(struct shared_data_tlv_entry) 195 #define SHARED_DATA_ENTRY_SIZE(size) (size + SHARED_DATA_ENTRY_HEADER_SIZE) 196 197 #ifdef __cplusplus 198 } 199 #endif 200 201 #endif /* __TFM_BOOT_STATUS_H__ */ 202