/* Copyright 2015 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.
 *
 * The USB Type-C chargers released with Samus ("Pixel (2015)") have upgradable
 * firmware. Due to space considerations, we don't have room for handy things
 * like an FMAP or headers for the signatures. Accordingly, all the normally
 * variable factors (image size, signature algorithms, etc.) are hard coded
 * and the image itself just looks like a bunch of random numbers.
 *
 * This file handles those images, but PLEASE don't use it as a template for
 * new devices. Look at file_type_rwsig.c instead.
 */

#include <stdint.h>
#include <stdio.h>
#include <unistd.h>

#include "2common.h"
#include "2rsa.h"
#include "2sha.h"
#include "2sysincludes.h"
#include "file_type.h"
#include "futility.h"
#include "futility_options.h"
#include "host_common.h"
#include "host_key2.h"
#include "host_signature2.h"
#include "util_misc.h"
#include "vb21_common.h"

/* Return 1 if okay, 0 if not */
static int parse_size_opts(uint32_t len,
			   uint32_t *ro_size_ptr, uint32_t *rw_size_ptr,
			   uint32_t *ro_offset_ptr, uint32_t * rw_offset_ptr)
{
	uint32_t ro_size, rw_size, ro_offset, rw_offset;

	/* Assume the image has both RO and RW, evenly split. */
	ro_offset = 0;
	ro_size = rw_size = rw_offset = len / 2;

	/* Unless told otherwise... */
	if (sign_option.ro_size != 0xffffffff)
		ro_size = sign_option.ro_size;
	if (sign_option.ro_offset != 0xffffffff)
		ro_offset = sign_option.ro_offset;

	/* If RO is missing, the whole thing must be RW */
	if (!ro_size) {
		rw_size = len;
		rw_offset = 0;
	}

	/* Unless that's overridden too */
	if (sign_option.rw_size != 0xffffffff)
		rw_size = sign_option.rw_size;
	if (sign_option.rw_offset != 0xffffffff)
		rw_offset = sign_option.rw_offset;

	VB2_DEBUG("ro_size     0x%08x\n", ro_size);
	VB2_DEBUG("ro_offset   0x%08x\n", ro_offset);
	VB2_DEBUG("rw_size     0x%08x\n", rw_size);
	VB2_DEBUG("rw_offset   0x%08x\n", rw_offset);

	/* Now let's do some sanity checks. */
	if (ro_size > len || ro_offset > len - ro_size ||
	    rw_size > len || rw_offset > len - rw_size) {
		printf("size/offset values are bogus\n");
		return 0;
	}

	*ro_size_ptr = ro_size;
	*rw_size_ptr = rw_size;
	*ro_offset_ptr = ro_offset;
	*rw_offset_ptr = rw_offset;

	return 1;
}

