/* 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 =
			(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);
	}
}


static const uint8_t crypto_to_sig[] = {
	VB2_SIG_RSA1024,
	VB2_SIG_RSA1024,
	VB2_SIG_RSA1024,
	VB2_SIG_RSA2048,
	VB2_SIG_RSA2048,
	VB2_SIG_RSA2048,
	VB2_SIG_RSA4096,
	VB2_SIG_RSA4096,
	VB2_SIG_RSA4096,
	VB2_SIG_RSA8192,
	VB2_SIG_RSA8192,
	VB2_SIG_RSA8192,
	VB2_SIG_RSA2048_EXP3,
	VB2_SIG_RSA2048_EXP3,
	VB2_SIG_RSA2048_EXP3,
	VB2_SIG_RSA3072_EXP3,
	VB2_SIG_RSA3072_EXP3,
	VB2_SIG_RSA3072_EXP3,
};

/**
 * Convert vb2_crypto_algorithm to vb2_signature_algorithm.
 *
 * @param algorithm	Crypto algorithm (vb2_crypto_algorithm)
 *
 * @return The signature algorithm for that crypto algorithm, or
 * VB2_SIG_INVALID if the crypto algorithm or its corresponding signature
 * algorithm is invalid or not supported.
 */
enum vb2_signature_algorithm vb2_crypto_to_signature(uint32_t algorithm)
{
	if (algorithm < ARRAY_SIZE(crypto_to_sig))
		return crypto_to_sig[algorithm];
	else
		return VB2_SIG_INVALID;
}

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.
 */
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;

	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;
	}

	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;
}
