/* 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.
 *
 * Signature validation functions
 */

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

const char *vb21_common_desc(const void *buf)
{
	const struct vb21_struct_common *c = buf;

	return c->desc_size ? (const char *)c + c->fixed_size : "";
}

int vb21_verify_common_header(const void *parent, uint32_t parent_size)
{
	const struct vb21_struct_common *c = parent;

	/* Parent buffer size must be at least the claimed total size */
	if (parent_size < c->total_size)
		return VB2_ERROR_COMMON_TOTAL_SIZE;

	/*
	 * And big enough for the fixed size, which itself must be at least as
	 * big as the common struct header.
	 */
	if (c->total_size < c->fixed_size || c->fixed_size < sizeof(*c))
		return VB2_ERROR_COMMON_FIXED_SIZE;

	/* Make sure sizes are all multiples of 32 bits */
	if (!vb2_aligned(c->total_size, sizeof(uint32_t)))
		return VB2_ERROR_COMMON_TOTAL_UNALIGNED;
	if (!vb2_aligned(c->fixed_size, sizeof(uint32_t)))
		return VB2_ERROR_COMMON_FIXED_UNALIGNED;
	if (!vb2_aligned(c->desc_size, sizeof(uint32_t)))
		return VB2_ERROR_COMMON_DESC_UNALIGNED;

	/* Check description */
	if (c->desc_size > 0) {
		/* Make sure description fits and doesn't wrap */
		if (c->fixed_size + c->desc_size < c->fixed_size)
			return VB2_ERROR_COMMON_DESC_WRAPS;
		if (c->fixed_size + c->desc_size > c->total_size)
			return VB2_ERROR_COMMON_DESC_SIZE;

		/* Description must be null-terminated */
		if (vb21_common_desc(c)[c->desc_size - 1] != 0)
			return VB2_ERROR_COMMON_DESC_TERMINATOR;
	}

	return VB2_SUCCESS;
}

int vb21_verify_common_member(const void *parent,
			      uint32_t *min_offset,
			      uint32_t member_offset,
			      uint32_t member_size)
{
	const struct vb21_struct_common *c = parent;
	uint32_t member_end = member_offset + member_size;

	/* Make sure member doesn't wrap */
	if (member_end < member_offset)
		return VB2_ERROR_COMMON_MEMBER_WRAPS;

	/* Member offset and size must be 32-bit aligned */
	if (!vb2_aligned(member_offset, sizeof(uint32_t)) ||
	    !vb2_aligned(member_size, sizeof(uint32_t)))
		return VB2_ERROR_COMMON_MEMBER_UNALIGNED;

	/* Initialize minimum offset if necessary */
	if (!*min_offset)
		*min_offset = c->fixed_size + c->desc_size;

	/* Member must be after minimum offset */
	if (member_offset < *min_offset)
		return VB2_ERROR_COMMON_MEMBER_OVERLAP;

	/* Member must end before total size */
	if (member_end > c->total_size)
		return VB2_ERROR_COMMON_MEMBER_SIZE;

	/* Update minimum offset for subsequent checks */
	*min_offset = member_end;

	return VB2_SUCCESS;
}

int vb21_verify_common_subobject(const void *parent,
				 uint32_t *min_offset,
				 uint32_t member_offset)
{
	const struct vb21_struct_common *p = parent;
	const struct vb21_struct_common *m =
		(const struct vb21_struct_common *)
		((const uint8_t *)parent + member_offset);
	int rv;

	/*
	 * Verify the parent has space at the member offset for the common
	 * header.
	 */
	rv = vb21_verify_common_member(parent, min_offset, member_offset,
				      sizeof(*m));
	if (rv)
		return rv;

	/*
	 * Now it's safe to look at the member's header, and verify any
	 * additional data for the object past its common header fits in the
	 * parent.
	 */
	rv = vb21_verify_common_header(m, p->total_size - member_offset);
	if (rv)
		return rv;

	/* Advance the min offset to the end of the subobject */
	*min_offset = member_offset + m->total_size;

	return VB2_SUCCESS;
}

uint32_t vb2_sig_size(enum vb2_signature_algorithm sig_alg,
		      enum vb2_hash_algorithm hash_alg)
{
	uint32_t digest_size = vb2_digest_size(hash_alg);

	/* Fail if we don't support the hash algorithm */
	if (!digest_size)
		return 0;

	/* Handle unsigned hashes */
	if (sig_alg == VB2_SIG_NONE)
		return digest_size;

	return vb2_rsa_sig_size(sig_alg);
}

