summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig32
-rw-r--r--lib/Makefile10
-rw-r--r--lib/fdtdec.c83
-rw-r--r--lib/hang.c5
-rw-r--r--lib/tpm-common.c10
-rw-r--r--lib/tpm-v1.c68
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;
}