/*
 * (C) Copyright 2000-2006
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

/*
 * Boot support
 */
#include <common.h>
#include <watchdog.h>
#include <driver.h>
#include <command.h>
#include <image.h>
#include <malloc.h>
#include <zlib.h>
#include <bzlib.h>
#include <environment.h>
#include <asm/byteorder.h>
#include <xfuncs.h>
#include <getopt.h>
#include <fcntl.h>
#include <fs.h>
#include <errno.h>
#include <boot.h>
#include <rtc.h>
#include <init.h>
#include <asm-generic/memory_layout.h>
#include <rsa_public_key.h>
#include <rsa_verify.h>
#include <sha1.h>
#include <secure_boot.h>
#include <antirebootloop.h>
#include <board_id.h>

#ifdef CONFIG_NAND_COMCERTO_ECC_HW_BCH
extern uint32_t temp_nand_ecc_errors[];
#endif
/*
 *  Continue booting an OS image; caller already has:
 *  - copied image header to global variable `header'
 *  - checked header magic number, checksums (both header & image),
 *  - verified image architecture (PPC) and type (KERNEL or MULTI),
 *  - loaded (first part of) image to header load address,
 *  - disabled interrupts.
 */
typedef void boot_os_Fcn(struct command *cmdtp, int flag,
			  int	argc, char *argv[],
			  ulong	addr,		/* of image to boot */
			  ulong	*len_ptr,	/* multi-file image length table */
			  int	verify);	/* getenv("verify")[0] != 'n' */

#ifndef CFG_BOOTM_LEN
#define CFG_BOOTM_LEN	0x800000	/* use 8MByte as default max gunzip size */
#endif

#ifdef CONFIG_SILENT_CONSOLE
static void
fixup_silent_linux ()
{
	char buf[256], *start, *end;
	char *cmdline = getenv ("bootargs");

	/* Only fix cmdline when requested */
	if (!(gd->flags & GD_FLG_SILENT))
		return;

	debug ("before silent fix-up: %s\n", cmdline);
	if (cmdline) {
		if ((start = strstr (cmdline, "console=")) != NULL) {
			end = strchr (start, ' ');
			strncpy (buf, cmdline, (start - cmdline + 8));
			if (end)
				strcpy (buf + (start - cmdline + 8), end);
			else
				buf[start - cmdline + 8] = '\0';
		} else {
			strcpy (buf, cmdline);
			strcat (buf, " console=");
		}
	} else {
		strcpy (buf, "console=");
	}

	setenv ("bootargs", buf);
	debug ("after silent fix-up: %s\n", buf);
}
#endif /* CONFIG_SILENT_CONSOLE */

int relocate_image(struct image_handle *handle, void *load_address)
{
	image_header_t *hdr = &handle->header;
	unsigned long len  = image_get_size(hdr);
	unsigned long data = (unsigned long)(handle->data);

#if defined CONFIG_CMD_BOOTM_ZLIB || defined CONFIG_CMD_BOOTM_BZLIB
	uint	unc_len = CFG_BOOTM_LEN;
#endif

	switch (image_get_comp(hdr)) {
	case IH_COMP_NONE:
		if(image_get_load(hdr) == data) {
			printf ("   XIP ... ");
		} else {
			memmove ((void *) image_get_load(hdr), (uchar *)data, len);
		}
		break;
#ifdef CONFIG_CMD_BOOTM_ZLIB
	case IH_COMP_GZIP:
		printf ("   Uncompressing ... ");
		if (gunzip (load_address, unc_len,
			    (uchar *)data, &len) != 0)
			return -1;
		break;
#endif
#ifdef CONFIG_CMD_BOOTM_BZLIB
	case IH_COMP_BZIP2:
		printf ("   Uncompressing ... ");
		/*
		 * If we've got less than 4 MB of malloc() space,
		 * use slower decompression algorithm which requires
		 * at most 2300 KB of memory.
		 */
		if (BZ2_bzBuffToBuffDecompress (load_address,
						&unc_len, (char *)data, len,
						MALLOC_SIZE < (4096 * 1024), 0)
						!= BZ_OK)
			return -1;
		break;
#endif
	default:
		printf("Unimplemented compression type %d\n",
		       image_get_comp(hdr));
		return -1;
	}

	return 0;
}
EXPORT_SYMBOL(relocate_image);

