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, &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()
156 f->data_size = header.inp_size; in parse_ecc_header()
157 f->ecc.blocks = fec_div_round_up(f->data_size, FEC_BLOCKSIZE); in parse_ecc_header()
158 f->ecc.rounds = fec_div_round_up(f->ecc.blocks, f->ecc.rsn); in parse_ecc_header()
161 (uint32_t)f->ecc.rounds * f->ecc.roots * FEC_BLOCKSIZE) { in parse_ecc_header()
166 f->ecc.size = header.fec_size; in parse_ecc_header()
167 f->ecc.start = header.inp_size; in parse_ecc_header()
177 while (n < f->ecc.size) { in parse_ecc_header()
178 if (len > f->ecc.size - n) { in parse_ecc_header()
179 len = f->ecc.size - n; in parse_ecc_header()
182 if (!raw_pread(f, buf, len, f->ecc.start + n)) { in parse_ecc_header()
194 f->ecc.valid = !memcmp(hash, header.hash, SHA256_DIGEST_LENGTH); in parse_ecc_header()
196 if (!f->ecc.valid) { in parse_ecc_header()
205 static int parse_ecc(fec_handle *f, uint64_t offset) in parse_ecc() argument
207 check(f); in parse_ecc()
212 if (parse_ecc_header(f, offset) == 0) { in parse_ecc()
217 if (parse_ecc_header(f, offset + FEC_BLOCKSIZE - sizeof(fec_header)) == 0) { in parse_ecc()
227 static int get_squashfs_size(fec_handle *f, uint64_t *offset) in get_squashfs_size() argument
229 check(f); in get_squashfs_size()
237 if (fec_pread(f, buffer, sizeof(buffer), 0) != (ssize_t)sb_size) { in get_squashfs_size()
255 static int get_ext4_size(fec_handle *f, uint64_t *offset) in get_ext4_size() argument
257 check(f); in get_ext4_size()
258 check(f->size > 1024 + sizeof(ext4_super_block)); in get_ext4_size()
263 if (fec_pread(f, &sb, sizeof(sb), 1024) != sizeof(sb)) { in get_ext4_size()
282 static int get_fs_size(fec_handle *f, uint64_t *offset) in get_fs_size() argument
284 check(f); in get_fs_size()
287 if (f->flags & FEC_FS_EXT4) { in get_fs_size()
288 return get_ext4_size(f, offset); in get_fs_size()
289 } else if (f->flags & FEC_FS_SQUASH) { in get_fs_size()
290 return get_squashfs_size(f, offset); in get_fs_size()
293 int rc = get_ext4_size(f, offset); in get_fs_size()
300 rc = get_squashfs_size(f, offset); in get_fs_size()
311 static int load_verity(fec_handle *f) in load_verity() argument
313 check(f); in load_verity()
314 debug("size = %" PRIu64 ", flags = %d", f->data_size, f->flags); in load_verity()
316 uint64_t offset = f->data_size - VERITY_METADATA_SIZE; in load_verity()
319 if (verity_parse_header(f, offset) == 0) { in load_verity()
321 f->verity.hash_start); in load_verity()
328 if (find_verity_offset(f, &offset) == 0 && in load_verity()
329 verity_parse_header(f, offset) == 0) { in load_verity()
331 f->verity.hash_start); in load_verity()
336 int rc = get_fs_size(f, &offset); in load_verity()
340 rc = verity_parse_header(f, offset); in load_verity()
344 f->verity.hash_start); in load_verity()
352 static int load_ecc(fec_handle *f) in load_ecc() argument
354 check(f); in load_ecc()
355 debug("size = %" PRIu64, f->data_size); in load_ecc()
357 uint64_t offset = f->data_size - FEC_BLOCKSIZE; in load_ecc()
359 if (parse_ecc(f, offset) == 0) { in load_ecc()
361 f->ecc.start); in load_ecc()
369 static int get_size(fec_handle *f) in get_size() argument
371 check(f); in get_size()
375 if (fstat(f->fd, &st) == -1) { in get_size()
383 if (ioctl(f->fd, BLKGETSIZE64, &f->size) == -1) { in get_size()
389 f->size = st.st_size; in get_size()
400 static void reset_handle(fec_handle *f) in reset_handle() argument
402 f->fd = -1; in reset_handle()
403 f->flags = 0; in reset_handle()
404 f->mode = 0; in reset_handle()
405 f->errors = 0; in reset_handle()
406 f->data_size = 0; in reset_handle()
407 f->pos = 0; in reset_handle()
408 f->size = 0; in reset_handle()
410 memset(&f->ecc, 0, sizeof(f->ecc)); in reset_handle()
411 memset(&f->verity, 0, sizeof(f->verity)); in reset_handle()
415 int fec_close(struct fec_handle *f) in fec_close() argument
417 check(f); in fec_close()
419 if (f->fd != -1) { in fec_close()
420 if (f->mode & O_RDWR && fdatasync(f->fd) == -1) { in fec_close()
424 TEMP_FAILURE_RETRY(close(f->fd)); in fec_close()
427 if (f->verity.hash) { in fec_close()
428 delete[] f->verity.hash; in fec_close()
430 if (f->verity.salt) { in fec_close()
431 delete[] f->verity.salt; in fec_close()
433 if (f->verity.table) { in fec_close()
434 delete[] f->verity.table; in fec_close()
437 pthread_mutex_destroy(&f->mutex); in fec_close()
439 reset_handle(f); in fec_close()
440 delete f; in fec_close()
447 int fec_verity_get_metadata(struct fec_handle *f, struct fec_verity_metadata *data) in fec_verity_get_metadata() argument
449 check(f); in fec_verity_get_metadata()
452 if (!f->verity.metadata_start) { in fec_verity_get_metadata()
456 check(f->data_size < f->size); in fec_verity_get_metadata()
457 check(f->data_size <= f->verity.hash_start); in fec_verity_get_metadata()
458 check(f->data_size <= f->verity.metadata_start); in fec_verity_get_metadata()
459 check(f->verity.table); in fec_verity_get_metadata()
461 data->disabled = f->verity.disabled; in fec_verity_get_metadata()
462 data->data_size = f->data_size; in fec_verity_get_metadata()
463 memcpy(data->signature, f->verity.header.signature, in fec_verity_get_metadata()
465 memcpy(data->ecc_signature, f->verity.ecc_header.signature, in fec_verity_get_metadata()
467 data->table = f->verity.table; in fec_verity_get_metadata()
468 data->table_length = f->verity.header.length; in fec_verity_get_metadata()
475 int fec_ecc_get_metadata(struct fec_handle *f, struct fec_ecc_metadata *data) in fec_ecc_get_metadata() argument
477 check(f); in fec_ecc_get_metadata()
480 if (!f->ecc.start) { in fec_ecc_get_metadata()
484 check(f->data_size < f->size); in fec_ecc_get_metadata()
485 check(f->ecc.start >= f->data_size); in fec_ecc_get_metadata()
486 check(f->ecc.start < f->size); in fec_ecc_get_metadata()
487 check(f->ecc.start % FEC_BLOCKSIZE == 0) in fec_ecc_get_metadata()
489 data->valid = f->ecc.valid; in fec_ecc_get_metadata()
490 data->roots = f->ecc.roots; in fec_ecc_get_metadata()
491 data->blocks = f->ecc.blocks; in fec_ecc_get_metadata()
492 data->rounds = f->ecc.rounds; in fec_ecc_get_metadata()
493 data->start = f->ecc.start; in fec_ecc_get_metadata()
499 int fec_get_status(struct fec_handle *f, struct fec_status *s) in fec_get_status() argument
501 check(f); in fec_get_status()
504 s->flags = f->flags; in fec_get_status()
505 s->mode = f->mode; in fec_get_status()
506 s->errors = f->errors; in fec_get_status()
507 s->data_size = f->data_size; in fec_get_status()
508 s->size = f->size; in fec_get_status()
532 fec::handle f(new (std::nothrow) fec_handle, fec_close); in fec_open() local
534 if (unlikely(!f)) { in fec_open()
540 reset_handle(f.get()); in fec_open()
542 f->mode = mode; in fec_open()
543 f->ecc.roots = roots; in fec_open()
544 f->ecc.rsn = FEC_RSM - roots; in fec_open()
545 f->flags = flags; in fec_open()
547 if (unlikely(pthread_mutex_init(&f->mutex, NULL) != 0)) { in fec_open()
552 f->fd = TEMP_FAILURE_RETRY(open(path, mode | O_CLOEXEC)); in fec_open()
554 if (f->fd == -1) { in fec_open()
559 if (get_size(f.get()) == -1) { in fec_open()
564 f->data_size = f->size; /* until ecc and/or verity are loaded */ in fec_open()
566 if (load_ecc(f.get()) == -1) { in fec_open()
570 if (load_verity(f.get()) == -1) { in fec_open()
574 *handle = f.release(); in fec_open()