/* Copyright (c) 2014 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.
 */

/*
 * Implementation of RSA signature verification which uses a pre-processed key
 * for computation. The code extends Android's RSA verification code to support
 * multiple RSA key lengths and hash digest algorithms.
 */

#include "2common.h"
#include "2rsa.h"
#include "2sha.h"
#include "2sysincludes.h"
#include "vboot_test.h"

/**
 * a[] -= mod
 */
static void subM(const struct vb2_public_key *key, uint32_t *a)
{
	int64_t A = 0;
	uint32_t i;
	for (i = 0; i < key->arrsize; ++i) {
		A += (uint64_t)a[i] - key->n[i];
		a[i] = (uint32_t)A;
		A >>= 32;
	}
}

/**
 * Return a[] >= mod
 */
int vb2_mont_ge(const struct vb2_public_key *key, uint32_t *a)
{
	uint32_t i;
	for (i = key->arrsize; i;) {
		--i;
		if (a[i] < key->n[i])
			return 0;
		if (a[i] > key->n[i])
			return 1;
	}
	return 1;  /* equal */
}

/**
 * Montgomery c[] += a * b[] / R % mod
 */
static void montMulAdd(const struct vb2_public_key *key,
		       uint32_t *c,
		       const uint32_t a,
		       const uint32_t *b)
{
	uint64_t A = (uint64_t)a * b[0] + c[0];
	uint32_t d0 = (uint32_t)A * key->n0inv;
	uint64_t B = (uint64_t)d0 * key->n[0] + (uint32_t)A;
	uint32_t i;

	for (i = 1; i < key->arrsize; ++i) {
		A = (A >> 32) + (uint64_t)a * b[i] + c[i];
		B = (B >> 32) + (uint64_t)d0 * key->n[i] + (uint32_t)A;
		c[i - 1] = (uint32_t)B;
	}

	A = (A >> 32) + (B >> 32);

	c[i - 1] = (uint32_t)A;

	if (A >> 32) {
		subM(key, c);
	}
}

/**
 * Montgomery c[] += 0 * b[] / R % mod
 */
static void montMulAdd0(const struct vb2_public_key *key,
			uint32_t *c,
			const uint32_t *b)
{
	uint32_t d0 = c[0] * key->n0inv;
	uint64_t B = (uint64_t)d0 * key->n[0] + c[0];
	uint32_t i;

	for (i = 1; i < key->arrsize; ++i) {
		B = (B >> 32) + (uint64_t)d0 * key->n[i] + c[i];
		c[i - 1] = (uint32_t)B;
	}

	c[i - 1] = B >> 32;
}

/**
 * Montgomery c[] = a[] * b[] / R % mod
 */
static void montMul(const struct vb2_public_key *key,
		    uint32_t *c,
		    const uint32_t *a,
		    const uint32_t *b)
{
	uint32_t i;
	for (i = 0; i < key->arrsize; ++i) {
		c[i] = 0;
	}
	for (i = 0; i < key->arrsize; ++i) {
		montMulAdd(key, c, a[i], b);
	}
}

/* Montgomery c[] = a[] * 1 / R % key. */
static void montMul1(const struct vb2_public_key *key,
		     uint32_t *c,
		     const uint32_t *a)
{
	int i;

	for (i = 0; i < key->arrsize; ++i)
		c[i] = 0;

	montMulAdd(key, c, 1, a);
	for (i = 1; i < key->arrsize; ++i)
		montMulAdd0(key, c, a);
}

/**
 * In-place public exponentiation.
 *
 * @param key		Key to use in signing
 * @param inout		Input and output big-endian byte array
 * @param workbuf32	Work buffer; caller must verify this is
 *			(3 * key->arrsize) elements long.
 * @param exp		RSA public exponent: either 65537 (F4) or 3
 */