/*
 * Checks whether the kernel image is in legacy or current format.
 *
 * It is technically possible for an attacker to wait for this method
 * to be called, then to swap out the kernel image. However, that doesn't
 * gain them anything, except (probably) a failed boot.
 *
 * Returns 0 on success, non-zero on failure. The is_legacy parameter is set
 * to indicate whether or not the kernel image is a legacy one. (1: is legacy,
 * 0: is non-legacy).
 */
static int _check_if_legacy_kernel_image(const char *filename, int *is_legacy)
{
	int fd, rv = 0;
	uint8_t sb_header[SB_HEADER_LEN];

	*is_legacy = 0;

	fd = open(filename, O_RDONLY);
	if (fd < 0) {
		return -1;
	}

	if (read(fd, sb_header, SB_HEADER_LEN) != SB_HEADER_LEN) {
		rv = -1;
		goto end;
	}

	/*
	 * Unfortunately, I can only think of one check we can do to try and detect
	 * legacy kernel images, based on the header of the non-legacy format:
	 *
	 *   1. The header has 8 bytes of 0 padding at the end.
	 */

	if (_get_le_uint32(&sb_header[8]) != 0 ||
			_get_le_uint32(&sb_header[12]) != 0) {
		*is_legacy = 1;
	}

end:
	close(fd);

	return rv;
}

