aboutsummaryrefslogtreecommitdiff
path: root/util/cbfstool/cbfs_image.c
diff options
context:
space:
mode:
authorJulius Werner <jwerner@chromium.org>2020-03-13 16:43:34 -0700
committerJulius Werner <jwerner@chromium.org>2020-12-03 00:00:33 +0000
commitd477565dbd6e9b6467f49c84a4f05047ffa22682 (patch)
tree864556875c6b3e15b5cb35193db29af542ae7e8e /util/cbfstool/cbfs_image.c
parent9d0cc2aea918eced42dc3825c1ac94d0d4fbc380 (diff)
cbfstool: Use cbfs_serialized.h and standard vboot helpers
This patch reduces some code duplication in cbfstool by switching it to use the CBFS data structure definitions in commonlib rather than its own private copy. In addition, replace a few custom helpers related to hash algorithms with the official vboot APIs of the same purpose. Signed-off-by: Julius Werner <jwerner@chromium.org> Change-Id: I22eae1bcd76d85fff17749617cfe4f1de55603f4 Reviewed-on: https://review.coreboot.org/c/coreboot/+/41117 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-by: Wim Vervoorn <wvervoorn@eltan.com>
Diffstat (limited to 'util/cbfstool/cbfs_image.c')
-rw-r--r--util/cbfstool/cbfs_image.c128
1 files changed, 53 insertions, 75 deletions
diff --git a/util/cbfstool/cbfs_image.c b/util/cbfstool/cbfs_image.c
index a042f0dac8..793713f336 100644
--- a/util/cbfstool/cbfs_image.c
+++ b/util/cbfstool/cbfs_image.c
@@ -65,16 +65,6 @@ int cbfs_parse_comp_algo(const char *name)
return lookup_type_by_name(types_cbfs_compression, name);
}
-static const char *get_hash_attr_name(uint16_t hash_type)
-{
- return lookup_name_by_type(types_cbfs_hash, hash_type, "(invalid)");
-}
-
-int cbfs_parse_hash_algo(const char *name)
-{
- return lookup_type_by_name(types_cbfs_hash, name);
-}
-
/* CBFS image */
size_t cbfs_calculate_file_header_size(const char *name)
@@ -212,7 +202,7 @@ int cbfs_image_create(struct cbfs_image *image, size_t entries_size)
size_t empty_header_len = cbfs_calculate_file_header_size("");
uint32_t entries_offset = 0;
- uint32_t align = CBFS_ENTRY_ALIGNMENT;
+ uint32_t align = CBFS_ALIGNMENT;
if (image->has_header) {
entries_offset = image->header.offset;
@@ -251,7 +241,7 @@ int cbfs_image_create(struct cbfs_image *image, size_t entries_size)
size_t capacity = entries_size - empty_header_len;
LOG("Created CBFS (capacity = %zu bytes)\n", capacity);
- return cbfs_create_empty_entry(entry_header, CBFS_COMPONENT_NULL,
+ return cbfs_create_empty_entry(entry_header, CBFS_TYPE_NULL,
capacity, "");
}
@@ -387,7 +377,7 @@ int cbfs_copy_instance(struct cbfs_image *image, struct buffer *dst)
size_t copy_end = buffer_size(dst);
- align = CBFS_ENTRY_ALIGNMENT;
+ align = CBFS_ALIGNMENT;
dst_entry = (struct cbfs_file *)buffer_get(dst);
@@ -397,9 +387,9 @@ int cbfs_copy_instance(struct cbfs_image *image, struct buffer *dst)
src_entry = cbfs_find_next_entry(image, src_entry)) {
size_t entry_size;
- if ((src_entry->type == htonl(CBFS_COMPONENT_NULL)) ||
- (src_entry->type == htonl(CBFS_COMPONENT_CBFSHEADER)) ||
- (src_entry->type == htonl(CBFS_COMPONENT_DELETED)))
+ if ((src_entry->type == htonl(CBFS_TYPE_NULL)) ||
+ (src_entry->type == htonl(CBFS_TYPE_CBFSHEADER)) ||
+ (src_entry->type == htonl(CBFS_TYPE_DELETED)))
continue;
entry_size = htonl(src_entry->len) + htonl(src_entry->offset);
@@ -425,7 +415,7 @@ int cbfs_copy_instance(struct cbfs_image *image, struct buffer *dst)
if (last_entry_size < 0)
WARN("No room to create the last entry!\n")
else
- cbfs_create_empty_entry(dst_entry, CBFS_COMPONENT_NULL,
+ cbfs_create_empty_entry(dst_entry, CBFS_TYPE_NULL,
last_entry_size, "");
return 0;
@@ -461,7 +451,7 @@ int cbfs_expand_to_region(struct buffer *region)
cbfs_calculate_file_header_size("") - sizeof(int32_t);
if (last_entry_size > 0) {
- cbfs_create_empty_entry(entry, CBFS_COMPONENT_NULL,
+ cbfs_create_empty_entry(entry, CBFS_TYPE_NULL,
last_entry_size, "");
/* If the last entry was an empty file, merge them. */
cbfs_walk(&image, cbfs_merge_empty_entry, NULL);
@@ -495,8 +485,8 @@ int cbfs_truncate_space(struct buffer *region, uint32_t *size)
* maximum size.
*/
if ((strlen(trailer->filename) != 0) &&
- (trailer->type != htonl(CBFS_COMPONENT_NULL)) &&
- (trailer->type != htonl(CBFS_COMPONENT_DELETED))) {
+ (trailer->type != htonl(CBFS_TYPE_NULL)) &&
+ (trailer->type != htonl(CBFS_TYPE_DELETED))) {
/* nothing to truncate. Return de-facto CBFS size in case it
* was already truncated. */
*size = (uint8_t *)entry - (uint8_t *)buffer_get(region);
@@ -550,8 +540,8 @@ int cbfs_compact_instance(struct cbfs_image *image)
uint32_t type = htonl(cur->type);
/* Current entry is empty. Kepp track of it. */
- if ((type == htonl(CBFS_COMPONENT_NULL)) ||
- (type == htonl(CBFS_COMPONENT_DELETED))) {
+ if ((type == htonl(CBFS_TYPE_NULL)) ||
+ (type == htonl(CBFS_TYPE_DELETED))) {
prev = cur;
continue;
}
@@ -612,7 +602,7 @@ int cbfs_compact_instance(struct cbfs_image *image)
prev_size -= spill_size + empty_metadata_size;
/* Create new empty file. */
- cbfs_create_empty_entry(cur, CBFS_COMPONENT_NULL,
+ cbfs_create_empty_entry(cur, CBFS_TYPE_NULL,
prev_size, "");
/* Merge any potential empty entries together. */
@@ -652,7 +642,7 @@ static int cbfs_add_entry_at(struct cbfs_image *image,
uint32_t min_entry_size = cbfs_calculate_file_header_size("");
uint32_t len, header_offset;
uint32_t align = image->has_header ? image->header.align :
- CBFS_ENTRY_ALIGNMENT;
+ CBFS_ALIGNMENT;
uint32_t header_size = ntohl(header->offset);
header_offset = content_offset - header_size;
@@ -667,7 +657,7 @@ static int cbfs_add_entry_at(struct cbfs_image *image,
if (header_offset - addr > min_entry_size) {
DEBUG("|min|...|header|content|... <create new entry>\n");
len = header_offset - addr - min_entry_size;
- cbfs_create_empty_entry(entry, CBFS_COMPONENT_NULL, len, "");
+ cbfs_create_empty_entry(entry, CBFS_TYPE_NULL, len, "");
if (verbose > 1) cbfs_print_entry_info(image, entry, stderr);
entry = cbfs_find_next_entry(image, entry);
addr = cbfs_get_entry_addr(image, entry);
@@ -726,7 +716,7 @@ static int cbfs_add_entry_at(struct cbfs_image *image,
buffer_size(&image->buffer) - sizeof(int32_t)) {
len -= sizeof(int32_t);
}
- cbfs_create_empty_entry(entry, CBFS_COMPONENT_NULL, len, "");
+ cbfs_create_empty_entry(entry, CBFS_TYPE_NULL, len, "");
if (verbose > 1) cbfs_print_entry_info(image, entry, stderr);
return 0;
}
@@ -762,7 +752,7 @@ int cbfs_add_entry(struct cbfs_image *image, struct buffer *buffer,
entry = cbfs_find_next_entry(image, entry)) {
entry_type = ntohl(entry->type);
- if (entry_type != CBFS_COMPONENT_NULL)
+ if (entry_type != CBFS_TYPE_NULL)
continue;
addr = cbfs_get_entry_addr(image, entry);
@@ -1337,10 +1327,10 @@ int cbfs_export_entry(struct cbfs_image *image, const char *entry_name,
if (do_processing) {
int (*make_elf)(struct buffer *, uint32_t) = NULL;
switch (ntohl(entry->type)) {
- case CBFS_COMPONENT_STAGE:
+ case CBFS_TYPE_STAGE:
make_elf = cbfs_stage_make_elf;
break;
- case CBFS_COMPONENT_SELF:
+ case CBFS_TYPE_SELF:
make_elf = cbfs_payload_make_elf;
break;
}
@@ -1374,7 +1364,7 @@ int cbfs_remove_entry(struct cbfs_image *image, const char *name)
}
DEBUG("cbfs_remove_entry: Removed %s @ 0x%x\n",
entry->filename, cbfs_get_entry_addr(image, entry));
- entry->type = htonl(CBFS_COMPONENT_DELETED);
+ entry->type = htonl(CBFS_TYPE_DELETED);
cbfs_walk(image, cbfs_merge_empty_entry, NULL);
return 0;
}
@@ -1498,28 +1488,21 @@ int cbfs_print_entry_info(struct cbfs_image *image, struct cbfs_file *entry,
decompressed_size
);
- struct cbfs_file_attr_hash *hash = NULL;
- while ((hash = cbfs_file_get_next_hash(entry, hash)) != NULL) {
- unsigned int hash_type = ntohl(hash->hash_type);
- if (hash_type >= CBFS_NUM_SUPPORTED_HASHES) {
- fprintf(fp, "invalid hash type %d\n", hash_type);
+ struct cbfs_file_attr_hash *attr = NULL;
+ while ((attr = cbfs_file_get_next_hash(entry, attr)) != NULL) {
+ size_t hash_len = vb2_digest_size(attr->hash.algo);
+ if (!hash_len) {
+ fprintf(fp, "invalid/unsupported hash algorithm: %d\n",
+ attr->hash.algo);
break;
}
- size_t hash_len = widths_cbfs_hash[hash_type];
- char *hash_str = bintohex(hash->hash_data, hash_len);
- uint8_t local_hash[hash_len];
- if (vb2_digest_buffer(CBFS_SUBHEADER(entry),
- ntohl(entry->len), hash_type, local_hash,
- hash_len) != VB2_SUCCESS) {
- fprintf(fp, "failed to hash '%s'\n", name);
- free(hash_str);
- break;
- }
- int valid = memcmp(local_hash, hash->hash_data, hash_len) == 0;
+ char *hash_str = bintohex(attr->hash.raw, hash_len);
+ int valid = vb2_hash_verify(CBFS_SUBHEADER(entry),
+ ntohl(entry->len), &attr->hash) == VB2_SUCCESS;
const char *valid_str = valid ? "valid" : "invalid";
fprintf(fp, " hash %s:%s %s\n",
- get_hash_attr_name(hash_type),
+ vb2_get_hash_algorithm_name(attr->hash.algo),
hash_str, valid_str);
free(hash_str);
}
@@ -1534,12 +1517,12 @@ int cbfs_print_entry_info(struct cbfs_image *image, struct cbfs_file *entry,
/* note the components of the subheader may be in host order ... */
switch (ntohl(entry->type)) {
- case CBFS_COMPONENT_STAGE:
+ case CBFS_TYPE_STAGE:
cbfs_print_stage_info((struct cbfs_stage *)
CBFS_SUBHEADER(entry), fp);
break;
- case CBFS_COMPONENT_SELF:
+ case CBFS_TYPE_SELF:
payload = (struct cbfs_payload_segment *)
CBFS_SUBHEADER(entry);
while (payload) {
@@ -1635,8 +1618,8 @@ int cbfs_merge_empty_entry(struct cbfs_image *image, struct cbfs_file *entry,
/* Loop until non-empty entry is found, starting from the current entry.
After the loop, next_addr points to the next non-empty entry. */
next = entry;
- while (ntohl(next->type) == CBFS_COMPONENT_DELETED ||
- ntohl(next->type) == CBFS_COMPONENT_NULL) {
+ while (ntohl(next->type) == CBFS_TYPE_DELETED ||
+ ntohl(next->type) == CBFS_TYPE_NULL) {
next = cbfs_find_next_entry(image, next);
if (!next)
break;
@@ -1657,7 +1640,7 @@ int cbfs_merge_empty_entry(struct cbfs_image *image, struct cbfs_file *entry,
uint32_t addr = cbfs_get_entry_addr(image, entry);
size_t len = next_addr - addr - cbfs_calculate_file_header_size("");
DEBUG("join_empty_entry: [0x%x, 0x%x) len=%zu\n", addr, next_addr, len);
- cbfs_create_empty_entry(entry, CBFS_COMPONENT_NULL, len, "");
+ cbfs_create_empty_entry(entry, CBFS_TYPE_NULL, len, "");
return 0;
}
@@ -1751,8 +1734,7 @@ struct cbfs_file *cbfs_find_next_entry(struct cbfs_image *image,
struct cbfs_file *entry)
{
uint32_t addr = cbfs_get_entry_addr(image, entry);
- int align = image->has_header ? image->header.align :
- CBFS_ENTRY_ALIGNMENT;
+ int align = image->has_header ? image->header.align : CBFS_ALIGNMENT;
assert(entry && cbfs_is_valid_entry(image, entry));
addr += ntohl(entry->offset) + ntohl(entry->len);
addr = align_up(addr, align);
@@ -1793,8 +1775,8 @@ int cbfs_is_valid_entry(struct cbfs_image *image, struct cbfs_file *entry)
struct cbfs_file *cbfs_create_file_header(int type,
size_t len, const char *name)
{
- struct cbfs_file *entry = malloc(MAX_CBFS_FILE_HEADER_BUFFER);
- memset(entry, CBFS_CONTENT_DEFAULT_VALUE, MAX_CBFS_FILE_HEADER_BUFFER);
+ struct cbfs_file *entry = malloc(CBFS_METADATA_MAX_SIZE);
+ memset(entry, CBFS_CONTENT_DEFAULT_VALUE, CBFS_METADATA_MAX_SIZE);
memcpy(entry->magic, CBFS_FILE_MAGIC, sizeof(entry->magic));
entry->type = htonl(type);
entry->len = htonl(len);
@@ -1867,7 +1849,7 @@ struct cbfs_file_attribute *cbfs_add_file_attr(struct cbfs_file *header,
next = cbfs_file_next_attr(header, attr);
} while (next != NULL);
uint32_t header_size = ntohl(header->offset) + size;
- if (header_size > MAX_CBFS_FILE_HEADER_BUFFER) {
+ if (header_size > CBFS_METADATA_MAX_SIZE) {
DEBUG("exceeding allocated space for cbfs_file headers");
return NULL;
}
@@ -1889,35 +1871,31 @@ struct cbfs_file_attribute *cbfs_add_file_attr(struct cbfs_file *header,
ntohl(attr->len));
}
header->offset = htonl(header_size);
- memset(attr, CBFS_CONTENT_DEFAULT_VALUE, size);
+ /* Attributes are expected to be small (much smaller than a flash page)
+ and not really meant to be overwritten in-place. To avoid surprising
+ values in reserved fields of attribute structures, initialize them to
+ 0, not 0xff. */
+ memset(attr, 0, size);
attr->tag = htonl(tag);
attr->len = htonl(size);
return attr;
}
int cbfs_add_file_hash(struct cbfs_file *header, struct buffer *buffer,
- enum vb2_hash_algorithm hash_type)
+ enum vb2_hash_algorithm alg)
{
- uint32_t hash_index = hash_type;
-
- if (hash_index >= CBFS_NUM_SUPPORTED_HASHES)
+ if (!vb2_digest_size(alg))
return -1;
- unsigned hash_size = widths_cbfs_hash[hash_type];
- if (hash_size == 0)
- return -1;
-
- struct cbfs_file_attr_hash *attrs =
+ struct cbfs_file_attr_hash *attr =
(struct cbfs_file_attr_hash *)cbfs_add_file_attr(header,
- CBFS_FILE_ATTR_TAG_HASH,
- sizeof(struct cbfs_file_attr_hash) + hash_size);
+ CBFS_FILE_ATTR_TAG_HASH, cbfs_file_attr_hash_size(alg));
- if (attrs == NULL)
+ if (attr == NULL)
return -1;
- attrs->hash_type = htonl(hash_type);
- if (vb2_digest_buffer(buffer_get(buffer), buffer_size(buffer),
- hash_type, attrs->hash_data, hash_size) != VB2_SUCCESS)
+ if (vb2_hash_calculate(buffer_get(buffer), buffer_size(buffer),
+ alg, &attr->hash) != VB2_SUCCESS)
return -1;
return 0;
@@ -1969,7 +1947,7 @@ int32_t cbfs_locate_entry(struct cbfs_image *image, size_t size,
size, page_size);
size_t image_align = image->has_header ? image->header.align :
- CBFS_ENTRY_ALIGNMENT;
+ CBFS_ALIGNMENT;
if (page_size % image_align)
WARN("%s: Page size (%#zx) not aligned with CBFS image (%#zx).\n",
__func__, page_size, image_align);
@@ -2005,7 +1983,7 @@ int32_t cbfs_locate_entry(struct cbfs_image *image, size_t size,
entry = cbfs_find_next_entry(image, entry)) {
uint32_t type = ntohl(entry->type);
- if (type != CBFS_COMPONENT_NULL)
+ if (type != CBFS_TYPE_NULL)
continue;
addr = cbfs_get_entry_addr(image, entry);