blob: 63e4608553a8d488fb0f16c5c7c2f43d36d9673e [file] [log] [blame]
Frans Hendriks72b3c3c2019-07-26 07:59:05 +02001/*
2 * This file is part of the coreboot project.
3 *
Frans Hendriks72b3c3c2019-07-26 07:59:05 +02004 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
Wim Vervoorn82100472020-01-27 15:47:44 +010014
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020015#include <boot_device.h>
Wim Vervoorn46cc24d2019-11-14 11:45:03 +010016#include <bootmem.h>
Bill XIE516c0a52020-02-24 23:08:35 +080017#include <bootmode.h>
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020018#include <cbfs.h>
19#include <vboot_check.h>
20#include <vboot_common.h>
Joel Kitching172ef5f2020-02-14 16:08:45 +080021#include <vb2_internals_please_do_not_use.h>
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020022
23#define RSA_PUBLICKEY_FILE_NAME "vboot_public_key.bin"
24
25#if CONFIG(VENDORCODE_ELTAN_VBOOT_USE_SHA512)
26#define DIGEST_SIZE VB2_SHA512_DIGEST_SIZE
Wim Vervoornac4896f2019-10-30 15:55:21 +010027#define HASH_ALG VB2_HASH_SHA512
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020028#else
29#define DIGEST_SIZE VB2_SHA256_DIGEST_SIZE
Wim Vervoornac4896f2019-10-30 15:55:21 +010030#define HASH_ALG VB2_HASH_SHA256
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020031#endif
32
33int verified_boot_check_manifest(void)
34{
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020035 uint8_t *buffer;
Wim Vervoorn82100472020-01-27 15:47:44 +010036 struct vb2_context *ctx;
37 struct vb2_kernel_preamble *pre;
38 static struct vb2_shared_data *sd;
39 size_t size;
40 uint8_t wb_buffer[2800];
41
42 if (vb2api_init(&wb_buffer, sizeof(wb_buffer), &ctx)) {
43 goto fail;
44 }
45
46 sd = vb2_get_sd(ctx);
Wim Vervoornac4896f2019-10-30 15:55:21 +010047
48 buffer = cbfs_boot_map_with_leak(RSA_PUBLICKEY_FILE_NAME, CBFS_TYPE_RAW, &size);
49 if (!buffer || !size) {
50 printk(BIOS_ERR, "ERROR: Public key not found!\n");
51 goto fail;
52 }
53
54 if ((size != CONFIG_VENDORCODE_ELTAN_VBOOT_KEY_SIZE) ||
Wim Vervoorn82100472020-01-27 15:47:44 +010055 (buffer != (void *)CONFIG_VENDORCODE_ELTAN_VBOOT_KEY_LOCATION)) {
Wim Vervoornac4896f2019-10-30 15:55:21 +010056 printk(BIOS_ERR, "ERROR: Illegal public key!\n");
57 goto fail;
58 }
59
Wim Vervoorn82100472020-01-27 15:47:44 +010060 /*
61 * Check if all items will fit into workbuffer:
62 * vb2_shared data, Public Key, Preamble data
63 */
64 if ((sd->workbuf_used + size + sizeof(struct vb2_kernel_preamble) +
65 ((CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE) + (2048/8))) >
66 sizeof(wb_buffer)) {
67 printk(BIOS_ERR, "ERROR: Work buffer too small\n");
Wim Vervoornac4896f2019-10-30 15:55:21 +010068 goto fail;
69 }
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020070
Wim Vervoorn82100472020-01-27 15:47:44 +010071 /* Add public key */
72 sd->data_key_offset = sd->workbuf_used;
73 sd->data_key_size = size;
74 sd->workbuf_used += sd->data_key_size;
75 memcpy((void *)((void *)sd + (long)sd->data_key_offset), (uint8_t *)buffer, size);
76
77 /* Fill preamble area */
78 sd->preamble_size = sizeof(struct vb2_kernel_preamble);
79 sd->preamble_offset = sd->data_key_offset + sd->data_key_size;
80 sd->workbuf_used += sd->preamble_size;
81 pre = (struct vb2_kernel_preamble *)((void *)sd + (long)sd->preamble_offset);
82
83 pre->flags = VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO;
84
85 /* Fill body_signature (vb2_structure). RSA2048 key is used */
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020086 cbfs_boot_map_with_leak("oemmanifest.bin", CBFS_TYPE_RAW, &size);
Wim Vervoorn82100472020-01-27 15:47:44 +010087 if (size != ((CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE) + (2048/8))) {
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020088 printk(BIOS_ERR, "ERROR: Incorrect manifest size!\n");
89 goto fail;
90 }
Wim Vervoorn82100472020-01-27 15:47:44 +010091 pre->body_signature.data_size = CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS *
92 DIGEST_SIZE;
93 pre->body_signature.sig_offset = sizeof(struct vb2_signature) +
94 pre->body_signature.data_size;
95 pre->body_signature.sig_size = size - pre->body_signature.data_size;
96 sd->workbuf_used += size;
97 memcpy((void *)((void *)&pre->body_signature + (long)sizeof(struct vb2_signature)),
Wim Vervoorn944fdc42019-10-30 16:46:41 +010098 (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC, size);
Wim Vervoornac4896f2019-10-30 15:55:21 +010099
Wim Vervoorn82100472020-01-27 15:47:44 +0100100
101 if (vb2api_verify_kernel_data(ctx, (void *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC,
102 pre->body_signature.data_size))
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200103 goto fail;
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200104
Wim Vervoornac4896f2019-10-30 15:55:21 +0100105 printk(BIOS_INFO, "%s: Successfully verified hash_table signature.\n", __func__);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200106 return 0;
107
108fail:
Wim Vervoorn82100472020-01-27 15:47:44 +0100109 die("ERROR: HASH table verification failed!\n");
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200110 return -1;
111}
112
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200113/*
114 *
115 * measure_item
116 *
117 * extends the defined pcr using the hash calculated by the verified boot
118 * routines.
119 *
120 * @param[in] pcr PCR to extend
121 * @param[in] *hashData Pointer to the hash data
122 * @param[in] hashDataLen Length of the hash data
123 * @param[in] *event_msg Message to log or display
124 * @param[in] eventType Event type to use when logging
125
126 * @retval TPM_SUCCESS Operation completed successfully.
127 * @retval TPM_E_IOERROR Unexpected device behavior.
128 */
129static int measure_item(uint32_t pcr, uint8_t *hashData, uint32_t hashDataLen,
130 int8_t *event_msg, TCG_EVENTTYPE eventType)
131{
132 int status = TPM_SUCCESS;
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200133 TCG_PCR_EVENT2_HDR tcgEventHdr;
134
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200135 memset(&tcgEventHdr, 0, sizeof(tcgEventHdr));
136 tcgEventHdr.pcrIndex = pcr;
137 tcgEventHdr.eventType = eventType;
138 if (event_msg) {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100139 status = mboot_hash_extend_log(MBOOT_HASH_PROVIDED, hashData,
140 hashDataLen, &tcgEventHdr,
141 (uint8_t *)event_msg);
142 if (status == TPM_SUCCESS)
143 printk(BIOS_INFO, "%s: Success! %s measured to pcr %d.\n", __func__,
144 event_msg, pcr);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200145 }
146 return status;
147}
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200148
Wim Vervoornac4896f2019-10-30 15:55:21 +0100149static void verified_boot_check_buffer(const char *name, void *start, size_t size,
150 uint32_t hash_index, int32_t pcr)
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200151{
152 uint8_t digest[DIGEST_SIZE];
Wim Vervoornac4896f2019-10-30 15:55:21 +0100153 vb2_error_t status;
154
155 printk(BIOS_DEBUG, "%s: %s HASH verification buffer %p size %d\n", __func__, name,
156 start, (int)size);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200157
158 if (start && size) {
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200159
Wim Vervoorn82100472020-01-27 15:47:44 +0100160 status = vb2_digest_buffer((const uint8_t *)start, size, HASH_ALG, digest, DIGEST_SIZE);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200161 if ((CONFIG(VENDORCODE_ELTAN_VBOOT) && memcmp((void *)(
162 (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC +
Wim Vervoornac4896f2019-10-30 15:55:21 +0100163 sizeof(digest) * hash_index), digest, sizeof(digest))) || status) {
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200164 printk(BIOS_DEBUG, "%s: buffer hash\n", __func__);
165 hexdump(digest, sizeof(digest));
166 printk(BIOS_DEBUG, "%s: manifest hash\n", __func__);
Wim Vervoornac4896f2019-10-30 15:55:21 +0100167 hexdump((void *)( (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC +
168 sizeof(digest) * hash_index), sizeof(digest));
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200169 printk(BIOS_EMERG, "%s ", name);
170 die("HASH verification failed!\n");
171 } else {
Kyösti Mälkkibf43f9e2019-11-05 17:55:15 +0200172 if (!ENV_BOOTBLOCK && CONFIG(VENDORCODE_ELTAN_MBOOT)) {
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200173 if (pcr != -1) {
Wim Vervoornffe4eba2019-11-14 11:06:35 +0100174 printk(BIOS_DEBUG, "%s: measuring %s\n", __func__,
175 name);
Wim Vervoornac4896f2019-10-30 15:55:21 +0100176 if (measure_item(pcr, digest, sizeof(digest),
177 (int8_t *)name, 0))
Wim Vervoorn944fdc42019-10-30 16:46:41 +0100178 printk(BIOS_DEBUG, "%s: measuring failed!\n",
179 __func__);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200180 }
181 }
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200182 if (CONFIG(VENDORCODE_ELTAN_VBOOT))
Wim Vervoornac4896f2019-10-30 15:55:21 +0100183 printk(BIOS_DEBUG, "%s HASH verification success\n", name);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200184 }
185 } else {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100186 printk(BIOS_EMERG, "Invalid buffer\n");
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200187 die("HASH verification failed!\n");
188 }
189}
190
Wim Vervoornac4896f2019-10-30 15:55:21 +0100191void verified_boot_check_cbfsfile(const char *name, uint32_t type, uint32_t hash_index,
192 void **buffer, uint32_t *filesize, int32_t pcr)
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200193{
194 void *start;
195 size_t size;
196
Wim Vervoornac4896f2019-10-30 15:55:21 +0100197 start = cbfs_boot_map_with_leak(name, type & ~VERIFIED_BOOT_COPY_BLOCK, &size);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200198 if (start && size) {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100199 /* Speed up processing by copying the file content to memory first */
Wim Vervoorn46cc24d2019-11-14 11:45:03 +0100200 if (!ENV_ROMSTAGE_OR_BEFORE && (type & VERIFIED_BOOT_COPY_BLOCK)) {
201
202 if ((buffer) && (*buffer) && (*filesize >= size) &&
203 ((uint32_t) start > (uint32_t)(~(CONFIG_CBFS_SIZE-1)))) {
204
205 /* Use the buffer passed in if possible */
Wim Vervoornac4896f2019-10-30 15:55:21 +0100206 printk(BIOS_DEBUG, "%s: move buffer to memory\n", __func__);
Wim Vervoorn46cc24d2019-11-14 11:45:03 +0100207 /* Move the file to memory buffer passed in */
208 memcpy(*buffer, start, size);
209 start = *buffer;
210 printk(BIOS_DEBUG, "%s: done\n", __func__);
211
212 } else if (ENV_RAMSTAGE) {
213 /* Try to allocate a buffer from boot_mem */
214 void *local_buffer = bootmem_allocate_buffer(size);
215
216 if (local_buffer) {
217
218 /* Use the allocated buffer */
219 printk(BIOS_DEBUG, "%s: move file to memory\n",
220 __func__);
221 memcpy(local_buffer, start, size);
222 start = local_buffer;
223 printk(BIOS_DEBUG, "%s: done\n", __func__);
224 }
225 }
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200226 }
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200227 verified_boot_check_buffer(name, start, size, hash_index, pcr);
228 } else {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100229 printk(BIOS_EMERG, "CBFS Failed to get file content for %s\n", name);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200230 die("HASH verification failed!\n");
231 }
232 if (buffer)
233 *buffer = start;
234 if (filesize)
235 *filesize = size;
236}
237
238void process_verify_list(const verify_item_t list[])
239{
240 int i = 0;
241
242 while (list[i].type != VERIFY_TERMINATOR) {
243 switch (list[i].type) {
244 case VERIFY_FILE:
Wim Vervoornac4896f2019-10-30 15:55:21 +0100245 verified_boot_check_cbfsfile(list[i].name, list[i].data.file.cbfs_type,
246 list[i].hash_index, NULL, NULL, list[i].pcr);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200247 if (list[i].data.file.related_items) {
248 printk(BIOS_SPEW, "process related items\n");
Wim Vervoornac4896f2019-10-30 15:55:21 +0100249 process_verify_list(
250 (verify_item_t *)list[i].data.file.related_items);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200251 }
252 break;
253 case VERIFY_BLOCK:
254 verified_boot_check_buffer(list[i].name,
Wim Vervoornac4896f2019-10-30 15:55:21 +0100255 (void *)list[i].data.block.start,
256 list[i].data.block.size,
257 list[i].hash_index, list[i].pcr);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200258 break;
259 default:
Wim Vervoornac4896f2019-10-30 15:55:21 +0100260 printk(BIOS_EMERG, "INVALID TYPE IN VERIFY LIST 0x%x\n", list[i].type);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200261 die("HASH verification failed!\n");
262 }
263 i++;
264 }
265}
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200266
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200267/*
268 * BOOTBLOCK
269 */
270
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200271void verified_boot_bootblock_check(void)
272{
273 printk(BIOS_SPEW, "%s: processing bootblock items\n", __func__);
274
275 if (CONFIG(VENDORCODE_ELTAN_VBOOT_SIGNED_MANIFEST)) {
276 printk(BIOS_SPEW, "%s: check the manifest\n", __func__);
277 if (verified_boot_check_manifest() != 0)
278 die("invalid manifest");
279 }
280 printk(BIOS_SPEW, "%s: process bootblock verify list\n", __func__);
281 process_verify_list(bootblock_verify_list);
282}
283
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200284/*
285 * ROMSTAGE
286 */
287
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200288void verified_boot_early_check(void)
289{
290 printk(BIOS_SPEW, "%s: processing early items\n", __func__);
291
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200292 if (CONFIG(VENDORCODE_ELTAN_MBOOT)) {
293 printk(BIOS_DEBUG, "mb_measure returned 0x%x\n",
Bill XIE516c0a52020-02-24 23:08:35 +0800294 mb_measure(platform_is_resuming()));
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200295 }
296
297 printk(BIOS_SPEW, "%s: process early verify list\n", __func__);
298 process_verify_list(romstage_verify_list);
299}
300
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200301/*
302 * RAM STAGE
303 */
304
305static int process_oprom_list(const verify_item_t list[],
306 struct rom_header *rom_header)
307{
308 int i = 0;
309 struct pci_data *rom_data;
310 uint32_t viddevid = 0;
311
312 if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100313 printk(BIOS_ERR, "Incorrect expansion ROM header signature %04x DONT START\n",
314 le32_to_cpu(rom_header->signature));
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200315 return 0;
316 }
317
318 rom_data = (((void *)rom_header) + le32_to_cpu(rom_header->data));
319
320 viddevid |= (rom_data->vendor << 16);
321 viddevid |= rom_data->device;
322
323 while (list[i].type != VERIFY_TERMINATOR) {
324 switch (list[i].type) {
325 case VERIFY_OPROM:
326 if (viddevid == list[i].data.oprom.viddev) {
327 verified_boot_check_buffer(list[i].name,
Wim Vervoornac4896f2019-10-30 15:55:21 +0100328 (void *)rom_header,
329 rom_header->size * 512,
330 list[i].hash_index, list[i].pcr);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200331 if (list[i].data.oprom.related_items) {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100332 printk(BIOS_SPEW, "%s: process related items\n",
333 __func__);
334 process_verify_list(
335 (verify_item_t *)list[i].data.oprom.related_items);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200336 }
Wim Vervoornac4896f2019-10-30 15:55:21 +0100337 printk(BIOS_SPEW, "%s: option rom can be started\n", __func__);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200338 return 1;
339 }
340 break;
341 default:
Wim Vervoornac4896f2019-10-30 15:55:21 +0100342 printk(BIOS_EMERG, "%s: INVALID TYPE IN OPTION ROM LIST 0x%x\n",
343 __func__, list[i].type);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200344 die("HASH verification failed!\n");
345 }
346 i++;
347 }
348 printk(BIOS_ERR, "%s: option rom not in list DONT START\n", __func__);
349 return 0;
350}
351
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200352int verified_boot_should_run_oprom(struct rom_header *rom_header)
353{
354 return process_oprom_list(oprom_verify_list, rom_header);
355}
356
Wim Vervoorne05dc172019-11-14 09:50:59 +0100357int prog_locate_hook(struct prog *prog)
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200358{
Wim Vervoornf4a30472019-11-14 10:03:25 +0100359 if (ENV_BOOTBLOCK)
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200360 verified_boot_bootblock_check();
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200361
362 if (ENV_ROMSTAGE) {
Wim Vervoornf4a30472019-11-14 10:03:25 +0100363 if (prog->type == PROG_REFCODE)
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200364 verified_boot_early_check();
Wim Vervoornf4a30472019-11-14 10:03:25 +0100365
366 if (CONFIG(POSTCAR_STAGE) && prog->type == PROG_POSTCAR)
367 process_verify_list(postcar_verify_list);
368
369 if (!CONFIG(POSTCAR_STAGE) && prog->type == PROG_RAMSTAGE)
370 process_verify_list(ramstage_verify_list);
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200371 }
372
Wim Vervoornf4a30472019-11-14 10:03:25 +0100373 if (ENV_POSTCAR && prog->type == PROG_RAMSTAGE)
374 process_verify_list(ramstage_verify_list);
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200375
Wim Vervoornf4a30472019-11-14 10:03:25 +0100376 if (ENV_RAMSTAGE && prog->type == PROG_PAYLOAD)
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200377 process_verify_list(payload_verify_list);
Wim Vervoornf4a30472019-11-14 10:03:25 +0100378
Wim Vervoorne05dc172019-11-14 09:50:59 +0100379 return 0;
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200380}