u-boot/board/gdsys/a38x/keyprogram.c
Miquel Raynal d677bfe2f7 tpm: disociate TPMv1.x specific and generic code
There are no changes in this commit but a new organization of the code
as follow.

* cmd/ directory:
        > move existing code from cmd/tpm.c in cmd/tpm-common.c
	> move specific code in cmd/tpm-v1.c
	> create a specific header file with generic definitions for
	  commands only called cmd/tpm-user-utils.h

* lib/ directory:
        > move existing code from lib/tpm.c in lib/tpm-common.c
	> move specific code in lib/tpm-v1.c
	> create a specific header file with generic definitions for
	  the library itself called lib/tpm-utils.h

* include/ directory:
        > move existing code from include/tpm.h in include/tpm-common.h
	> move specific code in include/tpm-v1.h

Code designated as 'common' is compiled if TPM are used. Code designated
as 'specific' is compiled only if the right specification has been
selected.

All files include tpm-common.h.
Files in cmd/ include tpm-user-utils.h.
Files in lib/ include tpm-utils.h.
Depending on the specification, files may include either (not both)
tpm-v1.h or tpm-v2.h.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
[trini: Fix a few more cases of tpm.h -> tpm-v1.h, some Kconfig logic]
Signed-off-by: Tom Rini <trini@konsulko.com>
2018-05-25 20:12:55 -04:00

157 lines
2.7 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2016
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
*/
#include <common.h>
#include <tpm-v1.h>
#include <malloc.h>
#include <linux/ctype.h>
#include <asm/unaligned.h>
#include "hre.h"
int flush_keys(void)
{
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_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(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(void)
{
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(prog->code, prog->code_size)) {
free(prog);
return 1;
}
printf("\nSD code ran successfully\n");
free(prog);
return 0;
}