const struct vb2_id *vb2_hash_id(enum vb2_hash_algorithm hash_alg)
{
	switch(hash_alg) {
#ifdef VB2_SUPPORT_SHA1
	case VB2_HASH_SHA1:
		{
			static const struct vb2_id id = VB2_ID_NONE_SHA1;
			return &id;
		}
#endif
#ifdef VB2_SUPPORT_SHA256
	case VB2_HASH_SHA256:
		{
			static const struct vb2_id id = VB2_ID_NONE_SHA256;
			return &id;
		}
#endif
#ifdef VB2_SUPPORT_SHA512
	case VB2_HASH_SHA512:
		{
			static const struct vb2_id id = VB2_ID_NONE_SHA512;
			return &id;
		}
#endif
	default:
		return NULL;
	}
}

int vb21_verify_signature(const struct vb21_signature *sig, uint32_t size)
{
	uint32_t min_offset = 0;
	uint32_t expect_sig_size;
	int rv;

	/* Check magic number */
	if (sig->c.magic != VB21_MAGIC_SIGNATURE)
		return VB2_ERROR_SIG_MAGIC;

	/* Make sure common header is good */
	rv = vb21_verify_common_header(sig, size);
	if (rv)
		return rv;

	/*
	 * Check for compatible version.  No need to check minor version, since
	 * that's compatible across readers matching the major version, and we
	 * haven't added any new fields.
	 */
	if (sig->c.struct_version_major != VB21_SIGNATURE_VERSION_MAJOR)
		return VB2_ERROR_SIG_VERSION;

	/* Make sure header is big enough for signature */
	if (sig->c.fixed_size < sizeof(*sig))
		return VB2_ERROR_SIG_HEADER_SIZE;

	/* Make sure signature data is inside */
	rv = vb21_verify_common_member(sig, &min_offset,
				      sig->sig_offset, sig->sig_size);
	if (rv)
		return rv;

	/* Make sure signature size is correct for the algorithm */
	expect_sig_size = vb2_sig_size(sig->sig_alg, sig->hash_alg);
	if (!expect_sig_size)
		return VB2_ERROR_SIG_ALGORITHM;
	if (sig->sig_size != expect_sig_size)
		return VB2_ERROR_SIG_SIZE;

	return VB2_SUCCESS;
}

/**
 * Return the signature data for a signature
 */
static uint8_t *vb21_signature_data(struct vb21_signature *sig)
{
	return (uint8_t *)sig + sig->sig_offset;
}

int vb21_verify_digest(const struct vb2_public_key *key,
		       struct vb21_signature *sig,
		       const uint8_t *digest,
		       const struct vb2_workbuf *wb)
{
	uint32_t key_sig_size = vb2_sig_size(key->sig_alg, key->hash_alg);

	/* If we can't figure out the signature size, key algorithm was bad */
	if (!key_sig_size)
		return VB2_ERROR_VDATA_ALGORITHM;

	/* Make sure the signature and key algorithms match */
	if (key->sig_alg != sig->sig_alg || key->hash_alg != sig->hash_alg)
		return VB2_ERROR_VDATA_ALGORITHM_MISMATCH;

	if (sig->sig_size != key_sig_size)
		return VB2_ERROR_VDATA_SIG_SIZE;

	if (key->sig_alg == VB2_SIG_NONE) {
		/* Bare hash */
		if (vb2_safe_memcmp(vb21_signature_data(sig),
				    digest, key_sig_size))
			return VB2_ERROR_VDATA_VERIFY_DIGEST;

		return VB2_SUCCESS;
	} else {
		/* RSA-signed digest */
		return vb2_rsa_verify_digest(key,
					     vb21_signature_data(sig),
					     digest, wb);
	}
}

int vb21_verify_data(const void *data,
		     uint32_t size,
		     struct vb21_signature *sig,
		     const struct vb2_public_key *key,
		     const struct vb2_workbuf *wb)
{
	struct vb2_workbuf wblocal = *wb;
	struct vb2_digest_context *dc;
	uint8_t *digest;
	uint32_t digest_size;
	int rv;

	if (sig->data_size != size) {
		VB2_DEBUG("Wrong amount of data signed.\n");
		return VB2_ERROR_VDATA_SIZE;
	}

	/* Digest goes at start of work buffer */
	digest_size = vb2_digest_size(key->hash_alg);
	if (!digest_size)
		return VB2_ERROR_VDATA_DIGEST_SIZE;

	digest = vb2_workbuf_alloc(&wblocal, digest_size);
	if (!digest)
		return VB2_ERROR_VDATA_WORKBUF_DIGEST;

	/* Hashing requires temp space for the context */
	dc = vb2_workbuf_alloc(&wblocal, sizeof(*dc));
	if (!dc)
		return VB2_ERROR_VDATA_WORKBUF_HASHING;

	rv = vb2_digest_init(dc, key->hash_alg);
	if (rv)
		return rv;

	rv = vb2_digest_extend(dc, data, size);
	if (rv)
		return rv;

	rv = vb2_digest_finalize(dc, digest, digest_size);
	if (rv)
		return rv;

	vb2_workbuf_free(&wblocal, sizeof(*dc));

	return vb21_verify_digest(key, sig, digest, &wblocal);
}

