/*
 * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * 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.
 */

#include <sysupgrade.h>

#define SBL_VERSION_FILE       "sbl_version"
#define TZ_VERSION_FILE        "tz_version"
#define HLOS_VERSION_FILE      "hlos_version"
#define APPSBL_VERSION_FILE    "appsbl_version"
#define RPM_VERSION_FILE       "rpm_version"
#define DEVCFG_VERSION_FILE	"devcfg_version"
#define VERSION_FILE_BASENAME  "/sys/devices/system/qfprom/qfprom0/"
#define AUTHENTICATE_FILE	"/sys/devices/system/qfprom/qfprom0/authenticate"
#define SEC_AUTHENTICATE_FILE  "/sys/sec_upgrade/sec_auth"
#define TEMP_KERNEL_PATH	"/tmp/tmp_kernel.bin"
#define MAX_SBL_VERSION	11
#define MAX_HLOS_VERSION	32
#define MAX_TZ_VERSION		14
#define MAX_APPSBL_VERSION	14
#define MAX_RPM_VERSION	8
#define MAX_DEVCFG_VERSION	11
#define HASH_P_FLAG		0x02200000
#define TMP_FILE_DIR		"/tmp/"
#define CERT_SIZE		2048
#define PRESENT		1
#define MBN_HDR_SIZE		40
#define SBL_HDR_SIZE		80
#define SIG_SIZE		256
#define NOT_PRESENT		0
#define SIG_CERT_2_SIZE	4352
#define SIG_CERT_3_SIZE	6400
#define SBL_NAND_PREAMBLE	10240
#define SBL_HDR_RESERVED	12
#define UBI_EC_HDR_MAGIC  0x55424923
#define UBI_VID_HDR_MAGIC 0x55424921

struct image_section sections[] = {
	{
		.section_type		= UBOOT_TYPE,
		.type			= "u-boot",
		.max_version		= MAX_APPSBL_VERSION,
		.file			= TMP_FILE_DIR,
		.version_file		= APPSBL_VERSION_FILE,
		.is_present		= NOT_PRESENT,
		.img_code		= "0x9"
	},
	{
		.section_type		= HLOS_TYPE,
		.type			= "hlos",
		.max_version		= MAX_HLOS_VERSION,
		.file			= TMP_FILE_DIR,
		.version_file		= HLOS_VERSION_FILE,
		.is_present		= NOT_PRESENT,
		.img_code		= "0x17"
	},
	{
		.section_type		= HLOS_TYPE,
		.type			= "ubi",
		.tmp_file		= TMP_FILE_DIR,
		.pre_op			= extract_kernel_binary,
		.max_version		= MAX_HLOS_VERSION,
		.file			= TEMP_KERNEL_PATH,
		.version_file		= HLOS_VERSION_FILE,
		.is_present		= NOT_PRESENT,
		.img_code		= "0x17"
	},
	{
		.section_type		= TZ_TYPE,
		.type			= "tz",
		.max_version		= MAX_TZ_VERSION,
		.file			= TMP_FILE_DIR,
		.version_file		= TZ_VERSION_FILE,
		.is_present		= NOT_PRESENT,
		.img_code		= "0x7"
	},
	{
		.section_type		= SBL_TYPE,
		.type			= "sbl1",
		.max_version		= MAX_SBL_VERSION,
		.file			= TMP_FILE_DIR,
		.version_file		= SBL_VERSION_FILE,
		.is_present		= NOT_PRESENT,
		.img_code		= "0x0"
	},
	{
		.section_type		= SBL_TYPE,
		.type			= "sbl2",
		.max_version		= MAX_SBL_VERSION,
		.file			= TMP_FILE_DIR,
		.version_file		= SBL_VERSION_FILE,
		.is_present		= NOT_PRESENT,
		.img_code		= "0x5"
	},
	{
		.section_type		= SBL_TYPE,
		.type			= "sbl3",
		.max_version		= MAX_SBL_VERSION,
		.file			= TMP_FILE_DIR,
		.version_file		= SBL_VERSION_FILE,
		.is_present		= NOT_PRESENT,
		.img_code		= "0x6"
	},
	{
		.section_type		= RPM_TYPE,
		.type			= "rpm",
		.max_version		= MAX_RPM_VERSION,
		.file			= TMP_FILE_DIR,
		.version_file		= RPM_VERSION_FILE,
		.is_present		= NOT_PRESENT,
		.img_code		= "0xA"
	},
	{
		.section_type		= DEVCFG_TYPE,
		.type			= "devcfg",
		.max_version		= MAX_DEVCFG_VERSION,
		.file			= TMP_FILE_DIR,
		.version_file		= DEVCFG_VERSION_FILE,
		.is_present		= NOT_PRESENT,
		.img_code		= "0x5"
	},
};

#define NO_OF_SECTIONS	ARRAY_SIZE(sections)
int src_size;