struct image_handle *map_image(const char *filename, int verify,
		int legacy_format, int secure_boot)
{
	int fd;
	uint32_t checksum, len;
	struct image_handle *handle;
	image_header_t *header;

	/* Used for secure boot. */
	sha1_context ctx;
	uint32_t total_image_len, sig_offset, verity_table_len;
	uint8_t sb_header[SB_HEADER_LEN], verity_info[SB_INFO_LEN], *verity_table;
	uint8_t hash[SHA1_SUM_LEN], sig[SB_SIG_LEN];

	fd = open(filename, O_RDONLY);
	if (fd < 0) {
		printf("could not open: %s\n", errno_str());
		return NULL;
	}

	handle = xzalloc(sizeof(struct image_handle) * 2);
	header = &handle->header;
	verity_table = NULL;

	if (legacy_format && secure_boot) {
		printf("Error: Cannot perform a secure boot of a legacy kernel image!\n");
		goto err_out;
	}

	if (!legacy_format) {
		if (secure_boot) {
			puts ("   Authenticating Image ... ");

			/*
			 * As the OS data is read in a piece at a time, into various structs, we
			 * construct the SHA data along the way and then verify it at the end.
			 */
			sha1_starts(&ctx);
		}

		if (read(fd, sb_header, SB_HEADER_LEN) != SB_HEADER_LEN) {
			printf("Could not read signature header!\n");
			goto err_out;
		}

		/* The verity header is currently unused, but is included in the hash. */
		if (read(fd, verity_info, SB_INFO_LEN) != SB_INFO_LEN) {
			printf("Could not read verity info!\n");
			goto err_out;
		}

		if (secure_boot) {
			sha1_update(&ctx, verity_info, SB_INFO_LEN);
		}
	}

	if (read(fd, header, image_get_header_size()) < 0) {
		printf("could not read: %s\n", errno_str());
		goto err_out;
	}

	if (secure_boot) {
		/* Do the SHA update before the CRC check, as CRC mutates the header. */
		sha1_update(&ctx, (uchar *) header, image_get_header_size());
	}

	if (image_get_magic(header) != IH_MAGIC) {
		puts ("\nBad OS Header Magic Number\n");
		goto err_out;
	}

	checksum = image_get_hcrc(header);
	header->ih_hcrc = 0;

	if (crc32 (0, (uchar *)header, image_get_header_size()) != checksum) {
		puts ("\nBad OS Header Checksum\n");
		goto err_out;
	}
	len  = image_get_size(header);

	if (!legacy_format) {
		/* In the non-legacy format, OS image (incl header) is 4096-byte padded. */
		len += image_get_header_size();
		len = ((len + 4095) / 4096) * 4096;
		len -= image_get_header_size();
	}

	handle->data = memmap(fd, PROT_READ);
	if (handle->data == (void *)-1) {
		handle->data = xmalloc(len);
		handle->flags = IH_MALLOC;
		if (read(fd, handle->data, len) < 0) {
			printf("could not read: %s\n", errno_str());
			goto err_out;
		}
	} else {
		handle->data = (void *)((unsigned long)handle->data +
						       SB_HEADER_LEN +
						       SB_INFO_LEN +
						       image_get_header_size());
	}

	if (!legacy_format) {
		/* The final piece of data to be read is the verity table. */
		total_image_len = _get_le_uint32(&sb_header[0]);
		verity_table_len = total_image_len - SB_INFO_LEN -
				image_get_header_size() - len;
		verity_table = xmalloc(verity_table_len);

		if (read(fd, verity_table, verity_table_len) != verity_table_len) {
			printf("\nCould not read verity table!\n");
			goto err_out;
		}

		if (secure_boot) {
			const struct rsa_public_key *public_key = NULL;

			/* Finish off the SHA-1 hash. */
			sha1_update(&ctx, handle->data, len);
			sha1_update(&ctx, verity_table, verity_table_len);
			sha1_finish(&ctx, hash);

			/* The signature can be found via an offset relative to the SB header end. */
			sig_offset = _get_le_uint32(&sb_header[4]);
			lseek(fd, SB_HEADER_LEN + sig_offset, SEEK_SET);
			if (read(fd, sig, SB_SIG_LEN) != SB_SIG_LEN) {
				printf("\nCould not read signature!\n");
				goto err_out;
			}

			if (rsa_get_public_key(OPTIMUS_BOARD_ID, &public_key) != 0) {
				printf("Could not get public key!\n");
				goto err_out;
			}

			if (rsa_verify(public_key, sig, SB_SIG_LEN, hash) != 0) {
				printf("Authentication failed!\n");
				goto err_out;
			}

			puts ("OK\n");
		}

		/*
		 * Slightly awkwardly, the OS CRC verification requires the original OS
		 * length, not the padded version length, so we have to restore it first.
		 */
		len = image_get_size(header);
	}

	if (verify) {
		puts ("   Verifying Checksum ... ");
		if (crc32 (0, handle->data, len) != image_get_dcrc(header)) {
			printf ("Bad Data CRC\n");

#ifdef CONFIG_NAND_COMCERTO_ECC_HW_BCH
			uint8_t i;
			for (i = 0; i < 4; i++)
				printf("temp_nand_ecc_errors[%d] = %d \n", i, temp_nand_ecc_errors[i]);
#endif
			goto err_out;
		}
		puts ("OK\n");
	}

	image_print_contents(header);

	close(fd);

	/*
	 * Multi-file uImage support.  If this is a multi-file uImage, then
	 * the header will say so, and the blobs in the file are in this
	 * predefined sequence: kernel, initrd, devicetree, [other...].
	 *
	 * The code above has already verified the checksum of the entire
	 * thing (ie. all blobs together) and loaded it all into a single
	 * RAM location.  Each blob in the file is already aligned to the
	 * nearest 32 bits.  So now we just need to appease the loader by
	 * producing one image_handle for each blob and creating "virtual"
	 * headers for each one.
	 *
	 * Earlier versions of this function returned only one handle.  Now
	 * we return an array of handles, terminated with a handle that
	 * is all-zeroes (in particular, the 'data' field is NULL).  Other
	 * than the code for unmap_image(), this is backward compatible with
	 * the old return value.
	 */
	if (image_get_type(header) == IH_TYPE_MULTI) {
		/*
		 * The bloblen section precedes the actual blobs.
		 * It's a series of 32-bit blob lengths, terminated
		 * by a 0.
		 */
		int numblobs, i, fixup;
		uint32_t *bloblen = handle->data, blobofs;

		printf("Multi-file uImage detected.\n");

		for (numblobs = 0; bloblen[numblobs]; numblobs++) { }
		if (!numblobs) {
			printf("Weird: multi-file image with zero blobs?\n");
			return handle;  /* leave header intact */
		}

		fixup = (numblobs + 1) * 4;
		blobofs = fixup;

		handle = xrealloc(handle,
			sizeof(struct image_handle) * (numblobs + 1));
		memset(&handle[1], 0,
			sizeof(struct image_handle) * numblobs);

		/*
		 * The kernel data area might be malloc'd, which means we
		 * can't just adjust handle[0].data to skip the bloblen[]
		 * header, because that would stop free() from working.
		 * Instead, move the load address backward so that the kernel
		 * itself will end up being loaded where it's supposed to be.
		 *
		 * We also have to set the size of the kernel to include
		 * the bloblen[] array.
		 */
		image_set_load(&handle[0].header,
			image_get_load(&handle[0].header) - fixup);
		image_set_size(&handle[0].header,
			uimage_to_cpu(bloblen[0]) + fixup);

		for (i = 0; i < numblobs; i++) {
			uint32_t type = 0;
			uint32_t len = uimage_to_cpu(bloblen[i]);
			if (i != 0) {
				memcpy(&handle[i], &handle[0],
					sizeof(handle[0]));
				handle[i].data = handle[0].data + blobofs;

				/*
				 * Blobs other than the first are not
				 * themselves separately malloc'd.
				 */
				handle[i].flags &= ~IH_MALLOC;

				/*
				 * The load address is only supplied for the
				 * first blob, which is the kernel. The others
				 * can be loaded anywhere; just set the load
				 * address to indicate their current location.
				 *
				 * NOTE(apenwarr): Sensitive to memory map.
				 * The ARM kernel (at least) writes over
				 * very low memory, plus memory right after
				 * the kernel image, during boot.  This code
				 * works only because in our situation we
				 * put the malloc() area fairly high in RAM,
				 * which the kernel doesn't overwrite until
				 * it finishes extracting the initrd.
				 */
				image_set_load(&handle[i].header,
					(uint32_t)handle[i].data);
				image_set_size(&handle[i].header, len);
				image_set_ep(&handle[i].header, 0);
			}

			switch (i) {
			case 0: type = IH_TYPE_KERNEL; break;
			case 1: type = IH_TYPE_RAMDISK; break;
			case 2: type = IH_TYPE_FLATDT; break;
			default: type= IH_TYPE_INVALID; break;
			}
			image_set_type(&handle[i].header, type);

			printf("Blob #%d: load=%08x len=%08x ptr=%p %s\n", i,
				image_get_load(&handle[i].header),
				image_get_size(&handle[i].header),
				handle[i].data,
				image_get_type_name(
					image_get_type(&handle[i].header)));

			/* all blobs are 32-bit aligned */
			blobofs += (len + 3) & ~3;
		}
	}

	return handle;
err_out:
	close(fd);
	if (handle->flags & IH_MALLOC)
		free(handle->data);
	free(handle);
	if (verity_table)
		free(verity_table);
	return NULL;
}
EXPORT_SYMBOL(map_image);

