blob: e2258b9cdd3551773e65844d03e4b243233babe0 [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 */
16#include <boot_device.h>
17#include <cbfs.h>
18#include <vboot_check.h>
19#include <vboot_common.h>
20#include "fmap_config.h"
21
22#define RSA_PUBLICKEY_FILE_NAME "vboot_public_key.bin"
23
24#if CONFIG(VENDORCODE_ELTAN_VBOOT_USE_SHA512)
25#define DIGEST_SIZE VB2_SHA512_DIGEST_SIZE
26#else
27#define DIGEST_SIZE VB2_SHA256_DIGEST_SIZE
28#endif
29
30int verified_boot_check_manifest(void)
31{
32 struct vb2_public_key key;
33 const struct vb2_workbuf wb;
34 uint8_t *buffer;
35 uint8_t digest[DIGEST_SIZE];
36 uint8_t *signature = NULL;
37 size_t size = 0;
38 int hash_algorithm;
39 int status;
40
41 cbfs_boot_map_with_leak("oemmanifest.bin", CBFS_TYPE_RAW, &size);
42
43 if (size != (CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS *
44 DIGEST_SIZE) + 256) {
45 printk(BIOS_ERR, "ERROR: Incorrect manifest size!\n");
46 goto fail;
47 }
48
49 buffer = cbfs_boot_map_with_leak(RSA_PUBLICKEY_FILE_NAME,
50 CBFS_TYPE_RAW, &size);
51
52 size = DIGEST_SIZE;
53 if (!vb2_unpack_key_data(&key, buffer, size)) {
54 printk(BIOS_ERR, "ERROR: Unable to create RSA Public Key !\n");
55 goto fail;
56 }
57
58 if (CONFIG(VENDORCODE_ELTAN_VBOOT_USE_SHA512)) {
59 key.hash_alg = VB2_HASH_SHA512;
60 hash_algorithm = VB2_HASH_SHA512;
61 } else {
62 key.sig_alg = VB2_HASH_SHA256;
63 hash_algorithm = VB2_HASH_SHA256;
64 }
65
66 /* Create a big endian digest */
67 status = cb_sha_endian(hash_algorithm,
68 (const uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC,
69 CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE,
70 digest, BIG_ENDIAN_ALGORITHM);
71 if (status)
72 goto fail;
73
74 signature = (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC +
75 CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE;
76
77 if (!vb2_rsa_verify_digest(&key, signature, digest, &wb)) {
78 printk(BIOS_ERR, "ERROR: Signature verification failed for"
79 "hash table !!\n");
80 goto fail;
81 }
82
83 printk(BIOS_DEBUG, "%s: Successfully verified hash_table signature.\n",
84 __func__);
85 return 0;
86
87fail:
88 die("HASH table verification failed!\n");
89 return -1;
90}
91
92static int vendor_secure_locate(struct cbfs_props *props)
93{
94 struct cbfs_header header;
95 const struct region_device *bdev;
96 int32_t rel_offset;
97 size_t offset;
98
99 bdev = boot_device_ro();
100
101 if (bdev == NULL)
102 return -1;
103
104 size_t fmap_top = ___FMAP__COREBOOT_BASE + ___FMAP__COREBOOT_SIZE;
105
106 /* Find location of header using signed 32-bit offset from
107 * end of CBFS region. */
108 offset = fmap_top - sizeof(int32_t);
109 if (rdev_readat(bdev, &rel_offset, offset, sizeof(int32_t)) < 0)
110 return -1;
111
112 offset = fmap_top + rel_offset;
113 if (rdev_readat(bdev, &header, offset, sizeof(header)) < 0)
114 return -1;
115
116 header.magic = ntohl(header.magic);
117 header.romsize = ntohl(header.romsize);
118 header.offset = ntohl(header.offset);
119
120 if (header.magic != CBFS_HEADER_MAGIC)
121 return -1;
122
123 props->offset = header.offset;
124 props->size = header.romsize;
125 props->size -= props->offset;
126
127 printk(BIOS_SPEW, "CBFS @ %zx size %zx\n", props->offset, props->size);
128
129 return 0;
130}
131
132#ifndef __BOOTBLOCK__
133
134/*
135 *
136 * measure_item
137 *
138 * extends the defined pcr using the hash calculated by the verified boot
139 * routines.
140 *
141 * @param[in] pcr PCR to extend
142 * @param[in] *hashData Pointer to the hash data
143 * @param[in] hashDataLen Length of the hash data
144 * @param[in] *event_msg Message to log or display
145 * @param[in] eventType Event type to use when logging
146
147 * @retval TPM_SUCCESS Operation completed successfully.
148 * @retval TPM_E_IOERROR Unexpected device behavior.
149 */
150static int measure_item(uint32_t pcr, uint8_t *hashData, uint32_t hashDataLen,
151 int8_t *event_msg, TCG_EVENTTYPE eventType)
152{
153 int status = TPM_SUCCESS;
154 EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrs;
155 TCG_PCR_EVENT2_HDR tcgEventHdr;
156
157 ActivePcrs = tpm2_get_active_pcrs();
158
159 memset(&tcgEventHdr, 0, sizeof(tcgEventHdr));
160 tcgEventHdr.pcrIndex = pcr;
161 tcgEventHdr.eventType = eventType;
162 if (event_msg) {
163 status = mboot_hash_extend_log(ActivePcrs, MBOOT_HASH_PROVIDED,
164 hashData, hashDataLen, &tcgEventHdr,
165 (uint8_t *)event_msg, 0);
166 if (status == TPM_SUCCESS) {
167 printk(BIOS_DEBUG, "%s: Success! %s measured to pcr"
168 "%d.\n", __func__, event_msg, pcr);
169 } else {
170 printk(BIOS_DEBUG, "%s: Fail! %s can't be measured. "
171 "ABORTING!!!\n", __func__, event_msg);
172 return status;
173 }
174 }
175 return status;
176}
177#endif
178
179static void verified_boot_check_buffer(const char *name, void *start,
180 size_t size, uint32_t hash_index, int32_t pcr)
181{
182 uint8_t digest[DIGEST_SIZE];
183 int hash_algorithm;
184 int status;
185 printk(BIOS_DEBUG, "%s: %s HASH verification buffer %p size %d\n",
186 __func__, name, start, (int) size);
187
188 if (start && size) {
189 if (CONFIG(VENDORCODE_ELTAN_VBOOT_USE_SHA512))
190 hash_algorithm = VB2_HASH_SHA512;
191 else
192 hash_algorithm = VB2_HASH_SHA256;
193
194 status = cb_sha_endian(hash_algorithm, (const uint8_t *)start,
195 size, digest, LITTLE_ENDIAN_ALGORITHM);
196
197 if ((CONFIG(VENDORCODE_ELTAN_VBOOT) && memcmp((void *)(
198 (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC +
199 sizeof(digest) * hash_index), digest, sizeof(digest))) ||
200 status) {
201 printk(BIOS_DEBUG, "%s: buffer hash\n", __func__);
202 hexdump(digest, sizeof(digest));
203 printk(BIOS_DEBUG, "%s: manifest hash\n", __func__);
204 hexdump((void *)(
205 (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC +
206 sizeof(digest) * hash_index), sizeof(digest));
207 printk(BIOS_EMERG, "%s ", name);
208 die("HASH verification failed!\n");
209 } else {
210#ifndef __BOOTBLOCK__
211 if (CONFIG(VENDORCODE_ELTAN_MBOOT)) {
212 if (pcr != -1) {
213 printk(BIOS_DEBUG, "%s: measuring %s\n",
214 __func__, name);
215 status = measure_item(pcr, digest,
216 sizeof(digest),
217 (int8_t *)name, 0);
218 }
219 }
220#endif
221 if (CONFIG(VENDORCODE_ELTAN_VBOOT))
222 printk(BIOS_DEBUG, "%s HASH verification "
223 "success\n", name);
224 }
225 } else {
226 printk(BIOS_EMERG, "Invalid buffer ");
227 die("HASH verification failed!\n");
228 }
229}
230
231void verified_boot_check_cbfsfile(const char *name, uint32_t type,
232 uint32_t hash_index, void **buffer, uint32_t *filesize,
233 int32_t pcr)
234{
235 void *start;
236 size_t size;
237
238 start = cbfs_boot_map_with_leak(name, type & ~VERIFIED_BOOT_COPY_BLOCK,
239 &size);
240 if (start && size) {
241 /*
242 * Speed up processing by copying the file content to memory
243 * first
244 */
245#ifndef __PRE_RAM__
246 if ((type & VERIFIED_BOOT_COPY_BLOCK) && (buffer) &&
247 (*buffer) &&
248 ((uint32_t) start > (uint32_t)(~(CONFIG_CBFS_SIZE-1)))) {
249 printk(BIOS_DEBUG, "%s: move buffer to "
250 "memory\n", __func__);
251 /* Move the file to a memory bufferof which we know it
252 * doesn't harm
253 */
254 memcpy(*buffer, start, size);
255 start = *buffer;
256 printk(BIOS_DEBUG, "%s: done\n", __func__);
257 }
258#endif // __PRE_RAM__
259 verified_boot_check_buffer(name, start, size, hash_index, pcr);
260 } else {
261 printk(BIOS_EMERG, "CBFS Failed to get file content for %s\n",
262 name);
263 die("HASH verification failed!\n");
264 }
265 if (buffer)
266 *buffer = start;
267 if (filesize)
268 *filesize = size;
269}
270
271void process_verify_list(const verify_item_t list[])
272{
273 int i = 0;
274
275 while (list[i].type != VERIFY_TERMINATOR) {
276 switch (list[i].type) {
277 case VERIFY_FILE:
278 verified_boot_check_cbfsfile(list[i].name,
279 list[i].data.file.cbfs_type,
280 list[i].hash_index, NULL, NULL,
281 list[i].pcr);
282 if (list[i].data.file.related_items) {
283 printk(BIOS_SPEW, "process related items\n");
284 process_verify_list((verify_item_t *)
285 list[i].data.file.related_items);
286 }
287 break;
288 case VERIFY_BLOCK:
289 verified_boot_check_buffer(list[i].name,
290 (void *) list[i].data.block.start,
291 list[i].data.block.size,
292 list[i].hash_index, list[i].pcr);
293 break;
294 default:
295 printk(BIOS_EMERG, "INVALID TYPE IN VERIFY"
296 "LIST 0x%x\n", list[i].type);
297 die("HASH verification failed!\n");
298 }
299 i++;
300 }
301}
302#ifdef __BOOTBLOCK__
303/*
304 * BOOTBLOCK
305 */
306
307extern verify_item_t bootblock_verify_list[];
308
309void verified_boot_bootblock_check(void)
310{
311 printk(BIOS_SPEW, "%s: processing bootblock items\n", __func__);
312
313 if (CONFIG(VENDORCODE_ELTAN_VBOOT_SIGNED_MANIFEST)) {
314 printk(BIOS_SPEW, "%s: check the manifest\n", __func__);
315 if (verified_boot_check_manifest() != 0)
316 die("invalid manifest");
317 }
318 printk(BIOS_SPEW, "%s: process bootblock verify list\n", __func__);
319 process_verify_list(bootblock_verify_list);
320}
321
322static void vendor_secure_prepare(void)
323{
324 printk(BIOS_SPEW, "%s: bootblock\n", __func__);
325 verified_boot_bootblock_check();
326}
327#endif //__BOOTBLOCK__
328
329#ifdef __ROMSTAGE__
330/*
331 * ROMSTAGE
332 */
333
334extern verify_item_t romstage_verify_list[];
335
336void verified_boot_early_check(void)
337{
338 printk(BIOS_SPEW, "%s: processing early items\n", __func__);
339
340 if (!CONFIG(C_ENVIRONMENT_BOOTBLOCK) &&
341 CONFIG(VENDORCODE_ELTAN_VBOOT_SIGNED_MANIFEST)) {
342 printk(BIOS_SPEW, "%s: check the manifest\n", __func__);
343 if (verified_boot_check_manifest() != 0)
344 die("invalid manifest");
345 }
346
347 if (CONFIG(VENDORCODE_ELTAN_MBOOT)) {
348 printk(BIOS_DEBUG, "mb_measure returned 0x%x\n",
349 mb_measure(vboot_platform_is_resuming()));
350 }
351
352 printk(BIOS_SPEW, "%s: process early verify list\n", __func__);
353 process_verify_list(romstage_verify_list);
354}
355
356static int prepare_romstage = 0;
357
358static void vendor_secure_prepare(void)
359{
360 printk(BIOS_SPEW, "%s: romstage\n", __func__);
361 if (!prepare_romstage) {
362 verified_boot_early_check();
363 prepare_romstage = 1;
364 }
365}
366#endif //__ROMSTAGE__
367
368#ifdef __POSTCAR__
369/*
370 * POSTCAR
371 */
372
373extern verify_item_t postcar_verify_list[];
374
375static void vendor_secure_prepare(void)
376{
377 printk(BIOS_SPEW, "%s: postcar\n", __func__);
378 process_verify_list(postcar_verify_list);
379}
380#endif //__POSTCAR__
381
382#ifdef __RAMSTAGE__
383/*
384 * RAM STAGE
385 */
386
387static int process_oprom_list(const verify_item_t list[],
388 struct rom_header *rom_header)
389{
390 int i = 0;
391 struct pci_data *rom_data;
392 uint32_t viddevid = 0;
393
394 if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) {
395 printk(BIOS_ERR, "Incorrect expansion ROM header "
396 "signature %04x DONT START\n",
397 le32_to_cpu(rom_header->signature));
398 return 0;
399 }
400
401 rom_data = (((void *)rom_header) + le32_to_cpu(rom_header->data));
402
403 viddevid |= (rom_data->vendor << 16);
404 viddevid |= rom_data->device;
405
406 while (list[i].type != VERIFY_TERMINATOR) {
407 switch (list[i].type) {
408 case VERIFY_OPROM:
409 if (viddevid == list[i].data.oprom.viddev) {
410 verified_boot_check_buffer(list[i].name,
411 (void *) rom_header,
412 rom_header->size * 512,
413 list[i].hash_index, list[i].pcr);
414 if (list[i].data.oprom.related_items) {
415 printk(BIOS_SPEW, "%s: process"
416 " related items\n", __func__);
417 process_verify_list((verify_item_t *)list[i].data.oprom.related_items);
418 }
419 printk(BIOS_SPEW, "%s: option rom can be"
420 " started\n", __func__);
421 return 1;
422 }
423 break;
424 default:
425 printk(BIOS_EMERG, "%s: INVALID TYPE IN OPTION ROM LIST"
426 "0x%x\n", __func__, list[i].type);
427 die("HASH verification failed!\n");
428 }
429 i++;
430 }
431 printk(BIOS_ERR, "%s: option rom not in list DONT START\n", __func__);
432 return 0;
433}
434
435extern verify_item_t payload_verify_list[];
436
437extern verify_item_t oprom_verify_list[];
438
439int verified_boot_should_run_oprom(struct rom_header *rom_header)
440{
441 return process_oprom_list(oprom_verify_list, rom_header);
442}
443
444static void vendor_secure_prepare(void)
445{
446 printk(BIOS_SPEW, "%s: ramstage\n", __func__);
447 process_verify_list(payload_verify_list);
448}
449#endif //__RAMSTAGE__
450
451const struct cbfs_locator cbfs_master_header_locator = {
452 .name = "Vendorcode Header Locator",
453 .prepare = vendor_secure_prepare,
454 .locate = vendor_secure_locate
455};