/* 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.
 *
 * Tests for misc library
 */

#include <stdio.h>

#include "2sysincludes.h"
#include "2api.h"
#include "2misc.h"
#include "2nvstorage.h"
#include "2rsa.h"
#include "2secdata.h"
#include "vb2_common.h"
#include "test_common.h"

/* Common context for tests */
static uint8_t workbuf[VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE]
	__attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
static struct vb2_context ctx;
static struct vb2_shared_data *sd;

const char mock_body[320] = "Mock body";
const int mock_body_size = sizeof(mock_body);
const int mock_algorithm = VB2_ALG_RSA2048_SHA256;
const int mock_hash_alg = VB2_HASH_SHA256;
const int mock_sig_size = 64;
static uint8_t digest_result[VB2_SHA256_DIGEST_SIZE];
static const uint32_t digest_result_size = sizeof(digest_result);

/* Mocked function data */

static enum {
	HWCRYPTO_DISABLED,
	HWCRYPTO_ENABLED,
	HWCRYPTO_FORBIDDEN,
} hwcrypto_state;

static vb2_error_t retval_vb2_load_fw_keyblock;
static vb2_error_t retval_vb2_load_fw_preamble;
static vb2_error_t retval_vb2_digest_finalize;
static vb2_error_t retval_vb2_verify_digest;

/* Type of test to reset for */
enum reset_type {
	FOR_MISC,
	FOR_EXTEND_HASH,
	FOR_CHECK_HASH,
};

static void reset_common_data(enum reset_type t)
{
	struct vb2_fw_preamble *pre;
	struct vb2_packed_key *k;

	memset(workbuf, 0xaa, sizeof(workbuf));

	memset(&ctx, 0, sizeof(ctx));
	ctx.workbuf = workbuf;
	ctx.workbuf_size = sizeof(workbuf);

	vb2_init_context(&ctx);
	sd = vb2_get_sd(&ctx);

	vb2_nv_init(&ctx);

	vb2api_secdata_create(&ctx);
	vb2_secdata_init(&ctx);

	retval_vb2_load_fw_keyblock = VB2_SUCCESS;
	retval_vb2_load_fw_preamble = VB2_SUCCESS;
	retval_vb2_digest_finalize = VB2_SUCCESS;
	retval_vb2_verify_digest = VB2_SUCCESS;

	sd->preamble_offset = ctx.workbuf_used;
	sd->preamble_size = sizeof(*pre);
	vb2_set_workbuf_used(&ctx, sd->preamble_offset
			     + sd->preamble_size);
	pre = vb2_member_of(sd, sd->preamble_offset);
	pre->body_signature.data_size = mock_body_size;
	pre->body_signature.sig_size = mock_sig_size;
	if (hwcrypto_state == HWCRYPTO_FORBIDDEN)
		pre->flags = VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO;
	else
		pre->flags = 0;

	sd->data_key_offset = ctx.workbuf_used;
	sd->data_key_size = sizeof(*k) + 8;
	vb2_set_workbuf_used(&ctx, sd->data_key_offset +
			     sd->data_key_size);
	k = vb2_member_of(sd, sd->data_key_offset);
	k->algorithm = mock_algorithm;

	if (t == FOR_EXTEND_HASH || t == FOR_CHECK_HASH)
		vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, NULL);

	if (t == FOR_CHECK_HASH)
		vb2api_extend_hash(&ctx, mock_body, mock_body_size);

	/* Always clear out the digest result. */
	memset(digest_result, 0, digest_result_size);
};

/* Mocked functions */

vb2_error_t vb2_load_fw_keyblock(struct vb2_context *c)
{
	return retval_vb2_load_fw_keyblock;
}

vb2_error_t vb2_load_fw_preamble(struct vb2_context *c)
{
	return retval_vb2_load_fw_preamble;
}

vb2_error_t vb2_unpack_key_buffer(struct vb2_public_key *key,
				  const uint8_t *buf, uint32_t size)
{
	struct vb2_packed_key *k = (struct vb2_packed_key *)buf;

	if (size != sizeof(*k) + 8)
		return VB2_ERROR_UNPACK_KEY_SIZE;

	key->sig_alg = vb2_crypto_to_signature(k->algorithm);
	key->hash_alg = vb2_crypto_to_hash(k->algorithm);

	return VB2_SUCCESS;
}

vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
				       uint32_t data_size)
{
	switch (hwcrypto_state) {
	case HWCRYPTO_DISABLED:
		return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
	case HWCRYPTO_ENABLED:
		if (hash_alg != mock_hash_alg)
			return VB2_ERROR_SHA_INIT_ALGORITHM;
		else
			return VB2_SUCCESS;
	case HWCRYPTO_FORBIDDEN:
	default:
		return VB2_ERROR_UNKNOWN;
	}
}

vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf,
					 uint32_t size)
{
	if (hwcrypto_state != HWCRYPTO_ENABLED)
		return VB2_ERROR_UNKNOWN;

	return VB2_SUCCESS;
}

static void fill_digest(uint8_t *digest, uint32_t digest_size)
{
	/* Set the result to a known value. */
	memset(digest, 0x0a, digest_size);
}

vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest,
				   uint32_t digest_size)
{
	if (hwcrypto_state != HWCRYPTO_ENABLED)
		return VB2_ERROR_UNKNOWN;

	if (retval_vb2_digest_finalize == VB2_SUCCESS)
		fill_digest(digest, digest_size);

	return retval_vb2_digest_finalize;
}

vb2_error_t vb2_digest_init(struct vb2_digest_context *dc,
		    enum vb2_hash_algorithm hash_alg)
{
	if (hwcrypto_state == HWCRYPTO_ENABLED)
		return VB2_ERROR_UNKNOWN;
	if (hash_alg != mock_hash_alg)
		return VB2_ERROR_SHA_INIT_ALGORITHM;

	dc->hash_alg = hash_alg;
	dc->using_hwcrypto = 0;

	return VB2_SUCCESS;
}

vb2_error_t vb2_digest_extend(struct vb2_digest_context *dc, const uint8_t *buf,
			      uint32_t size)
{
	if (hwcrypto_state == HWCRYPTO_ENABLED)
		return VB2_ERROR_UNKNOWN;
	if (dc->hash_alg != mock_hash_alg)
		return VB2_ERROR_SHA_EXTEND_ALGORITHM;

	return VB2_SUCCESS;
}

vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc, uint8_t *digest,
				uint32_t digest_size)
{
	if (hwcrypto_state == HWCRYPTO_ENABLED)
		return VB2_ERROR_UNKNOWN;

	if (retval_vb2_digest_finalize == VB2_SUCCESS)
		fill_digest(digest, digest_size);

	return retval_vb2_digest_finalize;
}

uint32_t vb2_rsa_sig_size(enum vb2_signature_algorithm sig_alg)
{
	return mock_sig_size;
}

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)
{
	return retval_vb2_verify_digest;
}

/* Tests */

static void phase3_tests(void)
{
	reset_common_data(FOR_MISC);
	TEST_SUCC(vb2api_fw_phase3(&ctx), "phase3 good");

	reset_common_data(FOR_MISC);
	retval_vb2_load_fw_keyblock = VB2_ERROR_MOCK;
	TEST_EQ(vb2api_fw_phase3(&ctx), VB2_ERROR_MOCK, "phase3 keyblock");
	TEST_EQ(vb2_nv_get(&ctx, VB2_NV_RECOVERY_REQUEST),
		VB2_RECOVERY_RO_INVALID_RW, "  recovery reason");

	reset_common_data(FOR_MISC);
	retval_vb2_load_fw_preamble = VB2_ERROR_MOCK;
	TEST_EQ(vb2api_fw_phase3(&ctx), VB2_ERROR_MOCK, "phase3 keyblock");
	TEST_EQ(vb2_nv_get(&ctx, VB2_NV_RECOVERY_REQUEST),
		VB2_RECOVERY_RO_INVALID_RW, "  recovery reason");
}

