/* Copyright (c) 2010 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 <openssl/pem.h>

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

#include "2sysincludes.h"

#include "2common.h"
#include "2rsa.h"
#include "2sha.h"
#include "host_common.h"
#include "host_signature2.h"
#include "signature_digest.h"

uint8_t* PrependDigestInfo(enum vb2_hash_algorithm hash_alg, uint8_t* digest)
{
	const int digest_size = vb2_digest_size(hash_alg);
	uint32_t digestinfo_size = 0;
	const uint8_t* digestinfo = NULL;

	if (VB2_SUCCESS != vb2_digest_info(hash_alg, &digestinfo,
					   &digestinfo_size))
		return NULL;

	uint8_t* p = malloc(digestinfo_size + digest_size);
	memcpy(p, digestinfo, digestinfo_size);
	memcpy(p + digestinfo_size, digest, digest_size);
	return p;
}

uint8_t* SignatureDigest(const uint8_t* buf, uint64_t len,
                         unsigned int algorithm)
{
	uint8_t* info_digest  = NULL;

	uint8_t digest[VB2_SHA512_DIGEST_SIZE];  /* Longest digest */

	if (algorithm >= VB2_ALG_COUNT) {
		VBDEBUG(("SignatureDigest() called with invalid algorithm!\n"));
	} else if (VB2_SUCCESS ==
		   vb2_digest_buffer(buf, len, vb2_crypto_to_hash(algorithm),
				     digest, sizeof(digest))) {
		info_digest = PrependDigestInfo(algorithm, digest);
	}
	return info_digest;
}

uint8_t* SignatureBuf(const uint8_t* buf, uint64_t len, const char* key_file,
                      unsigned int algorithm)
{
	const enum vb2_hash_algorithm hash_alg = vb2_crypto_to_hash(algorithm);
	FILE* key_fp = NULL;
	RSA* key = NULL;
	uint8_t* signature = NULL;
	uint8_t* signature_digest = SignatureDigest(buf, len, algorithm);
	if (!signature_digest) {
		VBDEBUG(("SignatureBuf(): Couldn't get signature digest\n"));
		return NULL;
	}

	const int digest_size = vb2_digest_size(hash_alg);

	uint32_t digestinfo_size = 0;
	const uint8_t* digestinfo = NULL;
	if (VB2_SUCCESS != vb2_digest_info(hash_alg, &digestinfo,
					   &digestinfo_size)) {
		VBDEBUG(("SignatureBuf(): Couldn't get digest info\n"));
		free(signature_digest);
		return NULL;
	}

	int signature_digest_len = digest_size + digestinfo_size;

	key_fp  = fopen(key_file, "r");
	if (!key_fp) {
		VBDEBUG(("SignatureBuf(): Couldn't open key file: %s\n",
			 key_file));
		free(signature_digest);
		return NULL;
	}
	if ((key = PEM_read_RSAPrivateKey(key_fp, NULL, NULL, NULL)))
		signature = (uint8_t *)malloc(
		    vb2_rsa_sig_size(vb2_crypto_to_signature(algorithm)));
	else
		VBDEBUG(("SignatureBuf(): Couldn't read private key from: %s\n",
			 key_file));
	if (signature) {
		if (-1 == RSA_private_encrypt(
				signature_digest_len,  /* Input length. */
				signature_digest,  /* Input data. */
				signature,  /* Output signature. */
				key,  /* Key to use. */
				RSA_PKCS1_PADDING))  /* Padding to use. */
			VBDEBUG(("SignatureBuf(): "
				 "RSA_private_encrypt() failed.\n"));
	}
	fclose(key_fp);
	if (key)
		RSA_free(key);
	free(signature_digest);
	return signature;
}
