/* 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.
 */

#include "2sysincludes.h"
#include "cgptlib.h"
#include "cgptlib_internal.h"
#include "crc32.h"
#include "gpt.h"
#include "gpt_misc.h"
#include "utility.h"

const static int MIN_SECTOR_SIZE = 512;

size_t CalculateEntriesSectors(GptHeader* h, uint32_t sector_bytes)
{
	size_t bytes = h->number_of_entries * h->size_of_entry;
	size_t ret = (bytes + sector_bytes - 1) / sector_bytes;
	return ret;
}

int CheckParameters(GptData *gpt)
{
	/* Only support 512-byte or larger sectors that are a power of 2 */
	if (gpt->sector_bytes < MIN_SECTOR_SIZE ||
			(gpt->sector_bytes  & (gpt->sector_bytes  - 1)) != 0)
		return GPT_ERROR_INVALID_SECTOR_SIZE;

	/*
	 * gpt_drive_sectors should be reasonable. It cannot be unset, and it
	 * cannot differ from streaming_drive_sectors if the GPT structs are
	 * stored on same device.
	 */
	if (gpt->gpt_drive_sectors == 0 ||
		(!(gpt->flags & GPT_FLAG_EXTERNAL) &&
		 gpt->gpt_drive_sectors != gpt->streaming_drive_sectors)) {
		return GPT_ERROR_INVALID_SECTOR_NUMBER;
	}

	/*
	 * Sector count of a drive should be reasonable. If the given value is
	 * too small to contain basic GPT structure (PMBR + Headers + Entries),
	 * the value is wrong.
	 */
	if (gpt->gpt_drive_sectors <
		(1 + 2 * (1 + MIN_NUMBER_OF_ENTRIES /
				(gpt->sector_bytes / sizeof(GptEntry)))))
		return GPT_ERROR_INVALID_SECTOR_NUMBER;

	return GPT_SUCCESS;
}

uint32_t HeaderCrc(GptHeader *h)
{
	uint32_t crc32, original_crc32;

	/* Original CRC is calculated with the CRC field 0. */
	original_crc32 = h->header_crc32;
	h->header_crc32 = 0;
	crc32 = Crc32((const uint8_t *)h, h->size);
	h->header_crc32 = original_crc32;

	return crc32;
}

int CheckHeader(GptHeader *h, int is_secondary,
		uint64_t streaming_drive_sectors,
		uint64_t gpt_drive_sectors, uint32_t flags,
		uint32_t sector_bytes)
{
	if (!h)
		return 1;

	/*
	 * Make sure we're looking at a header of reasonable size before
	 * attempting to calculate CRC.
	 */
	if (memcmp(h->signature, GPT_HEADER_SIGNATURE,
		   GPT_HEADER_SIGNATURE_SIZE) &&
	    memcmp(h->signature, GPT_HEADER_SIGNATURE2,
		   GPT_HEADER_SIGNATURE_SIZE))
		return 1;
	if (h->revision != GPT_HEADER_REVISION)
		return 1;
	if (h->size < MIN_SIZE_OF_HEADER || h->size > MAX_SIZE_OF_HEADER)
		return 1;

	/* Check CRC before looking at remaining fields */
	if (HeaderCrc(h) != h->header_crc32)
		return 1;

	/* Reserved fields must be zero. */
	if (h->reserved_zero)
		return 1;

	/* Could check that padding is zero, but that doesn't matter to us. */

	/*
	 * If entry size is different than our struct, we won't be able to
	 * parse it.  Technically, any size 2^N where N>=7 is valid.
	 */
	if (h->size_of_entry != sizeof(GptEntry))
		return 1;
	if ((h->number_of_entries < MIN_NUMBER_OF_ENTRIES) ||
	    (h->number_of_entries > MAX_NUMBER_OF_ENTRIES) ||
	    (!(flags & GPT_FLAG_EXTERNAL) &&
	    h->number_of_entries != MAX_NUMBER_OF_ENTRIES))
		return 1;

	/*
	 * Check locations for the header and its entries.  The primary
	 * immediately follows the PMBR, and is followed by its entries.  The
	 * secondary is at the end of the drive, preceded by its entries.
	 */
	if (is_secondary) {
		if (h->my_lba != gpt_drive_sectors - GPT_HEADER_SECTORS)
			return 1;
		if (h->entries_lba != h->my_lba - CalculateEntriesSectors(h,
								sector_bytes))
			return 1;
	} else {
		if (h->my_lba != GPT_PMBR_SECTORS)
			return 1;
		if (h->entries_lba < h->my_lba + 1)
			return 1;
	}

	/* FirstUsableLBA <= LastUsableLBA. */
	if (h->first_usable_lba > h->last_usable_lba)
		return 1;

	if (flags & GPT_FLAG_EXTERNAL) {
		if (h->last_usable_lba >= streaming_drive_sectors) {
			return 1;
		}
		return 0;
	}

	/*
	 * FirstUsableLBA must be after the end of the primary GPT table array.
	 * LastUsableLBA must be before the start of the secondary GPT table
	 * array.
	 */
	/* TODO(namnguyen): Also check for padding between header & entries. */
	if (h->first_usable_lba < 2 + CalculateEntriesSectors(h, sector_bytes))
		return 1;
	if (h->last_usable_lba >=
			streaming_drive_sectors - 1 - CalculateEntriesSectors(h,
								sector_bytes))
		return 1;

	/* Success */
	return 0;
}

