xref: /aosp_15_r20/external/gsc-utils/boot_param/test.c (revision 4f2df630800bdcf1d4f0decf95d8a1cb87344f5f)
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 <stdio.h>
8*4f2df630SAndroid Build Coastguard Worker #include <string.h>
9*4f2df630SAndroid Build Coastguard Worker 
10*4f2df630SAndroid Build Coastguard Worker #include "boot_param.h"
11*4f2df630SAndroid Build Coastguard Worker #include "boot_param_platform.h"
12*4f2df630SAndroid Build Coastguard Worker #include "boot_param_platform_host.h"
13*4f2df630SAndroid Build Coastguard Worker 
14*4f2df630SAndroid Build Coastguard Worker #define DUMPVAR(name) hexdump(#name, name, sizeof(name))
15*4f2df630SAndroid Build Coastguard Worker 
hexdump(const char * pfx,const uint8_t * buf,size_t size)16*4f2df630SAndroid Build Coastguard Worker static void hexdump(const char *pfx, const uint8_t *buf, size_t size)
17*4f2df630SAndroid Build Coastguard Worker {
18*4f2df630SAndroid Build Coastguard Worker 	size_t i;
19*4f2df630SAndroid Build Coastguard Worker 
20*4f2df630SAndroid Build Coastguard Worker 	printf("%s:\n  ", pfx);
21*4f2df630SAndroid Build Coastguard Worker 	for (i = 0; i < size; i++) {
22*4f2df630SAndroid Build Coastguard Worker 		if (i > 0 && i % 16 == 0)
23*4f2df630SAndroid Build Coastguard Worker 			printf("\n  ");
24*4f2df630SAndroid Build Coastguard Worker 		printf("%02x ", buf[i]);
25*4f2df630SAndroid Build Coastguard Worker 	}
26*4f2df630SAndroid Build Coastguard Worker 	printf("\n");
27*4f2df630SAndroid Build Coastguard Worker }
28*4f2df630SAndroid Build Coastguard Worker 
29*4f2df630SAndroid Build Coastguard Worker #undef TEST_PLATFORM
30*4f2df630SAndroid Build Coastguard Worker 
31*4f2df630SAndroid Build Coastguard Worker #ifdef TEST_PLATFORM
32*4f2df630SAndroid Build Coastguard Worker 
test_hkdf(void)33*4f2df630SAndroid Build Coastguard Worker static void test_hkdf(void)
34*4f2df630SAndroid Build Coastguard Worker {
35*4f2df630SAndroid Build Coastguard Worker 	uint8_t derived[DIGEST_BYTES];
36*4f2df630SAndroid Build Coastguard Worker 	const struct slice_ref_s ikm = {
37*4f2df630SAndroid Build Coastguard Worker 		3, (const uint8_t *)"key"
38*4f2df630SAndroid Build Coastguard Worker 	};
39*4f2df630SAndroid Build Coastguard Worker 	const struct slice_ref_s salt = {
40*4f2df630SAndroid Build Coastguard Worker 		4, (const uint8_t *)"salt"
41*4f2df630SAndroid Build Coastguard Worker 	};
42*4f2df630SAndroid Build Coastguard Worker 	const struct slice_ref_s info = {
43*4f2df630SAndroid Build Coastguard Worker 		5, (const uint8_t *)"label"
44*4f2df630SAndroid Build Coastguard Worker 	};
45*4f2df630SAndroid Build Coastguard Worker 	const struct slice_mut_s result = {DIGEST_BYTES, derived };
46*4f2df630SAndroid Build Coastguard Worker 
47*4f2df630SAndroid Build Coastguard Worker 	if (__platform_hkdf_sha256(ikm, salt, info, result)) {
48*4f2df630SAndroid Build Coastguard Worker 		__platform_log_str("HKDF: success");
49*4f2df630SAndroid Build Coastguard Worker 		DUMPVAR(derived);
50*4f2df630SAndroid Build Coastguard Worker 	} else {
51*4f2df630SAndroid Build Coastguard Worker 		__platform_log_str("HKDF: failed");
52*4f2df630SAndroid Build Coastguard Worker 	}
53*4f2df630SAndroid Build Coastguard Worker }
54*4f2df630SAndroid Build Coastguard Worker 
test_sha(void)55*4f2df630SAndroid Build Coastguard Worker static void test_sha(void)
56*4f2df630SAndroid Build Coastguard Worker {
57*4f2df630SAndroid Build Coastguard Worker 	uint8_t digest[DIGEST_BYTES];
58*4f2df630SAndroid Build Coastguard Worker 	const struct slice_ref_s input = {
59*4f2df630SAndroid Build Coastguard Worker 		4, (const uint8_t *)"test"
60*4f2df630SAndroid Build Coastguard Worker 	};
61*4f2df630SAndroid Build Coastguard Worker 
62*4f2df630SAndroid Build Coastguard Worker 	if (__platform_sha256(input, digest)) {
63*4f2df630SAndroid Build Coastguard Worker 		__platform_log_str("SHA256: success");
64*4f2df630SAndroid Build Coastguard Worker 		DUMPVAR(digest);
65*4f2df630SAndroid Build Coastguard Worker 	} else {
66*4f2df630SAndroid Build Coastguard Worker 		__platform_log_str("SHA256: failed");
67*4f2df630SAndroid Build Coastguard Worker 	}
68*4f2df630SAndroid Build Coastguard Worker }
69*4f2df630SAndroid Build Coastguard Worker 
test_ecdsa(void)70*4f2df630SAndroid Build Coastguard Worker static void test_ecdsa(void)
71*4f2df630SAndroid Build Coastguard Worker {
72*4f2df630SAndroid Build Coastguard Worker 	uint8_t seed[DIGEST_BYTES] = { 0 };
73*4f2df630SAndroid Build Coastguard Worker 	const void *key;
74*4f2df630SAndroid Build Coastguard Worker 	const struct slice_ref_s input = {
75*4f2df630SAndroid Build Coastguard Worker 		4, (const uint8_t *)"test"
76*4f2df630SAndroid Build Coastguard Worker 	};
77*4f2df630SAndroid Build Coastguard Worker 	uint8_t signature[ECDSA_SIG_BYTES];
78*4f2df630SAndroid Build Coastguard Worker 	struct ecdsa_public_s pub_key;
79*4f2df630SAndroid Build Coastguard Worker 
80*4f2df630SAndroid Build Coastguard Worker 	if (!__platform_ecdsa_p256_keygen_hmac_drbg(seed, &key)) {
81*4f2df630SAndroid Build Coastguard Worker 		__platform_log_str("ECDSA: keygen failed");
82*4f2df630SAndroid Build Coastguard Worker 		return;
83*4f2df630SAndroid Build Coastguard Worker 	}
84*4f2df630SAndroid Build Coastguard Worker 
85*4f2df630SAndroid Build Coastguard Worker 	if (!__platform_ecdsa_p256_sign(key, input, signature)) {
86*4f2df630SAndroid Build Coastguard Worker 		__platform_log_str("ECDSA: sign failed");
87*4f2df630SAndroid Build Coastguard Worker 		__platform_ecdsa_p256_free(key);
88*4f2df630SAndroid Build Coastguard Worker 		return;
89*4f2df630SAndroid Build Coastguard Worker 	}
90*4f2df630SAndroid Build Coastguard Worker 
91*4f2df630SAndroid Build Coastguard Worker 	if (!__platform_ecdsa_p256_get_pub_key(key, &pub_key)) {
92*4f2df630SAndroid Build Coastguard Worker 		__platform_log_str("ECDSA: get pubkey failed");
93*4f2df630SAndroid Build Coastguard Worker 		__platform_ecdsa_p256_free(key);
94*4f2df630SAndroid Build Coastguard Worker 		return;
95*4f2df630SAndroid Build Coastguard Worker 	}
96*4f2df630SAndroid Build Coastguard Worker 
97*4f2df630SAndroid Build Coastguard Worker 	__platform_ecdsa_p256_free(key);
98*4f2df630SAndroid Build Coastguard Worker 	__platform_log_str("ECDSA: success");
99*4f2df630SAndroid Build Coastguard Worker 	DUMPVAR(signature);
100*4f2df630SAndroid Build Coastguard Worker 	DUMPVAR(pub_key.x);
101*4f2df630SAndroid Build Coastguard Worker 	DUMPVAR(pub_key.y);
102*4f2df630SAndroid Build Coastguard Worker }
103*4f2df630SAndroid Build Coastguard Worker #endif /* TEST_PLATFORM */
104*4f2df630SAndroid Build Coastguard Worker 
save_to_file(const char * filename,uint8_t * buf,size_t size)105*4f2df630SAndroid Build Coastguard Worker static bool save_to_file(
106*4f2df630SAndroid Build Coastguard Worker 	const char *filename,
107*4f2df630SAndroid Build Coastguard Worker 	uint8_t *buf,
108*4f2df630SAndroid Build Coastguard Worker 	size_t size
109*4f2df630SAndroid Build Coastguard Worker )
110*4f2df630SAndroid Build Coastguard Worker {
111*4f2df630SAndroid Build Coastguard Worker 	FILE *f;
112*4f2df630SAndroid Build Coastguard Worker 	size_t written;
113*4f2df630SAndroid Build Coastguard Worker 
114*4f2df630SAndroid Build Coastguard Worker 	f = fopen(filename, "wb");
115*4f2df630SAndroid Build Coastguard Worker 	if (f == NULL) {
116*4f2df630SAndroid Build Coastguard Worker 		printf("Failed to open file \"%s\"\n", filename);
117*4f2df630SAndroid Build Coastguard Worker 		return false;
118*4f2df630SAndroid Build Coastguard Worker 	}
119*4f2df630SAndroid Build Coastguard Worker 	written = fwrite(buf, 1, size, f);
120*4f2df630SAndroid Build Coastguard Worker 	fclose(f);
121*4f2df630SAndroid Build Coastguard Worker 	return written == size;
122*4f2df630SAndroid Build Coastguard Worker }
123*4f2df630SAndroid Build Coastguard Worker 
test_boot_param(const char * filename_handover,const char * filename_chain)124*4f2df630SAndroid Build Coastguard Worker static bool test_boot_param(
125*4f2df630SAndroid Build Coastguard Worker 	const char *filename_handover,
126*4f2df630SAndroid Build Coastguard Worker 	const char *filename_chain
127*4f2df630SAndroid Build Coastguard Worker )
128*4f2df630SAndroid Build Coastguard Worker {
129*4f2df630SAndroid Build Coastguard Worker 	uint8_t boot_param[BOOT_PARAM_SIZE];
130*4f2df630SAndroid Build Coastguard Worker 	uint8_t dice_chain[DICE_CHAIN_SIZE];
131*4f2df630SAndroid Build Coastguard Worker 
132*4f2df630SAndroid Build Coastguard Worker 	if (get_boot_param_bytes(boot_param, 0, BOOT_PARAM_SIZE) !=
133*4f2df630SAndroid Build Coastguard Worker 				 BOOT_PARAM_SIZE) {
134*4f2df630SAndroid Build Coastguard Worker 		printf("get_boot_param_bytes failed");
135*4f2df630SAndroid Build Coastguard Worker 		return false;
136*4f2df630SAndroid Build Coastguard Worker 	}
137*4f2df630SAndroid Build Coastguard Worker 	DUMPVAR(boot_param);
138*4f2df630SAndroid Build Coastguard Worker 
139*4f2df630SAndroid Build Coastguard Worker 	if (get_dice_chain_bytes(dice_chain, 0, DICE_CHAIN_SIZE) !=
140*4f2df630SAndroid Build Coastguard Worker 				 DICE_CHAIN_SIZE) {
141*4f2df630SAndroid Build Coastguard Worker 		printf("get_dice_chain_bytes failed");
142*4f2df630SAndroid Build Coastguard Worker 		return false;
143*4f2df630SAndroid Build Coastguard Worker 	}
144*4f2df630SAndroid Build Coastguard Worker 	DUMPVAR(dice_chain);
145*4f2df630SAndroid Build Coastguard Worker 
146*4f2df630SAndroid Build Coastguard Worker 	return
147*4f2df630SAndroid Build Coastguard Worker 		save_to_file(filename_handover,
148*4f2df630SAndroid Build Coastguard Worker 			     boot_param,
149*4f2df630SAndroid Build Coastguard Worker 			     BOOT_PARAM_SIZE) &&
150*4f2df630SAndroid Build Coastguard Worker 		save_to_file(filename_chain,
151*4f2df630SAndroid Build Coastguard Worker 			     dice_chain,
152*4f2df630SAndroid Build Coastguard Worker 			     DICE_CHAIN_SIZE);
153*4f2df630SAndroid Build Coastguard Worker }
154*4f2df630SAndroid Build Coastguard Worker 
155*4f2df630SAndroid Build Coastguard Worker /* PCR0 values for various modes - see go/pcr0-tpm2 */
156*4f2df630SAndroid Build Coastguard Worker static const uint8_t kPcr0NormalMode[DIGEST_BYTES] = {
157*4f2df630SAndroid Build Coastguard Worker 	0x89, 0xEA, 0xF3, 0x51, 0x34, 0xB4, 0xB3, 0xC6,
158*4f2df630SAndroid Build Coastguard Worker 	0x49, 0xF4, 0x4C, 0x0C, 0x76, 0x5B, 0x96, 0xAE,
159*4f2df630SAndroid Build Coastguard Worker 	0xAB, 0x8B, 0xB3, 0x4E, 0xE8, 0x3C, 0xC7, 0xA6,
160*4f2df630SAndroid Build Coastguard Worker 	0x83, 0xC4, 0xE5, 0x3D, 0x15, 0x81, 0xC8, 0xC7
161*4f2df630SAndroid Build Coastguard Worker };
162*4f2df630SAndroid Build Coastguard Worker static const uint8_t kPcr0RecoveryNormalMode[DIGEST_BYTES] = {
163*4f2df630SAndroid Build Coastguard Worker 	0x9F, 0x9E, 0xA8, 0x66, 0xD3, 0xF3, 0x4F, 0xE3,
164*4f2df630SAndroid Build Coastguard Worker 	0xA3, 0x11, 0x2A, 0xE9, 0xCB, 0x1F, 0xBA, 0xBC,
165*4f2df630SAndroid Build Coastguard Worker 	0x6F, 0xFE, 0x8C, 0xD2, 0x61, 0xD4, 0x24, 0x93,
166*4f2df630SAndroid Build Coastguard Worker 	0xBC, 0x68, 0x42, 0xA9, 0xE4, 0xF9, 0x3B, 0x3D
167*4f2df630SAndroid Build Coastguard Worker };
168*4f2df630SAndroid Build Coastguard Worker static const uint8_t kPcr0DebugMode[DIGEST_BYTES] = {
169*4f2df630SAndroid Build Coastguard Worker 	0x23, 0xE1, 0x4D, 0xD9, 0xBB, 0x51, 0xA5, 0x0E,
170*4f2df630SAndroid Build Coastguard Worker 	0x16, 0x91, 0x1F, 0x7E, 0x11, 0xDF, 0x1E, 0x1A,
171*4f2df630SAndroid Build Coastguard Worker 	0xAF, 0x0B, 0x17, 0x13, 0x4D, 0xC7, 0x39, 0xC5,
172*4f2df630SAndroid Build Coastguard Worker 	0x65, 0x36, 0x07, 0xA1, 0xEC, 0x8D, 0xD3, 0x7A
173*4f2df630SAndroid Build Coastguard Worker };
174*4f2df630SAndroid Build Coastguard Worker static const uint8_t kPcr0Zeroes[DIGEST_BYTES] = {
175*4f2df630SAndroid Build Coastguard Worker 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176*4f2df630SAndroid Build Coastguard Worker 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177*4f2df630SAndroid Build Coastguard Worker 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178*4f2df630SAndroid Build Coastguard Worker 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
179*4f2df630SAndroid Build Coastguard Worker };
180*4f2df630SAndroid Build Coastguard Worker 
set_pcr0(const char * param)181*4f2df630SAndroid Build Coastguard Worker static void set_pcr0(const char *param)
182*4f2df630SAndroid Build Coastguard Worker {
183*4f2df630SAndroid Build Coastguard Worker 	const uint8_t *pcr0 = kPcr0DebugMode;
184*4f2df630SAndroid Build Coastguard Worker 
185*4f2df630SAndroid Build Coastguard Worker 	switch (param[0]) {
186*4f2df630SAndroid Build Coastguard Worker 	case '0':
187*4f2df630SAndroid Build Coastguard Worker 		pcr0 = kPcr0Zeroes;
188*4f2df630SAndroid Build Coastguard Worker 		break;
189*4f2df630SAndroid Build Coastguard Worker 	case 'n':
190*4f2df630SAndroid Build Coastguard Worker 		pcr0 = kPcr0NormalMode;
191*4f2df630SAndroid Build Coastguard Worker 		break;
192*4f2df630SAndroid Build Coastguard Worker 	case 'r':
193*4f2df630SAndroid Build Coastguard Worker 		pcr0 = kPcr0RecoveryNormalMode;
194*4f2df630SAndroid Build Coastguard Worker 		break;
195*4f2df630SAndroid Build Coastguard Worker 	}
196*4f2df630SAndroid Build Coastguard Worker 
197*4f2df630SAndroid Build Coastguard Worker 	memcpy(g_dice_config.pcr0, pcr0, DIGEST_BYTES);
198*4f2df630SAndroid Build Coastguard Worker }
199*4f2df630SAndroid Build Coastguard Worker 
main(int argc,char * argv[])200*4f2df630SAndroid Build Coastguard Worker int main(int argc, char *argv[])
201*4f2df630SAndroid Build Coastguard Worker {
202*4f2df630SAndroid Build Coastguard Worker #ifdef TEST_PLATFORM
203*4f2df630SAndroid Build Coastguard Worker 	printf("BOOT_PARAM_SIZE = %zu\n", BOOT_PARAM_SIZE);
204*4f2df630SAndroid Build Coastguard Worker 	printf("DICE_CHAIN_SIZE = %zu\n", DICE_CHAIN_SIZE);
205*4f2df630SAndroid Build Coastguard Worker 	test_hkdf();
206*4f2df630SAndroid Build Coastguard Worker 	test_sha();
207*4f2df630SAndroid Build Coastguard Worker 	test_ecdsa();
208*4f2df630SAndroid Build Coastguard Worker #endif /* TEST_PLATFORM */
209*4f2df630SAndroid Build Coastguard Worker 
210*4f2df630SAndroid Build Coastguard Worker 	if (argc != 1 + 3) {
211*4f2df630SAndroid Build Coastguard Worker 		printf("Syntax: %s <boot_param> <dice_chain> <bootmode>\n"
212*4f2df630SAndroid Build Coastguard Worker 		       "  where\n"
213*4f2df630SAndroid Build Coastguard Worker 		       "    <boot_param> - filename for writing the "
214*4f2df630SAndroid Build Coastguard Worker 		       "BootParam structure\n"
215*4f2df630SAndroid Build Coastguard Worker 		       "    <dice_chain> - filename for writing the "
216*4f2df630SAndroid Build Coastguard Worker 		       "dice chain structure\n"
217*4f2df630SAndroid Build Coastguard Worker 		       "    <bootmode> - sets PCR0 value: when starts with\n"
218*4f2df630SAndroid Build Coastguard Worker 		       "        0 = all zeroes\n"
219*4f2df630SAndroid Build Coastguard Worker 		       "        n = normal mode\n"
220*4f2df630SAndroid Build Coastguard Worker 		       "        r = recovery mode\n"
221*4f2df630SAndroid Build Coastguard Worker 		       "        <anything else> = debug mode\n"
222*4f2df630SAndroid Build Coastguard Worker 		       "",
223*4f2df630SAndroid Build Coastguard Worker 		       argv[0]);
224*4f2df630SAndroid Build Coastguard Worker 		return 2;
225*4f2df630SAndroid Build Coastguard Worker 	}
226*4f2df630SAndroid Build Coastguard Worker 	set_pcr0(argv[3]);
227*4f2df630SAndroid Build Coastguard Worker 	return test_boot_param(argv[1], argv[2]) ? 0 : 1;
228*4f2df630SAndroid Build Coastguard Worker }
229