/* SPDX-License-Identifier: GPL-2.0-only */

#include <commonlib/cbfs.h>
#include <commonlib/endian.h>
#include <commonlib/helpers.h>
#include <string.h>
#include <vb2_sha.h>

static size_t cbfs_next_offset(const struct region_device *cbfs,
				const struct cbfsf *f)
{
	size_t offset;

	if (f == NULL)
		return 0;

	/* The region_device objects store absolute offsets over the whole
	 * region. Therefore a relative offset needs to be calculated. */
	offset = rdev_relative_offset(cbfs, &f->data);
	offset += region_device_sz(&f->data);

	return ALIGN_UP(offset, CBFS_ALIGNMENT);
}

static int cbfs_end(const struct region_device *cbfs, size_t offset)
{
	if (offset >= region_device_sz(cbfs))
		return 1;

	return 0;
}

int cbfs_for_each_file(const struct region_device *cbfs,
			const struct cbfsf *prev, struct cbfsf *fh)
{
	size_t offset;

	offset = cbfs_next_offset(cbfs, prev);

	/* Try to scan the entire cbfs region looking for file name. */
	while (1) {
		struct cbfs_file file;
		const size_t fsz = sizeof(file);

		 DEBUG("Checking offset %zx\n", offset);

		/* End of region. */
		if (cbfs_end(cbfs, offset))
			return 1;

		/* Can't read file. Nothing else to do but bail out. */
		if (rdev_readat(cbfs, &file, offset, fsz) != fsz)
			break;

		if (memcmp(file.magic, CBFS_FILE_MAGIC, sizeof(file.magic))) {
			offset++;
			offset = ALIGN_UP(offset, CBFS_ALIGNMENT);
			continue;
		}

		file.len = read_be32(&file.len);
		file.offset = read_be32(&file.offset);

		DEBUG("File @ offset %zx size %x\n", offset, file.len);

		/* Keep track of both the metadata and the data for the file. */
		if (rdev_chain(&fh->metadata, cbfs, offset, file.offset))
			break;

		if (rdev_chain(&fh->data, cbfs, offset + file.offset, file.len))
			break;

		/* Success. */
		return 0;
	}

	return -1;
}

size_t cbfs_for_each_attr(void *metadata, size_t metadata_size,
			  size_t last_offset)
{
	struct cbfs_file_attribute *attr;

	if (!last_offset) {
		struct cbfs_file *file = metadata;
		size_t start_offset = read_be32(&file->attributes_offset);
		if (start_offset <= sizeof(struct cbfs_file) ||
		    start_offset + sizeof(*attr) > metadata_size)
			return 0;
		return start_offset;
	}

	attr = metadata + last_offset;
	size_t next_offset = last_offset + read_be32(&attr->len);

	if (next_offset + sizeof(*attr) > metadata_size)
		return 0;
	return next_offset;
}

int cbfsf_decompression_info(struct cbfsf *fh, uint32_t *algo, size_t *size)
{
	size_t metadata_size = region_device_sz(&fh->metadata);
	void *metadata = rdev_mmap_full(&fh->metadata);
	size_t offs = 0;

	if (!metadata)
		return -1;

	while ((offs = cbfs_for_each_attr(metadata, metadata_size, offs))) {
		struct cbfs_file_attr_compression *attr = metadata + offs;
		if (read_be32(&attr->tag) != CBFS_FILE_ATTR_TAG_COMPRESSION)
			continue;

		*algo = read_be32(&attr->compression);
		*size = read_be32(&attr->decompressed_size);
		rdev_munmap(&fh->metadata, metadata);
		return 0;
	}

	*algo = CBFS_COMPRESS_NONE;
	*size = region_device_sz(&fh->data);
	rdev_munmap(&fh->metadata, metadata);
	return 0;
}

int cbfsf_file_type(struct cbfsf *fh, uint32_t *ftype)
{
	const size_t sz = sizeof(*ftype);

	if (rdev_readat(&fh->metadata, ftype,
			offsetof(struct cbfs_file, type), sz) != sz)
		return -1;

	*ftype = read_be32(ftype);

	return 0;
}