static void init_hash_tests(void)
{
	struct vb2_packed_key *k;
	int wb_used_before;
	uint32_t size;

	/* For now, all we support is body signature hash */
	reset_common_data(FOR_MISC);
	wb_used_before = ctx.workbuf_used;
	TEST_SUCC(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, &size),
		  "init hash good");
	TEST_EQ(sd->hash_offset, wb_used_before,
		"hash context offset");
	TEST_EQ(sd->hash_size, sizeof(struct vb2_digest_context),
		"hash context size");
	TEST_EQ(ctx.workbuf_used,
		vb2_wb_round_up(sd->hash_offset +
				sd->hash_size),
		"hash uses workbuf");
	TEST_EQ(sd->hash_tag, VB2_HASH_TAG_FW_BODY, "hash tag");
	TEST_EQ(sd->hash_remaining_size, mock_body_size, "hash remaining");

	wb_used_before = ctx.workbuf_used;
	TEST_SUCC(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, NULL),
		  "init hash again");
	TEST_EQ(ctx.workbuf_used, wb_used_before, "init hash reuses context");

	reset_common_data(FOR_MISC);
	TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_INVALID, &size),
		VB2_ERROR_API_INIT_HASH_TAG, "init hash invalid tag");

	reset_common_data(FOR_MISC);
	sd->preamble_size = 0;
	TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, &size),
		VB2_ERROR_API_INIT_HASH_PREAMBLE, "init hash preamble");

	reset_common_data(FOR_MISC);
	TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY + 1, &size),
		VB2_ERROR_API_INIT_HASH_TAG, "init hash unknown tag");

	reset_common_data(FOR_MISC);
	ctx.workbuf_used = ctx.workbuf_size + VB2_WORKBUF_ALIGN -
			vb2_wb_round_up(sizeof(struct vb2_digest_context));
	TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, &size),
		VB2_ERROR_API_INIT_HASH_WORKBUF, "init hash workbuf");

	reset_common_data(FOR_MISC);
	sd->data_key_size = 0;
	TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, &size),
		VB2_ERROR_API_INIT_HASH_DATA_KEY, "init hash data key");

	reset_common_data(FOR_MISC);
	sd->data_key_size--;
	TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, &size),
		VB2_ERROR_UNPACK_KEY_SIZE, "init hash data key size");

	reset_common_data(FOR_MISC);
	k = vb2_member_of(sd, sd->data_key_offset);
	k->algorithm--;
	TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, &size),
		VB2_ERROR_SHA_INIT_ALGORITHM, "init hash algorithm");
}