int IsKernelEntry(const GptEntry *e)
{
	static Guid chromeos_kernel = GPT_ENT_TYPE_CHROMEOS_KERNEL;
	return !memcmp(&e->type, &chromeos_kernel, sizeof(Guid));
}

int CheckEntries(GptEntry *entries, GptHeader *h)
{
	if (!entries)
		return GPT_ERROR_INVALID_ENTRIES;
	GptEntry *entry;
	uint32_t crc32;
	uint32_t i;

	/* Check CRC before examining entries. */
	crc32 = Crc32((const uint8_t *)entries,
		      h->size_of_entry * h->number_of_entries);
	if (crc32 != h->entries_crc32)
		return GPT_ERROR_CRC_CORRUPTED;

	/* Check all entries. */
	for (i = 0, entry = entries; i < h->number_of_entries; i++, entry++) {
		GptEntry *e2;
		uint32_t i2;

		if (IsUnusedEntry(entry))
			continue;

		/* Entry must be in valid region. */
		if ((entry->starting_lba < h->first_usable_lba) ||
		    (entry->ending_lba > h->last_usable_lba) ||
		    (entry->ending_lba < entry->starting_lba))
			return GPT_ERROR_OUT_OF_REGION;

		/* Entry must not overlap other entries. */
		for (i2 = 0, e2 = entries; i2 < h->number_of_entries;
		     i2++, e2++) {
			if (i2 == i || IsUnusedEntry(e2))
				continue;

			if ((entry->starting_lba >= e2->starting_lba) &&
			    (entry->starting_lba <= e2->ending_lba))
				return GPT_ERROR_START_LBA_OVERLAP;
			if ((entry->ending_lba >= e2->starting_lba) &&
			    (entry->ending_lba <= e2->ending_lba))
				return GPT_ERROR_END_LBA_OVERLAP;

			/* UniqueGuid field must be unique. */
			if (0 == memcmp(&entry->unique, &e2->unique,
					sizeof(Guid)))
				return GPT_ERROR_DUP_GUID;
		}
	}

	/* Success */
	return 0;
}

int HeaderFieldsSame(GptHeader *h1, GptHeader *h2)
{
	if (memcmp(h1->signature, h2->signature, sizeof(h1->signature)))
		return 1;
	if (h1->revision != h2->revision)
		return 1;
	if (h1->size != h2->size)
		return 1;
	if (h1->reserved_zero != h2->reserved_zero)
		return 1;
	if (h1->first_usable_lba != h2->first_usable_lba)
		return 1;
	if (h1->last_usable_lba != h2->last_usable_lba)
		return 1;
	if (memcmp(&h1->disk_uuid, &h2->disk_uuid, sizeof(Guid)))
		return 1;
	if (h1->number_of_entries != h2->number_of_entries)
		return 1;
	if (h1->size_of_entry != h2->size_of_entry)
		return 1;
	if (h1->entries_crc32 != h2->entries_crc32)
		return 1;

	return 0;
}