void unmap_image(struct image_handle *handle)
{
	struct image_handle *first_handle = handle;
	while (handle->data) {
		if (handle->flags & IH_MALLOC)
			free(handle->data);
		handle->data = NULL;
		handle++;
	}
	free(first_handle);
}
EXPORT_SYMBOL(unmap_image);

static LIST_HEAD(handler_list);

int register_image_handler(struct image_handler *handler)
{
	list_add_tail(&handler->list, &handler_list);
	return 0;
}

static int initrd_handler_parse_options(struct image_data *data, int opt,
		char *optarg)
{
	switch(opt) {
	case 'r':
		printf("use initrd %s\n", optarg);
		data->initrd = map_image(optarg, data->verify, 1, 0);
		if (!data->initrd)
			return -1;
		return 0;
	default:
		return 1;
	}
}

static struct image_handler initrd_handler = {
	.cmdline_options = "r:",
	.cmdline_parse = initrd_handler_parse_options,
	.help_string = " -r <initrd>    specify an initrd image",
};

static int initrd_register_image_handler(void)
{
	return register_image_handler(&initrd_handler);
}

late_initcall(initrd_register_image_handler);

static int handler_parse_options(struct image_data *data, int opt, char *optarg)
{
	struct image_handler *handler;
	int ret;

	list_for_each_entry(handler, &handler_list, list) {
		if (!handler->cmdline_parse)
			continue;

		ret = handler->cmdline_parse(data, opt, optarg);
		if (ret > 0)
			continue;

		return ret;
	}

	return -1;
}