static void extend_hash_tests(void)
{
	struct vb2_digest_context *dc;

	reset_common_data(FOR_EXTEND_HASH);
	TEST_SUCC(vb2api_extend_hash(&ctx, mock_body, 32),
		"hash extend good");
	TEST_EQ(sd->hash_remaining_size, mock_body_size - 32,
		"hash extend remaining");
	TEST_SUCC(vb2api_extend_hash(&ctx, mock_body, mock_body_size - 32),
		"hash extend again");
	TEST_EQ(sd->hash_remaining_size, 0, "hash extend remaining 2");

	reset_common_data(FOR_EXTEND_HASH);
	sd->hash_size = 0;
	TEST_EQ(vb2api_extend_hash(&ctx, mock_body, mock_body_size),
		VB2_ERROR_API_EXTEND_HASH_WORKBUF, "hash extend no workbuf");

	reset_common_data(FOR_EXTEND_HASH);
	TEST_EQ(vb2api_extend_hash(&ctx, mock_body, mock_body_size + 1),
		VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend too much");

	reset_common_data(FOR_EXTEND_HASH);
	TEST_EQ(vb2api_extend_hash(&ctx, mock_body, 0),
		VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend empty");

	if (hwcrypto_state != HWCRYPTO_ENABLED) {
		reset_common_data(FOR_EXTEND_HASH);
		dc = (struct vb2_digest_context *)
			vb2_member_of(sd, sd->hash_offset);
		dc->hash_alg = mock_hash_alg + 1;
		TEST_EQ(vb2api_extend_hash(&ctx, mock_body, mock_body_size),
			VB2_ERROR_SHA_EXTEND_ALGORITHM, "hash extend fail");
	}
}

static void check_hash_tests(void)
{
	struct vb2_fw_preamble *pre;
	const uint32_t digest_value = 0x0a0a0a0a;

	reset_common_data(FOR_CHECK_HASH);
	TEST_SUCC(vb2api_check_hash(&ctx), "check hash good");

	reset_common_data(FOR_CHECK_HASH);
	TEST_SUCC(vb2api_check_hash_get_digest(&ctx, digest_result,
			digest_result_size), "check hash good with result");
	/* Check the first 4 bytes to ensure it was copied over. */
	TEST_SUCC(memcmp(digest_result, &digest_value, sizeof(digest_value)),
		"check digest value");

	reset_common_data(FOR_CHECK_HASH);
	TEST_EQ(vb2api_check_hash_get_digest(&ctx, digest_result,
			digest_result_size - 1),
		VB2_ERROR_API_CHECK_DIGEST_SIZE, "check digest size");
	TEST_NEQ(memcmp(digest_result, &digest_value, sizeof(digest_value)), 0,
		"check digest wrong size");

	reset_common_data(FOR_CHECK_HASH);
	sd->preamble_size = 0;
	TEST_EQ(vb2api_check_hash(&ctx),
		VB2_ERROR_API_CHECK_HASH_PREAMBLE, "check hash preamble");

	reset_common_data(FOR_CHECK_HASH);
	sd->hash_size = 0;
	TEST_EQ(vb2api_check_hash(&ctx),
		VB2_ERROR_API_CHECK_HASH_WORKBUF, "check hash no workbuf");

	reset_common_data(FOR_CHECK_HASH);
	sd->hash_remaining_size = 1;
	TEST_EQ(vb2api_check_hash(&ctx),
		VB2_ERROR_API_CHECK_HASH_SIZE, "check hash size");

	reset_common_data(FOR_CHECK_HASH);
	ctx.workbuf_used = ctx.workbuf_size;
	TEST_EQ(vb2api_check_hash(&ctx),
		VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST, "check hash workbuf");

	reset_common_data(FOR_CHECK_HASH);
	retval_vb2_digest_finalize = VB2_ERROR_MOCK;
	TEST_EQ(vb2api_check_hash(&ctx),	VB2_ERROR_MOCK, "check hash finalize");

	reset_common_data(FOR_CHECK_HASH);
	sd->hash_tag = VB2_HASH_TAG_INVALID;
	TEST_EQ(vb2api_check_hash(&ctx),
		VB2_ERROR_API_CHECK_HASH_TAG, "check hash tag");

	reset_common_data(FOR_CHECK_HASH);
	sd->data_key_size = 0;
	TEST_EQ(vb2api_check_hash(&ctx),
		VB2_ERROR_API_CHECK_HASH_DATA_KEY, "check hash data key");

	reset_common_data(FOR_CHECK_HASH);
	sd->data_key_size--;
	TEST_EQ(vb2api_check_hash(&ctx),
		VB2_ERROR_UNPACK_KEY_SIZE, "check hash data key size");

	reset_common_data(FOR_CHECK_HASH);
	pre = vb2_member_of(sd, sd->preamble_offset);
	pre->body_signature.sig_size++;
	TEST_EQ(vb2api_check_hash(&ctx),
		VB2_ERROR_VDATA_SIG_SIZE, "check hash sig size");

	reset_common_data(FOR_CHECK_HASH);
	retval_vb2_digest_finalize = VB2_ERROR_RSA_VERIFY_DIGEST;
	TEST_EQ(vb2api_check_hash(&ctx),
		VB2_ERROR_RSA_VERIFY_DIGEST, "check hash finalize");
}

int main(int argc, char* argv[])
{
	phase3_tests();

	fprintf(stderr, "Running hash API tests without hwcrypto support...\n");
	hwcrypto_state = HWCRYPTO_DISABLED;
	init_hash_tests();
	extend_hash_tests();
	check_hash_tests();

	fprintf(stderr, "Running hash API tests with hwcrypto support...\n");
	hwcrypto_state = HWCRYPTO_ENABLED;
	init_hash_tests();
	extend_hash_tests();
	check_hash_tests();

	fprintf(stderr, "Running hash API tests with forbidden hwcrypto...\n");
	hwcrypto_state = HWCRYPTO_FORBIDDEN;
	init_hash_tests();
	extend_hash_tests();
	check_hash_tests();

	return gTestSuccess ? 0 : 255;
}
