1*4f2df630SAndroid Build Coastguard Worker /*
2*4f2df630SAndroid Build Coastguard Worker * Copyright 2024 The ChromiumOS Authors
3*4f2df630SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
4*4f2df630SAndroid Build Coastguard Worker * found in the LICENSE file.
5*4f2df630SAndroid Build Coastguard Worker */
6*4f2df630SAndroid Build Coastguard Worker
7*4f2df630SAndroid Build Coastguard Worker #include "cbor_boot_param.h"
8*4f2df630SAndroid Build Coastguard Worker #include "cdi.h"
9*4f2df630SAndroid Build Coastguard Worker #include "boot_param.h"
10*4f2df630SAndroid Build Coastguard Worker #include "boot_param_platform.h"
11*4f2df630SAndroid Build Coastguard Worker
12*4f2df630SAndroid Build Coastguard Worker /* Common structure to build Sig_structure or DICE Handover structure
13*4f2df630SAndroid Build Coastguard Worker */
14*4f2df630SAndroid Build Coastguard Worker
15*4f2df630SAndroid Build Coastguard Worker /* Combined headers before cert payload (CWT claims) in DICE handover
16*4f2df630SAndroid Build Coastguard Worker */
17*4f2df630SAndroid Build Coastguard Worker struct combined_hdr_s {
18*4f2df630SAndroid Build Coastguard Worker struct dice_cert_chain_hdr_s cert_chain;
19*4f2df630SAndroid Build Coastguard Worker struct cdi_cert_hdr_s cert;
20*4f2df630SAndroid Build Coastguard Worker };
21*4f2df630SAndroid Build Coastguard Worker
22*4f2df630SAndroid Build Coastguard Worker union header_options_s {
23*4f2df630SAndroid Build Coastguard Worker uint8_t sig_struct[sizeof(struct combined_hdr_s)];
24*4f2df630SAndroid Build Coastguard Worker struct combined_hdr_s dice_handover;
25*4f2df630SAndroid Build Coastguard Worker };
26*4f2df630SAndroid Build Coastguard Worker
27*4f2df630SAndroid Build Coastguard Worker /* We need the following to be able to fill CDIs in dice_handover_s::hdr
28*4f2df630SAndroid Build Coastguard Worker * before we temporarily use dice_handover_s::options.sig_struct to calc
29*4f2df630SAndroid Build Coastguard Worker * signature.
30*4f2df630SAndroid Build Coastguard Worker */
31*4f2df630SAndroid Build Coastguard Worker _Static_assert(
32*4f2df630SAndroid Build Coastguard Worker sizeof(struct combined_hdr_s) >= sizeof(struct cdi_sig_struct_hdr_s)
33*4f2df630SAndroid Build Coastguard Worker );
34*4f2df630SAndroid Build Coastguard Worker
35*4f2df630SAndroid Build Coastguard Worker struct dice_handover_s {
36*4f2df630SAndroid Build Coastguard Worker struct dice_handover_hdr_s hdr;
37*4f2df630SAndroid Build Coastguard Worker union header_options_s options;
38*4f2df630SAndroid Build Coastguard Worker struct cwt_claims_bstr_s payload;
39*4f2df630SAndroid Build Coastguard Worker struct cbor_bstr64_s signature;
40*4f2df630SAndroid Build Coastguard Worker };
41*4f2df630SAndroid Build Coastguard Worker _Static_assert(
42*4f2df630SAndroid Build Coastguard Worker sizeof(struct dice_handover_s) - sizeof(struct dice_handover_hdr_s) ==
43*4f2df630SAndroid Build Coastguard Worker DICE_CHAIN_SIZE
44*4f2df630SAndroid Build Coastguard Worker );
45*4f2df630SAndroid Build Coastguard Worker
46*4f2df630SAndroid Build Coastguard Worker /* BootParam = {
47*4f2df630SAndroid Build Coastguard Worker * 1 : uint, ; structure version (0)
48*4f2df630SAndroid Build Coastguard Worker * 2 : GSCBootParam,
49*4f2df630SAndroid Build Coastguard Worker * 3 : AndroidDiceHandover,
50*4f2df630SAndroid Build Coastguard Worker * }
51*4f2df630SAndroid Build Coastguard Worker */
52*4f2df630SAndroid Build Coastguard Worker #define BOOT_PARAM_VERSION 0
53*4f2df630SAndroid Build Coastguard Worker struct boot_param_s {
54*4f2df630SAndroid Build Coastguard Worker /* Map header: 3 entries */
55*4f2df630SAndroid Build Coastguard Worker uint8_t map_hdr;
56*4f2df630SAndroid Build Coastguard Worker /* 1. Version: uint(1, 0bytes) => uint(BOOT_PARAM_VERSION, 0bytes) */
57*4f2df630SAndroid Build Coastguard Worker uint8_t version_label;
58*4f2df630SAndroid Build Coastguard Worker uint8_t version;
59*4f2df630SAndroid Build Coastguard Worker /* 2. GSCBootParam: uint(2, 0bytes) => GSCBootParam */
60*4f2df630SAndroid Build Coastguard Worker uint8_t gsc_boot_param_label;
61*4f2df630SAndroid Build Coastguard Worker struct gsc_boot_param_s gsc_boot_param;
62*4f2df630SAndroid Build Coastguard Worker /* 3. AndroidDiceHandover: uint(3, 0bytes) => AndroidDiceHandover */
63*4f2df630SAndroid Build Coastguard Worker uint8_t dice_handover_label;
64*4f2df630SAndroid Build Coastguard Worker struct dice_handover_s dice_handover;
65*4f2df630SAndroid Build Coastguard Worker };
66*4f2df630SAndroid Build Coastguard Worker _Static_assert(sizeof(struct boot_param_s) == BOOT_PARAM_SIZE);
67*4f2df630SAndroid Build Coastguard Worker
68*4f2df630SAndroid Build Coastguard Worker /* Context to pass between functions that build the DICE handover structure
69*4f2df630SAndroid Build Coastguard Worker */
70*4f2df630SAndroid Build Coastguard Worker struct dice_ctx_s {
71*4f2df630SAndroid Build Coastguard Worker struct boot_param_s output;
72*4f2df630SAndroid Build Coastguard Worker struct dice_config_s cfg;
73*4f2df630SAndroid Build Coastguard Worker };
74*4f2df630SAndroid Build Coastguard Worker
75*4f2df630SAndroid Build Coastguard Worker /* PCR0 values for various modes - see go/pcr0-tpm2 */
76*4f2df630SAndroid Build Coastguard Worker static const uint8_t kPcr0NormalMode[DIGEST_BYTES] = {
77*4f2df630SAndroid Build Coastguard Worker 0x89, 0xEA, 0xF3, 0x51, 0x34, 0xB4, 0xB3, 0xC6,
78*4f2df630SAndroid Build Coastguard Worker 0x49, 0xF4, 0x4C, 0x0C, 0x76, 0x5B, 0x96, 0xAE,
79*4f2df630SAndroid Build Coastguard Worker 0xAB, 0x8B, 0xB3, 0x4E, 0xE8, 0x3C, 0xC7, 0xA6,
80*4f2df630SAndroid Build Coastguard Worker 0x83, 0xC4, 0xE5, 0x3D, 0x15, 0x81, 0xC8, 0xC7
81*4f2df630SAndroid Build Coastguard Worker };
82*4f2df630SAndroid Build Coastguard Worker static const uint8_t kPcr0RecoveryNormalMode[DIGEST_BYTES] = {
83*4f2df630SAndroid Build Coastguard Worker 0x9F, 0x9E, 0xA8, 0x66, 0xD3, 0xF3, 0x4F, 0xE3,
84*4f2df630SAndroid Build Coastguard Worker 0xA3, 0x11, 0x2A, 0xE9, 0xCB, 0x1F, 0xBA, 0xBC,
85*4f2df630SAndroid Build Coastguard Worker 0x6F, 0xFE, 0x8C, 0xD2, 0x61, 0xD4, 0x24, 0x93,
86*4f2df630SAndroid Build Coastguard Worker 0xBC, 0x68, 0x42, 0xA9, 0xE4, 0xF9, 0x3B, 0x3D
87*4f2df630SAndroid Build Coastguard Worker };
88*4f2df630SAndroid Build Coastguard Worker
89*4f2df630SAndroid Build Coastguard Worker /* Const salts - see go/gsc-dice */
90*4f2df630SAndroid Build Coastguard Worker static const uint8_t kIdSalt[64] = {
91*4f2df630SAndroid Build Coastguard Worker 0xDB, 0xDB, 0xAE, 0xBC, 0x80, 0x20, 0xDA, 0x9F,
92*4f2df630SAndroid Build Coastguard Worker 0xF0, 0xDD, 0x5A, 0x24, 0xC8, 0x3A, 0xA5, 0xA5,
93*4f2df630SAndroid Build Coastguard Worker 0x42, 0x86, 0xDF, 0xC2, 0x63, 0x03, 0x1E, 0x32,
94*4f2df630SAndroid Build Coastguard Worker 0x9B, 0x4D, 0xA1, 0x48, 0x43, 0x06, 0x59, 0xFE,
95*4f2df630SAndroid Build Coastguard Worker 0x62, 0xCD, 0xB5, 0xB7, 0xE1, 0xE0, 0x0F, 0xC6,
96*4f2df630SAndroid Build Coastguard Worker 0x80, 0x30, 0x67, 0x11, 0xEB, 0x44, 0x4A, 0xF7,
97*4f2df630SAndroid Build Coastguard Worker 0x72, 0x09, 0x35, 0x94, 0x96, 0xFC, 0xFF, 0x1D,
98*4f2df630SAndroid Build Coastguard Worker 0xB9, 0x52, 0x0B, 0xA5, 0x1C, 0x7B, 0x29, 0xEA
99*4f2df630SAndroid Build Coastguard Worker };
100*4f2df630SAndroid Build Coastguard Worker static const uint8_t kAsymSalt[64] = {
101*4f2df630SAndroid Build Coastguard Worker 0x63, 0xB6, 0xA0, 0x4D, 0x2C, 0x07, 0x7F, 0xC1,
102*4f2df630SAndroid Build Coastguard Worker 0x0F, 0x63, 0x9F, 0x21, 0xDA, 0x79, 0x38, 0x44,
103*4f2df630SAndroid Build Coastguard Worker 0x35, 0x6C, 0xC2, 0xB0, 0xB4, 0x41, 0xB3, 0xA7,
104*4f2df630SAndroid Build Coastguard Worker 0x71, 0x24, 0x03, 0x5C, 0x03, 0xF8, 0xE1, 0xBE,
105*4f2df630SAndroid Build Coastguard Worker 0x60, 0x35, 0xD3, 0x1F, 0x28, 0x28, 0x21, 0xA7,
106*4f2df630SAndroid Build Coastguard Worker 0x45, 0x0A, 0x02, 0x22, 0x2A, 0xB1, 0xB3, 0xCF,
107*4f2df630SAndroid Build Coastguard Worker 0xF1, 0x67, 0x9B, 0x05, 0xAB, 0x1C, 0xA5, 0xD1,
108*4f2df630SAndroid Build Coastguard Worker 0xAF, 0xFB, 0x78, 0x9C, 0xCD, 0x2B, 0x0B, 0x3B
109*4f2df630SAndroid Build Coastguard Worker };
110*4f2df630SAndroid Build Coastguard Worker static const uint8_t kSigHdr[2] = CBOR_BSTR64_HDR;
111*4f2df630SAndroid Build Coastguard Worker
112*4f2df630SAndroid Build Coastguard Worker static const struct cwt_claims_bstr_s kCwtClaimsTemplate = {
113*4f2df630SAndroid Build Coastguard Worker CWT_CLAIMS_BSTR_HDR,
114*4f2df630SAndroid Build Coastguard Worker {
115*4f2df630SAndroid Build Coastguard Worker /* Map header: 10 entries */
116*4f2df630SAndroid Build Coastguard Worker CBOR_HDR1(CBOR_MAJOR_MAP, 10),
117*4f2df630SAndroid Build Coastguard Worker /* 1. ISS: uint(1, 0bytes) => tstr(hex(UDS_ID)) */
118*4f2df630SAndroid Build Coastguard Worker CWT_LABEL_ISS,
119*4f2df630SAndroid Build Coastguard Worker CBOR_TSTR40_EMPTY, /* CALC - calc from UDS */
120*4f2df630SAndroid Build Coastguard Worker /* 2. SUB: uint(2, 0bytes) =>
121*4f2df630SAndroid Build Coastguard Worker * tstr(hex(CDI_ID))
122*4f2df630SAndroid Build Coastguard Worker */
123*4f2df630SAndroid Build Coastguard Worker CWT_LABEL_SUB,
124*4f2df630SAndroid Build Coastguard Worker CBOR_TSTR40_EMPTY, /* CALC - calc from CDI */
125*4f2df630SAndroid Build Coastguard Worker /* 3. Code Hash: nint(-4670545, 4bytes) =>
126*4f2df630SAndroid Build Coastguard Worker * bstr(32bytes)
127*4f2df630SAndroid Build Coastguard Worker */
128*4f2df630SAndroid Build Coastguard Worker CWT_LABEL_CODE_HASH,
129*4f2df630SAndroid Build Coastguard Worker CBOR_BSTR32_EMPTY, /* VARIABLE */
130*4f2df630SAndroid Build Coastguard Worker /* 4. Cfg Hash: nint(-4670547, 4bytes) =>
131*4f2df630SAndroid Build Coastguard Worker * bstr(32bytes)
132*4f2df630SAndroid Build Coastguard Worker */
133*4f2df630SAndroid Build Coastguard Worker CWT_LABEL_CFG_HASH,
134*4f2df630SAndroid Build Coastguard Worker CBOR_BSTR32_EMPTY, /* CALC - calc from CfgDescr */
135*4f2df630SAndroid Build Coastguard Worker /* 5. Cfg Descr: nint(-4670548, 4bytes) =>
136*4f2df630SAndroid Build Coastguard Worker * bstr(struct cfg_descr_s)
137*4f2df630SAndroid Build Coastguard Worker */
138*4f2df630SAndroid Build Coastguard Worker CWT_LABEL_CFG_DESCR,
139*4f2df630SAndroid Build Coastguard Worker /* struct cfg_descr_bstr_s */
140*4f2df630SAndroid Build Coastguard Worker {
141*4f2df630SAndroid Build Coastguard Worker CFG_DESCR_BSTR_HDR,
142*4f2df630SAndroid Build Coastguard Worker /* struct cfg_descr_s */
143*4f2df630SAndroid Build Coastguard Worker {
144*4f2df630SAndroid Build Coastguard Worker /* Map header: 6 entries */
145*4f2df630SAndroid Build Coastguard Worker CBOR_HDR1(CBOR_MAJOR_MAP, 6),
146*4f2df630SAndroid Build Coastguard Worker /* 1. Comp name: nint(-70002, 4bytes) =>
147*4f2df630SAndroid Build Coastguard Worker * tstr("CrOS AP FW")
148*4f2df630SAndroid Build Coastguard Worker */
149*4f2df630SAndroid Build Coastguard Worker CFG_DESCR_LABEL_COMP_NAME,
150*4f2df630SAndroid Build Coastguard Worker CFG_DESCR_COMP_NAME,
151*4f2df630SAndroid Build Coastguard Worker /* 2. Resettable: nint(-70004, 4bytes) => null
152*4f2df630SAndroid Build Coastguard Worker */
153*4f2df630SAndroid Build Coastguard Worker CFG_DESCR_LABEL_RESETTABLE,
154*4f2df630SAndroid Build Coastguard Worker CBOR_NULL,
155*4f2df630SAndroid Build Coastguard Worker /* 3. Sec ver: nint(-70005, 4bytes) =>
156*4f2df630SAndroid Build Coastguard Worker * uint(Security ver, 4bytes)
157*4f2df630SAndroid Build Coastguard Worker */
158*4f2df630SAndroid Build Coastguard Worker CFG_DESCR_LABEL_SEC_VER,
159*4f2df630SAndroid Build Coastguard Worker CBOR_UINT32_ZERO, /* VARIABLE */
160*4f2df630SAndroid Build Coastguard Worker /* 4. APROV status:
161*4f2df630SAndroid Build Coastguard Worker * nint(-71000, 4bytes) =>
162*4f2df630SAndroid Build Coastguard Worker * uint(APROV status, 4bytes)
163*4f2df630SAndroid Build Coastguard Worker */
164*4f2df630SAndroid Build Coastguard Worker CFG_DESCR_LABEL_APROV_STATUS,
165*4f2df630SAndroid Build Coastguard Worker CBOR_UINT32_ZERO, /* VARIABLE */
166*4f2df630SAndroid Build Coastguard Worker /* 5. Vboot status: */
167*4f2df630SAndroid Build Coastguard Worker /* nint(-71000, 4bytes) => */
168*4f2df630SAndroid Build Coastguard Worker /* bstr(PCR0, 32bytes) */
169*4f2df630SAndroid Build Coastguard Worker CFG_DESCR_LABEL_VBOOT_STATUS,
170*4f2df630SAndroid Build Coastguard Worker CBOR_BSTR32_EMPTY, /* VARIABLE */
171*4f2df630SAndroid Build Coastguard Worker /* 6. AP FW version: */
172*4f2df630SAndroid Build Coastguard Worker /* nint(-71002, 4bytes) => */
173*4f2df630SAndroid Build Coastguard Worker /* bstr(PCR10, 32bytes) */
174*4f2df630SAndroid Build Coastguard Worker CFG_DESCR_LABEL_AP_FW_VERSION,
175*4f2df630SAndroid Build Coastguard Worker CBOR_BSTR32_EMPTY, /* VARIABLE */
176*4f2df630SAndroid Build Coastguard Worker },
177*4f2df630SAndroid Build Coastguard Worker },
178*4f2df630SAndroid Build Coastguard Worker /* 6. Auth Hash: nint(-4670549, 4bytes) => bstr(32bytes) */
179*4f2df630SAndroid Build Coastguard Worker CWT_LABEL_AUTH_HASH,
180*4f2df630SAndroid Build Coastguard Worker CBOR_BSTR32_EMPTY, /* always zero */
181*4f2df630SAndroid Build Coastguard Worker /* 7. Mode: nint(-4670551, 4bytes) => bstr(1byte) */
182*4f2df630SAndroid Build Coastguard Worker CWT_LABEL_MODE,
183*4f2df630SAndroid Build Coastguard Worker CBOR_BSTR1_EMPTY, /* VARIABLE */
184*4f2df630SAndroid Build Coastguard Worker /* 8. Subject PK: nint(-4670552, 4bytes) => bstr(COSE_Key) */
185*4f2df630SAndroid Build Coastguard Worker CWT_LABEL_SUBJECT_PK,
186*4f2df630SAndroid Build Coastguard Worker /* struct cose_key_ecdsa_bstr_s */
187*4f2df630SAndroid Build Coastguard Worker {
188*4f2df630SAndroid Build Coastguard Worker COSE_KEY_ECDSA_BSTR_HDR,
189*4f2df630SAndroid Build Coastguard Worker /* struct cose_key_ecdsa_s */
190*4f2df630SAndroid Build Coastguard Worker {
191*4f2df630SAndroid Build Coastguard Worker /* Map header: 6 entries */
192*4f2df630SAndroid Build Coastguard Worker CBOR_HDR1(CBOR_MAJOR_MAP, 6),
193*4f2df630SAndroid Build Coastguard Worker /* 1. Key type: uint(1, 0bytes) =>
194*4f2df630SAndroid Build Coastguard Worker * uint(2, 0bytes)
195*4f2df630SAndroid Build Coastguard Worker */
196*4f2df630SAndroid Build Coastguard Worker COSE_KEY_LABEL_KTY,
197*4f2df630SAndroid Build Coastguard Worker CBOR_UINT0(2), /* EC2 */
198*4f2df630SAndroid Build Coastguard Worker /* 2. Algorithm: uint(3, 0bytes) =>
199*4f2df630SAndroid Build Coastguard Worker * nint(-1, 0bytes)
200*4f2df630SAndroid Build Coastguard Worker */
201*4f2df630SAndroid Build Coastguard Worker COSE_KEY_LABEL_ALG,
202*4f2df630SAndroid Build Coastguard Worker CBOR_NINT0(-7), /* ECDSA w/SHA-256 */
203*4f2df630SAndroid Build Coastguard Worker /* 3. Key ops: uint(4, 0bytes) =>
204*4f2df630SAndroid Build Coastguard Worker * array(1) { uint(2, 0bytes) }
205*4f2df630SAndroid Build Coastguard Worker */
206*4f2df630SAndroid Build Coastguard Worker COSE_KEY_LABEL_KEY_OPS,
207*4f2df630SAndroid Build Coastguard Worker CBOR_HDR1(CBOR_MAJOR_ARR, 1),
208*4f2df630SAndroid Build Coastguard Worker CBOR_UINT0(2),
209*4f2df630SAndroid Build Coastguard Worker /* 4. Curve: nint(-1, 0bytes) => uint(1, 0bytes)
210*4f2df630SAndroid Build Coastguard Worker */
211*4f2df630SAndroid Build Coastguard Worker COSE_KEY_LABEL_CRV,
212*4f2df630SAndroid Build Coastguard Worker CBOR_UINT0(1), /* P-256 */
213*4f2df630SAndroid Build Coastguard Worker /* 5. X: nint(-2, 0bytes) =>
214*4f2df630SAndroid Build Coastguard Worker * bstr(X, 32bytes)
215*4f2df630SAndroid Build Coastguard Worker */
216*4f2df630SAndroid Build Coastguard Worker COSE_KEY_LABEL_X,
217*4f2df630SAndroid Build Coastguard Worker CBOR_BSTR32_EMPTY, /* VARIABLE */
218*4f2df630SAndroid Build Coastguard Worker /* 6. X: nint(-3, 0bytes) =>
219*4f2df630SAndroid Build Coastguard Worker * bstr(Y, 32bytes)
220*4f2df630SAndroid Build Coastguard Worker */
221*4f2df630SAndroid Build Coastguard Worker COSE_KEY_LABEL_Y,
222*4f2df630SAndroid Build Coastguard Worker CBOR_BSTR32_EMPTY, /* VARIABLE */
223*4f2df630SAndroid Build Coastguard Worker },
224*4f2df630SAndroid Build Coastguard Worker },
225*4f2df630SAndroid Build Coastguard Worker /* 9. Key Usage: nint(-4670553, 4bytes) => bstr(1byte) */
226*4f2df630SAndroid Build Coastguard Worker CWT_LABEL_KEY_USAGE,
227*4f2df630SAndroid Build Coastguard Worker {
228*4f2df630SAndroid Build Coastguard Worker CBOR_HDR1(CBOR_MAJOR_BSTR, 1),
229*4f2df630SAndroid Build Coastguard Worker 0x20, /* keyCertSign */
230*4f2df630SAndroid Build Coastguard Worker },
231*4f2df630SAndroid Build Coastguard Worker /* 10. Profile name: nint(-4670554, 4bytes) => */
232*4f2df630SAndroid Build Coastguard Worker /* tstr("android.16") */
233*4f2df630SAndroid Build Coastguard Worker CWT_LABEL_PROFILE_NAME,
234*4f2df630SAndroid Build Coastguard Worker CWT_PROFILE_NAME,
235*4f2df630SAndroid Build Coastguard Worker },
236*4f2df630SAndroid Build Coastguard Worker };
237*4f2df630SAndroid Build Coastguard Worker
238*4f2df630SAndroid Build Coastguard Worker static const struct dice_handover_hdr_s kDiceHandoverHdrTemplate = {
239*4f2df630SAndroid Build Coastguard Worker /* Map header: 3 elements */
240*4f2df630SAndroid Build Coastguard Worker CBOR_HDR1(CBOR_MAJOR_MAP, 3),
241*4f2df630SAndroid Build Coastguard Worker /* 1. CDI_Attest: uint(1, 0bytes) => bstr(32bytes) */
242*4f2df630SAndroid Build Coastguard Worker DICE_HANDOVER_LABEL_CDI_ATTEST,
243*4f2df630SAndroid Build Coastguard Worker CBOR_BSTR32_EMPTY, /* CALC - CDI_attest */
244*4f2df630SAndroid Build Coastguard Worker /* 2. CDI_Seal: uint(2, 0bytes) => bstr(32bytes) */
245*4f2df630SAndroid Build Coastguard Worker DICE_HANDOVER_LABEL_CDI_SEAL,
246*4f2df630SAndroid Build Coastguard Worker CBOR_BSTR32_EMPTY, /* CALC - CDI_seal */
247*4f2df630SAndroid Build Coastguard Worker /* 3. DICE chain: uint(3, 0bytes) => DICE cert chain */
248*4f2df630SAndroid Build Coastguard Worker DICE_HANDOVER_LABEL_DICE_CHAIN
249*4f2df630SAndroid Build Coastguard Worker /* DICE cert chain is not included */
250*4f2df630SAndroid Build Coastguard Worker };
251*4f2df630SAndroid Build Coastguard Worker
252*4f2df630SAndroid Build Coastguard Worker static const struct cdi_sig_struct_hdr_s kSigStructFixedHdr = {
253*4f2df630SAndroid Build Coastguard Worker /* Array header: 4 elements */
254*4f2df630SAndroid Build Coastguard Worker CBOR_HDR1(CBOR_MAJOR_ARR, 4),
255*4f2df630SAndroid Build Coastguard Worker /* 1. Context: tstr("Signature1") */
256*4f2df630SAndroid Build Coastguard Worker CDI_SIG_STRUCT_CONTEXT,
257*4f2df630SAndroid Build Coastguard Worker /* 2. Body protected: bstr(COSE param) */
258*4f2df630SAndroid Build Coastguard Worker COSE_PARAM_BSTR,
259*4f2df630SAndroid Build Coastguard Worker /* 3. External AAD: Bstr(0 bytes) */
260*4f2df630SAndroid Build Coastguard Worker CBOR_HDR1(CBOR_MAJOR_BSTR, 0),
261*4f2df630SAndroid Build Coastguard Worker /* 4. Payload - not fixed, contained in cdi_sig_struct_t */
262*4f2df630SAndroid Build Coastguard Worker };
263*4f2df630SAndroid Build Coastguard Worker
264*4f2df630SAndroid Build Coastguard Worker static const struct combined_hdr_s kCombinedHdrTemplate = {
265*4f2df630SAndroid Build Coastguard Worker /* struct dice_cert_chain_hdr_s cert_chain */
266*4f2df630SAndroid Build Coastguard Worker {
267*4f2df630SAndroid Build Coastguard Worker /* Array header: 2 elements */
268*4f2df630SAndroid Build Coastguard Worker CBOR_HDR1(CBOR_MAJOR_ARR, 2),
269*4f2df630SAndroid Build Coastguard Worker /* 1. UDS pub key: COSE_Key
270*4f2df630SAndroid Build Coastguard Worker * struct cose_key_ecdsa_s
271*4f2df630SAndroid Build Coastguard Worker */
272*4f2df630SAndroid Build Coastguard Worker {
273*4f2df630SAndroid Build Coastguard Worker /* Map header: 6 entries */
274*4f2df630SAndroid Build Coastguard Worker CBOR_HDR1(CBOR_MAJOR_MAP, 6),
275*4f2df630SAndroid Build Coastguard Worker /* 1. Key type: uint(1, 0bytes) => uint(2, 0bytes) */
276*4f2df630SAndroid Build Coastguard Worker COSE_KEY_LABEL_KTY,
277*4f2df630SAndroid Build Coastguard Worker CBOR_UINT0(2), /* EC2 */
278*4f2df630SAndroid Build Coastguard Worker /* 2. Algorithm: uint(3, 0bytes) => nint(-1, 0bytes) */
279*4f2df630SAndroid Build Coastguard Worker COSE_KEY_LABEL_ALG,
280*4f2df630SAndroid Build Coastguard Worker CBOR_NINT0(-7), /* ECDSA w/ SHA-256 */
281*4f2df630SAndroid Build Coastguard Worker /* 3. Key ops: uint(4, 0bytes) =>
282*4f2df630SAndroid Build Coastguard Worker * array(1) { uint(2, 0bytes) }
283*4f2df630SAndroid Build Coastguard Worker */
284*4f2df630SAndroid Build Coastguard Worker COSE_KEY_LABEL_KEY_OPS,
285*4f2df630SAndroid Build Coastguard Worker CBOR_HDR1(CBOR_MAJOR_ARR, 1),
286*4f2df630SAndroid Build Coastguard Worker CBOR_UINT0(2),
287*4f2df630SAndroid Build Coastguard Worker /* 4. Curve: nint(-1, 0bytes) => uint(1, 0bytes) */
288*4f2df630SAndroid Build Coastguard Worker COSE_KEY_LABEL_CRV,
289*4f2df630SAndroid Build Coastguard Worker CBOR_UINT0(1), /* P-256 */
290*4f2df630SAndroid Build Coastguard Worker /* 5. X: nint(-2, 0bytes) => bstr(X, 32bytes) */
291*4f2df630SAndroid Build Coastguard Worker COSE_KEY_LABEL_X,
292*4f2df630SAndroid Build Coastguard Worker CBOR_BSTR32_EMPTY, /* VARIABLE */
293*4f2df630SAndroid Build Coastguard Worker /* 6. X: nint(-3, 0bytes) => bstr(Y, 32bytes) */
294*4f2df630SAndroid Build Coastguard Worker COSE_KEY_LABEL_Y,
295*4f2df630SAndroid Build Coastguard Worker CBOR_BSTR32_EMPTY, /* VARIABLE */
296*4f2df630SAndroid Build Coastguard Worker },
297*4f2df630SAndroid Build Coastguard Worker /* 2. CDI DICE cert: - not included, */
298*4f2df630SAndroid Build Coastguard Worker /* consists of hdr=cdi_cert_hdr_s, payload=cwt_claims_bstr_s, */
299*4f2df630SAndroid Build Coastguard Worker /* sig=cbor_bstr64_s */
300*4f2df630SAndroid Build Coastguard Worker },
301*4f2df630SAndroid Build Coastguard Worker /* struct cdi_cert_hdr_s cert */
302*4f2df630SAndroid Build Coastguard Worker {
303*4f2df630SAndroid Build Coastguard Worker /* Array header: 4 elements */
304*4f2df630SAndroid Build Coastguard Worker CBOR_HDR1(CBOR_MAJOR_ARR, 4),
305*4f2df630SAndroid Build Coastguard Worker /* 1. Protected: bstr(COSE param) */
306*4f2df630SAndroid Build Coastguard Worker COSE_PARAM_BSTR,
307*4f2df630SAndroid Build Coastguard Worker /* 2. Unprotected: empty map */
308*4f2df630SAndroid Build Coastguard Worker CBOR_HDR1(CBOR_MAJOR_MAP, 0),
309*4f2df630SAndroid Build Coastguard Worker /* 3. Payload: bstr(CWT claims) - not fixed, contained in */
310*4f2df630SAndroid Build Coastguard Worker /* cdi_cert_t */
311*4f2df630SAndroid Build Coastguard Worker /* 4. Signature: bstr(64 bytes) - not fixed, contained in */
312*4f2df630SAndroid Build Coastguard Worker /* cdi_cert_t */
313*4f2df630SAndroid Build Coastguard Worker }
314*4f2df630SAndroid Build Coastguard Worker };
315*4f2df630SAndroid Build Coastguard Worker
316*4f2df630SAndroid Build Coastguard Worker static const struct slice_ref_s kCdiAttestLabel = {
317*4f2df630SAndroid Build Coastguard Worker 10 /* strlen("CDI_Attest") */,
318*4f2df630SAndroid Build Coastguard Worker (const uint8_t *)"CDI_Attest"
319*4f2df630SAndroid Build Coastguard Worker };
320*4f2df630SAndroid Build Coastguard Worker static const struct slice_ref_s kCdiSealLabel = {
321*4f2df630SAndroid Build Coastguard Worker 8 /* strlen("CDI_Seal") */,
322*4f2df630SAndroid Build Coastguard Worker (const uint8_t *)"CDI_Seal"
323*4f2df630SAndroid Build Coastguard Worker };
324*4f2df630SAndroid Build Coastguard Worker static const struct slice_ref_s kIdSaltSlice = {
325*4f2df630SAndroid Build Coastguard Worker 64,
326*4f2df630SAndroid Build Coastguard Worker (const uint8_t *)kIdSalt
327*4f2df630SAndroid Build Coastguard Worker };
328*4f2df630SAndroid Build Coastguard Worker static const struct slice_ref_s kAsymSaltSlice = {
329*4f2df630SAndroid Build Coastguard Worker 64,
330*4f2df630SAndroid Build Coastguard Worker (const uint8_t *)kAsymSalt
331*4f2df630SAndroid Build Coastguard Worker };
332*4f2df630SAndroid Build Coastguard Worker static const struct slice_ref_s kIdLabel = {
333*4f2df630SAndroid Build Coastguard Worker 2, /* streln("ID") */
334*4f2df630SAndroid Build Coastguard Worker (const uint8_t *)"ID"
335*4f2df630SAndroid Build Coastguard Worker };
336*4f2df630SAndroid Build Coastguard Worker static const struct slice_ref_s kKeyPairLabel = {
337*4f2df630SAndroid Build Coastguard Worker 8, /* strelen("Key Pair") */
338*4f2df630SAndroid Build Coastguard Worker (const uint8_t *)"Key Pair"
339*4f2df630SAndroid Build Coastguard Worker };
340*4f2df630SAndroid Build Coastguard Worker
341*4f2df630SAndroid Build Coastguard Worker /* Calculates CDI from {UDS, inputs_digest, label}
342*4f2df630SAndroid Build Coastguard Worker */
calc_cdi_from_digest(const uint8_t uds[DIGEST_BYTES],const uint8_t inputs_digest[DIGEST_BYTES],const struct slice_ref_s label,uint8_t cdi[DIGEST_BYTES])343*4f2df630SAndroid Build Coastguard Worker static inline bool calc_cdi_from_digest(
344*4f2df630SAndroid Build Coastguard Worker /* [IN] UDS */
345*4f2df630SAndroid Build Coastguard Worker const uint8_t uds[DIGEST_BYTES],
346*4f2df630SAndroid Build Coastguard Worker /* [IN] digest of inputs */
347*4f2df630SAndroid Build Coastguard Worker const uint8_t inputs_digest[DIGEST_BYTES],
348*4f2df630SAndroid Build Coastguard Worker /* [IN] label */
349*4f2df630SAndroid Build Coastguard Worker const struct slice_ref_s label,
350*4f2df630SAndroid Build Coastguard Worker /* [OUT] CDI */
351*4f2df630SAndroid Build Coastguard Worker uint8_t cdi[DIGEST_BYTES]
352*4f2df630SAndroid Build Coastguard Worker )
353*4f2df630SAndroid Build Coastguard Worker {
354*4f2df630SAndroid Build Coastguard Worker const struct slice_ref_s uds_slice = digest_as_slice(uds);
355*4f2df630SAndroid Build Coastguard Worker const struct slice_ref_s inputs_digest_slice =
356*4f2df630SAndroid Build Coastguard Worker digest_as_slice(inputs_digest);
357*4f2df630SAndroid Build Coastguard Worker const struct slice_mut_s cdi_slice = digest_as_slice_mut(cdi);
358*4f2df630SAndroid Build Coastguard Worker
359*4f2df630SAndroid Build Coastguard Worker return __platform_hkdf_sha256(uds_slice, inputs_digest_slice, label,
360*4f2df630SAndroid Build Coastguard Worker cdi_slice);
361*4f2df630SAndroid Build Coastguard Worker }
362*4f2df630SAndroid Build Coastguard Worker
363*4f2df630SAndroid Build Coastguard Worker /* Calculates CDI from {UDS, inputs, label}
364*4f2df630SAndroid Build Coastguard Worker */
calc_cdi(const uint8_t uds[DIGEST_BYTES],const struct slice_ref_s inputs,const struct slice_ref_s label,uint8_t cdi[DIGEST_BYTES])365*4f2df630SAndroid Build Coastguard Worker static bool calc_cdi(
366*4f2df630SAndroid Build Coastguard Worker /* [IN] UDS */
367*4f2df630SAndroid Build Coastguard Worker const uint8_t uds[DIGEST_BYTES],
368*4f2df630SAndroid Build Coastguard Worker /* [IN] inputs */
369*4f2df630SAndroid Build Coastguard Worker const struct slice_ref_s inputs,
370*4f2df630SAndroid Build Coastguard Worker /* [IN] label */
371*4f2df630SAndroid Build Coastguard Worker const struct slice_ref_s label,
372*4f2df630SAndroid Build Coastguard Worker /* [OUT] CDI */
373*4f2df630SAndroid Build Coastguard Worker uint8_t cdi[DIGEST_BYTES]
374*4f2df630SAndroid Build Coastguard Worker )
375*4f2df630SAndroid Build Coastguard Worker {
376*4f2df630SAndroid Build Coastguard Worker uint8_t inputs_digest[DIGEST_BYTES];
377*4f2df630SAndroid Build Coastguard Worker
378*4f2df630SAndroid Build Coastguard Worker if (!__platform_sha256(inputs, inputs_digest)) {
379*4f2df630SAndroid Build Coastguard Worker __platform_log_str("Failed to hash inputs");
380*4f2df630SAndroid Build Coastguard Worker return false;
381*4f2df630SAndroid Build Coastguard Worker }
382*4f2df630SAndroid Build Coastguard Worker return calc_cdi_from_digest(uds, inputs_digest, label, cdi);
383*4f2df630SAndroid Build Coastguard Worker }
384*4f2df630SAndroid Build Coastguard Worker
385*4f2df630SAndroid Build Coastguard Worker /* Fills inputs for sealing CDI.
386*4f2df630SAndroid Build Coastguard Worker * Assumes that ctx->cfg and CfgDescr in ctx->output are already filled.
387*4f2df630SAndroid Build Coastguard Worker */
fill_inputs_seal(const struct dice_ctx_s * ctx,struct cdi_seal_inputs_s * inputs)388*4f2df630SAndroid Build Coastguard Worker static inline void fill_inputs_seal(
389*4f2df630SAndroid Build Coastguard Worker /* [IN] dice context */
390*4f2df630SAndroid Build Coastguard Worker const struct dice_ctx_s *ctx,
391*4f2df630SAndroid Build Coastguard Worker /* [OUT] inputs */
392*4f2df630SAndroid Build Coastguard Worker struct cdi_seal_inputs_s *inputs
393*4f2df630SAndroid Build Coastguard Worker )
394*4f2df630SAndroid Build Coastguard Worker {
395*4f2df630SAndroid Build Coastguard Worker __platform_memset(inputs->auth_data_digest, 0, DIGEST_BYTES);
396*4f2df630SAndroid Build Coastguard Worker __platform_memcpy(inputs->hidden_digest, ctx->cfg.hidden_digest,
397*4f2df630SAndroid Build Coastguard Worker DIGEST_BYTES);
398*4f2df630SAndroid Build Coastguard Worker inputs->mode = ctx->output.dice_handover.payload.data.mode.value;
399*4f2df630SAndroid Build Coastguard Worker }
400*4f2df630SAndroid Build Coastguard Worker
401*4f2df630SAndroid Build Coastguard Worker /* Fills inputs for attestation CDI
402*4f2df630SAndroid Build Coastguard Worker * Assumes that ctx->cfg and CfgDescr in ctx->output are already filled.
403*4f2df630SAndroid Build Coastguard Worker */
fill_inputs_attest(const struct dice_ctx_s * ctx,struct cdi_attest_inputs_s * inputs)404*4f2df630SAndroid Build Coastguard Worker static inline void fill_inputs_attest(
405*4f2df630SAndroid Build Coastguard Worker /* [IN] dice context */
406*4f2df630SAndroid Build Coastguard Worker const struct dice_ctx_s *ctx,
407*4f2df630SAndroid Build Coastguard Worker /* [OUT] inputs */
408*4f2df630SAndroid Build Coastguard Worker struct cdi_attest_inputs_s *inputs
409*4f2df630SAndroid Build Coastguard Worker )
410*4f2df630SAndroid Build Coastguard Worker {
411*4f2df630SAndroid Build Coastguard Worker const struct cwt_claims_s *cwt_claims =
412*4f2df630SAndroid Build Coastguard Worker &ctx->output.dice_handover.payload.data;
413*4f2df630SAndroid Build Coastguard Worker
414*4f2df630SAndroid Build Coastguard Worker __platform_memcpy(inputs->code_digest,
415*4f2df630SAndroid Build Coastguard Worker cwt_claims->code_hash.value,
416*4f2df630SAndroid Build Coastguard Worker DIGEST_BYTES);
417*4f2df630SAndroid Build Coastguard Worker __platform_memcpy(inputs->cfg_desr_digest,
418*4f2df630SAndroid Build Coastguard Worker cwt_claims->cfg_hash.value,
419*4f2df630SAndroid Build Coastguard Worker DIGEST_BYTES);
420*4f2df630SAndroid Build Coastguard Worker fill_inputs_seal(ctx, &inputs->seal_inputs);
421*4f2df630SAndroid Build Coastguard Worker }
422*4f2df630SAndroid Build Coastguard Worker
423*4f2df630SAndroid Build Coastguard Worker /* Calculates attestation CDI.
424*4f2df630SAndroid Build Coastguard Worker * Assumes that ctx->cfg and CfgDescr in ctx->output are already filled.
425*4f2df630SAndroid Build Coastguard Worker */
calc_cdi_attest(const struct dice_ctx_s * ctx,uint8_t cdi[DIGEST_BYTES])426*4f2df630SAndroid Build Coastguard Worker static inline bool calc_cdi_attest(
427*4f2df630SAndroid Build Coastguard Worker /* [IN] dice context */
428*4f2df630SAndroid Build Coastguard Worker const struct dice_ctx_s *ctx,
429*4f2df630SAndroid Build Coastguard Worker /* [OUT] CDI */
430*4f2df630SAndroid Build Coastguard Worker uint8_t cdi[DIGEST_BYTES]
431*4f2df630SAndroid Build Coastguard Worker )
432*4f2df630SAndroid Build Coastguard Worker {
433*4f2df630SAndroid Build Coastguard Worker struct cdi_attest_inputs_s inputs;
434*4f2df630SAndroid Build Coastguard Worker const struct slice_ref_s inputs_slice = {
435*4f2df630SAndroid Build Coastguard Worker sizeof(inputs), (uint8_t *)&inputs
436*4f2df630SAndroid Build Coastguard Worker };
437*4f2df630SAndroid Build Coastguard Worker
438*4f2df630SAndroid Build Coastguard Worker fill_inputs_attest(ctx, &inputs);
439*4f2df630SAndroid Build Coastguard Worker return calc_cdi(ctx->cfg.uds, inputs_slice, kCdiAttestLabel, cdi);
440*4f2df630SAndroid Build Coastguard Worker }
441*4f2df630SAndroid Build Coastguard Worker
442*4f2df630SAndroid Build Coastguard Worker /* Calculates sealing CDI.
443*4f2df630SAndroid Build Coastguard Worker * Assumes that ctx->cfg and CfgDescr in ctx->output are already filled.
444*4f2df630SAndroid Build Coastguard Worker */
calc_cdi_seal(const struct dice_ctx_s * ctx,uint8_t cdi[DIGEST_BYTES])445*4f2df630SAndroid Build Coastguard Worker static inline bool calc_cdi_seal(
446*4f2df630SAndroid Build Coastguard Worker /* [IN] dice context */
447*4f2df630SAndroid Build Coastguard Worker const struct dice_ctx_s *ctx,
448*4f2df630SAndroid Build Coastguard Worker /* [OUT] CDI */
449*4f2df630SAndroid Build Coastguard Worker uint8_t cdi[DIGEST_BYTES]
450*4f2df630SAndroid Build Coastguard Worker )
451*4f2df630SAndroid Build Coastguard Worker {
452*4f2df630SAndroid Build Coastguard Worker struct cdi_seal_inputs_s inputs;
453*4f2df630SAndroid Build Coastguard Worker const struct slice_ref_s inputs_slice = {
454*4f2df630SAndroid Build Coastguard Worker sizeof(inputs), (uint8_t *)&inputs
455*4f2df630SAndroid Build Coastguard Worker };
456*4f2df630SAndroid Build Coastguard Worker
457*4f2df630SAndroid Build Coastguard Worker fill_inputs_seal(ctx, &inputs);
458*4f2df630SAndroid Build Coastguard Worker return calc_cdi(ctx->cfg.uds, inputs_slice, kCdiSealLabel, cdi);
459*4f2df630SAndroid Build Coastguard Worker }
460*4f2df630SAndroid Build Coastguard Worker
461*4f2df630SAndroid Build Coastguard Worker /* Calculates boot mode from the data in ctx->cfg
462*4f2df630SAndroid Build Coastguard Worker * On DT/OT with ti50:
463*4f2df630SAndroid Build Coastguard Worker * - Normal if
464*4f2df630SAndroid Build Coastguard Worker * - APROV succeeded or not configured from factory (for legacy devices).
465*4f2df630SAndroid Build Coastguard Worker * Note: AllowUnverifiedRo counts as a failure AND
466*4f2df630SAndroid Build Coastguard Worker * - Coreboot reported 'normal' boot mode
467*4f2df630SAndroid Build Coastguard Worker * - Recovery if
468*4f2df630SAndroid Build Coastguard Worker * - APROV succeeded or not configured from factory (for legacy devices).
469*4f2df630SAndroid Build Coastguard Worker * Note: AllowUnverifiedRo counts as a failure AND
470*4f2df630SAndroid Build Coastguard Worker * - Coreboot reported 'recovery-normal' boot mode
471*4f2df630SAndroid Build Coastguard Worker * - Debug - in all other cases
472*4f2df630SAndroid Build Coastguard Worker *
473*4f2df630SAndroid Build Coastguard Worker * On H1 with Cr50:
474*4f2df630SAndroid Build Coastguard Worker * - Normal if Coreboot reported 'normal' boot mode
475*4f2df630SAndroid Build Coastguard Worker * - Recovery if Coreboot reported 'recovery-normal' boot mode
476*4f2df630SAndroid Build Coastguard Worker * - Debug - in all other cases
477*4f2df630SAndroid Build Coastguard Worker */
calc_mode(const struct dice_ctx_s * ctx)478*4f2df630SAndroid Build Coastguard Worker static inline uint8_t calc_mode(
479*4f2df630SAndroid Build Coastguard Worker /* [IN] dice context */
480*4f2df630SAndroid Build Coastguard Worker const struct dice_ctx_s *ctx
481*4f2df630SAndroid Build Coastguard Worker )
482*4f2df630SAndroid Build Coastguard Worker {
483*4f2df630SAndroid Build Coastguard Worker if (__platform_aprov_status_allows_normal(ctx->cfg.aprov_status)) {
484*4f2df630SAndroid Build Coastguard Worker if (__platform_memcmp(ctx->cfg.pcr0, kPcr0NormalMode,
485*4f2df630SAndroid Build Coastguard Worker DIGEST_BYTES) == 0) {
486*4f2df630SAndroid Build Coastguard Worker return BOOT_MODE_NORMAL;
487*4f2df630SAndroid Build Coastguard Worker }
488*4f2df630SAndroid Build Coastguard Worker if (__platform_memcmp(ctx->cfg.pcr0, kPcr0RecoveryNormalMode,
489*4f2df630SAndroid Build Coastguard Worker DIGEST_BYTES) == 0) {
490*4f2df630SAndroid Build Coastguard Worker return BOOT_MODE_RECOVERY;
491*4f2df630SAndroid Build Coastguard Worker }
492*4f2df630SAndroid Build Coastguard Worker }
493*4f2df630SAndroid Build Coastguard Worker return BOOT_MODE_DEBUG;
494*4f2df630SAndroid Build Coastguard Worker }
495*4f2df630SAndroid Build Coastguard Worker
496*4f2df630SAndroid Build Coastguard Worker /* Generates CDI cert signature for the initialized builder with pre-filled
497*4f2df630SAndroid Build Coastguard Worker * CWT claims.
498*4f2df630SAndroid Build Coastguard Worker */
fill_cdi_cert_signature(struct dice_ctx_s * ctx,const void * key)499*4f2df630SAndroid Build Coastguard Worker static inline bool fill_cdi_cert_signature(
500*4f2df630SAndroid Build Coastguard Worker /* [IN/OUT] dice context */
501*4f2df630SAndroid Build Coastguard Worker struct dice_ctx_s *ctx,
502*4f2df630SAndroid Build Coastguard Worker /* [IN] key handle to sign */
503*4f2df630SAndroid Build Coastguard Worker const void *key
504*4f2df630SAndroid Build Coastguard Worker )
505*4f2df630SAndroid Build Coastguard Worker {
506*4f2df630SAndroid Build Coastguard Worker uint8_t *sig_struct = ((uint8_t *)&ctx->output.dice_handover.payload) -
507*4f2df630SAndroid Build Coastguard Worker sizeof(struct cdi_sig_struct_hdr_s);
508*4f2df630SAndroid Build Coastguard Worker const struct slice_ref_s data_to_sign = {
509*4f2df630SAndroid Build Coastguard Worker CDI_SIG_STRUCT_LEN, sig_struct
510*4f2df630SAndroid Build Coastguard Worker };
511*4f2df630SAndroid Build Coastguard Worker struct cbor_bstr64_s *sig_bstr64 =
512*4f2df630SAndroid Build Coastguard Worker &ctx->output.dice_handover.signature;
513*4f2df630SAndroid Build Coastguard Worker
514*4f2df630SAndroid Build Coastguard Worker __platform_memcpy(sig_struct, &kSigStructFixedHdr,
515*4f2df630SAndroid Build Coastguard Worker sizeof(struct cdi_sig_struct_hdr_s));
516*4f2df630SAndroid Build Coastguard Worker __platform_memcpy(sig_bstr64->cbor_hdr, kSigHdr, 2);
517*4f2df630SAndroid Build Coastguard Worker return __platform_ecdsa_p256_sign(key, data_to_sign,
518*4f2df630SAndroid Build Coastguard Worker sig_bstr64->value);
519*4f2df630SAndroid Build Coastguard Worker }
520*4f2df630SAndroid Build Coastguard Worker
521*4f2df630SAndroid Build Coastguard Worker /* Generates key from UDS or CDI_Attest value.
522*4f2df630SAndroid Build Coastguard Worker */
generate_key(const uint8_t input[DIGEST_BYTES],const void ** key)523*4f2df630SAndroid Build Coastguard Worker static bool generate_key(
524*4f2df630SAndroid Build Coastguard Worker /* [IN] CDI_attest or UDS */
525*4f2df630SAndroid Build Coastguard Worker const uint8_t input[DIGEST_BYTES],
526*4f2df630SAndroid Build Coastguard Worker /* [OUT] key handle */
527*4f2df630SAndroid Build Coastguard Worker const void **key
528*4f2df630SAndroid Build Coastguard Worker )
529*4f2df630SAndroid Build Coastguard Worker {
530*4f2df630SAndroid Build Coastguard Worker uint8_t drbg_seed[DIGEST_BYTES];
531*4f2df630SAndroid Build Coastguard Worker const struct slice_ref_s input_slice = digest_as_slice(input);
532*4f2df630SAndroid Build Coastguard Worker const struct slice_mut_s drbg_seed_slice =
533*4f2df630SAndroid Build Coastguard Worker digest_as_slice_mut(drbg_seed);
534*4f2df630SAndroid Build Coastguard Worker
535*4f2df630SAndroid Build Coastguard Worker if (!__platform_hkdf_sha256(input_slice, kAsymSaltSlice,
536*4f2df630SAndroid Build Coastguard Worker kKeyPairLabel, drbg_seed_slice)) {
537*4f2df630SAndroid Build Coastguard Worker __platform_log_str("ASYM_KDF failed");
538*4f2df630SAndroid Build Coastguard Worker return false;
539*4f2df630SAndroid Build Coastguard Worker }
540*4f2df630SAndroid Build Coastguard Worker return __platform_ecdsa_p256_keygen_hmac_drbg(drbg_seed, key);
541*4f2df630SAndroid Build Coastguard Worker }
542*4f2df630SAndroid Build Coastguard Worker
543*4f2df630SAndroid Build Coastguard Worker /* Generates {UDS, CDI}_ID from {UDS, CDI} public key.
544*4f2df630SAndroid Build Coastguard Worker */
generate_id_from_pub_key(const struct ecdsa_public_s * pub_key,uint8_t dice_id[DICE_ID_BYTES])545*4f2df630SAndroid Build Coastguard Worker static bool generate_id_from_pub_key(
546*4f2df630SAndroid Build Coastguard Worker /* [IN] public key */
547*4f2df630SAndroid Build Coastguard Worker const struct ecdsa_public_s *pub_key,
548*4f2df630SAndroid Build Coastguard Worker /* [OUT] generated id */
549*4f2df630SAndroid Build Coastguard Worker uint8_t dice_id[DICE_ID_BYTES]
550*4f2df630SAndroid Build Coastguard Worker )
551*4f2df630SAndroid Build Coastguard Worker {
552*4f2df630SAndroid Build Coastguard Worker const struct slice_ref_s pub_key_slice = {
553*4f2df630SAndroid Build Coastguard Worker sizeof(struct ecdsa_public_s), (const uint8_t *)pub_key
554*4f2df630SAndroid Build Coastguard Worker };
555*4f2df630SAndroid Build Coastguard Worker const struct slice_mut_s dice_id_slice = {
556*4f2df630SAndroid Build Coastguard Worker DICE_ID_BYTES, (uint8_t *)dice_id
557*4f2df630SAndroid Build Coastguard Worker };
558*4f2df630SAndroid Build Coastguard Worker
559*4f2df630SAndroid Build Coastguard Worker return __platform_hkdf_sha256(pub_key_slice, kIdSaltSlice, kIdLabel,
560*4f2df630SAndroid Build Coastguard Worker dice_id_slice);
561*4f2df630SAndroid Build Coastguard Worker }
562*4f2df630SAndroid Build Coastguard Worker
563*4f2df630SAndroid Build Coastguard Worker /* Returns hexdump character for the half-byte.
564*4f2df630SAndroid Build Coastguard Worker */
hexdump_halfbyte(uint8_t half_byte)565*4f2df630SAndroid Build Coastguard Worker static inline uint8_t hexdump_halfbyte(uint8_t half_byte)
566*4f2df630SAndroid Build Coastguard Worker {
567*4f2df630SAndroid Build Coastguard Worker if (half_byte < 10)
568*4f2df630SAndroid Build Coastguard Worker return '0' + half_byte;
569*4f2df630SAndroid Build Coastguard Worker else
570*4f2df630SAndroid Build Coastguard Worker return 'a' + half_byte - 10;
571*4f2df630SAndroid Build Coastguard Worker }
572*4f2df630SAndroid Build Coastguard Worker
573*4f2df630SAndroid Build Coastguard Worker /* Fills hexdump of the byte (lowercase).
574*4f2df630SAndroid Build Coastguard Worker */
hexdump_byte(uint8_t byte,uint8_t * str)575*4f2df630SAndroid Build Coastguard Worker static inline void hexdump_byte(
576*4f2df630SAndroid Build Coastguard Worker /* [IN] byte to hexdump */
577*4f2df630SAndroid Build Coastguard Worker uint8_t byte,
578*4f2df630SAndroid Build Coastguard Worker /* [OUT] str (always 2 bytes) with hexdump */
579*4f2df630SAndroid Build Coastguard Worker uint8_t *str
580*4f2df630SAndroid Build Coastguard Worker )
581*4f2df630SAndroid Build Coastguard Worker {
582*4f2df630SAndroid Build Coastguard Worker str[0] = hexdump_halfbyte((byte & 0xF0) >> 4);
583*4f2df630SAndroid Build Coastguard Worker str[1] = hexdump_halfbyte(byte & 0x0F);
584*4f2df630SAndroid Build Coastguard Worker }
585*4f2df630SAndroid Build Coastguard Worker
586*4f2df630SAndroid Build Coastguard Worker /* Fills {CDI, UDS} ID string from ID bytes.
587*4f2df630SAndroid Build Coastguard Worker */
fill_dice_id_string(const uint8_t dice_id[DICE_ID_BYTES],uint8_t dice_id_str[DICE_ID_HEX_BYTES])588*4f2df630SAndroid Build Coastguard Worker static void fill_dice_id_string(
589*4f2df630SAndroid Build Coastguard Worker /* [IN] IDS_ID or CDI_ID */
590*4f2df630SAndroid Build Coastguard Worker const uint8_t dice_id[DICE_ID_BYTES],
591*4f2df630SAndroid Build Coastguard Worker /* [OUT] hexdump of this ID */
592*4f2df630SAndroid Build Coastguard Worker uint8_t dice_id_str[DICE_ID_HEX_BYTES]
593*4f2df630SAndroid Build Coastguard Worker )
594*4f2df630SAndroid Build Coastguard Worker {
595*4f2df630SAndroid Build Coastguard Worker size_t idx;
596*4f2df630SAndroid Build Coastguard Worker
597*4f2df630SAndroid Build Coastguard Worker for (idx = 0; idx < DICE_ID_BYTES; idx++, dice_id_str += 2)
598*4f2df630SAndroid Build Coastguard Worker hexdump_byte(dice_id[idx], dice_id_str);
599*4f2df630SAndroid Build Coastguard Worker }
600*4f2df630SAndroid Build Coastguard Worker
601*4f2df630SAndroid Build Coastguard Worker /* Fills COSE_Key structure from pubkey.
602*4f2df630SAndroid Build Coastguard Worker * Assumes that all fields in COSE_Key except for X, y are already filled
603*4f2df630SAndroid Build Coastguard Worker * from template.
604*4f2df630SAndroid Build Coastguard Worker */
fill_cose_pubkey(const struct ecdsa_public_s * pub_key,struct cose_key_ecdsa_s * cose_key)605*4f2df630SAndroid Build Coastguard Worker static inline void fill_cose_pubkey(
606*4f2df630SAndroid Build Coastguard Worker /* [IN] pub key */
607*4f2df630SAndroid Build Coastguard Worker const struct ecdsa_public_s *pub_key,
608*4f2df630SAndroid Build Coastguard Worker /* [IN/OUT] COSE key structure */
609*4f2df630SAndroid Build Coastguard Worker struct cose_key_ecdsa_s *cose_key
610*4f2df630SAndroid Build Coastguard Worker )
611*4f2df630SAndroid Build Coastguard Worker {
612*4f2df630SAndroid Build Coastguard Worker __platform_memcpy(cose_key->x.value, pub_key->x, ECDSA_POINT_BYTES);
613*4f2df630SAndroid Build Coastguard Worker __platform_memcpy(cose_key->y.value, pub_key->y, ECDSA_POINT_BYTES);
614*4f2df630SAndroid Build Coastguard Worker }
615*4f2df630SAndroid Build Coastguard Worker
616*4f2df630SAndroid Build Coastguard Worker /* Fills CDI_attest pubkey, CDI_ID in the CDI certificate using generated
617*4f2df630SAndroid Build Coastguard Worker * CDI_attest key.
618*4f2df630SAndroid Build Coastguard Worker */
fill_cdi_details_with_key(struct dice_ctx_s * ctx,const void * cdi_key)619*4f2df630SAndroid Build Coastguard Worker static inline bool fill_cdi_details_with_key(
620*4f2df630SAndroid Build Coastguard Worker /* [IN/OUT] dice context */
621*4f2df630SAndroid Build Coastguard Worker struct dice_ctx_s *ctx,
622*4f2df630SAndroid Build Coastguard Worker /* [IN] CDI_attest key handle */
623*4f2df630SAndroid Build Coastguard Worker const void *cdi_key
624*4f2df630SAndroid Build Coastguard Worker )
625*4f2df630SAndroid Build Coastguard Worker {
626*4f2df630SAndroid Build Coastguard Worker struct ecdsa_public_s cdi_pub_key;
627*4f2df630SAndroid Build Coastguard Worker uint8_t cdi_id[DICE_ID_BYTES];
628*4f2df630SAndroid Build Coastguard Worker struct cwt_claims_s *cwt_claims =
629*4f2df630SAndroid Build Coastguard Worker &ctx->output.dice_handover.payload.data;
630*4f2df630SAndroid Build Coastguard Worker
631*4f2df630SAndroid Build Coastguard Worker if (!__platform_ecdsa_p256_get_pub_key(cdi_key, &cdi_pub_key)) {
632*4f2df630SAndroid Build Coastguard Worker __platform_log_str("Failed to get CDI pubkey");
633*4f2df630SAndroid Build Coastguard Worker return false;
634*4f2df630SAndroid Build Coastguard Worker }
635*4f2df630SAndroid Build Coastguard Worker fill_cose_pubkey(&cdi_pub_key, &cwt_claims->subject_pk.data);
636*4f2df630SAndroid Build Coastguard Worker if (!generate_id_from_pub_key(&cdi_pub_key, cdi_id)) {
637*4f2df630SAndroid Build Coastguard Worker __platform_log_str("Failed to generate CDI_ID");
638*4f2df630SAndroid Build Coastguard Worker return false;
639*4f2df630SAndroid Build Coastguard Worker }
640*4f2df630SAndroid Build Coastguard Worker /* SUB = hex(CDI_ID) */
641*4f2df630SAndroid Build Coastguard Worker fill_dice_id_string(cdi_id, cwt_claims->sub.value);
642*4f2df630SAndroid Build Coastguard Worker
643*4f2df630SAndroid Build Coastguard Worker return true;
644*4f2df630SAndroid Build Coastguard Worker }
645*4f2df630SAndroid Build Coastguard Worker
646*4f2df630SAndroid Build Coastguard Worker /* Fills CDI_attest pubkey, CDI_ID in the CDI certificate.
647*4f2df630SAndroid Build Coastguard Worker * Assumes that ctx->cfg and CfgDescr in ctx->output are already filled.
648*4f2df630SAndroid Build Coastguard Worker */
fill_cdi_details(struct dice_ctx_s * ctx)649*4f2df630SAndroid Build Coastguard Worker static inline bool fill_cdi_details(
650*4f2df630SAndroid Build Coastguard Worker /* [IN/OUT] dice context */
651*4f2df630SAndroid Build Coastguard Worker struct dice_ctx_s *ctx
652*4f2df630SAndroid Build Coastguard Worker )
653*4f2df630SAndroid Build Coastguard Worker {
654*4f2df630SAndroid Build Coastguard Worker const void *cdi_key;
655*4f2df630SAndroid Build Coastguard Worker bool result;
656*4f2df630SAndroid Build Coastguard Worker struct dice_handover_hdr_s *hdr = &ctx->output.dice_handover.hdr;
657*4f2df630SAndroid Build Coastguard Worker
658*4f2df630SAndroid Build Coastguard Worker __platform_memcpy(hdr, &kDiceHandoverHdrTemplate,
659*4f2df630SAndroid Build Coastguard Worker sizeof(struct dice_handover_hdr_s));
660*4f2df630SAndroid Build Coastguard Worker if (!calc_cdi_attest(ctx, hdr->cdi_attest.value)) {
661*4f2df630SAndroid Build Coastguard Worker __platform_log_str("Failed to calc CDI_attest");
662*4f2df630SAndroid Build Coastguard Worker return false;
663*4f2df630SAndroid Build Coastguard Worker }
664*4f2df630SAndroid Build Coastguard Worker if (!calc_cdi_seal(ctx, hdr->cdi_seal.value)) {
665*4f2df630SAndroid Build Coastguard Worker __platform_log_str("Failed to calc CDI_seal");
666*4f2df630SAndroid Build Coastguard Worker return false;
667*4f2df630SAndroid Build Coastguard Worker }
668*4f2df630SAndroid Build Coastguard Worker if (!generate_key(hdr->cdi_attest.value, &cdi_key)) {
669*4f2df630SAndroid Build Coastguard Worker __platform_log_str("Failed to generate CDI key");
670*4f2df630SAndroid Build Coastguard Worker return false;
671*4f2df630SAndroid Build Coastguard Worker }
672*4f2df630SAndroid Build Coastguard Worker result = fill_cdi_details_with_key(ctx, cdi_key);
673*4f2df630SAndroid Build Coastguard Worker __platform_ecdsa_p256_free(cdi_key);
674*4f2df630SAndroid Build Coastguard Worker
675*4f2df630SAndroid Build Coastguard Worker return result;
676*4f2df630SAndroid Build Coastguard Worker }
677*4f2df630SAndroid Build Coastguard Worker
678*4f2df630SAndroid Build Coastguard Worker /* Fills UDS_ID, signature into the certificate using generated UDS key.
679*4f2df630SAndroid Build Coastguard Worker * Assumes that all other fields of CDI certificate are filled already.
680*4f2df630SAndroid Build Coastguard Worker */
fill_uds_details_with_key(struct dice_ctx_s * ctx,const void * uds_key)681*4f2df630SAndroid Build Coastguard Worker static inline bool fill_uds_details_with_key(
682*4f2df630SAndroid Build Coastguard Worker /* [IN/OUT] dice context */
683*4f2df630SAndroid Build Coastguard Worker struct dice_ctx_s *ctx,
684*4f2df630SAndroid Build Coastguard Worker /* [IN] UDS key handle */
685*4f2df630SAndroid Build Coastguard Worker const void *uds_key
686*4f2df630SAndroid Build Coastguard Worker )
687*4f2df630SAndroid Build Coastguard Worker {
688*4f2df630SAndroid Build Coastguard Worker struct ecdsa_public_s uds_pub_key;
689*4f2df630SAndroid Build Coastguard Worker uint8_t uds_id[DICE_ID_BYTES];
690*4f2df630SAndroid Build Coastguard Worker struct cwt_claims_s *cwt_claims =
691*4f2df630SAndroid Build Coastguard Worker &ctx->output.dice_handover.payload.data;
692*4f2df630SAndroid Build Coastguard Worker struct combined_hdr_s *combined_hdr =
693*4f2df630SAndroid Build Coastguard Worker &ctx->output.dice_handover.options.dice_handover;
694*4f2df630SAndroid Build Coastguard Worker
695*4f2df630SAndroid Build Coastguard Worker if (!__platform_ecdsa_p256_get_pub_key(uds_key, &uds_pub_key)) {
696*4f2df630SAndroid Build Coastguard Worker __platform_log_str("Failed to get UDS pubkey");
697*4f2df630SAndroid Build Coastguard Worker return false;
698*4f2df630SAndroid Build Coastguard Worker }
699*4f2df630SAndroid Build Coastguard Worker if (!generate_id_from_pub_key(&uds_pub_key, uds_id)) {
700*4f2df630SAndroid Build Coastguard Worker __platform_log_str("Failed to generate UDS_ID");
701*4f2df630SAndroid Build Coastguard Worker return false;
702*4f2df630SAndroid Build Coastguard Worker }
703*4f2df630SAndroid Build Coastguard Worker /* ISS = hex(UDS_ID) */
704*4f2df630SAndroid Build Coastguard Worker fill_dice_id_string(uds_id, cwt_claims->iss.value);
705*4f2df630SAndroid Build Coastguard Worker if (!fill_cdi_cert_signature(ctx, uds_key)) {
706*4f2df630SAndroid Build Coastguard Worker __platform_log_str("Failed to sign CDI cert");
707*4f2df630SAndroid Build Coastguard Worker return false;
708*4f2df630SAndroid Build Coastguard Worker }
709*4f2df630SAndroid Build Coastguard Worker
710*4f2df630SAndroid Build Coastguard Worker /* We can do the rest only after we generated the signature because */
711*4f2df630SAndroid Build Coastguard Worker /* signature generation uses ctx->output.hdr temporarily to build */
712*4f2df630SAndroid Build Coastguard Worker /* Sig_struct for signing. */
713*4f2df630SAndroid Build Coastguard Worker __platform_memcpy(combined_hdr,
714*4f2df630SAndroid Build Coastguard Worker &kCombinedHdrTemplate,
715*4f2df630SAndroid Build Coastguard Worker sizeof(struct combined_hdr_s));
716*4f2df630SAndroid Build Coastguard Worker fill_cose_pubkey(
717*4f2df630SAndroid Build Coastguard Worker &uds_pub_key,
718*4f2df630SAndroid Build Coastguard Worker &combined_hdr->cert_chain.uds_pub_key);
719*4f2df630SAndroid Build Coastguard Worker
720*4f2df630SAndroid Build Coastguard Worker return true;
721*4f2df630SAndroid Build Coastguard Worker }
722*4f2df630SAndroid Build Coastguard Worker
723*4f2df630SAndroid Build Coastguard Worker /* Fills UDS_ID, signature into the certificate. */
724*4f2df630SAndroid Build Coastguard Worker /* Assumes that all other fields of CDI certificate were filled already. */
fill_uds_details(struct dice_ctx_s * ctx)725*4f2df630SAndroid Build Coastguard Worker static inline bool fill_uds_details(
726*4f2df630SAndroid Build Coastguard Worker struct dice_ctx_s *ctx /* [IN/OUT] dice context */
727*4f2df630SAndroid Build Coastguard Worker )
728*4f2df630SAndroid Build Coastguard Worker {
729*4f2df630SAndroid Build Coastguard Worker const void *uds_key;
730*4f2df630SAndroid Build Coastguard Worker bool result;
731*4f2df630SAndroid Build Coastguard Worker
732*4f2df630SAndroid Build Coastguard Worker if (!generate_key(ctx->cfg.uds, &uds_key)) {
733*4f2df630SAndroid Build Coastguard Worker __platform_log_str("Failed to generate UDS key");
734*4f2df630SAndroid Build Coastguard Worker return false;
735*4f2df630SAndroid Build Coastguard Worker }
736*4f2df630SAndroid Build Coastguard Worker result = fill_uds_details_with_key(ctx, uds_key);
737*4f2df630SAndroid Build Coastguard Worker __platform_ecdsa_p256_free(uds_key);
738*4f2df630SAndroid Build Coastguard Worker
739*4f2df630SAndroid Build Coastguard Worker return result;
740*4f2df630SAndroid Build Coastguard Worker }
741*4f2df630SAndroid Build Coastguard Worker
742*4f2df630SAndroid Build Coastguard Worker /* Fills value in struct cbor_uint32_s */
743*4f2df630SAndroid Build Coastguard Worker /* Assumes that `cbor_var->cbor_hdr` is already pre-set */
set_cbor_u32(uint32_t value,struct cbor_uint32_s * cbor_var)744*4f2df630SAndroid Build Coastguard Worker static inline void set_cbor_u32(
745*4f2df630SAndroid Build Coastguard Worker uint32_t value, /* [IN] value to set */
746*4f2df630SAndroid Build Coastguard Worker struct cbor_uint32_s *cbor_var /* [OUT] CBOR UINT32 variable to fill */
747*4f2df630SAndroid Build Coastguard Worker )
748*4f2df630SAndroid Build Coastguard Worker {
749*4f2df630SAndroid Build Coastguard Worker cbor_var->value[0] = (uint8_t)(((value) & 0xFF000000) >> 24);
750*4f2df630SAndroid Build Coastguard Worker cbor_var->value[1] = (uint8_t)(((value) & 0x00FF0000) >> 16);
751*4f2df630SAndroid Build Coastguard Worker cbor_var->value[2] = (uint8_t)(((value) & 0x0000FF00) >> 8);
752*4f2df630SAndroid Build Coastguard Worker cbor_var->value[3] = (uint8_t)((value) & 0x000000FF);
753*4f2df630SAndroid Build Coastguard Worker }
754*4f2df630SAndroid Build Coastguard Worker
755*4f2df630SAndroid Build Coastguard Worker /* Fills CfgDescr, CfgDescr digest and boot mode in CDI certificate */
fill_config_details(struct dice_ctx_s * ctx)756*4f2df630SAndroid Build Coastguard Worker static inline bool fill_config_details(
757*4f2df630SAndroid Build Coastguard Worker struct dice_ctx_s *ctx /* [IN/OUT] dice context */
758*4f2df630SAndroid Build Coastguard Worker )
759*4f2df630SAndroid Build Coastguard Worker {
760*4f2df630SAndroid Build Coastguard Worker struct cwt_claims_bstr_s *payload = &ctx->output.dice_handover.payload;
761*4f2df630SAndroid Build Coastguard Worker struct cwt_claims_s *cwt_claims = &payload->data;
762*4f2df630SAndroid Build Coastguard Worker struct cfg_descr_s *cfg_descr = &payload->data.cfg_descr.data;
763*4f2df630SAndroid Build Coastguard Worker const struct slice_ref_s cfg_descr_slice = { sizeof(struct cfg_descr_s),
764*4f2df630SAndroid Build Coastguard Worker (uint8_t *)cfg_descr };
765*4f2df630SAndroid Build Coastguard Worker
766*4f2df630SAndroid Build Coastguard Worker /* Copy fixed data from the template */
767*4f2df630SAndroid Build Coastguard Worker __platform_memcpy(payload, &kCwtClaimsTemplate,
768*4f2df630SAndroid Build Coastguard Worker sizeof(struct cwt_claims_bstr_s));
769*4f2df630SAndroid Build Coastguard Worker
770*4f2df630SAndroid Build Coastguard Worker /* Fill Cfg Descriptor variables based on ctx->cfg */
771*4f2df630SAndroid Build Coastguard Worker set_cbor_u32(ctx->cfg.aprov_status, &cfg_descr->aprov_status);
772*4f2df630SAndroid Build Coastguard Worker set_cbor_u32(ctx->cfg.sec_ver, &cfg_descr->sec_ver);
773*4f2df630SAndroid Build Coastguard Worker __platform_memcpy(cfg_descr->vboot_status.value, ctx->cfg.pcr0,
774*4f2df630SAndroid Build Coastguard Worker DIGEST_BYTES);
775*4f2df630SAndroid Build Coastguard Worker __platform_memcpy(cfg_descr->ap_fw_version.value, ctx->cfg.pcr10,
776*4f2df630SAndroid Build Coastguard Worker DIGEST_BYTES);
777*4f2df630SAndroid Build Coastguard Worker
778*4f2df630SAndroid Build Coastguard Worker /* Calculate Cfg Descriptor digest */
779*4f2df630SAndroid Build Coastguard Worker if (!__platform_sha256(cfg_descr_slice, cwt_claims->cfg_hash.value)) {
780*4f2df630SAndroid Build Coastguard Worker __platform_log_str("Failed to calc CfgDescr digest");
781*4f2df630SAndroid Build Coastguard Worker return false;
782*4f2df630SAndroid Build Coastguard Worker }
783*4f2df630SAndroid Build Coastguard Worker
784*4f2df630SAndroid Build Coastguard Worker /* Calculate boot mode */
785*4f2df630SAndroid Build Coastguard Worker cwt_claims->mode.value = calc_mode(ctx);
786*4f2df630SAndroid Build Coastguard Worker
787*4f2df630SAndroid Build Coastguard Worker return true;
788*4f2df630SAndroid Build Coastguard Worker }
789*4f2df630SAndroid Build Coastguard Worker
790*4f2df630SAndroid Build Coastguard Worker /* Fills DICE handover structure in struct dice_ctx_s. */
791*4f2df630SAndroid Build Coastguard Worker /* Assumes ctx.cfg is already filled */
generate_dice_handover(struct dice_ctx_s * ctx)792*4f2df630SAndroid Build Coastguard Worker static inline bool generate_dice_handover(
793*4f2df630SAndroid Build Coastguard Worker struct dice_ctx_s *ctx /* [IN/OUT] dice context */
794*4f2df630SAndroid Build Coastguard Worker )
795*4f2df630SAndroid Build Coastguard Worker {
796*4f2df630SAndroid Build Coastguard Worker /* 1. Fill device configuration details in CDI certificate: CfgDescr and
797*4f2df630SAndroid Build Coastguard Worker * its digest, boot mode.
798*4f2df630SAndroid Build Coastguard Worker * 2. Fill CDI details in CDI certificate (CDI pubkey, CDI_ID) and DICE
799*4f2df630SAndroid Build Coastguard Worker * handover (CDIs) Relies on config details to be filled already
800*4f2df630SAndroid Build Coastguard Worker * 3. Fill UDS details in CDI certificate (UDS_ID, signature by UDS key)
801*4f2df630SAndroid Build Coastguard Worker * and DICE chain (UDS pubkey) Relies on the rest of CDI certificate to
802*4f2df630SAndroid Build Coastguard Worker * be filled already.
803*4f2df630SAndroid Build Coastguard Worker */
804*4f2df630SAndroid Build Coastguard Worker
805*4f2df630SAndroid Build Coastguard Worker return fill_config_details(ctx) &&
806*4f2df630SAndroid Build Coastguard Worker fill_cdi_details(ctx) &&
807*4f2df630SAndroid Build Coastguard Worker fill_uds_details(ctx);
808*4f2df630SAndroid Build Coastguard Worker }
809*4f2df630SAndroid Build Coastguard Worker
810*4f2df630SAndroid Build Coastguard Worker /* Fills GSCBootParam. */
fill_gsc_boot_param(struct gsc_boot_param_s * gsc_boot_param)811*4f2df630SAndroid Build Coastguard Worker static inline bool fill_gsc_boot_param(
812*4f2df630SAndroid Build Coastguard Worker struct gsc_boot_param_s *gsc_boot_param /* [IN/OUT] GSCBootParam */
813*4f2df630SAndroid Build Coastguard Worker )
814*4f2df630SAndroid Build Coastguard Worker {
815*4f2df630SAndroid Build Coastguard Worker /* GSCBootParam: Map header: 3 entries */
816*4f2df630SAndroid Build Coastguard Worker gsc_boot_param->map_hdr = CBOR_HDR1(CBOR_MAJOR_MAP, 3);
817*4f2df630SAndroid Build Coastguard Worker
818*4f2df630SAndroid Build Coastguard Worker /* GSCBootParam entry 1: EarlyEntropy:
819*4f2df630SAndroid Build Coastguard Worker * uint(1, 0bytes) => bstr(entropy, 64bytes)
820*4f2df630SAndroid Build Coastguard Worker */
821*4f2df630SAndroid Build Coastguard Worker gsc_boot_param->early_entropy_label = CBOR_UINT0(1);
822*4f2df630SAndroid Build Coastguard Worker gsc_boot_param->early_entropy.cbor_hdr[0] =
823*4f2df630SAndroid Build Coastguard Worker CBOR_HDR1(CBOR_MAJOR_BSTR, CBOR_BYTES1);
824*4f2df630SAndroid Build Coastguard Worker gsc_boot_param->early_entropy.cbor_hdr[1] = EARLY_ENTROPY_BYTES;
825*4f2df630SAndroid Build Coastguard Worker
826*4f2df630SAndroid Build Coastguard Worker /* GSCBootParam entry 2: SessionKeySeed:
827*4f2df630SAndroid Build Coastguard Worker * uint(2, 0bytes) => bstr(entropy, 32bytes)
828*4f2df630SAndroid Build Coastguard Worker */
829*4f2df630SAndroid Build Coastguard Worker gsc_boot_param->session_key_seed_label = CBOR_UINT0(2);
830*4f2df630SAndroid Build Coastguard Worker gsc_boot_param->session_key_seed.cbor_hdr[0] =
831*4f2df630SAndroid Build Coastguard Worker CBOR_HDR1(CBOR_MAJOR_BSTR, CBOR_BYTES1);
832*4f2df630SAndroid Build Coastguard Worker gsc_boot_param->session_key_seed.cbor_hdr[1] = KEY_SEED_BYTES;
833*4f2df630SAndroid Build Coastguard Worker
834*4f2df630SAndroid Build Coastguard Worker /* GSCBootParam entry 3: AuthTokenKeySeed:
835*4f2df630SAndroid Build Coastguard Worker * uint(3, 0bytes) => bstr(entropy, 32bytes)
836*4f2df630SAndroid Build Coastguard Worker */
837*4f2df630SAndroid Build Coastguard Worker gsc_boot_param->auth_token_key_seed_label = CBOR_UINT0(3);
838*4f2df630SAndroid Build Coastguard Worker gsc_boot_param->auth_token_key_seed.cbor_hdr[0] =
839*4f2df630SAndroid Build Coastguard Worker CBOR_HDR1(CBOR_MAJOR_BSTR, CBOR_BYTES1);
840*4f2df630SAndroid Build Coastguard Worker gsc_boot_param->auth_token_key_seed.cbor_hdr[1] = KEY_SEED_BYTES;
841*4f2df630SAndroid Build Coastguard Worker
842*4f2df630SAndroid Build Coastguard Worker if (!__platform_get_gsc_boot_param(
843*4f2df630SAndroid Build Coastguard Worker gsc_boot_param->early_entropy.value,
844*4f2df630SAndroid Build Coastguard Worker gsc_boot_param->session_key_seed.value,
845*4f2df630SAndroid Build Coastguard Worker gsc_boot_param->auth_token_key_seed.value)) {
846*4f2df630SAndroid Build Coastguard Worker __platform_log_str("Failed to get GSC boot param");
847*4f2df630SAndroid Build Coastguard Worker return false;
848*4f2df630SAndroid Build Coastguard Worker }
849*4f2df630SAndroid Build Coastguard Worker return true;
850*4f2df630SAndroid Build Coastguard Worker }
851*4f2df630SAndroid Build Coastguard Worker
852*4f2df630SAndroid Build Coastguard Worker /* Fills GSCBootParam and BootParam header in struct dice_ctx_s. */
853*4f2df630SAndroid Build Coastguard Worker /* Doesn't touch DICE handover structure */
fill_boot_param(struct dice_ctx_s * ctx)854*4f2df630SAndroid Build Coastguard Worker static inline bool fill_boot_param(
855*4f2df630SAndroid Build Coastguard Worker struct dice_ctx_s *ctx /* [IN/OUT] dice context */
856*4f2df630SAndroid Build Coastguard Worker )
857*4f2df630SAndroid Build Coastguard Worker {
858*4f2df630SAndroid Build Coastguard Worker /* BootParam: Map header: 3 entries */
859*4f2df630SAndroid Build Coastguard Worker ctx->output.map_hdr = CBOR_HDR1(CBOR_MAJOR_MAP, 3);
860*4f2df630SAndroid Build Coastguard Worker
861*4f2df630SAndroid Build Coastguard Worker /* BootParam entry 1: Version:
862*4f2df630SAndroid Build Coastguard Worker * uint(1, 0bytes) => uint(BOOT_PARAM_VERSION, 0bytes)
863*4f2df630SAndroid Build Coastguard Worker */
864*4f2df630SAndroid Build Coastguard Worker ctx->output.version_label = CBOR_UINT0(1);
865*4f2df630SAndroid Build Coastguard Worker ctx->output.version = CBOR_UINT0(0);
866*4f2df630SAndroid Build Coastguard Worker
867*4f2df630SAndroid Build Coastguard Worker /* BootParam entry 2: GSCBootParam:
868*4f2df630SAndroid Build Coastguard Worker * uint(2, 0bytes) => GSCBootParam (filled in fill_gsc_boot_param)
869*4f2df630SAndroid Build Coastguard Worker */
870*4f2df630SAndroid Build Coastguard Worker ctx->output.gsc_boot_param_label = CBOR_UINT0(2);
871*4f2df630SAndroid Build Coastguard Worker
872*4f2df630SAndroid Build Coastguard Worker /* BootParam entry 3: AndroidDiceHandover:
873*4f2df630SAndroid Build Coastguard Worker * uint(3, 0bytes) => AndroidDiceHandover (not touched in this func)
874*4f2df630SAndroid Build Coastguard Worker */
875*4f2df630SAndroid Build Coastguard Worker ctx->output.dice_handover_label = CBOR_UINT0(3);
876*4f2df630SAndroid Build Coastguard Worker
877*4f2df630SAndroid Build Coastguard Worker return fill_gsc_boot_param(&ctx->output.gsc_boot_param);
878*4f2df630SAndroid Build Coastguard Worker }
879*4f2df630SAndroid Build Coastguard Worker
880*4f2df630SAndroid Build Coastguard Worker /* Get (part of) BootParam structure: [offset .. offset + size). */
get_boot_param_bytes(uint8_t * dest,size_t offset,size_t size)881*4f2df630SAndroid Build Coastguard Worker size_t get_boot_param_bytes(
882*4f2df630SAndroid Build Coastguard Worker /* [OUT] destination buffer to fill */
883*4f2df630SAndroid Build Coastguard Worker uint8_t *dest,
884*4f2df630SAndroid Build Coastguard Worker /* [IN] starting offset in the BootParam struct */
885*4f2df630SAndroid Build Coastguard Worker size_t offset,
886*4f2df630SAndroid Build Coastguard Worker /* [IN] size of the BootParam struct to copy */
887*4f2df630SAndroid Build Coastguard Worker size_t size
888*4f2df630SAndroid Build Coastguard Worker )
889*4f2df630SAndroid Build Coastguard Worker {
890*4f2df630SAndroid Build Coastguard Worker struct dice_ctx_s ctx;
891*4f2df630SAndroid Build Coastguard Worker uint8_t *src = (uint8_t *)&ctx.output;
892*4f2df630SAndroid Build Coastguard Worker
893*4f2df630SAndroid Build Coastguard Worker if (size == 0 || offset >= BOOT_PARAM_SIZE)
894*4f2df630SAndroid Build Coastguard Worker return 0;
895*4f2df630SAndroid Build Coastguard Worker if (size > BOOT_PARAM_SIZE - offset)
896*4f2df630SAndroid Build Coastguard Worker size = BOOT_PARAM_SIZE - offset;
897*4f2df630SAndroid Build Coastguard Worker
898*4f2df630SAndroid Build Coastguard Worker if (!__platform_get_dice_config(&ctx.cfg)) {
899*4f2df630SAndroid Build Coastguard Worker __platform_log_str("Failed to get DICE config");
900*4f2df630SAndroid Build Coastguard Worker return 0;
901*4f2df630SAndroid Build Coastguard Worker }
902*4f2df630SAndroid Build Coastguard Worker if (!generate_dice_handover(&ctx))
903*4f2df630SAndroid Build Coastguard Worker return 0;
904*4f2df630SAndroid Build Coastguard Worker
905*4f2df630SAndroid Build Coastguard Worker if (!fill_boot_param(&ctx))
906*4f2df630SAndroid Build Coastguard Worker return 0;
907*4f2df630SAndroid Build Coastguard Worker
908*4f2df630SAndroid Build Coastguard Worker __platform_memcpy(dest, src + offset, size);
909*4f2df630SAndroid Build Coastguard Worker return size;
910*4f2df630SAndroid Build Coastguard Worker }
911*4f2df630SAndroid Build Coastguard Worker
912*4f2df630SAndroid Build Coastguard Worker /* Get (part of) DiceChain structure: [offset .. offset + size) */
get_dice_chain_bytes(uint8_t * dest,size_t offset,size_t size)913*4f2df630SAndroid Build Coastguard Worker size_t get_dice_chain_bytes(
914*4f2df630SAndroid Build Coastguard Worker /* [OUT] destination buffer to fill */
915*4f2df630SAndroid Build Coastguard Worker uint8_t *dest,
916*4f2df630SAndroid Build Coastguard Worker /* [IN] starting offset in the DiceChain struct */
917*4f2df630SAndroid Build Coastguard Worker size_t offset,
918*4f2df630SAndroid Build Coastguard Worker /* [IN] size of the data to copy */
919*4f2df630SAndroid Build Coastguard Worker size_t size
920*4f2df630SAndroid Build Coastguard Worker )
921*4f2df630SAndroid Build Coastguard Worker {
922*4f2df630SAndroid Build Coastguard Worker struct dice_ctx_s ctx;
923*4f2df630SAndroid Build Coastguard Worker uint8_t *src = (uint8_t *)&ctx.output.dice_handover.options;
924*4f2df630SAndroid Build Coastguard Worker
925*4f2df630SAndroid Build Coastguard Worker if (size == 0 || offset >= DICE_CHAIN_SIZE)
926*4f2df630SAndroid Build Coastguard Worker return 0;
927*4f2df630SAndroid Build Coastguard Worker if (size > DICE_CHAIN_SIZE - offset)
928*4f2df630SAndroid Build Coastguard Worker size = DICE_CHAIN_SIZE - offset;
929*4f2df630SAndroid Build Coastguard Worker
930*4f2df630SAndroid Build Coastguard Worker if (!__platform_get_dice_config(&ctx.cfg)) {
931*4f2df630SAndroid Build Coastguard Worker __platform_log_str("Failed to get DICE config");
932*4f2df630SAndroid Build Coastguard Worker return 0;
933*4f2df630SAndroid Build Coastguard Worker }
934*4f2df630SAndroid Build Coastguard Worker if (!generate_dice_handover(&ctx))
935*4f2df630SAndroid Build Coastguard Worker return 0;
936*4f2df630SAndroid Build Coastguard Worker
937*4f2df630SAndroid Build Coastguard Worker __platform_memcpy(dest, src + offset, size);
938*4f2df630SAndroid Build Coastguard Worker return size;
939*4f2df630SAndroid Build Coastguard Worker }
940