1 // SPDX-License-Identifier: GPL-2.0+
4 * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
12 #include <linux/ctype.h>
13 #include <asm/unaligned.h>
17 int flush_keys(struct udevice *tpm)
25 /* fetch list of already loaded keys in the TPM */
26 err = tpm1_get_capability(tpm, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
30 key_count = get_unaligned_be16(buf);
32 for (i = 0; i < key_count; ++i, ptr += 4) {
33 err = tpm1_flush_specific(tpm, get_unaligned_be32(ptr),
35 if (err && err != TPM_KEY_OWNER_CONTROL)
42 int decode_hexstr(char *hexstr, u8 **result)
44 int len = strlen(hexstr);
52 *result = (u8 *)malloc(bytes);
54 for (i = 0; i < len; i++) {
55 char cur = tolower(hexstr[i]);
58 if ((cur >= 'a' && cur <= 'f') || (cur >= '0' && cur <= '9')) {
59 val = cur - (cur > '9' ? 87 : 48);
64 (*result)[i / 2] = acc + val;
74 int extract_subprogram(u8 **progdata, u32 expected_magic,
75 struct key_program **result)
77 struct key_program *prog = *result;
78 u32 magic, code_crc, code_size;
80 magic = get_unaligned_be32(*progdata);
81 code_crc = get_unaligned_be32(*progdata + 4);
82 code_size = get_unaligned_be32(*progdata + 8);
86 if (magic != expected_magic)
89 *result = malloc(sizeof(struct key_program) + code_size);
95 prog->code_crc = code_crc;
96 prog->code_size = code_size;
97 memcpy(prog->code, *progdata, code_size);
99 *progdata += code_size;
101 if (hre_verify_program(prog)) {
109 struct key_program *parse_and_check_keyprog(u8 *progdata)
111 struct key_program *result = NULL, *hmac = NULL;
113 /* Part 1: Load key program */
115 if (extract_subprogram(&progdata, MAGIC_KEY_PROGRAM, &result))
118 /* Part 2: Load hmac program */
120 if (extract_subprogram(&progdata, MAGIC_HMAC, &hmac))
128 int load_and_run_keyprog(struct udevice *tpm)
133 struct key_program *prog;
135 cmd = env_get("loadkeyprogram");
137 if (!cmd || run_command(cmd, 0))
140 hexprog = env_get("keyprogram");
142 if (decode_hexstr(hexprog, &binprog))
145 prog = parse_and_check_keyprog(binprog);
151 if (hre_run_program(tpm, prog->code, prog->code_size)) {
156 printf("\nSD code ran successfully\n");