/* 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 "vb21_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_id test_id = {.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 vb21_signature *sig, *sig2;
	uint32_t size;

	uint8_t workbuf[VB2_VERIFY_DATA_WORKBUF_BYTES]
		 __attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
	struct vb2_workbuf wb;

	uint8_t *buf;
	uint32_t bufsize;
	struct vb21_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->id = test_id;
	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->id = &test_id;
	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(vb21_sign_data(&sig, test_data, test_size, prik, NULL),
		  "Sign good");
	TEST_PTR_NEQ(sig, NULL, "  sig_ptr");
	TEST_EQ(0, strcmp(vb21_common_desc(sig), test_desc), "  desc");
	TEST_EQ(0, memcmp(&sig->id, &test_id, sizeof(test_id)), "  id");
	TEST_EQ(sig->data_size, test_size, "  data_size");
	TEST_SUCC(vb21_sig_size_for_key(&size, prik, NULL), "Sig size");
	TEST_EQ(size, sig->c.total_size, "  size");
	TEST_SUCC(vb21_verify_data(test_data, test_size, sig, pubk, &wb),
		  "Verify good");
	free(sig);

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

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

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

	prik2 = *prik;
	prik2.sig_alg = VB2_SIG_INVALID;
	TEST_EQ(vb21_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(vb21_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 vb21_struct_common *)buf;
	c->total_size = bufsize;

	TEST_SUCC(vb21_sign_object(buf, c_sig_offs, prik, NULL), "Sign object");
	sig = (struct vb21_signature *)(buf + c_sig_offs);
	TEST_SUCC(vb21_verify_data(buf, c_sig_offs, sig, pubk, &wb),
		  "Verify object");

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

	/* Multiply sign an object */
	TEST_SUCC(vb21_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 vb21_struct_common *)buf;
	c->total_size = bufsize;

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

	c->total_size -= 4;
	TEST_EQ(vb21_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);

	snprintf(pemfile, sizeof(pemfile),
		 "%s/key_rsa%d.pem", keys_dir, rsa_bits);
	snprintf(keybfile, sizeof(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;
}