int GptSanityCheck(GptData *gpt)
{
	int retval;
	GptHeader *header1 = (GptHeader *)(gpt->primary_header);
	GptHeader *header2 = (GptHeader *)(gpt->secondary_header);
	GptEntry *entries1 = (GptEntry *)(gpt->primary_entries);
	GptEntry *entries2 = (GptEntry *)(gpt->secondary_entries);
	GptHeader *goodhdr = NULL;

	gpt->valid_headers = 0;
	gpt->valid_entries = 0;
	gpt->ignored = 0;

	retval = CheckParameters(gpt);
	if (retval != GPT_SUCCESS)
		return retval;

	/* Check both headers; we need at least one valid header. */
	if (0 == CheckHeader(header1, 0, gpt->streaming_drive_sectors,
			     gpt->gpt_drive_sectors, gpt->flags,
			     gpt->sector_bytes)) {
		gpt->valid_headers |= MASK_PRIMARY;
		goodhdr = header1;
		if (0 == CheckEntries(entries1, goodhdr))
			gpt->valid_entries |= MASK_PRIMARY;
	} else if (header1 && !memcmp(header1->signature,
		   GPT_HEADER_SIGNATURE_IGNORED, GPT_HEADER_SIGNATURE_SIZE)) {
		gpt->ignored |= MASK_PRIMARY;
	}
	if (0 == CheckHeader(header2, 1, gpt->streaming_drive_sectors,
			     gpt->gpt_drive_sectors, gpt->flags,
			     gpt->sector_bytes)) {
		gpt->valid_headers |= MASK_SECONDARY;
		if (!goodhdr)
			goodhdr = header2;
		/* Check header1+entries2 if it was good, to catch mismatch. */
		if (0 == CheckEntries(entries2, goodhdr))
			gpt->valid_entries |= MASK_SECONDARY;
	} else if (header2 && !memcmp(header2->signature,
		   GPT_HEADER_SIGNATURE_IGNORED, GPT_HEADER_SIGNATURE_SIZE)) {
		gpt->ignored |= MASK_SECONDARY;
	}

	if (!gpt->valid_headers)
		return GPT_ERROR_INVALID_HEADERS;

	/*
	 * If both headers are good but neither entries were good, check the
	 * entries with the secondary header.
	 */
	if (MASK_BOTH == gpt->valid_headers && !gpt->valid_entries) {
		if (0 == CheckEntries(entries1, header2))
			gpt->valid_entries |= MASK_PRIMARY;
		if (0 == CheckEntries(entries2, header2))
			gpt->valid_entries |= MASK_SECONDARY;
		if (gpt->valid_entries) {
			/*
			 * Sure enough, header2 had a good CRC for one of the
			 * entries.  Mark header1 invalid, so we'll update its
			 * entries CRC.
			 */
			gpt->valid_headers &= ~MASK_PRIMARY;
			goodhdr = header2;
		}
	}

	if (!gpt->valid_entries)
		return GPT_ERROR_INVALID_ENTRIES;

	/*
	 * Now that we've determined which header contains a good CRC for
	 * the entries, make sure the headers are otherwise identical.
	 */
	if (MASK_BOTH == gpt->valid_headers &&
	    0 != HeaderFieldsSame(header1, header2))
		gpt->valid_headers &= ~MASK_SECONDARY;

	/*
	 * When we're ignoring a GPT, make it look in memory like the other one
	 * and pretend that everything is fine (until we try to save).
	 */
	if (MASK_NONE != gpt->ignored) {
		GptRepair(gpt);
		gpt->modified = 0;
	}

	return GPT_SUCCESS;
}

void GptRepair(GptData *gpt)
{
	GptHeader *header1 = (GptHeader *)(gpt->primary_header);
	GptHeader *header2 = (GptHeader *)(gpt->secondary_header);
	GptEntry *entries1 = (GptEntry *)(gpt->primary_entries);
	GptEntry *entries2 = (GptEntry *)(gpt->secondary_entries);
	int entries_size;

	/* Need at least one good header and one good set of entries. */
	if (MASK_NONE == gpt->valid_headers || MASK_NONE == gpt->valid_entries)
		return;

	/* Repair headers if necessary */
	if (MASK_PRIMARY == gpt->valid_headers) {
		/* Primary is good, secondary is bad */
		memcpy(header2, header1, sizeof(GptHeader));
		header2->my_lba = gpt->gpt_drive_sectors - GPT_HEADER_SECTORS;
		header2->alternate_lba = GPT_PMBR_SECTORS;  /* Second sector. */
		header2->entries_lba = header2->my_lba -
			CalculateEntriesSectors(header1, gpt->sector_bytes);
		header2->header_crc32 = HeaderCrc(header2);
		gpt->modified |= GPT_MODIFIED_HEADER2;
	}
	else if (MASK_SECONDARY == gpt->valid_headers) {
		/* Secondary is good, primary is bad */
		memcpy(header1, header2, sizeof(GptHeader));
		header1->my_lba = GPT_PMBR_SECTORS;  /* Second sector. */
		header1->alternate_lba =
			gpt->streaming_drive_sectors - GPT_HEADER_SECTORS;
		/* TODO (namnguyen): Preserve (header, entries) padding. */
		header1->entries_lba = header1->my_lba + 1;
		header1->header_crc32 = HeaderCrc(header1);
		gpt->modified |= GPT_MODIFIED_HEADER1;
	}
	gpt->valid_headers = MASK_BOTH;

	/* Repair entries if necessary */
	entries_size = header1->size_of_entry * header1->number_of_entries;
	if (MASK_PRIMARY == gpt->valid_entries) {
		/* Primary is good, secondary is bad */
		memcpy(entries2, entries1, entries_size);
		gpt->modified |= GPT_MODIFIED_ENTRIES2;
	}
	else if (MASK_SECONDARY == gpt->valid_entries) {
		/* Secondary is good, primary is bad */
		memcpy(entries1, entries2, entries_size);
		gpt->modified |= GPT_MODIFIED_ENTRIES1;
	}
	gpt->valid_entries = MASK_BOTH;
}

