/*
 * Copyright (c) 2015, Google Inc.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#ifndef USE_HOSTCC
#include <common.h>
#include <fdtdec.h>
#include <u-boot/sha256.h>
#include <fuse.h>
#include <asm/byteorder.h>
#include <asm/errno.h>
#include <asm/unaligned.h>
#else
#include "fdt_host.h"
#include "mkimage.h"
#include <fdt_support.h>
#endif /* !USE_HOSTCC*/
#include <rsa-imx.h>

#ifdef USE_HOSTCC
static inline uint32_t get_unaligned_be32(const uint8_t *p)
{
    return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
}
static inline void put_unaligned_be32(uint32_t val, uint8_t *p)
{
    p[0] = val >> 24;
    p[1] = val >> 16;
    p[2] = val >> 8;
    p[3] = val;
}
#endif

#define KEY_INDEX_NODENAME "key_index" // We use this index to verify the key hasn't been revoked

/* Use Bank 4 Word 6 to store the kernel ITB signing key revocation mask.
 * Setting the LS bit revokes key 0, setting the MS bit revokes key 31
 */
#define KERNEL_ITB_KEY_REVOCATION_MASK_OCOTP_BANK 4
#define KERNEL_ITB_KEY_REVOCATION_MASK_OCOTP_WORD 6

#define UINT64_MULT32(v, multby)  (((uint64_t)(v)) * ((uint32_t)(multby)))

#define RSA2048_BYTES	(2048 / 8)

/* This is the maximum signature length that we support, in bits */
#define IMX_RSA_MAX_SIG_BITS	2048

static const uint8_t imx_padding_sha256_rsa2048[RSA2048_BYTES - SHA256_SUM_LEN] = {
	0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x31, 0x30,
	0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
	0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
};


/**
 * subtract_modulus() - subtract modulus from the given value
 *
 * @key:	Key containing modulus to subtract
 * @num:	Number to subtract modulus from, as little endian word array
 */
static void subtract_modulus(const struct imx_rsa_public_key *key, uint32_t num[])
{
	int64_t acc = 0;
	uint i;

	for (i = 0; i < key->len; i++) {
		acc += (uint64_t)num[i] - key->modulus[i];
		num[i] = (uint32_t)acc;
		acc >>= 32;
	}
}

/**
 * greater_equal_modulus() - check if a value is >= modulus
 *
 * @key:	Key containing modulus to check
 * @num:	Number to check against modulus, as little endian word array
 * @return 0 if num < modulus, 1 if num >= modulus
 */
static int greater_equal_modulus(const struct imx_rsa_public_key *key,
				 uint32_t num[])
{
	uint32_t i;

	for (i = key->len - 1; i >= 0; i--) {
		if (num[i] < key->modulus[i])
			return 0;
		if (num[i] > key->modulus[i])
			return 1;
	}

	return 1;  /* equal */
}

/**
 * montgomery_mul_add_step() - Perform montgomery multiply-add step
 *
 * Operation: montgomery result[] += a * b[] / n0inv % modulus
 *
 * @key:	RSA key
 * @result:	Place to put result, as little endian word array
 * @a:		Multiplier
 * @b:		Multiplicand, as little endian word array
 */
static void montgomery_mul_add_step(const struct imx_rsa_public_key *key,
		uint32_t result[], const uint32_t a, const uint32_t b[])
{
	uint64_t acc_a, acc_b;
	uint32_t d0;
	uint i;

	acc_a = (uint64_t)a * b[0] + result[0];
	d0 = (uint32_t)acc_a * key->n0inv;
	acc_b = (uint64_t)d0 * key->modulus[0] + (uint32_t)acc_a;
	for (i = 1; i < key->len; i++) {
		acc_a = (acc_a >> 32) + (uint64_t)a * b[i] + result[i];
		acc_b = (acc_b >> 32) + (uint64_t)d0 * key->modulus[i] +
				(uint32_t)acc_a;
		result[i - 1] = (uint32_t)acc_b;
	}

	acc_a = (acc_a >> 32) + (acc_b >> 32);

	result[i - 1] = (uint32_t)acc_a;

	if (acc_a >> 32)
		subtract_modulus(key, result);
}

/**
 * montgomery_mul() - Perform montgomery mutitply
 *
 * Operation: montgomery result[] = a[] * b[] / n0inv % modulus
 *
 * @key:	RSA key
 * @result:	Place to put result, as little endian word array
 * @a:		Multiplier, as little endian word array
 * @b:		Multiplicand, as little endian word array
 */
