diff options
Diffstat (limited to 'util/cbfstool/cbfs_image.c')
-rw-r--r-- | util/cbfstool/cbfs_image.c | 128 |
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); |