int GetEntryRequired(const GptEntry *e)
{
	return e->attrs.fields.required;
}

int GetEntryLegacyBoot(const GptEntry *e)
{
	return e->attrs.fields.legacy_boot;
}

int GetEntrySuccessful(const GptEntry *e)
{
	return (e->attrs.fields.gpt_att & CGPT_ATTRIBUTE_SUCCESSFUL_MASK) >>
		CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET;
}

int GetEntryPriority(const GptEntry *e)
{
	return (e->attrs.fields.gpt_att & CGPT_ATTRIBUTE_PRIORITY_MASK) >>
		CGPT_ATTRIBUTE_PRIORITY_OFFSET;
}

int GetEntryTries(const GptEntry *e)
{
	return (e->attrs.fields.gpt_att & CGPT_ATTRIBUTE_TRIES_MASK) >>
		CGPT_ATTRIBUTE_TRIES_OFFSET;
}

void SetEntryRequired(GptEntry *e, int required)
{
	e->attrs.fields.required = required;
}

void SetEntryLegacyBoot(GptEntry *e, int legacy_boot)
{
	e->attrs.fields.legacy_boot = legacy_boot;
}

void SetEntrySuccessful(GptEntry *e, int successful)
{
	if (successful)
		e->attrs.fields.gpt_att |= CGPT_ATTRIBUTE_SUCCESSFUL_MASK;
	else
		e->attrs.fields.gpt_att &= ~CGPT_ATTRIBUTE_SUCCESSFUL_MASK;
}

void SetEntryPriority(GptEntry *e, int priority)
{
	e->attrs.fields.gpt_att &= ~CGPT_ATTRIBUTE_PRIORITY_MASK;
	e->attrs.fields.gpt_att |=
		(priority << CGPT_ATTRIBUTE_PRIORITY_OFFSET) &
		CGPT_ATTRIBUTE_PRIORITY_MASK;
}

void SetEntryTries(GptEntry *e, int tries)
{
	e->attrs.fields.gpt_att &= ~CGPT_ATTRIBUTE_TRIES_MASK;
	e->attrs.fields.gpt_att |= (tries << CGPT_ATTRIBUTE_TRIES_OFFSET) &
		CGPT_ATTRIBUTE_TRIES_MASK;
}

void GetCurrentKernelUniqueGuid(GptData *gpt, void *dest)
{
	GptEntry *entries = (GptEntry *)gpt->primary_entries;
	GptEntry *e = entries + gpt->current_kernel;
	memcpy(dest, &e->unique, sizeof(Guid));
}

void GptModified(GptData *gpt) {
	GptHeader *header = (GptHeader *)gpt->primary_header;

	/* Update the CRCs */
	header->entries_crc32 = Crc32(gpt->primary_entries,
				      header->size_of_entry *
				      header->number_of_entries);
	header->header_crc32 = HeaderCrc(header);
	gpt->modified |= GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1;

	/*
	 * Use the repair function to update the other copy of the GPT.  This
	 * is a tad inefficient, but is much faster than the disk I/O to update
	 * the GPT on disk so it doesn't matter.
	 */
	gpt->valid_headers = MASK_PRIMARY;
	gpt->valid_entries = MASK_PRIMARY;
	GptRepair(gpt);
}


const char *GptErrorText(int error_code)
{
	switch(error_code) {
	case GPT_SUCCESS:
		return "none";

	case GPT_ERROR_NO_VALID_KERNEL:
		return "Invalid kernel";

	case GPT_ERROR_INVALID_HEADERS:
		return "Invalid headers";

	case GPT_ERROR_INVALID_ENTRIES:
		return "Invalid entries";

	case GPT_ERROR_INVALID_SECTOR_SIZE:
		return "Invalid sector size";

	case GPT_ERROR_INVALID_SECTOR_NUMBER:
		return "Invalid sector number";

	case GPT_ERROR_INVALID_UPDATE_TYPE:
		return "Invalid update type";

	case GPT_ERROR_CRC_CORRUPTED:
		return "Entries' crc corrupted";

	case GPT_ERROR_OUT_OF_REGION:
		return "Entry outside of valid region";

	case GPT_ERROR_START_LBA_OVERLAP:
		return "Starting LBA overlaps";

	case GPT_ERROR_END_LBA_OVERLAP:
		return "Ending LBA overlaps";

	case GPT_ERROR_DUP_GUID:
		return "Duplicated GUID";

	case GPT_ERROR_INVALID_FLASH_GEOMETRY:
		return "Invalid flash geometry";

	case GPT_ERROR_NO_SUCH_ENTRY:
		return "No entry found";

	default:
		break;
	};
	return "Unknown";
}
