/* 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 host library vboot2 key functions
 */

#include <stdio.h>
#include <unistd.h>

#include "2sysincludes.h"
#include "2common.h"
#include "2rsa.h"
#include "vb2_common.h"
#include "host_common.h"
#include "host_key2.h"
#include "host_signature2.h"
#include "test_common.h"

/* Test only the algorithms we use */
struct alg_combo {
	const char *name;
	enum vb2_signature_algorithm sig_alg;
	enum vb2_hash_algorithm hash_alg;
};

static const struct alg_combo test_algs[] = {
	{"RSA2048/SHA-256", VB2_SIG_RSA2048, VB2_HASH_SHA256},
	{"RSA4096/SHA-256", VB2_SIG_RSA4096, VB2_HASH_SHA256},
	{"RSA8192/SHA-512", VB2_SIG_RSA8192, VB2_HASH_SHA512},
};

const struct vb2_guid test_guid = {.raw = {0xaa}};
const char *test_desc = "The test key";
const char *test_sig_desc = "The test signature";
const uint8_t test_data[] = "Some test data";
const uint32_t test_size = sizeof(test_data);

static void sig_tests(const struct alg_combo *combo,
		      const char *pemfile,
		      const char *keybfile)
{
	struct vb2_private_key *prik, prik2;
	const struct vb2_private_key *prihash, *priks[2];
	struct vb2_public_key *pubk, pubhash;
	struct vb2_signature *sig, *sig2;
	uint32_t size;

	uint8_t workbuf[VB2_VERIFY_DATA_WORKBUF_BYTES];
	struct vb2_workbuf wb;

	uint8_t *buf;
	uint32_t bufsize;
	struct vb2_struct_common *c;
	uint32_t c_sig_offs;

	vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));

	/* Create test keys */
	/* TODO: should read these from .vbprik2, .vbpubk2 files */
	TEST_SUCC(vb2_private_key_read_pem(&prik, pemfile), "Read private key");
	prik->guid = test_guid;
	prik->hash_alg = combo->hash_alg;
	prik->sig_alg = combo->sig_alg;
	vb2_private_key_set_desc(prik, test_desc);

	TEST_SUCC(vb2_public_key_read_keyb(&pubk, keybfile), "Read pub key");
	pubk->guid = &test_guid;
	pubk->hash_alg = combo->hash_alg;
	vb2_public_key_set_desc(pubk, test_desc);

	TEST_SUCC(vb2_private_key_hash(&prihash, combo->hash_alg),
		  "Private hash key");
	TEST_SUCC(vb2_public_key_hash(&pubhash, combo->hash_alg),
		  "Public hash key");

	priks[0] = prik;
	priks[1] = prihash;

	/* Sign test data */
	TEST_SUCC(vb2_sign_data(&sig, test_data, test_size, prik, NULL),
		  "Sign good");
	TEST_PTR_NEQ(sig, NULL, "  sig_ptr");
	TEST_EQ(0, strcmp(vb2_common_desc(sig), test_desc), "  desc");
	TEST_EQ(0, memcmp(&sig->guid, &test_guid, sizeof(test_guid)), "  guid");
	TEST_EQ(sig->data_size, test_size, "  data_size");
	TEST_SUCC(vb2_sig_size_for_key(&size, prik, NULL), "Sig size");
	TEST_EQ(size, sig->c.total_size, "  size");
	TEST_SUCC(vb2_verify_data(test_data, test_size, sig, pubk, &wb),
		  "Verify good");
	free(sig);

	TEST_SUCC(vb2_sign_data(&sig, test_data, test_size, prik,
				test_sig_desc),
		  "Sign with desc");
	TEST_EQ(0, strcmp(vb2_common_desc(sig),	test_sig_desc), "  desc");
	free(sig);

	TEST_SUCC(vb2_sign_data(&sig, test_data, test_size, prik, ""),
		  "Sign with no desc");
	TEST_EQ(sig->c.desc_size, 0, "  desc");
	TEST_SUCC(vb2_sig_size_for_key(&size, prik, ""), "Sig size");
	TEST_EQ(size, sig->c.total_size, "  size");
	free(sig);

	TEST_SUCC(vb2_sign_data(&sig, test_data, test_size, prihash, NULL),
		  "Sign with hash");
	TEST_SUCC(vb2_verify_data(test_data, test_size, sig, &pubhash, &wb),
		  "Verify with hash");
	free(sig);

	prik2 = *prik;
	prik2.sig_alg = VB2_SIG_INVALID;
	TEST_EQ(vb2_sign_data(&sig, test_data, test_size, &prik2, NULL),
		VB2_SIGN_DATA_SIG_SIZE, "Sign bad sig alg");

	/* Sign an object with a little (24 bytes) data */
	c_sig_offs = sizeof(*c) + 24;
	TEST_SUCC(vb2_sig_size_for_key(&size, prik, NULL), "Sig size");
	bufsize = c_sig_offs + size;
	buf = calloc(1, bufsize);
	memset(buf + sizeof(*c), 0x12, 24);
	c = (struct vb2_struct_common *)buf;
	c->total_size = bufsize;

	TEST_SUCC(vb2_sign_object(buf, c_sig_offs, prik, NULL), "Sign object");
	sig = (struct vb2_signature *)(buf + c_sig_offs);
	TEST_SUCC(vb2_verify_data(buf, c_sig_offs, sig, pubk, &wb),
		  "Verify object");

	TEST_EQ(vb2_sign_object(buf, c_sig_offs + 4, prik, NULL),
		VB2_SIGN_OBJECT_OVERFLOW, "Sign object overflow");
	free(buf);

	/* Multiply sign an object */
	TEST_SUCC(vb2_sig_size_for_keys(&size, priks, 2), "Sigs size");
	bufsize = c_sig_offs + size;
	buf = calloc(1, bufsize);
	memset(buf + sizeof(*c), 0x12, 24);
	c = (struct vb2_struct_common *)buf;
	c->total_size = bufsize;

	TEST_SUCC(vb2_sign_object_multiple(buf, c_sig_offs, priks, 2),
		  "Sign multiple");
	sig = (struct vb2_signature *)(buf + c_sig_offs);
	TEST_SUCC(vb2_verify_data(buf, c_sig_offs, sig, pubk, &wb),
		  "Verify object with sig 1");
	sig2 = (struct vb2_signature *)(buf + c_sig_offs + sig->c.total_size);
	TEST_SUCC(vb2_verify_data(buf, c_sig_offs, sig2, &pubhash, &wb),
		  "Verify object with sig 2");

	c->total_size -= 4;
	TEST_EQ(vb2_sign_object_multiple(buf, c_sig_offs, priks, 2),
		VB2_SIGN_OBJECT_OVERFLOW, "Sign multple overflow");

	TEST_EQ(size, sig->c.total_size + sig2->c.total_size,
		"Sigs size total");

	free(buf);

	vb2_private_key_free(prik);
	vb2_public_key_free(pubk);
}

static int test_algorithm(const struct alg_combo *combo, const char *keys_dir)
{
	int rsa_bits = vb2_rsa_sig_size(combo->sig_alg) * 8;
	char pemfile[1024];
	char keybfile[1024];

	printf("***Testing algorithm: %s\n", combo->name);

	sprintf(pemfile, "%s/key_rsa%d.pem", keys_dir, rsa_bits);
	sprintf(keybfile, "%s/key_rsa%d.keyb", keys_dir, rsa_bits);

	sig_tests(combo, pemfile, keybfile);

	return 0;
}

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

	if (argc == 2) {
		int i;

		for (i = 0; i < ARRAY_SIZE(test_algs); i++) {
			if (test_algorithm(test_algs + i, argv[1]))
				return 1;
		}
	} else {
		fprintf(stderr, "Usage: %s <keys_dir>", argv[0]);
		return -1;
	}

	return gTestSuccess ? 0 : 255;
}
