// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
/* Copyright 2013-2019 IBM Corp. */

#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"
#include "ibmtss/TPM_Types.h"

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

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

/*
 * Partitions retrieved from PNOR must be extended to the proper PCR and
 * recorded in the event log. Later, customers may use: the PCR values to attest
 * the boot security, and the event log to inspect what measurements were
 * extended to the PCRs.
 *
 * The whitelist below should map every skiboot event (or resource) to a PCR
 * following the TCG PC Client Platform Firmware Profile specification,
 * Family 2.0, Level 00, Revision 1.03 v51.
 *
 * Convention for skiboot events:
 *	- Events that represents data should be extended to PCR 4.
 *	- Events that represents config should be extended to PCR 5.
 *	- For the lack of an event type that fits the specific purpose,
 *	  both data and config events should be logged as EV_COMPACT_HASH.
 */
static struct {
	enum resource_id id;
	TPMI_DH_PCR pcr;
} resources[] = {
	{ RESOURCE_ID_IMA_CATALOG,	PCR_4},
	{ RESOURCE_ID_KERNEL,		PCR_4},
	{ RESOURCE_ID_CAPP,		PCR_4},
	{ RESOURCE_ID_VERSION,		PCR_4}, /* Also data for Hostboot */
};

/*
 * 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_dangerous("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_INFO, "trusted mode %s\n",
		      trusted_mode ? "on" : "off");
	}

	if (!trusted_mode)
		return;

	cvc_init();
	tpm_init();

	trusted_init = true;
	boot_services_exited = false;
}

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

	if (!trusted_mode)
		goto out_free;

	if (boot_services_exited) {
		prlog(PR_WARNING, "Trusted boot services exited before.\n");
		goto out_free;
	}

	boot_services_exited = true;
#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, SHA1_DIGEST_SIZE);
	prlog(PR_NOTICE, "ev_separator.sha256:\n");
	stb_print_data((uint8_t*) ev_separator.sha256, SHA256_DIGEST_SIZE);
#endif
	/*
	 * Extend the digest of 0xFFFFFFFF to PCR[0-7] and record it as
	 * EV_SEPARATOR
	 */
	for (pcr = 0; pcr < 8; pcr++) {
		rc = tpm_extendl(pcr,
				TPM_ALG_SHA256, (uint8_t*) ev_separator.sha256,
				TPM_ALG_SHA1, (uint8_t*) ev_separator.sha1,
				EV_SEPARATOR, ev_separator.event,
				strlen(ev_separator.event));
		if (rc)
			failed = true;
	}
	tpm_add_status_property();
	tss_set_platform_auth();

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;
	TPMI_DH_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, SHA256_DIGEST_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, (uint8_t*) digest,
			   TPM_ALG_SHA1, (uint8_t*) digest,
			   EV_COMPACT_HASH, name, strlen(name));
}
