Lines Matching refs:f
89 static int find_verity_offset(fec_handle *f, uint64_t *offset) in find_verity_offset() argument
91 check(f); in find_verity_offset()
94 return find_offset(f->data_size, 0, offset, get_verity_size, in find_verity_offset()
99 static int parse_ecc_header(fec_handle *f, uint64_t offset) in parse_ecc_header() argument
101 check(f); in parse_ecc_header()
102 check(f->ecc.rsn > 0 && f->ecc.rsn < FEC_RSM); in parse_ecc_header()
103 check(f->size > sizeof(fec_header)); in parse_ecc_header()
107 if (offset > f->size - sizeof(fec_header)) { in parse_ecc_header()
115 if (!raw_pread(f->fd, &header, sizeof(fec_header), offset)) { in parse_ecc_header()
138 if (f->ecc.roots != (int)header.roots) { in parse_ecc_header()
139 error("unexpected number of roots: %d vs %u", f->ecc.roots, in parse_ecc_header()
149 f->data_size = header.inp_size; in parse_ecc_header()
150 f->ecc.blocks = fec_div_round_up(f->data_size, FEC_BLOCKSIZE); in parse_ecc_header()
151 f->ecc.rounds = fec_div_round_up(f->ecc.blocks, f->ecc.rsn); in parse_ecc_header()
154 (uint32_t)f->ecc.rounds * f->ecc.roots * FEC_BLOCKSIZE) { in parse_ecc_header()
159 f->ecc.size = header.fec_size; in parse_ecc_header()
160 f->ecc.start = header.inp_size; in parse_ecc_header()
170 while (n < f->ecc.size) { in parse_ecc_header()
171 if (len > f->ecc.size - n) { in parse_ecc_header()
172 len = f->ecc.size - n; in parse_ecc_header()
175 if (!raw_pread(f->fd, buf, len, f->ecc.start + n)) { in parse_ecc_header()
187 f->ecc.valid = !memcmp(hash, header.hash, SHA256_DIGEST_LENGTH); in parse_ecc_header()
189 if (!f->ecc.valid) { in parse_ecc_header()
198 static int parse_ecc(fec_handle *f, uint64_t offset) in parse_ecc() argument
200 check(f); in parse_ecc()
205 if (parse_ecc_header(f, offset) == 0) { in parse_ecc()
210 if (parse_ecc_header(f, offset + FEC_BLOCKSIZE - sizeof(fec_header)) == 0) { in parse_ecc()
220 static int get_squashfs_size(fec_handle *f, uint64_t *offset) in get_squashfs_size() argument
222 check(f); in get_squashfs_size()
230 if (fec_pread(f, buffer, sizeof(buffer), 0) != (ssize_t)sb_size) { in get_squashfs_size()
248 static int get_ext4_size(fec_handle *f, uint64_t *offset) in get_ext4_size() argument
250 check(f); in get_ext4_size()
251 check(f->size > 1024 + sizeof(ext4_super_block)); in get_ext4_size()
256 if (fec_pread(f, &sb, sizeof(sb), 1024) != sizeof(sb)) { in get_ext4_size()
275 static int get_fs_size(fec_handle *f, uint64_t *offset) in get_fs_size() argument
277 check(f); in get_fs_size()
280 if (f->flags & FEC_FS_EXT4) { in get_fs_size()
281 return get_ext4_size(f, offset); in get_fs_size()
282 } else if (f->flags & FEC_FS_SQUASH) { in get_fs_size()
283 return get_squashfs_size(f, offset); in get_fs_size()
286 int rc = get_ext4_size(f, offset); in get_fs_size()
293 rc = get_squashfs_size(f, offset); in get_fs_size()
304 static int load_verity(fec_handle *f) in load_verity() argument
306 check(f); in load_verity()
307 debug("size = %" PRIu64 ", flags = %d", f->data_size, f->flags); in load_verity()
309 uint64_t offset = f->data_size - VERITY_METADATA_SIZE; in load_verity()
312 if (verity_parse_header(f, offset) == 0) { in load_verity()
314 f->verity.hashtree.hash_start); in load_verity()
321 if (find_verity_offset(f, &offset) == 0 && in load_verity()
322 verity_parse_header(f, offset) == 0) { in load_verity()
324 f->verity.hashtree.hash_start); in load_verity()
329 int rc = get_fs_size(f, &offset); in load_verity()
334 rc = verity_parse_header(f, offset); in load_verity()
338 f->verity.hashtree.hash_start); in load_verity()
346 static int load_ecc(fec_handle *f) in load_ecc() argument
348 check(f); in load_ecc()
349 debug("size = %" PRIu64, f->data_size); in load_ecc()
351 uint64_t offset = f->data_size - FEC_BLOCKSIZE; in load_ecc()
353 if (parse_ecc(f, offset) == 0) { in load_ecc()
355 f->ecc.start); in load_ecc()
363 static int get_size(fec_handle *f) in get_size() argument
365 check(f); in get_size()
369 if (fstat(f->fd, &st) == -1) { in get_size()
377 if (ioctl(f->fd, BLKGETSIZE64, &f->size) == -1) { in get_size()
383 f->size = st.st_size; in get_size()
394 static void reset_handle(fec_handle *f) in reset_handle() argument
396 f->fd = -1; in reset_handle()
397 f->flags = 0; in reset_handle()
398 f->mode = 0; in reset_handle()
399 f->errors = 0; in reset_handle()
400 f->data_size = 0; in reset_handle()
401 f->pos = 0; in reset_handle()
402 f->size = 0; in reset_handle()
404 f->ecc = {}; in reset_handle()
405 f->verity = {}; in reset_handle()
409 int fec_close(struct fec_handle *f) in fec_close() argument
411 check(f); in fec_close()
413 if (f->fd != -1) { in fec_close()
414 if (f->mode & O_RDWR && fdatasync(f->fd) == -1) { in fec_close()
418 close(f->fd); in fec_close()
421 pthread_mutex_destroy(&f->mutex); in fec_close()
423 reset_handle(f); in fec_close()
424 delete f; in fec_close()
431 int fec_verity_get_metadata(struct fec_handle *f, struct fec_verity_metadata *data) in fec_verity_get_metadata() argument
433 check(f); in fec_verity_get_metadata()
436 if (!f->verity.metadata_start) { in fec_verity_get_metadata()
440 check(f->data_size < f->size); in fec_verity_get_metadata()
441 check(f->data_size <= f->verity.hashtree.hash_start); in fec_verity_get_metadata()
442 check(f->data_size <= f->verity.metadata_start); in fec_verity_get_metadata()
443 check(!f->verity.table.empty()); in fec_verity_get_metadata()
445 data->disabled = f->verity.disabled; in fec_verity_get_metadata()
446 data->data_size = f->data_size; in fec_verity_get_metadata()
447 memcpy(data->signature, f->verity.header.signature, in fec_verity_get_metadata()
449 memcpy(data->ecc_signature, f->verity.ecc_header.signature, in fec_verity_get_metadata()
451 data->table = f->verity.table.c_str(); in fec_verity_get_metadata()
452 data->table_length = f->verity.header.length; in fec_verity_get_metadata()
459 int fec_ecc_get_metadata(struct fec_handle *f, struct fec_ecc_metadata *data) in fec_ecc_get_metadata() argument
461 check(f); in fec_ecc_get_metadata()
464 if (!f->ecc.start) { in fec_ecc_get_metadata()
468 check(f->data_size < f->size); in fec_ecc_get_metadata()
469 check(f->ecc.start >= f->data_size); in fec_ecc_get_metadata()
470 check(f->ecc.start < f->size); in fec_ecc_get_metadata()
471 check(f->ecc.start % FEC_BLOCKSIZE == 0); in fec_ecc_get_metadata()
473 data->valid = f->ecc.valid; in fec_ecc_get_metadata()
474 data->roots = f->ecc.roots; in fec_ecc_get_metadata()
475 data->blocks = f->ecc.blocks; in fec_ecc_get_metadata()
476 data->rounds = f->ecc.rounds; in fec_ecc_get_metadata()
477 data->start = f->ecc.start; in fec_ecc_get_metadata()
483 int fec_get_status(struct fec_handle *f, struct fec_status *s) in fec_get_status() argument
485 check(f); in fec_get_status()
488 s->flags = f->flags; in fec_get_status()
489 s->mode = f->mode; in fec_get_status()
490 s->errors = f->errors; in fec_get_status()
491 s->data_size = f->data_size; in fec_get_status()
492 s->size = f->size; in fec_get_status()
516 fec::handle f(new (std::nothrow) fec_handle, fec_close); in fec_open() local
518 if (unlikely(!f)) { in fec_open()
524 reset_handle(f.get()); in fec_open()
526 f->mode = mode; in fec_open()
527 f->ecc.roots = roots; in fec_open()
528 f->ecc.rsn = FEC_RSM - roots; in fec_open()
529 f->flags = flags; in fec_open()
531 if (unlikely(pthread_mutex_init(&f->mutex, NULL) != 0)) { in fec_open()
536 f->fd = TEMP_FAILURE_RETRY(open(path, mode | O_CLOEXEC)); in fec_open()
538 if (f->fd == -1) { in fec_open()
543 if (get_size(f.get()) == -1) { in fec_open()
548 f->data_size = f->size; /* until ecc and/or verity are loaded */ in fec_open()
553 if (parse_vbmeta_from_footer(f.get(), &vbmeta) == 0) { in fec_open()
554 if (parse_avb_image(f.get(), vbmeta) != 0) { in fec_open()
559 *handle = f.release(); in fec_open()
567 if (load_ecc(f.get()) == -1) { in fec_open()
571 if (load_verity(f.get()) == -1) { in fec_open()
575 *handle = f.release(); in fec_open()