/* 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.
 *
 * Boot descriptor block firmware functions
 */

#include "2sysincludes.h"
#include "2common.h"
#include "2sha.h"
#include "bdb.h"

/*****************************************************************************/

/**
 * Check if string contains a null terminator.
 *
 * Bytes after the null terminator do not need to be null.
 *
 * @param s		String to check
 * @param size		Size of string buffer in characters
 * @return 1 if string has a null terminator, 0 if not
 */
static int string_has_null(const char *s, size_t size)
{
	for (; size; size--) {
		if (*s++ == 0)
			return 1;
	}
	return 0;
}

int bdb_check_header(const struct bdb_header *p, size_t size)
{
	if (size < sizeof(*p) || size < p->struct_size)
		return BDB_ERROR_BUF_SIZE;

	if (p->struct_magic != BDB_HEADER_MAGIC)
		return BDB_ERROR_STRUCT_MAGIC;

	if (p->struct_major_version != BDB_HEADER_VERSION_MAJOR)
		return BDB_ERROR_STRUCT_VERSION;

	/* Note that minor version doesn't matter yet */

	if (p->struct_size < sizeof(*p))
		return BDB_ERROR_STRUCT_SIZE;

	if (p->oem_area_0_size & 3)
		return BDB_ERROR_OEM_AREA_SIZE;  /* Not 32-bit aligned */

	/*
	 * Make sure the BDB is at least big enough for us.  At this point, all
	 * the caller may have loaded is this header We'll check if there's
	 * space for everything else after we load it.
	 */
	if (p->bdb_size < sizeof(*p))
		return BDB_ERROR_BDB_SIZE;

	/*
	 * The rest of the fields don't matter yet; we'll check them when we
	 * check the BDB itself.
	 */
	return BDB_SUCCESS;
}

int bdb_check_key(const struct bdb_key *p, size_t size)
{
	size_t expect_key_size = 0;

	if (size < sizeof(*p) || size < p->struct_size)
		return BDB_ERROR_BUF_SIZE;

	if (p->struct_magic != BDB_KEY_MAGIC)
		return BDB_ERROR_STRUCT_MAGIC;

	if (p->struct_major_version != BDB_KEY_VERSION_MAJOR)
		return BDB_ERROR_STRUCT_VERSION;

	/* Note that minor version doesn't matter yet */

	if (!string_has_null(p->description, sizeof(p->description)))
		return BDB_ERROR_DESCRIPTION;

	/* We currently only support SHA-256 */
	if (p->hash_alg != BDB_HASH_ALG_SHA256)
		return BDB_ERROR_HASH_ALG;

	/* Make sure signature algorithm and size are correct */
	switch (p->sig_alg) {
	case BDB_SIG_ALG_RSA4096:
		expect_key_size = BDB_RSA4096_KEY_DATA_SIZE;
		break;
	case BDB_SIG_ALG_ECSDSA521:
		expect_key_size = BDB_ECDSA521_KEY_DATA_SIZE;
		break;
	case BDB_SIG_ALG_RSA3072B:
		expect_key_size = BDB_RSA3072B_KEY_DATA_SIZE;
		break;
	default:
		return BDB_ERROR_SIG_ALG;
	}

	if (p->struct_size < sizeof(*p) + expect_key_size)
		return BDB_ERROR_STRUCT_SIZE;

	return BDB_SUCCESS;
}

