// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2016
 * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
 */

#include <common.h>
#include <env.h>
#include <tpm-v1.h>
#include <malloc.h>
#include <linux/ctype.h>
#include <asm/unaligned.h>

#include "hre.h"

int flush_keys(struct udevice *tpm)
{
	u16 key_count;
	u8 buf[288];
	u8 *ptr;
	u32 err;
	uint i;

	/* fetch list of already loaded keys in the TPM */
	err = tpm_get_capability(tpm, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
				 sizeof(buf));
	if (err)
		return -1;
	key_count = get_unaligned_be16(buf);
	ptr = buf + 2;
	for (i = 0; i < key_count; ++i, ptr += 4) {
		err = tpm_flush_specific(tpm, get_unaligned_be32(ptr),
					 TPM_RT_KEY);
		if (err && err != TPM_KEY_OWNER_CONTROL)
			return err;
	}

	return 0;
}

int decode_hexstr(char *hexstr, u8 **result)
{
	int len = strlen(hexstr);
	int bytes = len / 2;
	int i;
	u8 acc = 0;

	if (len % 2 == 1)
		return 1;

	*result = (u8 *)malloc(bytes);

	for (i = 0; i < len; i++) {
		char cur = tolower(hexstr[i]);
		u8 val;

		if ((cur >= 'a' && cur <= 'f') || (cur >= '0' && cur <= '9')) {
			val = cur - (cur > '9' ? 87 : 48);

			if (i % 2 == 0)
				acc = 16 * val;
			else
				(*result)[i / 2] = acc + val;
		} else {
			free(*result);
			return 1;
		}
	}

	return 0;
}

int extract_subprogram(u8 **progdata, u32 expected_magic,
		       struct key_program **result)
{
	struct key_program *prog = *result;
	u32 magic, code_crc, code_size;

	magic = get_unaligned_be32(*progdata);
	code_crc = get_unaligned_be32(*progdata + 4);
	code_size = get_unaligned_be32(*progdata + 8);

	*progdata += 12;

	if (magic != expected_magic)
		return -1;

	*result = malloc(sizeof(struct key_program) + code_size);

	if (!*result)
		return -1;

	prog->magic = magic;
	prog->code_crc = code_crc;
	prog->code_size = code_size;
	memcpy(prog->code, *progdata, code_size);

	*progdata += code_size;

	if (hre_verify_program(prog)) {
		free(prog);
		return -1;
	}

	return 0;
}

struct key_program *parse_and_check_keyprog(u8 *progdata)
{
	struct key_program *result = NULL, *hmac = NULL;

	/* Part 1: Load key program */

	if (extract_subprogram(&progdata, MAGIC_KEY_PROGRAM, &result))
		return NULL;

	/* Part 2: Load hmac program */

	if (extract_subprogram(&progdata, MAGIC_HMAC, &hmac))
		return NULL;

	free(hmac);

	return result;
}

int load_and_run_keyprog(struct udevice *tpm)
{
	char *cmd = NULL;
	u8 *binprog = NULL;
	char *hexprog;
	struct key_program *prog;

	cmd = env_get("loadkeyprogram");

	if (!cmd || run_command(cmd, 0))
		return 1;

	hexprog = env_get("keyprogram");

	if (decode_hexstr(hexprog, &binprog))
		return 1;

	prog = parse_and_check_keyprog(binprog);
	free(binprog);

	if (!prog)
		return 1;

	if (hre_run_program(tpm, prog->code, prog->code_size)) {
		free(prog);
		return 1;
	}

	printf("\nSD code ran successfully\n");

	free(prog);

	return 0;
}
