diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Kconfig | 32 | ||||
-rw-r--r-- | lib/Makefile | 10 | ||||
-rw-r--r-- | lib/fdtdec.c | 83 | ||||
-rw-r--r-- | lib/hang.c | 5 | ||||
-rw-r--r-- | lib/tpm-common.c | 10 | ||||
-rw-r--r-- | lib/tpm-v1.c | 68 |
6 files changed, 114 insertions, 94 deletions
diff --git a/lib/Kconfig b/lib/Kconfig index 622f3c26c33..ccab426e121 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -185,6 +185,28 @@ config TPM for the low-level TPM interface, but only one TPM is supported at a time by the TPM library. +config SPL_TPM + bool "Trusted Platform Module (TPM) Support in SPL" + depends on SPL_DM + help + This enables support for TPMs which can be used to provide security + features for your board. The TPM can be connected via LPC or I2C + and a sandbox TPM is provided for testing purposes. Use the 'tpm' + command to interactive the TPM. Driver model support is provided + for the low-level TPM interface, but only one TPM is supported at + a time by the TPM library. + +config TPL_TPM + bool "Trusted Platform Module (TPM) Support in TPL" + depends on TPL_DM + help + This enables support for TPMs which can be used to provide security + features for your board. The TPM can be connected via LPC or I2C + and a sandbox TPM is provided for testing purposes. Use the 'tpm' + command to interactive the TPM. Driver model support is provided + for the low-level TPM interface, but only one TPM is supported at + a time by the TPM library. + endmenu menu "Android Verified Boot" @@ -331,6 +353,16 @@ config SPL_OF_LIBFDT particular compatible nodes. The library operates on a flattened version of the device tree. +config TPL_OF_LIBFDT + bool "Enable the FDT library for TPL" + default y if TPL_OF_CONTROL + help + This enables the FDT library (libfdt). It provides functions for + accessing binary device tree images in memory, such as adding and + removing nodes and properties, scanning through the tree and finding + particular compatible nodes. The library operates on a flattened + version of the device tree. + config FDT_FIXUP_PARTITIONS bool "overwrite MTD partitions in DTS through defined in 'mtdparts'" depends on OF_LIBFDT diff --git a/lib/Makefile b/lib/Makefile index f1696448506..fb6944128aa 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -45,14 +45,18 @@ obj-$(CONFIG_PHYSMEM) += physmem.o obj-y += qsort.o obj-y += rc4.o obj-$(CONFIG_SUPPORT_EMMC_RPMB) += sha256.o -obj-$(CONFIG_TPM) += tpm-common.o -obj-$(CONFIG_TPM_V1) += tpm-v1.o -obj-$(CONFIG_TPM_V2) += tpm-v2.o obj-$(CONFIG_RBTREE) += rbtree.o obj-$(CONFIG_BITREVERSE) += bitrev.o obj-y += list_sort.o endif +obj-$(CONFIG_$(SPL_TPL_)TPM) += tpm-common.o +ifeq ($(CONFIG_$(SPL_TPL_)TPM),y) +obj-y += crc8.o +obj-$(CONFIG_TPM_V1) += tpm-v1.o +obj-$(CONFIG_TPM_V2) += tpm-v2.o +endif + obj-$(CONFIG_RSA) += rsa/ obj-$(CONFIG_SHA1) += sha1.o obj-$(CONFIG_SHA256) += sha256.o diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 74196ce7f9f..b1b39254bfd 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -922,28 +922,6 @@ char *fdtdec_get_config_string(const void *blob, const char *prop_name) return (char *)nodep; } -int fdtdec_decode_region(const void *blob, int node, const char *prop_name, - fdt_addr_t *basep, fdt_size_t *sizep) -{ - const fdt_addr_t *cell; - int len; - - debug("%s: %s: %s\n", __func__, fdt_get_name(blob, node, NULL), - prop_name); - cell = fdt_getprop(blob, node, prop_name, &len); - if (!cell || (len < sizeof(fdt_addr_t) * 2)) { - debug("cell=%p, len=%d\n", cell, len); - return -1; - } - - *basep = fdt_addr_to_cpu(*cell); - *sizep = fdt_size_to_cpu(cell[1]); - debug("%s: base=%08lx, size=%lx\n", __func__, (ulong)*basep, - (ulong)*sizep); - - return 0; -} - u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells) { u64 number = 0; @@ -1002,67 +980,6 @@ int fdt_get_named_resource(const void *fdt, int node, const char *property, return fdt_get_resource(fdt, node, property, index, res); } -int fdtdec_decode_memory_region(const void *blob, int config_node, - const char *mem_type, const char *suffix, - fdt_addr_t *basep, fdt_size_t *sizep) -{ - char prop_name[50]; - const char *mem; - fdt_size_t size, offset_size; - fdt_addr_t base, offset; - int node; - - if (config_node == -1) { - config_node = fdt_path_offset(blob, "/config"); - if (config_node < 0) { - debug("%s: Cannot find /config node\n", __func__); - return -ENOENT; - } - } - if (!suffix) - suffix = ""; - - snprintf(prop_name, sizeof(prop_name), "%s-memory%s", mem_type, - suffix); - mem = fdt_getprop(blob, config_node, prop_name, NULL); - if (!mem) { - debug("%s: No memory type for '%s', using /memory\n", __func__, - prop_name); - mem = "/memory"; - } - - node = fdt_path_offset(blob, mem); - if (node < 0) { - debug("%s: Failed to find node '%s': %s\n", __func__, mem, - fdt_strerror(node)); - return -ENOENT; - } - - /* - * Not strictly correct - the memory may have multiple banks. We just - * use the first - */ - if (fdtdec_decode_region(blob, node, "reg", &base, &size)) { - debug("%s: Failed to decode memory region %s\n", __func__, - mem); - return -EINVAL; - } - - snprintf(prop_name, sizeof(prop_name), "%s-offset%s", mem_type, - suffix); - if (fdtdec_decode_region(blob, config_node, prop_name, &offset, - &offset_size)) { - debug("%s: Failed to decode memory region '%s'\n", __func__, - prop_name); - return -EINVAL; - } - - *basep = base + offset; - *sizep = offset_size; - - return 0; -} - static int decode_timing_property(const void *blob, int node, const char *name, struct timing_entry *result) { diff --git a/lib/hang.c b/lib/hang.c index bf56f4c662a..c5a78694be6 100644 --- a/lib/hang.c +++ b/lib/hang.c @@ -20,8 +20,9 @@ */ void hang(void) { -#if !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \ - defined(CONFIG_SPL_SERIAL_SUPPORT)) +#if !defined(CONFIG_SPL_BUILD) || \ + (CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT) && \ + CONFIG_IS_ENABLED(SERIAL_SUPPORT)) puts("### ERROR ### Please RESET the board ###\n"); #endif bootstage_error(BOOTSTAGE_ID_NEED_RESET); diff --git a/lib/tpm-common.c b/lib/tpm-common.c index 43b530865a0..a440639cec3 100644 --- a/lib/tpm-common.c +++ b/lib/tpm-common.c @@ -4,6 +4,8 @@ * Coypright (c) 2013 Guntermann & Drunck GmbH */ +#define LOG_CATEGORY UCLASS_TPM + #include <common.h> #include <dm.h> #include <asm/unaligned.h> @@ -110,6 +112,8 @@ int unpack_byte_string(const u8 *str, size_t size, const char *format, ...) if (offset + length > size) { va_end(args); + log_err("Failed to read: size=%d, offset=%x, len=%x\n", + size, offset, length); return -1; } @@ -176,10 +180,10 @@ u32 tpm_sendrecv_command(const void *command, void *response, size_t *size_ptr) ret = tpm_return_code(response); - log(LOGC_NONE, LOGL_DEBUG, "TPM response [ret:%d]: ", ret); + log_debug("TPM response [ret:%d]: ", ret); for (i = 0; i < response_length; i++) - log(LOGC_NONE, LOGL_DEBUG, "%02x ", ((u8 *)response)[i]); - log(LOGC_NONE, LOGL_DEBUG, "\n"); + log_debug("%02x ", ((u8 *)response)[i]); + log_debug("\n"); return ret; } diff --git a/lib/tpm-v1.c b/lib/tpm-v1.c index 7aecb24f921..9d45c3d3bf6 100644 --- a/lib/tpm-v1.c +++ b/lib/tpm-v1.c @@ -4,6 +4,8 @@ * Coypright (c) 2013 Guntermann & Drunck GmbH */ +#define LOG_CATEGORY UCLASS_TPM + #include <common.h> #include <dm.h> #include <asm/unaligned.h> @@ -45,6 +47,11 @@ u32 tpm_startup(enum tpm_startup_type mode) return tpm_sendrecv_command(buf, NULL, NULL); } +u32 tpm_resume(void) +{ + return tpm_startup(TPM_ST_STATE); +} + u32 tpm_self_test_full(void) { const u8 command[10] = { @@ -61,6 +68,34 @@ u32 tpm_continue_self_test(void) return tpm_sendrecv_command(command, NULL, NULL); } +u32 tpm_clear_and_reenable(void) +{ + u32 ret; + + log_info("TPM: Clear and re-enable\n"); + ret = tpm_force_clear(); + if (ret != TPM_SUCCESS) { + log_err("Can't initiate a force clear\n"); + return ret; + } + +#if IS_ENABLED(CONFIG_TPM_V1) + ret = tpm_physical_enable(); + if (ret != TPM_SUCCESS) { + log_err("TPM: Can't set enabled state\n"); + return ret; + } + + ret = tpm_physical_set_deactivated(0); + if (ret != TPM_SUCCESS) { + log_err("TPM: Can't set deactivated state\n"); + return ret; + } +#endif + + return TPM_SUCCESS; +} + u32 tpm_nv_define_space(u32 index, u32 perm, u32 size) { const u8 command[101] = { @@ -104,6 +139,11 @@ u32 tpm_nv_define_space(u32 index, u32 perm, u32 size) return tpm_sendrecv_command(buf, NULL, NULL); } +u32 tpm_nv_set_locked(void) +{ + return tpm_nv_define_space(TPM_NV_INDEX_LOCK, 0, 0); +} + u32 tpm_nv_read_value(u32 index, void *data, u32 count) { const u8 command[22] = { @@ -168,6 +208,13 @@ u32 tpm_nv_write_value(u32 index, const void *data, u32 length) return 0; } +uint32_t tpm_set_global_lock(void) +{ + u32 x; + + return tpm_nv_write_value(TPM_NV_INDEX_0, (uint8_t *)&x, 0); +} + u32 tpm_extend(u32 index, const void *in_digest, void *out_digest) { const u8 command[34] = { @@ -243,6 +290,15 @@ u32 tpm_tsc_physical_presence(u16 presence) return tpm_sendrecv_command(buf, NULL, NULL); } +u32 tpm_finalise_physical_presence(void) +{ + const u8 command[12] = { + 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x2, 0xa0, + }; + + return tpm_sendrecv_command(command, NULL, NULL); +} + u32 tpm_read_pubek(void *data, size_t count) { const u8 command[30] = { @@ -377,13 +433,19 @@ u32 tpm_get_permanent_flags(struct tpm_permanent_flags *pflags) if (err) return err; if (unpack_byte_string(response, response_length, "d", - data_size_offset, &data_size)) + data_size_offset, &data_size)) { + log_err("Cannot unpack data size\n"); return TPM_LIB_ERROR; - if (data_size < sizeof(*pflags)) + } + if (data_size < sizeof(*pflags)) { + log_err("Data size too small\n"); return TPM_LIB_ERROR; + } if (unpack_byte_string(response, response_length, "s", - data_offset, pflags, sizeof(*pflags))) + data_offset, pflags, sizeof(*pflags))) { + log_err("Cannot unpack pflags\n"); return TPM_LIB_ERROR; + } return 0; } |