blob: 9d99e02e71b038ba2d044033677af0375a717ea7 [file] [log] [blame]
Frans Hendriks72b3c3c2019-07-26 07:59:05 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2016 Intel Corp.
5 * Copyright (C) 2017-2019 Eltan B.V.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
Wim Vervoorn82100472020-01-27 15:47:44 +010016
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020017#include <boot_device.h>
Wim Vervoorn46cc24d2019-11-14 11:45:03 +010018#include <bootmem.h>
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020019#include <cbfs.h>
20#include <vboot_check.h>
21#include <vboot_common.h>
Joel Kitching172ef5f2020-02-14 16:08:45 +080022#include <vb2_internals_please_do_not_use.h>
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020023
24#define RSA_PUBLICKEY_FILE_NAME "vboot_public_key.bin"
25
26#if CONFIG(VENDORCODE_ELTAN_VBOOT_USE_SHA512)
27#define DIGEST_SIZE VB2_SHA512_DIGEST_SIZE
Wim Vervoornac4896f2019-10-30 15:55:21 +010028#define HASH_ALG VB2_HASH_SHA512
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020029#else
30#define DIGEST_SIZE VB2_SHA256_DIGEST_SIZE
Wim Vervoornac4896f2019-10-30 15:55:21 +010031#define HASH_ALG VB2_HASH_SHA256
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020032#endif
33
34int verified_boot_check_manifest(void)
35{
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020036 uint8_t *buffer;
Wim Vervoorn82100472020-01-27 15:47:44 +010037 struct vb2_context *ctx;
38 struct vb2_kernel_preamble *pre;
39 static struct vb2_shared_data *sd;
40 size_t size;
41 uint8_t wb_buffer[2800];
42
43 if (vb2api_init(&wb_buffer, sizeof(wb_buffer), &ctx)) {
44 goto fail;
45 }
46
47 sd = vb2_get_sd(ctx);
Wim Vervoornac4896f2019-10-30 15:55:21 +010048
49 buffer = cbfs_boot_map_with_leak(RSA_PUBLICKEY_FILE_NAME, CBFS_TYPE_RAW, &size);
50 if (!buffer || !size) {
51 printk(BIOS_ERR, "ERROR: Public key not found!\n");
52 goto fail;
53 }
54
55 if ((size != CONFIG_VENDORCODE_ELTAN_VBOOT_KEY_SIZE) ||
Wim Vervoorn82100472020-01-27 15:47:44 +010056 (buffer != (void *)CONFIG_VENDORCODE_ELTAN_VBOOT_KEY_LOCATION)) {
Wim Vervoornac4896f2019-10-30 15:55:21 +010057 printk(BIOS_ERR, "ERROR: Illegal public key!\n");
58 goto fail;
59 }
60
Wim Vervoorn82100472020-01-27 15:47:44 +010061 /*
62 * Check if all items will fit into workbuffer:
63 * vb2_shared data, Public Key, Preamble data
64 */
65 if ((sd->workbuf_used + size + sizeof(struct vb2_kernel_preamble) +
66 ((CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE) + (2048/8))) >
67 sizeof(wb_buffer)) {
68 printk(BIOS_ERR, "ERROR: Work buffer too small\n");
Wim Vervoornac4896f2019-10-30 15:55:21 +010069 goto fail;
70 }
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020071
Wim Vervoorn82100472020-01-27 15:47:44 +010072 /* Add public key */
73 sd->data_key_offset = sd->workbuf_used;
74 sd->data_key_size = size;
75 sd->workbuf_used += sd->data_key_size;
76 memcpy((void *)((void *)sd + (long)sd->data_key_offset), (uint8_t *)buffer, size);
77
78 /* Fill preamble area */
79 sd->preamble_size = sizeof(struct vb2_kernel_preamble);
80 sd->preamble_offset = sd->data_key_offset + sd->data_key_size;
81 sd->workbuf_used += sd->preamble_size;
82 pre = (struct vb2_kernel_preamble *)((void *)sd + (long)sd->preamble_offset);
83
84 pre->flags = VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO;
85
86 /* Fill body_signature (vb2_structure). RSA2048 key is used */
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020087 cbfs_boot_map_with_leak("oemmanifest.bin", CBFS_TYPE_RAW, &size);
Wim Vervoorn82100472020-01-27 15:47:44 +010088 if (size != ((CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE) + (2048/8))) {
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020089 printk(BIOS_ERR, "ERROR: Incorrect manifest size!\n");
90 goto fail;
91 }
Wim Vervoorn82100472020-01-27 15:47:44 +010092 pre->body_signature.data_size = CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS *
93 DIGEST_SIZE;
94 pre->body_signature.sig_offset = sizeof(struct vb2_signature) +
95 pre->body_signature.data_size;
96 pre->body_signature.sig_size = size - pre->body_signature.data_size;
97 sd->workbuf_used += size;
98 memcpy((void *)((void *)&pre->body_signature + (long)sizeof(struct vb2_signature)),
Wim Vervoorn944fdc42019-10-30 16:46:41 +010099 (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC, size);
Wim Vervoornac4896f2019-10-30 15:55:21 +0100100
Wim Vervoorn82100472020-01-27 15:47:44 +0100101
102 if (vb2api_verify_kernel_data(ctx, (void *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC,
103 pre->body_signature.data_size))
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200104 goto fail;
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200105
Wim Vervoornac4896f2019-10-30 15:55:21 +0100106 printk(BIOS_INFO, "%s: Successfully verified hash_table signature.\n", __func__);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200107 return 0;
108
109fail:
Wim Vervoorn82100472020-01-27 15:47:44 +0100110 die("ERROR: HASH table verification failed!\n");
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200111 return -1;
112}
113
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200114/*
115 *
116 * measure_item
117 *
118 * extends the defined pcr using the hash calculated by the verified boot
119 * routines.
120 *
121 * @param[in] pcr PCR to extend
122 * @param[in] *hashData Pointer to the hash data
123 * @param[in] hashDataLen Length of the hash data
124 * @param[in] *event_msg Message to log or display
125 * @param[in] eventType Event type to use when logging
126
127 * @retval TPM_SUCCESS Operation completed successfully.
128 * @retval TPM_E_IOERROR Unexpected device behavior.
129 */
130static int measure_item(uint32_t pcr, uint8_t *hashData, uint32_t hashDataLen,
131 int8_t *event_msg, TCG_EVENTTYPE eventType)
132{
133 int status = TPM_SUCCESS;
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200134 TCG_PCR_EVENT2_HDR tcgEventHdr;
135
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200136 memset(&tcgEventHdr, 0, sizeof(tcgEventHdr));
137 tcgEventHdr.pcrIndex = pcr;
138 tcgEventHdr.eventType = eventType;
139 if (event_msg) {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100140 status = mboot_hash_extend_log(MBOOT_HASH_PROVIDED, hashData,
141 hashDataLen, &tcgEventHdr,
142 (uint8_t *)event_msg);
143 if (status == TPM_SUCCESS)
144 printk(BIOS_INFO, "%s: Success! %s measured to pcr %d.\n", __func__,
145 event_msg, pcr);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200146 }
147 return status;
148}
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200149
Wim Vervoornac4896f2019-10-30 15:55:21 +0100150static void verified_boot_check_buffer(const char *name, void *start, size_t size,
151 uint32_t hash_index, int32_t pcr)
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200152{
153 uint8_t digest[DIGEST_SIZE];
Wim Vervoornac4896f2019-10-30 15:55:21 +0100154 vb2_error_t status;
155
156 printk(BIOS_DEBUG, "%s: %s HASH verification buffer %p size %d\n", __func__, name,
157 start, (int)size);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200158
159 if (start && size) {
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200160
Wim Vervoorn82100472020-01-27 15:47:44 +0100161 status = vb2_digest_buffer((const uint8_t *)start, size, HASH_ALG, digest, DIGEST_SIZE);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200162 if ((CONFIG(VENDORCODE_ELTAN_VBOOT) && memcmp((void *)(
163 (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC +
Wim Vervoornac4896f2019-10-30 15:55:21 +0100164 sizeof(digest) * hash_index), digest, sizeof(digest))) || status) {
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200165 printk(BIOS_DEBUG, "%s: buffer hash\n", __func__);
166 hexdump(digest, sizeof(digest));
167 printk(BIOS_DEBUG, "%s: manifest hash\n", __func__);
Wim Vervoornac4896f2019-10-30 15:55:21 +0100168 hexdump((void *)( (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC +
169 sizeof(digest) * hash_index), sizeof(digest));
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200170 printk(BIOS_EMERG, "%s ", name);
171 die("HASH verification failed!\n");
172 } else {
Kyösti Mälkkibf43f9e2019-11-05 17:55:15 +0200173 if (!ENV_BOOTBLOCK && CONFIG(VENDORCODE_ELTAN_MBOOT)) {
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200174 if (pcr != -1) {
Wim Vervoornffe4eba2019-11-14 11:06:35 +0100175 printk(BIOS_DEBUG, "%s: measuring %s\n", __func__,
176 name);
Wim Vervoornac4896f2019-10-30 15:55:21 +0100177 if (measure_item(pcr, digest, sizeof(digest),
178 (int8_t *)name, 0))
Wim Vervoorn944fdc42019-10-30 16:46:41 +0100179 printk(BIOS_DEBUG, "%s: measuring failed!\n",
180 __func__);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200181 }
182 }
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200183 if (CONFIG(VENDORCODE_ELTAN_VBOOT))
Wim Vervoornac4896f2019-10-30 15:55:21 +0100184 printk(BIOS_DEBUG, "%s HASH verification success\n", name);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200185 }
186 } else {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100187 printk(BIOS_EMERG, "Invalid buffer\n");
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200188 die("HASH verification failed!\n");
189 }
190}
191
Wim Vervoornac4896f2019-10-30 15:55:21 +0100192void verified_boot_check_cbfsfile(const char *name, uint32_t type, uint32_t hash_index,
193 void **buffer, uint32_t *filesize, int32_t pcr)
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200194{
195 void *start;
196 size_t size;
197
Wim Vervoornac4896f2019-10-30 15:55:21 +0100198 start = cbfs_boot_map_with_leak(name, type & ~VERIFIED_BOOT_COPY_BLOCK, &size);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200199 if (start && size) {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100200 /* Speed up processing by copying the file content to memory first */
Wim Vervoorn46cc24d2019-11-14 11:45:03 +0100201 if (!ENV_ROMSTAGE_OR_BEFORE && (type & VERIFIED_BOOT_COPY_BLOCK)) {
202
203 if ((buffer) && (*buffer) && (*filesize >= size) &&
204 ((uint32_t) start > (uint32_t)(~(CONFIG_CBFS_SIZE-1)))) {
205
206 /* Use the buffer passed in if possible */
Wim Vervoornac4896f2019-10-30 15:55:21 +0100207 printk(BIOS_DEBUG, "%s: move buffer to memory\n", __func__);
Wim Vervoorn46cc24d2019-11-14 11:45:03 +0100208 /* Move the file to memory buffer passed in */
209 memcpy(*buffer, start, size);
210 start = *buffer;
211 printk(BIOS_DEBUG, "%s: done\n", __func__);
212
213 } else if (ENV_RAMSTAGE) {
214 /* Try to allocate a buffer from boot_mem */
215 void *local_buffer = bootmem_allocate_buffer(size);
216
217 if (local_buffer) {
218
219 /* Use the allocated buffer */
220 printk(BIOS_DEBUG, "%s: move file to memory\n",
221 __func__);
222 memcpy(local_buffer, start, size);
223 start = local_buffer;
224 printk(BIOS_DEBUG, "%s: done\n", __func__);
225 }
226 }
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200227 }
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200228 verified_boot_check_buffer(name, start, size, hash_index, pcr);
229 } else {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100230 printk(BIOS_EMERG, "CBFS Failed to get file content for %s\n", name);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200231 die("HASH verification failed!\n");
232 }
233 if (buffer)
234 *buffer = start;
235 if (filesize)
236 *filesize = size;
237}
238
239void process_verify_list(const verify_item_t list[])
240{
241 int i = 0;
242
243 while (list[i].type != VERIFY_TERMINATOR) {
244 switch (list[i].type) {
245 case VERIFY_FILE:
Wim Vervoornac4896f2019-10-30 15:55:21 +0100246 verified_boot_check_cbfsfile(list[i].name, list[i].data.file.cbfs_type,
247 list[i].hash_index, NULL, NULL, list[i].pcr);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200248 if (list[i].data.file.related_items) {
249 printk(BIOS_SPEW, "process related items\n");
Wim Vervoornac4896f2019-10-30 15:55:21 +0100250 process_verify_list(
251 (verify_item_t *)list[i].data.file.related_items);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200252 }
253 break;
254 case VERIFY_BLOCK:
255 verified_boot_check_buffer(list[i].name,
Wim Vervoornac4896f2019-10-30 15:55:21 +0100256 (void *)list[i].data.block.start,
257 list[i].data.block.size,
258 list[i].hash_index, list[i].pcr);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200259 break;
260 default:
Wim Vervoornac4896f2019-10-30 15:55:21 +0100261 printk(BIOS_EMERG, "INVALID TYPE IN VERIFY LIST 0x%x\n", list[i].type);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200262 die("HASH verification failed!\n");
263 }
264 i++;
265 }
266}
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200267
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200268/*
269 * BOOTBLOCK
270 */
271
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200272void verified_boot_bootblock_check(void)
273{
274 printk(BIOS_SPEW, "%s: processing bootblock items\n", __func__);
275
276 if (CONFIG(VENDORCODE_ELTAN_VBOOT_SIGNED_MANIFEST)) {
277 printk(BIOS_SPEW, "%s: check the manifest\n", __func__);
278 if (verified_boot_check_manifest() != 0)
279 die("invalid manifest");
280 }
281 printk(BIOS_SPEW, "%s: process bootblock verify list\n", __func__);
282 process_verify_list(bootblock_verify_list);
283}
284
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200285/*
286 * ROMSTAGE
287 */
288
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200289void verified_boot_early_check(void)
290{
291 printk(BIOS_SPEW, "%s: processing early items\n", __func__);
292
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200293 if (CONFIG(VENDORCODE_ELTAN_MBOOT)) {
294 printk(BIOS_DEBUG, "mb_measure returned 0x%x\n",
295 mb_measure(vboot_platform_is_resuming()));
296 }
297
298 printk(BIOS_SPEW, "%s: process early verify list\n", __func__);
299 process_verify_list(romstage_verify_list);
300}
301
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200302/*
303 * RAM STAGE
304 */
305
306static int process_oprom_list(const verify_item_t list[],
307 struct rom_header *rom_header)
308{
309 int i = 0;
310 struct pci_data *rom_data;
311 uint32_t viddevid = 0;
312
313 if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100314 printk(BIOS_ERR, "Incorrect expansion ROM header signature %04x DONT START\n",
315 le32_to_cpu(rom_header->signature));
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200316 return 0;
317 }
318
319 rom_data = (((void *)rom_header) + le32_to_cpu(rom_header->data));
320
321 viddevid |= (rom_data->vendor << 16);
322 viddevid |= rom_data->device;
323
324 while (list[i].type != VERIFY_TERMINATOR) {
325 switch (list[i].type) {
326 case VERIFY_OPROM:
327 if (viddevid == list[i].data.oprom.viddev) {
328 verified_boot_check_buffer(list[i].name,
Wim Vervoornac4896f2019-10-30 15:55:21 +0100329 (void *)rom_header,
330 rom_header->size * 512,
331 list[i].hash_index, list[i].pcr);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200332 if (list[i].data.oprom.related_items) {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100333 printk(BIOS_SPEW, "%s: process related items\n",
334 __func__);
335 process_verify_list(
336 (verify_item_t *)list[i].data.oprom.related_items);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200337 }
Wim Vervoornac4896f2019-10-30 15:55:21 +0100338 printk(BIOS_SPEW, "%s: option rom can be started\n", __func__);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200339 return 1;
340 }
341 break;
342 default:
Wim Vervoornac4896f2019-10-30 15:55:21 +0100343 printk(BIOS_EMERG, "%s: INVALID TYPE IN OPTION ROM LIST 0x%x\n",
344 __func__, list[i].type);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200345 die("HASH verification failed!\n");
346 }
347 i++;
348 }
349 printk(BIOS_ERR, "%s: option rom not in list DONT START\n", __func__);
350 return 0;
351}
352
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200353int verified_boot_should_run_oprom(struct rom_header *rom_header)
354{
355 return process_oprom_list(oprom_verify_list, rom_header);
356}
357
Wim Vervoorne05dc172019-11-14 09:50:59 +0100358int prog_locate_hook(struct prog *prog)
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200359{
Wim Vervoornf4a30472019-11-14 10:03:25 +0100360 if (ENV_BOOTBLOCK)
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200361 verified_boot_bootblock_check();
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200362
363 if (ENV_ROMSTAGE) {
Wim Vervoornf4a30472019-11-14 10:03:25 +0100364 if (prog->type == PROG_REFCODE)
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200365 verified_boot_early_check();
Wim Vervoornf4a30472019-11-14 10:03:25 +0100366
367 if (CONFIG(POSTCAR_STAGE) && prog->type == PROG_POSTCAR)
368 process_verify_list(postcar_verify_list);
369
370 if (!CONFIG(POSTCAR_STAGE) && prog->type == PROG_RAMSTAGE)
371 process_verify_list(ramstage_verify_list);
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200372 }
373
Wim Vervoornf4a30472019-11-14 10:03:25 +0100374 if (ENV_POSTCAR && prog->type == PROG_RAMSTAGE)
375 process_verify_list(ramstage_verify_list);
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200376
Wim Vervoornf4a30472019-11-14 10:03:25 +0100377 if (ENV_RAMSTAGE && prog->type == PROG_PAYLOAD)
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200378 process_verify_list(payload_verify_list);
Wim Vervoornf4a30472019-11-14 10:03:25 +0100379
Wim Vervoorne05dc172019-11-14 09:50:59 +0100380 return 0;
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200381}