int bdb_check_sig(const struct bdb_sig *p, size_t size)
{
	size_t expect_sig_size = 0;

	if (size < sizeof(*p) || size < p->struct_size)
		return BDB_ERROR_BUF_SIZE;

	if (p->struct_magic != BDB_SIG_MAGIC)
		return BDB_ERROR_STRUCT_MAGIC;

	if (p->struct_major_version != BDB_SIG_VERSION_MAJOR)
		return BDB_ERROR_STRUCT_VERSION;

	/* Note that minor version doesn't matter yet */

	if (!string_has_null(p->description, sizeof(p->description)))
		return BDB_ERROR_DESCRIPTION;

	/* We currently only support SHA-256 */
	if (p->hash_alg != BDB_HASH_ALG_SHA256)
		return BDB_ERROR_HASH_ALG;

	/* Make sure signature algorithm and size are correct */
	switch (p->sig_alg) {
	case BDB_SIG_ALG_RSA4096:
		expect_sig_size = BDB_RSA4096_SIG_SIZE;
		break;
	case BDB_SIG_ALG_ECSDSA521:
		expect_sig_size = BDB_ECDSA521_SIG_SIZE;
		break;
	case BDB_SIG_ALG_RSA3072B:
		expect_sig_size = BDB_RSA3072B_SIG_SIZE;
		break;
	default:
		return BDB_ERROR_SIG_ALG;
	}

	if (p->struct_size < sizeof(*p) + expect_sig_size)
		return BDB_ERROR_STRUCT_SIZE;

	return BDB_SUCCESS;
}

int bdb_check_data(const struct bdb_data *p, size_t size)
{
	size_t need_size;

	if (size < sizeof(*p) || size < p->signed_size)
		return BDB_ERROR_BUF_SIZE;

	if (p->struct_magic != BDB_DATA_MAGIC)
		return BDB_ERROR_STRUCT_MAGIC;

	if (p->struct_major_version != BDB_DATA_VERSION_MAJOR)
		return BDB_ERROR_STRUCT_VERSION;

	/* Note that minor version doesn't matter yet */

	if (!string_has_null(p->description, sizeof(p->description)))
		return BDB_ERROR_DESCRIPTION;

	if (p->struct_size < sizeof(*p))
		return BDB_ERROR_STRUCT_SIZE;

	if (p->hash_entry_size < sizeof(struct bdb_hash))
		return BDB_ERROR_HASH_ENTRY_SIZE;

	/* Calculate expected size */
	need_size = p->struct_size + p->num_hashes * p->hash_entry_size;

	/* Make sure OEM area size doesn't cause wraparound */
	if (need_size + p->oem_area_1_size < need_size)
		return BDB_ERROR_OEM_AREA_SIZE;
	if (p->oem_area_1_size & 3)
		return BDB_ERROR_OEM_AREA_SIZE;  /* Not 32-bit aligned */
	need_size += p->oem_area_1_size;

	if (p->signed_size < need_size)
		return BDB_ERROR_SIGNED_SIZE;

	return BDB_SUCCESS;
}

/*****************************************************************************/

const struct bdb_header *bdb_get_header(const void *buf)
{
	return buf;
}

uint32_t bdb_size_of(const void *buf)
{
	return bdb_get_header(buf)->bdb_size;
}

const struct bdb_key *bdb_get_bdbkey(const void *buf)
{
	const struct bdb_header *h = bdb_get_header(buf);
	const uint8_t *b8 = buf;

	/* BDB key follows header */
	return (const struct bdb_key *)(b8 + h->struct_size);
}

const void *bdb_get_oem_area_0(const void *buf)
{
	const struct bdb_key *k = bdb_get_bdbkey(buf);
	const uint8_t *b8 = (const uint8_t *)k;

	/* OEM area 0 follows BDB key */
	return b8 + k->struct_size;
}

const struct bdb_key *bdb_get_datakey(const void *buf)
{
	const struct bdb_header *h = bdb_get_header(buf);
	const uint8_t *b8 = bdb_get_oem_area_0(buf);

	/* datakey follows OEM area 0 */
	return (const struct bdb_key *)(b8 + h->oem_area_0_size);
}

ptrdiff_t bdb_offset_of_datakey(const void *buf)
{
	return vb2_offset_of(buf, bdb_get_datakey(buf));
}

const struct bdb_sig *bdb_get_header_sig(const void *buf)
{
	const struct bdb_header *h = bdb_get_header(buf);
	const uint8_t *b8 = bdb_get_oem_area_0(buf);

	/* Header signature starts after signed data */
	return (const struct bdb_sig *)(b8 + h->signed_size);
}