int check_mbn_elf(struct image_section **sec)
{
	int fd = open((*sec)->file, O_RDONLY);
	struct stat sb;
	uint8_t *fp;
	Elf32_Ehdr *elf;

	if (fd < 0) {
		perror((*sec)->file);
		return 0;
	}

	memset(&sb, 0, sizeof(struct stat));
	if (fstat(fd, &sb) == -1) {
		perror("fstat");
		close(fd);
		return 0;
	}

	fp = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
	if (fp == MAP_FAILED) {
		perror("mmap");
		close(fd);
		return 0;
	}

	elf = (Elf32_Ehdr *)fp;
	if (!strncmp((char *)&(elf->e_ident[1]), "ELF", 3)) {
		/* EI_CLASS Check for 32/64-bit */
		if( ((int)(elf->e_ident[4])) == 2) {
			(*sec)->get_sw_id = get_sw_id_from_component_bin_elf64;
			(*sec)->split_components = split_code_signature_cert_from_component_bin_elf64;
		} else {
			(*sec)->get_sw_id = get_sw_id_from_component_bin_elf;
			(*sec)->split_components = split_code_signature_cert_from_component_bin_elf;
		}
	} else if (!strncmp((char *)&(((Elf32_Ehdr *)(fp + SBL_NAND_PREAMBLE))->e_ident[1]), "ELF", 3)) {
		if( ((int)(elf->e_ident[4])) == 2) {
			(*sec)->get_sw_id = get_sw_id_from_component_bin_elf64;
			(*sec)->split_components = split_code_signature_cert_from_component_bin_elf64;
		} else {
			(*sec)->get_sw_id = get_sw_id_from_component_bin_elf;
			(*sec)->split_components = split_code_signature_cert_from_component_bin_elf;
		}
	} else {
		(*sec)->get_sw_id = get_sw_id_from_component_bin;
		(*sec)->split_components = split_code_signature_cert_from_component_bin;
	}

	return 1;
}

int get_sections(void)
{
	DIR *dir = opendir(TMP_FILE_DIR);
	struct dirent *file;
	int i,data_size;
	struct image_section *sec;

	if (dir == NULL) {
		printf("Error accessing the image directory\n");
		return 0;
	}

	data_size = find_mtd_part_size();
	while ((file = readdir(dir)) != NULL) {
		for (i = 0, sec = &sections[0]; i < NO_OF_SECTIONS; i++, sec++) {
			/* Skip loading of ubi section if board is not from nand boot */
			if (data_size == -1 && !strncmp(sec->type, "ubi", strlen("ubi")))
				continue;
			if (!strncmp(file->d_name, sec->type, strlen(sec->type))) {
				if (sec->pre_op) {
					strlcat(sec->tmp_file, file->d_name,
							sizeof(sec->tmp_file));
					if (!sec->pre_op(sec)) {
						printf("Error extracting kernel from ubi\n");
						return 0;
					}
				} else {
					strlcat(sec->file, file->d_name,
							sizeof(sec->file));
				}
				if (!check_mbn_elf(&sec)) {
					closedir(dir);
					return 0;
				}
				if (!sec->get_sw_id(sec)) {
					closedir(dir);
					return 0;
				}
				get_local_image_version(sec);
				sec->is_present = PRESENT;
				break;
			}
		}
	}
	closedir(dir);
	return 1;
}

int load_sections(void)
{
	DIR *dir;
	int i,data_size;
	struct dirent *file;
	struct image_section *sec;

	dir = opendir(TMP_FILE_DIR);
	if (dir == NULL) {
		printf("Error accessing the %s image directory\n", TMP_FILE_DIR);
		return 0;
	}

	data_size = find_mtd_part_size();
	while ((file = readdir(dir)) != NULL) {
		for (i = 0, sec = &sections[0]; i < NO_OF_SECTIONS; i++, sec++) {
			/* Skip loading of ubi section if board is not from nand boot */
			if (data_size == -1 && !strncmp(sec->type, "ubi", strlen("ubi")))
				continue;
			if (!strncmp(file->d_name, sec->type, strlen(sec->type))) {
				if (sec->pre_op) {
					strlcat(sec->tmp_file, file->d_name,
							sizeof(sec->tmp_file));
					if (!sec->pre_op(sec)) {
						printf("Error extracting %s from ubi\n",
									   sec->tmp_file);
						closedir(dir);
						return 0;
					}
				} else {
					strlcat(sec->file, file->d_name,
							sizeof(sec->file));
				}
				sec->is_present = PRESENT;
				break;
			}
		}
	}
	closedir(dir);
	return 1;
}

/**
 * is_authentication_check_enabled() - checks whether installed image is
 * secure(1) or not(0)
 *
 */
int is_authentication_check_enabled(void)
{
	int fd = open(AUTHENTICATE_FILE, O_RDONLY);
	char authenticate_string[4];
	int len;

	if (fd == -1) {
		perror(AUTHENTICATE_FILE);
		return 0;
	}

	len = read(fd, authenticate_string, 1);
	close(fd);

	if (len > 0 && authenticate_string[0] == '0') {
		return 0;
	}

	return 1;
}

int is_tz_authentication_enabled(void)
{
	struct stat sb;

	if (stat(SEC_AUTHENTICATE_FILE, &sb) == -1) {
		perror("stat");
		return 0;
	}
	return 1;
}

/**
 * get_local_image_version() check the version file & if it exists, read the
 * value & save it into global variable local_version
 *
 */
int get_local_image_version(struct image_section *section)
{
	int len, fd;
	char local_version_string[16], version_file[64];
	struct stat st;

	snprintf(version_file, sizeof(version_file), "%s%s", VERSION_FILE_BASENAME, section->version_file);
	fd = open(version_file, O_RDONLY);
	if (fd == -1) {
		perror(version_file);
		return 0;
	}

	memset(&st, 0, sizeof(struct stat));
	fstat(fd, &st);

	len = st.st_size < sizeof(local_version_string) - 1 ? st.st_size :
							sizeof(local_version_string) - 1;
	if (read(fd, local_version_string, len) == -1) {
		close(fd);
		return 0;
	}
	local_version_string[len] = '\0';
	close(fd);

	section->local_version = atoi(local_version_string);
	printf("Local image version:%s\n", local_version_string);

	return 1;
}

/**
 * set_local_image_version() update the version of the image by writing the version
 * to the version file
 *
 */
