/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * High-level firmware API for loading and verifying rewritable firmware.
 * (Firmware portion)
 */

#include "2sysincludes.h"
#include "2common.h"

#include "sysincludes.h"
#include "bmpblk_header.h"
#include "region.h"
#include "gbb_access.h"
#include "gbb_header.h"
#include "load_kernel_fw.h"
#include "utility.h"
#include "vboot_api.h"
#include "vboot_struct.h"

static VbError_t VbRegionReadGbb(VbCommonParams *cparams, uint32_t offset,
				  uint32_t size, void *buf)
{
	return VbRegionReadData(cparams, VB_REGION_GBB, offset, size, buf);
}

VbError_t VbGbbReadBmpHeader(VbCommonParams *cparams, BmpBlockHeader *hdr_ret)
{
	BmpBlockHeader *hdr;
	VbError_t ret;

	if (!cparams)
		return VBERROR_INVALID_GBB;
	if (!cparams->bmp) {
		GoogleBinaryBlockHeader *gbb = cparams->gbb;

		if (0 == gbb->bmpfv_size)
			return VBERROR_INVALID_GBB;

		hdr = malloc(sizeof(*hdr));
		ret = VbRegionReadGbb(cparams, gbb->bmpfv_offset,
				      sizeof(BmpBlockHeader), hdr);
		if (ret) {
			free(hdr);
			return ret;
		}

		/* Sanity-check the bitmap block header */
		if ((0 != memcmp(hdr->signature, BMPBLOCK_SIGNATURE,
				BMPBLOCK_SIGNATURE_SIZE)) ||
		(hdr->major_version > BMPBLOCK_MAJOR_VERSION) ||
		((hdr->major_version == BMPBLOCK_MAJOR_VERSION) &&
		(hdr->minor_version > BMPBLOCK_MINOR_VERSION))) {
			VB2_DEBUG("VbGbbReadBmpHeader(): "
				  "invalid/too new bitmap header\n");
			free(hdr);
			return VBERROR_INVALID_BMPFV;
		}
		cparams->bmp = hdr;
	}

	*hdr_ret = *cparams->bmp;
	return VBERROR_SUCCESS;
}

VbError_t VbRegionReadHWID(VbCommonParams *cparams, char *hwid,
			   uint32_t max_size)
{
	GoogleBinaryBlockHeader *gbb;
	VbError_t ret;

	if (!max_size)
		return VBERROR_INVALID_PARAMETER;
	*hwid = '\0';
	StrnAppend(hwid, "{INVALID}", max_size);
	if (!cparams)
		return VBERROR_INVALID_GBB;

	gbb = cparams->gbb;

	if (0 == gbb->hwid_size) {
		VB2_DEBUG("VbHWID(): invalid hwid size\n");
		return VBERROR_SUCCESS; /* oddly enough! */
	}

	if (gbb->hwid_size > max_size) {
		VB2_DEBUG("VbDisplayDebugInfo(): invalid hwid offset/size\n");
		return VBERROR_INVALID_PARAMETER;
	}
	ret = VbRegionReadGbb(cparams, gbb->hwid_offset, gbb->hwid_size, hwid);
	if (ret)
		return ret;

	return VBERROR_SUCCESS;
}

VbError_t VbGbbReadImage(VbCommonParams *cparams,
			       uint32_t localization, uint32_t screen_index,
			       uint32_t image_num, ScreenLayout *layout,
			       ImageInfo *image_info, char **image_datap,
			       uint32_t *image_data_sizep)
{
	uint32_t layout_offset, image_offset, data_offset, data_size;
	GoogleBinaryBlockHeader *gbb;
	BmpBlockHeader hdr;
	void *data = NULL;
	VbError_t ret;

	if (!cparams)
		return VBERROR_INVALID_GBB;

	ret = VbGbbReadBmpHeader(cparams, &hdr);
	if (ret)
		return ret;

	gbb = cparams->gbb;
	layout_offset = gbb->bmpfv_offset + sizeof(BmpBlockHeader) +
		localization * hdr.number_of_screenlayouts *
			sizeof(ScreenLayout) +
		screen_index * sizeof(ScreenLayout);
	ret = VbRegionReadGbb(cparams, layout_offset, sizeof(*layout), layout);
	if (ret)
		return ret;

	if (!layout->images[image_num].image_info_offset)
		return VBERROR_NO_IMAGE_PRESENT;

	image_offset = gbb->bmpfv_offset +
			layout->images[image_num].image_info_offset;
	ret = VbRegionReadGbb(cparams, image_offset, sizeof(*image_info),
			      image_info);
	if (ret)
		return ret;

	data_offset = image_offset + sizeof(*image_info);
	data_size = image_info->compressed_size;
	if (data_size) {
		void *orig_data;

		data = malloc(image_info->compressed_size);
		ret = VbRegionReadGbb(cparams, data_offset,
				      image_info->compressed_size, data);
		if (ret) {
			free(data);
			return ret;
		}
		if (image_info->compression != COMPRESS_NONE) {
			uint32_t inoutsize = image_info->original_size;

			orig_data = malloc(image_info->original_size);
			ret = VbExDecompress(data,
					     image_info->compressed_size,
					     image_info->compression,
					     orig_data, &inoutsize);
			data_size = inoutsize;
			free(data);
			data = orig_data;
			if (ret) {
				free(data);
				return ret;
			}
		}
	}

	*image_datap = data;
	*image_data_sizep = data_size;

	return VBERROR_SUCCESS;
}

#define OUTBUF_LEN 128

void VbRegionCheckVersion(VbCommonParams *cparams)
{
	GoogleBinaryBlockHeader *gbb;

	if (!cparams)
		return;

	gbb = cparams->gbb;

	/*
	 * If GBB flags is nonzero, complain because that's something that the
	 * factory MUST fix before shipping. We only have to do this here,
	 * because it's obvious that something is wrong if we're not displaying
	 * screens from the GBB.
	 */
	if (gbb->major_version == GBB_MAJOR_VER && gbb->minor_version >= 1 &&
	    (gbb->flags != 0)) {
		uint32_t used = 0;
		char outbuf[OUTBUF_LEN];

		*outbuf = '\0';
		used += StrnAppend(outbuf + used, "gbb.flags is nonzero: 0x",
				OUTBUF_LEN - used);
		used += Uint64ToString(outbuf + used, OUTBUF_LEN - used,
				       gbb->flags, 16, 8);
		used += StrnAppend(outbuf + used, "\n", OUTBUF_LEN - used);
		(void)VbExDisplayDebugInfo(outbuf);
	}
}
