/* Copyright 2016 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 <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "futility.h"

enum {
	OPT_HELP = 1000,
	OPT_OFFSET,
};

static const struct option long_opts[] = {
	{"help", 0, 0, OPT_HELP},
	{"offset", 1, 0, OPT_OFFSET},
	{NULL, 0, NULL, 0},
};

static void print_help(int argc, char *argv[])
{
	printf("\nUsage:  " MYNAME " %s FILE [OPTIONS]\n", argv[0]);
	printf("\nOptions:\n");
	printf(" --offset <offset>          Offset of cache within FILE\n");
	printf("\n");
}

struct mrc_metadata {
	uint32_t signature;
	uint32_t data_size;
	uint16_t data_checksum;
	uint16_t header_checksum;
	uint32_t version;
} __attribute__((packed));

#define MRC_DATA_SIGNATURE		(('M'<<0)|('R'<<8)|('C'<<16)|('D'<<24))
#define REGF_BLOCK_SHIFT		4
#define REGF_BLOCK_GRANULARITY		(1 << REGF_BLOCK_SHIFT)
#define REGF_METADATA_BLOCK_SIZE	REGF_BLOCK_GRANULARITY
#define REGF_UNALLOCATED_BLOCK		0xffff

static unsigned long compute_ip_checksum(const void *addr, unsigned long length)
{
	const uint8_t *ptr;
	volatile union {
		uint8_t  byte[2];
		uint16_t word;
	} value;
	unsigned long sum;
	unsigned long i;
	/* In the most straight forward way possible,
	 * compute an ip style checksum.
	 */
	sum = 0;
	ptr = addr;
	for(i = 0; i < length; i++) {
		unsigned long v;
		v = ptr[i];
		if (i & 1) {
			v <<= 8;
		}
		/* Add the new value */
		sum += v;
		/* Wrap around the carry */
		if (sum > 0xFFFF) {
			sum = (sum + (sum >> 16)) & 0xFFFF;
		}
	}
	value.byte[0] = sum & 0xff;
	value.byte[1] = (sum >> 8) & 0xff;
	return (~value.word) & 0xFFFF;
}

static int verify_mrc_slot(struct mrc_metadata *md, unsigned long slot_len)
{
	uint32_t header_checksum;

	if (slot_len < sizeof(*md)) {
		fprintf(stderr, "Slot too small!\n");
		return 1;
	}

	if (md->signature != MRC_DATA_SIGNATURE) {
		fprintf(stderr, "MRC signature mismatch\n");
		return 1;
	}

	fprintf(stderr, "MRC signature match.. successful\n");

	if (md->data_size > slot_len) {
		fprintf(stderr, "MRC cache size overflow\n");
		return 1;
	}

	header_checksum = md->header_checksum;
	md->header_checksum = 0;

	if (header_checksum != compute_ip_checksum(md, sizeof(*md))) {
		fprintf(stderr, "MRC metadata header checksum mismatch\n");
		return 1;
	}

	md->header_checksum = header_checksum;

	fprintf(stderr, "MRC metadata header checksum.. verified!\n");

	if (md->data_checksum != compute_ip_checksum(&md[1], md->data_size)) {
		fprintf(stderr, "MRC data checksum mismatch\n");
		return 1;
	}

	fprintf(stderr, "MRC data checksum.. verified!\n");
	return 0;
}

static int block_offset_unallocated(uint16_t offset)
{
	return offset == REGF_UNALLOCATED_BLOCK;
}

static uint8_t *get_next_mb(uint8_t *curr_mb)
{
	return curr_mb + REGF_METADATA_BLOCK_SIZE;
}

