/* Copyright 2013-2018 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 <inttypes.h>
#include "secureboot.h"

static const void* hw_key_hash = NULL;
static size_t hw_key_hash_size;
static bool secure_mode = false;
static bool secure_init = false;
static unsigned int level = PR_ERR;

static struct {
	enum secureboot_version version;
	const char *compat;
} secureboot_map[] = {
	{ IBM_SECUREBOOT_V1, "ibm,secureboot-v1" },
	{ IBM_SECUREBOOT_SOFTROM, "ibm,secureboot-v1-softrom" },
	{ IBM_SECUREBOOT_V2, "ibm,secureboot-v2" },
};

static void secureboot_enforce(void)
{
	/* Sanity check */
	if (!secure_mode)
		return;

	/*
	 * TODO: Ideally, the BMC should decide what security policy to apply
	 * (power off, reboot, switch PNOR sides, etc). We may need to provide
	 * extra info to BMC other than just abort.  Terminate Immediate
	 * Attention ? (TI)
	 */
	prlog(PR_EMERG, "secure mode enforced, aborting.\n");
	abort();
}

bool secureboot_is_compatible(struct dt_node *node, int *version, const char **compat)
{
	int i;

	if (!node)
		return false;

	for (i = 0; i < ARRAY_SIZE(secureboot_map); i++) {
		if (dt_node_is_compatible(node, secureboot_map[i].compat)) {
			if (version)
				*version = secureboot_map[i].version;
			if (compat)
				*compat = secureboot_map[i].compat;
			return true;
		}
	}
	return false;
}

void secureboot_init(void)
{
	struct dt_node *node;
	const char *hash_algo;
	const char *compat = NULL;
	int version;
	size_t size;

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

	if (!secureboot_is_compatible(node, &version, &compat)) {
		/**
		 * @fwts-label SecureBootNotCompatible
		 * @fwts-advice Compatible secureboot driver not found. Probably,
		 * hostboot/mambo/skiboot has updated the
		 * /ibm,secureboot/compatible without adding a driver that
		 * supports it.
		 */
		prlog(PR_ERR, "%s FAILED, /ibm,secureboot not compatible.\n",
		      __func__);
		return;
	}

	prlog(PR_NOTICE, "Found %s\n", compat);

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

	/* Use emergency log level only when secure mode is ON */
        if (secure_mode)
                level = PR_EMERG;
        else
                level = PR_ERR;

	if (version == IBM_SECUREBOOT_V1 ||
	    version == IBM_SECUREBOOT_SOFTROM) {

		hash_algo = dt_prop_get(node, "hash-algo");
		if (strcmp(hash_algo, "sha512")) {
			/**
			 * @fwts-label HashAlgoInvalid
			 * @fwts-advice Hash algorithm invalid, secureboot
			 * containers version 1 requires sha512. If you're
			 * running the latest POWER firmware, so probably there
			 * is a bug in the device tree received from hostboot.
			 */
			prlog(level, "secureboot init FAILED, hash-algo=%s "
			      "not supported\n", hash_algo);
			secureboot_enforce();
		}
		hw_key_hash_size = SHA512_DIGEST_LENGTH;

	} else if (version == IBM_SECUREBOOT_V2) {

		hw_key_hash_size = dt_prop_get_u32(node, "hw-key-hash-size");
		if (hw_key_hash_size == 0) {
			prlog(level, "hw-key-hash-size=%zd too short\n",
			      hw_key_hash_size);
			secureboot_enforce();
		}
		if (hw_key_hash_size > SHA512_DIGEST_LENGTH) {
			prlog(level, "hw-key-hash-size=%zd too big\n",
			      hw_key_hash_size);
			secureboot_enforce();
		}

	} else {
		prlog(level, "%s FAILED. /ibm,secureboot not supported",
		      __func__);
		secureboot_enforce();
	}

	hw_key_hash = dt_prop_get_def_size(node, "hw-key-hash", NULL, &size);
	if (!hw_key_hash) {
		prlog(level, "hw-key-hash not found\n");
		secureboot_enforce();
	}
	if (size != hw_key_hash_size) {
	       prlog(level, "hw_key-hash wrong size %zd (expected=%zd)\n",
		     size, hw_key_hash_size);
	       secureboot_enforce();
	}
	if (cvc_init())
		secureboot_enforce();

	secure_init = true;
}

int secureboot_verify(enum resource_id id, void *buf, size_t len)
{
	const char *name;
	uint64_t log;
	int rc = -1;

	name = flash_map_resource_name(id);
	if (!name) {
		prlog(level, "container NOT VERIFIED, resource_id=%d "
		      "unknown\n", id);
		secureboot_enforce();
		return -1;
	}

        if (!secure_init) {
                prlog(level, "container NOT VERIFIED, resource_id=%d "
                      "secureboot not yet initialized\n", id);
		secureboot_enforce();
		return -1;
        }

	rc = call_cvc_verify(buf, len, hw_key_hash, hw_key_hash_size, &log);

	if (rc == OPAL_SUCCESS) {
		prlog(PR_NOTICE, "%s verified\n", name);
	} else if (rc == OPAL_PARTIAL) {
		/*
		 * The value returned in log indicates what checking has
		 * failed. Return codes defined in
		 * /hostboot/src/include/securerom/status_codes.H
		 */
		prlog(level, "%s verification FAILED. log=0x%" PRIx64 "\n",
			name, be64_to_cpu(log));
		secureboot_enforce();
	} else if (rc == OPAL_PARAMETER) {
		prlog(level, "%s NOT VERIFIED, invalid param. buf=%p, "
		      "len=%zd key-hash=%p hash-size=%zd\n", name, buf, len,
		      hw_key_hash, hw_key_hash_size);
		secureboot_enforce();
	} else if (rc == OPAL_UNSUPPORTED) {
		prlog(level, "%s NOT VERIFIED, CVC-verify service not "
		      "supported\n", name);
		secureboot_enforce();
	} else {
		prlog(level, "%s NOT VERIFIED, unknown CVC-verify error. "
		      "rc=%d\n", name, rc);
		secureboot_enforce();
	}
	return 0;
}