int set_local_image_version(struct image_section *section)
{
	int fd;
	char version_string[16], version_file[64];
	int len;

	snprintf(version_file, sizeof(version_file), "%s%s", TMP_FILE_DIR, section->version_file);
	fd = open(version_file, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
	if (fd == -1) {
		perror(version_file);
		return 0;
	}

	len = snprintf(version_string, 8, "%d", section->img_version);
	if (len < 0) {
		printf("Error in formatting the version string");
		return 0;
	}

	printf("Version to be updated:%s\n", version_string);
	if (write(fd, version_string, len) == -1) {
		printf("Error writing version to %s\n", version_file);
		close(fd);
		return 0;
	}

	close(fd);
	return 1;
}

/**
 * is_version_check_enabled() checks whether version check is
 * enabled(non-zero value) or not
 *
 */
int is_version_check_enabled()
{
	if (get_local_image_version(&sections[0]) != -1) {
		printf("Returning 1 from is_version_check_enabled because local_version_string is non-ZERO\n");
		return 1;
	}

	return 0;
}

char *find_value(char *buffer, char *search, int size)
{
	char *value = malloc(size * sizeof(char));
	int i, j;

	if (value == NULL) {
		return NULL;
	}

	for (i = 0; i < CERT_SIZE; i++) {
		for (j = 0; search[j] && (buffer[i + j] == search[j]); j++);
		if (search[j] == '\0') {
			strlcpy(value, &buffer[i - size], size);
			value[size - 1] = '\0';
			return value;
		}
	}
	free(value);
	return NULL;
}

/**
 * check_nand_preamble() compares first 12 bytes of section with
 * pre defined PREAMBLE value and returns 0 if both value matches
 */
int check_nand_preamble(uint8_t *mfp)
{
	char magic[12] = { 0xd1, 0xdc, 0x4b, 0x84,
			   0x34, 0x10, 0xd7, 0x73,
			   0x5a, 0x43, 0x0b, 0x7d };
	return memcmp(magic, mfp, sizeof(magic));
}

/**
 * get_sw_id_from_component_bin() parses the MBN header & checks image size v/s
 * code size. If both differ, it means signature & certificates are
 * appended at end.
 * Extract the attestation certificate & read the Subject & retreive the SW_ID.
 *
 * @bin_file: struct image_section *
 */
int get_sw_id_from_component_bin(struct image_section *section)
{
	Mbn_Hdr *mbn_hdr;
	int fd = open(section->file, O_RDONLY);
	struct stat sb;
	uint8_t *fp;
	int cert_offset;
	char *sw_version;
	int sig_cert_size;

	if (fd == -1) {
		perror(section->file);
		return 0;
	}

	memset(&sb, 0, sizeof(struct stat));
	if (fstat(fd, &sb) == -1) {
		perror("fstat");
		close(fd);
		return 0;
	}

	fp = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
	if (fp == MAP_FAILED) {
		perror("mmap");
		close(fd);
		return 0;
	}

	mbn_hdr = (Mbn_Hdr *)fp;
	if (strstr(section->file, sections[4].type)) {
		uint32_t preamble = !check_nand_preamble(fp) ? SBL_NAND_PREAMBLE : 0;
		Sbl_Hdr *sbl_hdr = (Sbl_Hdr *)(fp + preamble);

		sig_cert_size = sbl_hdr->image_size - sbl_hdr->code_size;
		cert_offset = preamble + sbl_hdr->cert_ptr - sbl_hdr->image_dest_ptr +
				SBL_HDR_SIZE;
	} else {
		sig_cert_size = mbn_hdr->image_size - mbn_hdr->code_size;
		cert_offset = mbn_hdr->cert_ptr - mbn_hdr->image_dest_ptr + 40;
	}
	if (sig_cert_size != SIG_CERT_2_SIZE && sig_cert_size != SIG_CERT_3_SIZE) {
		printf("WARNING: signature certificate size is different\n");
		// ipq807x has certificate size as dynamic, hence ignore this check
	}

	printf("Image with version information\n");
	sw_version = find_value((char *)(fp + cert_offset), "SW_ID", 17);
	if (sw_version != NULL) {
		sw_version[8] = '\0';
		sscanf(sw_version, "%x", &section->img_version);
		printf("SW ID:%d\n", section->img_version);
		free(sw_version);
	}

	close(fd);
	return 1;
}

int process_elf(char *bin_file, uint8_t **fp, Elf32_Ehdr **elf, Elf32_Phdr **phdr, Mbn_Hdr **mbn_hdr)
{
	int fd = open(bin_file, O_RDONLY);
	struct stat sb;
	int version = 0;
	int i = 0;

	if (fd < 0) {
		perror(bin_file);
		return 0;
	}

	memset(&sb, 0, sizeof(struct stat));
	if (fstat(fd, &sb) == -1) {
		perror("fstat");
		close(fd);
		return 0;
	}

	*fp = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
	if (*fp == MAP_FAILED) {
		perror("mmap");
		close(fd);
		return 0;
	}

	*elf = (Elf32_Ehdr *)*fp;
	while (strncmp((char *)&((*elf)->e_ident[1]), "ELF", 3)) {
		*fp = (uint8_t *)((char *)(*fp) + SBL_NAND_PREAMBLE);
		*elf = (Elf32_Ehdr *)*fp;
	}

	*phdr = (Elf32_Phdr *)(*fp + (*elf)->e_phoff);
	for (i = 0; i < (*elf)->e_phnum; i++, (*phdr)++) {
		if ((*phdr)->p_flags == HASH_P_FLAG) {
			*mbn_hdr = (Mbn_Hdr *)(*fp + (*phdr)->p_offset);
			if ((*mbn_hdr)->image_size != (*mbn_hdr)->code_size) {
				version = 1;
				break;
			} else {
				printf("Error: Image without version information\n");
				close(fd);
				return 0;
			}
		}
	}

	if (version != 1) {
		printf("Error: Image without version information\n");
		return 0;
	}

	close(fd);
	return 1;
}

int process_elf64(char *bin_file, uint8_t **fp, Elf64_Ehdr **elf, Elf64_Phdr **phdr, Mbn_Hdr **mbn_hdr)
{
	struct stat sb;
	int i, fd, version = 0;

	fd = open(bin_file, O_RDONLY);
	if (fd < 0) {
		perror(bin_file);
		return 0;
	}

	memset(&sb, 0, sizeof(struct stat));
	if (fstat(fd, &sb) == -1) {
		perror("fstat");
		close(fd);
		return 0;
	}

	*fp = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
	if (*fp == MAP_FAILED) {
		perror("mmap");
		close(fd);
		return 0;
	}

	*elf = (Elf64_Ehdr *)*fp;
	while (strncmp((char *)&((*elf)->e_ident[1]), "ELF", 3)) {
		*fp = (uint8_t *)((char *)(*fp) + SBL_NAND_PREAMBLE);
		*elf = (Elf64_Ehdr *)*fp;
	}

	*phdr = (Elf64_Phdr *)(*fp + (*elf)->e_phoff);
	for (i = 0; i < (*elf)->e_phnum; i++, (*phdr)++) {
		if ((*phdr)->p_flags == HASH_P_FLAG) {
			*mbn_hdr = (Mbn_Hdr *)(*fp + (*phdr)->p_offset);
			if ((*mbn_hdr)->image_size != (*mbn_hdr)->code_size) {
				version = 1;
				break;
			} else {
				printf("Error: Image without version information\n");
				close(fd);
				return 0;
			}
		}
	}

	if (version != 1) {
		printf("Error: Image without version information\n");
		return 0;
	}

	close(fd);
	return 1;
}

/**
 * get_sw_id_from_component_bin_elf() parses the ELF header to get the MBN header
 * of the hash table segment. Parses the MBN header of hash table segment & checks
 * total size v/s actual component size. If both differ, it means signature &
 * certificates are appended at end.
 * Extract the attestation certificate & read the Subject & retreive the SW_ID.
 *
 * @bin_file: struct image_section *
 */
int get_sw_id_from_component_bin_elf(struct image_section *section)
{
	Elf32_Ehdr *elf;
	Elf32_Phdr *phdr;
	Mbn_Hdr *mbn_hdr;
	uint8_t *fp;
	int cert_offset;
	char *sw_version;

	if (!process_elf(section->file, &fp, &elf, &phdr, &mbn_hdr)) {
		return 0;
	}

	cert_offset = mbn_hdr->cert_ptr - mbn_hdr->image_dest_ptr + 40;
	printf("Image with version information\n");
	sw_version = find_value((char *)(fp + phdr->p_offset + cert_offset), "SW_ID", 17);
	if (sw_version) {
		sw_version[8] = '\0';
		sscanf(sw_version, "%x", &section->img_version);
		printf("SW ID:%d\n", section->img_version);
		free(sw_version);
	}

	return 1;
}

/**
 * get_sw_id_from_component_bin_elf64() parses the ELF64 header to get the MBN header
 * of the hash table segment. Parses the MBN header of hash table segment & checks
 * total size v/s actual component size. If both differ, it means signature &
 * certificates are appended at end.
 * Extract the attestation certificate & read the Subject & retreive the SW_ID.
 *
 32_Phdr *phdr;* @bin_file: struct image_section *
 */
int get_sw_id_from_component_bin_elf64(struct image_section *section)
{
	Elf64_Ehdr *elf;
	Elf64_Phdr *phdr;
	Mbn_Hdr *mbn_hdr;
	uint8_t *fp;
	int cert_offset;
	char *sw_version;

	if (!process_elf64(section->file, &fp, &elf, &phdr, &mbn_hdr)) {
		return 0;
	}

	cert_offset = mbn_hdr->code_size + mbn_hdr->sig_sz + 40;
	printf("Image with version information64\n");
	sw_version = find_value((char *)(fp + phdr->p_offset + cert_offset), "SW_ID", 17);
	if (sw_version) {
		sw_version[8] = '\0';
		sscanf(sw_version, "%x", &section->img_version);
		printf("SW ID:%d\n", section->img_version);
		free(sw_version);
	}

	return 1;
}

int find_mtd_part_size(void)
{
	char *mtdname = "kernel";
	char prefix[] = "/dev/mtd";
	char dev[PATH_MAX];
	int i = -1, fd;
	int vol_size;
	int flag = 0;
	char mtd_part[256];
	FILE *fp = fopen("/proc/mtd", "r");
	mtd_info_t mtd_dev_info;

	if (fp == NULL) {
		printf("Error finding mtd part\n");
		return -1;
	}

	while (fgets(dev, sizeof(dev), fp)) {
		if (strstr(dev, mtdname)) {
			flag = 1;
			break;
		}
		i++;
	}
	fclose(fp);

	if (flag != 1) {
		printf("%s block not found\n", mtdname);
		return -1;
	}

	snprintf(mtd_part, sizeof(mtd_part), "%s%d", prefix, i);

	fd = open(mtd_part, O_RDWR);
	if (fd == -1) {
		return -1;
	}

	if (ioctl(fd, MEMGETINFO, &mtd_dev_info) == -1) {
		printf("Error getting block size\n");
		close(fd);
		return -1;
	}

	vol_size = mtd_dev_info.erasesize;
	close(fd);

	return vol_size;
}

/**
 * In case of NAND image, Kernel image is ubinized & version information is
 * part of Kernel image. Hence need to un-ubinize the image.
 * To get the kernel image, Find the volume with volume id 0. Kernel image
 * is fragmented and hence to assemble it to get complete image.
 * In UBI image, first look for UBI#, which is magic number used to identify
 * each eraseble block. Parse the UBI header, which starts with UBI# & get
 * the VID(volume ID) header offset as well as Data offset.
 * Traverse to VID header offset & check the volume ID. If it is ZERO, Kernel
 * image is stored in this volume. Use Data offset to extract the Kernel image.
 *
 * @bin_file: struct image_section *
 */
int extract_kernel_binary(struct image_section *section)
{
	struct ubi_ec_hdr *ubi_ec;
	struct ubi_vid_hdr *ubi_vol;
	uint8_t *fp;
	int fd, ofd, magic, data_size, vid_hdr_offset, data_offset;
	struct stat sb;

	fd = open(section->tmp_file, O_RDONLY);
	if (fd < 0) {
		perror(section->tmp_file);
		return 0;
	}

	memset(&sb, 0, sizeof(struct stat));
	if (fstat(fd, &sb) == -1) {
		perror("fstat");
		close(fd);
		return 0;
	}

	fp = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
	if (fp == MAP_FAILED) {
		perror("mmap");
		close(fd);
		return 0;
	}

	ofd = open(section->file, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
	if (ofd == -1) {
		perror(section->file);
		close(fd);
		return 0;
	}

	data_size = find_mtd_part_size();
	if (data_size == -1) {
		printf("Error finding data size\n");
		return 0;
	}

	ubi_ec = (struct ubi_ec_hdr *)fp;
	magic = be32_to_cpu(ubi_ec->magic);
	while (magic == UBI_EC_HDR_MAGIC) {
		vid_hdr_offset = be32_to_cpu(ubi_ec->vid_hdr_offset);
		data_offset = be32_to_cpu(ubi_ec->data_offset);
		ubi_vol = (struct ubi_vid_hdr *)((uint8_t *)ubi_ec + vid_hdr_offset);
		magic = be32_to_cpu(ubi_vol->magic);
		if (magic != UBI_VID_HDR_MAGIC) {
			printf("Wrong ubi format\n");
			close(ofd);
			close(fd);
			return 0;
		}

		if (ubi_vol->vol_id == 0) {
			if (write(ofd, (void *)((uint8_t *)ubi_ec + data_offset), data_size) == -1) {
				printf("Write error\n");
				close(fd);
				close(ofd);
				return 0;
			}
		}
		if ((int)ubi_vol->vol_id > 0) {
			break;
		}

		ubi_ec = (struct ubi_ec_hdr *)((uint8_t *)ubi_ec + data_offset + data_size);
		magic = be32_to_cpu(ubi_ec->magic);
	}

	close(ofd);
	close(fd);
	printf("Kernel extracted from ubi image\n");
	return 1;
}

/**
 * is_image_version_higher() iterates through each component and check
 * versions against locally installed version.
 * If newer component version is lower than locally insatlled image,
 * abort the FW upgrade process.
 *
 * @img: char *
 */
int is_image_version_higher(void)
{
	int i;
	for (i = 0; i < NO_OF_SECTIONS; i++) {
		if (!sections[i].is_present) {
			continue;
		}

		if (sections[i].local_version > sections[i].img_version) {
			printf("Version of image %s (%d) is lower than minimal supported version(%d)\n",
					sections[i].file,
					sections[i].img_version,
					sections[i].local_version);
			return 0;
		}

		if (sections[i].img_version > sections[i].max_version) {
			printf("Version of image %s (%d) is higher than maximum supported version(%d)\n",
					sections[i].file,
					sections[i].img_version,
					sections[i].max_version);
		}
	}

	return 1;
}

/**
 * Update the version information file based on currently SW_ID being installed.
 *
 */
int update_version(void)
{
	int i;
	for (i = 0; i < NO_OF_SECTIONS; i++) {
		if (!sections[i].is_present) {
			continue;
		}

		if (set_local_image_version(&sections[i]) != 1) {
			printf("Error updating version of %s\n", sections[i].file);
			return 0;
		}
	}

	return 1;
}

int check_image_version(void)
{
	if (is_version_check_enabled() == 0) {
		printf("Version check is not enabled, upgrade to continue !!!\n");
		return 1;
	}

	if (is_image_version_higher() == 0) {
		printf("New image versions are lower than existing image, upgrade to STOP !!!\n");
		return 0;
	}

	if (update_version() != 1) {
		printf("Error while updating verison information\n");
		return 0;
	}
	printf("Update completed!\n");

	return 1;
}

/**
 * split_code_signature_cert_from_component_bin splits the component
 * binary by splitting into code(including MBN header), signature file &
 * attenstation certificate.
 *
 * @bin_file: char *
 * @src: char *
 * @sig: char *
 * @cert: char *
 */
int split_code_signature_cert_from_component_bin(struct image_section *section,
		char **src, char **sig, char **cert)
{
	Mbn_Hdr *mbn_hdr;
	Sbl_Hdr *sbl_hdr;
	int fd = open(section->file, O_RDONLY);
	uint8_t *fp;
	int sig_offset = 0;
	int src_offset = 0;
	int cert_offset = 0;
	struct stat sb;
	int sig_cert_size;

	if (fd == -1) {
		perror(section->file);
		return 0;
	}

	memset(&sb, 0, sizeof(struct stat));
	if (fstat(fd, &sb) == -1) {
		perror("fstat");
		close(fd);
		return 0;
	}

	fp = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
	if (fp == MAP_FAILED) {
		perror("mmap");
		close(fd);
		return 0;
	}

	mbn_hdr = (Mbn_Hdr *)fp;
	if (strstr(section->file, sections[4].type)) {
		uint32_t preamble = !check_nand_preamble(fp) ? SBL_NAND_PREAMBLE : 0;

		sbl_hdr = (Sbl_Hdr *)(fp + preamble);
		src_offset = preamble;
		sig_offset = preamble + sbl_hdr->sig_ptr - sbl_hdr->image_dest_ptr +
				SBL_HDR_SIZE;
		cert_offset = preamble + sbl_hdr->cert_ptr - sbl_hdr->image_dest_ptr +
				SBL_HDR_SIZE;
		sig_cert_size = sbl_hdr->image_size - sbl_hdr->code_size;
		src_size = sbl_hdr->sig_ptr - sbl_hdr->image_dest_ptr + SBL_HDR_SIZE;
	} else {
		sig_cert_size = mbn_hdr->image_size - mbn_hdr->code_size;
		src_size = mbn_hdr->sig_ptr - mbn_hdr->image_dest_ptr + MBN_HDR_SIZE;
		sig_offset += mbn_hdr->sig_ptr - mbn_hdr->image_dest_ptr + MBN_HDR_SIZE;
		cert_offset += mbn_hdr->cert_ptr - mbn_hdr->image_dest_ptr + MBN_HDR_SIZE;
	}

	if (sig_cert_size != SIG_CERT_2_SIZE && sig_cert_size != SIG_CERT_3_SIZE) {
		printf("WARNING: signature certificate size is different\n");
	}
        *src = malloc(src_size + 1);
	if (*src == NULL) {
		close(fd);
		return 0;
	}
	memcpy(*src, fp + src_offset, src_size);
	(*src)[src_size] = '\0';

	*sig = malloc((SIG_SIZE + 1) * sizeof(char));
	if (*sig == NULL) {
		free(*src);
		return 0;
	}
	memcpy(*sig, fp + sig_offset, SIG_SIZE);
	(*sig)[SIG_SIZE] = '\0';

	*cert = malloc((CERT_SIZE + 1) * sizeof(char));
	if (*cert == NULL) {
		free(*src);
		free(*sig);
		return 0;
	}
	memcpy(*cert, fp + cert_offset, CERT_SIZE);
	(*cert)[CERT_SIZE] = '\0';

	close(fd);
	return 1;
}

/**
 * split_code_signature_cert_from_component_bin_elf splits the component
 * binary by splitting into code(including ELF header), signature file &
 * attenstation certificate.
 *
 * @bin_file: char *
 * @src: char *
 * @sig: char *
 * @cert: char *
 */
int split_code_signature_cert_from_component_bin_elf(struct image_section *section,
		char **src, char **sig, char **cert)
{
	Elf32_Ehdr *elf;
	Elf32_Phdr *phdr;
	Mbn_Hdr *mbn_hdr;
	uint8_t *fp;
	int sig_offset;
	int cert_offset;
	int len;

	if (!process_elf(section->file, &fp, &elf, &phdr, &mbn_hdr)) {
		return 0;
	}

	sig_offset = mbn_hdr->sig_ptr - mbn_hdr->image_dest_ptr + MBN_HDR_SIZE;
	len = sig_offset;
	*src = malloc((len + 1) * sizeof(char));
	if (*src == NULL) {
		return 0;
	}
	memcpy(*src, fp + phdr->p_offset, len);
	src_size = len;
	(*src)[len] = '\0';

	*sig = malloc((SIG_SIZE + 1) * sizeof(char));
	if (*sig == NULL) {
		free(*src);
		return 0;
	}
	memcpy(*sig, fp + phdr->p_offset + sig_offset, SIG_SIZE);
	(*sig)[SIG_SIZE] = '\0';

	cert_offset = mbn_hdr->cert_ptr - mbn_hdr->image_dest_ptr + MBN_HDR_SIZE;
	*cert = malloc((CERT_SIZE + 1) * sizeof(char));
	if (*cert == NULL) {
		free(*src);
		free(*sig);
		return 0;
	}
	memcpy(*cert, fp + phdr->p_offset + cert_offset, CERT_SIZE);
	(*cert)[CERT_SIZE] = '\0';

	return 1;
}

/**
 * split_code_signature_cert_from_component_bin_elf64 splits the component
 * binary by splitting into code(including ELF header), signature file &
 * attenstation certificate.
 *
 * @bin_file: char *
 * @src: char *
 * @sig: char *
 * @cert: char *
 */
int split_code_signature_cert_from_component_bin_elf64(struct image_section *section,
                char **src, char **sig, char **cert)
{
	Elf64_Ehdr *elf;
	Elf64_Phdr *phdr;
	Mbn_Hdr *mbn_hdr;
	uint8_t *fp;
	int len, sig_offset, cert_offset;

	if (!process_elf64(section->file, &fp, &elf, &phdr, &mbn_hdr)) {
		return 0;
	}

	sig_offset = mbn_hdr->code_size + MBN_HDR_SIZE;
	len = sig_offset;
	*src = malloc((len + 1) * sizeof(char));
	if (*src == NULL) {
		return 0;
	}

	memcpy(*src, fp + phdr->p_offset, len);
	src_size = len;
	(*src)[len] = '\0';

	*sig = malloc((SIG_SIZE + 1) * sizeof(char));
	if (*sig == NULL) {
		free(*src);
		return 0;
	}

	memcpy(*sig, fp + phdr->p_offset + sig_offset, SIG_SIZE);
	(*sig)[SIG_SIZE] = '\0';

	cert_offset = mbn_hdr->code_size + mbn_hdr->sig_sz + MBN_HDR_SIZE;
	*cert = malloc((CERT_SIZE + 1) * sizeof(char));
	if (*cert == NULL) {
		free(*src);
		free(*sig);
		return 0;
	}
	memcpy(*cert, fp + phdr->p_offset + cert_offset, CERT_SIZE);
	(*cert)[CERT_SIZE] = '\0';

	return 1;
}

/**
 * being used to calculate the image hash
 *
 */
#define SW_MASK		0x3636363636363636ull

void generate_swid_ipad(char *sw_id, unsigned long long *swid_xor_ipad)
{
	unsigned long long int val;

	val = strtoull(sw_id, NULL, 16);
	*swid_xor_ipad = val ^ SW_MASK;

	printf("%llx\n", *swid_xor_ipad);
}

/**
 * being used to calculate the image hash
 *
 */
#define HW_ID_MASK		0x5c5c5c5cull
#define OEM_ID_MASK		0x00005c5cull
#define OEM_MODEL_ID_MASK	0x00005c5cull

void generate_hwid_opad(char *hw_id, char *oem_id, char *oem_model_id,
					unsigned long long *hwid_xor_opad)
{
	unsigned long long val;

	val = strtoull(hw_id, NULL, 16);
	*hwid_xor_opad = (((val >> 32) ^ HW_ID_MASK) << 32);

	val = strtoul(oem_id, NULL, 16);
	*hwid_xor_opad |= ((val ^ OEM_ID_MASK) << 16);

	val = strtoul(oem_model_id, NULL, 16);
	*hwid_xor_opad |= (val ^ OEM_MODEL_ID_MASK) & 0xffff;

	printf("%llx\n", *hwid_xor_opad);
}

int create_file(char *name, char *buffer, int size)
{
	int fd;

	fd = open(name, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
	if (fd == -1) {
		perror(name);
		return 0;
	}

	if (write(fd, buffer, size) == -1) {
		close(fd);
		return 0;
	}

	close(fd);
	return 1;
}

char *create_xor_ipad_opad(char *f_xor, unsigned long long *xor_buffer)
{
	int fd;
	char *file;
	unsigned long long sw_id, sw_id_be;

	file = mktemp(f_xor);
	fd = open(file, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
	if (fd == -1) {
		perror(file);
		return NULL;
	}

	sw_id = *xor_buffer;
	sw_id_be = htobe64(sw_id);
	write(fd, &sw_id_be, sizeof(sw_id_be));
	close(fd);
	return file;
}

char *read_file(char *file_name, size_t *file_size)
{
	int fd;
	struct stat st;
	char *buffer;

	fd = open(file_name, O_RDONLY);
	if (fd == -1) {
		perror(file_name);
		return NULL;
	}

	memset(&st, 0, sizeof(struct stat));
	fstat(fd, &st);
	buffer = malloc(st.st_size * sizeof(buffer));
	if (buffer == NULL) {
		close(fd);
		return NULL;
	}

	if (read(fd, buffer, st.st_size) == -1) {
		close(fd);
		return NULL;
	}

	*file_size = (size_t) st.st_size;
	close(fd);
	return buffer;
}

int generate_hash(char *cert, char *sw_file, char *hw_file)
{
	unsigned long long swid_xor_ipad, hwid_xor_opad;
	char *tmp;
	char *sw_id_str = find_value(cert, "SW_ID", 17);
	char *hw_id_str = find_value(cert, "HW_ID", 17);
	char *oem_id_str = find_value(cert, "OEM_ID", 5);
	char *oem_model_id_str = find_value(cert, "MODEL_ID", 5);
	char f_sw_xor[] = "/tmp/swid_xor_XXXXXX";
	char f_hw_xor[] = "/tmp/hwid_xor_XXXXXX";

	if (sw_id_str == NULL || hw_id_str == NULL || oem_id_str == NULL || oem_model_id_str == NULL) {
		if (sw_id_str != NULL) {
			free(sw_id_str);
		}
		if (hw_id_str != NULL) {
			free(hw_id_str);
		}
		if (oem_id_str != NULL) {
			free(oem_id_str);
		}
		if (oem_model_id_str != NULL) {
			free(oem_model_id_str);
		}
		return 0;
	}
	printf("sw_id=%s\thw_id=%s\t", sw_id_str, hw_id_str);
	printf("oem_id=%s\toem_model_id=%s\n", oem_id_str, oem_model_id_str);

	generate_swid_ipad(sw_id_str, &swid_xor_ipad);
	tmp = create_xor_ipad_opad(f_sw_xor, &swid_xor_ipad);
	if (tmp == NULL) {
		free(sw_id_str);
		free(hw_id_str);
		free(oem_id_str);
		free(oem_model_id_str);
		return 0;
	}
	strlcpy(sw_file, tmp, 32);

	generate_hwid_opad(hw_id_str, oem_id_str, oem_model_id_str, &hwid_xor_opad);
	tmp = create_xor_ipad_opad(f_hw_xor, &hwid_xor_opad);
	if (tmp == NULL) {
		free(sw_id_str);
		free(hw_id_str);
		free(oem_id_str);
		free(oem_model_id_str);
		return 0;
	}
	strlcpy(hw_file, tmp, 32);

	free(sw_id_str);
	free(hw_id_str);
	free(oem_id_str);
	free(oem_model_id_str);

	return 1;
}

void remove_file(char *sw_file, char *hw_file, char *code_file, char *pub_file)
{
	remove(sw_file);
	remove(hw_file);
	remove(code_file);
	remove(pub_file);
	remove("src");
	remove("sig");
	remove("cert");
}

/**
 * is_component_authenticated() usage the code, signature & public key retrieved
 * for each component.
 *
 * @src: char *
 * @sig: char *
 * @cert: char *
 */
int is_component_authenticated(char *src, char *sig, char *cert)
{
	char command[256];
	char *computed_hash;
	char *reference_hash;
	char pub_key[] = "/tmp/pub_keyXXXXXX", *pub_file;
	char code_hash[] = "/tmp/code_hash_XXXXXX", *code_file;
	char tmp_hash[] = "/tmp/tmp_hash_XXXXXX", *tmp_file;
	char f_computed_hash[] = "/tmp/computed_hash_XXXXXX", *computed_file;
	char f_reference_hash[] = "/tmp/reference_hash_XXXXXX", *reference_file;
	char sw_file[32],hw_file[32];
	int retval;
	size_t comp_hash_size, ref_hash_size;

	if (!create_file("src", src, src_size) || !create_file("sig", sig, SIG_SIZE) ||
			!create_file("cert", cert, CERT_SIZE)) {
		return 0;
	}

	pub_file = mktemp(pub_key);
	snprintf(command, sizeof(command),
		"openssl x509 -in cert -pubkey -inform DER -noout > %s", pub_file);
	retval = system(command);
	if (retval != 0) {
		remove("src");
		remove("sig");
		remove("cert");
		printf("Error generating public key\n");
		return 0;
	}

	retval = generate_hash(cert, sw_file, hw_file);
	if (retval == 0) {
		return 0;
	}

	code_file = mktemp(code_hash);
	snprintf(command, sizeof(command),
		"openssl dgst -sha256 -binary -out %s src", code_file);
	retval = system(command);
	if (retval != 0) {
		remove_file(sw_file, hw_file, code_file, pub_file);
		printf("Error in openssl digest\n");
		return 0;
	}

	tmp_file = mktemp(tmp_hash);
	snprintf(command, sizeof(command),
		"cat %s %s | openssl dgst -sha256 -binary -out %s",
						sw_file, code_file, tmp_file);
	retval = system(command);
	if (retval != 0) {
		remove_file(sw_file, hw_file, code_file, pub_file);
		remove(tmp_file);
		printf("Error generating temp has\n");
		return 0;
	}

	computed_file = mktemp(f_computed_hash);
	snprintf(command, sizeof(command),
		"cat %s %s | openssl dgst -sha256 -binary -out %s",
						hw_file, tmp_file, computed_file);
	retval = system(command);
	if (retval != 0) {
		remove_file(sw_file, hw_file, code_file, pub_file);
		remove(tmp_file);
		remove(computed_file);
		printf("Error generating hash\n");
		return 0;
	}

	reference_file = mktemp(f_reference_hash);
	snprintf(command, sizeof(command),
		"openssl rsautl -in sig -pubin -inkey %s -verify > %s",
						pub_file, reference_file);
	retval = system(command);
	if (retval != 0) {
		remove_file(sw_file, hw_file, code_file, pub_file);
		remove(tmp_file);
		remove(computed_file);
		remove(reference_file);
		printf("Error generating reference hash\n");
		return 0;
	}

	computed_hash = read_file(computed_file, &comp_hash_size);
	reference_hash = read_file(reference_file, &ref_hash_size);
	if (computed_hash == NULL || reference_hash == NULL) {
		remove_file(sw_file, hw_file, code_file, pub_file);
		remove(tmp_file);
		remove(computed_file);
		remove(reference_file);
		free(computed_hash?computed_hash:reference_hash);
		return 0;
	}

	remove_file(sw_file, hw_file, code_file, pub_file);
	remove(tmp_file);
	remove(computed_file);
	remove(reference_file);
	if (memcmp(computed_hash, reference_hash, ref_hash_size) ||
			(comp_hash_size != ref_hash_size)) {
		free(computed_hash);
		free(reference_hash);
		printf("Error: Hash or file_size not equal\n");
		return 0;
	}
	free(computed_hash);
	free(reference_hash);
	return 1;
}

/**
 * is_image_authenticated() iterates through each component and check
 * whether individual component is authenticated. If not, abort the FW
 * upgrade process.
 *
 * @img: char *
 */
int is_image_authenticated(void)
{
	int i;
	char *src, *sig, *cert;
	for (i = 0; i < NO_OF_SECTIONS; i++) {
		if (!sections[i].is_present) {
			continue;
		}
		if (!sections[i].split_components(&sections[i], &src, &sig, &cert)) {
			printf("Error while splitting code/signature/Certificate from %s\n",
					sections[i].file);
			return 0;
		}
		if (!is_component_authenticated(src, sig, cert)) {
			printf("Error while authenticating %s\n", sections[i].file);
			return 0;
		}
	}

	return 1;
}

int sec_image_auth(void)
{
	int fd, i, len;
	char *buf = NULL;

	fd = open(SEC_AUTHENTICATE_FILE, O_RDWR);
	if (-1 == fd) {
		perror(SEC_AUTHENTICATE_FILE);
		return 1;
	}
	buf = (char*)malloc(SIG_SIZE);
	if (buf == NULL) {
		perror("Memory allocation failed\n");
		close(fd);
		return 1;
	}
	for (i = 0; i < NO_OF_SECTIONS; i++) {
		if (!sections[i].is_present) {
			continue;
		}

		len = snprintf(buf, SIG_SIZE, "%s %s", sections[i].img_code, sections[i].file);
		if (len < 0 || len > SIG_SIZE) {
			perror("Array out of Index\n");
			free(buf);
			close(fd);
			return 1;
		}
		if (write(fd, buf, len) != len) {
			perror("write");
			printf("%s Image authentication failed\n", buf);
			free(buf);
			close(fd);
			return 1;
		}
	}
	close(fd);
	free(buf);
	return 0;
}

int do_board_upgrade_check(char *img)
{
	if (is_tz_authentication_enabled()) {
		printf("TZ authentication enabled ...\n");
		if (!load_sections()) {
			printf("Error: Failed to load sections from image: %s\n", img);
			return 1;
		}
		return sec_image_auth();
	} else if (is_authentication_check_enabled()) {
		if (!get_sections()) {
			printf("Error: %s is not a signed image\n", img);
			return 1;
		}

		if (!is_image_authenticated()) {
			printf("Error: \"%s\" couldn't be authenticated. Abort...\n", img);
			return 1;
		}

		if (!check_image_version()) {
			printf("Error: \"%s\" couldn't be upgraded. Abort...\n", img);
			return 1;
		}
	}

	return 0;
}