int ft_sign_usbpd1(const char *name, uint8_t *buf, uint32_t len, void *data)
{
	struct vb2_private_key *key_ptr = 0;
	struct vb21_signature *sig_ptr = 0;
	uint8_t *keyb_data = 0;
	uint32_t keyb_size;
	int retval = 1;
	uint32_t sig_size;
	uint32_t sig_offset;
	uint32_t pub_size;
	uint32_t pub_offset;
	uint32_t ro_size;
	uint32_t rw_size;
	uint32_t ro_offset;
	uint32_t rw_offset;
	uint32_t r;

	VB2_DEBUG("%s(): name %s len  0x%08x (%d)\n", name, len, len);

	/* Get image locations */
	if (!parse_size_opts(len, &ro_size, &rw_size, &ro_offset, &rw_offset))
		goto done;

	/* Read the signing keypair file */
	if (vb2_private_key_read_pem(&key_ptr, sign_option.pem_signpriv)) {
		fprintf(stderr, "Unable to read keypair from %s\n",
			sign_option.pem_signpriv);
		goto done;
	}

	/* Set the algs */
	key_ptr->hash_alg = sign_option.hash_alg;
	key_ptr->sig_alg = vb2_rsa_sig_alg(key_ptr->rsa_private_key);
	if (key_ptr->sig_alg == VB2_SIG_INVALID) {
		fprintf(stderr, "Unsupported sig algorithm in RSA key\n");
		goto done;
	}

	/* Figure out what needs signing */
	sig_size = vb2_rsa_sig_size(key_ptr->sig_alg);
	if (rw_size < sig_size) {
		fprintf(stderr,
			"The RW image is too small to hold the signature"
			" (0x%08x < %08x)\n", rw_size, sig_size);
		goto done;
	}
	rw_size -= sig_size;
	sig_offset = rw_offset + rw_size;

	VB2_DEBUG("rw_size   => 0x%08x\n", rw_size);
	VB2_DEBUG("rw_offset => 0x%08x\n", rw_offset);
	VB2_DEBUG("sig_size     0x%08x\n", sig_size);
	VB2_DEBUG("sig_offset   0x%08x\n", sig_offset);

	/* Sign the blob */
	r = vb21_sign_data(&sig_ptr, buf + rw_offset, rw_size, key_ptr, "Bah");
	if (r) {
		fprintf(stderr,
			"Unable to sign data (error 0x%08x, if that helps)\n",
			r);
		goto done;
	}

	/* Double-check the size */
	if (sig_ptr->sig_size != sig_size) {
		fprintf(stderr,
			"ERROR: sig size is %d bytes, not %d as expected.\n",
			sig_ptr->sig_size, sig_size);
		goto done;
	}

	/* Okay, looking good. Update the signature. */
	memcpy(buf + sig_offset,
	       (uint8_t *)sig_ptr + sig_ptr->sig_offset,
	       sig_ptr->sig_size);


	/* If there's no RO section, we're done. */
	if (!ro_size) {
		retval = 0;
		goto done;
	}

	/* Otherwise, now update the public key */
	if (vb_keyb_from_rsa(key_ptr->rsa_private_key,
			     &keyb_data, &keyb_size)) {
		fprintf(stderr, "Couldn't extract the public key\n");
		goto done;
	}
	VB2_DEBUG("keyb_size is 0x%x (%d):\n", keyb_size, keyb_size);

	/*
	 * Of course the packed public key format is different. Why would you
	 * think otherwise? Since the dawn of time, vboot has used this:
	 *
	 *   uint32_t  nwords        size of RSA key in 32-bit words
	 *   uint32_t  n0inv         magic RSA n0inv
	 *   uint32_t  n[nwords]     magic RSA modulus little endian array
	 *   uint32_t  rr[nwords]    magic RSA R^2 little endian array
	 *
	 * But for no discernable reason, the usbpd1 format uses this:
	 *
	 *   uint32_t  n[nwords]     magic RSA modulus little endian array
	 *   uint32_t  rr[nwords]    magic RSA R^2 little endian array
	 *   uint32_t  n0inv         magic RSA n0inv
	 *
	 * There's no nwords field, and n0inv is last insted of first. Sigh.
	 */
	pub_size = keyb_size - 4;

	/* align pubkey size to 16-byte boundary */
	uint32_t pub_pad = pub_size;
	pub_size = (pub_size + 16) / 16 * 16;
	pub_pad = pub_size - pub_pad;

	pub_offset = ro_offset + ro_size - pub_size;

	if (ro_size < pub_size) {
		fprintf(stderr,
			"The RO image is too small to hold the public key"
			" (0x%08x < %08x)\n", ro_size, pub_size);
		goto done;
	}

	/* How many bytes in the arrays? */
	uint32_t nbytes = 4 * (*(uint32_t *)keyb_data);
	/* Source offsets from keyb_data */
	uint32_t src_ofs_n0inv = 4;
	uint32_t src_ofs_n = src_ofs_n0inv + 4;
	uint32_t src_ofs_rr = src_ofs_n + nbytes;
	/* Dest offsets from buf */
	uint32_t dst_ofs_n = pub_offset + 0;
	uint32_t dst_ofs_rr = dst_ofs_n + nbytes;
	uint32_t dst_ofs_n0inv = dst_ofs_rr + nbytes;

	VB2_DEBUG("len 0x%08x ro_size 0x%08x ro_offset 0x%08x\n",
		  len, ro_size, ro_offset);
	VB2_DEBUG("pub_size 0x%08x pub_offset 0x%08x nbytes 0x%08x\n",
		  pub_size, pub_offset, nbytes);
	VB2_DEBUG("pub_pad 0x%08x\n", pub_pad);

	/* Copy n[nwords] */
	memcpy(buf + dst_ofs_n,
	       keyb_data + src_ofs_n,
	       nbytes);
	/* Copy rr[nwords] */
	memcpy(buf + dst_ofs_rr,
	       keyb_data + src_ofs_rr,
	       nbytes);
	/* Copy n0inv */
	memcpy(buf + dst_ofs_n0inv,
	       keyb_data + src_ofs_n0inv,
	       4);
	/* Pad with 0xff */
	memset(buf + dst_ofs_n0inv + 4, 0xff, pub_pad);

	/* Finally */
	retval = 0;
done:
	if (key_ptr)
		vb2_private_key_free(key_ptr);
	if (keyb_data)
		free(keyb_data);

	return retval;
}