ptrdiff_t bdb_offset_of_header_sig(const void *buf)
{
	return vb2_offset_of(buf, bdb_get_header_sig(buf));
}

const struct bdb_data *bdb_get_data(const void *buf)
{
	const struct bdb_sig *s = bdb_get_header_sig(buf);
	const uint8_t *b8 = (const uint8_t *)s;

	/* Data follows header signature */
	return (const struct bdb_data *)(b8 + s->struct_size);
}

ptrdiff_t bdb_offset_of_data(const void *buf)
{
	return vb2_offset_of(buf, bdb_get_data(buf));
}

const void *bdb_get_oem_area_1(const void *buf)
{
	const struct bdb_data *p = bdb_get_data(buf);
	const uint8_t *b8 = (const uint8_t *)p;

	/* OEM area 1 follows BDB data */
	return b8 + p->struct_size;
}

static const void *bdb_get_hash(const void *buf)
{
	const struct bdb_data *data = bdb_get_data(buf);
	const uint8_t *b8 = bdb_get_oem_area_1(buf);

	/* Hashes follow OEM area 0 */
	return b8 + data->oem_area_1_size;
}

const struct bdb_hash *bdb_get_hash_by_type(const void *buf,
					    enum bdb_data_type type)
{
	const struct bdb_data *data = bdb_get_data(buf);
	const uint8_t *b8 = bdb_get_hash(buf);
	int i;

	/* Search for a matching hash */
	for (i = 0; i < data->num_hashes; i++, b8 += data->hash_entry_size) {
		const struct bdb_hash *h = (const struct bdb_hash *)b8;

		if (h->type == type)
			return h;
	}

	return NULL;
}

const struct bdb_hash *bdb_get_hash_by_index(const void *buf, int index)
{
	const struct bdb_data *data = bdb_get_data(buf);
	const uint8_t *p = bdb_get_hash(buf);
	const struct bdb_hash *h = NULL;
	int i;

	/* Search for a matching hash */
	for (i = 0; i < data->num_hashes; i++, p += data->hash_entry_size) {
		if (i == index) {
			h = (const struct bdb_hash *)p;
			break;
		}
	}

	return h;
}

const struct bdb_sig *bdb_get_data_sig(const void *buf)
{
	const struct bdb_data *data = bdb_get_data(buf);
	const uint8_t *b8 = (const uint8_t *)data;

	/* Data signature starts after signed data */
	return (const struct bdb_sig *)(b8 + data->signed_size);
}

/*****************************************************************************/

static int bdb_verify_sig(const struct bdb_key *key,
			  const struct bdb_sig *sig,
			  const uint8_t *digest)
{
	/* Key and signature algorithms must match */
	if (key->sig_alg != sig->sig_alg)
		return BDB_ERROR_SIG_ALG;

	switch (key->sig_alg) {
	case BDB_SIG_ALG_RSA4096:
		if (bdb_rsa4096_verify(key->key_data, sig->sig_data, digest))
			return BDB_ERROR_VERIFY_SIG;
		break;
	case BDB_SIG_ALG_ECSDSA521:
		if (bdb_ecdsa521_verify(key->key_data, sig->sig_data, digest))
			return BDB_ERROR_VERIFY_SIG;
		break;
	case BDB_SIG_ALG_RSA3072B:
		if (bdb_rsa3072b_verify(key->key_data, sig->sig_data, digest))
			return BDB_ERROR_VERIFY_SIG;
		break;
	default:
		return BDB_ERROR_VERIFY_SIG;
	}

	return BDB_SUCCESS;
}

