/* Copyright 2013-2017 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef pr_fmt
#define pr_fmt(fmt) "STB: " fmt
#endif

#include <skiboot.h>
#include <device.h>
#include <nvram.h>
#include <opal-api.h>
#include "secureboot.h"
#include "trustedboot.h"
#include "tpm_chip.h"

/* For debugging only */
//#define STB_DEBUG

static bool trusted_mode = false;
static bool trusted_init = false;
static bool boot_services_exited = false;

/*
 * This maps a PCR for each resource we can measure. The PCR number is
 * mapped according to the TCG PC Client Platform Firmware Profile
 * specification, Revision 00.21
 * Only resources included in this whitelist can be measured.
 */
static struct {
	enum resource_id id;
	TPM_Pcr pcr;
} resources[] = {
	{ RESOURCE_ID_IMA_CATALOG, PCR_2 },
	{ RESOURCE_ID_KERNEL, PCR_4 },
	{ RESOURCE_ID_CAPP,   PCR_2 },
	{ RESOURCE_ID_VERSION, PCR_3 },
};

/*
 * Event Separator - digest of 0xFFFFFFFF
 */
static struct {
	const unsigned char *event;
	const unsigned char *sha1;
	const unsigned char *sha256;
} ev_separator = {

	.event = "\xff\xff\xff\xff",

	.sha1   = "\xd9\xbe\x65\x24\xa5\xf5\x04\x7d\xb5\x86"
		  "\x68\x13\xac\xf3\x27\x78\x92\xa7\xa3\x0a",

	.sha256 = "\xad\x95\x13\x1b\xc0\xb7\x99\xc0\xb1\xaf"
		  "\x47\x7f\xb1\x4f\xcf\x26\xa6\xa9\xf7\x60"
		  "\x79\xe4\x8b\xf0\x90\xac\xb7\xe8\x36\x7b"
		  "\xfd\x0e"
};

static TPM_Pcr map_pcr(enum resource_id id)
{
	int i;
	for (i = 0; i < ARRAY_SIZE(resources); i++) {
		if (resources[i].id == id)
			return resources[i].pcr;
	}
	return -1;
}

void trustedboot_init(void)
{
	struct dt_node *node;

	node = dt_find_by_path(dt_root, "/ibm,secureboot");
	if (!node) {
		prlog(PR_NOTICE, "trusted boot not supported\n");
		return;
	}

	if (!secureboot_is_compatible(node, NULL, NULL)) {
		/**
		 * @fwts-label TrustedBootNotCompatible
		 * @fwts-advice Compatible trustedboot driver not found. Probably,
		 * hostboot/mambo/skiboot has updated the
		 * /ibm,secureboot/compatible without adding a driver that
		 * supports it.
		 */
		prlog(PR_ERR, "trustedboot init FAILED, '%s' node not "
		      "compatible.\n", node->name);
		return;
	}

	if (nvram_query_eq("force-trusted-mode", "true")) {
		trusted_mode = true;
		prlog(PR_NOTICE, "trusted mode on (FORCED by nvram)\n");
	} else {
		trusted_mode = dt_has_node_property(node, "trusted-enabled", NULL);
		prlog(PR_NOTICE, "trusted mode %s\n",
		      trusted_mode ? "on" : "off");
	}

	if (!trusted_mode)
		return;

	cvc_init();
	tpm_init();

	trusted_init = true;
}

int trustedboot_exit_boot_services(void)
{
	uint32_t pcr;
	int rc = 0;
	bool failed = false;

	boot_services_exited = true;

	if (!trusted_mode)
		goto out_free;

#ifdef STB_DEBUG
	prlog(PR_NOTICE, "ev_separator.event: %s\n", ev_separator.event);
	prlog(PR_NOTICE, "ev_separator.sha1:\n");
	stb_print_data((uint8_t*) ev_separator.sha1, TPM_ALG_SHA1_SIZE);
	prlog(PR_NOTICE, "ev_separator.sha256:\n");
	stb_print_data((uint8_t*) ev_separator.sha256, TPM_ALG_SHA256_SIZE);
#endif
	/*
	 * As defined in the TCG Platform Firmware PWe are done. Extending the digest of 0xFFFFFFFF
	 * in PCR[0-7], and recording an EV_SEPARATOR event in
	 * event log as defined in the TCG Platform Firmware Profile
	 * specification, Revision 00.21
	 */
	for (pcr = 0; pcr < 8; pcr++) {
		rc = tpm_extendl(pcr, TPM_ALG_SHA256,
				(uint8_t*) ev_separator.sha256,
				TPM_ALG_SHA256_SIZE, TPM_ALG_SHA1,
				(uint8_t*) ev_separator.sha1,
				TPM_ALG_SHA1_SIZE, EV_SEPARATOR,
				ev_separator.event);
		if (rc)
			failed = true;
	}
	tpm_add_status_property();

out_free:
	tpm_cleanup();

	return (failed) ? -1 : 0;
}

