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