static void modpow(const struct vb2_public_key *key, uint8_t *inout,
		uint32_t *workbuf32, int exp)
{
	uint32_t *a = workbuf32;
	uint32_t *aR = a + key->arrsize;
	uint32_t *aaR = aR + key->arrsize;
	uint32_t *aaa = aaR;  /* Re-use location. */
	int i;

	/* Convert from big endian byte array to little endian word array. */
	for (i = 0; i < (int)key->arrsize; ++i) {
		uint32_t tmp =
			((uint32_t)inout[((key->arrsize - 1 - i) * 4) + 0]
				<< 24) |
			(inout[((key->arrsize - 1 - i) * 4) + 1] << 16) |
			(inout[((key->arrsize - 1 - i) * 4) + 2] << 8) |
			(inout[((key->arrsize - 1 - i) * 4) + 3] << 0);
		a[i] = tmp;
	}

	montMul(key, aR, a, key->rr);  /* aR = a * RR / R mod M   */
	if (exp == 3) {
		montMul(key, aaR, aR, aR); /* aaR = aR * aR / R mod M */
		montMul(key, a, aaR, aR); /* a = aaR * aR / R mod M */
		montMul1(key, aaa, a); /* aaa = a * 1 / R mod M */
	} else {
		/* Exponent 65537 */
		for (i = 0; i < 16; i+=2) {
			montMul(key, aaR, aR, aR);  /* aaR = aR * aR / R mod M */
			montMul(key, aR, aaR, aaR);  /* aR = aaR * aaR / R mod M */
		}
		montMul(key, aaa, aR, a);  /* aaa = aR * a / R mod M */
	}

	/* Make sure aaa < mod; aaa is at most 1x mod too large. */
	if (vb2_mont_ge(key, aaa)) {
		subM(key, aaa);
	}

	/* Convert to bigendian byte array */
	for (i = (int)key->arrsize - 1; i >= 0; --i) {
		uint32_t tmp = aaa[i];
		*inout++ = (uint8_t)(tmp >> 24);
		*inout++ = (uint8_t)(tmp >> 16);
		*inout++ = (uint8_t)(tmp >>  8);
		*inout++ = (uint8_t)(tmp >>  0);
	}
}

uint32_t vb2_rsa_sig_size(enum vb2_signature_algorithm sig_alg)
{
	switch (sig_alg) {
	case VB2_SIG_RSA1024:
		return 1024 / 8;
	case VB2_SIG_RSA2048:
	case VB2_SIG_RSA2048_EXP3:
		return 2048 / 8;
	case VB2_SIG_RSA3072_EXP3:
		return 3072 / 8;
	case VB2_SIG_RSA4096:
		return 4096 / 8;
	case VB2_SIG_RSA8192:
		return 8192 / 8;
	default:
		return 0;
	}
}

/**
 * Return the exponent used by an RSA algorithm
 *
 * @param sig_alg	Signature algorithm
 * @return The exponent to use (3 or 65537(F4)), or 0 if error.
 */
static uint32_t vb2_rsa_exponent(enum vb2_signature_algorithm sig_alg)
{
	switch (sig_alg) {
	case VB2_SIG_RSA1024:
	case VB2_SIG_RSA2048:
	case VB2_SIG_RSA4096:
	case VB2_SIG_RSA8192:
		return 65537;
	case VB2_SIG_RSA2048_EXP3:
	case VB2_SIG_RSA3072_EXP3:
		return 3;
	default:
		return 0;
	}
}

uint32_t vb2_packed_key_size(enum vb2_signature_algorithm sig_alg)
{
	uint32_t sig_size = vb2_rsa_sig_size(sig_alg);

	if (!sig_size)
		return 0;

	/*
	 * Total size needed by a RSAPublicKey buffer is =
	 *  2 * key_len bytes for the n and rr arrays
	 *  + sizeof len + sizeof n0inv.
	 */
	return 2 * sig_size + 2 * sizeof(uint32_t);
}

/*
 * PKCS 1.5 padding (from the RSA PKCS#1 v2.1 standard)
 *
 * Depending on the RSA key size and hash function, the padding is calculated
 * as follows:
 *
 * 0x00 || 0x01 || PS || 0x00 || T
 *
 * T: DER Encoded DigestInfo value which depends on the hash function used.
 *
 * SHA-1:   (0x)30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14 || H.
 * SHA-256: (0x)30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20 || H.
 * SHA-512: (0x)30 51 30 0d 06 09 60 86 48 01 65 03 04 02 03 05 00 04 40 || H.
 *
 * Length(T) = 35 octets for SHA-1
 * Length(T) = 51 octets for SHA-256
 * Length(T) = 83 octets for SHA-512
 *
 * PS: octet string consisting of {Length(RSA Key) - Length(T) - 3} 0xFF
 */
static const uint8_t sha1_tail[] = {
	0x00,0x30,0x21,0x30,0x09,0x06,0x05,0x2b,
	0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14
};

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

static const uint8_t sha512_tail[] = {
	0x00,0x30,0x51,0x30,0x0d,0x06,0x09,0x60,
	0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,
	0x05,0x00,0x04,0x40
};

/**
 * Check pkcs 1.5 padding bytes
 *
 * @param sig		Signature to verify
 * @param key		Key to take signature and hash algorithms from
 * @return VB2_SUCCESS, or non-zero if error.
 */
