diff options
Diffstat (limited to 'src/vendorcode/eltan/security/verified_boot')
3 files changed, 96 insertions, 119 deletions
diff --git a/src/vendorcode/eltan/security/verified_boot/Kconfig b/src/vendorcode/eltan/security/verified_boot/Kconfig index 3177529dc9..d9e989f2b2 100644 --- a/src/vendorcode/eltan/security/verified_boot/Kconfig +++ b/src/vendorcode/eltan/security/verified_boot/Kconfig @@ -55,9 +55,14 @@ config VENDORCODE_ELTAN_VBOOT_KEY_LOCATION depends on VENDORCODE_ELTAN_VBOOT_SIGNED_MANIFEST default 0xFFFFF500 +config VENDORCODE_ELTAN_VBOOT_KEY_FILE + string "Verified boot Key File" + depends on VENDORCODE_ELTAN_VBOOT_SIGNED_MANIFEST + default "3rdparty/eltan/verified_boot/Keys/key.vbpubk2" + config VENDORCODE_ELTAN_VBOOT_KEY_SIZE int - default 554 if VENDORCODE_ELTAN_VBOOT_USE_SHA512 - default 520 + default 610 if VENDORCODE_ELTAN_VBOOT_USE_SHA512 + default 576 endmenu # Verified Boot (verified_boot) diff --git a/src/vendorcode/eltan/security/verified_boot/Makefile.inc b/src/vendorcode/eltan/security/verified_boot/Makefile.inc index 3f6ba904c4..357e520298 100644 --- a/src/vendorcode/eltan/security/verified_boot/Makefile.inc +++ b/src/vendorcode/eltan/security/verified_boot/Makefile.inc @@ -37,12 +37,10 @@ endif # ($(CONFIG_VENDORCODE_ELTAN_VBOOT_SIGNED_MANIFEST),y) ifeq ($(CONFIG_VENDORCODE_ELTAN_VBOOT_SIGNED_MANIFEST),y) cbfs-files-y += vboot_public_key.bin -vboot_public_key.bin-file := $(obj)/vboot_public_key.bin +vboot_public_key.bin-file := $(call strip_quotes, $(CONFIG_VENDORCODE_ELTAN_VBOOT_KEY_FILE)) vboot_public_key.bin-position := $(CONFIG_VENDORCODE_ELTAN_VBOOT_KEY_LOCATION) vboot_public_key.bin-type := raw -$(obj)/vboot_public_key.bin: - dd if=/dev/zero of=$@ bs=$(CONFIG_VENDORCODE_ELTAN_VBOOT_KEY_SIZE) count=1 endif # ($(CONFIG_VENDORCODE_ELTAN_VBOOT_SIGNED_MANIFEST),y) endif # CONFIG_VENDORCODE_ELTAN_VBOOT diff --git a/src/vendorcode/eltan/security/verified_boot/vboot_check.c b/src/vendorcode/eltan/security/verified_boot/vboot_check.c index e2258b9cdd..07c69020c8 100644 --- a/src/vendorcode/eltan/security/verified_boot/vboot_check.c +++ b/src/vendorcode/eltan/security/verified_boot/vboot_check.c @@ -23,65 +23,66 @@ #if CONFIG(VENDORCODE_ELTAN_VBOOT_USE_SHA512) #define DIGEST_SIZE VB2_SHA512_DIGEST_SIZE +#define HASH_ALG VB2_HASH_SHA512 #else #define DIGEST_SIZE VB2_SHA256_DIGEST_SIZE +#define HASH_ALG VB2_HASH_SHA256 #endif int verified_boot_check_manifest(void) { - struct vb2_public_key key; - const struct vb2_workbuf wb; uint8_t *buffer; - uint8_t digest[DIGEST_SIZE]; - uint8_t *signature = NULL; + uint8_t sig_buffer[1024]; /* used to build vb21_signature */ size_t size = 0; - int hash_algorithm; - int status; - - cbfs_boot_map_with_leak("oemmanifest.bin", CBFS_TYPE_RAW, &size); + struct vb2_public_key key; + struct vb2_workbuf wb; + struct vb21_signature *vb2_sig_hdr = (struct vb21_signature *)sig_buffer; + uint8_t wb_buffer[1024]; - if (size != (CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * - DIGEST_SIZE) + 256) { - printk(BIOS_ERR, "ERROR: Incorrect manifest size!\n"); + buffer = cbfs_boot_map_with_leak(RSA_PUBLICKEY_FILE_NAME, CBFS_TYPE_RAW, &size); + if (!buffer || !size) { + printk(BIOS_ERR, "ERROR: Public key not found!\n"); goto fail; } - buffer = cbfs_boot_map_with_leak(RSA_PUBLICKEY_FILE_NAME, - CBFS_TYPE_RAW, &size); - - size = DIGEST_SIZE; - if (!vb2_unpack_key_data(&key, buffer, size)) { - printk(BIOS_ERR, "ERROR: Unable to create RSA Public Key !\n"); + if ((size != CONFIG_VENDORCODE_ELTAN_VBOOT_KEY_SIZE) || + (buffer != (void *)CONFIG_VENDORCODE_ELTAN_VBOOT_KEY_LOCATION)) { + printk(BIOS_ERR, "ERROR: Illegal public key!\n"); goto fail; } - if (CONFIG(VENDORCODE_ELTAN_VBOOT_USE_SHA512)) { - key.hash_alg = VB2_HASH_SHA512; - hash_algorithm = VB2_HASH_SHA512; - } else { - key.sig_alg = VB2_HASH_SHA256; - hash_algorithm = VB2_HASH_SHA256; + if (vb21_unpack_key(&key, buffer, size)) { + printk(BIOS_ERR, "ERROR: Invalid public key!\n"); + goto fail; } - /* Create a big endian digest */ - status = cb_sha_endian(hash_algorithm, - (const uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC, - CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE, - digest, BIG_ENDIAN_ALGORITHM); - if (status) + cbfs_boot_map_with_leak("oemmanifest.bin", CBFS_TYPE_RAW, &size); + if (size != (CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE) + + vb2_rsa_sig_size(VB2_SIG_RSA2048)) { + printk(BIOS_ERR, "ERROR: Incorrect manifest size!\n"); goto fail; + } - signature = (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC + - CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE; - - if (!vb2_rsa_verify_digest(&key, signature, digest, &wb)) { - printk(BIOS_ERR, "ERROR: Signature verification failed for" - "hash table !!\n"); + /* prepare work buffer structure */ + wb.buf = (uint8_t *)&wb_buffer; + wb.size = sizeof(wb_buffer); + + /* Build vb2_sig_hdr buffer */ + vb2_sig_hdr->sig_offset = sizeof(struct vb21_signature) + + (CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE); + vb2_sig_hdr->sig_alg = VB2_SIG_RSA2048; + vb2_sig_hdr->sig_size = vb2_rsa_sig_size(VB2_SIG_RSA2048); + vb2_sig_hdr->hash_alg = HASH_ALG; + vb2_sig_hdr->data_size = CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE; + memcpy(&sig_buffer[sizeof(struct vb21_signature)], (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC, size); + + if (vb21_verify_data(&sig_buffer[sizeof(struct vb21_signature)], vb2_sig_hdr->data_size, + (struct vb21_signature *)&sig_buffer, &key, &wb)) { + printk(BIOS_ERR, "ERROR: Signature verification failed for hash table\n"); goto fail; } - printk(BIOS_DEBUG, "%s: Successfully verified hash_table signature.\n", - __func__); + printk(BIOS_INFO, "%s: Successfully verified hash_table signature.\n", __func__); return 0; fail: @@ -151,39 +152,32 @@ static int measure_item(uint32_t pcr, uint8_t *hashData, uint32_t hashDataLen, int8_t *event_msg, TCG_EVENTTYPE eventType) { int status = TPM_SUCCESS; - EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrs; TCG_PCR_EVENT2_HDR tcgEventHdr; - ActivePcrs = tpm2_get_active_pcrs(); - memset(&tcgEventHdr, 0, sizeof(tcgEventHdr)); tcgEventHdr.pcrIndex = pcr; tcgEventHdr.eventType = eventType; if (event_msg) { - status = mboot_hash_extend_log(ActivePcrs, MBOOT_HASH_PROVIDED, - hashData, hashDataLen, &tcgEventHdr, - (uint8_t *)event_msg, 0); - if (status == TPM_SUCCESS) { - printk(BIOS_DEBUG, "%s: Success! %s measured to pcr" - "%d.\n", __func__, event_msg, pcr); - } else { - printk(BIOS_DEBUG, "%s: Fail! %s can't be measured. " - "ABORTING!!!\n", __func__, event_msg); - return status; - } + status = mboot_hash_extend_log(MBOOT_HASH_PROVIDED, hashData, + hashDataLen, &tcgEventHdr, + (uint8_t *)event_msg); + if (status == TPM_SUCCESS) + printk(BIOS_INFO, "%s: Success! %s measured to pcr %d.\n", __func__, + event_msg, pcr); } return status; } #endif -static void verified_boot_check_buffer(const char *name, void *start, - size_t size, uint32_t hash_index, int32_t pcr) +static void verified_boot_check_buffer(const char *name, void *start, size_t size, + uint32_t hash_index, int32_t pcr) { uint8_t digest[DIGEST_SIZE]; int hash_algorithm; - int status; - printk(BIOS_DEBUG, "%s: %s HASH verification buffer %p size %d\n", - __func__, name, start, (int) size); + vb2_error_t status; + + printk(BIOS_DEBUG, "%s: %s HASH verification buffer %p size %d\n", __func__, name, + start, (int)size); if (start && size) { if (CONFIG(VENDORCODE_ELTAN_VBOOT_USE_SHA512)) @@ -191,66 +185,51 @@ static void verified_boot_check_buffer(const char *name, void *start, else hash_algorithm = VB2_HASH_SHA256; - status = cb_sha_endian(hash_algorithm, (const uint8_t *)start, - size, digest, LITTLE_ENDIAN_ALGORITHM); - + status = cb_sha_endian(hash_algorithm, (const uint8_t *)start, size, digest); if ((CONFIG(VENDORCODE_ELTAN_VBOOT) && memcmp((void *)( (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC + - sizeof(digest) * hash_index), digest, sizeof(digest))) || - status) { + sizeof(digest) * hash_index), digest, sizeof(digest))) || status) { printk(BIOS_DEBUG, "%s: buffer hash\n", __func__); hexdump(digest, sizeof(digest)); printk(BIOS_DEBUG, "%s: manifest hash\n", __func__); - hexdump((void *)( - (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC + - sizeof(digest) * hash_index), sizeof(digest)); + hexdump((void *)( (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC + + sizeof(digest) * hash_index), sizeof(digest)); printk(BIOS_EMERG, "%s ", name); die("HASH verification failed!\n"); } else { #ifndef __BOOTBLOCK__ if (CONFIG(VENDORCODE_ELTAN_MBOOT)) { if (pcr != -1) { - printk(BIOS_DEBUG, "%s: measuring %s\n", - __func__, name); - status = measure_item(pcr, digest, - sizeof(digest), - (int8_t *)name, 0); + printk(BIOS_DEBUG, "%s: measuring %s\n", __func__, name); + if (measure_item(pcr, digest, sizeof(digest), + (int8_t *)name, 0)) + printk(BIOS_DEBUG, "%s: measuring failed!\n", __func__); } } #endif if (CONFIG(VENDORCODE_ELTAN_VBOOT)) - printk(BIOS_DEBUG, "%s HASH verification " - "success\n", name); + printk(BIOS_DEBUG, "%s HASH verification success\n", name); } } else { - printk(BIOS_EMERG, "Invalid buffer "); + printk(BIOS_EMERG, "Invalid buffer\n"); die("HASH verification failed!\n"); } } -void verified_boot_check_cbfsfile(const char *name, uint32_t type, - uint32_t hash_index, void **buffer, uint32_t *filesize, - int32_t pcr) +void verified_boot_check_cbfsfile(const char *name, uint32_t type, uint32_t hash_index, + void **buffer, uint32_t *filesize, int32_t pcr) { void *start; size_t size; - start = cbfs_boot_map_with_leak(name, type & ~VERIFIED_BOOT_COPY_BLOCK, - &size); + start = cbfs_boot_map_with_leak(name, type & ~VERIFIED_BOOT_COPY_BLOCK, &size); if (start && size) { - /* - * Speed up processing by copying the file content to memory - * first - */ + /* Speed up processing by copying the file content to memory first */ #ifndef __PRE_RAM__ - if ((type & VERIFIED_BOOT_COPY_BLOCK) && (buffer) && - (*buffer) && + if ((type & VERIFIED_BOOT_COPY_BLOCK) && (buffer) && (*buffer) && ((uint32_t) start > (uint32_t)(~(CONFIG_CBFS_SIZE-1)))) { - printk(BIOS_DEBUG, "%s: move buffer to " - "memory\n", __func__); - /* Move the file to a memory bufferof which we know it - * doesn't harm - */ + printk(BIOS_DEBUG, "%s: move buffer to memory\n", __func__); + /* Move the file to a memory bufferof which we know it doesn't harm */ memcpy(*buffer, start, size); start = *buffer; printk(BIOS_DEBUG, "%s: done\n", __func__); @@ -258,8 +237,7 @@ void verified_boot_check_cbfsfile(const char *name, uint32_t type, #endif // __PRE_RAM__ verified_boot_check_buffer(name, start, size, hash_index, pcr); } else { - printk(BIOS_EMERG, "CBFS Failed to get file content for %s\n", - name); + printk(BIOS_EMERG, "CBFS Failed to get file content for %s\n", name); die("HASH verification failed!\n"); } if (buffer) @@ -275,25 +253,22 @@ void process_verify_list(const verify_item_t list[]) while (list[i].type != VERIFY_TERMINATOR) { switch (list[i].type) { case VERIFY_FILE: - verified_boot_check_cbfsfile(list[i].name, - list[i].data.file.cbfs_type, - list[i].hash_index, NULL, NULL, - list[i].pcr); + verified_boot_check_cbfsfile(list[i].name, list[i].data.file.cbfs_type, + list[i].hash_index, NULL, NULL, list[i].pcr); if (list[i].data.file.related_items) { printk(BIOS_SPEW, "process related items\n"); - process_verify_list((verify_item_t *) - list[i].data.file.related_items); + process_verify_list( + (verify_item_t *)list[i].data.file.related_items); } break; case VERIFY_BLOCK: verified_boot_check_buffer(list[i].name, - (void *) list[i].data.block.start, - list[i].data.block.size, - list[i].hash_index, list[i].pcr); + (void *)list[i].data.block.start, + list[i].data.block.size, + list[i].hash_index, list[i].pcr); break; default: - printk(BIOS_EMERG, "INVALID TYPE IN VERIFY" - "LIST 0x%x\n", list[i].type); + printk(BIOS_EMERG, "INVALID TYPE IN VERIFY LIST 0x%x\n", list[i].type); die("HASH verification failed!\n"); } i++; @@ -392,9 +367,8 @@ static int process_oprom_list(const verify_item_t list[], uint32_t viddevid = 0; if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) { - printk(BIOS_ERR, "Incorrect expansion ROM header " - "signature %04x DONT START\n", - le32_to_cpu(rom_header->signature)); + printk(BIOS_ERR, "Incorrect expansion ROM header signature %04x DONT START\n", + le32_to_cpu(rom_header->signature)); return 0; } @@ -408,22 +382,22 @@ static int process_oprom_list(const verify_item_t list[], case VERIFY_OPROM: if (viddevid == list[i].data.oprom.viddev) { verified_boot_check_buffer(list[i].name, - (void *) rom_header, - rom_header->size * 512, - list[i].hash_index, list[i].pcr); + (void *)rom_header, + rom_header->size * 512, + list[i].hash_index, list[i].pcr); if (list[i].data.oprom.related_items) { - printk(BIOS_SPEW, "%s: process" - " related items\n", __func__); - process_verify_list((verify_item_t *)list[i].data.oprom.related_items); + printk(BIOS_SPEW, "%s: process related items\n", + __func__); + process_verify_list( + (verify_item_t *)list[i].data.oprom.related_items); } - printk(BIOS_SPEW, "%s: option rom can be" - " started\n", __func__); + printk(BIOS_SPEW, "%s: option rom can be started\n", __func__); return 1; } break; default: - printk(BIOS_EMERG, "%s: INVALID TYPE IN OPTION ROM LIST" - "0x%x\n", __func__, list[i].type); + printk(BIOS_EMERG, "%s: INVALID TYPE IN OPTION ROM LIST 0x%x\n", + __func__, list[i].type); die("HASH verification failed!\n"); } i++; |