static int do_bootm(struct command *cmdtp, int argc, char *argv[])
{
	ulong	iflag;
	int	opt, secure_boot, legacy_format;
	image_header_t *os_header;
	struct image_handle *os_handle = NULL, *initrd_handle = NULL;
	struct image_handler *handler;
	struct image_data data;
	char options[53]; /* worst case: whole alphabet with colons */
#if !(defined(CONFIG_FORCE_KERNEL_AUTH) || defined(CONFIG_DEVELOPER_BAREBOX))
	secure_boot_mode_t boot_mode;
#endif

	memset(&data, 0, sizeof(struct image_data));
	data.verify = 1;

	/* Collect options from registered handlers */
	strcpy(options, "nh");
	list_for_each_entry(handler, &handler_list, list) {
		if (handler->cmdline_options)
			strcat(options, handler->cmdline_options);
	}

	while((opt = getopt(argc, argv, options)) > 0) {
		switch(opt) {
		case 'n':
			data.verify = 0;
			break;
		case 'h':
			printf("bootm advanced options:\n");

			list_for_each_entry(handler, &handler_list, list) {
				if (handler->help_string)
					printf("%s\n", handler->help_string);
			}

			return 0;
		default:
			if (!handler_parse_options(&data, opt, optarg))
				continue;

			return 1;
		}
	}

	if (optind == argc)
		return COMMAND_ERROR_USAGE;

#ifdef CONFIG_FORCE_KERNEL_AUTH
	printf("Secure boot forced; will authenticate kernel.\n");
	secure_boot = 1;
#elif defined(CONFIG_DEVELOPER_BAREBOX)
	printf("Developer barebox detected; will not authenticate kernel.\n");
	secure_boot = 0;
#else
	boot_mode = get_secure_boot_mode();
	if (boot_mode == UNKNOWN) {
		printf("Error: Unable to determine secure boot status!\n");
		return 1;
	}
	secure_boot = (boot_mode == SECURE);
#endif

	if (_check_if_legacy_kernel_image(argv[optind], &legacy_format)) {
		printf("Error: Unable to determine whether kernel is legacy/non-legacy!\n");
		return 1;
	}

	os_handle = map_image(argv[optind], data.verify, legacy_format, secure_boot);
	if (!os_handle)
		return 1;
	data.os = os_handle;
	if (!data.initrd && os_handle[1].data)
		data.initrd = &os_handle[1];

	os_header = &os_handle->header;

	if (image_get_arch(os_header) != IH_ARCH) {
		printf("Unsupported Architecture 0x%x\n",
		       image_get_arch(os_header));
		goto err_out;
	}

	/*
	 * We have reached the point of no return: we are going to
	 * overwrite all exception vector code, so we cannot easily
	 * recover from any failures any more...
	 */

	iflag = disable_interrupts();

	puts ("OK\n");

#ifdef CONFIG_ANTIREBOOTLOOP
	antirebootloop_preboot_hook();
#endif

	/* loop through the registered handlers */
	list_for_each_entry(handler, &handler_list, list) {
		if (image_get_os(os_header) == handler->image_type) {
			handler->bootm(&data);
			printf("handler returned!\n");
			goto err_out;
		}
	}

	printf("no image handler found for image type %d\n",
	       image_get_os(os_header));

err_out:
	if (os_handle)
		unmap_image(os_handle);
	if (initrd_handle)
		unmap_image(initrd_handle);
	return 1;
}