static void montgomery_mul(const struct imx_rsa_public_key *key,
		uint32_t result[], uint32_t a[], const uint32_t b[])
{
	uint i;

	for (i = 0; i < key->len; ++i)
		result[i] = 0;
	for (i = 0; i < key->len; ++i)
		montgomery_mul_add_step(key, result, a[i], b);
}

/**
 * pow_mod() - in-place public exponentiation
 *
 * @key:	RSA key
 * @inout:	Big-endian word array containing value and result
 */
static int pow_mod(const struct imx_rsa_public_key *key, uint32_t *inout)
{
	uint32_t *result, *ptr;
	uint i;

	/* Sanity check for stack size - key->len is in 32-bit words */
	if (key->len > IMX_RSA_MAX_KEY_BITS / 32) {
		debug("RSA key words %u exceeds maximum %d\n", key->len,
		      IMX_RSA_MAX_KEY_BITS / 32);
		return -EINVAL;
	}

	uint32_t val[key->len], acc[key->len], tmp[key->len];
	result = tmp;  /* Re-use location. */

	/* Convert from big endian byte array to little endian word array. */
	for (i = 0, ptr = inout + key->len - 1; i < key->len; i++, ptr--)
		val[i] = get_unaligned_be32((uint8_t *)ptr);

	montgomery_mul(key, acc, val, key->rr);  /* axx = a * RR / R mod M */
	for (i = 0; i < 16; i += 2) {
		montgomery_mul(key, tmp, acc, acc); /* tmp = acc^2 / R mod M */
		montgomery_mul(key, acc, tmp, tmp); /* acc = tmp^2 / R mod M */
	}
	montgomery_mul(key, result, acc, val);  /* result = XX * a / R mod M */

	/* Make sure result < mod; result is at most 1x mod too large. */
	if (greater_equal_modulus(key, result))
		subtract_modulus(key, result);

	/* Convert to bigendian byte array */
	for (i = key->len - 1, ptr = inout; (int)i >= 0; i--, ptr++)
		put_unaligned_be32(result[i], (uint8_t *)ptr);

	return 0;
}

int rsa_imx_verify_key(const struct imx_rsa_public_key *key, const uint8_t *sig,
		const uint32_t sig_len, const uint8_t *hash)
{
	const uint8_t *padding;
	int pad_len;
	int ret;

	if (!key || !sig || !hash)
		return -EIO;

	if (sig_len != (key->len * sizeof(uint32_t))) {
		debug("Signature is of incorrect length %d\n", sig_len);
		return -EINVAL;
	}

	/* Sanity check for stack size */
	if (sig_len > IMX_RSA_MAX_SIG_BITS / 8) {
		debug("Signature length %u exceeds maximum %d\n", sig_len,
		      IMX_RSA_MAX_SIG_BITS / 8);
		return -EINVAL;
	}

	uint32_t buf[sig_len / sizeof(uint32_t)];

	memcpy(buf, sig, sig_len);

	ret = pow_mod(key, buf);
	if (ret)
		return ret;

	/* Determine padding to use depending on the signature type. */
	padding = imx_padding_sha256_rsa2048;
	pad_len = RSA2048_BYTES - SHA256_SUM_LEN;

	/* Don't return early if either check fails, to prevent side channel attacks */

	/* Check pkcs1.5 padding bytes. */
	if (memcmp(buf, padding, pad_len)) {
		debug("In RSAVerify(): Padding check failed!\n");
		ret = -EINVAL;
	}

	/* Check hash. */
	if (memcmp((uint8_t *)buf + pad_len, hash, sig_len - pad_len)) {
		debug("In RSAVerify(): Hash check failed!\n");
		ret = -EACCES;
	}

	return ret;
}

static void rsa_convert_big_endian(uint32_t *dst, const uint32_t *src, int len)
{
	int i;

	for (i = 0; i < len; i++)
		dst[i] = fdt32_to_cpu(src[len - 1 - i]);
}