int cbfs_locate(struct cbfsf *fh, const struct region_device *cbfs,
		const char *name, uint32_t *type)
{
	struct cbfsf *prev;

	LOG("Locating '%s'\n", name);

	prev = NULL;

	while (1) {
		int ret;
		char *fname;
		int name_match;
		const size_t fsz = sizeof(struct cbfs_file);

		ret = cbfs_for_each_file(cbfs, prev, fh);
		prev = fh;

		/* Either failed to read or hit the end of the region. */
		if (ret < 0 || ret > 0)
			break;

		fname = rdev_mmap(&fh->metadata, fsz,
				region_device_sz(&fh->metadata) - fsz);

		if (fname == NULL)
			break;

		name_match = !strcmp(fname, name);
		rdev_munmap(&fh->metadata, fname);

		if (!name_match) {
			DEBUG(" Unmatched '%s' at %zx\n", fname,
				rdev_relative_offset(cbfs, &fh->metadata));
			continue;
		}

		if (type != NULL) {
			uint32_t ftype;

			if (cbfsf_file_type(fh, &ftype))
				break;

			if (*type != 0 && *type != ftype) {
				DEBUG(" Unmatched type %x at %zx\n", ftype,
					rdev_relative_offset(cbfs,
							&fh->metadata));
				continue;
			}
			// *type being 0 means we want to know ftype.
			// We could just do a blind assignment but
			// if type is pointing to read-only memory
			// that might be bad.
			if (*type == 0)
				*type = ftype;
		}

		LOG("Found @ offset %zx size %zx\n",
			rdev_relative_offset(cbfs, &fh->metadata),
			region_device_sz(&fh->data));

		/* Success. */
		return 0;
	}

	LOG("'%s' not found.\n", name);
	return -1;
}

static int cbfs_extend_hash_buffer(struct vb2_digest_context *ctx,
					void *buf, size_t sz)
{
	return vb2_digest_extend(ctx, buf, sz);
}

static int cbfs_extend_hash(struct vb2_digest_context *ctx,
				const struct region_device *rdev)
{
	uint8_t buffer[1024];
	size_t sz_left;
	size_t offset;

	sz_left = region_device_sz(rdev);
	offset = 0;

	while (sz_left) {
		int rv;
		size_t block_sz = MIN(sz_left, sizeof(buffer));

		if (rdev_readat(rdev, buffer, offset, block_sz) != block_sz)
			return VB2_ERROR_UNKNOWN;

		rv = cbfs_extend_hash_buffer(ctx, buffer, block_sz);

		if (rv)
			return rv;

		sz_left -= block_sz;
		offset += block_sz;
	}

	return VB2_SUCCESS;
}

/* Include offsets of child regions within the parent into the hash. */
static int cbfs_extend_hash_with_offset(struct vb2_digest_context *ctx,
					const struct region_device *p,
					const struct region_device *c)
{
	int32_t soffset;
	int rv;

	soffset = rdev_relative_offset(p, c);

	if (soffset < 0)
		return VB2_ERROR_UNKNOWN;

	/* All offsets in big endian format. */
	write_be32(&soffset, soffset);

	rv = cbfs_extend_hash_buffer(ctx, &soffset, sizeof(soffset));

	if (rv)
		return rv;

	return cbfs_extend_hash(ctx, c);
}

/* Hash in the potential CBFS header sitting at the beginning of the CBFS
 * region as well as relative offset at the end. */
static int cbfs_extend_hash_master_header(struct vb2_digest_context *ctx,
					const struct region_device *cbfs)
{
	struct region_device rdev;
	int rv;

	if (rdev_chain(&rdev, cbfs, 0, sizeof(struct cbfs_header)))
		return VB2_ERROR_UNKNOWN;

	rv = cbfs_extend_hash_with_offset(ctx, cbfs, &rdev);

	if (rv)
		return rv;

	/* Include potential relative offset at end of region. */
	if (rdev_chain(&rdev, cbfs, region_device_sz(cbfs) - sizeof(int32_t),
			sizeof(int32_t)))
		return VB2_ERROR_UNKNOWN;

	return cbfs_extend_hash_with_offset(ctx, cbfs, &rdev);
}

int cbfs_vb2_hash_contents(const struct region_device *cbfs,
				enum vb2_hash_algorithm hash_alg, void *digest,
				size_t digest_sz)
{
	struct vb2_digest_context ctx;
	int rv;
	struct cbfsf f;
	struct cbfsf *prev;
	struct cbfsf *fh;

	rv = vb2_digest_init(&ctx, hash_alg);

	if (rv)
		return rv;

	rv = cbfs_extend_hash_master_header(&ctx, cbfs);
	if (rv)
		return rv;

	prev = NULL;
	fh = &f;

	while (1) {
		uint32_t ftype;

		rv = cbfs_for_each_file(cbfs, prev, fh);
		prev = fh;

		if (rv < 0)
			return VB2_ERROR_UNKNOWN;

		/* End of CBFS. */
		if (rv > 0)
			break;

		rv = cbfs_extend_hash_with_offset(&ctx, cbfs, &fh->metadata);

		if (rv)
			return rv;

		/* Include data contents in hash if file is non-empty. */
		if (cbfsf_file_type(fh, &ftype))
			return VB2_ERROR_UNKNOWN;

		if (ftype == CBFS_TYPE_DELETED || ftype == CBFS_TYPE_NULL)
			continue;

		rv = cbfs_extend_hash_with_offset(&ctx, cbfs, &fh->data);

		if (rv)
			return rv;
	}

	return vb2_digest_finalize(&ctx, digest, digest_sz);
}
