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