From 35b65dd8ef3d37a088ee9169763a4d891aed618d Mon Sep 17 00:00:00 2001 From: Harald Seiler Date: Tue, 15 Dec 2020 16:47:52 +0100 Subject: reset: Remove addr parameter from reset_cpu() Historically, the reset_cpu() function had an `addr` parameter which was meant to pass in an address of the reset vector location, where the CPU should reset to. This feature is no longer used anywhere in U-Boot as all reset_cpu() implementations now ignore the passed value. Generic code has been added which always calls reset_cpu() with `0` which means this feature can no longer be used easily anyway. Over time, many implementations seem to have "misunderstood" the existence of this parameter as a way to customize/parameterize the reset (e.g. COLD vs WARM resets). As this is not properly supported, the code will almost always not do what it is intended to (because all call-sites just call reset_cpu() with 0). To avoid confusion and to clean up the codebase from unused left-overs of the past, remove the `addr` parameter entirely. Code which intends to support different kinds of resets should be rewritten as a sysreset driver instead. This transformation was done with the following coccinelle patch: @@ expression argvalue; @@ - reset_cpu(argvalue) + reset_cpu() @@ identifier argname; type argtype; @@ - reset_cpu(argtype argname) + reset_cpu(void) { ... } Signed-off-by: Harald Seiler Reviewed-by: Simon Glass --- cmd/tpm_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cmd') diff --git a/cmd/tpm_test.c b/cmd/tpm_test.c index ebfb25cab0a..3fb964c3719 100644 --- a/cmd/tpm_test.c +++ b/cmd/tpm_test.c @@ -146,7 +146,7 @@ static int test_enable(struct udevice *dev) #define reboot() do { \ printf("\trebooting...\n"); \ - reset_cpu(0); \ + reset_cpu(); \ } while (0) static int test_fast_enable(struct udevice *dev) -- cgit v1.3.1 From d6a885f0878043d572bfd85a423e4a6bb6073178 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 6 Feb 2021 14:23:36 -0700 Subject: tpm: Switch TPMv1 over to use the new API Take over the plain 'tpm_...' functions for use by the new TPM API. Rename all the TPMv1 functions so they are called from the API. Update the TPMv1 functions so that they are called from the API. Change existing users to use the tpm1_ prefix so they don't need to go through the API, which might introduce uncertainty. Signed-off-by: Simon Glass Acked-by: Ilias Apalodimas --- board/gdsys/a38x/controlcenterdc.c | 4 +- board/gdsys/a38x/hre.c | 28 ++++----- board/gdsys/a38x/keyprogram.c | 8 +-- board/gdsys/mpc8308/gazerbeam.c | 4 +- board/gdsys/p1022/controlcenterd-id.c | 36 +++++------ cmd/tpm-v1.c | 25 ++++---- cmd/tpm_test.c | 40 ++++++------ include/tpm-v1.h | 76 +++++++++++----------- lib/Makefile | 1 + lib/tpm-v1.c | 115 ++++++++++++++++------------------ 10 files changed, 168 insertions(+), 169 deletions(-) (limited to 'cmd') diff --git a/board/gdsys/a38x/controlcenterdc.c b/board/gdsys/a38x/controlcenterdc.c index 4f1dc3b4316..dc424f271c5 100644 --- a/board/gdsys/a38x/controlcenterdc.c +++ b/board/gdsys/a38x/controlcenterdc.c @@ -288,8 +288,8 @@ int last_stage_init(void) ccdc_eth_init(); #endif ret = get_tpm(&tpm); - if (ret || tpm_init(tpm) || tpm_startup(tpm, TPM_ST_CLEAR) || - tpm_continue_self_test(tpm)) { + if (ret || tpm_init(tpm) || tpm1_startup(tpm, TPM_ST_CLEAR) || + tpm1_continue_self_test(tpm)) { return 1; } diff --git a/board/gdsys/a38x/hre.c b/board/gdsys/a38x/hre.c index 699241b3e62..de5411a6b93 100644 --- a/board/gdsys/a38x/hre.c +++ b/board/gdsys/a38x/hre.c @@ -107,8 +107,8 @@ static int get_tpm_nv_size(struct udevice *tpm, uint32_t index, uint32_t *size) uint8_t *ptr; uint16_t v16; - err = tpm_get_capability(tpm, TPM_CAP_NV_INDEX, index, - info, sizeof(info)); + err = tpm1_get_capability(tpm, TPM_CAP_NV_INDEX, index, info, + sizeof(info)); if (err) { printf("tpm_get_capability(CAP_NV_INDEX, %08x) failed: %u\n", index, err); @@ -150,8 +150,8 @@ static int find_key(struct udevice *tpm, const uint8_t auth[20], unsigned int i; /* fetch list of already loaded keys in the TPM */ - err = tpm_get_capability(tpm, TPM_CAP_HANDLE, TPM_RT_KEY, buf, - sizeof(buf)); + err = tpm1_get_capability(tpm, TPM_CAP_HANDLE, TPM_RT_KEY, buf, + sizeof(buf)); if (err) return -1; key_count = get_unaligned_be16(buf); @@ -162,8 +162,8 @@ static int find_key(struct udevice *tpm, const uint8_t auth[20], /* now search a(/ the) key which we can access with the given auth */ for (i = 0; i < key_count; ++i) { buf_len = sizeof(buf); - err = tpm_get_pub_key_oiap(tpm, key_handles[i], auth, buf, - &buf_len); + err = tpm1_get_pub_key_oiap(tpm, key_handles[i], auth, buf, + &buf_len); if (err && err != TPM_AUTHFAIL) return -1; if (err) @@ -192,8 +192,8 @@ static int read_common_data(struct udevice *tpm) if (get_tpm_nv_size(tpm, NV_COMMON_DATA_INDEX, &size) || size < NV_COMMON_DATA_MIN_SIZE) return 1; - err = tpm_nv_read_value(tpm, NV_COMMON_DATA_INDEX, - buf, min(sizeof(buf), size)); + err = tpm1_nv_read_value(tpm, NV_COMMON_DATA_INDEX, buf, + min(sizeof(buf), size)); if (err) { printf("tpm_nv_read_value() failed: %u\n", err); return 1; @@ -270,8 +270,8 @@ static struct h_reg *access_hreg(struct udevice *tpm, uint8_t spec, if (mode & HREG_RD) { if (!result->valid) { if (IS_PCR_HREG(spec)) { - hre_tpm_err = tpm_pcr_read(tpm, HREG_IDX(spec), - result->digest, 20); + hre_tpm_err = tpm1_pcr_read(tpm, HREG_IDX(spec), + result->digest, 20); result->valid = (hre_tpm_err == TPM_SUCCESS); } else if (IS_FIX_HREG(spec)) { switch (HREG_IDX(spec)) { @@ -357,8 +357,8 @@ static int hre_op_loadkey(struct udevice *tpm, struct h_reg *src_reg, return -1; if (find_key(tpm, src_reg->digest, dst_reg->digest, &parent_handle)) return -1; - hre_tpm_err = tpm_load_key2_oiap(tpm, parent_handle, key, key_size, - src_reg->digest, &key_handle); + hre_tpm_err = tpm1_load_key2_oiap(tpm, parent_handle, key, key_size, + src_reg->digest, &key_handle); if (hre_tpm_err) { hre_err = HRE_E_TPM_FAILURE; return -1; @@ -474,8 +474,8 @@ do_bin_func: } if (dst_reg && dst_modified && IS_PCR_HREG(dst_spec)) { - hre_tpm_err = tpm_extend(tpm, HREG_IDX(dst_spec), - dst_reg->digest, dst_reg->digest); + hre_tpm_err = tpm1_extend(tpm, HREG_IDX(dst_spec), + dst_reg->digest, dst_reg->digest); if (hre_tpm_err) { hre_err = HRE_E_TPM_FAILURE; return NULL; diff --git a/board/gdsys/a38x/keyprogram.c b/board/gdsys/a38x/keyprogram.c index 853981aadbb..7020fae1894 100644 --- a/board/gdsys/a38x/keyprogram.c +++ b/board/gdsys/a38x/keyprogram.c @@ -23,15 +23,15 @@ int flush_keys(struct udevice *tpm) 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)); + 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 = tpm_flush_specific(tpm, get_unaligned_be32(ptr), - TPM_RT_KEY); + err = tpm1_flush_specific(tpm, get_unaligned_be32(ptr), + TPM_RT_KEY); if (err && err != TPM_KEY_OWNER_CONTROL) return err; } diff --git a/board/gdsys/mpc8308/gazerbeam.c b/board/gdsys/mpc8308/gazerbeam.c index 4e974c56d2c..3d4a7e57fee 100644 --- a/board/gdsys/mpc8308/gazerbeam.c +++ b/board/gdsys/mpc8308/gazerbeam.c @@ -145,8 +145,8 @@ int last_stage_init(void) env_set_ulong("fpga_hw_rev", fpga_hw_rev); ret = get_tpm(&tpm); - if (ret || tpm_init(tpm) || tpm_startup(tpm, TPM_ST_CLEAR) || - tpm_continue_self_test(tpm)) { + if (ret || tpm_init(tpm) || tpm1_startup(tpm, TPM_ST_CLEAR) || + tpm1_continue_self_test(tpm)) { printf("TPM init failed\n"); } diff --git a/board/gdsys/p1022/controlcenterd-id.c b/board/gdsys/p1022/controlcenterd-id.c index 1b5aa9042f5..87b346aa9cf 100644 --- a/board/gdsys/p1022/controlcenterd-id.c +++ b/board/gdsys/p1022/controlcenterd-id.c @@ -273,8 +273,8 @@ static int get_tpm_nv_size(struct udevice *tpm, uint32_t index, uint32_t *size) uint8_t *ptr; uint16_t v16; - err = tpm_get_capability(tpm, TPM_CAP_NV_INDEX, index, - info, sizeof(info)); + err = tpm1_get_capability(tpm, TPM_CAP_NV_INDEX, index, info, + sizeof(info)); if (err) { printf("tpm_get_capability(CAP_NV_INDEX, %08x) failed: %u\n", index, err); @@ -315,8 +315,8 @@ static int find_key(struct udevice *tpm, const uint8_t auth[20], unsigned int i; /* fetch list of already loaded keys in the TPM */ - err = tpm_get_capability(tpm, TPM_CAP_HANDLE, TPM_RT_KEY, buf, - sizeof(buf)); + err = tpm1_get_capability(tpm, TPM_CAP_HANDLE, TPM_RT_KEY, buf, + sizeof(buf)); if (err) return -1; key_count = get_unaligned_be16(buf); @@ -327,8 +327,8 @@ static int find_key(struct udevice *tpm, const uint8_t auth[20], /* now search a(/ the) key which we can access with the given auth */ for (i = 0; i < key_count; ++i) { buf_len = sizeof(buf); - err = tpm_get_pub_key_oiap(tpm, key_handles[i], auth, buf, - &buf_len); + err = tpm1_get_pub_key_oiap(tpm, key_handles[i], auth, buf, + &buf_len); if (err && err != TPM_AUTHFAIL) return -1; if (err) @@ -356,8 +356,8 @@ static int read_common_data(struct udevice *tpm) if (get_tpm_nv_size(tpm, NV_COMMON_DATA_INDEX, &size) || size < NV_COMMON_DATA_MIN_SIZE) return 1; - err = tpm_nv_read_value(tpm, NV_COMMON_DATA_INDEX, - buf, min(sizeof(buf), size)); + err = tpm1_nv_read_value(tpm, NV_COMMON_DATA_INDEX, buf, + min(sizeof(buf), size)); if (err) { printf("tpm_nv_read_value() failed: %u\n", err); return 1; @@ -508,8 +508,8 @@ static struct h_reg *access_hreg(struct udevice *tpm, uint8_t spec, if (mode & HREG_RD) { if (!result->valid) { if (IS_PCR_HREG(spec)) { - hre_tpm_err = tpm_pcr_read(tpm, HREG_IDX(spec), - result->digest, 20); + hre_tpm_err = tpm1_pcr_read(tpm, HREG_IDX(spec), + result->digest, 20); result->valid = (hre_tpm_err == TPM_SUCCESS); } else if (IS_FIX_HREG(spec)) { switch (HREG_IDX(spec)) { @@ -601,8 +601,8 @@ static int hre_op_loadkey(struct udevice *tpm, struct h_reg *src_reg, return -1; if (find_key(tpm, src_reg->digest, dst_reg->digest, &parent_handle)) return -1; - hre_tpm_err = tpm_load_key2_oiap(tpm, parent_handle, key, key_size, - src_reg->digest, &key_handle); + hre_tpm_err = tpm1_load_key2_oiap(tpm, parent_handle, key, key_size, + src_reg->digest, &key_handle); if (hre_tpm_err) { hre_err = HRE_E_TPM_FAILURE; return -1; @@ -718,8 +718,8 @@ do_bin_func: } if (dst_reg && dst_modified && IS_PCR_HREG(dst_spec)) { - hre_tpm_err = tpm_extend(tpm, HREG_IDX(dst_spec), - dst_reg->digest, dst_reg->digest); + hre_tpm_err = tpm1_extend(tpm, HREG_IDX(dst_spec), + dst_reg->digest, dst_reg->digest); if (hre_tpm_err) { hre_err = HRE_E_TPM_FAILURE; return NULL; @@ -964,10 +964,10 @@ static int first_stage_actions(struct udevice *tpm) puts("CCDM S1: start actions\n"); #ifndef CCDM_SECOND_STAGE - if (tpm_continue_self_test(tpm)) + if (tpm1_continue_self_test(tpm)) goto failure; #else - tpm_continue_self_test(tpm); + tpm1_continue_self_test(tpm); #endif mdelay(37); @@ -1003,7 +1003,7 @@ static int first_stage_init(void) puts("CCDM S1\n"); ret = get_tpm(&tpm); - if (ret || tpm_init(tpm) || tpm_startup(tpm, TPM_ST_CLEAR)) + if (ret || tpm_init(tpm) || tpm1_startup(tpm, TPM_ST_CLEAR)) return 1; ret = first_stage_actions(tpm); #ifndef CCDM_SECOND_STAGE @@ -1061,7 +1061,7 @@ static int second_stage_init(void) ret = get_tpm(&tpm); if (ret || tpm_init(tpm)) return 1; - err = tpm_startup(tpm, TPM_ST_CLEAR); + err = tpm1_startup(tpm, TPM_ST_CLEAR); if (err != TPM_INVALID_POSTINIT) did_first_stage_run = false; diff --git a/cmd/tpm-v1.c b/cmd/tpm-v1.c index 0e2168aea67..3a7e35d5255 100644 --- a/cmd/tpm-v1.c +++ b/cmd/tpm-v1.c @@ -11,6 +11,7 @@ #include #include #include "tpm-user-utils.h" +#include static int do_tpm_startup(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) @@ -55,7 +56,7 @@ static int do_tpm_nv_define_space(struct cmd_tbl *cmdtp, int flag, int argc, perm = simple_strtoul(argv[2], NULL, 0); size = simple_strtoul(argv[3], NULL, 0); - return report_return_code(tpm_nv_define_space(dev, index, perm, size)); + return report_return_code(tpm1_nv_define_space(dev, index, perm, size)); } static int do_tpm_nv_read_value(struct cmd_tbl *cmdtp, int flag, int argc, @@ -130,7 +131,7 @@ static int do_tpm_extend(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_FAILURE; } - rc = tpm_extend(dev, index, in_digest, out_digest); + rc = tpm_pcr_extend(dev, index, in_digest, out_digest); if (!rc) { puts("PCR value after execution of the command:\n"); print_byte_string(out_digest, sizeof(out_digest)); @@ -304,7 +305,7 @@ static int do_tpm_nv_define(struct cmd_tbl *cmdtp, int flag, int argc, index = simple_strtoul(argv[2], NULL, 0); perm = simple_strtoul(argv[3], NULL, 0); - return report_return_code(tpm_nv_define_space(dev, index, perm, size)); + return report_return_code(tpm1_nv_define_space(dev, index, perm, size)); } static int do_tpm_nv_read(struct cmd_tbl *cmdtp, int flag, int argc, @@ -389,7 +390,7 @@ static int do_tpm_oiap(struct cmd_tbl *cmdtp, int flag, int argc, if (rc) return rc; - err = tpm_oiap(dev, &auth_handle); + err = tpm1_oiap(dev, &auth_handle); return report_return_code(err); } @@ -461,8 +462,8 @@ static int do_tpm_load_key2_oiap(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_FAILURE; parse_byte_string(argv[4], usage_auth, NULL); - err = tpm_load_key2_oiap(dev, parent_handle, key, key_len, usage_auth, - &key_handle); + err = tpm1_load_key2_oiap(dev, parent_handle, key, key_len, usage_auth, + &key_handle); if (!err) printf("Key handle is 0x%x\n", key_handle); @@ -491,8 +492,8 @@ static int do_tpm_get_pub_key_oiap(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_FAILURE; parse_byte_string(argv[2], usage_auth, NULL); - err = tpm_get_pub_key_oiap(dev, key_handle, usage_auth, pub_key_buffer, - &pub_key_len); + err = tpm1_get_pub_key_oiap(dev, key_handle, usage_auth, pub_key_buffer, + &pub_key_len); if (!err) { printf("dump of received pub key structure:\n"); print_byte_string(pub_key_buffer, pub_key_len); @@ -500,7 +501,7 @@ static int do_tpm_get_pub_key_oiap(struct cmd_tbl *cmdtp, int flag, int argc, return report_return_code(err); } -TPM_COMMAND_NO_ARG(tpm_end_oiap) +TPM_COMMAND_NO_ARG(tpm1_end_oiap) #endif /* CONFIG_TPM_AUTH_SESSIONS */ @@ -562,7 +563,7 @@ static int do_tpm_flush(struct cmd_tbl *cmdtp, int flag, int argc, res_count = get_unaligned_be16(buf); ptr = buf + 2; for (i = 0; i < res_count; ++i, ptr += 4) - tpm_flush_specific(dev, get_unaligned_be32(ptr), type); + tpm1_flush_specific(dev, get_unaligned_be32(ptr), type); } else { u32 handle = simple_strtoul(argv[2], NULL, 0); @@ -570,7 +571,7 @@ static int do_tpm_flush(struct cmd_tbl *cmdtp, int flag, int argc, printf("Illegal resource handle %s\n", argv[2]); return -1; } - tpm_flush_specific(dev, cpu_to_be32(handle), type); + tpm1_flush_specific(dev, cpu_to_be32(handle), type); } return 0; @@ -691,7 +692,7 @@ static struct cmd_tbl tpm1_commands[] = { U_BOOT_CMD_MKENT(oiap, 0, 1, do_tpm_oiap, "", ""), U_BOOT_CMD_MKENT(end_oiap, 0, 1, - do_tpm_end_oiap, "", ""), + do_tpm1_end_oiap, "", ""), U_BOOT_CMD_MKENT(load_key2_oiap, 0, 1, do_tpm_load_key2_oiap, "", ""), #ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1 diff --git a/cmd/tpm_test.c b/cmd/tpm_test.c index 3fb964c3719..a3ccb12f53a 100644 --- a/cmd/tpm_test.c +++ b/cmd/tpm_test.c @@ -9,6 +9,7 @@ #include #include #include "tpm-user-utils.h" +#include /* Prints error and returns on failure */ #define TPM_CHECK(tpm_command) do { \ @@ -49,7 +50,7 @@ static uint32_t tpm_get_flags(struct udevice *dev, uint8_t *disable, struct tpm_permanent_flags pflags; uint32_t result; - result = tpm_get_permanent_flags(dev, &pflags); + result = tpm1_get_permanent_flags(dev, &pflags); if (result) return result; if (disable) @@ -90,7 +91,7 @@ static int test_early_extend(struct udevice *dev) tpm_init(dev); TPM_CHECK(tpm_startup(dev, TPM_ST_CLEAR)); TPM_CHECK(tpm_continue_self_test(dev)); - TPM_CHECK(tpm_extend(dev, 1, value_in, value_out)); + TPM_CHECK(tpm_pcr_extend(dev, 1, value_in, value_out)); printf("done\n"); return 0; } @@ -238,18 +239,18 @@ static void initialise_spaces(struct udevice *dev) uint32_t perm = TPM_NV_PER_WRITE_STCLEAR | TPM_NV_PER_PPWRITE; printf("\tInitialising spaces\n"); - tpm_nv_set_locked(dev); /* useful only the first time */ - tpm_nv_define_space(dev, INDEX0, perm, 4); + tpm1_nv_set_locked(dev); /* useful only the first time */ + tpm1_nv_define_space(dev, INDEX0, perm, 4); tpm_nv_write_value(dev, INDEX0, (uint8_t *)&zero, 4); - tpm_nv_define_space(dev, INDEX1, perm, 4); + tpm1_nv_define_space(dev, INDEX1, perm, 4); tpm_nv_write_value(dev, INDEX1, (uint8_t *)&zero, 4); - tpm_nv_define_space(dev, INDEX2, perm, 4); + tpm1_nv_define_space(dev, INDEX2, perm, 4); tpm_nv_write_value(dev, INDEX2, (uint8_t *)&zero, 4); - tpm_nv_define_space(dev, INDEX3, perm, 4); + tpm1_nv_define_space(dev, INDEX3, perm, 4); tpm_nv_write_value(dev, INDEX3, (uint8_t *)&zero, 4); perm = TPM_NV_PER_READ_STCLEAR | TPM_NV_PER_WRITE_STCLEAR | TPM_NV_PER_PPWRITE; - tpm_nv_define_space(dev, INDEX_INITIALISED, perm, 1); + tpm1_nv_define_space(dev, INDEX_INITIALISED, perm, 1); } static int test_readonly(struct udevice *dev) @@ -325,30 +326,33 @@ static int test_redefine_unowned(struct udevice *dev) /* Redefines spaces a couple of times. */ perm = TPM_NV_PER_PPWRITE | TPM_NV_PER_GLOBALLOCK; - TPM_CHECK(tpm_nv_define_space(dev, INDEX0, perm, 2 * sizeof(uint32_t))); - TPM_CHECK(tpm_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t))); + TPM_CHECK(tpm1_nv_define_space(dev, INDEX0, perm, + 2 * sizeof(uint32_t))); + TPM_CHECK(tpm1_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t))); perm = TPM_NV_PER_PPWRITE; - TPM_CHECK(tpm_nv_define_space(dev, INDEX1, perm, 2 * sizeof(uint32_t))); - TPM_CHECK(tpm_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t))); + TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm, + 2 * sizeof(uint32_t))); + TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t))); /* Sets the global lock */ tpm_set_global_lock(dev); /* Verifies that index0 cannot be redefined */ - result = tpm_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t)); + result = tpm1_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t)); assert(result == TPM_AREA_LOCKED); /* Checks that index1 can */ - TPM_CHECK(tpm_nv_define_space(dev, INDEX1, perm, 2 * sizeof(uint32_t))); - TPM_CHECK(tpm_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t))); + TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm, + 2 * sizeof(uint32_t))); + TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t))); /* Turns off PP */ tpm_tsc_physical_presence(dev, PHYS_PRESENCE); /* Verifies that neither index0 nor index1 can be redefined */ - result = tpm_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t)); + result = tpm1_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t)); assert(result == TPM_BAD_PRESENCE); - result = tpm_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t)); + result = tpm1_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t)); assert(result == TPM_BAD_PRESENCE); printf("done\n"); @@ -434,7 +438,7 @@ static int test_timing(struct udevice *dev) 100); TTPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)), 100); - TTPM_CHECK(tpm_extend(dev, 0, in, out), 200); + TTPM_CHECK(tpm_pcr_extend(dev, 0, in, out), 200); TTPM_CHECK(tpm_set_global_lock(dev), 50); TTPM_CHECK(tpm_tsc_physical_presence(dev, PHYS_PRESENCE), 100); printf("done\n"); diff --git a/include/tpm-v1.h b/include/tpm-v1.h index 8f6cc28a9ea..fcfe1f054f6 100644 --- a/include/tpm-v1.h +++ b/include/tpm-v1.h @@ -289,7 +289,7 @@ struct __packed tpm_nv_data_public { * @param mode TPM startup mode * @return return code of the operation */ -u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode); +u32 tpm1_startup(struct udevice *dev, enum tpm_startup_type mode); /** * Issue a TPM_SelfTestFull command. @@ -297,7 +297,7 @@ u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode); * @param dev TPM device * @return return code of the operation */ -u32 tpm_self_test_full(struct udevice *dev); +u32 tpm1_self_test_full(struct udevice *dev); /** * Issue a TPM_ContinueSelfTest command. @@ -305,7 +305,7 @@ u32 tpm_self_test_full(struct udevice *dev); * @param dev TPM device * @return return code of the operation */ -u32 tpm_continue_self_test(struct udevice *dev); +u32 tpm1_continue_self_test(struct udevice *dev); /** * Issue a TPM_NV_DefineSpace command. The implementation is limited @@ -318,7 +318,7 @@ u32 tpm_continue_self_test(struct udevice *dev); * @param size size of the area * @return return code of the operation */ -u32 tpm_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size); +u32 tpm1_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size); /** * Issue a TPM_NV_ReadValue command. This implementation is limited @@ -331,7 +331,7 @@ u32 tpm_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size); * @param count size of output buffer * @return return code of the operation */ -u32 tpm_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count); +u32 tpm1_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count); /** * Issue a TPM_NV_WriteValue command. This implementation is limited @@ -344,8 +344,8 @@ u32 tpm_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count); * @param length length of data bytes of input buffer * @return return code of the operation */ -u32 tpm_nv_write_value(struct udevice *dev, u32 index, const void *data, - u32 length); +u32 tpm1_nv_write_value(struct udevice *dev, u32 index, const void *data, + u32 length); /** * Issue a TPM_Extend command. @@ -358,8 +358,8 @@ u32 tpm_nv_write_value(struct udevice *dev, u32 index, const void *data, * command * @return return code of the operation */ -u32 tpm_extend(struct udevice *dev, u32 index, const void *in_digest, - void *out_digest); +u32 tpm1_extend(struct udevice *dev, u32 index, const void *in_digest, + void *out_digest); /** * Issue a TPM_PCRRead command. @@ -370,7 +370,7 @@ u32 tpm_extend(struct udevice *dev, u32 index, const void *in_digest, * @param count size of output buffer * @return return code of the operation */ -u32 tpm_pcr_read(struct udevice *dev, u32 index, void *data, size_t count); +u32 tpm1_pcr_read(struct udevice *dev, u32 index, void *data, size_t count); /** * Issue a TSC_PhysicalPresence command. TPM physical presence flag @@ -380,7 +380,7 @@ u32 tpm_pcr_read(struct udevice *dev, u32 index, void *data, size_t count); * @param presence TPM physical presence flag * @return return code of the operation */ -u32 tpm_tsc_physical_presence(struct udevice *dev, u16 presence); +u32 tpm1_tsc_physical_presence(struct udevice *dev, u16 presence); /** * Issue a TPM_ReadPubek command. @@ -390,7 +390,7 @@ u32 tpm_tsc_physical_presence(struct udevice *dev, u16 presence); * @param count size of output buffer * @return return code of the operation */ -u32 tpm_read_pubek(struct udevice *dev, void *data, size_t count); +u32 tpm1_read_pubek(struct udevice *dev, void *data, size_t count); /** * Issue a TPM_ForceClear command. @@ -398,7 +398,7 @@ u32 tpm_read_pubek(struct udevice *dev, void *data, size_t count); * @param dev TPM device * @return return code of the operation */ -u32 tpm_force_clear(struct udevice *dev); +u32 tpm1_force_clear(struct udevice *dev); /** * Issue a TPM_PhysicalEnable command. @@ -406,7 +406,7 @@ u32 tpm_force_clear(struct udevice *dev); * @param dev TPM device * @return return code of the operation */ -u32 tpm_physical_enable(struct udevice *dev); +u32 tpm1_physical_enable(struct udevice *dev); /** * Issue a TPM_PhysicalDisable command. @@ -414,7 +414,7 @@ u32 tpm_physical_enable(struct udevice *dev); * @param dev TPM device * @return return code of the operation */ -u32 tpm_physical_disable(struct udevice *dev); +u32 tpm1_physical_disable(struct udevice *dev); /** * Issue a TPM_PhysicalSetDeactivated command. @@ -423,7 +423,7 @@ u32 tpm_physical_disable(struct udevice *dev); * @param state boolean state of the deactivated flag * @return return code of the operation */ -u32 tpm_physical_set_deactivated(struct udevice *dev, u8 state); +u32 tpm1_physical_set_deactivated(struct udevice *dev, u8 state); /** * Issue a TPM_GetCapability command. This implementation is limited @@ -437,8 +437,8 @@ u32 tpm_physical_set_deactivated(struct udevice *dev, u8 state); * @param count size of output buffer * @return return code of the operation */ -u32 tpm_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap, - void *cap, size_t count); +u32 tpm1_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap, + void *cap, size_t count); /** * Issue a TPM_FlushSpecific command for a AUTH resource. @@ -447,7 +447,7 @@ u32 tpm_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap, * @param auth_handle handle of the auth session * @return return code of the operation */ -u32 tpm_terminate_auth_session(struct udevice *dev, u32 auth_handle); +u32 tpm1_terminate_auth_session(struct udevice *dev, u32 auth_handle); /** * Issue a TPM_OIAP command to setup an object independent authorization @@ -460,7 +460,7 @@ u32 tpm_terminate_auth_session(struct udevice *dev, u32 auth_handle); * @param auth_handle pointer to the (new) auth handle or NULL. * @return return code of the operation */ -u32 tpm_oiap(struct udevice *dev, u32 *auth_handle); +u32 tpm1_oiap(struct udevice *dev, u32 *auth_handle); /** * Ends an active OIAP session. @@ -468,7 +468,7 @@ u32 tpm_oiap(struct udevice *dev, u32 *auth_handle); * @param dev TPM device * @return return code of the operation */ -u32 tpm_end_oiap(struct udevice *dev); +u32 tpm1_end_oiap(struct udevice *dev); /** * Issue a TPM_LoadKey2 (Auth1) command using an OIAP session for authenticating @@ -482,9 +482,9 @@ u32 tpm_end_oiap(struct udevice *dev); * @param key_handle pointer to the key handle * @return return code of the operation */ -u32 tpm_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key, - size_t key_length, const void *parent_key_usage_auth, - u32 *key_handle); +u32 tpm1_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key, + size_t key_length, const void *parent_key_usage_auth, + u32 *key_handle); /** * Issue a TPM_GetPubKey (Auth1) command using an OIAP session for @@ -500,9 +500,9 @@ u32 tpm_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key, * of the stored TPM_PUBKEY structure (iff pubkey != NULL). * @return return code of the operation */ -u32 tpm_get_pub_key_oiap(struct udevice *dev, u32 key_handle, - const void *usage_auth, void *pubkey, - size_t *pubkey_len); +u32 tpm1_get_pub_key_oiap(struct udevice *dev, u32 key_handle, + const void *usage_auth, void *pubkey, + size_t *pubkey_len); /** * Get the TPM permanent flags value @@ -511,8 +511,8 @@ u32 tpm_get_pub_key_oiap(struct udevice *dev, u32 key_handle, * @param pflags Place to put permanent flags * @return return code of the operation */ -u32 tpm_get_permanent_flags(struct udevice *dev, - struct tpm_permanent_flags *pflags); +u32 tpm1_get_permanent_flags(struct udevice *dev, + struct tpm_permanent_flags *pflags); /** * Get the TPM permissions @@ -521,7 +521,7 @@ u32 tpm_get_permanent_flags(struct udevice *dev, * @param perm Returns permissions value * @return return code of the operation */ -u32 tpm_get_permissions(struct udevice *dev, u32 index, u32 *perm); +u32 tpm1_get_permissions(struct udevice *dev, u32 index, u32 *perm); /** * Flush a resource with a given handle and type from the TPM @@ -531,7 +531,7 @@ u32 tpm_get_permissions(struct udevice *dev, u32 index, u32 *perm); * @param resource_type type of the resource * @return return code of the operation */ -u32 tpm_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type); +u32 tpm1_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type); #ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1 /** @@ -543,8 +543,8 @@ u32 tpm_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type); * @param[out] handle The handle of the key (Non-null iff found) * @return 0 if key was found in TPM; != 0 if not. */ -u32 tpm_find_key_sha1(struct udevice *dev, const u8 auth[20], - const u8 pubkey_digest[20], u32 *handle); +u32 tpm1_find_key_sha1(struct udevice *dev, const u8 auth[20], + const u8 pubkey_digest[20], u32 *handle); #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */ /** @@ -557,7 +557,7 @@ u32 tpm_find_key_sha1(struct udevice *dev, const u8 auth[20], * @param count size of output buffer * @return return code of the operation */ -u32 tpm_get_random(struct udevice *dev, void *data, u32 count); +u32 tpm1_get_random(struct udevice *dev, void *data, u32 count); /** * tpm_finalise_physical_presence() - Finalise physical presence @@ -565,15 +565,15 @@ u32 tpm_get_random(struct udevice *dev, void *data, u32 count); * @param dev TPM device * @return return code of the operation (0 = success) */ -u32 tpm_finalise_physical_presence(struct udevice *dev); +u32 tpm1_finalise_physical_presence(struct udevice *dev); /** - * tpm_nv_set_locked() - lock the non-volatile space + * tpm_nv_enable_locking() - lock the non-volatile space * * @param dev TPM device * @return return code of the operation (0 = success) */ -u32 tpm_nv_set_locked(struct udevice *dev); +u32 tpm1_nv_set_locked(struct udevice *dev); /** * tpm_set_global_lock() - set the global lock @@ -589,6 +589,6 @@ u32 tpm_set_global_lock(struct udevice *dev); * @param dev TPM device * @return return code of the operation (0 = success) */ -u32 tpm_resume(struct udevice *dev); +u32 tpm1_resume(struct udevice *dev); #endif /* __TPM_V1_H */ diff --git a/lib/Makefile b/lib/Makefile index edc1c3dd4f9..c42d4e12335 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -53,6 +53,7 @@ endif obj-$(CONFIG_$(SPL_TPL_)TPM) += tpm-common.o ifeq ($(CONFIG_$(SPL_TPL_)TPM),y) obj-y += crc8.o +obj-$(CONFIG_TPM) += tpm_api.o obj-$(CONFIG_TPM_V1) += tpm-v1.o obj-$(CONFIG_TPM_V2) += tpm-v2.o endif diff --git a/lib/tpm-v1.c b/lib/tpm-v1.c index a846fe00dd3..8dc144080ca 100644 --- a/lib/tpm-v1.c +++ b/lib/tpm-v1.c @@ -32,7 +32,7 @@ static struct session_data oiap_session = {0, }; #endif /* CONFIG_TPM_AUTH_SESSIONS */ -u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode) +u32 tpm1_startup(struct udevice *dev, enum tpm_startup_type mode) { const u8 command[12] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0, @@ -48,12 +48,12 @@ u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode) return tpm_sendrecv_command(dev, buf, NULL, NULL); } -u32 tpm_resume(struct udevice *dev) +u32 tpm1_resume(struct udevice *dev) { - return tpm_startup(dev, TPM_ST_STATE); + return tpm1_startup(dev, TPM_ST_STATE); } -u32 tpm_self_test_full(struct udevice *dev) +u32 tpm1_self_test_full(struct udevice *dev) { const u8 command[10] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50, @@ -61,7 +61,7 @@ u32 tpm_self_test_full(struct udevice *dev) return tpm_sendrecv_command(dev, command, NULL, NULL); } -u32 tpm_continue_self_test(struct udevice *dev) +u32 tpm1_continue_self_test(struct udevice *dev) { const u8 command[10] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53, @@ -69,35 +69,33 @@ u32 tpm_continue_self_test(struct udevice *dev) return tpm_sendrecv_command(dev, command, NULL, NULL); } -u32 tpm_clear_and_reenable(struct udevice *dev) +u32 tpm1_clear_and_reenable(struct udevice *dev) { u32 ret; log_info("TPM: Clear and re-enable\n"); - ret = tpm_force_clear(dev); + ret = tpm1_force_clear(dev); if (ret != TPM_SUCCESS) { log_err("Can't initiate a force clear\n"); return ret; } - if (tpm_get_version(dev) == TPM_V1) { - ret = tpm_physical_enable(dev); - if (ret != TPM_SUCCESS) { - log_err("TPM: Can't set enabled state\n"); - return ret; - } + ret = tpm1_physical_enable(dev); + if (ret != TPM_SUCCESS) { + log_err("TPM: Can't set enabled state\n"); + return ret; + } - ret = tpm_physical_set_deactivated(dev, 0); - if (ret != TPM_SUCCESS) { - log_err("TPM: Can't set deactivated state\n"); - return ret; - } + ret = tpm1_physical_set_deactivated(dev, 0); + if (ret != TPM_SUCCESS) { + log_err("TPM: Can't set deactivated state\n"); + return ret; } return TPM_SUCCESS; } -u32 tpm_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size) +u32 tpm1_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size) { const u8 command[101] = { 0x0, 0xc1, /* TPM_TAG */ @@ -140,12 +138,12 @@ u32 tpm_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size) return tpm_sendrecv_command(dev, buf, NULL, NULL); } -u32 tpm_nv_set_locked(struct udevice *dev) +u32 tpm1_nv_set_locked(struct udevice *dev) { - return tpm_nv_define_space(dev, TPM_NV_INDEX_LOCK, 0, 0); + return tpm1_nv_define_space(dev, TPM_NV_INDEX_LOCK, 0, 0); } -u32 tpm_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count) +u32 tpm1_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count) { const u8 command[22] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0xcf, @@ -179,8 +177,8 @@ u32 tpm_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count) return 0; } -u32 tpm_nv_write_value(struct udevice *dev, u32 index, const void *data, - u32 length) +u32 tpm1_nv_write_value(struct udevice *dev, u32 index, const void *data, + u32 length) { const u8 command[256] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd, @@ -210,13 +208,8 @@ u32 tpm_nv_write_value(struct udevice *dev, u32 index, const void *data, return 0; } -uint32_t tpm_set_global_lock(struct udevice *dev) -{ - return tpm_nv_write_value(dev, TPM_NV_INDEX_0, NULL, 0); -} - -u32 tpm_extend(struct udevice *dev, u32 index, const void *in_digest, - void *out_digest) +u32 tpm1_extend(struct udevice *dev, u32 index, const void *in_digest, + void *out_digest) { const u8 command[34] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14, @@ -247,7 +240,7 @@ u32 tpm_extend(struct udevice *dev, u32 index, const void *in_digest, return 0; } -u32 tpm_pcr_read(struct udevice *dev, u32 index, void *data, size_t count) +u32 tpm1_pcr_read(struct udevice *dev, u32 index, void *data, size_t count) { const u8 command[14] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15, @@ -275,7 +268,7 @@ u32 tpm_pcr_read(struct udevice *dev, u32 index, void *data, size_t count) return 0; } -u32 tpm_tsc_physical_presence(struct udevice *dev, u16 presence) +u32 tpm1_tsc_physical_presence(struct udevice *dev, u16 presence) { const u8 command[12] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x0, @@ -291,7 +284,7 @@ u32 tpm_tsc_physical_presence(struct udevice *dev, u16 presence) return tpm_sendrecv_command(dev, buf, NULL, NULL); } -u32 tpm_finalise_physical_presence(struct udevice *dev) +u32 tpm1_finalise_physical_presence(struct udevice *dev) { const u8 command[12] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x2, 0xa0, @@ -300,7 +293,7 @@ u32 tpm_finalise_physical_presence(struct udevice *dev) return tpm_sendrecv_command(dev, command, NULL, NULL); } -u32 tpm_read_pubek(struct udevice *dev, void *data, size_t count) +u32 tpm1_read_pubek(struct udevice *dev, void *data, size_t count) { const u8 command[30] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x7c, @@ -331,7 +324,7 @@ u32 tpm_read_pubek(struct udevice *dev, void *data, size_t count) return 0; } -u32 tpm_force_clear(struct udevice *dev) +u32 tpm1_force_clear(struct udevice *dev) { const u8 command[10] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d, @@ -340,7 +333,7 @@ u32 tpm_force_clear(struct udevice *dev) return tpm_sendrecv_command(dev, command, NULL, NULL); } -u32 tpm_physical_enable(struct udevice *dev) +u32 tpm1_physical_enable(struct udevice *dev) { const u8 command[10] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f, @@ -349,7 +342,7 @@ u32 tpm_physical_enable(struct udevice *dev) return tpm_sendrecv_command(dev, command, NULL, NULL); } -u32 tpm_physical_disable(struct udevice *dev) +u32 tpm1_physical_disable(struct udevice *dev) { const u8 command[10] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70, @@ -358,7 +351,7 @@ u32 tpm_physical_disable(struct udevice *dev) return tpm_sendrecv_command(dev, command, NULL, NULL); } -u32 tpm_physical_set_deactivated(struct udevice *dev, u8 state) +u32 tpm1_physical_set_deactivated(struct udevice *dev, u8 state) { const u8 command[11] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72, @@ -374,8 +367,8 @@ u32 tpm_physical_set_deactivated(struct udevice *dev, u8 state) return tpm_sendrecv_command(dev, buf, NULL, NULL); } -u32 tpm_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap, - void *cap, size_t count) +u32 tpm1_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap, + void *cap, size_t count) { const u8 command[22] = { 0x0, 0xc1, /* TPM_TAG */ @@ -414,8 +407,8 @@ u32 tpm_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap, return 0; } -u32 tpm_get_permanent_flags(struct udevice *dev, - struct tpm_permanent_flags *pflags) +u32 tpm1_get_permanent_flags(struct udevice *dev, + struct tpm_permanent_flags *pflags) { const u8 command[22] = { 0x0, 0xc1, /* TPM_TAG */ @@ -453,7 +446,7 @@ u32 tpm_get_permanent_flags(struct udevice *dev, return 0; } -u32 tpm_get_permissions(struct udevice *dev, u32 index, u32 *perm) +u32 tpm1_get_permissions(struct udevice *dev, u32 index, u32 *perm) { const u8 command[22] = { 0x0, 0xc1, /* TPM_TAG */ @@ -482,7 +475,7 @@ u32 tpm_get_permissions(struct udevice *dev, u32 index, u32 *perm) } #ifdef CONFIG_TPM_FLUSH_RESOURCES -u32 tpm_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type) +u32 tpm1_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type) { const u8 command[18] = { 0x00, 0xc1, /* TPM_TAG */ @@ -641,7 +634,7 @@ static u32 verify_response_auth(u32 command_code, const void *response, return TPM_SUCCESS; } -u32 tpm_terminate_auth_session(struct udevice *dev, u32 auth_handle) +u32 tpm1_terminate_auth_session(struct udevice *dev, u32 auth_handle) { const u8 command[18] = { 0x00, 0xc1, /* TPM_TAG */ @@ -663,16 +656,16 @@ u32 tpm_terminate_auth_session(struct udevice *dev, u32 auth_handle) return tpm_sendrecv_command(dev, request, NULL, NULL); } -u32 tpm_end_oiap(struct udevice *dev) +u32 tpm1_end_oiap(struct udevice *dev) { u32 err = TPM_SUCCESS; if (oiap_session.valid) - err = tpm_terminate_auth_session(dev, oiap_session.handle); + err = tpm1_terminate_auth_session(dev, oiap_session.handle); return err; } -u32 tpm_oiap(struct udevice *dev, u32 *auth_handle) +u32 tpm1_oiap(struct udevice *dev, u32 *auth_handle) { const u8 command[10] = { 0x00, 0xc1, /* TPM_TAG */ @@ -686,7 +679,7 @@ u32 tpm_oiap(struct udevice *dev, u32 *auth_handle) u32 err; if (oiap_session.valid) - tpm_terminate_auth_session(dev, oiap_session.handle); + tpm1_terminate_auth_session(dev, oiap_session.handle); err = tpm_sendrecv_command(dev, command, response, &response_length); if (err) @@ -702,9 +695,9 @@ u32 tpm_oiap(struct udevice *dev, u32 *auth_handle) return 0; } -u32 tpm_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key, - size_t key_length, const void *parent_key_usage_auth, - u32 *key_handle) +u32 tpm1_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key, + size_t key_length, const void *parent_key_usage_auth, + u32 *key_handle) { const u8 command[14] = { 0x00, 0xc2, /* TPM_TAG */ @@ -723,7 +716,7 @@ u32 tpm_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key, u32 err; if (!oiap_session.valid) { - err = tpm_oiap(dev, NULL); + err = tpm1_oiap(dev, NULL); if (err) return err; } @@ -768,9 +761,9 @@ u32 tpm_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key, return 0; } -u32 tpm_get_pub_key_oiap(struct udevice *dev, u32 key_handle, - const void *usage_auth, void *pubkey, - size_t *pubkey_len) +u32 tpm1_get_pub_key_oiap(struct udevice *dev, u32 key_handle, + const void *usage_auth, void *pubkey, + size_t *pubkey_len) { const u8 command[14] = { 0x00, 0xc2, /* TPM_TAG */ @@ -788,7 +781,7 @@ u32 tpm_get_pub_key_oiap(struct udevice *dev, u32 key_handle, u32 err; if (!oiap_session.valid) { - err = tpm_oiap(dev, NULL); + err = tpm1_oiap(dev, NULL); if (err) return err; } @@ -834,8 +827,8 @@ u32 tpm_get_pub_key_oiap(struct udevice *dev, u32 key_handle, } #ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1 -u32 tpm_find_key_sha1(struct udevice *dev, const u8 auth[20], - const u8 pubkey_digest[20], u32 *handle) +u32 tpm1_find_key_sha1(struct udevice *dev, const u8 auth[20], + const u8 pubkey_digest[20], u32 *handle) { u16 key_count; u32 key_handles[10]; @@ -876,7 +869,7 @@ u32 tpm_find_key_sha1(struct udevice *dev, const u8 auth[20], #endif /* CONFIG_TPM_AUTH_SESSIONS */ -u32 tpm_get_random(struct udevice *dev, void *data, u32 count) +u32 tpm1_get_random(struct udevice *dev, void *data, u32 count) { const u8 command[14] = { 0x0, 0xc1, /* TPM_TAG */ -- cgit v1.3.1 From 9586a481731c67997a09162dd41579dbc8c35db6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 20 Jan 2021 20:10:56 -0700 Subject: tpm: Don't select LOG We don't need to enable logging to run this command since the output will still appear. Drop the 'select'. Signed-off-by: Simon Glass --- cmd/Kconfig | 1 - 1 file changed, 1 deletion(-) (limited to 'cmd') diff --git a/cmd/Kconfig b/cmd/Kconfig index 4defbd9cf9c..400133f8de9 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2027,7 +2027,6 @@ config CMD_TPM_V1 config CMD_TPM_V2 bool - select CMD_LOG config CMD_TPM bool "Enable the 'tpm' command" -- cgit v1.3.1 From 26839e5ddee369ea68acd8cbc8e24c7180c17e82 Mon Sep 17 00:00:00 2001 From: Jorge Ramirez-Ortiz Date: Sun, 14 Feb 2021 16:27:24 +0100 Subject: cmd: SCP03: enable and provision command Enable and provision the SCP03 keys on a TEE controlled secured elemt from the U-Boot shell. Executing this command will generate and program new SCP03 encryption keys on the secure element NVM. Depending on the TEE implementation, the keys would then be stored in some persistent storage or better derived from some platform secret (so they can't be lost). Signed-off-by: Jorge Ramirez-Ortiz Reviewed-by: Simon Glass Reviewed-by: Igor Opaniuk --- cmd/Kconfig | 8 ++++++++ cmd/Makefile | 3 +++ cmd/scp03.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 cmd/scp03.c (limited to 'cmd') diff --git a/cmd/Kconfig b/cmd/Kconfig index 400133f8de9..960080d6d40 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2022,6 +2022,14 @@ config HASH_VERIFY help Add -v option to verify data against a hash. +config CMD_SCP03 + bool "scp03 - SCP03 enable and rotate/provision operations" + depends on SCP03 + help + This command provides access to a Trusted Application + running in a TEE to request Secure Channel Protocol 03 + (SCP03) enablement and/or rotation of its SCP03 keys. + config CMD_TPM_V1 bool diff --git a/cmd/Makefile b/cmd/Makefile index 176bf925fdc..a7017e84524 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -193,6 +193,9 @@ obj-$(CONFIG_CMD_BLOB) += blob.o # Android Verified Boot 2.0 obj-$(CONFIG_CMD_AVB) += avb.o +# Foundries.IO SCP03 +obj-$(CONFIG_CMD_SCP03) += scp03.o + obj-$(CONFIG_ARM) += arm/ obj-$(CONFIG_RISCV) += riscv/ obj-$(CONFIG_SANDBOX) += sandbox/ diff --git a/cmd/scp03.c b/cmd/scp03.c new file mode 100644 index 00000000000..655e0bba08b --- /dev/null +++ b/cmd/scp03.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2021, Foundries.IO + * + */ + +#include +#include +#include +#include + +int do_scp03_enable(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + if (argc != 1) + return CMD_RET_USAGE; + + if (tee_enable_scp03()) { + printf("TEE failed to enable SCP03\n"); + return CMD_RET_FAILURE; + } + + printf("SCP03 is enabled\n"); + + return CMD_RET_SUCCESS; +} + +int do_scp03_provision(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + if (argc != 1) + return CMD_RET_USAGE; + + if (tee_provision_scp03()) { + printf("TEE failed to provision SCP03 keys\n"); + return CMD_RET_FAILURE; + } + + printf("SCP03 is provisioned\n"); + + return CMD_RET_SUCCESS; +} + +static char text[] = + "provides a command to enable SCP03 and provision the SCP03 keys\n" + " enable - enable SCP03 on the TEE\n" + " provision - provision SCP03 on the TEE\n"; + +U_BOOT_CMD_WITH_SUBCMDS(scp03, "Secure Channel Protocol 03 control", text, + U_BOOT_SUBCMD_MKENT(enable, 1, 1, do_scp03_enable), + U_BOOT_SUBCMD_MKENT(provision, 1, 1, do_scp03_provision)); + -- cgit v1.3.1 From df7d89a6fcd1920944c2e8b257525b3fb7226dbe Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 7 Feb 2021 14:27:02 -0700 Subject: efi: Fix compiler warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This occur when building on Raspberry Pi 400 (32-bit ARM). Fix them. Examples: cmd/efidebug.c: In function ‘do_efi_capsule_update’: cmd/efidebug.c:75:49: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] ret = EFI_CALL(RT->update_capsule(&capsule, 1, (u64)NULL)); ^ include/efi_loader.h:104:9: note: in definition of macro ‘EFI_CALL’ typeof(exp) _r = exp; \ ^~~ cmd/efidebug.c:75:49: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] ret = EFI_CALL(RT->update_capsule(&capsule, 1, (u64)NULL)); ^ include/efi_loader.h:104:19: note: in definition of macro ‘EFI_CALL’ typeof(exp) _r = exp; \ ^~~ In file included from include/common.h:20, from lib/efi_loader/efi_capsule.c:9: lib/efi_loader/efi_capsule.c: In function ‘efi_update_capsule’: include/efi_loader.h:83:8: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 10 has type ‘size_t’ {aka ‘unsigned int’} [-Wformat=] debug("%sEFI: Entry %s(" format ")\n", __efi_nesting_inc(), \ ^~~~~~~~~~~~~~~~~~ include/linux/printk.h:37:21: note: in definition of macro ‘pr_fmt’ #define pr_fmt(fmt) fmt ^~~ include/log.h:229:2: note: in expansion of macro ‘log’ log(LOG_CATEGORY, LOGL_DEBUG, fmt, ##args); \ ^~~ include/log.h:249:2: note: in expansion of macro ‘debug_cond’ debug_cond(_DEBUG, fmt, ##args) ^~~~~~~~~~ include/efi_loader.h:83:2: note: in expansion of macro ‘debug’ debug("%sEFI: Entry %s(" format ")\n", __efi_nesting_inc(), \ ^~~~~ lib/efi_loader/efi_capsule.c:444:2: note: in expansion of macro ‘EFI_ENTRY’ EFI_ENTRY("%p, %lu, %llu\n", capsule_header_array, capsule_count, ^~~~~~~~~ lib/efi_loader/efi_capsule.c:444:19: note: format string is defined here EFI_ENTRY("%p, %lu, %llu\n", capsule_header_array, capsule_count, ~~^ %u Signed-off-by: Simon Glass Replace (uintptr_t)NULL by 0. Reviewed-by: Heinrich Schuchardt --- cmd/efidebug.c | 2 +- lib/efi_loader/efi_capsule.c | 4 ++-- lib/efi_loader/efi_firmware.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'cmd') diff --git a/cmd/efidebug.c b/cmd/efidebug.c index e4030f514a6..55c7abe3d07 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -72,7 +72,7 @@ static int do_efi_capsule_update(struct cmd_tbl *cmdtp, int flag, capsule->capsule_image_size); } - ret = EFI_CALL(RT->update_capsule(&capsule, 1, (u64)NULL)); + ret = EFI_CALL(RT->update_capsule(&capsule, 1, 0)); if (ret) { printf("Cannot handle a capsule at %p", capsule); return CMD_RET_FAILURE; diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index b57f0302c59..7ba1ced0a08 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -449,7 +449,7 @@ efi_status_t EFIAPI efi_update_capsule( unsigned int i; efi_status_t ret; - EFI_ENTRY("%p, %lu, %llu\n", capsule_header_array, capsule_count, + EFI_ENTRY("%p, %zu, %llu\n", capsule_header_array, capsule_count, scatter_gather_list); if (!capsule_count) { @@ -509,7 +509,7 @@ efi_status_t EFIAPI efi_query_capsule_caps( unsigned int i; efi_status_t ret; - EFI_ENTRY("%p, %lu, %p, %p\n", capsule_header_array, capsule_count, + EFI_ENTRY("%p, %zu, %p, %p\n", capsule_header_array, capsule_count, maximum_capsule_size, reset_type); if (!maximum_capsule_size) { diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index 5e401bbca2b..7a3cca27936 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -299,7 +299,7 @@ efi_status_t EFIAPI efi_firmware_fit_set_image( efi_status_t (*progress)(efi_uintn_t completion), u16 **abort_reason) { - EFI_ENTRY("%p %d %p %ld %p %p %p\n", this, image_index, image, + EFI_ENTRY("%p %d %p %zd %p %p %p\n", this, image_index, image, image_size, vendor_code, progress, abort_reason); if (!image || image_index != 1) @@ -414,7 +414,7 @@ efi_status_t EFIAPI efi_firmware_raw_set_image( efi_status_t status; efi_uintn_t capsule_payload_size; - EFI_ENTRY("%p %d %p %ld %p %p %p\n", this, image_index, image, + EFI_ENTRY("%p %d %p %zd %p %p %p\n", this, image_index, image, image_size, vendor_code, progress, abort_reason); if (!image) -- cgit v1.3.1 From 7dbd7dd399a8b0fe17a4ce1da421b48c0621532b Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 19 Mar 2021 02:50:57 +0000 Subject: cmd/load: support uploading EFI binary via UART When uploading an EFI binary via the UART we have to call efi_set_bootdev() or we won't be able to execute it. Put the includes into alphabetic order. Fixes: 5f59518a7b1a ("efi_loader: setting boot device") Signed-off-by: Heinrich Schuchardt --- cmd/load.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'cmd') diff --git a/cmd/load.c b/cmd/load.c index 5bbc39baead..b7894d7db02 100644 --- a/cmd/load.c +++ b/cmd/load.c @@ -11,12 +11,14 @@ #include #include #include +#include #include +#include #include #include -#include +#include #include -#include +#include #include #include #include @@ -996,6 +998,10 @@ static ulong load_serial_ymodem(ulong offset, int mode) } } + if (IS_ENABLED(CONFIG_CMD_BOOTEFI)) + efi_set_bootdev("Uart", "", "", + map_sysmem(offset, 0), size); + } else { printf("%s\n", xyzModem_error(err)); } -- cgit v1.3.1 From 53f6a5aa86267a59ea9d45c89405e42002410e37 Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Wed, 17 Mar 2021 21:55:00 +0200 Subject: efi_loader: Replace config option for initrd loading Up to now we install EFI_LOAD_FILE2_PROTOCOL to load an initrd unconditionally. Although we correctly return various EFI exit codes depending on the file status (i.e EFI_NO_MEDIA, EFI_NOT_FOUND etc), the kernel loader, only falls back to the cmdline interpreted initrd if the protocol is not installed. This creates a problem for EFI installers, since they won't be able to load their own initrd and continue the installation. It also makes the feature hard to use, since we can either have a single initrd or we have to recompile u-boot if the filename changes. So let's introduce a different logic that will decouple the initrd path from the config option we currently have. When defining a UEFI BootXXXX we can use the filepathlist and store a file path pointing to our initrd. Specifically the EFI spec describes: "The first element of the array is a device path that describes the device and location of the Image for this load option. Other device paths may optionally exist in the FilePathList, but their usage is OSV specific" When the EFI application is launched through the bootmgr, we'll try to interpret the extra device path. If that points to a file that exists on our disk, we'll now install the load_file2 and the efi-stub will be able to use it. This opens up another path using U-Boot and defines a new boot flow. A user will be able to control the kernel/initrd pairs without explicit cmdline args or GRUB. Signed-off-by: Ilias Apalodimas Reviewed-by: Heinrich Schuchardt --- cmd/bootefi.c | 3 + include/efi_loader.h | 1 + lib/efi_loader/Kconfig | 17 ++-- lib/efi_loader/efi_bootmgr.c | 19 +++- lib/efi_loader/efi_load_initrd.c | 202 +++++++++++++++++++++++---------------- 5 files changed, 144 insertions(+), 98 deletions(-) (limited to 'cmd') diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 271b385edea..cba81ffe75e 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -358,6 +358,9 @@ static efi_status_t do_bootefi_exec(efi_handle_t handle, void *load_options) free(load_options); + if (IS_ENABLED(CONFIG_EFI_LOAD_FILE2_INITRD)) + efi_initrd_deregister(); + return ret; } diff --git a/include/efi_loader.h b/include/efi_loader.h index 9c227005d13..903bf60bc0a 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -437,6 +437,7 @@ efi_status_t efi_net_register(void); /* Called by bootefi to make the watchdog available */ efi_status_t efi_watchdog_register(void); efi_status_t efi_initrd_register(void); +void efi_initrd_deregister(void); /* Called by bootefi to make SMBIOS tables available */ /** * efi_acpi_register() - write out ACPI tables diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 634d3b1ff4e..0a412441a71 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -315,18 +315,13 @@ config EFI_TCG2_PROTOCOL_EVENTLOG_SIZE config EFI_LOAD_FILE2_INITRD bool "EFI_FILE_LOAD2_PROTOCOL for Linux initial ramdisk" - default n - help - Expose a EFI_FILE_LOAD2_PROTOCOL that the Linux UEFI stub can - use to load the initial ramdisk. Once this is enabled using - initrd= will stop working. - -config EFI_INITRD_FILESPEC - string "initramfs path" - default "host 0:1 initrd" - depends on EFI_LOAD_FILE2_INITRD + default y help - Full path of the initramfs file, e.g. mmc 0:2 initramfs.cpio.gz. + Linux v5.7 and later can make use of this option. If the boot option + selected by the UEFI boot manager specifies an existing file to be used + as initial RAM disk, a Linux specific Load File2 protocol will be + installed and Linux 5.7+ will ignore any initrd= command line + argument. config EFI_SECURE_BOOT bool "Enable EFI secure boot support" diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index 25f5cebfdb6..46c8011344b 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -118,11 +118,13 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle, ret = efi_set_variable_int(L"BootCurrent", &efi_global_variable_guid, attributes, sizeof(n), &n, false); - if (ret != EFI_SUCCESS) { - if (EFI_CALL(efi_unload_image(*handle)) - != EFI_SUCCESS) - log_err("Unloading image failed\n"); - goto error; + if (ret != EFI_SUCCESS) + goto unload; + /* try to register load file2 for initrd's */ + if (IS_ENABLED(CONFIG_EFI_LOAD_FILE2_INITRD)) { + ret = efi_initrd_register(); + if (ret != EFI_SUCCESS) + goto unload; } log_info("Booting: %ls\n", lo.label); @@ -146,6 +148,13 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle, error: free(load_option); + return ret; + +unload: + if (EFI_CALL(efi_unload_image(*handle)) != EFI_SUCCESS) + log_err("Unloading image failed\n"); + free(load_option); + return ret; } diff --git a/lib/efi_loader/efi_load_initrd.c b/lib/efi_loader/efi_load_initrd.c index b9ee8839054..e2a80630230 100644 --- a/lib/efi_loader/efi_load_initrd.c +++ b/lib/efi_loader/efi_load_initrd.c @@ -3,9 +3,11 @@ * Copyright (c) 2020, Linaro Limited */ +#define LOG_CATEGORY LOGC_EFI #include #include #include +#include #include #include #include @@ -23,57 +25,56 @@ static const struct efi_load_file_protocol efi_lf2_protocol = { * Device path defined by Linux to identify the handle providing the * EFI_LOAD_FILE2_PROTOCOL used for loading the initial ramdisk. */ -static const struct efi_initrd_dp dp = { +static const struct efi_initrd_dp dp_lf2_handle = { .vendor = { { DEVICE_PATH_TYPE_MEDIA_DEVICE, DEVICE_PATH_SUB_TYPE_VENDOR_PATH, - sizeof(dp.vendor), + sizeof(dp_lf2_handle.vendor), }, EFI_INITRD_MEDIA_GUID, }, .end = { DEVICE_PATH_TYPE_END, DEVICE_PATH_SUB_TYPE_END, - sizeof(dp.end), + sizeof(dp_lf2_handle.end), } }; +static efi_handle_t efi_initrd_handle; + /** - * get_file_size() - retrieve the size of initramfs, set efi status on error + * get_initrd_fp() - Get initrd device path from a FilePathList device path * - * @dev: device to read from, e.g. "mmc" - * @part: device partition, e.g. "0:1" - * @file: name of file - * @status: EFI exit code in case of failure + * @initrd_fp: the final initrd filepath * - * Return: size of file + * Return: status code. Caller must free initrd_fp */ -static loff_t get_file_size(const char *dev, const char *part, const char *file, - efi_status_t *status) +static efi_status_t get_initrd_fp(struct efi_device_path **initrd_fp) { - loff_t sz = 0; - int ret; - - ret = fs_set_blk_dev(dev, part, FS_TYPE_ANY); - if (ret) { - *status = EFI_NO_MEDIA; - goto out; - } + const efi_guid_t lf2_initrd_guid = EFI_INITRD_MEDIA_GUID; + struct efi_device_path *dp = NULL; - ret = fs_size(file, &sz); - if (ret) { - sz = 0; - *status = EFI_NOT_FOUND; - goto out; - } + /* + * if bootmgr is setup with and initrd, the device path will be + * in the FilePathList[] of our load options in Boot####. + * The first device path of the multi instance device path will + * start with a VenMedia and the initrds will follow. + * + * If the device path is not found return EFI_INVALID_PARAMETER. + * We can then use this specific return value and not install the + * protocol, while allowing the boot to continue + */ + dp = efi_get_dp_from_boot(lf2_initrd_guid); + if (!dp) + return EFI_INVALID_PARAMETER; -out: - return sz; + *initrd_fp = dp; + return EFI_SUCCESS; } /** - * efi_load_file2initrd() - load initial RAM disk + * efi_load_file2_initrd() - load initial RAM disk * * This function implements the LoadFile service of the EFI_LOAD_FILE2_PROTOCOL * in order to load an initial RAM disk requested by the Linux kernel stub. @@ -93,102 +94,125 @@ efi_load_file2_initrd(struct efi_load_file_protocol *this, struct efi_device_path *file_path, bool boot_policy, efi_uintn_t *buffer_size, void *buffer) { - char *filespec; - efi_status_t status = EFI_NOT_FOUND; - loff_t file_sz = 0, read_sz = 0; - char *dev, *part, *file; - char *pos; - int ret; + struct efi_device_path *initrd_fp = NULL; + efi_status_t ret = EFI_NOT_FOUND; + struct efi_file_handle *f = NULL; + efi_uintn_t bs; EFI_ENTRY("%p, %p, %d, %p, %p", this, file_path, boot_policy, buffer_size, buffer); - filespec = strdup(CONFIG_EFI_INITRD_FILESPEC); - if (!filespec) - goto out; - pos = filespec; - if (!this || this != &efi_lf2_protocol || !buffer_size) { - status = EFI_INVALID_PARAMETER; + ret = EFI_INVALID_PARAMETER; goto out; } - if (file_path->type != dp.end.type || - file_path->sub_type != dp.end.sub_type) { - status = EFI_INVALID_PARAMETER; + if (file_path->type != dp_lf2_handle.end.type || + file_path->sub_type != dp_lf2_handle.end.sub_type) { + ret = EFI_INVALID_PARAMETER; goto out; } if (boot_policy) { - status = EFI_UNSUPPORTED; + ret = EFI_UNSUPPORTED; goto out; } - /* - * expect a string with three space separated parts: - * - * * a block device type, e.g. "mmc" - * * a device and partition identifier, e.g. "0:1" - * * a file path on the block device, e.g. "/boot/initrd.cpio.gz" - */ - dev = strsep(&pos, " "); - if (!dev) + ret = get_initrd_fp(&initrd_fp); + if (ret != EFI_SUCCESS) goto out; - part = strsep(&pos, " "); - if (!part) - goto out; - file = strsep(&pos, " "); - if (!file) + + /* Open file */ + f = efi_file_from_path(initrd_fp); + if (!f) { + log_err("Can't find initrd specified in Boot####\n"); + ret = EFI_NOT_FOUND; goto out; + } - file_sz = get_file_size(dev, part, file, &status); - if (!file_sz) + /* Get file size */ + ret = efi_file_size(f, &bs); + if (ret != EFI_SUCCESS) goto out; - if (!buffer || *buffer_size < file_sz) { - status = EFI_BUFFER_TOO_SMALL; - *buffer_size = file_sz; + if (!buffer || *buffer_size < bs) { + ret = EFI_BUFFER_TOO_SMALL; + *buffer_size = bs; } else { - ret = fs_set_blk_dev(dev, part, FS_TYPE_ANY); - if (ret) { - status = EFI_NO_MEDIA; - goto out; - } - - ret = fs_read(file, map_to_sysmem(buffer), 0, *buffer_size, - &read_sz); - if (ret || read_sz != file_sz) - goto out; - *buffer_size = read_sz; - - status = EFI_SUCCESS; + ret = EFI_CALL(f->read(f, &bs, (void *)(uintptr_t)buffer)); + *buffer_size = bs; + } + +out: + efi_free_pool(initrd_fp); + if (f) + EFI_CALL(f->close(f)); + return EFI_EXIT(ret); +} + +/** + * check_initrd() - Determine if the file defined as an initrd in Boot#### + * load_options device path is present + * + * Return: status code + */ +static efi_status_t check_initrd(void) +{ + struct efi_device_path *initrd_fp = NULL; + struct efi_file_handle *f; + efi_status_t ret; + + ret = get_initrd_fp(&initrd_fp); + if (ret != EFI_SUCCESS) + goto out; + + /* + * If the file is not found, but the file path is set, return an error + * and trigger the bootmgr fallback + */ + f = efi_file_from_path(initrd_fp); + if (!f) { + log_err("Can't find initrd specified in Boot####\n"); + ret = EFI_NOT_FOUND; + goto out; } + EFI_CALL(f->close(f)); + out: - free(filespec); - return EFI_EXIT(status); + efi_free_pool(initrd_fp); + return ret; } /** * efi_initrd_register() - create handle for loading initial RAM disk * * This function creates a new handle and installs a Linux specific vendor - * device path and an EFI_LOAD_FILE_2_PROTOCOL. Linux uses the device path + * device path and an EFI_LOAD_FILE2_PROTOCOL. Linux uses the device path * to identify the handle and then calls the LoadFile service of the - * EFI_LOAD_FILE_2_PROTOCOL to read the initial RAM disk. + * EFI_LOAD_FILE2_PROTOCOL to read the initial RAM disk. * * Return: status code */ efi_status_t efi_initrd_register(void) { - efi_handle_t efi_initrd_handle = NULL; efi_status_t ret; + /* + * Allow the user to continue if Boot#### file path is not set for + * an initrd + */ + ret = check_initrd(); + if (ret == EFI_INVALID_PARAMETER) + return EFI_SUCCESS; + if (ret != EFI_SUCCESS) + return ret; + ret = EFI_CALL(efi_install_multiple_protocol_interfaces (&efi_initrd_handle, /* initramfs */ - &efi_guid_device_path, &dp, + &efi_guid_device_path, &dp_lf2_handle, /* LOAD_FILE2 */ &efi_guid_load_file2_protocol, (void *)&efi_lf2_protocol, @@ -196,3 +220,17 @@ efi_status_t efi_initrd_register(void) return ret; } + +/** + * efi_initrd_deregister() - delete the handle for loading initial RAM disk + * + * This will delete the handle containing the Linux specific vendor device + * path and EFI_LOAD_FILE2_PROTOCOL for loading an initrd + * + * Return: status code + */ +void efi_initrd_deregister(void) +{ + efi_delete_handle(efi_initrd_handle); + efi_initrd_handle = NULL; +} -- cgit v1.3.1 From cbea241e935ec754df44d5de0ad20b801f2d3f90 Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Wed, 17 Mar 2021 21:55:01 +0200 Subject: efidebug: add multiple device path instances on Boot#### The UEFI spec allows a packed array of UEFI device paths in the FilePathList[] of an EFI_LOAD_OPTION. The first file path must describe the loaded image but the rest are OS specific. Previous patches parse the device path and try to use the second member of the array as an initrd. So let's modify efidebug slightly and install the second file described in the command line as the initrd device path. Signed-off-by: Ilias Apalodimas --- cmd/efidebug.c | 191 +++++++++++++++++---- doc/board/emulation/qemu_capsule_update.rst | 4 +- doc/uefi/uefi.rst | 2 +- .../test_efi_capsule/test_capsule_firmware.py | 6 +- test/py/tests/test_efi_secboot/test_signed.py | 16 +- .../py/tests/test_efi_secboot/test_signed_intca.py | 8 +- test/py/tests/test_efi_secboot/test_unsigned.py | 8 +- 7 files changed, 177 insertions(+), 58 deletions(-) (limited to 'cmd') diff --git a/cmd/efidebug.c b/cmd/efidebug.c index 55c7abe3d07..80ddd598e0a 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include #define BS systab.boottime #define RT systab.runtime @@ -798,6 +800,54 @@ static int do_efi_show_tables(struct cmd_tbl *cmdtp, int flag, return CMD_RET_SUCCESS; } +/** + * create_initrd_dp() - Create a special device for our Boot### option + * + * @dev: Device + * @part: Disk partition + * @file: Filename + * Return: Pointer to the device path or ERR_PTR + * + */ +static +struct efi_device_path *create_initrd_dp(const char *dev, const char *part, + const char *file) + +{ + struct efi_device_path *tmp_dp = NULL, *tmp_fp = NULL; + struct efi_device_path *initrd_dp = NULL; + efi_status_t ret; + const struct efi_initrd_dp id_dp = { + .vendor = { + { + DEVICE_PATH_TYPE_MEDIA_DEVICE, + DEVICE_PATH_SUB_TYPE_VENDOR_PATH, + sizeof(id_dp.vendor), + }, + EFI_INITRD_MEDIA_GUID, + }, + .end = { + DEVICE_PATH_TYPE_END, + DEVICE_PATH_SUB_TYPE_END, + sizeof(id_dp.end), + } + }; + + ret = efi_dp_from_name(dev, part, file, &tmp_dp, &tmp_fp); + if (ret != EFI_SUCCESS) { + printf("Cannot create device path for \"%s %s\"\n", part, file); + goto out; + } + + initrd_dp = efi_dp_append((const struct efi_device_path *)&id_dp, + tmp_fp); + +out: + efi_free_pool(tmp_dp); + efi_free_pool(tmp_fp); + return initrd_dp; +} + /** * do_efi_boot_add() - set UEFI load option * @@ -810,7 +860,9 @@ static int do_efi_show_tables(struct cmd_tbl *cmdtp, int flag, * * Implement efidebug "boot add" sub-command. Create or change UEFI load option. * - * efidebug boot add