xref: /aosp_15_r20/external/gsc-utils/boot_param/cbor_boot_param.h (revision 4f2df630800bdcf1d4f0decf95d8a1cb87344f5f)
1 /*
2  * Copyright 2024 The ChromiumOS Authors
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6 
7 #ifndef __GSC_UTILS_BOOT_PARAM_CBOR_BOOT_PARAM_H
8 #define __GSC_UTILS_BOOT_PARAM_CBOR_BOOT_PARAM_H
9 
10 #include "cbor_basic.h"
11 #include "boot_param_types.h"
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
17 /* Boot mode decisions.
18  * Boot mode == "Not configured" is not allowed
19  */
20 #define BOOT_MODE_NORMAL   1
21 #define BOOT_MODE_DEBUG	   2
22 #define BOOT_MODE_RECOVERY 3
23 
24 /* Configuration descriptor - see go/gsc-dice
25  */
26 #define CFG_DESCR_LABEL_COMP_NAME     CBOR_NINT32(-70002)
27 #define CFG_DESCR_LABEL_RESETTABLE    CBOR_NINT32(-70004)
28 #define CFG_DESCR_LABEL_SEC_VER	      CBOR_NINT32(-70005)
29 #define CFG_DESCR_LABEL_APROV_STATUS  CBOR_NINT32(-71000)
30 #define CFG_DESCR_LABEL_VBOOT_STATUS  CBOR_NINT32(-71001)
31 #define CFG_DESCR_LABEL_AP_FW_VERSION CBOR_NINT32(-71002)
32 
33 #define CFG_DESCR_COMP_NAME_VALUE_LEN 10 /* "CrOS AP FW" */
34 #define CFG_DESCR_COMP_NAME_LEN	      (1 + CFG_DESCR_COMP_NAME_VALUE_LEN)
35 #define CFG_DESCR_COMP_NAME                                                \
36 	{                                                                  \
37 		CBOR_HDR1(CBOR_MAJOR_TSTR, CFG_DESCR_COMP_NAME_VALUE_LEN), \
38 			'C', 'r', 'O', 'S', ' ', 'A', 'P', ' ', 'F', 'W'   \
39 	}
40 
41 struct cfg_descr_s {
42 	/* Map header: 6 entries */
43 	uint8_t map_hdr;
44 	/* 1. Comp name: nint(-70002, 4bytes) => tstr("CrOS AP FW") */
45 	uint8_t comp_name_label[CBOR_NINT32_LEN];
46 	uint8_t comp_name[CFG_DESCR_COMP_NAME_LEN];
47 	/* 2. Resettable: nint(-70004, 4bytes) => null */
48 	uint8_t resettable_label[CBOR_NINT32_LEN];
49 	uint8_t resettable;
50 	/* 3. Sec ver: nint(-70005, 4bytes) => uint(Security ver, 4bytes) */
51 	uint8_t sec_ver_label[CBOR_NINT32_LEN];
52 	struct cbor_uint32_s sec_ver;
53 	/* 4. APROV status: nint(-71000, 4bytes) => uint(APROV_sts, 4bytes) */
54 	uint8_t aprov_status_label[CBOR_NINT32_LEN];
55 	struct cbor_uint32_s aprov_status;
56 	/* 5. Vboot status: nint(-71001, 4bytes) => bstr(PCR0, 32bytes) */
57 	uint8_t vboot_status_label[CBOR_NINT32_LEN];
58 	struct cbor_bstr32_s vboot_status;
59 	/* 6. AP FW version: nint(-71002, 4bytes) => bstr(PCR10, 32bytes) */
60 	uint8_t ap_fw_version_label[CBOR_NINT32_LEN];
61 	struct cbor_bstr32_s ap_fw_version;
62 };
63 
64 #define CFG_DESCR_LEN sizeof(struct cfg_descr_s)
65 struct cfg_descr_bstr_s {
66 	uint8_t bstr_hdr[2]; /* bstr(sizeof(struct cfg_descr_s), 1byte) */
67 	struct cfg_descr_s data;
68 };
69 #define CFG_DESCR_BSTR_HDR CBOR_BSTR_HDR8(CFG_DESCR_LEN)
70 
71 /* COSE keys - see go/gsc-dice
72  */
73 #define COSE_KEY_LABEL_KTY     CBOR_UINT0(1)
74 #define COSE_KEY_LABEL_ALG     CBOR_UINT0(3)
75 #define COSE_KEY_LABEL_KEY_OPS CBOR_UINT0(4)
76 #define COSE_KEY_LABEL_CRV     CBOR_NINT0(-1)
77 #define COSE_KEY_LABEL_X       CBOR_NINT0(-2)
78 #define COSE_KEY_LABEL_Y       CBOR_NINT0(-3)
79 
80 /* Configuration descriptor per go/gsc-dice
81  */
82 struct cose_key_ecdsa_s {
83 	/* Map header: 6 entries */
84 	uint8_t map_hdr;
85 	/* 1. Key type: uint(1, 0bytes) => uint(2, 0bytes) */
86 	uint8_t kty_label;
87 	uint8_t kty;
88 	/* 2. Algorithm: uint(3, 0bytes) => nint(-1, 0bytes) */
89 	uint8_t alg_label;
90 	uint8_t alg;
91 	/* 3. Key ops: uint(4, 0bytes) => array(1) { uint(2, 0bytes) } */
92 	uint8_t key_ops_label;
93 	uint8_t key_ops_array_hdr;
94 	uint8_t key_ops;
95 	/* 4. Curve: nint(-1, 0bytes) => uint(1, 0bytes) */
96 	uint8_t crv_label;
97 	uint8_t crv;
98 	/* 5. X: nint(-2, 0bytes) => bstr(X, 32bytes) */
99 	uint8_t x_label;
100 	struct cbor_bstr32_s x;
101 	/* 6. X: nint(-3, 0bytes) => bstr(Y, 32bytes) */
102 	uint8_t y_label;
103 	struct cbor_bstr32_s y;
104 };
105 
106 #define COSE_KEY_ECDSA_LEN sizeof(struct cose_key_ecdsa_s)
107 struct cose_key_ecdsa_bstr_s {
108 	uint8_t bstr_hdr[2]; /* bstr(sizeof(struct cose_key_ecdsa_s), 1byte) */
109 	struct cose_key_ecdsa_s data;
110 };
111 #define COSE_KEY_ECDSA_BSTR_HDR CBOR_BSTR_HDR8(COSE_KEY_ECDSA_LEN)
112 
113 /* CWT claims - see go/gsc-dice
114  * Size of TSTR containing an {UDS,CDI}_ID: (24 =< DICE_ID_HEX_LEN < 255)
115  * => 1 byte size encoding
116  */
117 #define DICE_ID_TSTR_LEN (2 + DICE_ID_HEX_BYTES)
118 
119 #define CWT_LABEL_ISS	       CBOR_UINT0(1)
120 #define CWT_LABEL_SUB	       CBOR_UINT0(2)
121 #define CWT_LABEL_CODE_HASH    CBOR_NINT32(-4670545)
122 #define CWT_LABEL_CFG_HASH     CBOR_NINT32(-4670547)
123 #define CWT_LABEL_CFG_DESCR    CBOR_NINT32(-4670548)
124 #define CWT_LABEL_AUTH_HASH    CBOR_NINT32(-4670549)
125 #define CWT_LABEL_MODE	       CBOR_NINT32(-4670551)
126 #define CWT_LABEL_SUBJECT_PK   CBOR_NINT32(-4670552)
127 #define CWT_LABEL_KEY_USAGE    CBOR_NINT32(-4670553)
128 #define CWT_LABEL_PROFILE_NAME CBOR_NINT32(-4670554)
129 
130 #define CWT_PROFILE_NAME_VALUE_LEN 10 /* "android.16" */
131 #define CWT_PROFILE_NAME_LEN	   (1 + CWT_PROFILE_NAME_VALUE_LEN)
132 #define CWT_PROFILE_NAME                                                 \
133 	{                                                                \
134 		CBOR_HDR1(CBOR_MAJOR_TSTR, CWT_PROFILE_NAME_VALUE_LEN),  \
135 			'a', 'n', 'd', 'r', 'o', 'i', 'd', '.', '1', '6' \
136 	}
137 
138 struct cwt_claims_s {
139 	/* Map header: 10 entries */
140 	uint8_t map_hdr;
141 	/* 1. ISS: uint(1, 0bytes) => tstr(hex(UDS_ID)) */
142 	uint8_t iss_label;
143 	struct cbor_tstr40_s iss;
144 	/* 2. SUB: uint(2, 0bytes) => tstr(hex(CDI_ID)) */
145 	uint8_t sub_label;
146 	struct cbor_tstr40_s sub;
147 	/* 3. Code Hash: nint(-4670545, 4bytes) => bstr(32bytes) */
148 	uint8_t code_hash_label[CBOR_NINT32_LEN];
149 	struct cbor_bstr32_s code_hash;
150 	/* 4. Cfg Hash: nint(-4670547, 4bytes) => bstr(32bytes) */
151 	uint8_t cfg_hash_label[CBOR_NINT32_LEN];
152 	struct cbor_bstr32_s cfg_hash;
153 	/* 5. Cfg Descr: nint(-4670548, 4bytes) => bstr(struct cfg_descr_s) */
154 	uint8_t cfg_descr_label[CBOR_NINT32_LEN];
155 	struct cfg_descr_bstr_s cfg_descr;
156 	/* 6. Auth Hash: nint(-4670549, 4bytes) => bstr(32bytes) */
157 	uint8_t auth_hash_label[CBOR_NINT32_LEN];
158 	struct cbor_bstr32_s auth_hash;
159 	/* 7. Mode: nint(-4670551, 4bytes) => bstr(1byte) */
160 	uint8_t mode_label[CBOR_NINT32_LEN];
161 	struct cbor_bstr1_s mode;
162 	/* 8. Subject PK: nint(-4670552, 4bytes) => bstr(COSE_Key) */
163 	uint8_t subject_pk_label[CBOR_NINT32_LEN];
164 	struct cose_key_ecdsa_bstr_s subject_pk;
165 	/* 9. Key Usage: nint(-4670553, 4bytes) => bstr(1byte) */
166 	uint8_t key_usage_label[CBOR_NINT32_LEN];
167 	struct cbor_bstr1_s key_usage;
168 	/* 10. Profile name: nint(-4670554, 4bytes) => tstr("android.16") */
169 	uint8_t profile_name_label[CBOR_NINT32_LEN];
170 	uint8_t profile_name[CWT_PROFILE_NAME_LEN];
171 };
172 
173 #define CWT_CLAIMS_LEN sizeof(struct cwt_claims_s)
174 struct cwt_claims_bstr_s {
175 	uint8_t bstr_hdr[3]; /* bstr(sizeof(struct cose_key_ecdsa_s), 2bytes) */
176 	struct cwt_claims_s data;
177 };
178 #define CWT_CLAIMS_BSTR_HDR CBOR_BSTR_HDR16(CWT_CLAIMS_LEN)
179 
180 /* Protected COSE header parameters - see go/gsc-dice
181  */
182 #define COSE_PARAM_LABEL_ALG CBOR_UINT0(1)
183 struct cose_param_bstr_s {
184 	/* BSTR of size 3 - see the rest of the struct */
185 	uint8_t bstr_hdr;
186 	/* Map header: 1 element */
187 	uint8_t map_hdr;
188 	/* 1. Alg: uint(1, 0bytes) => nint(-7, 0bytes) */
189 	uint8_t alg_label;
190 	uint8_t alg;
191 };
192 
193 #define COSE_PARAM_BSTR                                                       \
194 	{                                                                     \
195 		/* BSTR of size 3 - see the rest of the struct */             \
196 		CBOR_HDR1(CBOR_MAJOR_BSTR, 3),                                \
197 		/* Map header: 1 elem */                                      \
198 		CBOR_HDR1(CBOR_MAJOR_MAP, 1),                                 \
199 		/* 1. Alg: uint(1) => nint(-7) */                             \
200 		COSE_PARAM_LABEL_ALG,                                         \
201 		CBOR_NINT0(-7) /* ECDSA w/ SHA-256 */                         \
202 	}
203 
204 /* Sig structure for CDI certificate - see go/gsc-dice
205  */
206 #define CDI_SIG_STRUCT_CONTEXT_VALUE_LEN 10 /* "Signature1" */
207 #define CDI_SIG_STRUCT_CONTEXT_LEN	 (1 + CDI_SIG_STRUCT_CONTEXT_VALUE_LEN)
208 #define CDI_SIG_STRUCT_CONTEXT                                                \
209 	{                                                                     \
210 		CBOR_HDR1(CBOR_MAJOR_TSTR, CDI_SIG_STRUCT_CONTEXT_VALUE_LEN), \
211 			'S', 'i', 'g', 'n', 'a', 't', 'u', 'r', 'e', '1'      \
212 	}
213 
214 struct cdi_sig_struct_hdr_s {
215 	/* Array header: 4 elements */
216 	uint8_t array_hdr;
217 	/* 1. Context: tstr("Signature1") */
218 	uint8_t context[CDI_SIG_STRUCT_CONTEXT_LEN];
219 	/* 2. Body protected: bstr(COSE param) */
220 	struct cose_param_bstr_s body_protected;
221 	/* 3. External AAD: bstr(0 bytes) */
222 	uint8_t external_aad;
223 	/* 4. Payload - not fixed, contained in cdi_sig_struct_t */
224 };
225 
226 #define CDI_SIG_STRUCT_LEN \
227 	(sizeof(struct cdi_sig_struct_hdr_s) + sizeof(struct cwt_claims_bstr_s))
228 
229 /* CDI certificate = COSE_Sign1 structure - see go/gsc-dice
230  */
231 
232 /* Header of the certificate that includes protected & unprotected
233  * parameters, but not payload (CWT claims) and signature.
234  * This header is actually fixed (no variable fields).
235  * We need it to be able to prepend either it or Sig_structure header to
236  * payload: the former to return as a part of AndroidDiceHandover,
237  * the latter to calculate certificate signature.
238  */
239 struct cdi_cert_hdr_s {
240 	/* Array header: 4 elements */
241 	uint8_t array_hdr;
242 	/* 1. Protected: bstr(COSE param) */
243 	struct cose_param_bstr_s protected;
244 	/* 2. Unprotected: empty map */
245 	uint8_t unprotected;
246 	/* 3. Payload: bstr(CWT claims) - not fixed, struct cwt_claims_bstr_s */
247 	/* 4. Signature: bstr(64 bytes) - not fixed, struct cbor_bstr64_s */
248 };
249 
250 #define CDI_CERT_LEN                        \
251 	(sizeof(struct cdi_cert_hdr_s) +    \
252 	 sizeof(struct cwt_claims_bstr_s) + \
253 	 sizeof(struct cbor_bstr64_s))
254 
255 /* DICE cert chain. In our case, CBOR array consisting of exactly 2 entries
256  * DiceCertChain = [
257  * COSE_Key,       ; UDS pub key
258  * COSE_Sign1,     ; CDI DICE cert
259  * ]
260  */
261 
262 /* Header of DICE cert chain that includes UDS pubkey, but not CDI DICE cert.
263  * This header contains variable fields (UDS key).
264  * We need it to be able to prepend either it + cert header or Sig_structure
265  * header to CWT claims: the former to return as a part of
266  * AndroidDiceHandover, the latter to calculate certificate signature.
267  */
268 struct dice_cert_chain_hdr_s {
269 	/* Array header: 2 elements */
270 	uint8_t array_hdr;
271 	/* 1. UDS pub key: COSE_Key */
272 	struct cose_key_ecdsa_s uds_pub_key;
273 	/* 2. CDI DICE cert: - not included,
274 	 * consists of hdr=cdi_cert_hdr_s, payload=cwt_claims_bstr_s,
275 	 * sig=cbor_bstr64_s
276 	 */
277 };
278 
279 /* Dice Handover struct. In our case, CBOR map with exactly 3 entries:
280  * AndroidDiceHandover = {
281  * 1 : bstr .size 32,     ; CDI_Attest
282  * 2 : bstr .size 32,     ; CDI_Seal
283  * 3 : DiceCertChain,     ; DICE chain - see above
284  * }
285  */
286 
287 #define DICE_HANDOVER_LABEL_CDI_ATTEST CBOR_UINT0(1)
288 #define DICE_HANDOVER_LABEL_CDI_SEAL   CBOR_UINT0(2)
289 #define DICE_HANDOVER_LABEL_DICE_CHAIN CBOR_UINT0(3)
290 
291 /* Header of the DICE handover structure that contains the CDIs, but not the
292  * DICE chain. This header contains variable fields (CDIs). We need it to be
293  * able to prepend either it + DICE chain header + cert header or
294  * Sig_structure header to CWT claims: the former to return as a part of
295  * AndroidDiceHandover, the latter to calculate certificate signature.
296  */
297 struct dice_handover_hdr_s {
298 	/* Map header: 3 elements */
299 	uint8_t map_hdr;
300 	/* 1. CDI_Attest: uint(1, 0bytes) => bstr(32bytes) */
301 	uint8_t cdi_attest_label;
302 	struct cbor_bstr32_s cdi_attest;
303 	/* 2. CDI_Seal: uint(2, 0bytes) => bstr(32bytes) */
304 	uint8_t cdi_seal_label;
305 	struct cbor_bstr32_s cdi_seal;
306 	/* 3. DICE chain: uint(3, 0bytes) => DICE cert chain */
307 	uint8_t dice_chain_label;
308 	/* DICE cert chain is not included */
309 };
310 
311 /* GSC Boot Parameters for TEE.
312  * GSCBootParam = {
313  *   1  : bstr .size 64,     ; EarlyEntropy
314  *   2  : bstr .size 32,     ; SessionKeySeed
315  *   3  : bstr .size 32,     ; AuthTokenKeySeed
316  * }
317  */
318 struct gsc_boot_param_s {
319 	/* Map header: 3 entries */
320 	uint8_t map_hdr;
321 	/* 1. EarlyEntropy: uint(1, 0bytes) => bstr(entropy, 64bytes) */
322 	uint8_t early_entropy_label;
323 	struct cbor_bstr64_s early_entropy;
324 	/* 2. SessionKeySeed: uint(2, 0bytes) => bstr(entropy, 32bytes) */
325 	uint8_t session_key_seed_label;
326 	struct cbor_bstr32_s session_key_seed;
327 	/* 3. AuthTokenKeySeed: uint(3, 0bytes) => bstr(entropy, 32bytes) */
328 	uint8_t auth_token_key_seed_label;
329 	struct cbor_bstr32_s auth_token_key_seed;
330 };
331 
332 #ifdef __cplusplus
333 } /* extern "C" */
334 #endif
335 
336 #endif /* __GSC_UTILS_BOOT_PARAM_CBOR_BOOT_PARAM_H */
337