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 /* Initial attestation: General claim does not belong any particular SW 97 * component. But they might be part of the boot status. 98 */ 99 #define BOOT_SEED 0x00 100 #define CERT_REF 0x01 101 #define SECURITY_LIFECYCLE 0x02 102 103 /* General macros to handle TLV type */ 104 #define MAJOR_MASK 0xF /* 4 bit */ 105 #define MAJOR_POS 12 /* 12 bit */ 106 #define MINOR_MASK 0xFFF /* 12 bit */ 107 #define MINOR_POS 0 108 109 #define MASK_LEFT_SHIFT(data, mask, position) \ 110 (((data) & (mask)) << (position)) 111 #define MASK_RIGHT_SHIFT(data, mask, position) \ 112 ((uint16_t)((data) & (mask)) >> (position)) 113 114 #define SET_TLV_TYPE(major, minor) \ 115 (MASK_LEFT_SHIFT(major, MAJOR_MASK, MAJOR_POS) | \ 116 MASK_LEFT_SHIFT(minor, MINOR_MASK, MINOR_POS)) 117 #define GET_MAJOR(tlv_type) ((tlv_type) >> MAJOR_POS) 118 #define GET_MINOR(tlv_type) ((tlv_type) & MINOR_MASK) 119 120 /* Initial attestation, Measured boot and Firmware Update common macros */ 121 #define MODULE_POS 6 /* 6 bit */ 122 #define MODULE_MASK 0x3F /* 6 bit */ 123 #define CLAIM_POS 0 124 #define CLAIM_MASK 0x3F /* 6 bit */ 125 126 /* Initial attestation specific macros */ 127 #define MEASUREMENT_CLAIM_POS 3 /* 3 bit */ 128 129 #define GET_IAS_MODULE(tlv_type) \ 130 MASK_RIGHT_SHIFT(tlv_type, MINOR_MASK, MODULE_POS) 131 #define GET_IAS_CLAIM(tlv_type) \ 132 MASK_RIGHT_SHIFT(tlv_type, CLAIM_MASK, CLAIM_POS) 133 #define GET_IAS_MEASUREMENT_CLAIM(ias_claim) \ 134 MASK_RIGHT_SHIFT(ias_claim, CLAIM_MASK, MEASUREMENT_CLAIM_POS) 135 #define SET_IAS_MINOR(sw_module, claim) \ 136 (MASK_LEFT_SHIFT(sw_module, MODULE_MASK, MODULE_POS) | \ 137 MASK_LEFT_SHIFT(claim, CLAIM_MASK, CLAIM_POS)) 138 139 /* Measured boot specific macros */ 140 #define SLOT_ID_POS 6 141 #define SLOT_ID_MASK 0x3F /* 6 bit */ 142 143 #define GET_MBS_SLOT(tlv_type) \ 144 MASK_RIGHT_SHIFT(tlv_type, MINOR_MASK, SLOT_ID_POS) 145 #define GET_MBS_CLAIM(tlv_type) \ 146 MASK_RIGHT_SHIFT(tlv_type, CLAIM_MASK, CLAIM_POS) 147 #define SET_MBS_MINOR(slot_index, claim) \ 148 (MASK_LEFT_SHIFT(slot_index, SLOT_ID_MASK, SLOT_ID_POS) | \ 149 MASK_LEFT_SHIFT(claim, CLAIM_MASK, CLAIM_POS)) 150 151 /* Firmware Update specific macros */ 152 #define GET_FWU_MODULE(tlv_type) \ 153 MASK_RIGHT_SHIFT(tlv_type, MINOR_MASK, MODULE_POS) 154 #define GET_FWU_CLAIM(tlv_type) \ 155 MASK_RIGHT_SHIFT(tlv_type, CLAIM_MASK, CLAIM_POS) 156 #define SET_FWU_MINOR(sw_module, claim) \ 157 (MASK_LEFT_SHIFT(sw_module, MODULE_MASK, MODULE_POS) | \ 158 MASK_LEFT_SHIFT(claim, CLAIM_MASK, CLAIM_POS)) 159 160 /* Magic value which marks the beginning of shared data area in memory */ 161 #define SHARED_DATA_TLV_INFO_MAGIC 0x2016 162 163 /** 164 * Shared data TLV header. All fields in little endian. 165 * 166 * ----------------------------------- 167 * | tlv_magic(16) | tlv_tot_len(16) | 168 * ----------------------------------- 169 */ 170 struct shared_data_tlv_header { 171 uint16_t tlv_magic; 172 uint16_t tlv_tot_len; /* size of whole TLV area (including this header) */ 173 }; 174 175 #define SHARED_DATA_HEADER_SIZE sizeof(struct shared_data_tlv_header) 176 177 /** 178 * Shared data TLV entry header format. All fields in little endian. 179 * 180 * ------------------------------- 181 * | tlv_type(16) | tlv_len(16) | 182 * ------------------------------- 183 * | Raw data | 184 * ------------------------------- 185 */ 186 struct shared_data_tlv_entry { 187 uint16_t tlv_type; 188 uint16_t tlv_len; /* size of single TLV entry (not including this header) */ 189 }; 190 191 /** 192 * \struct tfm_boot_data 193 * 194 * \brief Store the data for the runtime SW 195 */ 196 struct tfm_boot_data { 197 struct shared_data_tlv_header header; 198 uint8_t data[]; 199 }; 200 201 #define SHARED_DATA_ENTRY_HEADER_SIZE sizeof(struct shared_data_tlv_entry) 202 #define SHARED_DATA_ENTRY_SIZE(size) (size + SHARED_DATA_ENTRY_HEADER_SIZE) 203 204 #ifdef __cplusplus 205 } 206 #endif 207 208 #endif /* __TFM_BOOT_STATUS_H__ */ 209