int bdb_verify(const void *buf, size_t size, const uint8_t *bdb_key_digest)
{
	const uint8_t *end = (const uint8_t *)buf + size;
	const struct bdb_header *h;
	const struct bdb_key *bdbkey, *datakey;
	const struct bdb_sig *sig;
	const struct bdb_data *data;
	const void *oem;
	uint8_t digest[BDB_SHA256_DIGEST_SIZE];
	int bdb_digest_mismatch = -1;

	/* Make sure buffer doesn't wrap around address space */
	if (end < (const uint8_t *)buf)
		return BDB_ERROR_BUF_SIZE;

	/*
	 * Check header now that we've actually loaded it.  We can't guarantee
	 * this is the same header which was checked before.
	 */
	h = bdb_get_header(buf);
	if (bdb_check_header(h, size))
		return BDB_ERROR_HEADER;

	/* Sanity-check BDB key */
	bdbkey = bdb_get_bdbkey(buf);
	if (bdb_check_key(bdbkey, end - (const uint8_t *)bdbkey))
		return BDB_ERROR_BDBKEY;

	/* Calculate BDB key digest and compare with expected */
	if (vb2_digest_buffer((uint8_t *)bdbkey, bdbkey->struct_size,
			      VB2_HASH_SHA256, digest, BDB_SHA256_DIGEST_SIZE))
		return BDB_ERROR_DIGEST;

	if (bdb_key_digest)
		bdb_digest_mismatch = memcmp(digest,
					     bdb_key_digest, sizeof(digest));

	/* Make sure OEM area 0 fits */
	oem = bdb_get_oem_area_0(buf);
	if (h->oem_area_0_size > end - (const uint8_t *)oem)
		return BDB_ERROR_OEM_AREA_0;

	/* Sanity-check datakey */
	datakey = bdb_get_datakey(buf);
	if (bdb_check_key(datakey, end - (const uint8_t *)datakey))
		return BDB_ERROR_DATAKEY;

	/* Make sure enough data was signed, and the signed data fits */
	if (h->oem_area_0_size + datakey->struct_size > h->signed_size ||
	    h->signed_size > end - (const uint8_t *)oem)
		return BDB_ERROR_BDB_SIGNED_SIZE;

	/* Sanity-check header signature */
	sig = bdb_get_header_sig(buf);
	if (bdb_check_sig(sig, end - (const uint8_t *)sig))
		return BDB_ERROR_HEADER_SIG;

	/* Make sure it signed the right amount of data */
	if (sig->signed_size != h->signed_size)
		return BDB_ERROR_HEADER_SIG;

	/* Calculate header digest and compare with expected signature */
	if (vb2_digest_buffer((uint8_t *)oem, h->signed_size,
			      VB2_HASH_SHA256, digest, BDB_SHA256_DIGEST_SIZE))
		return BDB_ERROR_DIGEST;
	if (bdb_verify_sig(bdbkey, sig, digest))
		return BDB_ERROR_HEADER_SIG;

	/*
	 * Sanity-check data struct.  This also checks that OEM area 1 and the
	 * hashes fit in the remaining buffer.
	 */
	data = bdb_get_data(buf);
	if (bdb_check_data(data, end - (const uint8_t *)data))
		return BDB_ERROR_DATA;

	/* Sanity-check data signature */
	sig = bdb_get_data_sig(buf);
	if (bdb_check_sig(sig, end - (const uint8_t *)sig))
		return BDB_ERROR_DATA_CHECK_SIG;
	if (sig->signed_size != data->signed_size)
		return BDB_ERROR_DATA_SIGNED_SIZE;

	/* Calculate data digest and compare with expected signature */
	if (vb2_digest_buffer((uint8_t *)data, data->signed_size,
			      VB2_HASH_SHA256, digest, BDB_SHA256_DIGEST_SIZE))
		return BDB_ERROR_DIGEST;
	if (bdb_verify_sig(datakey, sig, digest))
		return BDB_ERROR_DATA_SIG;

	/* Return success or success-other-than-BDB-key-mismatch */
	return bdb_digest_mismatch ? BDB_GOOD_OTHER_THAN_KEY : BDB_SUCCESS;
}
