/* 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"

int vb2_verify_common_header(const void *parent, uint32_t parent_size)
{
	const struct vb2_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 */
		const uint8_t *desc = (const uint8_t *)c + c->fixed_size;
		if (desc[c->desc_size - 1] != 0)
			return VB2_ERROR_COMMON_DESC_TERMINATOR;
	}

	return VB2_SUCCESS;
}

int vb2_verify_common_member(const void *parent,
			     uint32_t *min_offset,
			     uint32_t member_offset,
			     uint32_t member_size)
{
	const struct vb2_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 vb2_verify_common_subobject(const void *parent,
				uint32_t *min_offset,
				uint32_t member_offset)
{
	const struct vb2_struct_common *p = parent;
	const struct vb2_struct_common *m =
		(const struct vb2_struct_common *)
		((const uint8_t *)parent + member_offset);
	int rv;

	/*
	 * Verify the parent has space at the member offset for the common
	 * header.
	 */
	rv = vb2_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 = vb2_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_guid *vb2_hash_guid(enum vb2_hash_algorithm hash_alg)
{
	switch(hash_alg) {
#ifdef VB2_SUPPORT_SHA1
	case VB2_HASH_SHA1:
		{
			static const struct vb2_guid guid = VB2_GUID_NONE_SHA1;
			return &guid;
		}
#endif
#ifdef VB2_SUPPORT_SHA256
	case VB2_HASH_SHA256:
		{
			static const struct vb2_guid guid =
				VB2_GUID_NONE_SHA256;
			return &guid;
		}
#endif
#ifdef VB2_SUPPORT_SHA512
	case VB2_HASH_SHA512:
		{
			static const struct vb2_guid guid =
				VB2_GUID_NONE_SHA512;
			return &guid;
		}
#endif
	default:
		return NULL;
	}
}

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

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

	/* Make sure common header is good */
	rv = vb2_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 != VB2_SIGNATURE2_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 = vb2_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 *vb2_signature2_data(struct vb2_signature2 *sig)
{
	return (uint8_t *)sig + sig->sig_offset;
}

int vb2_verify_digest2(const struct vb2_public_key *key,
		       struct vb2_signature2 *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(vb2_signature2_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,
					     vb2_signature2_data(sig),
					     digest, wb);
	}
}

int vb2_verify_data2(const void *data,
		     uint32_t size,
		     struct vb2_signature2 *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 vb2_verify_digest2(key, sig, digest, &wblocal);
}

int vb2_verify_keyblock2(struct vb2_keyblock2 *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 != VB2_MAGIC_KEYBLOCK2)
		return VB2_ERROR_KEYBLOCK_MAGIC;

	/* Make sure common header is good */
	rv = vb2_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 != VB2_KEYBLOCK2_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 = vb2_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 vb2_signature2 *sig;

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

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

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

		/* Skip signature if it doesn't match the key GUID */
		if (memcmp(&sig->guid, key->guid, GUID_SIZE))
			continue;

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

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

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