static int get_mrc_data_slot(uint16_t *mb, uint32_t *data_offset,
			     uint32_t *data_size)
{
	uint16_t num_metadata_blocks = *mb;

	if (block_offset_unallocated(*mb)) {
		fprintf(stderr, "MRC cache is empty!!\n");
		return 1;
	}

	/*
	 * First block offset in metadata block tells the total number of
	 * metadata blocks.
	 * Currently, we expect only 1 metadata block to be used.
	 */
	if (num_metadata_blocks != 1) {
		uint16_t *next_mb = (uint16_t *)get_next_mb((uint8_t *)mb);
		if (!block_offset_unallocated(*next_mb)) {
			fprintf(stderr, "More than 1 valid metadata block!!");
			return 1;
		}
	}

	/*
	 * RECOVERY_MRC_CACHE is expected to contain only one slot. Thus, there
	 * should be only one block offset present, indicating size of the MRC
	 * cache slot.
	 */
	mb++;
	*data_offset = (1 << REGF_BLOCK_SHIFT) * num_metadata_blocks;
	*data_size = (*mb - num_metadata_blocks) << REGF_BLOCK_SHIFT;

	mb++;
	if (!block_offset_unallocated(*mb)) {
		fprintf(stderr, "More than 1 slot in recovery mrc cache.\n");
		return 1;
	}

	return 0;
}

static int do_validate_rec_mrc(int argc, char *argv[])
{
	char *infile = NULL;
	int parse_error = 0;
	int fd, i, ret = 1;
	uint32_t file_size;
	uint8_t *buff;
	uint32_t offset = 0;
	uint32_t data_offset;
	uint32_t data_size;
	char *e;

	while (((i = getopt_long(argc, argv, ":", long_opts, NULL)) != -1) &&
	       !parse_error) {
		switch (i) {
		case OPT_HELP:
			print_help(argc, argv);
			return 0;
		case OPT_OFFSET:
			offset = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e)) {
				fprintf(stderr, "Invalid --offset\n");
				parse_error = 1;
			}
			break;
		default:
		case '?':
			parse_error = 1;
			break;
		}
	}

	if (parse_error) {
		print_help(argc, argv);
		return 1;
	}

	if ((argc - optind) < 1) {
		fprintf(stderr, "You must specify an input FILE!\n");
		print_help(argc, argv);
		return 1;
	} else if ((argc - optind) != 1) {
		fprintf(stderr, "Unexpected arguments!\n");
		print_help(argc, argv);
		return 1;
	}

	infile = argv[optind++];

	fd = open(infile, O_RDONLY);
	if (fd < 0) {
		fprintf(stderr, "Cannot open %s:%s\n", infile, strerror(errno));
		return 1;
	}

	if (futil_map_file(fd, MAP_RO, &buff, &file_size) != FILE_ERR_NONE) {
		fprintf(stderr, "Cannot map file %s\n", infile);
		close(fd);
		return 1;
	}

	if (offset > file_size) {
		fprintf(stderr, "File size(%#x) smaller than offset(%#x)\n",
			file_size, offset);
		futil_unmap_file(fd, MAP_RO, buff, file_size);
		close(fd);
		return 1;
	}

	if (get_mrc_data_slot((uint16_t *)(buff + offset), &data_offset,
			      &data_size)) {
		fprintf(stderr, "Metadata block error\n");
		futil_unmap_file(fd, MAP_RO, buff, file_size);
		close(fd);
		return 1;
	}
	offset += data_offset;

	if ((file_size > offset) && ((file_size - offset) >= data_size))
		ret = verify_mrc_slot((struct mrc_metadata *)(buff + offset),
				      data_size);
	else
		fprintf(stderr, "Offset or data size greater than file size: "
			"offset=%#x, file size=%#x, data_size=%#x\n",
			offset, file_size, data_size);

	if (futil_unmap_file(fd, MAP_RO, buff, file_size) != FILE_ERR_NONE) {
		fprintf(stderr, "Failed to unmap file %s\n", infile);
		ret = 1;
	}

	close(fd);
	return ret;
}

DECLARE_FUTIL_COMMAND(validate_rec_mrc, do_validate_rec_mrc, VBOOT_VERSION_ALL,
		      "Validates content of Recovery MRC cache");
