1 /*
2  * Copyright (c) 2018-2020 Arm Limited
3  * Copyright (c) 2020 Linaro Limited
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef __BOOT_STATUS_H__
19 #define __BOOT_STATUS_H__
20 
21 #include <stdint.h>
22 #include <stddef.h>
23 
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 /**
30  * The shared data between boot loader and runtime SW is TLV encoded. The
31  * shared data is stored in a well known location in memory and this is a
32  * contract between boot loader and runtime SW.
33  *
34  * The structure of shared data must be the following:
35  *  - At the beginning there must be a header: struct shared_data_tlv_header
36  *    This contains a magic number and a size field which covers the entire
37  *    size of the shared data area including this header.
38  *  - After the header there come the entries which are composed from an entry
39  *    header structure: struct shared_data_tlv_entry and the data. In the entry
40  *    header is a type field (tly_type) which identify the consumer of the
41  *    entry in the runtime SW and specify the subtype of that data item. There
42  *    is a size field (tlv_len) which covers the size of the the data. After
43  *    this structure comes the actual data.
44  *
45  *  - Arbitrary number and size of data entry can be in the shared memory area.
46  *
47  * This table gives of overview about the tlv_type field in the entry header.
48  * The tlv_type always composed from a major and minor number. Major number
49  * identifies the addressee in runtime SW, who should process the data entry.
50  * Minor number used to encode more info about the data entry. The actual
51  * definition of minor number could change per major number.
52  *
53  * In case of boot status data, which can be processed by an attestation
54  * service the minor number is split further to two part: sw_module and claim.
55  * The sw_module identifies the SW component in the system which the data item
56  * belongs to and the claim part identifies the exact type of the data.
57  *
58  * |---------------------------------------|
59  * |            tlv_type (16)              |
60  * |---------------------------------------|
61  * | tlv_major(4)|      tlv_minor(12)      |
62  * |---------------------------------------|
63  * | MAJOR_IAS   | sw_module(6) | claim(6) |
64  * |---------------------------------------|
65  */
66 
67 /* General macros to handle TLV type */
68 #define MAJOR_MASK 0xF     /* 4  bit */
69 #define MAJOR_POS  12      /* 12 bit */
70 #define MINOR_MASK 0xFFF   /* 12 bit */
71 
72 #define SET_TLV_TYPE(major, minor) \
73         (((uint16_t)((major) & MAJOR_MASK) << MAJOR_POS) \
74         | ((minor) & MINOR_MASK))
75 #define GET_MAJOR(tlv_type) ((uint16_t)(tlv_type) >> MAJOR_POS)
76 #define GET_MINOR(tlv_type) ((tlv_type) & MINOR_MASK)
77 
78 /* Magic value which marks the beginning of shared data area in memory */
79 #define SHARED_DATA_TLV_INFO_MAGIC    0x2016
80 
81 /* Initial attestation specific macros */
82 
83 /**
84  * Major numbers (4 bit) to identify the
85  * consumer of shared data in runtime SW.
86  */
87 #define TLV_MAJOR_IAS      0x1
88 
89 /* Initial attestation: Claim per SW components / SW modules */
90 /* Bits: 0-2 */
91 #define SW_VERSION       0x00
92 #define SW_SIGNER_ID     0x01
93 /* Reserved              0x02 */
94 #define SW_TYPE          0x03
95 /* Bits: 3-5 */
96 #define SW_MEASURE_VALUE 0x08
97 #define SW_MEASURE_TYPE  0x09
98 #define SW_BOOT_RECORD   0x3F
99 
100 #define MODULE_POS 6               /* 6 bit */
101 #define CLAIM_MASK 0x3F            /* 6 bit */
102 #define MEASUREMENT_CLAIM_POS 3    /* 3 bit */
103 
104 #define GET_IAS_MODULE(tlv_type) ((uint16_t)GET_MINOR(tlv_type) >> MODULE_POS)
105 #define GET_IAS_CLAIM(tlv_type)  (GET_MINOR(tlv_type) & CLAIM_MASK)
106 #define SET_IAS_MINOR(sw_module, claim) \
107         (((uint16_t)(sw_module) << MODULE_POS) | (claim))
108 
109 /**
110  * Shared data TLV header.  All fields in little endian.
111  *
112  *    -----------------------------------
113  *    | tlv_magic(16) | tlv_tot_len(16) |
114  *    -----------------------------------
115  */
116 struct shared_data_tlv_header {
117     uint16_t tlv_magic;
118     uint16_t tlv_tot_len; /* size of whole TLV area (including this header) */
119 };
120 
121 #define SHARED_DATA_HEADER_SIZE sizeof(struct shared_data_tlv_header)
122 
123 /**
124  * Shared data TLV entry header format. All fields in little endian.
125  *
126  *    -------------------------------
127  *    | tlv_type(16) |  tlv_len(16) |
128  *    -------------------------------
129  *    |         Raw data            |
130  *    -------------------------------
131  */
132 struct shared_data_tlv_entry {
133     uint16_t tlv_type;
134     uint16_t tlv_len; /* TLV data length (not including this header). */
135 };
136 
137 #define SHARED_DATA_ENTRY_HEADER_SIZE sizeof(struct shared_data_tlv_entry)
138 #define SHARED_DATA_ENTRY_SIZE(size) (size + SHARED_DATA_ENTRY_HEADER_SIZE)
139 
140 /* Structure to store the boot data for the runtime SW. */
141 struct shared_boot_data {
142     struct shared_data_tlv_header header;
143     uint8_t data[];
144 };
145 
146 #ifdef __cplusplus
147 }
148 #endif
149 
150 #endif /* __BOOT_STATUS_H__ */
151