MCPcopy Create free account
hub / github.com/coreboot/coreboot / qualcomm_find_hash

Function qualcomm_find_hash

util/cbfstool/platform_fixups.c:114–190  ·  view source on GitHub ↗

* NOTE: This currently only implements support for MBN version 6 (as used by sc7180). Support * for other MBN versions could probably be added but may require more parsing to tell them * apart, and minor modifications (e.g. different hash algorithm). Add later as needed. */

Source from the content-addressed store, hash-verified

112 * apart, and minor modifications (e.g. different hash algorithm). Add later as needed.
113 */
114static void *qualcomm_find_hash(struct buffer *in, size_t bb_offset, struct vb2_hash *real_hash)
115{
116 Elf64_Phdr *ph;
117 struct buffer elf;
118 buffer_clone(&elf, in);
119
120 /* When buffer_size(&elf) becomes this small, we know we've searched through 32KiB (or
121 the whole bootblock) without finding anything, so we know we can stop looking. */
122 size_t search_end_size = MIN(0, buffer_size(in) - 32 * KiB);
123
124 /* To identify a Qualcomm image, first we find the GPT header... */
125 while (buffer_size(&elf) > search_end_size &&
126 !buffer_check_magic(&elf, "EFI PART", 8))
127 buffer_seek(&elf, 512);
128
129 /* ...then shortly afterwards there's an ELF header... */
130 while (buffer_size(&elf) > search_end_size &&
131 !buffer_check_magic(&elf, ELFMAG, 4))
132 buffer_seek(&elf, 512);
133
134 if (buffer_size(&elf) <= search_end_size)
135 return NULL; /* Doesn't seem to be a Qualcomm image. */
136
137 struct parsed_elf pelf;
138 if (parse_elf(&elf, &pelf, ELF_PARSE_PHDR))
139 return NULL; /* Not an ELF -- guess not a Qualcomm MBN after all? */
140
141 /*
142 * Check if it is a multi ELF or single ELF. If bb_offset is beyond the
143 * final segment of first ELF, it is a multi ELF.
144 */
145 ph = &pelf.phdr[pelf.ehdr.e_phnum - 1];
146 if (bb_offset > (ph->p_offset + ph->p_filesz)) { /* MBNv7 multi ELF */
147 parsed_elf_destroy(&pelf);
148 return qualcomm_find_hash_mbnv7(&elf, bb_offset, real_hash);
149 }
150
151 /* Qualcomm stores an array of SHA-384 hashes in a special ELF segment. One special one
152 to start with, and then one for each segment in order. */
153 void *bb_hash = NULL;
154 void *hashtable = NULL;
155 int i;
156 int bb_segment = -1;
157 for (i = 0; i < pelf.ehdr.e_phnum; i++) {
158 ph = &pelf.phdr[i];
159 if ((ph->p_flags & PF_QC_SG_MASK) == PF_QC_SG_HASH) {
160 if ((int)ph->p_filesz !=
161 (pelf.ehdr.e_phnum + 1) * VB2_SHA384_DIGEST_SIZE) {
162 ERROR("fixups: Qualcomm hash segment has wrong size!\n");
163 goto destroy_elf;
164 } /* Found the table with the hashes -- store its address. */
165 hashtable = buffer_get(&elf) + ph->p_offset;
166 } else if (bb_segment < 0 && ph->p_offset + ph->p_filesz < buffer_size(&elf) &&
167 buffer_offset(&elf) + ph->p_offset <= bb_offset &&
168 buffer_offset(&elf) + ph->p_offset + ph->p_filesz > bb_offset) {
169 bb_segment = i; /* Found the bootblock segment -- store its index. */
170 }
171 }

Callers 2

qualcomm_probeFunction · 0.85
qualcomm_fixupFunction · 0.85

Calls 9

buffer_cloneFunction · 0.85
buffer_sizeFunction · 0.85
buffer_check_magicFunction · 0.85
buffer_seekFunction · 0.85
parse_elfFunction · 0.85
parsed_elf_destroyFunction · 0.85
qualcomm_find_hash_mbnv7Function · 0.85
buffer_getFunction · 0.85
buffer_offsetFunction · 0.85

Tested by

no test coverage detected