/*
 * Algorithms that we want to try, in order. We've only ever shipped with
 * RSA2048 / SHA256, but the others should work in tests.
 */
static enum vb2_signature_algorithm sigs[] = {
	VB2_SIG_RSA2048,
	VB2_SIG_RSA2048_EXP3,
	VB2_SIG_RSA1024,
	VB2_SIG_RSA4096,
	VB2_SIG_RSA8192,
};
static enum vb2_hash_algorithm hashes[] = {
	VB2_HASH_SHA256,
	VB2_HASH_SHA1,
	VB2_HASH_SHA512,
};

/*
 * The size of the public key structure used by usbpd1 is
 * 2 x RSANUMBYTES for n and rr fields
 * plus 4 for n0inv, aligned on a multiple of 16
 */
static uint32_t usbpd1_packed_key_size(enum vb2_signature_algorithm sig_alg)
{
	switch (sig_alg) {
	case VB2_SIG_RSA1024:
		return 272;
	case VB2_SIG_RSA2048:
	case VB2_SIG_RSA2048_EXP3:
		return 528;
	case VB2_SIG_RSA4096:
		return 1040;
	case VB2_SIG_RSA8192:
		return 2064;
	default:
		return 0;
	}
}
static void vb2_pubkey_from_usbpd1(struct vb2_public_key *key,
				   enum vb2_signature_algorithm sig_alg,
				   enum vb2_hash_algorithm hash_alg,
				   const uint8_t *o_pubkey,
				   uint32_t o_pubkey_size)
{
	key->arrsize = vb2_rsa_sig_size(sig_alg) / sizeof(uint32_t);
	key->n0inv = *((uint32_t *)o_pubkey + 2 * key->arrsize);
	key->n = (uint32_t *)o_pubkey;
	key->rr = (uint32_t *)o_pubkey + key->arrsize;
	key->sig_alg = sig_alg;
	key->hash_alg = hash_alg;
	key->desc = 0;
	key->version = 0;
	key->id = vb2_hash_id(hash_alg);
}

static vb2_error_t vb21_sig_from_usbpd1(struct vb21_signature **sig,
					enum vb2_signature_algorithm sig_alg,
					enum vb2_hash_algorithm hash_alg,
					const uint8_t *o_sig,
					uint32_t o_sig_size, uint32_t data_size)
{
	struct vb21_signature s = {
		.c.magic = VB21_MAGIC_SIGNATURE,
		.c.struct_version_major = VB21_SIGNATURE_VERSION_MAJOR,
		.c.struct_version_minor = VB21_SIGNATURE_VERSION_MINOR,
		.c.fixed_size = sizeof(s),
		.sig_alg = sig_alg,
		.hash_alg = hash_alg,
		.data_size = data_size,
		.sig_size = vb2_rsa_sig_size(sig_alg),
		.sig_offset = sizeof(s),
	};
	uint32_t total_size = sizeof(s) + o_sig_size;
	uint8_t *buf = calloc(1, total_size);
	if (!buf)
		return VB2_ERROR_UNKNOWN;

	memcpy(buf, &s, sizeof(s));
	memcpy(buf + sizeof(s), o_sig, o_sig_size);

	*sig = (struct vb21_signature *)buf;
	return VB2_SUCCESS;
}

static void show_usbpd1_stuff(const char *name,
			      enum vb2_signature_algorithm sig_alg,
			      enum vb2_hash_algorithm hash_alg,
			      const uint8_t *o_pubkey, uint32_t o_pubkey_size)
{
	struct vb2_public_key key;
	struct vb21_packed_key *pkey;
	uint8_t sha1sum[VB2_SHA1_DIGEST_SIZE];
	int i;

	vb2_pubkey_from_usbpd1(&key, sig_alg, hash_alg,
			       o_pubkey, o_pubkey_size);

	if (vb21_public_key_pack(&pkey, &key))
		return;

	vb2_digest_buffer((uint8_t *)pkey + pkey->key_offset, pkey->key_size,
			  VB2_HASH_SHA1, sha1sum, sizeof(sha1sum));

	printf("USB-PD v1 image:       %s\n", name);
	printf("  Algorithm:           %s %s\n",
	       vb2_get_sig_algorithm_name(sig_alg),
	       vb2_get_hash_algorithm_name(hash_alg));
	printf("  Key sha1sum:         ");
	for (i = 0; i < VB2_SHA1_DIGEST_SIZE; i++)
		printf("%02x", sha1sum[i]);
	printf("\n");

	free(pkey);
}


