tools/manifest_visualizer/manifest_visualizor.c (1,129 lines of code) (raw):
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "crypto/hash.h"
#include "manifest/cfm/cfm_format.h"
#include "manifest/manifest_format.h"
#include "manifest/pcd/pcd.h"
#include "manifest/pcd/pcd_format.h"
#include "manifest/pfm/pfm_format.h"
uint8_t *element_types = NULL;
uint8_t *element_formats = NULL;
int entry_count = 0;
enum {
MANIFEST_TYPE_PFM = 0,
MANIFEST_TYPE_CFM,
MANIFEST_TYPE_PCD,
};
int32_t visualize_pfm_v1 (uint8_t *pfm)
{
struct pfm_allowable_firmware_header *allowable_fw_header =
(struct pfm_allowable_firmware_header*) pfm;
uint8_t *pointer = ((uint8_t*) allowable_fw_header) +
sizeof (struct pfm_allowable_firmware_header);
printf ("pfm_allowable_firmware_header\n");
printf ("{");
printf ("\tlength: %i\n", allowable_fw_header->length);
printf ("\tfw_count: %i\n", allowable_fw_header->fw_count);
printf ("\treserved: %i\n", allowable_fw_header->reserved);
printf ("}\n");
printf ("Allowable Firmware\n");
printf ("[\n");
for (int i = 0; i < allowable_fw_header->fw_count; ++i) {
struct pfm_firmware_header *fw_header = (struct pfm_firmware_header*) pointer;
char *version_id = (char*) malloc (fw_header->version_length + 1);
if (version_id == NULL) {
printf ("Failed to allocate version id buffer.\n");
return -1;
}
strncpy (version_id, (char*) ((uint8_t*) fw_header + sizeof (struct pfm_firmware_header)),
fw_header->version_length);
version_id[fw_header->version_length] = '\0';
int alignment = fw_header->version_length % 4;
alignment = (alignment == 0) ? 0 : (4 - alignment);
pointer = (uint8_t*) fw_header + sizeof (struct pfm_firmware_header) +
fw_header->version_length + alignment;
printf ("\t{\n");
printf ("\t\tpfm_firmware_header\n");
printf ("\t\t{\n");
printf ("\t\t\tlength: %i\n", fw_header->length);
printf ("\t\t\tversion_length: %i\n", fw_header->version_length);
printf ("\t\t\tblank_byte: 0x%02x\n", fw_header->blank_byte);
printf ("\t\t\tversion_addr: 0x%x\n", fw_header->version_addr);
printf ("\t\t\timg_count: %i\n", fw_header->img_count);
printf ("\t\t\trw_count: %i\n", fw_header->rw_count);
printf ("\t\t\treserved: %i\n", fw_header->reserved);
printf ("\t\t}\n");
printf ("\t\tversion_id: %s\n", version_id);
free (version_id);
printf ("\t\tRW Regions\n");
printf ("\t\t[\n");
for (int j = 0; j < fw_header->rw_count; ++j) {
uint32_t start_addr = *((uint32_t*) pointer);
uint32_t end_addr = *((uint32_t*) pointer + 1);
pointer = (uint8_t*) ((uint32_t*) pointer + 2);
printf ("\t\t\t{\n");
printf ("\t\t\t\tpfm_flash_region\n");
printf ("\t\t\t\t{\n");
printf ("\t\t\t\t\tstart_addr: 0x%x\n", start_addr);
printf ("\t\t\t\t\tend_addr: 0x%x\n", end_addr);
printf ("\t\t\t\t}\n");
printf ("\t\t\t}\n");
}
printf ("\t\t]\n");
for (int j = 0; j < fw_header->img_count; ++j) {
struct pfm_image_header *img_header = (struct pfm_image_header*) pointer;
uint8_t *sig = malloc (img_header->sig_length);
if (sig == NULL) {
printf ("Failed to allocate signature buffer.\n");
return -1;
}
memcpy (sig, img_header + 1, img_header->sig_length);
pointer = (uint8_t*) img_header + sizeof (struct pfm_image_header) +
img_header->sig_length;
printf ("\t\tpfm_image_header\n");
printf ("\t\t{\n");
printf ("\t\t\tlength: %i\n", img_header->length);
printf ("\t\t\tflags: %i\n", img_header->flags);
printf ("\t\t\tkey_id: %i\n", img_header->key_id);
printf ("\t\t\tregion_count: %i\n", img_header->region_count);
printf ("\t\t\tsig_length: %i\n", img_header->sig_length);
printf ("\t\t}\n");
printf ("\t\tSignature:");
for (int k = 0; k < img_header->sig_length; ++k) {
if ((k % 32) == 0) {
printf ("\n\t\t\t");
}
printf ("%02x", sig[k]);
}
printf ("\n");
free (sig);
printf ("\t\tRO Regions\n");
printf ("\t\t[\n");
for (int k = 0; k < img_header->region_count; ++k) {
printf ("\t\t\t{\n");
uint32_t start_addr = *((uint32_t*) pointer);
uint32_t end_addr = *((uint32_t*) pointer + 1);
pointer = (uint8_t*) ((uint32_t*) pointer + 2);
printf ("\t\t\t\tpfm_flash_region\n");
printf ("\t\t\t\t{\n");
printf ("\t\t\t\t\tstart_addr: 0x%x\n", start_addr);
printf ("\t\t\t\t\tend_addr: 0x%x\n", end_addr);
printf ("\t\t\t\t}\n");
printf ("\t\t\t}\n");
}
printf ("\t\t]\n");
}
printf ("\t}\n");
}
printf ("]\n");
struct pfm_key_manifest_header *key_manifest_header = (struct pfm_key_manifest_header*) pointer;
pointer = (uint8_t*) pointer + sizeof (struct pfm_key_manifest_header);
printf ("pfm_key_manifest_header\n");
printf ("{\n");
printf ("\tlength: %i\n", key_manifest_header->length);
printf ("\tkey_count: %i\n", key_manifest_header->key_count);
printf ("\treserved: %i\n", key_manifest_header->reserved);
printf ("}\n");
printf ("Keys\n");
printf ("[\n");
for (int i = 0; i < key_manifest_header->key_count; ++i) {
struct pfm_public_key_header *key_header = (struct pfm_public_key_header*) pointer;
printf ("\t{\n");
printf ("\t\tpfm_key_manifest_header\n");
printf ("\t\tlength: %i\n", key_header->length);
printf ("\t\tkey_length: %i\n", key_header->key_length);
printf ("\t\tkey_exponent: 0x%x\n", key_header->key_exponent);
printf ("\t\tid: %i\n", key_header->id);
printf ("\t\treserved[0]: %i\n", key_header->reserved[0]);
printf ("\t\treserved[1]: %i\n", key_header->reserved[1]);
printf ("\t\treserved[2]: %i\n", key_header->reserved[2]);
uint8_t *modulus = (uint8_t*) malloc (key_header->key_length);
if (modulus == NULL) {
printf ("Failed to allocate modulus buffer.\n");
return -1;
}
memcpy (modulus, key_header + 1, key_header->key_length);
pointer = (uint8_t*) key_header + sizeof (struct pfm_public_key_header) +
key_header->key_length;
printf ("\t\tmodulus:");
for (int j = 0; j < key_header->key_length; ++j) {
if ((j % 32) == 0) {
printf ("\n\t\t\t");
}
printf ("%02x", modulus[j]);
}
printf ("\n");
free (modulus);
printf ("\n");
printf ("\t}\n");
}
printf ("]\n");
struct pfm_platform_header *platform_header = (struct pfm_platform_header*) pointer;
pointer = (uint8_t*) pointer + sizeof (struct pfm_platform_header);
printf ("pfm_platform_header\n");
printf ("{\n");
printf ("\tlength: %i\n", platform_header->length);
printf ("\tid_length: %i\n", platform_header->id_length);
printf ("\treserved: %i\n", platform_header->reserved);
printf ("}\n");
char *platform_id = malloc (platform_header->id_length + 1);
if (platform_id == NULL) {
printf ("Failed to allocate platform id buffer.\n");
return -1;
}
memcpy (platform_id, pointer, platform_header->id_length);
platform_id[platform_header->id_length] = '\0';
int alignment = platform_header->id_length % 4;
alignment = (alignment == 0) ? 0 : (4 - alignment);
pointer += platform_header->id_length + alignment;
printf ("platform_id: %s\n", platform_id);
free (platform_id);
return (pointer - pfm);
}
int32_t visualize_toc (uint8_t *start)
{
struct manifest_toc_header *toc_header = (struct manifest_toc_header*) start;
uint8_t *pointer = start + sizeof (struct manifest_toc_header);
int hash_len;
printf ("manifest_toc_header\n");
printf ("{\n");
printf ("\tentry_count: %i\n", toc_header->entry_count);
printf ("\thash_count: %i\n", toc_header->hash_count);
printf ("\thash_type: %i\n", toc_header->hash_type);
printf ("\treserved: %i\n", toc_header->reserved);
entry_count = toc_header->entry_count;
element_types = malloc (sizeof (uint8_t) * entry_count);
element_formats = malloc (sizeof (uint8_t) * entry_count);
switch (toc_header->hash_type) {
case MANIFEST_HASH_SHA256:
hash_len = SHA256_HASH_LENGTH;
break;
case MANIFEST_HASH_SHA384:
hash_len = SHA384_HASH_LENGTH;
break;
case MANIFEST_HASH_SHA512:
hash_len = SHA512_HASH_LENGTH;
break;
default:
printf ("Unsupported hash type selected: %i\n", toc_header->hash_type);
return -1;
}
printf ("\tEntries\n");
printf ("\t[\n");
for (int i = 0; i < toc_header->entry_count; ++i) {
struct manifest_toc_entry *entry = (struct manifest_toc_entry*) pointer;
pointer += sizeof (struct manifest_toc_entry);
element_types[i] = entry->type_id;
element_formats[i] = entry->format;
printf ("\t\tmanifest_toc_entry\n");
printf ("\t\t{\n");
printf ("\t\t\ttype_id: 0x%x\n", entry->type_id);
printf ("\t\t\tparent: 0x%x\n", entry->parent);
printf ("\t\t\tformat: %i\n", entry->format);
printf ("\t\t\thash_id: %i\n", entry->hash_id);
printf ("\t\t\toffset: 0x%x\n", entry->offset);
printf ("\t\t\tlength: 0x%x\n", entry->length);
printf ("\t\t}\n");
}
printf ("\t]\n");
printf ("\tHash\n");
printf ("\t[\n");
for (int i = 0; i < toc_header->hash_count; ++i) {
printf ("\t\tHash %i\n", i);
printf ("\t\t{");
for (int j = 0; j < hash_len; ++j, ++pointer) {
if ((j % 32) == 0) {
printf ("\n\t\t\t");
}
printf ("%02x", *pointer);
}
printf ("\n");
printf ("\t\t}\n");
}
printf ("\t\tTable Hash\n");
printf ("\t\t{");
for (int i = 0; i < hash_len; ++i, ++pointer) {
if ((i % 32) == 0) {
printf ("\n\t\t\t");
}
printf ("%02x", *pointer);
}
printf ("\n");
printf ("\t\t}\n");
printf ("\t]\n");
printf ("}\n");
return (pointer - start);
}
int32_t visualize_pcd_rot_element (uint8_t *start, const char *prefix, int entry, uint8_t format)
{
uint8_t *pointer = start;
struct pcd_rot_element_v2 *rot = (struct pcd_rot_element_v2*) pointer;
pointer += sizeof (struct pcd_rot_element_v1);
printf ("%spcd_rot_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\trot_flags: 0x%x\n", prefix, rot->v1.rot_flags);
printf ("%s\tport_count: %i\n", prefix, rot->v1.port_count);
printf ("%s\tcomponents_count: %i\n", prefix, rot->v1.components_count);
printf ("%s\trot_address: 0x%x\n", prefix, rot->v1.rot_address);
printf ("%s\trot_eid: 0x%x\n", prefix, rot->v1.rot_eid);
printf ("%s\tbridge_address: 0x%x\n", prefix, rot->v1.bridge_address);
printf ("%s\tbridge_eid: 0x%x\n", prefix, rot->v1.bridge_eid);
printf ("%s\treserved: %i\n", prefix, rot->v1.reserved);
if (format == 2) {
pointer += (sizeof (struct pcd_rot_element_v2) - sizeof (struct pcd_rot_element_v1));
printf ("%s\tattestation_success_retry: %i\n", prefix, rot->attestation_success_retry);
printf ("%s\tattestation_fail_retry: %i\n", prefix, rot->attestation_fail_retry);
printf ("%s\tdiscovery_fail_retry: %i\n", prefix, rot->discovery_fail_retry);
printf ("%s\tmctp_ctrl_timeout: %i\n", prefix, rot->mctp_ctrl_timeout);
printf ("%s\tmctp_bridge_get_table_wait: %i\n", prefix, rot->mctp_bridge_get_table_wait);
printf ("%s\tmctp_bridge_additional_timeout: %i\n", prefix,
rot->mctp_bridge_additional_timeout);
printf ("%s\tattestation_rsp_not_ready_max_duration: %i\n", prefix,
rot->attestation_rsp_not_ready_max_duration);
printf ("%s\tattestation_rsp_not_ready_max_retry: %i\n", prefix,
rot->attestation_rsp_not_ready_max_retry);
printf ("%s\treserved2[0]: %i\n", prefix, rot->reserved2[0]);
printf ("%s\treserved2[1]: %i\n", prefix, rot->reserved2[1]);
printf ("%s\treserved2[2]: %i\n", prefix, rot->reserved2[2]);
}
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_pcd_port_element (uint8_t *start, const char *prefix, int entry)
{
uint8_t *pointer = start;
struct pcd_port_element *port = (struct pcd_port_element*) pointer;
pointer += sizeof (struct pcd_port_element);
printf ("%spcd_port_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\tport_id: %i\n", prefix, port->port_id);
printf ("%s\tport_flags: 0x%x\n", prefix, port->port_flags);
printf ("%s\tpolicy: 0x%x\n", prefix, port->policy);
printf ("%s\tpulse_interval: %i\n", prefix, port->pulse_interval);
printf ("%s\tspi_frequency_hz: %i\n", prefix, port->spi_frequency_hz);
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_pcd_power_controller_element (uint8_t *start, const char *prefix, int entry)
{
uint8_t *pointer = start;
struct pcd_power_controller_element *power_controller =
(struct pcd_power_controller_element*) pointer;
pointer += sizeof (struct pcd_power_controller_element);
printf ("%spcd_power_controller_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\tmux_count: %i\n", prefix, power_controller->i2c.mux_count);
printf ("%s\ti2c_flags: 0x%x\n", prefix, power_controller->i2c.i2c_flags);
printf ("%s\tbus: %i\n", prefix, power_controller->i2c.bus);
printf ("%s\taddress: 0x%x\n", prefix, power_controller->i2c.address);
printf ("%s\teid: 0x%x\n", prefix, power_controller->i2c.eid);
printf ("%s\tMuxes\n", prefix);
printf ("%s\t[\n", prefix);
for (int i = 0; i < power_controller->i2c.mux_count; ++i) {
struct pcd_mux *mux = (struct pcd_mux*) pointer;
pointer += sizeof (struct pcd_mux);
printf ("%s\t\tpcd_mux\n", prefix);
printf ("%s\t\t{\n", prefix);
printf ("%s\t\t\tmux_address: 0x%x\n", prefix, mux->mux_address);
printf ("%s\t\t\tmux_channel: %i\n", prefix, mux->mux_channel);
printf ("%s\t\t\treserved: %i\n", prefix, mux->reserved);
printf ("%s\t\t}\n", prefix);
}
printf ("%s\t]\n", prefix);
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_pcd_direct_i2c_component_element (uint8_t *start, const char *prefix, int entry)
{
uint8_t *pointer = start;
struct pcd_component_common *component = (struct pcd_component_common*) pointer;
struct pcd_i2c_interface *interface;
pointer += (sizeof (struct pcd_component_common));
printf ("%spcd_direct_i2c_component_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\tpolicy: 0x%x\n", prefix, component->policy);
printf ("%s\tpower_ctrl_reg: 0x%x\n", prefix, component->power_ctrl_reg);
printf ("%s\tpower_ctrl_mask: 0x%x\n", prefix, component->power_ctrl_mask);
printf ("%s\treserved: %i\n", prefix, component->reserved);
printf ("%s\tcomponent_id: 0x%x\n", prefix, component->component_id);
interface = (struct pcd_i2c_interface*) pointer;
pointer += sizeof (struct pcd_i2c_interface);
printf ("%s\tmux_count: %i\n", prefix, interface->mux_count);
printf ("%s\ti2c_flags: 0x%x\n", prefix, interface->i2c_flags);
printf ("%s\tbus: %i\n", prefix, interface->bus);
printf ("%s\taddress: 0x%x\n", prefix, interface->address);
printf ("%s\teid: 0x%x\n", prefix, interface->eid);
printf ("%s\tMuxes\n", prefix);
printf ("%s\t[\n", prefix);
for (int i = 0; i < interface->mux_count; ++i) {
struct pcd_mux *mux = (struct pcd_mux*) pointer;
pointer += sizeof (struct pcd_mux);
printf ("%s\t\tpcd_mux\n", prefix);
printf ("%s\t\t{\n", prefix);
printf ("%s\t\t\tmux_address: 0x%x\n", prefix, mux->mux_address);
printf ("%s\t\t\tmux_channel: %i\n", prefix, mux->mux_channel);
printf ("%s\t\t\treserved: %i\n", prefix, mux->reserved);
printf ("%s\t\t}\n", prefix);
}
printf ("%s\t]\n", prefix);
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_pcd_mctp_bridge_component_element (uint8_t *start, const char *prefix, int entry)
{
uint8_t *pointer = start;
struct pcd_component_common *component = (struct pcd_component_common*) pointer;
struct pcd_mctp_bridge_component_connection *bridge_connection;
pointer += (sizeof (struct pcd_component_common));
printf ("%spcd_mctp_bridge_component_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\tpolicy: 0x%x\n", prefix, component->policy);
printf ("%s\tpower_ctrl_reg: 0x%x\n", prefix, component->power_ctrl_reg);
printf ("%s\tpower_ctrl_mask: 0x%x\n", prefix, component->power_ctrl_mask);
printf ("%s\treserved: %i\n", prefix, component->reserved);
printf ("%s\tcomponent_id: 0x%x\n", prefix, component->component_id);
bridge_connection = (struct pcd_mctp_bridge_component_connection*) pointer;
pointer += sizeof (struct pcd_mctp_bridge_component_connection);
printf ("%s\tdevice_id: 0x%x\n", prefix, bridge_connection->device_id);
printf ("%s\tvendor_id: 0x%x\n", prefix, bridge_connection->vendor_id);
printf ("%s\tsubsystem_device_id: 0x%x\n", prefix, bridge_connection->subsystem_device_id);
printf ("%s\tsubsystem_vendor_id: 0x%x\n", prefix, bridge_connection->subsystem_vendor_id);
printf ("%s\tcomponents_count: %i\n", prefix, bridge_connection->components_count);
printf ("%s\teid: 0x%x\n", prefix, bridge_connection->eid);
printf ("%s\treserved: %i\n", prefix, bridge_connection->reserved);
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_platform_id (uint8_t *start, const char *prefix, int entry)
{
uint8_t *pointer = start;
struct manifest_platform_id *platform_id = (struct manifest_platform_id*) pointer;
uint8_t *id;
size_t id_len;
pointer += sizeof (struct manifest_platform_id);
printf ("%smanifest_platform_id (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\tid_length: %i\n", prefix, platform_id->id_length);
printf ("%s\treserved1: %i\n", prefix, platform_id->reserved[0]);
printf ("%s\treserved2: %i\n", prefix, platform_id->reserved[1]);
printf ("%s\treserved3: %i\n", prefix, platform_id->reserved[2]);
id = malloc (platform_id->id_length + 1);
if (id == NULL) {
printf ("Failed to allocate platform ID buffer.\n");
return -1;
}
memcpy (id, pointer, platform_id->id_length);
id[platform_id->id_length] = '\0';
printf ("%s\tPlatform ID: %s\n", prefix, id);
free (id);
id_len = ((platform_id->id_length + 3) & ~((size_t) 3));
pointer += id_len;
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_common_element (uint8_t type, uint8_t *pointer, const char *prefix, int entry)
{
switch (type) {
case MANIFEST_PLATFORM_ID:
return visualize_platform_id (pointer, prefix, entry);
default:
printf ("Unsupported element type: 0x%x (Entry %d)\n", type, entry);
return -1;
}
}
int32_t visualize_pfm_flash_device_element (uint8_t *start, const char *prefix, int entry)
{
uint8_t *pointer = start;
struct pfm_flash_device_element *flash_device = (struct pfm_flash_device_element*) pointer;
pointer += sizeof (struct pfm_flash_device_element);
printf ("%spfm_flash_device_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\tblank_byte: 0x%x\n", prefix, flash_device->blank_byte);
printf ("%s\tfw_count: %i\n", prefix, flash_device->fw_count);
printf ("%s\treserved: %i\n", prefix, flash_device->reserved);
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_pfm_fw_element (uint8_t *start, const char *prefix, int entry)
{
uint8_t *pointer = start;
struct pfm_firmware_element *fw = (struct pfm_firmware_element*) pointer;
uint8_t *fw_id;
size_t fw_id_len;
pointer += (sizeof (struct pfm_firmware_element) - MANIFEST_MAX_STRING);
printf ("%spfm_firmware_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\tversion_count: %i\n", prefix, fw->version_count);
printf ("%s\tid_length: %i\n", prefix, fw->id_length);
printf ("%s\tflags: 0x%x\n", prefix, fw->flags);
printf ("%s\treserved: %i\n", prefix, fw->reserved);
fw_id = malloc ((size_t) fw->id_length + 1);
if (fw_id == NULL) {
printf ("Failed to allocate FW ID buffer.\n");
return -1;
}
memcpy (fw_id, pointer, fw->id_length);
fw_id[fw->id_length] = '\0';
printf ("%s\tFW ID: %s\n", prefix, fw_id);
free (fw_id);
fw_id_len = (((size_t) fw->id_length + 3) & ~((size_t) 3));
pointer += fw_id_len;
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_pfm_fw_version_element (uint8_t *start, const char *prefix, int entry)
{
uint8_t *pointer = start;
struct pfm_firmware_version_element *version = (struct pfm_firmware_version_element*) pointer;
uint8_t *version_str;
size_t version_str_len;
pointer += (sizeof (struct pfm_firmware_version_element) - MANIFEST_MAX_STRING);
printf ("%spfm_firmware_version_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\timg_count: %i\n", prefix, version->img_count);
printf ("%s\trw_count: %i\n", prefix, version->rw_count);
printf ("%s\tversion_length: %i\n", prefix, version->version_length);
printf ("%s\treserved: %i\n", prefix, version->reserved);
printf ("%s\tversion_addr: 0x%x\n", prefix, version->version_addr);
version_str = malloc ((size_t) version->version_length + 1);
if (version_str == NULL) {
printf ("Failed to allocate Version buffer.\n");
return -1;
}
memcpy (version_str, pointer, version->version_length);
version_str[version->version_length] = '\0';
printf ("%s\tVersion: %s\n", prefix, version_str);
free (version_str);
version_str_len = (((size_t) version->version_length + 3) & ~((size_t) 3));
pointer += version_str_len;
printf ("%s\tRW Regions\n", prefix);
printf ("%s\t[\n", prefix);
for (int i = 0; i < version->rw_count; ++i) {
struct pfm_fw_version_element_rw_region *rw =
(struct pfm_fw_version_element_rw_region*) pointer;
pointer += (sizeof (struct pfm_fw_version_element_rw_region) -
sizeof (struct pfm_flash_region));
struct pfm_flash_region *region = (struct pfm_flash_region*) pointer;
pointer += sizeof (struct pfm_flash_region);
printf ("%s\t\tpfm_fw_version_element_rw_region\n", prefix);
printf ("%s\t\t{\n", prefix);
printf ("%s\t\t\tflags: 0x%x\n", prefix, rw->flags);
printf ("%s\t\t\treserved_0: %i\n", prefix, rw->reserved[0]);
printf ("%s\t\t\treserved_1: %i\n", prefix, rw->reserved[1]);
printf ("%s\t\t\treserved_2: %i\n", prefix, rw->reserved[2]);
printf ("%s\t\t\tpfm_flash_region\n", prefix);
printf ("%s\t\t\t{\n", prefix);
printf ("%s\t\t\t\tstart_addr: 0x%x\n", prefix, region->start_addr);
printf ("%s\t\t\t\tend_addr: 0x%x\n", prefix, region->end_addr);
printf ("%s\t\t\t}\n", prefix);
printf ("%s\t\t}\n", prefix);
}
printf ("%s\t]\n", prefix);
printf ("%s\tImages\n", prefix);
printf ("%s\t[\n", prefix);
for (int i = 0; i < version->img_count; ++i) {
struct pfm_fw_version_element_image *img = (struct pfm_fw_version_element_image*) pointer;
int hash_len;
pointer += sizeof (struct pfm_fw_version_element_image);
printf ("%s\t\tpfm_fw_version_element_image\n", prefix);
printf ("%s\t\t{\n", prefix);
printf ("%s\t\t\thash_type: %i\n", prefix, img->hash_type);
printf ("%s\t\t\tregion_count: %i\n", prefix, img->region_count);
printf ("%s\t\t\tflags: 0x%x\n", prefix, img->flags);
printf ("%s\t\t\treserved: %i\n", prefix, img->reserved);
switch (img->hash_type) {
case MANIFEST_HASH_SHA256:
hash_len = SHA256_HASH_LENGTH;
break;
case MANIFEST_HASH_SHA384:
hash_len = SHA384_HASH_LENGTH;
break;
case MANIFEST_HASH_SHA512:
hash_len = SHA512_HASH_LENGTH;
break;
default:
printf ("Unsupported hash type selected: %i\n", img->hash_type);
return -1;
}
printf ("%s\t\t\tHash:\n", prefix);
printf ("%s\t\t\t{", prefix);
for (int j = 0; j < hash_len; ++j, ++pointer) {
if ((j % 32) == 0) {
printf ("%s\n\t\t\t\t", prefix);
}
printf ("%02x", *pointer);
}
printf ("\n");
printf ("%s\t\t\t}\n", prefix);
printf ("%s\t\t\tRegions:\n", prefix);
printf ("%s\t\t\t[\n", prefix);
for (int j = 0; j < img->region_count; ++j) {
uint32_t *address = (uint32_t*) pointer;
pointer += sizeof (uint32_t);
printf ("%s\t\t\t\tRegion %i\n", prefix, j);
printf ("%s\t\t\t\t{\n", prefix);
printf ("%s\t\t\t\t\tImage Start Address: 0x%x\n", prefix, *address);
address = (uint32_t*) pointer;
pointer += sizeof (uint32_t);
printf ("%s\t\t\t\t\tImage End Address: 0x%x\n", prefix, *address);
printf ("%s\t\t\t\t}\n", prefix);
}
printf ("\n");
printf ("%s\t\t\t]\n", prefix);
printf ("%s\t\t}\n", prefix);
}
printf ("%s\t]\n", prefix);
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_cfm_component_device (uint8_t *start, const char *prefix, int entry,
uint8_t *measurement_hash_type)
{
uint8_t *pointer = start;
struct cfm_component_device_element *device = (struct cfm_component_device_element*) pointer;
pointer += sizeof (struct cfm_component_device_element);
printf ("%scfm_component_device_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\tcert_slot: %i\n", prefix, device->cert_slot);
printf ("%s\tattestation_protocol: %i\n", prefix, device->attestation_protocol);
printf ("%s\ttranscript_hash_type: %i\n", prefix, device->transcript_hash_type);
printf ("%s\tmeasurement_hash_type: %i\n", prefix, device->measurement_hash_type);
printf ("%s\treserved: %i\n", prefix, device->reserved);
printf ("%s\treserved2: %i\n", prefix, device->reserved2);
printf ("%s\tcomponent_id: %d\n", prefix, device->component_id);
printf ("%s}\n", prefix);
*measurement_hash_type = device->measurement_hash_type;
return (pointer - start);
}
int32_t visualize_cfm_pmr_digest (uint8_t *start, const char *prefix, int entry,
uint8_t measurement_hash_type)
{
uint8_t *pointer = start;
struct cfm_pmr_digest_element *pmr_digest = (struct cfm_pmr_digest_element*) pointer;
int hash_len;
pointer += sizeof (struct cfm_pmr_digest_element);
printf ("%scfm_pmr_digest_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\tpmr_id: %i\n", prefix, pmr_digest->pmr_id);
printf ("%s\tdigest_count: %i\n", prefix, pmr_digest->digest_count);
printf ("%s\treserved: %i\n", prefix, pmr_digest->reserved);
switch (measurement_hash_type) {
case MANIFEST_HASH_SHA256:
hash_len = SHA256_HASH_LENGTH;
break;
case MANIFEST_HASH_SHA384:
hash_len = SHA384_HASH_LENGTH;
break;
case MANIFEST_HASH_SHA512:
hash_len = SHA512_HASH_LENGTH;
break;
default:
printf ("Unsupported measurement hash type: %i\n", measurement_hash_type);
return -1;
}
printf ("%s\tHashes:\n", prefix);
printf ("%s\t[\n", prefix);
for (int i = 0; i < pmr_digest->digest_count; ++i) {
printf ("%s\t\t{", prefix);
for (int j = 0; j < hash_len; ++j, ++pointer) {
if ((j % 32) == 0) {
printf ("%s\n\t\t\t", prefix);
}
printf ("%02x", *pointer);
}
printf ("%s\n\t\t}\n", prefix);
}
printf ("%s\t]\n", prefix);
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_cfm_measurement (uint8_t *start, const char *prefix, int entry,
uint8_t measurement_hash_type)
{
uint8_t *pointer = start;
struct cfm_measurement_element *measurement = (struct cfm_measurement_element*) pointer;
struct cfm_allowable_digest_element *allowable_digest =
(struct cfm_allowable_digest_element*) (pointer + sizeof (struct cfm_measurement_element));
int hash_len;
pointer += sizeof (struct cfm_measurement_element);
printf ("%scfm_measurement_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\tpmr_id: %i\n", prefix, measurement->pmr_id);
printf ("%s\tmeasurement_id: %i\n", prefix, measurement->measurement_id);
printf ("%s\tallowable_digest_count: %i\n", prefix, measurement->allowable_digest_count);
printf ("%s\treserved: %i\n", prefix, measurement->reserved);
switch (measurement_hash_type) {
case MANIFEST_HASH_SHA256:
hash_len = SHA256_HASH_LENGTH;
break;
case MANIFEST_HASH_SHA384:
hash_len = SHA384_HASH_LENGTH;
break;
case MANIFEST_HASH_SHA512:
hash_len = SHA512_HASH_LENGTH;
break;
default:
printf ("Unsupported measurement hash type: %i\n", measurement_hash_type);
return -1;
}
printf ("%s\tHashes:\n", prefix);
printf ("%s\t[\n", prefix);
for (int i = 0; i < measurement->allowable_digest_count; ++i) {
printf ("%s\t\t{\n", prefix);
printf ("%s\t\t\tversion_set: %i\n", prefix, allowable_digest->version_set);
printf ("%s\t\t\tdigest_count: %i\n", prefix, allowable_digest->digest_count);
printf ("%s\t\t\treserved: %i\n", prefix, allowable_digest->reserved);
pointer += sizeof (struct cfm_allowable_digest_element);
for (int j = 0; j < allowable_digest->digest_count; j++) {
printf ("%s\t\t\t{", prefix);
for (int k = 0; k < hash_len; ++k, ++pointer) {
if ((k % 32) == 0) {
printf ("%s\n\t\t\t\t", prefix);
}
printf ("%02x", *pointer);
}
printf ("%s\n\t\t\t}\n", prefix);
}
printf ("%s\n\t\t}\n", prefix);
allowable_digest = (struct cfm_allowable_digest_element*) ((char*) allowable_digest +
sizeof (struct cfm_allowable_digest_element) +
(allowable_digest->digest_count * hash_len));
}
printf ("%s\t]\n", prefix);
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_cfm_measurement_data (uint8_t *start, const char *prefix, int entry)
{
uint8_t *pointer = start;
struct cfm_measurement_data_element *measurement_data =
(struct cfm_measurement_data_element*) pointer;
pointer += sizeof (struct cfm_measurement_data_element);
printf ("%scfm_measurement_data_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\tpmr_id: %i\n", prefix, measurement_data->pmr_id);
printf ("%s\tmeasurement_id: %i\n", prefix, measurement_data->measurement_id);
printf ("%s\treserved: %i\n", prefix, measurement_data->reserved);
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_cfm_allowable_data (uint8_t *start, const char *prefix, int entry)
{
uint8_t *pointer = start;
struct cfm_allowable_data_element *allowable_data =
(struct cfm_allowable_data_element*) pointer;
struct cfm_allowable_data_element_entry *allowable_data_entry;
int entry_len = 0;
pointer += sizeof (struct cfm_allowable_data_element);
printf ("%scfm_allowable_data_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\tcheck: %i\n", prefix, allowable_data->check.check);
printf ("%s\treserved: %i\n", prefix, allowable_data->check.reserved);
printf ("%s\tendianness: %i\n", prefix, allowable_data->check.endianness);
printf ("%s\tnum_data: %i\n", prefix, allowable_data->num_data);
printf ("%s\tbitmask_length: %i\n", prefix, allowable_data->bitmask_length);
if (allowable_data->bitmask_length) {
printf ("%s\tBitmask:\n", prefix);
printf ("%s\t{", prefix);
for (int i = 0; i < allowable_data->bitmask_length; ++i, ++pointer) {
if ((i % 32) == 0) {
printf ("%s\n\t\t", prefix);
}
printf ("%02x", *pointer);
}
pointer += ((((size_t) allowable_data->bitmask_length + 3) &
~((size_t) 3)) - allowable_data->bitmask_length);
printf ("\n\t}\n");
}
printf ("%s\tdata_list:\n", prefix);
printf ("%s\t[\n", prefix);
for (int i = 0; i < allowable_data->num_data; ++i) {
allowable_data_entry = (struct cfm_allowable_data_element_entry*) pointer;
printf ("%s\t\t{\n", prefix);
printf ("%s\t\t\tversion set: %i\n", prefix, allowable_data_entry->version_set);
printf ("%s\t\t\tdata_length: %i\n", prefix, allowable_data_entry->data_length);
pointer += sizeof (struct cfm_allowable_data_element_entry);
entry_len = sizeof (struct cfm_allowable_data_element_entry);
printf ("%s\t\t\tData:\n", prefix);
printf ("%s\t\t\t{", prefix);
for (int j = 0; j < allowable_data_entry->data_length; ++j, ++pointer, ++entry_len) {
if ((j % 32) == 0) {
printf ("%s\n\t\t\t\t", prefix);
}
printf ("%02x", *pointer);
}
pointer += ((((size_t) entry_len + 3) & ~((size_t) 3)) - entry_len);
printf ("\n\t\t\t}\n");
printf ("\n\t\t}\n");
}
printf ("%s\t]\n", prefix);
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_cfm_allowable_manifest (uint8_t *start, const char *prefix)
{
uint8_t *pointer = start;
struct cfm_allowable_manifest *allowable_manifest = (struct cfm_allowable_manifest*) pointer;
uint8_t *platform_id;
size_t platform_id_len;
pointer += (sizeof (struct cfm_allowable_manifest) - MANIFEST_MAX_STRING);
printf ("%scfm_allowable_manifest\n", prefix);
printf ("%s{\n", prefix);
printf ("%s\tplatform_id_len: %i\n", prefix, allowable_manifest->platform_id_len);
platform_id = malloc ((size_t) allowable_manifest->platform_id_len + 1);
if (platform_id == NULL) {
printf ("Failed to allocate platform ID buffer.\n");
return -1;
}
memcpy (platform_id, pointer, allowable_manifest->platform_id_len);
platform_id[allowable_manifest->platform_id_len] = '\0';
printf ("%s\tplatform_id: %s\n", prefix, platform_id);
free (platform_id);
platform_id_len = (((size_t) allowable_manifest->platform_id_len + 3) & ~((size_t) 3));
pointer += platform_id_len;
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_cfm_allowable_pfm (uint8_t *start, const char *prefix, int entry)
{
uint8_t *pointer = start;
struct cfm_allowable_pfm_element *pfm = (struct cfm_allowable_pfm_element*) pointer;
pointer += (sizeof (struct cfm_allowable_pfm_element) - sizeof (struct cfm_allowable_manifest));
printf ("%scfm_allowable_pfm_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\tport_id: %i\n", prefix, pfm->port_id);
pointer += visualize_cfm_allowable_manifest (pointer, "\t");
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_cfm_allowable_cfm (uint8_t *start, const char *prefix, int entry)
{
uint8_t *pointer = start;
struct cfm_allowable_cfm_element *cfm = (struct cfm_allowable_cfm_element*) pointer;
pointer += (sizeof (struct cfm_allowable_cfm_element) - sizeof (struct cfm_allowable_manifest));
printf ("%scfm_allowable_cfm_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\tindex: %i\n", prefix, cfm->index);
pointer += visualize_cfm_allowable_manifest (pointer, "\t");
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_cfm_allowable_pcd (uint8_t *start, const char *prefix, int entry)
{
uint8_t *pointer = start;
struct cfm_allowable_pcd_element *pcd = (struct cfm_allowable_pcd_element*) pointer;
pointer += (sizeof (struct cfm_allowable_pcd_element) - sizeof (struct cfm_allowable_manifest));
printf ("%scfm_allowable_pcd_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\treserved: %i\n", prefix, pcd->reserved);
pointer += visualize_cfm_allowable_manifest (pointer, "\t");
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_cfm_allowable_id (uint8_t *start, const char *prefix, int entry)
{
uint8_t *pointer = start;
uint32_t *id;
struct cfm_allowable_id_element *allowable_id = (struct cfm_allowable_id_element*) pointer;
pointer += sizeof (struct cfm_allowable_id_element);
printf ("%scfm_allowable_id_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\tcheck: %i\n", prefix, allowable_id->check.check);
printf ("%s\treserved: %i\n", prefix, allowable_id->check.reserved);
printf ("%s\tendianness: %i\n", prefix, allowable_id->check.endianness);
printf ("%s\tnum_id: %i\n", prefix, allowable_id->num_id);
printf ("%s\treserved: %i\n", prefix, allowable_id->reserved);
printf ("%s\tIDs:\n", prefix);
printf ("%s\t[\n", prefix);
for (int i = 0; i < allowable_id->num_id; ++i, pointer += sizeof (uint32_t)) {
id = (uint32_t*) pointer;
printf ("\t\t0x%08x\n", *id);
}
printf ("%s\t]\n", prefix);
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_cfm_root_ca_digests (uint8_t *start, const char *prefix, int entry,
uint8_t measurement_hash_type)
{
uint8_t *pointer = start;
struct cfm_root_ca_digests_element *root_ca_digests =
(struct cfm_root_ca_digests_element*) pointer;
int hash_len;
pointer += sizeof (struct cfm_root_ca_digests_element);
printf ("%scfm_root_ca_digests_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\tca_count: %i\n", prefix, root_ca_digests->ca_count);
printf ("%s\treserved[0]: %i\n", prefix, root_ca_digests->reserved[0]);
printf ("%s\treserved[1]: %i\n", prefix, root_ca_digests->reserved[1]);
printf ("%s\treserved[2]: %i\n", prefix, root_ca_digests->reserved[2]);
switch (measurement_hash_type) {
case MANIFEST_HASH_SHA256:
hash_len = SHA256_HASH_LENGTH;
break;
case MANIFEST_HASH_SHA384:
hash_len = SHA384_HASH_LENGTH;
break;
case MANIFEST_HASH_SHA512:
hash_len = SHA512_HASH_LENGTH;
break;
default:
printf ("Unsupported measurement hash type: %i\n", measurement_hash_type);
return -1;
}
printf ("%s\tHashes:\n", prefix);
printf ("%s\t[\n", prefix);
for (int i = 0; i < root_ca_digests->ca_count; ++i) {
printf ("%s\t\t{", prefix);
for (int j = 0; j < hash_len; ++j, ++pointer) {
if ((j % 32) == 0) {
printf ("%s\n\t\t\t", prefix);
}
printf ("%02x", *pointer);
}
printf ("%s\n\t\t}\n", prefix);
}
printf ("%s\t]\n", prefix);
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_cfm_pmr (uint8_t *start, const char *prefix, int entry,
uint8_t measurement_hash_type)
{
uint8_t *pointer = start;
struct cfm_pmr_element *pmr = (struct cfm_pmr_element*) pointer;
int hash_len;
pointer += (sizeof (struct cfm_pmr_element) - SHA512_HASH_LENGTH);
printf ("%scfm_pmr_element (Entry %d)\n", prefix, entry);
printf ("%s{\n", prefix);
printf ("%s\tpmr_id: %i\n", prefix, pmr->pmr_id);
printf ("%s\treserved[0]: %i\n", prefix, pmr->reserved[0]);
printf ("%s\treserved[1]: %i\n", prefix, pmr->reserved[1]);
printf ("%s\treserved[2]: %i\n", prefix, pmr->reserved[2]);
switch (measurement_hash_type) {
case MANIFEST_HASH_SHA256:
hash_len = SHA256_HASH_LENGTH;
break;
case MANIFEST_HASH_SHA384:
hash_len = SHA384_HASH_LENGTH;
break;
case MANIFEST_HASH_SHA512:
hash_len = SHA512_HASH_LENGTH;
break;
default:
printf ("Unsupported measurement hash type: %i\n", measurement_hash_type);
return -1;
}
printf ("%s\tInitial Value:\n", prefix);
printf ("%s\t{", prefix);
for (int j = 0; j < hash_len; ++j, ++pointer) {
if ((j % 32) == 0) {
printf ("%s\n\t\t", prefix);
}
printf ("%02x", *pointer);
}
printf ("%s\n\t}\n", prefix);
printf ("%s}\n", prefix);
return (pointer - start);
}
int32_t visualize_pfm (uint8_t *start)
{
uint8_t *pointer = start;
int32_t offset;
offset = visualize_toc (pointer);
if (offset == -1) {
return offset;
}
pointer += offset;
for (int i = 0; i < entry_count; ++i) {
switch (element_types[i]) {
case PFM_FLASH_DEVICE:
offset = visualize_pfm_flash_device_element (pointer, "", i);
break;
case PFM_FIRMWARE:
offset = visualize_pfm_fw_element (pointer, "", i);
break;
case PFM_FIRMWARE_VERSION:
offset = visualize_pfm_fw_version_element (pointer, "", i);
break;
default:
offset = visualize_common_element (element_types[i], pointer, "", i);
break;
}
if (offset == -1) {
return -1;
}
pointer += offset;
}
return (pointer - start);
}
int32_t visualize_cfm (uint8_t *start)
{
uint8_t *pointer = start;
int32_t offset;
uint8_t measurement_hash_type = SHA256_HASH_LENGTH;
offset = visualize_toc (pointer);
if (offset == -1) {
return offset;
}
pointer += offset;
for (int i = 0; i < entry_count; ++i) {
switch (element_types[i]) {
case CFM_COMPONENT_DEVICE:
offset = visualize_cfm_component_device (pointer, "", i, &measurement_hash_type);
break;
case CFM_PMR_DIGEST:
offset = visualize_cfm_pmr_digest (pointer, "", i, measurement_hash_type);
break;
case CFM_MEASUREMENT:
offset = visualize_cfm_measurement (pointer, "", i, measurement_hash_type);
break;
case CFM_MEASUREMENT_DATA:
offset = visualize_cfm_measurement_data (pointer, "", i);
break;
case CFM_ALLOWABLE_DATA:
offset = visualize_cfm_allowable_data (pointer, "", i);
break;
case CFM_ALLOWABLE_PFM:
offset = visualize_cfm_allowable_pfm (pointer, "", i);
break;
case CFM_ALLOWABLE_CFM:
offset = visualize_cfm_allowable_cfm (pointer, "", i);
break;
case CFM_ALLOWABLE_PCD:
offset = visualize_cfm_allowable_pcd (pointer, "", i);
break;
case CFM_ALLOWABLE_ID:
offset = visualize_cfm_allowable_id (pointer, "", i);
break;
case CFM_ROOT_CA:
offset = visualize_cfm_root_ca_digests (pointer, "", i, measurement_hash_type);
break;
case CFM_PMR:
offset = visualize_cfm_pmr (pointer, "", i, measurement_hash_type);
break;
default:
offset = visualize_common_element (element_types[i], pointer, "", i);
break;
}
if (offset == -1) {
return -1;
}
pointer += offset;
}
return (pointer - start);
}
int32_t visualize_pcd (uint8_t *start)
{
uint8_t *pointer = start;
int32_t offset;
offset = visualize_toc (pointer);
if (offset == -1) {
return offset;
}
pointer += offset;
for (int i = 0; i < entry_count; ++i) {
switch (element_types[i]) {
case PCD_ROT:
offset = visualize_pcd_rot_element (pointer, "", i, element_formats[i]);
break;
case PCD_SPI_FLASH_PORT:
offset = visualize_pcd_port_element (pointer, "", i);
break;
case PCD_POWER_CONTROLLER:
offset = visualize_pcd_power_controller_element (pointer, "", i);
break;
case PCD_COMPONENT_DIRECT:
offset = visualize_pcd_direct_i2c_component_element (pointer, "", i);
break;
case PCD_COMPONENT_MCTP_BRIDGE:
offset = visualize_pcd_mctp_bridge_component_element (pointer, "", i);
break;
default:
offset = visualize_common_element (element_types[i], pointer, "", i);
break;
}
if (offset == -1) {
return -1;
}
pointer += offset;
}
return (pointer - start);
}
int main (int argc, char **argv)
{
FILE *fp;
int32_t offset;
uint8_t *pointer;
uint8_t *manifest;
unsigned long fileLen;
if ((argc < 1) || (argv == NULL)) {
printf ("No manifest file passed in.\n");
return -1;
}
fp = fopen (argv[1], "rb");
if (fp == NULL) {
printf ("Failed to open manifest file.\n");
return -1;
}
fseek (fp, 0, SEEK_END);
fileLen = ftell (fp);
fseek (fp, 0, SEEK_SET);
manifest = (uint8_t*) malloc (fileLen + 1);
if (manifest == NULL) {
printf ("Failed to allocate manifest buffer.\n");
return -1;
}
fread ((void*) manifest, sizeof (uint8_t), fileLen, fp);
fclose (fp);
struct manifest_header *header = (struct manifest_header*) manifest;
printf ("manifest_header\n");
printf ("{");
printf ("\tlength: %i\n", header->length);
printf ("\tmagic: 0x%x\n", header->magic);
printf ("\tid: %i\n", header->id);
printf ("\tsig_length: %i\n", header->sig_length);
printf ("\tsig_type: %i\n", header->sig_type);
printf ("\treserved: %i\n", header->reserved);
printf ("}\n");
switch (header->magic) {
case PFM_MAGIC_NUM:
offset = visualize_pfm_v1 (manifest + sizeof (struct manifest_header));
break;
case PFM_V2_MAGIC_NUM:
offset = visualize_pfm (manifest + sizeof (struct manifest_header));
break;
case CFM_V2_MAGIC_NUM:
offset = visualize_cfm (manifest + sizeof (struct manifest_header));
break;
case PCD_V2_MAGIC_NUM:
offset = visualize_pcd (manifest + sizeof (struct manifest_header));
break;
default:
goto exit;
}
if (offset == -1) {
goto exit;
}
pointer = manifest + offset + sizeof (struct manifest_header);
printf ("Signature:");
for (int k = 0; k < header->sig_length; ++k) {
if ((k % 32) == 0) {
printf ("\n\t");
}
printf ("%02x", pointer[k]);
}
printf ("\n");
exit:
if (manifest != NULL) {
free (manifest);
}
if (element_types != NULL) {
free (element_types);
}
if (element_formats != NULL) {
free (element_formats);
}
}