/*
 * 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 "2sysincludes.h"
#include "2common.h"
#include "2sha.h"
#include "2rsa.h"
#include "file_type.h"
#include "futility.h"
#include "futility_options.h"
#include "vb21_common.h"
#include "host_common.h"
#include "host_key2.h"
#include "host_signature2.h"
#include "util_misc.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 int 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 int 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),
	};
	int 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 int 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;
	int 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;
}
