blob: 824570e481e7260a46ad48208a769a16387680d9 [file] [log] [blame]
Angel Pons3ef916f2020-04-02 23:49:13 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Wim Vervoorn82100472020-01-27 15:47:44 +01002
Frans Hendriks72b3c3c2019-07-26 07:59:05 +02003#include <boot_device.h>
Wim Vervoorn46cc24d2019-11-14 11:45:03 +01004#include <bootmem.h>
Bill XIE516c0a52020-02-24 23:08:35 +08005#include <bootmode.h>
Frans Hendriks72b3c3c2019-07-26 07:59:05 +02006#include <cbfs.h>
7#include <vboot_check.h>
8#include <vboot_common.h>
Joel Kitching172ef5f2020-02-14 16:08:45 +08009#include <vb2_internals_please_do_not_use.h>
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020010
11#define RSA_PUBLICKEY_FILE_NAME "vboot_public_key.bin"
12
13#if CONFIG(VENDORCODE_ELTAN_VBOOT_USE_SHA512)
14#define DIGEST_SIZE VB2_SHA512_DIGEST_SIZE
Wim Vervoornac4896f2019-10-30 15:55:21 +010015#define HASH_ALG VB2_HASH_SHA512
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020016#else
17#define DIGEST_SIZE VB2_SHA256_DIGEST_SIZE
Wim Vervoornac4896f2019-10-30 15:55:21 +010018#define HASH_ALG VB2_HASH_SHA256
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020019#endif
20
21int verified_boot_check_manifest(void)
22{
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020023 uint8_t *buffer;
Wim Vervoorn82100472020-01-27 15:47:44 +010024 struct vb2_context *ctx;
25 struct vb2_kernel_preamble *pre;
26 static struct vb2_shared_data *sd;
27 size_t size;
Frans Hendriks70231742020-04-20 13:37:00 +020028 uint8_t wb_buffer[3000];
Wim Vervoorn82100472020-01-27 15:47:44 +010029
30 if (vb2api_init(&wb_buffer, sizeof(wb_buffer), &ctx)) {
31 goto fail;
32 }
33
34 sd = vb2_get_sd(ctx);
Wim Vervoornac4896f2019-10-30 15:55:21 +010035
Julius Werner834b3ec2020-03-04 16:52:08 -080036 buffer = cbfs_map(RSA_PUBLICKEY_FILE_NAME, &size);
Wim Vervoornac4896f2019-10-30 15:55:21 +010037 if (!buffer || !size) {
38 printk(BIOS_ERR, "ERROR: Public key not found!\n");
39 goto fail;
40 }
41
42 if ((size != CONFIG_VENDORCODE_ELTAN_VBOOT_KEY_SIZE) ||
Wim Vervoorn82100472020-01-27 15:47:44 +010043 (buffer != (void *)CONFIG_VENDORCODE_ELTAN_VBOOT_KEY_LOCATION)) {
Wim Vervoornac4896f2019-10-30 15:55:21 +010044 printk(BIOS_ERR, "ERROR: Illegal public key!\n");
45 goto fail;
46 }
47
Wim Vervoorn82100472020-01-27 15:47:44 +010048 /*
49 * Check if all items will fit into workbuffer:
50 * vb2_shared data, Public Key, Preamble data
51 */
52 if ((sd->workbuf_used + size + sizeof(struct vb2_kernel_preamble) +
53 ((CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE) + (2048/8))) >
54 sizeof(wb_buffer)) {
55 printk(BIOS_ERR, "ERROR: Work buffer too small\n");
Wim Vervoornac4896f2019-10-30 15:55:21 +010056 goto fail;
57 }
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020058
Wim Vervoorn82100472020-01-27 15:47:44 +010059 /* Add public key */
60 sd->data_key_offset = sd->workbuf_used;
61 sd->data_key_size = size;
62 sd->workbuf_used += sd->data_key_size;
63 memcpy((void *)((void *)sd + (long)sd->data_key_offset), (uint8_t *)buffer, size);
64
65 /* Fill preamble area */
66 sd->preamble_size = sizeof(struct vb2_kernel_preamble);
67 sd->preamble_offset = sd->data_key_offset + sd->data_key_size;
68 sd->workbuf_used += sd->preamble_size;
69 pre = (struct vb2_kernel_preamble *)((void *)sd + (long)sd->preamble_offset);
70
71 pre->flags = VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO;
72
73 /* Fill body_signature (vb2_structure). RSA2048 key is used */
Julius Werner834b3ec2020-03-04 16:52:08 -080074 cbfs_map("oemmanifest.bin", &size);
Wim Vervoorn82100472020-01-27 15:47:44 +010075 if (size != ((CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE) + (2048/8))) {
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020076 printk(BIOS_ERR, "ERROR: Incorrect manifest size!\n");
77 goto fail;
78 }
Wim Vervoorn82100472020-01-27 15:47:44 +010079 pre->body_signature.data_size = CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS *
80 DIGEST_SIZE;
81 pre->body_signature.sig_offset = sizeof(struct vb2_signature) +
82 pre->body_signature.data_size;
Frans Hendriks988a2732020-04-20 13:58:07 +020083 pre->body_signature.sig_size = size - pre->body_signature.data_size;
Wim Vervoorn82100472020-01-27 15:47:44 +010084 sd->workbuf_used += size;
85 memcpy((void *)((void *)&pre->body_signature + (long)sizeof(struct vb2_signature)),
Wim Vervoorn944fdc42019-10-30 16:46:41 +010086 (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC, size);
Wim Vervoornac4896f2019-10-30 15:55:21 +010087
Wim Vervoorn82100472020-01-27 15:47:44 +010088
89 if (vb2api_verify_kernel_data(ctx, (void *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC,
90 pre->body_signature.data_size))
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020091 goto fail;
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020092
Wim Vervoornac4896f2019-10-30 15:55:21 +010093 printk(BIOS_INFO, "%s: Successfully verified hash_table signature.\n", __func__);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020094 return 0;
95
96fail:
Wim Vervoorn82100472020-01-27 15:47:44 +010097 die("ERROR: HASH table verification failed!\n");
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020098 return -1;
99}
100
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200101/*
102 *
103 * measure_item
104 *
105 * extends the defined pcr using the hash calculated by the verified boot
106 * routines.
107 *
108 * @param[in] pcr PCR to extend
109 * @param[in] *hashData Pointer to the hash data
110 * @param[in] hashDataLen Length of the hash data
111 * @param[in] *event_msg Message to log or display
112 * @param[in] eventType Event type to use when logging
113
114 * @retval TPM_SUCCESS Operation completed successfully.
115 * @retval TPM_E_IOERROR Unexpected device behavior.
116 */
117static int measure_item(uint32_t pcr, uint8_t *hashData, uint32_t hashDataLen,
118 int8_t *event_msg, TCG_EVENTTYPE eventType)
119{
120 int status = TPM_SUCCESS;
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200121 TCG_PCR_EVENT2_HDR tcgEventHdr;
122
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200123 memset(&tcgEventHdr, 0, sizeof(tcgEventHdr));
124 tcgEventHdr.pcrIndex = pcr;
125 tcgEventHdr.eventType = eventType;
126 if (event_msg) {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100127 status = mboot_hash_extend_log(MBOOT_HASH_PROVIDED, hashData,
128 hashDataLen, &tcgEventHdr,
129 (uint8_t *)event_msg);
130 if (status == TPM_SUCCESS)
131 printk(BIOS_INFO, "%s: Success! %s measured to pcr %d.\n", __func__,
132 event_msg, pcr);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200133 }
134 return status;
135}
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200136
Wim Vervoornac4896f2019-10-30 15:55:21 +0100137static void verified_boot_check_buffer(const char *name, void *start, size_t size,
138 uint32_t hash_index, int32_t pcr)
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200139{
140 uint8_t digest[DIGEST_SIZE];
Wim Vervoornac4896f2019-10-30 15:55:21 +0100141 vb2_error_t status;
142
143 printk(BIOS_DEBUG, "%s: %s HASH verification buffer %p size %d\n", __func__, name,
144 start, (int)size);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200145
146 if (start && size) {
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200147
Frans Hendriks988a2732020-04-20 13:58:07 +0200148 status = vb2_digest_buffer((const uint8_t *)start, size, HASH_ALG, digest,
149 DIGEST_SIZE);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200150 if ((CONFIG(VENDORCODE_ELTAN_VBOOT) && memcmp((void *)(
151 (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC +
Wim Vervoornac4896f2019-10-30 15:55:21 +0100152 sizeof(digest) * hash_index), digest, sizeof(digest))) || status) {
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200153 printk(BIOS_DEBUG, "%s: buffer hash\n", __func__);
154 hexdump(digest, sizeof(digest));
155 printk(BIOS_DEBUG, "%s: manifest hash\n", __func__);
Wim Vervoornac4896f2019-10-30 15:55:21 +0100156 hexdump((void *)( (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC +
157 sizeof(digest) * hash_index), sizeof(digest));
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200158 printk(BIOS_EMERG, "%s ", name);
159 die("HASH verification failed!\n");
160 } else {
Kyösti Mälkkibf43f9e2019-11-05 17:55:15 +0200161 if (!ENV_BOOTBLOCK && CONFIG(VENDORCODE_ELTAN_MBOOT)) {
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200162 if (pcr != -1) {
Wim Vervoornffe4eba2019-11-14 11:06:35 +0100163 printk(BIOS_DEBUG, "%s: measuring %s\n", __func__,
164 name);
Wim Vervoornac4896f2019-10-30 15:55:21 +0100165 if (measure_item(pcr, digest, sizeof(digest),
166 (int8_t *)name, 0))
Wim Vervoorn944fdc42019-10-30 16:46:41 +0100167 printk(BIOS_DEBUG, "%s: measuring failed!\n",
168 __func__);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200169 }
170 }
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200171 if (CONFIG(VENDORCODE_ELTAN_VBOOT))
Wim Vervoornac4896f2019-10-30 15:55:21 +0100172 printk(BIOS_DEBUG, "%s HASH verification success\n", name);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200173 }
174 } else {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100175 printk(BIOS_EMERG, "Invalid buffer\n");
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200176 die("HASH verification failed!\n");
177 }
178}
179
Wim Vervoornac4896f2019-10-30 15:55:21 +0100180void verified_boot_check_cbfsfile(const char *name, uint32_t type, uint32_t hash_index,
181 void **buffer, uint32_t *filesize, int32_t pcr)
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200182{
183 void *start;
184 size_t size;
185
Julius Werner834b3ec2020-03-04 16:52:08 -0800186 start = cbfs_map(name, &size);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200187 if (start && size) {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100188 /* Speed up processing by copying the file content to memory first */
Wim Vervoorn46cc24d2019-11-14 11:45:03 +0100189 if (!ENV_ROMSTAGE_OR_BEFORE && (type & VERIFIED_BOOT_COPY_BLOCK)) {
190
191 if ((buffer) && (*buffer) && (*filesize >= size) &&
192 ((uint32_t) start > (uint32_t)(~(CONFIG_CBFS_SIZE-1)))) {
193
194 /* Use the buffer passed in if possible */
Wim Vervoornac4896f2019-10-30 15:55:21 +0100195 printk(BIOS_DEBUG, "%s: move buffer to memory\n", __func__);
Wim Vervoorn46cc24d2019-11-14 11:45:03 +0100196 /* Move the file to memory buffer passed in */
197 memcpy(*buffer, start, size);
198 start = *buffer;
199 printk(BIOS_DEBUG, "%s: done\n", __func__);
200
201 } else if (ENV_RAMSTAGE) {
202 /* Try to allocate a buffer from boot_mem */
203 void *local_buffer = bootmem_allocate_buffer(size);
204
205 if (local_buffer) {
206
207 /* Use the allocated buffer */
208 printk(BIOS_DEBUG, "%s: move file to memory\n",
209 __func__);
210 memcpy(local_buffer, start, size);
211 start = local_buffer;
212 printk(BIOS_DEBUG, "%s: done\n", __func__);
213 }
214 }
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200215 }
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200216 verified_boot_check_buffer(name, start, size, hash_index, pcr);
217 } else {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100218 printk(BIOS_EMERG, "CBFS Failed to get file content for %s\n", name);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200219 die("HASH verification failed!\n");
220 }
221 if (buffer)
222 *buffer = start;
223 if (filesize)
224 *filesize = size;
225}
226
227void process_verify_list(const verify_item_t list[])
228{
229 int i = 0;
230
231 while (list[i].type != VERIFY_TERMINATOR) {
232 switch (list[i].type) {
233 case VERIFY_FILE:
Wim Vervoornac4896f2019-10-30 15:55:21 +0100234 verified_boot_check_cbfsfile(list[i].name, list[i].data.file.cbfs_type,
235 list[i].hash_index, NULL, NULL, list[i].pcr);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200236 if (list[i].data.file.related_items) {
237 printk(BIOS_SPEW, "process related items\n");
Wim Vervoornac4896f2019-10-30 15:55:21 +0100238 process_verify_list(
239 (verify_item_t *)list[i].data.file.related_items);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200240 }
241 break;
242 case VERIFY_BLOCK:
243 verified_boot_check_buffer(list[i].name,
Wim Vervoornac4896f2019-10-30 15:55:21 +0100244 (void *)list[i].data.block.start,
245 list[i].data.block.size,
246 list[i].hash_index, list[i].pcr);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200247 break;
248 default:
Wim Vervoornac4896f2019-10-30 15:55:21 +0100249 printk(BIOS_EMERG, "INVALID TYPE IN VERIFY LIST 0x%x\n", list[i].type);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200250 die("HASH verification failed!\n");
251 }
252 i++;
253 }
254}
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200255
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200256/*
257 * BOOTBLOCK
258 */
259
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200260void verified_boot_bootblock_check(void)
261{
262 printk(BIOS_SPEW, "%s: processing bootblock items\n", __func__);
263
264 if (CONFIG(VENDORCODE_ELTAN_VBOOT_SIGNED_MANIFEST)) {
265 printk(BIOS_SPEW, "%s: check the manifest\n", __func__);
266 if (verified_boot_check_manifest() != 0)
267 die("invalid manifest");
268 }
269 printk(BIOS_SPEW, "%s: process bootblock verify list\n", __func__);
270 process_verify_list(bootblock_verify_list);
271}
272
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200273/*
274 * ROMSTAGE
275 */
276
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200277void verified_boot_early_check(void)
278{
279 printk(BIOS_SPEW, "%s: processing early items\n", __func__);
280
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200281 if (CONFIG(VENDORCODE_ELTAN_MBOOT)) {
282 printk(BIOS_DEBUG, "mb_measure returned 0x%x\n",
Bill XIE516c0a52020-02-24 23:08:35 +0800283 mb_measure(platform_is_resuming()));
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200284 }
285
286 printk(BIOS_SPEW, "%s: process early verify list\n", __func__);
287 process_verify_list(romstage_verify_list);
288}
289
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200290/*
291 * RAM STAGE
292 */
293
294static int process_oprom_list(const verify_item_t list[],
295 struct rom_header *rom_header)
296{
297 int i = 0;
298 struct pci_data *rom_data;
299 uint32_t viddevid = 0;
300
301 if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100302 printk(BIOS_ERR, "Incorrect expansion ROM header signature %04x DONT START\n",
303 le32_to_cpu(rom_header->signature));
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200304 return 0;
305 }
306
307 rom_data = (((void *)rom_header) + le32_to_cpu(rom_header->data));
308
309 viddevid |= (rom_data->vendor << 16);
310 viddevid |= rom_data->device;
311
312 while (list[i].type != VERIFY_TERMINATOR) {
313 switch (list[i].type) {
314 case VERIFY_OPROM:
315 if (viddevid == list[i].data.oprom.viddev) {
316 verified_boot_check_buffer(list[i].name,
Wim Vervoornac4896f2019-10-30 15:55:21 +0100317 (void *)rom_header,
318 rom_header->size * 512,
319 list[i].hash_index, list[i].pcr);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200320 if (list[i].data.oprom.related_items) {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100321 printk(BIOS_SPEW, "%s: process related items\n",
322 __func__);
323 process_verify_list(
324 (verify_item_t *)list[i].data.oprom.related_items);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200325 }
Wim Vervoornac4896f2019-10-30 15:55:21 +0100326 printk(BIOS_SPEW, "%s: option rom can be started\n", __func__);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200327 return 1;
328 }
329 break;
330 default:
Wim Vervoornac4896f2019-10-30 15:55:21 +0100331 printk(BIOS_EMERG, "%s: INVALID TYPE IN OPTION ROM LIST 0x%x\n",
332 __func__, list[i].type);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200333 die("HASH verification failed!\n");
334 }
335 i++;
336 }
337 printk(BIOS_ERR, "%s: option rom not in list DONT START\n", __func__);
338 return 0;
339}
340
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200341int verified_boot_should_run_oprom(struct rom_header *rom_header)
342{
343 return process_oprom_list(oprom_verify_list, rom_header);
344}
345
Wim Vervoorne05dc172019-11-14 09:50:59 +0100346int prog_locate_hook(struct prog *prog)
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200347{
Wim Vervoornf4a30472019-11-14 10:03:25 +0100348 if (ENV_BOOTBLOCK)
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200349 verified_boot_bootblock_check();
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200350
351 if (ENV_ROMSTAGE) {
Wim Vervoornf4a30472019-11-14 10:03:25 +0100352 if (prog->type == PROG_REFCODE)
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200353 verified_boot_early_check();
Wim Vervoornf4a30472019-11-14 10:03:25 +0100354
355 if (CONFIG(POSTCAR_STAGE) && prog->type == PROG_POSTCAR)
356 process_verify_list(postcar_verify_list);
357
358 if (!CONFIG(POSTCAR_STAGE) && prog->type == PROG_RAMSTAGE)
359 process_verify_list(ramstage_verify_list);
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200360 }
361
Wim Vervoornf4a30472019-11-14 10:03:25 +0100362 if (ENV_POSTCAR && prog->type == PROG_RAMSTAGE)
363 process_verify_list(ramstage_verify_list);
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200364
Wim Vervoornf4a30472019-11-14 10:03:25 +0100365 if (ENV_RAMSTAGE && prog->type == PROG_PAYLOAD)
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200366 process_verify_list(payload_verify_list);
Wim Vervoornf4a30472019-11-14 10:03:25 +0100367
Wim Vervoorne05dc172019-11-14 09:50:59 +0100368 return 0;
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200369}