BAREBOX_CMD_HELP_START(bootm)
BAREBOX_CMD_HELP_USAGE("bootm [-n] image\n")
BAREBOX_CMD_HELP_SHORT("Boot an application image.\n")
BAREBOX_CMD_HELP_OPT  ("-n",  "Do not verify the image (speeds up boot process)\n")
BAREBOX_CMD_HELP_END

BAREBOX_CMD_START(bootm)
	.cmd		= do_bootm,
	.usage		= "boot an application image",
	BAREBOX_CMD_HELP(cmd_bootm_help)
BAREBOX_CMD_END

/**
 * @page bootm_command

\todo What does bootm do, what kind of image does it boot?

 */

#ifdef CONFIG_CMD_IMI
static int do_iminfo(struct command *cmdtp, int argc, char *argv[])
{
	int	arg;
	ulong	addr;
	int     rcode=0;

	if (argc < 2) {
		return image_info (load_addr);
	}

	for (arg=1; arg <argc; ++arg) {
		addr = simple_strtoul(argv[arg], NULL, 16);
		if (image_info (addr) != 0) rcode = 1;
	}
	return rcode;
}

static int image_info (ulong addr)
{
	ulong	data, len, checksum;
	image_header_t *hdr = &header;

	printf ("\n## Checking Image at %08lx ...\n", addr);

	/* Copy header so we can blank CRC field for re-calculation */
	memmove (&header, (char *)addr, image_get_header_size());

	if (image_get_magic(hdr) != IH_MAGIC) {
		puts ("   Bad Magic Number\n");
		return 1;
	}

	data = (ulong)&header;
	len  = image_get_header_size();

	checksum = image_get_hcrc(hdr);
	hdr->ih_hcrc = 0;

	if (crc32 (0, (uchar *)data, len) != checksum) {
		puts ("   Bad Header Checksum\n");
		return 1;
	}

	/* for multi-file images we need the data part, too */
	print_image_hdr ((image_header_t *)addr);

	data = addr + image_get_header_size();
	len  = image_get_size(hdr);

	puts ("   Verifying Checksum ... ");
	if (crc32 (0, (uchar *)data, len) != image_get_dcrc(hdr)) {
		puts ("   Bad Data CRC\n");
		return 1;
	}
	puts ("OK\n");
	return 0;
}

BAREBOX_CMD_HELP_START(iminfo)
BAREBOX_CMD_HELP_USAGE("iminfo\n")
BAREBOX_CMD_HELP_SHORT("Print header information for an application image.\n")
BAREBOX_CMD_HELP_END

BAREBOX_CMD_START(iminfo)
	.cmd		= do_iminfo,
	.usage		= "print header information for an application image",
	BAREBOX_CMD_HELP(cmd_iminfo_help)
BAREBOX_CMD_END

#endif	/* CONFIG_CMD_IMI */

#ifdef CONFIG_BZLIB
void bz_internal_error(int errcode)
{
	printf ("BZIP2 internal error %d\n", errcode);
}
#endif /* CONFIG_BZLIB */

/**
 * @file
 * @brief Boot support for Linux
 */

/**
 * @page boot_preparation Preparing for Boot
 *
 * This chapter describes what's to be done to forward the control from
 * barebox to Linux. This part describes the generic part, below you can find
 * the architecture specific part.
 *
 * - @subpage arm_boot_preparation
 * - @subpage ppc_boot_preparation
 * - @subpage x86_boot_preparation
 */
