aboutsummaryrefslogtreecommitdiffstats
path: root/roms/u-boot/board/gdsys/a38x/keyprogram.c
diff options
context:
space:
mode:
authorAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
committerAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
commitaf1a266670d040d2f4083ff309d732d648afba2a (patch)
tree2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/u-boot/board/gdsys/a38x/keyprogram.c
parente02cda008591317b1625707ff8e115a4841aa889 (diff)
Add submodule dependency filesHEADmaster
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/u-boot/board/gdsys/a38x/keyprogram.c')
-rw-r--r--roms/u-boot/board/gdsys/a38x/keyprogram.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/roms/u-boot/board/gdsys/a38x/keyprogram.c b/roms/u-boot/board/gdsys/a38x/keyprogram.c
new file mode 100644
index 000000000..7020fae18
--- /dev/null
+++ b/roms/u-boot/board/gdsys/a38x/keyprogram.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016
+ * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
+ */
+
+#include <common.h>
+#include <command.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 = tpm1_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 = tpm1_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;
+}