int rsa_imx_get_key(const void *fdt_blob, int node, struct imx_rsa_public_key *key)
{
	const void *modulus, *rr;

	if (node < 0) {
		debug("%s: Skipping invalid node", __func__);
		return -EBADF;
	}
	if (!fdt_getprop(fdt_blob, node, "rsa,n0-inverse", NULL)) {
		debug("%s: Missing rsa,n0-inverse", __func__);
		return -EFAULT;
	}

	key->len = fdtdec_get_int(fdt_blob, node, "rsa,num-bits", 0);
	key->n0inv = fdtdec_get_int(fdt_blob, node, "rsa,n0-inverse", 0);
	modulus = fdt_getprop(fdt_blob, node, "rsa,modulus", NULL);
	rr = fdt_getprop(fdt_blob, node, "rsa,r-squared", NULL);
	if (!key->len || !modulus || !rr) {
		debug("%s: Missing RSA key info", __func__);
		return -EFAULT;
	}

	/* Sanity check for stack size */
	if (key->len > IMX_RSA_MAX_KEY_BITS || key->len < IMX_RSA_MIN_KEY_BITS) {
		debug("RSA key bits %u outside allowed range %d..%d\n",
		      key->len, IMX_RSA_MIN_KEY_BITS, IMX_RSA_MAX_KEY_BITS);
		return -EFAULT;
	}
	key->len /= sizeof(uint32_t) * 8;

	rsa_convert_big_endian(key->modulus, modulus, key->len);
	rsa_convert_big_endian(key->rr, rr, key->len);

	debug("key length %d\n", key->len);

	return 0;
}

static int rsa_verify_with_keynode(struct image_sign_info *info,
		const void *hash, uint8_t *sig, uint sig_len, int node,
		uint32_t kernel_itb_key_revocation_mask)
{
	const void *blob = info->fdt_blob;
	struct imx_rsa_public_key key;
	int ret;
	int key_index;
	uint32_t key_mask;

	ret = rsa_imx_get_key(blob, node, &key);
	if (ret) {
		debug("%s: RSA failed to load key: %d\n", __func__, ret);
		return ret;
	}

	if (!fdt_getprop(blob, node, KEY_INDEX_NODENAME, NULL)) {
		debug("%s: No key index found\n", __func__);
		return -ENOENT;
	}

	/* Verify that the kernel ITB signing key hasn't been revoked.
	 * Key indices start at one, not zero.
	 */
	key_index = fdtdec_get_int(blob, node, KEY_INDEX_NODENAME, 0);
	key_mask = 1 << (key_index - 1);
	debug("(key_mask=0x%08x revocation mask=0x%08x)", key_mask, kernel_itb_key_revocation_mask);
	if (key_mask & kernel_itb_key_revocation_mask) {
		printf("ERROR: signing key has been revoked");
		return -ENOENT;
	}

	ret = rsa_imx_verify_key(&key, sig, sig_len, hash);
	if (ret) {
		printf("%s: RSA failed to verify: %d\n", __func__, ret);
		return ret;
	}

	return 0;
}

int rsa_imx_verify(struct image_sign_info *info,
	       const struct image_region region[], int region_count,
	       uint8_t *sig, uint sig_len)
{
	const void *blob = info->fdt_blob;
	uint8_t hash[SHA256_SUM_LEN];
	int sig_node, node;
	char name[100];
	sha256_context ctx;
	int ret, i;

	uint32_t kernel_itb_key_revocation_mask = 0;

#ifndef USE_HOSTCC
	ret = fuse_read(KERNEL_ITB_KEY_REVOCATION_MASK_OCOTP_BANK, KERNEL_ITB_KEY_REVOCATION_MASK_OCOTP_WORD, &kernel_itb_key_revocation_mask);
	if (ret) {
		debug("%s: Error reading kernel key revocation fuse: %i\n", __func__, ret);
		return ret;
	}
#endif

	sig_node = fdt_subnode_offset(blob, 0, FIT_SIG_NODENAME);
	if (sig_node < 0) {
		debug("%s: No signature node found\n", __func__);
		return -ENOENT;
	}

	sha256_starts(&ctx);
	for (i = 0; i < region_count; i++)
		sha256_update(&ctx, region[i].data, region[i].size);
	sha256_finish(&ctx, hash);

	/* Look for a key that matches our hint */
	snprintf(name, sizeof(name), "key-%s", info->keyname);
	node = fdt_subnode_offset(blob, sig_node, name);
	if (node < 0)
		return node;

	ret = rsa_verify_with_keynode(info, hash, sig, sig_len, node, kernel_itb_key_revocation_mask);
	if (!ret)
		return ret;

	return ret;
}
