blob: 09da5c50addfdd1b1d77483d7494ecaf5148672e [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>
Arthur Heymansac522f12021-07-25 10:40:53 +02007#include <fmap_config.h>
Frans Hendriks72b3c3c2019-07-26 07:59:05 +02008#include <vboot_check.h>
9#include <vboot_common.h>
Joel Kitching172ef5f2020-02-14 16:08:45 +080010#include <vb2_internals_please_do_not_use.h>
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020011
12#define RSA_PUBLICKEY_FILE_NAME "vboot_public_key.bin"
13
14#if CONFIG(VENDORCODE_ELTAN_VBOOT_USE_SHA512)
15#define DIGEST_SIZE VB2_SHA512_DIGEST_SIZE
Wim Vervoornac4896f2019-10-30 15:55:21 +010016#define HASH_ALG VB2_HASH_SHA512
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020017#else
18#define DIGEST_SIZE VB2_SHA256_DIGEST_SIZE
Wim Vervoornac4896f2019-10-30 15:55:21 +010019#define HASH_ALG VB2_HASH_SHA256
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020020#endif
21
22int verified_boot_check_manifest(void)
23{
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020024 uint8_t *buffer;
Wim Vervoorn82100472020-01-27 15:47:44 +010025 struct vb2_context *ctx;
26 struct vb2_kernel_preamble *pre;
27 static struct vb2_shared_data *sd;
28 size_t size;
Frans Hendriks70231742020-04-20 13:37:00 +020029 uint8_t wb_buffer[3000];
Wim Vervoorn82100472020-01-27 15:47:44 +010030
31 if (vb2api_init(&wb_buffer, sizeof(wb_buffer), &ctx)) {
32 goto fail;
33 }
34
35 sd = vb2_get_sd(ctx);
Wim Vervoornac4896f2019-10-30 15:55:21 +010036
Julius Werner834b3ec2020-03-04 16:52:08 -080037 buffer = cbfs_map(RSA_PUBLICKEY_FILE_NAME, &size);
Wim Vervoornac4896f2019-10-30 15:55:21 +010038 if (!buffer || !size) {
Julius Wernere9665952022-01-21 17:06:20 -080039 printk(BIOS_ERR, "Public key not found!\n");
Wim Vervoornac4896f2019-10-30 15:55:21 +010040 goto fail;
41 }
42
43 if ((size != CONFIG_VENDORCODE_ELTAN_VBOOT_KEY_SIZE) ||
Wim Vervoorn82100472020-01-27 15:47:44 +010044 (buffer != (void *)CONFIG_VENDORCODE_ELTAN_VBOOT_KEY_LOCATION)) {
Julius Wernere9665952022-01-21 17:06:20 -080045 printk(BIOS_ERR, "Illegal public key!\n");
Wim Vervoornac4896f2019-10-30 15:55:21 +010046 goto fail;
47 }
48
Wim Vervoorn82100472020-01-27 15:47:44 +010049 /*
50 * Check if all items will fit into workbuffer:
51 * vb2_shared data, Public Key, Preamble data
52 */
53 if ((sd->workbuf_used + size + sizeof(struct vb2_kernel_preamble) +
54 ((CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE) + (2048/8))) >
55 sizeof(wb_buffer)) {
Julius Wernere9665952022-01-21 17:06:20 -080056 printk(BIOS_ERR, "Work buffer too small\n");
Wim Vervoornac4896f2019-10-30 15:55:21 +010057 goto fail;
58 }
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020059
Wim Vervoorn82100472020-01-27 15:47:44 +010060 /* Add public key */
61 sd->data_key_offset = sd->workbuf_used;
62 sd->data_key_size = size;
63 sd->workbuf_used += sd->data_key_size;
64 memcpy((void *)((void *)sd + (long)sd->data_key_offset), (uint8_t *)buffer, size);
65
66 /* Fill preamble area */
67 sd->preamble_size = sizeof(struct vb2_kernel_preamble);
68 sd->preamble_offset = sd->data_key_offset + sd->data_key_size;
69 sd->workbuf_used += sd->preamble_size;
70 pre = (struct vb2_kernel_preamble *)((void *)sd + (long)sd->preamble_offset);
71
72 pre->flags = VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO;
73
74 /* Fill body_signature (vb2_structure). RSA2048 key is used */
Julius Werner834b3ec2020-03-04 16:52:08 -080075 cbfs_map("oemmanifest.bin", &size);
Wim Vervoorn82100472020-01-27 15:47:44 +010076 if (size != ((CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE) + (2048/8))) {
Julius Wernere9665952022-01-21 17:06:20 -080077 printk(BIOS_ERR, "Incorrect manifest size!\n");
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020078 goto fail;
79 }
Wim Vervoorn82100472020-01-27 15:47:44 +010080 pre->body_signature.data_size = CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS *
81 DIGEST_SIZE;
82 pre->body_signature.sig_offset = sizeof(struct vb2_signature) +
83 pre->body_signature.data_size;
Frans Hendriks988a2732020-04-20 13:58:07 +020084 pre->body_signature.sig_size = size - pre->body_signature.data_size;
Wim Vervoorn82100472020-01-27 15:47:44 +010085 sd->workbuf_used += size;
86 memcpy((void *)((void *)&pre->body_signature + (long)sizeof(struct vb2_signature)),
Wim Vervoorn944fdc42019-10-30 16:46:41 +010087 (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC, size);
Wim Vervoornac4896f2019-10-30 15:55:21 +010088
Wim Vervoorn82100472020-01-27 15:47:44 +010089
90 if (vb2api_verify_kernel_data(ctx, (void *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC,
91 pre->body_signature.data_size))
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020092 goto fail;
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020093
Wim Vervoornac4896f2019-10-30 15:55:21 +010094 printk(BIOS_INFO, "%s: Successfully verified hash_table signature.\n", __func__);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020095 return 0;
96
97fail:
Wim Vervoorn82100472020-01-27 15:47:44 +010098 die("ERROR: HASH table verification failed!\n");
Frans Hendriks72b3c3c2019-07-26 07:59:05 +020099 return -1;
100}
101
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200102/*
103 *
104 * measure_item
105 *
106 * extends the defined pcr using the hash calculated by the verified boot
107 * routines.
108 *
109 * @param[in] pcr PCR to extend
110 * @param[in] *hashData Pointer to the hash data
111 * @param[in] hashDataLen Length of the hash data
112 * @param[in] *event_msg Message to log or display
113 * @param[in] eventType Event type to use when logging
114
115 * @retval TPM_SUCCESS Operation completed successfully.
116 * @retval TPM_E_IOERROR Unexpected device behavior.
117 */
118static int measure_item(uint32_t pcr, uint8_t *hashData, uint32_t hashDataLen,
119 int8_t *event_msg, TCG_EVENTTYPE eventType)
120{
121 int status = TPM_SUCCESS;
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200122 TCG_PCR_EVENT2_HDR tcgEventHdr;
123
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200124 memset(&tcgEventHdr, 0, sizeof(tcgEventHdr));
125 tcgEventHdr.pcrIndex = pcr;
126 tcgEventHdr.eventType = eventType;
127 if (event_msg) {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100128 status = mboot_hash_extend_log(MBOOT_HASH_PROVIDED, hashData,
129 hashDataLen, &tcgEventHdr,
130 (uint8_t *)event_msg);
131 if (status == TPM_SUCCESS)
132 printk(BIOS_INFO, "%s: Success! %s measured to pcr %d.\n", __func__,
133 event_msg, pcr);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200134 }
135 return status;
136}
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200137
Wim Vervoornac4896f2019-10-30 15:55:21 +0100138static void verified_boot_check_buffer(const char *name, void *start, size_t size,
139 uint32_t hash_index, int32_t pcr)
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200140{
141 uint8_t digest[DIGEST_SIZE];
Wim Vervoornac4896f2019-10-30 15:55:21 +0100142 vb2_error_t status;
143
144 printk(BIOS_DEBUG, "%s: %s HASH verification buffer %p size %d\n", __func__, name,
145 start, (int)size);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200146
147 if (start && size) {
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200148
Frans Hendriks988a2732020-04-20 13:58:07 +0200149 status = vb2_digest_buffer((const uint8_t *)start, size, HASH_ALG, digest,
150 DIGEST_SIZE);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200151 if ((CONFIG(VENDORCODE_ELTAN_VBOOT) && memcmp((void *)(
152 (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC +
Wim Vervoornac4896f2019-10-30 15:55:21 +0100153 sizeof(digest) * hash_index), digest, sizeof(digest))) || status) {
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200154 printk(BIOS_DEBUG, "%s: buffer hash\n", __func__);
155 hexdump(digest, sizeof(digest));
156 printk(BIOS_DEBUG, "%s: manifest hash\n", __func__);
Wim Vervoornac4896f2019-10-30 15:55:21 +0100157 hexdump((void *)( (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC +
158 sizeof(digest) * hash_index), sizeof(digest));
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200159 printk(BIOS_EMERG, "%s ", name);
160 die("HASH verification failed!\n");
161 } else {
Kyösti Mälkkibf43f9e2019-11-05 17:55:15 +0200162 if (!ENV_BOOTBLOCK && CONFIG(VENDORCODE_ELTAN_MBOOT)) {
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200163 if (pcr != -1) {
Wim Vervoornffe4eba2019-11-14 11:06:35 +0100164 printk(BIOS_DEBUG, "%s: measuring %s\n", __func__,
165 name);
Wim Vervoornac4896f2019-10-30 15:55:21 +0100166 if (measure_item(pcr, digest, sizeof(digest),
167 (int8_t *)name, 0))
Wim Vervoorn944fdc42019-10-30 16:46:41 +0100168 printk(BIOS_DEBUG, "%s: measuring failed!\n",
169 __func__);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200170 }
171 }
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200172 if (CONFIG(VENDORCODE_ELTAN_VBOOT))
Wim Vervoornac4896f2019-10-30 15:55:21 +0100173 printk(BIOS_DEBUG, "%s HASH verification success\n", name);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200174 }
175 } else {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100176 printk(BIOS_EMERG, "Invalid buffer\n");
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200177 die("HASH verification failed!\n");
178 }
179}
180
Arthur Heymansac522f12021-07-25 10:40:53 +0200181#if FMAP_SECTION_COREBOOT_START < (0xffffffff - CONFIG_ROM_SIZE + 1)
182#define COREBOOT_CBFS_START (0xffffffff - CONFIG_ROM_SIZE + 1 + FMAP_SECTION_COREBOOT_START)
183#else
184#define COREBOOT_CBFS_START FMAP_SECTION_COREBOOT_START
185#endif
186
Wim Vervoornac4896f2019-10-30 15:55:21 +0100187void verified_boot_check_cbfsfile(const char *name, uint32_t type, uint32_t hash_index,
188 void **buffer, uint32_t *filesize, int32_t pcr)
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200189{
190 void *start;
191 size_t size;
192
Julius Werner834b3ec2020-03-04 16:52:08 -0800193 start = cbfs_map(name, &size);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200194 if (start && size) {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100195 /* Speed up processing by copying the file content to memory first */
Wim Vervoorn46cc24d2019-11-14 11:45:03 +0100196 if (!ENV_ROMSTAGE_OR_BEFORE && (type & VERIFIED_BOOT_COPY_BLOCK)) {
197
198 if ((buffer) && (*buffer) && (*filesize >= size) &&
Arthur Heymansac522f12021-07-25 10:40:53 +0200199 ((uint32_t) start > COREBOOT_CBFS_START)) {
Wim Vervoorn46cc24d2019-11-14 11:45:03 +0100200
201 /* Use the buffer passed in if possible */
Wim Vervoornac4896f2019-10-30 15:55:21 +0100202 printk(BIOS_DEBUG, "%s: move buffer to memory\n", __func__);
Wim Vervoorn46cc24d2019-11-14 11:45:03 +0100203 /* Move the file to memory buffer passed in */
204 memcpy(*buffer, start, size);
205 start = *buffer;
206 printk(BIOS_DEBUG, "%s: done\n", __func__);
207
208 } else if (ENV_RAMSTAGE) {
209 /* Try to allocate a buffer from boot_mem */
210 void *local_buffer = bootmem_allocate_buffer(size);
211
212 if (local_buffer) {
213
214 /* Use the allocated buffer */
215 printk(BIOS_DEBUG, "%s: move file to memory\n",
216 __func__);
217 memcpy(local_buffer, start, size);
218 start = local_buffer;
219 printk(BIOS_DEBUG, "%s: done\n", __func__);
220 }
221 }
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200222 }
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200223 verified_boot_check_buffer(name, start, size, hash_index, pcr);
224 } else {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100225 printk(BIOS_EMERG, "CBFS Failed to get file content for %s\n", name);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200226 die("HASH verification failed!\n");
227 }
228 if (buffer)
229 *buffer = start;
230 if (filesize)
231 *filesize = size;
232}
233
234void process_verify_list(const verify_item_t list[])
235{
236 int i = 0;
237
238 while (list[i].type != VERIFY_TERMINATOR) {
239 switch (list[i].type) {
240 case VERIFY_FILE:
Wim Vervoornac4896f2019-10-30 15:55:21 +0100241 verified_boot_check_cbfsfile(list[i].name, list[i].data.file.cbfs_type,
242 list[i].hash_index, NULL, NULL, list[i].pcr);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200243 if (list[i].data.file.related_items) {
244 printk(BIOS_SPEW, "process related items\n");
Wim Vervoornac4896f2019-10-30 15:55:21 +0100245 process_verify_list(
246 (verify_item_t *)list[i].data.file.related_items);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200247 }
248 break;
249 case VERIFY_BLOCK:
250 verified_boot_check_buffer(list[i].name,
Wim Vervoornac4896f2019-10-30 15:55:21 +0100251 (void *)list[i].data.block.start,
252 list[i].data.block.size,
253 list[i].hash_index, list[i].pcr);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200254 break;
255 default:
Wim Vervoornac4896f2019-10-30 15:55:21 +0100256 printk(BIOS_EMERG, "INVALID TYPE IN VERIFY LIST 0x%x\n", list[i].type);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200257 die("HASH verification failed!\n");
258 }
259 i++;
260 }
261}
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200262
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200263/*
264 * BOOTBLOCK
265 */
266
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200267void verified_boot_bootblock_check(void)
268{
269 printk(BIOS_SPEW, "%s: processing bootblock items\n", __func__);
270
271 if (CONFIG(VENDORCODE_ELTAN_VBOOT_SIGNED_MANIFEST)) {
272 printk(BIOS_SPEW, "%s: check the manifest\n", __func__);
273 if (verified_boot_check_manifest() != 0)
274 die("invalid manifest");
275 }
276 printk(BIOS_SPEW, "%s: process bootblock verify list\n", __func__);
277 process_verify_list(bootblock_verify_list);
278}
279
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200280/*
281 * ROMSTAGE
282 */
283
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200284void verified_boot_early_check(void)
285{
286 printk(BIOS_SPEW, "%s: processing early items\n", __func__);
287
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200288 if (CONFIG(VENDORCODE_ELTAN_MBOOT)) {
289 printk(BIOS_DEBUG, "mb_measure returned 0x%x\n",
Bill XIE516c0a52020-02-24 23:08:35 +0800290 mb_measure(platform_is_resuming()));
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200291 }
292
293 printk(BIOS_SPEW, "%s: process early verify list\n", __func__);
294 process_verify_list(romstage_verify_list);
295}
296
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200297/*
298 * RAM STAGE
299 */
300
301static int process_oprom_list(const verify_item_t list[],
302 struct rom_header *rom_header)
303{
304 int i = 0;
305 struct pci_data *rom_data;
306 uint32_t viddevid = 0;
307
308 if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100309 printk(BIOS_ERR, "Incorrect expansion ROM header signature %04x DONT START\n",
310 le32_to_cpu(rom_header->signature));
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200311 return 0;
312 }
313
314 rom_data = (((void *)rom_header) + le32_to_cpu(rom_header->data));
315
316 viddevid |= (rom_data->vendor << 16);
317 viddevid |= rom_data->device;
318
319 while (list[i].type != VERIFY_TERMINATOR) {
320 switch (list[i].type) {
321 case VERIFY_OPROM:
322 if (viddevid == list[i].data.oprom.viddev) {
323 verified_boot_check_buffer(list[i].name,
Wim Vervoornac4896f2019-10-30 15:55:21 +0100324 (void *)rom_header,
325 rom_header->size * 512,
326 list[i].hash_index, list[i].pcr);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200327 if (list[i].data.oprom.related_items) {
Wim Vervoornac4896f2019-10-30 15:55:21 +0100328 printk(BIOS_SPEW, "%s: process related items\n",
329 __func__);
330 process_verify_list(
331 (verify_item_t *)list[i].data.oprom.related_items);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200332 }
Wim Vervoornac4896f2019-10-30 15:55:21 +0100333 printk(BIOS_SPEW, "%s: option rom can be started\n", __func__);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200334 return 1;
335 }
336 break;
337 default:
Wim Vervoornac4896f2019-10-30 15:55:21 +0100338 printk(BIOS_EMERG, "%s: INVALID TYPE IN OPTION ROM LIST 0x%x\n",
339 __func__, list[i].type);
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200340 die("HASH verification failed!\n");
341 }
342 i++;
343 }
344 printk(BIOS_ERR, "%s: option rom not in list DONT START\n", __func__);
345 return 0;
346}
347
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200348int verified_boot_should_run_oprom(struct rom_header *rom_header)
349{
350 return process_oprom_list(oprom_verify_list, rom_header);
351}
352
Wim Vervoorne05dc172019-11-14 09:50:59 +0100353int prog_locate_hook(struct prog *prog)
Frans Hendriks72b3c3c2019-07-26 07:59:05 +0200354{
Frans Hendriks70dca082020-12-22 14:34:23 +0100355 static int initialized;
356
Wim Vervoornf4a30472019-11-14 10:03:25 +0100357 if (ENV_BOOTBLOCK)
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200358 verified_boot_bootblock_check();
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200359
360 if (ENV_ROMSTAGE) {
Frans Hendriks70dca082020-12-22 14:34:23 +0100361 if (!initialized && ((prog->type == PROG_REFCODE) ||
362 (prog->type == PROG_POSTCAR))) {
Kyösti Mälkkied8eaab2019-11-05 17:12:42 +0200363 verified_boot_early_check();
Frans Hendriks70dca082020-12-22 14:34:23 +0100364 initialized = 1;
365 }
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}