test_mockable
vb2_error_t vb2_check_padding(const uint8_t *sig,
			      const struct vb2_public_key *key)
{
	/* Determine padding to use depending on the signature type */
	uint32_t sig_size = vb2_rsa_sig_size(key->sig_alg);
	uint32_t hash_size = vb2_digest_size(key->hash_alg);
	uint32_t pad_size = sig_size - hash_size;
	const uint8_t *tail;
	uint32_t tail_size;
	int result = 0;
	int i;

	if (!sig_size || !hash_size || hash_size > sig_size)
		return VB2_ERROR_RSA_PADDING_SIZE;

	switch (key->hash_alg) {
	case VB2_HASH_SHA1:
		tail = sha1_tail;
		tail_size = sizeof(sha1_tail);
		break;
	case VB2_HASH_SHA256:
		tail = sha256_tail;
		tail_size = sizeof(sha256_tail);
		break;
	case VB2_HASH_SHA512:
		tail = sha512_tail;
		tail_size = sizeof(sha512_tail);
		break;
	default:
		return VB2_ERROR_RSA_PADDING_ALGORITHM;
	}

	/* First 2 bytes are always 0x00 0x01 */
	result |= *sig++ ^ 0x00;
	result |= *sig++ ^ 0x01;

	/* Then 0xff bytes until the tail */
	for (i = 0; i < pad_size - tail_size - 2; i++)
		result |= *sig++ ^ 0xff;

	/*
	 * Then the tail.  Even though there are probably no timing issues
	 * here, we use vb2_safe_memcmp() just to be on the safe side.
	 */
	result |= vb2_safe_memcmp(sig, tail, tail_size);

	return result ? VB2_ERROR_RSA_PADDING : VB2_SUCCESS;
}

vb2_error_t vb2_rsa_verify_digest(const struct vb2_public_key *key,
				  uint8_t *sig, const uint8_t *digest,
				  const struct vb2_workbuf *wb)
{
	struct vb2_workbuf wblocal = *wb;
	uint32_t *workbuf32;
	uint32_t key_bytes;
	int sig_size;
	int pad_size;
	int exp;
	vb2_error_t rv = VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;

	if (!key || !sig || !digest)
		return VB2_ERROR_RSA_VERIFY_PARAM;

	sig_size = vb2_rsa_sig_size(key->sig_alg);
	exp = vb2_rsa_exponent(key->sig_alg);
	if (!sig_size || !exp) {
		VB2_DEBUG("Invalid signature type!\n");
		return VB2_ERROR_RSA_VERIFY_ALGORITHM;
	}

	/* Signature length should be same as key length */
	key_bytes = key->arrsize * sizeof(uint32_t);
	if (key_bytes != sig_size) {
		VB2_DEBUG("Signature is of incorrect length!\n");
		return VB2_ERROR_RSA_VERIFY_SIG_LEN;
	}

	workbuf32 = vb2_workbuf_alloc(&wblocal, 3 * key_bytes);
	if (!workbuf32) {
		VB2_DEBUG("ERROR - vboot2 work buffer too small!\n");
		return VB2_ERROR_RSA_VERIFY_WORKBUF;
	}

	if (key->allow_hwcrypto) {
		rv = vb2ex_hwcrypto_modexp(key, sig, workbuf32, exp);

		if (rv == VB2_SUCCESS)
			VB2_DEBUG("Using HW modexp engine for sig_alg %d\n",
					key->sig_alg);
		else
			VB2_DEBUG("HW modexp for sig_alg %d not supported, using SW\n",
					key->sig_alg);
	} else {
		VB2_DEBUG("HW modexp forbidden, using SW\n");
	}

	if (rv != VB2_SUCCESS) {
		modpow(key, sig, workbuf32, exp);
	}

	vb2_workbuf_free(&wblocal, 3 * key_bytes);

	/*
	 * Check padding.  Only fail immediately if the padding size is bad.
	 * Otherwise, continue on to check the digest to reduce the risk of
	 * timing based attacks.
	 */
	rv = vb2_check_padding(sig, key);
	if (rv == VB2_ERROR_RSA_PADDING_SIZE)
		return rv;

	/*
	 * Check digest.  Even though there are probably no timing issues here,
	 * use vb2_safe_memcmp() just to be on the safe side.  (That's also why
	 * we don't return before this check if the padding check failed.)
	 */
	pad_size = sig_size - vb2_digest_size(key->hash_alg);
	if (vb2_safe_memcmp(sig + pad_size, digest, key_bytes - pad_size)) {
		VB2_DEBUG("Digest check failed!\n");
		if (!rv)
			rv = VB2_ERROR_RSA_VERIFY_DIGEST;
	}

	return rv;
}
