/* Copyright (c) 2011 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.
 */


#include <stdint.h>
#include <stdio.h>

#include "cryptolib.h"
#include "file_keys.h"
#include "rsa_padding_test.h"
#include "test_common.h"
#include "utility.h"

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

/**
 * Convert an old-style RSA public key struct to a new one.
 *
 * The new one does not allocate memory, so you must keep the old one around
 * until you're done with the new one.
 *
 * @param k2		Destination new key
 * @param key		Source old key
 */
void vb2_public_key_to_vb2(struct vb2_public_key *k2,
			   const struct RSAPublicKey *key)
{
	k2->arrsize = key->len;
	k2->n0inv = key->n0inv;
	k2->n = key->n;
	k2->rr = key->rr;
	k2->algorithm = key->algorithm;
}

/**
 * Test valid and invalid signatures.
 */
static void test_signatures(const struct vb2_public_key *key)
{
	uint8_t workbuf[VB2_VERIFY_DIGEST_WORKBUF_BYTES];
	uint8_t sig[RSA1024NUMBYTES];
	struct vb2_workbuf wb;
	int unexpected_success;
	int i;

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

	/* The first test signature is valid. */
	Memcpy(sig, signatures[0], sizeof(sig));
	TEST_SUCC(vb2_verify_digest(key, sig, test_message_sha1_hash, &wb),
		  "RSA Padding Test valid sig");

	/* All other signatures should fail verification. */
	unexpected_success = 0;
	for (i = 1; i < sizeof(signatures) / sizeof(signatures[0]); i++) {
		Memcpy(sig, signatures[i], sizeof(sig));
		if (!vb2_verify_digest(key, sig, test_message_sha1_hash, &wb)) {
			fprintf(stderr,
				"RSA Padding Test vector %d FAILED!\n", i);
			unexpected_success++;
		}
	}
	TEST_EQ(unexpected_success, 0, "RSA Padding Test invalid sigs");
}


/**
 * Test other error conditions in vb2_verify_digest().
 */
static void test_verify_digest(struct vb2_public_key *key) {
	uint8_t workbuf[VB2_VERIFY_DIGEST_WORKBUF_BYTES];
	uint8_t sig[RSA1024NUMBYTES];
	struct vb2_workbuf wb;

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

	Memcpy(sig, signatures[0], sizeof(sig));
	TEST_SUCC(vb2_verify_digest(key, sig, test_message_sha1_hash, &wb),
		  "vb2_verify_digest() good");

	Memcpy(sig, signatures[0], sizeof(sig));
	vb2_workbuf_init(&wb, workbuf, sizeof(sig) * 3 - 1);
	TEST_EQ(vb2_verify_digest(key, sig, test_message_sha1_hash, &wb),
		VB2_ERROR_RSA_VERIFY_WORKBUF,
		"vb2_verify_digest() small workbuf");
	vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));

	key->algorithm += VB2_ALG_COUNT;
	Memcpy(sig, signatures[0], sizeof(sig));
	TEST_EQ(vb2_verify_digest(key, sig, test_message_sha1_hash, &wb),
		VB2_ERROR_RSA_VERIFY_ALGORITHM,
		"vb2_verify_digest() bad key alg");
	key->algorithm -= VB2_ALG_COUNT;

	key->arrsize *= 2;
	Memcpy(sig, signatures[0], sizeof(sig));
	TEST_EQ(vb2_verify_digest(key, sig, test_message_sha1_hash, &wb),
		VB2_ERROR_RSA_VERIFY_SIG_LEN,
		"vb2_verify_digest() bad sig len");
	key->arrsize /= 2;

	/* Corrupt the signature near start and end */
	Memcpy(sig, signatures[0], sizeof(sig));
	sig[3] ^= 0x42;
	TEST_EQ(vb2_verify_digest(key, sig, test_message_sha1_hash, &wb),
		VB2_ERROR_RSA_PADDING, "vb2_verify_digest() bad sig");

	Memcpy(sig, signatures[0], sizeof(sig));
	sig[RSA1024NUMBYTES - 3] ^= 0x56;
	TEST_EQ(vb2_verify_digest(key, sig, test_message_sha1_hash, &wb),
		VB2_ERROR_RSA_PADDING, "vb2_verify_digest() bad sig end");
}

int main(int argc, char *argv[])
{
	int error = 0;
	RSAPublicKey *key;
	struct vb2_public_key k2;

	/* Read test key */
	if (argc != 2) {
		fprintf(stderr, "Usage: %s <test public key>\n", argv[0]);
		return 1;
	}
	key = RSAPublicKeyFromFile(argv[1]);

	if (!key) {
		fprintf(stderr, "Couldn't read RSA public key for the test.\n");
		return 1;
	}

	// TODO: why is test key algorithm wrong?
	key->algorithm = 0;

	/* Convert test key to Vb2 format */
	vb2_public_key_to_vb2(&k2, key);

	/* Run tests */
	test_signatures(&k2);
	test_verify_digest(&k2);

	/* Clean up and exit */
	RSAPublicKeyFree(key);

	if (!gTestSuccess)
		error = 255;

	return error;
}