int vb21_verify_keyblock(struct vb21_keyblock *block,
			 uint32_t size,
			 const struct vb2_public_key *key,
			 const struct vb2_workbuf *wb)
{
	uint32_t min_offset = 0, sig_offset;
	int rv, i;

	/* Check magic number */
	if (block->c.magic != VB21_MAGIC_KEYBLOCK)
		return VB2_ERROR_KEYBLOCK_MAGIC;

	/* Make sure common header is good */
	rv = vb21_verify_common_header(block, size);
	if (rv)
		return rv;

	/*
	 * Check for compatible version.  No need to check minor version, since
	 * that's compatible across readers matching the major version, and we
	 * haven't added any new fields.
	 */
	if (block->c.struct_version_major != VB21_KEYBLOCK_VERSION_MAJOR)
		return VB2_ERROR_KEYBLOCK_HEADER_VERSION;

	/* Make sure header is big enough */
	if (block->c.fixed_size < sizeof(*block))
		return VB2_ERROR_KEYBLOCK_SIZE;

	/* Make sure data key is inside */
	rv = vb21_verify_common_subobject(block, &min_offset,
					  block->key_offset);
	if (rv)
		return rv;

	/* Loop over signatures */
	sig_offset = block->sig_offset;
	for (i = 0; i < block->sig_count; i++, sig_offset = min_offset) {
		struct vb21_signature *sig;

		/* Make sure signature is inside keyblock */
		rv = vb21_verify_common_subobject(block, &min_offset,
						 sig_offset);
		if (rv)
			return rv;

		sig = (struct vb21_signature *)((uint8_t *)block + sig_offset);

		/* Verify the signature integrity */
		rv = vb21_verify_signature(sig,
					  block->c.total_size - sig_offset);
		if (rv)
			return rv;

		/* Skip signature if it doesn't match the key ID */
		if (memcmp(&sig->id, key->id, VB2_ID_NUM_BYTES))
			continue;

		/* Make sure we signed the right amount of data */
		if (sig->data_size != block->sig_offset)
			return VB2_ERROR_KEYBLOCK_SIGNED_SIZE;

		return vb21_verify_data(block, block->sig_offset, sig, key, wb);
	}

	/* If we're still here, no signature matched the key ID */
	return VB2_ERROR_KEYBLOCK_SIG_ID;
}

int vb21_verify_fw_preamble(struct vb21_fw_preamble *preamble,
			    uint32_t size,
			    const struct vb2_public_key *key,
			    const struct vb2_workbuf *wb)
{
	struct vb21_signature *sig;
	uint32_t min_offset = 0, hash_offset;
	int rv, i;

	/* Check magic number */
	if (preamble->c.magic != VB21_MAGIC_FW_PREAMBLE)
		return VB2_ERROR_PREAMBLE_MAGIC;

	/* Make sure common header is good */
	rv = vb21_verify_common_header(preamble, size);
	if (rv)
		return rv;

	/*
	 * Check for compatible version.  No need to check minor version, since
	 * that's compatible across readers matching the major version, and we
	 * haven't added any new fields.
	 */
	if (preamble->c.struct_version_major != VB21_FW_PREAMBLE_VERSION_MAJOR)
		return VB2_ERROR_PREAMBLE_HEADER_VERSION;

	/* Make sure header is big enough */
	if (preamble->c.fixed_size < sizeof(*preamble))
		return VB2_ERROR_PREAMBLE_SIZE;

	/* Make sure all hash signatures are inside */
	hash_offset = preamble->hash_offset;
	for (i = 0; i < preamble->hash_count; i++, hash_offset = min_offset) {
		/* Make sure signature is inside preamble */
		rv = vb21_verify_common_subobject(preamble, &min_offset,
						  hash_offset);
		if (rv)
			return rv;

		sig = (struct vb21_signature *)
			((uint8_t *)preamble + hash_offset);

		/* Verify the signature integrity */
		rv = vb21_verify_signature(
				sig, preamble->c.total_size - hash_offset);
		if (rv)
			return rv;

		/* Hashes must all be unsigned */
		if (sig->sig_alg != VB2_SIG_NONE)
			return VB2_ERROR_PREAMBLE_HASH_SIGNED;
	}

	/* Make sure signature is inside preamble */
	rv = vb21_verify_common_subobject(preamble, &min_offset,
					 preamble->sig_offset);
	if (rv)
		return rv;

	/* Verify preamble signature */
	sig = (struct vb21_signature *)((uint8_t *)preamble +
					preamble->sig_offset);

	rv = vb21_verify_data(preamble, preamble->sig_offset, sig, key, wb);
	if (rv)
		return rv;

	return VB2_SUCCESS;
}