/* Returns VB2_SUCCESS or random error code */
static vb2_error_t try_our_own(enum vb2_signature_algorithm sig_alg,
			       enum vb2_hash_algorithm hash_alg,
			       const uint8_t *o_pubkey, uint32_t o_pubkey_size,
			       const uint8_t *o_sig, uint32_t o_sig_size,
			       const uint8_t *data, uint32_t data_size)
{
	struct vb2_public_key pubkey;
	struct vb21_signature *sig;
	uint8_t buf[VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE]
		__attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
	struct vb2_workbuf wb = {
		.buf = buf,
		.size = sizeof(buf),
	};
	vb2_error_t rv = VB2_ERROR_UNKNOWN;

	vb2_pubkey_from_usbpd1(&pubkey, sig_alg, hash_alg,
			       o_pubkey, o_pubkey_size);

	if ((rv = vb21_sig_from_usbpd1(&sig, sig_alg, hash_alg,
				       o_sig, o_sig_size, data_size)))
	    return rv;

	rv = vb21_verify_data(data, data_size, sig, &pubkey, &wb);

	free(sig);

	return rv;
}

/* Returns VB2_SUCCESS if the image validates itself */
static vb2_error_t check_self_consistency(const uint8_t *buf, const char *name,
					  uint32_t ro_size, uint32_t rw_size,
					  uint32_t ro_offset,
					  uint32_t rw_offset,
					  enum vb2_signature_algorithm sig_alg,
					  enum vb2_hash_algorithm hash_alg)
{
	/* Where are the important bits? */
	uint32_t sig_size = vb2_rsa_sig_size(sig_alg);
	uint32_t sig_offset = rw_offset + rw_size - sig_size;
	uint32_t pubkey_size = usbpd1_packed_key_size(sig_alg);
	uint32_t pubkey_offset = ro_offset + ro_size - pubkey_size;
	vb2_error_t rv;

	/* Skip stuff that obviously doesn't work */
	if (sig_size > rw_size || pubkey_size > ro_size)
		return VB2_ERROR_UNKNOWN;

	rv = try_our_own(sig_alg, hash_alg,		   /* algs */
			 buf + pubkey_offset, pubkey_size, /* pubkey blob */
			 buf + sig_offset, sig_size,	   /* sig blob */
			 buf + rw_offset, rw_size - sig_size); /* RW image */

	if (rv == VB2_SUCCESS && name)
		show_usbpd1_stuff(name, sig_alg, hash_alg,
				  buf + pubkey_offset, pubkey_size);

	return rv;
}


int ft_show_usbpd1(const char *name, uint8_t *buf, uint32_t len, void *data)
{
	uint32_t ro_size, rw_size, ro_offset, rw_offset;
	int s, h;

	VB2_DEBUG("name %s len  0x%08x (%d)\n", name, len, len);

	/* Get image locations */
	if (!parse_size_opts(len, &ro_size, &rw_size, &ro_offset, &rw_offset))
		return 1;

	/* TODO: If we don't have a RO image, ask for a public key
	 * TODO: If we're given an external public key, use it (and its alg) */
	if (!ro_size) {
		printf("Can't find the public key\n");
		return 1;
	}

	/* TODO: Only loop through the numbers we haven't been given */
	for (s = 0; s < ARRAY_SIZE(sigs); s++)
		for (h = 0; h < ARRAY_SIZE(hashes); h++)
			if (!check_self_consistency(buf, name,
						    ro_size, rw_size,
						    ro_offset, rw_offset,
						    sigs[s], hashes[h]))
				return 0;

	printf("This doesn't appear to be a complete usbpd1 image\n");
	return 1;
}

enum futil_file_type ft_recognize_usbpd1(uint8_t *buf, uint32_t len)
{
	uint32_t ro_size, rw_size, ro_offset, rw_offset;
	int s, h;

	/*
	 * Since we don't use any headers to identify or locate the pubkey and
	 * signature, in order to identify blob as the right type we have to
	 * just assume that the RO & RW are 1) both present, and 2) evenly
	 * split. Then we just try to use what we think might be the pubkey to
	 * validate what we think might be the signature.
	 */
	ro_offset = 0;
	ro_size = rw_size = rw_offset = len / 2;

	for (s = 0; s < ARRAY_SIZE(sigs); s++)
		for (h = 0; h < ARRAY_SIZE(hashes); h++)
			if (!check_self_consistency(buf, 0,
						    ro_size, rw_size,
						    ro_offset, rw_offset,
						    sigs[s], hashes[h]))
				return FILE_TYPE_USBPD1;

	return FILE_TYPE_UNKNOWN;
}