int trustedboot_measure(enum resource_id id, void *buf, size_t len)
{
	uint8_t digest[SHA512_DIGEST_LENGTH];
	void *buf_aux;
	size_t len_aux;
	const char *name;
	TPM_Pcr pcr;
	int rc = -1;

	if (!trusted_mode)
		return 1;

	name = flash_map_resource_name(id);
	if (!name) {
		/**
		 * @fwts-label ResourceNotMeasuredUnknown
		 * @fwts-advice This is a bug in the trustedboot_measure()
		 * caller, which is passing an unknown resource_id.
		 */
		prlog(PR_ERR, "resource NOT MEASURED, resource_id=%d unknown\n", id);
		return -1;
	}

        if (!trusted_init) {
                prlog(PR_ERR, "resource NOT MEASURED, resource_id=%d "
                      "trustedboot not yet initialized\n", id);
                return -1;
        }

	if (boot_services_exited) {
		prlog(PR_ERR, "%s NOT MEASURED. Already exited from boot "
		      "services\n", name);
		return -1;
	}
	pcr = map_pcr(id);
	if (pcr == -1) {
		/**
		 * @fwts-label ResourceNotMappedToPCR
		 * @fwts-advice This is a bug. The resource cannot be measured
		 * because it is not mapped to a PCR in the resources[] array.
		 */
		prlog(PR_ERR, "%s NOT MEASURED, it's not mapped to a PCR\n", name);
		return -1;
	}
	if (!buf) {
		/**
		 * @fwts-label ResourceNotMeasuredNull
		 * @fwts-advice This is a bug. The trustedboot_measure() caller
		 * provided a NULL container.
		 */
		prlog(PR_ERR, "%s NOT MEASURED, it's null\n", name);
		return -1;
	}
	if (stb_is_container(buf, len)) {
		buf_aux = buf + SECURE_BOOT_HEADERS_SIZE;
		len_aux = len - SECURE_BOOT_HEADERS_SIZE;
	} else {
		buf_aux = buf;
		len_aux = len;
	}

	rc = call_cvc_sha512(buf_aux, len_aux, digest, SHA512_DIGEST_LENGTH);

	if (rc == OPAL_SUCCESS) {
		prlog(PR_NOTICE, "%s hash calculated\n", name);
	} else if (rc == OPAL_PARAMETER) {
		prlog(PR_ERR, "%s NOT MEASURED, invalid param. buf=%p, "
		      "len=%zd, digest=%p\n", name, buf_aux,
		      len_aux, digest);
		return -1;
	} else if (rc == OPAL_UNSUPPORTED) {
		prlog(PR_ERR, "%s NOT MEASURED, CVC-sha512 service not "
		      "supported\n", name);
		return -1;
	} else {
		prlog(PR_ERR, "%s NOT MEASURED, unknown CVC-sha512 error. "
		      "rc=%d\n", name, rc);
		return -1;
	}

#ifdef STB_DEBUG
	stb_print_data(digest, TPM_ALG_SHA256_SIZE);
#endif
	/*
	 * Extend the given PCR number in both sha256 and sha1 banks with the
	 * sha512 hash calculated. The hash is truncated accordingly to fit the
	 * PCR.
	 */
	return tpm_extendl(pcr,
			   TPM_ALG_SHA256, digest, TPM_ALG_SHA256_SIZE,
			   TPM_ALG_SHA1,   digest, TPM_ALG_SHA1_SIZE,
			   EV_ACTION, name);
}
