Re: [U-Boot] [PATCH] ARM: aspeed: Add SD host controller driver

2019-08-13 Thread Eddie James


On 8/13/19 11:55 AM, Cédric Le Goater wrote:

On 13/08/2019 08:41, Peng Fan wrote:

Subject: [U-Boot][PATCH] ARM: aspeed: Add SD host controller driver

Add support for the Aspeed SD host controller engine. This involves adding an
MMC SDHCI driver and various additions to the clock and reset drivers for
Aspeed chips.

Signed-off-by: Eddie James 
---
  arch/arm/include/asm/arch-aspeed/scu_ast2500.h |  3 +
  arch/arm/include/asm/gpio.h|  3 +-
  arch/arm/mach-aspeed/ast2500-board.c   |  3 +
  drivers/clk/aspeed/clk_ast2500.c   | 27 +
  drivers/mmc/Kconfig| 11 
  drivers/mmc/Makefile   |  1 +
  drivers/mmc/aspeed_sdhci.c | 78

Please split the patch.

yes. a clock patch, a driver patch, a board integration patch at least,
with some DT addons for the EVB.

Don't we want to sync up the DT from Linux also ?



The Linux one uses a parent node for the whole Aspeed SD controller and 
child nodes for the all the SD card slots. We don't need that parent 
driver in U-Boot and also it seems complicated (i.e. I couldn't figure 
out how) to probe up child nodes with the U-Boot driver model.



Thanks,

Eddie



Thanks,


C.


Thanks,
Peng.


++
  drivers/pinctrl/aspeed/pinctrl_ast2500.c   |  2 +
  8 files changed, 127 insertions(+), 1 deletion(-)  create mode 100644
drivers/mmc/aspeed_sdhci.c

diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
index 4988ced..8db4901 100644
--- a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
+++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
@@ -22,6 +22,8 @@
  #define SCU_MPLL_POST_MASK(0x3f << SCU_MPLL_POST_SHIFT)
  #define SCU_PCLK_DIV_SHIFT23
  #define SCU_PCLK_DIV_MASK (7 << SCU_PCLK_DIV_SHIFT)
+#define SCU_SDCLK_DIV_SHIFT12
+#define SCU_SDCLK_DIV_MASK (7 << SCU_SDCLK_DIV_SHIFT)
  #define SCU_HPLL_DENUM_SHIFT  0
  #define SCU_HPLL_DENUM_MASK   0x1f
  #define SCU_HPLL_NUM_SHIFT5
@@ -107,6 +109,7 @@

  #define SCU_CLKSTOP_MAC1  (1 << 20)
  #define SCU_CLKSTOP_MAC2  (1 << 21)
+#define SCU_CLKSTOP_SDCLK  (1 << 27)

  #define SCU_D2PLL_EXT1_OFF(1 << 0)
  #define SCU_D2PLL_EXT1_BYPASS (1 << 1)
diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h
index 370031f..38a5922 100644
--- a/arch/arm/include/asm/gpio.h
+++ b/arch/arm/include/asm/gpio.h
@@ -1,6 +1,7 @@
  #if !defined(CONFIG_ARCH_UNIPHIER) && !defined(CONFIG_ARCH_STI) &&
\
!defined(CONFIG_ARCH_K3) && !defined(CONFIG_ARCH_BCM6858) &&
\
-   !defined(CONFIG_ARCH_BCM63158)
&& !defined(CONFIG_ARCH_ROCKCHIP)
+   !defined(CONFIG_ARCH_BCM63158)
&& !defined(CONFIG_ARCH_ROCKCHIP) && \
+   !defined(CONFIG_ARCH_ASPEED)
  #include 
  #endif
  #include 
diff --git a/arch/arm/mach-aspeed/ast2500-board.c
b/arch/arm/mach-aspeed/ast2500-board.c
index e7edd54..52a4e05 100644
--- a/arch/arm/mach-aspeed/ast2500-board.c
+++ b/arch/arm/mach-aspeed/ast2500-board.c
@@ -4,6 +4,7 @@
   */
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -55,6 +56,8 @@ int board_init(void)
  {
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;

+   mmc_initialize(gd->bd);
+
return 0;
  }

diff --git a/drivers/clk/aspeed/clk_ast2500.c
b/drivers/clk/aspeed/clk_ast2500.c
index dbee13a..9249cf9 100644
--- a/drivers/clk/aspeed/clk_ast2500.c
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -143,6 +143,17 @@ static ulong ast2500_clk_get_rate(struct clk *clk)
rate = rate / apb_div;
}
break;
+   case BCLK_SDCLK:
+   {
+   ulong apb_div = 4 + 4 * ((readl(>scu->clk_sel1)
+ & SCU_SDCLK_DIV_MASK)
+>> SCU_SDCLK_DIV_SHIFT);
+   rate = ast2500_get_hpll_rate(clkin,
+readl(>
+  scu->h_pll_param));
+   rate = rate / apb_div;
+   }
+   break;
case PCLK_UART1:
rate = ast2500_get_uart_clk_rate(priv->scu, 1);
break;
@@ -436,6 +447,22 @@ static int ast2500_clk_enable(struct clk *clk)
struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);

switch (clk->id) {
+   case BCLK_SDCLK:
+   if (readl(>scu->clk_stop_ctrl1) & SCU_CLKSTOP_SDCLK) {
+   ast_scu_unlock(priv->scu);
+
+   setbits_le32(>scu->sysr

[U-Boot] [PATCH v2 2/4] mmc: Add Aspeed SD controller driver

2019-08-13 Thread Eddie James
Add support for the Aspeed SD host controller engine.

Signed-off-by: Eddie James 
---
 drivers/mmc/Kconfig| 11 +++
 drivers/mmc/Makefile   |  1 +
 drivers/mmc/aspeed_sdhci.c | 78 ++
 3 files changed, 90 insertions(+)
 create mode 100644 drivers/mmc/aspeed_sdhci.c

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index c6812f6..536f66a 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -421,6 +421,17 @@ config SPL_MMC_SDHCI_ADMA
  This enables support for the ADMA (Advanced DMA) defined
  in the SD Host Controller Standard Specification Version 3.00 in SPL.
 
+config MMC_SDHCI_ASPEED
+   bool "Aspeed SDHCI controller"
+   depends on ARCH_ASPEED
+   depends on DM_MMC
+   depends on MMC_SDHCI
+   help
+ Enables support for the Aspeed SDHCI 2.0 controller present on Aspeed
+ SoCs. This device is compatible with SD 3.0 and/or MMC 4.3
+ specifications. On the AST2600, the device is also compatible with
+ MMC 5.1 and eMMC 3.0.
+
 config MMC_SDHCI_ATMEL
bool "Atmel SDHCI controller support"
depends on ARCH_AT91
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 6cc018b..5594195 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_JZ47XX_MMC) += jz_mmc.o
 
 # SDHCI
 obj-$(CONFIG_MMC_SDHCI)+= sdhci.o
+obj-$(CONFIG_MMC_SDHCI_ASPEED) += aspeed_sdhci.o
 obj-$(CONFIG_MMC_SDHCI_ATMEL)  += atmel_sdhci.o
 obj-$(CONFIG_MMC_SDHCI_BCM2835)+= bcm2835_sdhci.o
 obj-$(CONFIG_MMC_SDHCI_BCMSTB) += bcmstb_sdhci.o
diff --git a/drivers/mmc/aspeed_sdhci.c b/drivers/mmc/aspeed_sdhci.c
new file mode 100644
index 000..c292c42
--- /dev/null
+++ b/drivers/mmc/aspeed_sdhci.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 IBM Corp.
+ * Eddie James 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct aspeed_sdhci_plat {
+   struct mmc_config cfg;
+   struct mmc mmc;
+};
+
+static int aspeed_sdhci_probe(struct udevice *dev)
+{
+   struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+   struct aspeed_sdhci_plat *plat = dev_get_platdata(dev);
+   struct sdhci_host *host = dev_get_priv(dev);
+   u32 max_clk;
+   struct clk clk;
+   int ret;
+
+   ret = clk_get_by_index(dev, 0, );
+   if (ret)
+   return ret;
+
+   ret = clk_enable();
+   if (ret)
+   return ret;
+
+   host->name = dev->name;
+   host->ioaddr = (void *)devfdt_get_addr(dev);
+
+   max_clk = clk_get_rate();
+   if (!max_clk)
+   return -EINVAL;
+
+   host->max_clk = max_clk;
+   host->mmc = >mmc;
+   host->mmc->dev = dev;
+   host->mmc->priv = host;
+   upriv->mmc = host->mmc;
+
+   ret = sdhci_setup_cfg(>cfg, host, 0, 0);
+   if (ret)
+   return ret;
+
+   return sdhci_probe(dev);
+}
+
+static int aspeed_sdhci_bind(struct udevice *dev)
+{
+   struct aspeed_sdhci_plat *plat = dev_get_platdata(dev);
+
+   return sdhci_bind(dev, >mmc, >cfg);
+}
+
+static const struct udevice_id aspeed_sdhci_ids[] = {
+   { .compatible = "aspeed,ast2400-sdhci" },
+   { .compatible = "aspeed,ast2500-sdhci" },
+   { .compatible = "aspeed,ast2600-sdhci" },
+   { }
+};
+
+U_BOOT_DRIVER(aspeed_sdhci_drv) = {
+   .name   = "aspeed_sdhci",
+   .id = UCLASS_MMC,
+   .of_match   = aspeed_sdhci_ids,
+   .ops= _ops,
+   .bind   = aspeed_sdhci_bind,
+   .probe  = aspeed_sdhci_probe,
+   .priv_auto_alloc_size = sizeof(struct sdhci_host),
+   .platdata_auto_alloc_size = sizeof(struct aspeed_sdhci_plat),
+};
-- 
1.8.3.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 0/4] ARM: aspeed: Add SD host controller driver

2019-08-13 Thread Eddie James
This series adds support for the SD host controller on Aspeed ast2XXX SocS.
It also enables MMC and the SD controller on the ast2500 EVB.

Changes since v1:
 - split the patch up
 - Add defconfig and dts changes

Eddie James (4):
  clk: aspeed: Add support for SD clock
  mmc: Add Aspeed SD controller driver
  aspeed: Support SD controller on the ast2500 board
  ARM: dts: ast2500: Add SDHCI nodes

 arch/arm/dts/ast2500-evb.dts   | 14 +
 arch/arm/dts/ast2500-u-boot.dtsi   | 16 ++
 arch/arm/include/asm/arch-aspeed/scu_ast2500.h |  3 +
 arch/arm/include/asm/gpio.h|  3 +-
 arch/arm/mach-aspeed/ast2500-board.c   |  3 +
 configs/evb-ast2500_defconfig  |  6 ++
 drivers/clk/aspeed/clk_ast2500.c   | 27 +
 drivers/mmc/Kconfig| 11 
 drivers/mmc/Makefile   |  1 +
 drivers/mmc/aspeed_sdhci.c | 78 ++
 drivers/pinctrl/aspeed/pinctrl_ast2500.c   |  2 +
 11 files changed, 163 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mmc/aspeed_sdhci.c

-- 
1.8.3.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 1/4] clk: aspeed: Add support for SD clock

2019-08-13 Thread Eddie James
Add code to enable the SD clock on the ast2500 SoC.

Signed-off-by: Eddie James 
---
 arch/arm/include/asm/arch-aspeed/scu_ast2500.h |  3 +++
 drivers/clk/aspeed/clk_ast2500.c   | 27 ++
 drivers/pinctrl/aspeed/pinctrl_ast2500.c   |  2 ++
 3 files changed, 32 insertions(+)

diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h 
b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
index 4988ced..8db4901 100644
--- a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
+++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
@@ -22,6 +22,8 @@
 #define SCU_MPLL_POST_MASK (0x3f << SCU_MPLL_POST_SHIFT)
 #define SCU_PCLK_DIV_SHIFT 23
 #define SCU_PCLK_DIV_MASK  (7 << SCU_PCLK_DIV_SHIFT)
+#define SCU_SDCLK_DIV_SHIFT12
+#define SCU_SDCLK_DIV_MASK (7 << SCU_SDCLK_DIV_SHIFT)
 #define SCU_HPLL_DENUM_SHIFT   0
 #define SCU_HPLL_DENUM_MASK0x1f
 #define SCU_HPLL_NUM_SHIFT 5
@@ -107,6 +109,7 @@
 
 #define SCU_CLKSTOP_MAC1   (1 << 20)
 #define SCU_CLKSTOP_MAC2   (1 << 21)
+#define SCU_CLKSTOP_SDCLK  (1 << 27)
 
 #define SCU_D2PLL_EXT1_OFF (1 << 0)
 #define SCU_D2PLL_EXT1_BYPASS  (1 << 1)
diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
index dbee13a..9249cf9 100644
--- a/drivers/clk/aspeed/clk_ast2500.c
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -143,6 +143,17 @@ static ulong ast2500_clk_get_rate(struct clk *clk)
rate = rate / apb_div;
}
break;
+   case BCLK_SDCLK:
+   {
+   ulong apb_div = 4 + 4 * ((readl(>scu->clk_sel1)
+ & SCU_SDCLK_DIV_MASK)
+>> SCU_SDCLK_DIV_SHIFT);
+   rate = ast2500_get_hpll_rate(clkin,
+readl(>
+  scu->h_pll_param));
+   rate = rate / apb_div;
+   }
+   break;
case PCLK_UART1:
rate = ast2500_get_uart_clk_rate(priv->scu, 1);
break;
@@ -436,6 +447,22 @@ static int ast2500_clk_enable(struct clk *clk)
struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
 
switch (clk->id) {
+   case BCLK_SDCLK:
+   if (readl(>scu->clk_stop_ctrl1) & SCU_CLKSTOP_SDCLK) {
+   ast_scu_unlock(priv->scu);
+
+   setbits_le32(>scu->sysreset_ctrl1,
+SCU_SYSRESET_SDIO);
+   udelay(100);
+   clrbits_le32(>scu->clk_stop_ctrl1,
+SCU_CLKSTOP_SDCLK);
+   mdelay(10);
+   clrbits_le32(>scu->sysreset_ctrl1,
+SCU_SYSRESET_SDIO);
+
+   ast_scu_lock(priv->scu);
+   }
+   break;
/*
 * For MAC clocks the clock rate is
 * configured based on whether RGMII or RMII mode has been selected
diff --git a/drivers/pinctrl/aspeed/pinctrl_ast2500.c 
b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
index ed333b9..a6e9c0d 100644
--- a/drivers/pinctrl/aspeed/pinctrl_ast2500.c
+++ b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
@@ -58,6 +58,8 @@ static const struct ast2500_group_config ast2500_groups[] = {
{ "MDIO1", 3, (1 << 31) | (1 << 30) },
{ "MAC2LINK", 1, (1 << 1) },
{ "MDIO2", 5, (1 << 2) },
+   { "SD1", 5, (1 << 0) },
+   { "SD2", 5, (1 << 1) },
 };
 
 static int ast2500_pinctrl_get_groups_count(struct udevice *dev)
-- 
1.8.3.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 4/4] ARM: dts: ast2500: Add SDHCI nodes

2019-08-13 Thread Eddie James
Add nodes for the Aspeed SD controllers with their necessary properties.

Signed-off-by: Eddie James 
---
 arch/arm/dts/ast2500-evb.dts | 14 ++
 arch/arm/dts/ast2500-u-boot.dtsi | 16 
 2 files changed, 30 insertions(+)

diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts
index ebf44fd..4796ed4 100644
--- a/arch/arm/dts/ast2500-evb.dts
+++ b/arch/arm/dts/ast2500-evb.dts
@@ -59,3 +59,17 @@
pinctrl-names = "default";
pinctrl-0 = <_mac2link_default _mdio2_default>;
 };
+
+ {
+   status = "okay";
+
+   pinctrl-names = "default";
+   pinctrl-0 = <_sd1_default>;
+};
+
+ {
+   status = "okay";
+
+   pinctrl-names = "default";
+   pinctrl-0 = <_sd2_default>;
+};
diff --git a/arch/arm/dts/ast2500-u-boot.dtsi b/arch/arm/dts/ast2500-u-boot.dtsi
index 7f80bad..8ac4215 100644
--- a/arch/arm/dts/ast2500-u-boot.dtsi
+++ b/arch/arm/dts/ast2500-u-boot.dtsi
@@ -34,6 +34,22 @@
 
apb {
u-boot,dm-pre-reloc;
+
+   sdhci0: sdhci@1e740100 {
+   compatible = "aspeed,ast2500-sdhci";
+   reg = <0x1e740100>;
+   #reset-cells = <1>;
+   clocks = < BCLK_SDCLK>;
+   resets = < AST_RESET_SDIO>;
+   };
+
+   sdhci1: sdhci@1e740200 {
+   compatible = "aspeed,ast2500-sdhci";
+   reg = <0x1e740200>;
+   #reset-cells = <1>;
+   clocks = < BCLK_SDCLK>;
+   resets = < AST_RESET_SDIO>;
+   };
};
 
};
-- 
1.8.3.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 3/4] aspeed: Support SD controller on the ast2500 board

2019-08-13 Thread Eddie James
Initialize the MMC subsystem on the ast2500 board. Compile MMC and the
Aspeed SD controller on the ast2500 EVB.

Signed-off-by: Eddie James 
---
 arch/arm/include/asm/gpio.h  | 3 ++-
 arch/arm/mach-aspeed/ast2500-board.c | 3 +++
 configs/evb-ast2500_defconfig| 6 ++
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h
index 370031f..38a5922 100644
--- a/arch/arm/include/asm/gpio.h
+++ b/arch/arm/include/asm/gpio.h
@@ -1,6 +1,7 @@
 #if !defined(CONFIG_ARCH_UNIPHIER) && !defined(CONFIG_ARCH_STI) && \
!defined(CONFIG_ARCH_K3) && !defined(CONFIG_ARCH_BCM6858) && \
-   !defined(CONFIG_ARCH_BCM63158) && !defined(CONFIG_ARCH_ROCKCHIP)
+   !defined(CONFIG_ARCH_BCM63158) && !defined(CONFIG_ARCH_ROCKCHIP) && \
+   !defined(CONFIG_ARCH_ASPEED)
 #include 
 #endif
 #include 
diff --git a/arch/arm/mach-aspeed/ast2500-board.c 
b/arch/arm/mach-aspeed/ast2500-board.c
index e7edd54..52a4e05 100644
--- a/arch/arm/mach-aspeed/ast2500-board.c
+++ b/arch/arm/mach-aspeed/ast2500-board.c
@@ -4,6 +4,7 @@
  */
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -55,6 +56,8 @@ int board_init(void)
 {
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
 
+   mmc_initialize(gd->bd);
+
return 0;
 }
 
diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
index 59d41cb..bfa6b32 100644
--- a/configs/evb-ast2500_defconfig
+++ b/configs/evb-ast2500_defconfig
@@ -16,6 +16,7 @@ CONFIG_HUSH_PARSER=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
+CONFIG_CMD_MMC=y
 CONFIG_CMD_PING=y
 CONFIG_DEFAULT_DEVICE_TREE="ast2500-evb"
 CONFIG_NET_RANDOM_ETHADDR=y
@@ -36,3 +37,8 @@ CONFIG_SYS_NS16550=y
 CONFIG_SYSRESET=y
 CONFIG_TIMER=y
 CONFIG_WDT=y
+CONFIG_MMC=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ASPEED=y
+CONFIG_MMC_VERBOSE=y
-- 
1.8.3.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3 3/4] configs: AST2500 EVB: Enable SD controller

2019-08-15 Thread Eddie James
Enable the MMC subsystem and the Aspeed SD controller. Also enable the
use of the device tree for probing the controller.

Signed-off-by: Eddie James 
---
 configs/evb-ast2500_defconfig | 8 
 1 file changed, 8 insertions(+)

diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
index 59d41cb..b47ca5b 100644
--- a/configs/evb-ast2500_defconfig
+++ b/configs/evb-ast2500_defconfig
@@ -16,6 +16,7 @@ CONFIG_HUSH_PARSER=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
+CONFIG_CMD_MMC=y
 CONFIG_CMD_PING=y
 CONFIG_DEFAULT_DEVICE_TREE="ast2500-evb"
 CONFIG_NET_RANDOM_ETHADDR=y
@@ -36,3 +37,10 @@ CONFIG_SYS_NS16550=y
 CONFIG_SYSRESET=y
 CONFIG_TIMER=y
 CONFIG_WDT=y
+CONFIG_MMC=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ASPEED=y
+CONFIG_MMC_VERBOSE=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_EMBED=y
-- 
1.8.3.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3 0/4] ARM: Aspeed: Add SD host controller driver

2019-08-15 Thread Eddie James
This series adds support for the SD host controller on the Aspeed ast2xxx SocS.
It also enables MMC and the SD controller for the ast2500 EVB.

Changes since v2:
 - Remove mmc_initialize call in the ast2500 board init
 - Add OF_CONTROL to the ast2500 EVB configuration
 - Fix the clock-getting code in the driver probe function

Changes since v1:
 - Split the patch up
 - Add defconfig and devicetree changes

Eddie James (4):
  clk: aspeed: Add support for SD clock
  mmc: Add Aspeed SD controller driver
  configs: AST2500 EVB: Enable SD controller
  ARM: dts: ast2500: Add SDHCI nodes

 arch/arm/dts/ast2500-evb.dts   | 14 
 arch/arm/dts/ast2500-u-boot.dtsi   | 16 +
 arch/arm/include/asm/arch-aspeed/scu_ast2500.h |  3 +
 arch/arm/include/asm/gpio.h|  3 +-
 configs/evb-ast2500_defconfig  |  8 +++
 drivers/clk/aspeed/clk_ast2500.c   | 27 
 drivers/mmc/Kconfig| 11 
 drivers/mmc/Makefile   |  1 +
 drivers/mmc/aspeed_sdhci.c | 90 ++
 drivers/pinctrl/aspeed/pinctrl_ast2500.c   |  2 +
 10 files changed, 174 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mmc/aspeed_sdhci.c

-- 
1.8.3.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3 1/4] clk: aspeed: Add support for SD clock

2019-08-15 Thread Eddie James
Add code to enable the SD clock on the ast2500 SoC.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Eddie James 
---
 arch/arm/include/asm/arch-aspeed/scu_ast2500.h |  3 +++
 drivers/clk/aspeed/clk_ast2500.c   | 27 ++
 drivers/pinctrl/aspeed/pinctrl_ast2500.c   |  2 ++
 3 files changed, 32 insertions(+)

diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h 
b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
index 4988ced..8db4901 100644
--- a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
+++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
@@ -22,6 +22,8 @@
 #define SCU_MPLL_POST_MASK (0x3f << SCU_MPLL_POST_SHIFT)
 #define SCU_PCLK_DIV_SHIFT 23
 #define SCU_PCLK_DIV_MASK  (7 << SCU_PCLK_DIV_SHIFT)
+#define SCU_SDCLK_DIV_SHIFT12
+#define SCU_SDCLK_DIV_MASK (7 << SCU_SDCLK_DIV_SHIFT)
 #define SCU_HPLL_DENUM_SHIFT   0
 #define SCU_HPLL_DENUM_MASK0x1f
 #define SCU_HPLL_NUM_SHIFT 5
@@ -107,6 +109,7 @@
 
 #define SCU_CLKSTOP_MAC1   (1 << 20)
 #define SCU_CLKSTOP_MAC2   (1 << 21)
+#define SCU_CLKSTOP_SDCLK  (1 << 27)
 
 #define SCU_D2PLL_EXT1_OFF (1 << 0)
 #define SCU_D2PLL_EXT1_BYPASS  (1 << 1)
diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
index dbee13a..9249cf9 100644
--- a/drivers/clk/aspeed/clk_ast2500.c
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -143,6 +143,17 @@ static ulong ast2500_clk_get_rate(struct clk *clk)
rate = rate / apb_div;
}
break;
+   case BCLK_SDCLK:
+   {
+   ulong apb_div = 4 + 4 * ((readl(>scu->clk_sel1)
+ & SCU_SDCLK_DIV_MASK)
+>> SCU_SDCLK_DIV_SHIFT);
+   rate = ast2500_get_hpll_rate(clkin,
+readl(>
+  scu->h_pll_param));
+   rate = rate / apb_div;
+   }
+   break;
case PCLK_UART1:
rate = ast2500_get_uart_clk_rate(priv->scu, 1);
break;
@@ -436,6 +447,22 @@ static int ast2500_clk_enable(struct clk *clk)
struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
 
switch (clk->id) {
+   case BCLK_SDCLK:
+   if (readl(>scu->clk_stop_ctrl1) & SCU_CLKSTOP_SDCLK) {
+   ast_scu_unlock(priv->scu);
+
+   setbits_le32(>scu->sysreset_ctrl1,
+SCU_SYSRESET_SDIO);
+   udelay(100);
+   clrbits_le32(>scu->clk_stop_ctrl1,
+SCU_CLKSTOP_SDCLK);
+   mdelay(10);
+   clrbits_le32(>scu->sysreset_ctrl1,
+SCU_SYSRESET_SDIO);
+
+   ast_scu_lock(priv->scu);
+   }
+   break;
/*
 * For MAC clocks the clock rate is
 * configured based on whether RGMII or RMII mode has been selected
diff --git a/drivers/pinctrl/aspeed/pinctrl_ast2500.c 
b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
index ed333b9..a6e9c0d 100644
--- a/drivers/pinctrl/aspeed/pinctrl_ast2500.c
+++ b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
@@ -58,6 +58,8 @@ static const struct ast2500_group_config ast2500_groups[] = {
{ "MDIO1", 3, (1 << 31) | (1 << 30) },
{ "MAC2LINK", 1, (1 << 1) },
{ "MDIO2", 5, (1 << 2) },
+   { "SD1", 5, (1 << 0) },
+   { "SD2", 5, (1 << 1) },
 };
 
 static int ast2500_pinctrl_get_groups_count(struct udevice *dev)
-- 
1.8.3.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v2 2/4] mmc: Add Aspeed SD controller driver

2019-08-15 Thread Eddie James


On 8/14/19 10:18 AM, Cédric Le Goater wrote:

On 13/08/2019 21:31, Eddie James wrote:

Add support for the Aspeed SD host controller engine.

It looks correct and simple enough. Some comments below.


Signed-off-by: Eddie James 
---
  drivers/mmc/Kconfig| 11 +++
  drivers/mmc/Makefile   |  1 +
  drivers/mmc/aspeed_sdhci.c | 78 ++
  3 files changed, 90 insertions(+)
  create mode 100644 drivers/mmc/aspeed_sdhci.c

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index c6812f6..536f66a 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -421,6 +421,17 @@ config SPL_MMC_SDHCI_ADMA
  This enables support for the ADMA (Advanced DMA) defined
  in the SD Host Controller Standard Specification Version 3.00 in SPL.
  
+config MMC_SDHCI_ASPEED

+   bool "Aspeed SDHCI controller"
+   depends on ARCH_ASPEED
+   depends on DM_MMC
+   depends on MMC_SDHCI
+   help
+ Enables support for the Aspeed SDHCI 2.0 controller present on Aspeed
+ SoCs. This device is compatible with SD 3.0 and/or MMC 4.3
+ specifications. On the AST2600, the device is also compatible with
+ MMC 5.1 and eMMC 3.0.
+
  config MMC_SDHCI_ATMEL
bool "Atmel SDHCI controller support"
depends on ARCH_AT91
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 6cc018b..5594195 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_JZ47XX_MMC) += jz_mmc.o
  
  # SDHCI

  obj-$(CONFIG_MMC_SDHCI)   += sdhci.o
+obj-$(CONFIG_MMC_SDHCI_ASPEED) += aspeed_sdhci.o
  obj-$(CONFIG_MMC_SDHCI_ATMEL) += atmel_sdhci.o
  obj-$(CONFIG_MMC_SDHCI_BCM2835)   += bcm2835_sdhci.o
  obj-$(CONFIG_MMC_SDHCI_BCMSTB)+= bcmstb_sdhci.o
diff --git a/drivers/mmc/aspeed_sdhci.c b/drivers/mmc/aspeed_sdhci.c
new file mode 100644
index 000..c292c42
--- /dev/null
+++ b/drivers/mmc/aspeed_sdhci.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 IBM Corp.
+ * Eddie James 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct aspeed_sdhci_plat {
+   struct mmc_config cfg;
+   struct mmc mmc;
+};
+
+static int aspeed_sdhci_probe(struct udevice *dev)
+{
+   struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+   struct aspeed_sdhci_plat *plat = dev_get_platdata(dev);
+   struct sdhci_host *host = dev_get_priv(dev);
+   u32 max_clk;
+   struct clk clk;
+   int ret;
+
+   ret = clk_get_by_index(dev, 0, );
+   if (ret)
+   return ret;
+
+   ret = clk_enable();
+   if (ret)
+   return ret;

Don't we need to release the clock below in case of error ?



Yes.



+   host->name = dev->name;
+   host->ioaddr = (void *)devfdt_get_addr(dev);
+
+   max_clk = clk_get_rate();
+   if (!max_clk)

may be use IS_ERR_VALUE(max_clk) and return max_clk



Yep, good idea.


Thanks for the quick review!

Eddie





+   return -EINVAL;
+
+   host->max_clk = max_clk;
+   host->mmc = >mmc;
+   host->mmc->dev = dev;
+   host->mmc->priv = host;
+   upriv->mmc = host->mmc;
+
+   ret = sdhci_setup_cfg(>cfg, host, 0, 0);
+   if (ret)
+   return ret;
+
+   return sdhci_probe(dev);
+}
+
+static int aspeed_sdhci_bind(struct udevice *dev)
+{
+   struct aspeed_sdhci_plat *plat = dev_get_platdata(dev);
+
+   return sdhci_bind(dev, >mmc, >cfg);
+}
+
+static const struct udevice_id aspeed_sdhci_ids[] = {
+   { .compatible = "aspeed,ast2400-sdhci" },
+   { .compatible = "aspeed,ast2500-sdhci" },
+   { .compatible = "aspeed,ast2600-sdhci" },
+   { }
+};
+
+U_BOOT_DRIVER(aspeed_sdhci_drv) = {
+   .name   = "aspeed_sdhci",
+   .id = UCLASS_MMC,
+   .of_match   = aspeed_sdhci_ids,
+   .ops= _ops,
+   .bind   = aspeed_sdhci_bind,
+   .probe  = aspeed_sdhci_probe,
+   .priv_auto_alloc_size = sizeof(struct sdhci_host),
+   .platdata_auto_alloc_size = sizeof(struct aspeed_sdhci_plat),
+};


___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v2 3/4] aspeed: Support SD controller on the ast2500 board

2019-08-15 Thread Eddie James


On 8/14/19 10:23 AM, Cédric Le Goater wrote:

On 13/08/2019 21:31, Eddie James wrote:

Initialize the MMC subsystem on the ast2500 board. Compile MMC and the
Aspeed SD controller on the ast2500 EVB.

Signed-off-by: Eddie James 
---
  arch/arm/include/asm/gpio.h  | 3 ++-
  arch/arm/mach-aspeed/ast2500-board.c | 3 +++
  configs/evb-ast2500_defconfig| 6 ++
  3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h
index 370031f..38a5922 100644
--- a/arch/arm/include/asm/gpio.h
+++ b/arch/arm/include/asm/gpio.h
@@ -1,6 +1,7 @@
  #if !defined(CONFIG_ARCH_UNIPHIER) && !defined(CONFIG_ARCH_STI) && \
!defined(CONFIG_ARCH_K3) && !defined(CONFIG_ARCH_BCM6858) && \
-   !defined(CONFIG_ARCH_BCM63158) && !defined(CONFIG_ARCH_ROCKCHIP)
+   !defined(CONFIG_ARCH_BCM63158) && !defined(CONFIG_ARCH_ROCKCHIP) && \
+   !defined(CONFIG_ARCH_ASPEED)
  #include 
  #endif
  #include 
diff --git a/arch/arm/mach-aspeed/ast2500-board.c 
b/arch/arm/mach-aspeed/ast2500-board.c
index e7edd54..52a4e05 100644
--- a/arch/arm/mach-aspeed/ast2500-board.c
+++ b/arch/arm/mach-aspeed/ast2500-board.c
@@ -4,6 +4,7 @@
   */
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -55,6 +56,8 @@ int board_init(void)
  {
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
  
+	mmc_initialize(gd->bd);

+

isn't that called automatically by board_init_r() already ?



You are correct, I will drop this.

Thanks,

Eddie




C.


return 0;
  }
  
diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig

index 59d41cb..bfa6b32 100644
--- a/configs/evb-ast2500_defconfig
+++ b/configs/evb-ast2500_defconfig
@@ -16,6 +16,7 @@ CONFIG_HUSH_PARSER=y
  CONFIG_CMD_I2C=y
  CONFIG_CMD_DHCP=y
  CONFIG_CMD_MII=y
+CONFIG_CMD_MMC=y
  CONFIG_CMD_PING=y
  CONFIG_DEFAULT_DEVICE_TREE="ast2500-evb"
  CONFIG_NET_RANDOM_ETHADDR=y
@@ -36,3 +37,8 @@ CONFIG_SYS_NS16550=y
  CONFIG_SYSRESET=y
  CONFIG_TIMER=y
  CONFIG_WDT=y
+CONFIG_MMC=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ASPEED=y
+CONFIG_MMC_VERBOSE=y


___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3 4/4] ARM: dts: ast2500: Add SDHCI nodes

2019-08-15 Thread Eddie James
Add nodes for the Aspeed SD controllers with their necessary properties.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Eddie James 
---
 arch/arm/dts/ast2500-evb.dts | 14 ++
 arch/arm/dts/ast2500-u-boot.dtsi | 16 
 2 files changed, 30 insertions(+)

diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts
index ebf44fd..4796ed4 100644
--- a/arch/arm/dts/ast2500-evb.dts
+++ b/arch/arm/dts/ast2500-evb.dts
@@ -59,3 +59,17 @@
pinctrl-names = "default";
pinctrl-0 = <_mac2link_default _mdio2_default>;
 };
+
+ {
+   status = "okay";
+
+   pinctrl-names = "default";
+   pinctrl-0 = <_sd1_default>;
+};
+
+ {
+   status = "okay";
+
+   pinctrl-names = "default";
+   pinctrl-0 = <_sd2_default>;
+};
diff --git a/arch/arm/dts/ast2500-u-boot.dtsi b/arch/arm/dts/ast2500-u-boot.dtsi
index 7f80bad..8ac4215 100644
--- a/arch/arm/dts/ast2500-u-boot.dtsi
+++ b/arch/arm/dts/ast2500-u-boot.dtsi
@@ -34,6 +34,22 @@
 
apb {
u-boot,dm-pre-reloc;
+
+   sdhci0: sdhci@1e740100 {
+   compatible = "aspeed,ast2500-sdhci";
+   reg = <0x1e740100>;
+   #reset-cells = <1>;
+   clocks = < BCLK_SDCLK>;
+   resets = < AST_RESET_SDIO>;
+   };
+
+   sdhci1: sdhci@1e740200 {
+   compatible = "aspeed,ast2500-sdhci";
+   reg = <0x1e740200>;
+   #reset-cells = <1>;
+   clocks = < BCLK_SDCLK>;
+   resets = < AST_RESET_SDIO>;
+   };
};
 
};
-- 
1.8.3.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v3 2/4] mmc: Add Aspeed SD controller driver

2019-08-15 Thread Eddie James
Add support for the Aspeed SD host controller engine.

Signed-off-by: Eddie James 
---
 arch/arm/include/asm/gpio.h |  3 +-
 drivers/mmc/Kconfig | 11 ++
 drivers/mmc/Makefile|  1 +
 drivers/mmc/aspeed_sdhci.c  | 90 +
 4 files changed, 104 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mmc/aspeed_sdhci.c

diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h
index 370031f..38a5922 100644
--- a/arch/arm/include/asm/gpio.h
+++ b/arch/arm/include/asm/gpio.h
@@ -1,6 +1,7 @@
 #if !defined(CONFIG_ARCH_UNIPHIER) && !defined(CONFIG_ARCH_STI) && \
!defined(CONFIG_ARCH_K3) && !defined(CONFIG_ARCH_BCM6858) && \
-   !defined(CONFIG_ARCH_BCM63158) && !defined(CONFIG_ARCH_ROCKCHIP)
+   !defined(CONFIG_ARCH_BCM63158) && !defined(CONFIG_ARCH_ROCKCHIP) && \
+   !defined(CONFIG_ARCH_ASPEED)
 #include 
 #endif
 #include 
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index c6812f6..536f66a 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -421,6 +421,17 @@ config SPL_MMC_SDHCI_ADMA
  This enables support for the ADMA (Advanced DMA) defined
  in the SD Host Controller Standard Specification Version 3.00 in SPL.
 
+config MMC_SDHCI_ASPEED
+   bool "Aspeed SDHCI controller"
+   depends on ARCH_ASPEED
+   depends on DM_MMC
+   depends on MMC_SDHCI
+   help
+ Enables support for the Aspeed SDHCI 2.0 controller present on Aspeed
+ SoCs. This device is compatible with SD 3.0 and/or MMC 4.3
+ specifications. On the AST2600, the device is also compatible with
+ MMC 5.1 and eMMC 3.0.
+
 config MMC_SDHCI_ATMEL
bool "Atmel SDHCI controller support"
depends on ARCH_AT91
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 6cc018b..5594195 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_JZ47XX_MMC) += jz_mmc.o
 
 # SDHCI
 obj-$(CONFIG_MMC_SDHCI)+= sdhci.o
+obj-$(CONFIG_MMC_SDHCI_ASPEED) += aspeed_sdhci.o
 obj-$(CONFIG_MMC_SDHCI_ATMEL)  += atmel_sdhci.o
 obj-$(CONFIG_MMC_SDHCI_BCM2835)+= bcm2835_sdhci.o
 obj-$(CONFIG_MMC_SDHCI_BCMSTB) += bcmstb_sdhci.o
diff --git a/drivers/mmc/aspeed_sdhci.c b/drivers/mmc/aspeed_sdhci.c
new file mode 100644
index 000..1321ec3
--- /dev/null
+++ b/drivers/mmc/aspeed_sdhci.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 IBM Corp.
+ * Eddie James 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct aspeed_sdhci_plat {
+   struct mmc_config cfg;
+   struct mmc mmc;
+};
+
+static int aspeed_sdhci_probe(struct udevice *dev)
+{
+   struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+   struct aspeed_sdhci_plat *plat = dev_get_platdata(dev);
+   struct sdhci_host *host = dev_get_priv(dev);
+   u32 max_clk;
+   struct clk clk;
+   int ret;
+
+   ret = clk_get_by_index(dev, 0, );
+   if (ret)
+   return ret;
+
+   ret = clk_enable();
+   if (ret)
+   goto free;
+
+   host->name = dev->name;
+   host->ioaddr = (void *)devfdt_get_addr(dev);
+
+   max_clk = clk_get_rate();
+   if (IS_ERR_VALUE(max_clk)) {
+   ret = max_clk;
+   goto err;
+   }
+
+   host->max_clk = max_clk;
+   host->mmc = >mmc;
+   host->mmc->dev = dev;
+   host->mmc->priv = host;
+   upriv->mmc = host->mmc;
+
+   ret = sdhci_setup_cfg(>cfg, host, 0, 0);
+   if (ret)
+   goto err;
+
+   ret = sdhci_probe(dev);
+   if (ret)
+   goto err;
+
+   return 0;
+
+err:
+   clk_disable();
+free:
+   clk_free();
+   return ret;
+}
+
+static int aspeed_sdhci_bind(struct udevice *dev)
+{
+   struct aspeed_sdhci_plat *plat = dev_get_platdata(dev);
+
+   return sdhci_bind(dev, >mmc, >cfg);
+}
+
+static const struct udevice_id aspeed_sdhci_ids[] = {
+   { .compatible = "aspeed,ast2400-sdhci" },
+   { .compatible = "aspeed,ast2500-sdhci" },
+   { .compatible = "aspeed,ast2600-sdhci" },
+   { }
+};
+
+U_BOOT_DRIVER(aspeed_sdhci_drv) = {
+   .name   = "aspeed_sdhci",
+   .id = UCLASS_MMC,
+   .of_match   = aspeed_sdhci_ids,
+   .ops= _ops,
+   .bind   = aspeed_sdhci_bind,
+   .probe  = aspeed_sdhci_probe,
+   .priv_auto_alloc_size = sizeof(struct sdhci_host),
+   .platdata_auto_alloc_size = sizeof(struct aspeed_sdhci_plat),
+};
-- 
1.8.3.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] ARM: aspeed: Add SD host controller driver

2019-08-12 Thread Eddie James
Add support for the Aspeed SD host controller engine. This involves
adding an MMC SDHCI driver and various additions to the clock and reset
drivers for Aspeed chips.

Signed-off-by: Eddie James 
---
 arch/arm/include/asm/arch-aspeed/scu_ast2500.h |  3 +
 arch/arm/include/asm/gpio.h|  3 +-
 arch/arm/mach-aspeed/ast2500-board.c   |  3 +
 drivers/clk/aspeed/clk_ast2500.c   | 27 +
 drivers/mmc/Kconfig| 11 
 drivers/mmc/Makefile   |  1 +
 drivers/mmc/aspeed_sdhci.c | 78 ++
 drivers/pinctrl/aspeed/pinctrl_ast2500.c   |  2 +
 8 files changed, 127 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mmc/aspeed_sdhci.c

diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h 
b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
index 4988ced..8db4901 100644
--- a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
+++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
@@ -22,6 +22,8 @@
 #define SCU_MPLL_POST_MASK (0x3f << SCU_MPLL_POST_SHIFT)
 #define SCU_PCLK_DIV_SHIFT 23
 #define SCU_PCLK_DIV_MASK  (7 << SCU_PCLK_DIV_SHIFT)
+#define SCU_SDCLK_DIV_SHIFT12
+#define SCU_SDCLK_DIV_MASK (7 << SCU_SDCLK_DIV_SHIFT)
 #define SCU_HPLL_DENUM_SHIFT   0
 #define SCU_HPLL_DENUM_MASK0x1f
 #define SCU_HPLL_NUM_SHIFT 5
@@ -107,6 +109,7 @@
 
 #define SCU_CLKSTOP_MAC1   (1 << 20)
 #define SCU_CLKSTOP_MAC2   (1 << 21)
+#define SCU_CLKSTOP_SDCLK  (1 << 27)
 
 #define SCU_D2PLL_EXT1_OFF (1 << 0)
 #define SCU_D2PLL_EXT1_BYPASS  (1 << 1)
diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h
index 370031f..38a5922 100644
--- a/arch/arm/include/asm/gpio.h
+++ b/arch/arm/include/asm/gpio.h
@@ -1,6 +1,7 @@
 #if !defined(CONFIG_ARCH_UNIPHIER) && !defined(CONFIG_ARCH_STI) && \
!defined(CONFIG_ARCH_K3) && !defined(CONFIG_ARCH_BCM6858) && \
-   !defined(CONFIG_ARCH_BCM63158) && !defined(CONFIG_ARCH_ROCKCHIP)
+   !defined(CONFIG_ARCH_BCM63158) && !defined(CONFIG_ARCH_ROCKCHIP) && \
+   !defined(CONFIG_ARCH_ASPEED)
 #include 
 #endif
 #include 
diff --git a/arch/arm/mach-aspeed/ast2500-board.c 
b/arch/arm/mach-aspeed/ast2500-board.c
index e7edd54..52a4e05 100644
--- a/arch/arm/mach-aspeed/ast2500-board.c
+++ b/arch/arm/mach-aspeed/ast2500-board.c
@@ -4,6 +4,7 @@
  */
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -55,6 +56,8 @@ int board_init(void)
 {
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
 
+   mmc_initialize(gd->bd);
+
return 0;
 }
 
diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
index dbee13a..9249cf9 100644
--- a/drivers/clk/aspeed/clk_ast2500.c
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -143,6 +143,17 @@ static ulong ast2500_clk_get_rate(struct clk *clk)
rate = rate / apb_div;
}
break;
+   case BCLK_SDCLK:
+   {
+   ulong apb_div = 4 + 4 * ((readl(>scu->clk_sel1)
+ & SCU_SDCLK_DIV_MASK)
+>> SCU_SDCLK_DIV_SHIFT);
+   rate = ast2500_get_hpll_rate(clkin,
+readl(>
+  scu->h_pll_param));
+   rate = rate / apb_div;
+   }
+   break;
case PCLK_UART1:
rate = ast2500_get_uart_clk_rate(priv->scu, 1);
break;
@@ -436,6 +447,22 @@ static int ast2500_clk_enable(struct clk *clk)
struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
 
switch (clk->id) {
+   case BCLK_SDCLK:
+   if (readl(>scu->clk_stop_ctrl1) & SCU_CLKSTOP_SDCLK) {
+   ast_scu_unlock(priv->scu);
+
+   setbits_le32(>scu->sysreset_ctrl1,
+SCU_SYSRESET_SDIO);
+   udelay(100);
+   clrbits_le32(>scu->clk_stop_ctrl1,
+SCU_CLKSTOP_SDCLK);
+   mdelay(10);
+   clrbits_le32(>scu->sysreset_ctrl1,
+SCU_SYSRESET_SDIO);
+
+   ast_scu_lock(priv->scu);
+   }
+   break;
/*
 * For MAC clocks the clock rate is
 * configured based on whether RGMII or RMII mode has been selected
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index c6812f6..536f66a 100644
--- a/drivers/mmc/Kconfig
+++ b/

[U-Boot] [PATCH v4 2/4] mmc: Add Aspeed SD controller driver

2019-08-27 Thread Eddie James
Add support for the Aspeed SD host controller engine.

Signed-off-by: Eddie James 
Reviewed-by: Cédric Le Goater 
---
Changes since v3:
 - Rebase on master

 arch/arm/include/asm/gpio.h |  3 +-
 drivers/mmc/Kconfig | 11 ++
 drivers/mmc/Makefile|  1 +
 drivers/mmc/aspeed_sdhci.c  | 90 +
 4 files changed, 104 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mmc/aspeed_sdhci.c

diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h
index b946105..6ff5f42 100644
--- a/arch/arm/include/asm/gpio.h
+++ b/arch/arm/include/asm/gpio.h
@@ -2,7 +2,8 @@
!defined(CONFIG_ARCH_K3) && !defined(CONFIG_ARCH_BCM6858) && \
!defined(CONFIG_ARCH_BCM63158) && !defined(CONFIG_ARCH_ROCKCHIP) && \
!defined(CONFIG_ARCH_LX2160A) && !defined(CONFIG_ARCH_LS1028A) && \
-   !defined(CONFIG_ARCH_LS2080A) && !defined(CONFIG_ARCH_LS1088A)
+   !defined(CONFIG_ARCH_LS2080A) && !defined(CONFIG_ARCH_LS1088A) && \
+   !defined(CONFIG_ARCH_ASPEED)
 #include 
 #endif
 #include 
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 0ccb1ea..8fb2bfa 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -421,6 +421,17 @@ config SPL_MMC_SDHCI_ADMA
  This enables support for the ADMA (Advanced DMA) defined
  in the SD Host Controller Standard Specification Version 3.00 in SPL.
 
+config MMC_SDHCI_ASPEED
+   bool "Aspeed SDHCI controller"
+   depends on ARCH_ASPEED
+   depends on DM_MMC
+   depends on MMC_SDHCI
+   help
+ Enables support for the Aspeed SDHCI 2.0 controller present on Aspeed
+ SoCs. This device is compatible with SD 3.0 and/or MMC 4.3
+ specifications. On the AST2600, the device is also compatible with
+ MMC 5.1 and eMMC 3.0.
+
 config MMC_SDHCI_ATMEL
bool "Atmel SDHCI controller support"
depends on ARCH_AT91
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 6cc018b..5594195 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_JZ47XX_MMC) += jz_mmc.o
 
 # SDHCI
 obj-$(CONFIG_MMC_SDHCI)+= sdhci.o
+obj-$(CONFIG_MMC_SDHCI_ASPEED) += aspeed_sdhci.o
 obj-$(CONFIG_MMC_SDHCI_ATMEL)  += atmel_sdhci.o
 obj-$(CONFIG_MMC_SDHCI_BCM2835)+= bcm2835_sdhci.o
 obj-$(CONFIG_MMC_SDHCI_BCMSTB) += bcmstb_sdhci.o
diff --git a/drivers/mmc/aspeed_sdhci.c b/drivers/mmc/aspeed_sdhci.c
new file mode 100644
index 000..1321ec3
--- /dev/null
+++ b/drivers/mmc/aspeed_sdhci.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 IBM Corp.
+ * Eddie James 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct aspeed_sdhci_plat {
+   struct mmc_config cfg;
+   struct mmc mmc;
+};
+
+static int aspeed_sdhci_probe(struct udevice *dev)
+{
+   struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+   struct aspeed_sdhci_plat *plat = dev_get_platdata(dev);
+   struct sdhci_host *host = dev_get_priv(dev);
+   u32 max_clk;
+   struct clk clk;
+   int ret;
+
+   ret = clk_get_by_index(dev, 0, );
+   if (ret)
+   return ret;
+
+   ret = clk_enable();
+   if (ret)
+   goto free;
+
+   host->name = dev->name;
+   host->ioaddr = (void *)devfdt_get_addr(dev);
+
+   max_clk = clk_get_rate();
+   if (IS_ERR_VALUE(max_clk)) {
+   ret = max_clk;
+   goto err;
+   }
+
+   host->max_clk = max_clk;
+   host->mmc = >mmc;
+   host->mmc->dev = dev;
+   host->mmc->priv = host;
+   upriv->mmc = host->mmc;
+
+   ret = sdhci_setup_cfg(>cfg, host, 0, 0);
+   if (ret)
+   goto err;
+
+   ret = sdhci_probe(dev);
+   if (ret)
+   goto err;
+
+   return 0;
+
+err:
+   clk_disable();
+free:
+   clk_free();
+   return ret;
+}
+
+static int aspeed_sdhci_bind(struct udevice *dev)
+{
+   struct aspeed_sdhci_plat *plat = dev_get_platdata(dev);
+
+   return sdhci_bind(dev, >mmc, >cfg);
+}
+
+static const struct udevice_id aspeed_sdhci_ids[] = {
+   { .compatible = "aspeed,ast2400-sdhci" },
+   { .compatible = "aspeed,ast2500-sdhci" },
+   { .compatible = "aspeed,ast2600-sdhci" },
+   { }
+};
+
+U_BOOT_DRIVER(aspeed_sdhci_drv) = {
+   .name   = "aspeed_sdhci",
+   .id = UCLASS_MMC,
+   .of_match   = aspeed_sdhci_ids,
+   .ops= _ops,
+   .bind   = aspeed_sdhci_bind,
+   .probe  = aspeed_sdhci_probe,
+   .priv_auto_alloc_size = sizeof(struct sdhci_host),
+   .platdata_auto_alloc_size = sizeof(struct aspeed_sdhci_plat),
+};
-- 
1.8.3.1

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v3 2/4] mmc: Add Aspeed SD controller driver

2019-08-27 Thread Eddie James


On 8/27/19 2:34 AM, Peng Fan wrote:

Hi Eddie,


Subject: [PATCH v3 2/4] mmc: Add Aspeed SD controller driver

This patch could not be applied to latest tree, could you please check?



Sorry I was a little behind master. I just sent this patch rebased.

Thanks,

Eddie




Thanks,
Peng.

Add support for the Aspeed SD host controller engine.

Signed-off-by: Eddie James 
---
  arch/arm/include/asm/gpio.h |  3 +-
  drivers/mmc/Kconfig | 11 ++
  drivers/mmc/Makefile|  1 +
  drivers/mmc/aspeed_sdhci.c  | 90
+
  4 files changed, 104 insertions(+), 1 deletion(-)  create mode 100644
drivers/mmc/aspeed_sdhci.c

diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h
index 370031f..38a5922 100644
--- a/arch/arm/include/asm/gpio.h
+++ b/arch/arm/include/asm/gpio.h
@@ -1,6 +1,7 @@
  #if !defined(CONFIG_ARCH_UNIPHIER) && !defined(CONFIG_ARCH_STI) &&
\
!defined(CONFIG_ARCH_K3) && !defined(CONFIG_ARCH_BCM6858) &&
\
-   !defined(CONFIG_ARCH_BCM63158)
&& !defined(CONFIG_ARCH_ROCKCHIP)
+   !defined(CONFIG_ARCH_BCM63158)
&& !defined(CONFIG_ARCH_ROCKCHIP) && \
+   !defined(CONFIG_ARCH_ASPEED)
  #include 
  #endif
  #include 
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index
c6812f6..536f66a 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -421,6 +421,17 @@ config SPL_MMC_SDHCI_ADMA
  This enables support for the ADMA (Advanced DMA) defined
  in the SD Host Controller Standard Specification Version 3.00 in SPL.

+config MMC_SDHCI_ASPEED
+   bool "Aspeed SDHCI controller"
+   depends on ARCH_ASPEED
+   depends on DM_MMC
+   depends on MMC_SDHCI
+   help
+ Enables support for the Aspeed SDHCI 2.0 controller present on
Aspeed
+ SoCs. This device is compatible with SD 3.0 and/or MMC 4.3
+ specifications. On the AST2600, the device is also compatible with
+ MMC 5.1 and eMMC 3.0.
+
  config MMC_SDHCI_ATMEL
bool "Atmel SDHCI controller support"
depends on ARCH_AT91
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index
6cc018b..5594195 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_JZ47XX_MMC) += jz_mmc.o

  # SDHCI
  obj-$(CONFIG_MMC_SDHCI)   += sdhci.o
+obj-$(CONFIG_MMC_SDHCI_ASPEED) += aspeed_sdhci.o
  obj-$(CONFIG_MMC_SDHCI_ATMEL) += atmel_sdhci.o
  obj-$(CONFIG_MMC_SDHCI_BCM2835)   += bcm2835_sdhci.o
  obj-$(CONFIG_MMC_SDHCI_BCMSTB)+= bcmstb_sdhci.o
diff --git a/drivers/mmc/aspeed_sdhci.c b/drivers/mmc/aspeed_sdhci.c new
file mode 100644 index 000..1321ec3
--- /dev/null
+++ b/drivers/mmc/aspeed_sdhci.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 IBM Corp.
+ * Eddie James 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct aspeed_sdhci_plat {
+   struct mmc_config cfg;
+   struct mmc mmc;
+};
+
+static int aspeed_sdhci_probe(struct udevice *dev) {
+   struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+   struct aspeed_sdhci_plat *plat = dev_get_platdata(dev);
+   struct sdhci_host *host = dev_get_priv(dev);
+   u32 max_clk;
+   struct clk clk;
+   int ret;
+
+   ret = clk_get_by_index(dev, 0, );
+   if (ret)
+   return ret;
+
+   ret = clk_enable();
+   if (ret)
+   goto free;
+
+   host->name = dev->name;
+   host->ioaddr = (void *)devfdt_get_addr(dev);
+
+   max_clk = clk_get_rate();
+   if (IS_ERR_VALUE(max_clk)) {
+   ret = max_clk;
+   goto err;
+   }
+
+   host->max_clk = max_clk;
+   host->mmc = >mmc;
+   host->mmc->dev = dev;
+   host->mmc->priv = host;
+   upriv->mmc = host->mmc;
+
+   ret = sdhci_setup_cfg(>cfg, host, 0, 0);
+   if (ret)
+   goto err;
+
+   ret = sdhci_probe(dev);
+   if (ret)
+   goto err;
+
+   return 0;
+
+err:
+   clk_disable();
+free:
+   clk_free();
+   return ret;
+}
+
+static int aspeed_sdhci_bind(struct udevice *dev) {
+   struct aspeed_sdhci_plat *plat = dev_get_platdata(dev);
+
+   return sdhci_bind(dev, >mmc, >cfg); }
+
+static const struct udevice_id aspeed_sdhci_ids[] = {
+   { .compatible = "aspeed,ast2400-sdhci" },
+   { .compatible = "aspeed,ast2500-sdhci" },
+   { .compatible = "aspeed,ast2600-sdhci" },
+   { }
+};
+
+U_BOOT_DRIVER(aspeed_sdhci_drv) = {
+   .name   = "aspeed_sdhci",
+   .id = UCLASS_MMC,
+   .of_match   = aspeed_sdhci_ids,
+   .ops= _ops,
+   .bind   = aspeed_sdhci_bind,
+   .probe  = aspeed_sdhci_probe,
+   .priv_auto_alloc_size = 

Re: [PATCH] gpio: Enable hogging support in SPL

2022-02-04 Thread Eddie James



On 2/4/22 09:24, Simon Glass wrote:

Hi Eddie,

On Thu, 3 Feb 2022 at 15:37, Eddie James  wrote:

Use the CONFIG macros to conditionally build the GPIO hogging support in
either the SPL or U-Boot, or both, depending on the configuration. Also
call the GPIO hog probe function in the common SPL board initialization
as an equivalent to adding it to the U-Boot init sequence functions.

Signed-off-by: Eddie James 
---
  common/spl/spl.c   |  7 +++
  drivers/gpio/Kconfig   | 10 ++
  drivers/gpio/gpio-uclass.c | 10 ++
  3 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/common/spl/spl.c b/common/spl/spl.c
index 884102bdea..f667908eec 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -20,6 +20,9 @@
  #include 
  #include 
  #include 
+#if defined(CONFIG_SPL_GPIO_HOG)

Can you drop this ifdef?



Sure.





+#include 
+#endif
  #include 
  #include 
  #include 
@@ -739,6 +742,10 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
 }
 }

+#if defined(CONFIG_SPL_GPIO_HOG)
+   gpio_hog_probe_all();
+#endif

if (CONFIG_IS_ENABLED(GPIO_HOG))



Ack.



...


+
  #if CONFIG_IS_ENABLED(BOARD_INIT)
 spl_board_init();
  #endif
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 305a2dc563..4da2bdc10d 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -57,6 +57,16 @@ config GPIO_HOG
   is a mechanism providing automatic GPIO request and config-
   uration as part of the gpio-controller's driver probe function.

+config SPL_GPIO_HOG
+   bool "Enable GPIO hog support in SPL"
+   depends on SPL_GPIO_SUPPORT

Should it depend on GPIO_HOG? I'm not sure, just a question



No, this way the gpio hog support can be configured for either SPL or 
U-Boot or both. They are the same option just in the different builds.



Thanks for the review,

Eddie






+   default n
+   help
+ Enable gpio hog support in SPL
+ The GPIO chip may contain GPIO hog definitions. GPIO hogging
+ is a mechanism providing automatic GPIO request and config-
+ uration as part of the gpio-controller's driver probe function.
+
  config DM_GPIO_LOOKUP_LABEL
 bool "Enable searching for gpio labelnames"
 depends on DM_GPIO
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 125ae53d61..bebba620c9 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -1432,9 +1432,6 @@ void devm_gpiod_put(struct udevice *dev, struct gpio_desc 
*desc)

  static int gpio_post_bind(struct udevice *dev)
  {
-   struct udevice *child;
-   ofnode node;
-
  #if defined(CONFIG_NEEDS_MANUAL_RELOC)
 struct dm_gpio_ops *ops = (struct dm_gpio_ops *)device_get_ops(dev);
 static int reloc_done;
@@ -1465,7 +1462,11 @@ static int gpio_post_bind(struct udevice *dev)
 }
  #endif

-   if (CONFIG_IS_ENABLED(OF_REAL) && IS_ENABLED(CONFIG_GPIO_HOG)) {
+#if CONFIG_IS_ENABLED(GPIO_HOG)
+   {
+   struct udevice *child;
+   ofnode node;
+
 dev_for_each_subnode(node, dev) {
 if (ofnode_read_bool(node, "gpio-hog")) {
 const char *name = ofnode_get_name(node);
@@ -1480,6 +1481,7 @@ static int gpio_post_bind(struct udevice *dev)
 }
 }
 }
+#endif
 return 0;
  }

--
2.27.0



[PATCH v3] gpio: Enable hogging support in SPL

2022-02-07 Thread Eddie James
Use the CONFIG macros to conditionally build the GPIO hogging support in
either the SPL or U-Boot, or both, depending on the configuration. Also
call the GPIO hog probe function in the common SPL board initialization
as an equivalent to adding it to the U-Boot init sequence functions.

Signed-off-by: Eddie James 
---
Changes since v2:
 - change #if to if() in gpio_post_bind

 Changes since v1:
 - remove #if guards around gpio include
 - change #if to if() in spl board_init_r

 common/spl/spl.c   |  4 
 drivers/gpio/Kconfig   | 10 ++
 drivers/gpio/gpio-uclass.c |  8 
 3 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/common/spl/spl.c b/common/spl/spl.c
index 884102bdea..36115e674d 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -739,6 +740,9 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
}
}
 
+   if (CONFIG_IS_ENABLED(GPIO_HOG))
+   gpio_hog_probe_all();
+
 #if CONFIG_IS_ENABLED(BOARD_INIT)
spl_board_init();
 #endif
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 305a2dc563..4da2bdc10d 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -57,6 +57,16 @@ config GPIO_HOG
  is a mechanism providing automatic GPIO request and config-
  uration as part of the gpio-controller's driver probe function.
 
+config SPL_GPIO_HOG
+   bool "Enable GPIO hog support in SPL"
+   depends on SPL_GPIO_SUPPORT
+   default n
+   help
+ Enable gpio hog support in SPL
+ The GPIO chip may contain GPIO hog definitions. GPIO hogging
+ is a mechanism providing automatic GPIO request and config-
+ uration as part of the gpio-controller's driver probe function.
+
 config DM_GPIO_LOOKUP_LABEL
bool "Enable searching for gpio labelnames"
depends on DM_GPIO
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 125ae53d61..9075c7235d 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -1432,9 +1432,6 @@ void devm_gpiod_put(struct udevice *dev, struct gpio_desc 
*desc)
 
 static int gpio_post_bind(struct udevice *dev)
 {
-   struct udevice *child;
-   ofnode node;
-
 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
struct dm_gpio_ops *ops = (struct dm_gpio_ops *)device_get_ops(dev);
static int reloc_done;
@@ -1465,7 +1462,10 @@ static int gpio_post_bind(struct udevice *dev)
}
 #endif
 
-   if (CONFIG_IS_ENABLED(OF_REAL) && IS_ENABLED(CONFIG_GPIO_HOG)) {
+   if (CONFIG_IS_ENABLED(GPIO_HOG)) {
+   struct udevice *child;
+   ofnode node;
+
dev_for_each_subnode(node, dev) {
if (ofnode_read_bool(node, "gpio-hog")) {
const char *name = ofnode_get_name(node);
-- 
2.27.0



[PATCH v2] gpio: Enable hogging support in SPL

2022-02-07 Thread Eddie James
Use the CONFIG macros to conditionally build the GPIO hogging support in
either the SPL or U-Boot, or both, depending on the configuration. Also
call the GPIO hog probe function in the common SPL board initialization
as an equivalent to adding it to the U-Boot init sequence functions.

Signed-off-by: Eddie James 
---
 common/spl/spl.c   |  4 
 drivers/gpio/Kconfig   | 10 ++
 drivers/gpio/gpio-uclass.c | 10 ++
 3 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/common/spl/spl.c b/common/spl/spl.c
index 884102bdea..36115e674d 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -739,6 +740,9 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
}
}
 
+   if (CONFIG_IS_ENABLED(GPIO_HOG))
+   gpio_hog_probe_all();
+
 #if CONFIG_IS_ENABLED(BOARD_INIT)
spl_board_init();
 #endif
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 305a2dc563..4da2bdc10d 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -57,6 +57,16 @@ config GPIO_HOG
  is a mechanism providing automatic GPIO request and config-
  uration as part of the gpio-controller's driver probe function.
 
+config SPL_GPIO_HOG
+   bool "Enable GPIO hog support in SPL"
+   depends on SPL_GPIO_SUPPORT
+   default n
+   help
+ Enable gpio hog support in SPL
+ The GPIO chip may contain GPIO hog definitions. GPIO hogging
+ is a mechanism providing automatic GPIO request and config-
+ uration as part of the gpio-controller's driver probe function.
+
 config DM_GPIO_LOOKUP_LABEL
bool "Enable searching for gpio labelnames"
depends on DM_GPIO
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 125ae53d61..bebba620c9 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -1432,9 +1432,6 @@ void devm_gpiod_put(struct udevice *dev, struct gpio_desc 
*desc)
 
 static int gpio_post_bind(struct udevice *dev)
 {
-   struct udevice *child;
-   ofnode node;
-
 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
struct dm_gpio_ops *ops = (struct dm_gpio_ops *)device_get_ops(dev);
static int reloc_done;
@@ -1465,7 +1462,11 @@ static int gpio_post_bind(struct udevice *dev)
}
 #endif
 
-   if (CONFIG_IS_ENABLED(OF_REAL) && IS_ENABLED(CONFIG_GPIO_HOG)) {
+#if CONFIG_IS_ENABLED(GPIO_HOG)
+   {
+   struct udevice *child;
+   ofnode node;
+
dev_for_each_subnode(node, dev) {
if (ofnode_read_bool(node, "gpio-hog")) {
const char *name = ofnode_get_name(node);
@@ -1480,6 +1481,7 @@ static int gpio_post_bind(struct udevice *dev)
}
}
}
+#endif
return 0;
 }
 
-- 
2.27.0



Re: [PATCH v14 4/8] bootm: Support boot measurement

2023-10-25 Thread Eddie James



On 10/25/23 07:41, Ilias Apalodimas wrote:

On Tue, 24 Oct 2023 at 18:44, Eddie James  wrote:

Add a configuration option to measure the boot through the bootm
function. Add the measurement state to the booti and bootz paths
as well.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
---
Changes since v8:
  - Added a configuration option to select to ignore any existing
event log. This would only be selected for systems that know
that U-Boot is the first stage bootloader. This is necessary
because the reserved memory region may persist through resets
and so U-Boot attempts to append to the previous boot's log.

Changes since v6:
  - Added comment for bootm_measure
  - Fixed line length in bootm_measure

  boot/Kconfig| 32 +
  boot/bootm.c| 74 +
  cmd/booti.c |  1 +
  cmd/bootm.c |  2 ++
  cmd/bootz.c |  1 +
  include/bootm.h | 11 
  include/image.h |  1 +
  7 files changed, 122 insertions(+)

diff --git a/boot/Kconfig b/boot/Kconfig
index a01e6cb8aa..abbc72f4cf 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -685,6 +685,38 @@ config LEGACY_IMAGE_FORMAT
   loaded. If a board needs the legacy image format support in this
   case, enable it here.

+config MEASURED_BOOT
+   bool "Measure boot images and configuration to TPM and event log"
+   depends on HASH && TPM_V2

I know Simon reviewed this already, but don't we need to add !EFI here?
UEFI already supports measurements via the TCG protocol implementation.
But since EFI is 'default y' nowadays anyone minds if I change the
help & bool messages during merge?
Something along the lines of
bool "Measure boot images and configuration to TPM and event log when
booting without EFI"



Oh right, yes, go ahead, that sounds good, thanks.

Eddie




[...]

Thanks
/Ilias


[PATCH v12 5/8] test: Add sandbox TPM boot measurement

2023-10-12 Thread Eddie James
Use the sandbox TPM driver to measure some boot images in a unit
test case.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
Acked-by: Ilias Apalodimas 
---
Changes since v5:
 - Only compile in the measurement u-boot command when
   CONFIG_MEASURED_BOOT is enabled.

 arch/sandbox/dts/sandbox.dtsi | 13 +++
 arch/sandbox/dts/test.dts | 13 +++
 configs/sandbox_defconfig |  1 +
 include/test/suites.h |  1 +
 test/boot/Makefile|  1 +
 test/boot/measurement.c   | 66 +++
 test/cmd_ut.c |  4 +++
 7 files changed, 99 insertions(+)
 create mode 100644 test/boot/measurement.c

diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index ff7e5584c5..241f397ba6 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -4,11 +4,23 @@
  * and sandbox64 builds.
  */
 
+#include 
 #include 
 
 #define USB_CLASS_HUB  9
 
 / {
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   event_log: tcg_event_log {
+   no-map;
+   reg = <(CFG_SYS_SDRAM_SIZE - 0x2000) 0x2000>;
+   };
+   };
+
binman {
};
 
@@ -342,6 +354,7 @@
 
tpm2 {
compatible = "sandbox,tpm2";
+   memory-region = <_log>;
};
 
triangle {
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 9a863ea732..bb2ddd9bf2 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -9,6 +9,7 @@
 
 /dts-v1/;
 
+#include 
 #include 
 #include 
 #include 
@@ -68,6 +69,17 @@
osd0 = "/osd";
};
 
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   event_log: tcg_event_log {
+   no-map;
+   reg = <(CFG_SYS_SDRAM_SIZE - 0x2000) 0x2000>;
+   };
+   };
+
binman: binman {
};
 
@@ -1422,6 +1434,7 @@
 
tpm2 {
compatible = "sandbox,tpm2";
+   memory-region = <_log>;
};
 
tpm {
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index d667cb9ae4..12c387a77e 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -349,3 +349,4 @@ CONFIG_UNIT_TEST=y
 CONFIG_UT_TIME=y
 CONFIG_UT_DM=y
 CONFIG_ARM_FFA_TRANSPORT=y
+CONFIG_MEASURED_BOOT=y
diff --git a/include/test/suites.h b/include/test/suites.h
index 1c7dc65966..48ed549c13 100644
--- a/include/test/suites.h
+++ b/include/test/suites.h
@@ -45,6 +45,7 @@ int do_ut_font(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[]);
 int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_loadm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_log(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]);
+int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc, char * const 
argv[]);
 int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc,
diff --git a/test/boot/Makefile b/test/boot/Makefile
index 52947580ae..068522cb9e 100644
--- a/test/boot/Makefile
+++ b/test/boot/Makefile
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_BOOTSTD) += bootdev.o bootstd_common.o bootflow.o bootmeth.o
 obj-$(CONFIG_FIT) += image.o
+obj-$(CONFIG_MEASURED_BOOT) += measurement.o
 
 obj-$(CONFIG_EXPO) += expo.o
 obj-$(CONFIG_CEDIT) += cedit.o
diff --git a/test/boot/measurement.c b/test/boot/measurement.c
new file mode 100644
index 00..9db2ed324c
--- /dev/null
+++ b/test/boot/measurement.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test for measured boot functions
+ *
+ * Copyright 2023 IBM Corp.
+ * Written by Eddie James 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MEASUREMENT_TEST(_name, _flags)\
+   UNIT_TEST(_name, _flags, measurement_test)
+
+static int measure(struct unit_test_state *uts)
+{
+   struct bootm_headers images;
+   const size_t size = 1024;
+   u8 *kernel;
+   u8 *initrd;
+   size_t i;
+
+   kernel = malloc(size);
+   initrd = malloc(size);
+
+   images.os.image_start = map_to_sysmem(kernel);
+   images.os.image_len = size;
+
+   images.rd_start = map_to_sysmem(initrd);
+   images.rd_end = images.rd_start + size;
+
+   images.ft_addr = malloc(size);
+   images.ft_len = size;
+
+   env_set("bootargs", "measurement testing");
+
+   for (i = 0; i < size; ++i) {
+   kernel[i] = 0xf0 | (i & 0xf);
+   in

[PATCH v12 0/8] tpm: Support boot measurements

2023-10-12 Thread Eddie James
This series adds support for measuring the boot images more generically
than the existing EFI support. Several EFI functions have been moved to
the TPM layer. The series includes optional measurement from the bootm 
command.
A new test case has been added for the bootm measurement to test the new
path, and the sandbox TPM2 driver has been updated to support this use
case.

Changes since v11:
 - Rebase on next. Sorry for the delay (been on leave).

Changes since v10:
 - Fix commit message on efi_loader change
 - Drop python test change
 - Squash armv7 fix from Ilias

Changes since v9:
 - Rebase and add Ilias' fixes (thanks!)

Changes since v8:
 - Fix a sandbox driver off-by-one error in checking the property type.
 - Fix log parsing again - any data corruption seen while replaying the
   event log was failing the entire measurement.
 - Added an option to ignore the existing log and a configuration option
   for systems to select that for the bootm measurement. This would only
   be selected for systems that know that U-Boot is the first stage
   bootloader. This is necessary because the reserved memory region may
   persist through resets and so U-Boot attempts to append to the
   previous boot's log.

Changes since v7:
 - Change name of tcg2_init_log and add more documentation
 - Add a check, when parsing the event log header, to ensure that the
   previous stage bootloader used all the active PCRs.
 - Change name of tcg2_log_find_end
 - Fix the greater than or equal to check to exit the log parsing
 - Make sure log_position is 0 if there is any error discovering the log
 - Return errors parsing the log if the data is corrupt so that we don't
   end up with half a log

Changes since v6:
 - Added comment for bootm_measure
 - Fixed line length in bootm_measure
 - Added Linaro copyright for all the EFI moved code
 - Changed tcg2_init_log (and by extension, tcg2_measurement_init) to
   copy any discovered event log to the user's log if passed in.

Changes since v5:
 - Re-ordered the patches to put the sandbox TPM driver patch second
 - Remove unused platform_get_eventlog in efi_tcg2.c
 - First look for tpm_event_log_* properties instead of linux,sml-*
 - Fix efi_tcg2.c compilation
 - Select SHA* configs
 - Remove the !SANDBOX dependency for EFI TCG2
 - Only compile in the measurement u-boot command when CONFIG_MEASURED_BOOT
   is enabled

Changes since v4:
 - Remove tcg2_measure_event function and check for NULL data in
   tcg2_measure_data
 - Use tpm_auto_startup
 - Fix efi_tcg2.c compilation for removing tcg2_pcr_read function
 - Change PCR indexes for initrd and dtb
 - Drop u8 casting in measurement test
 - Use bullets in documentation

Changes since v3:
 - Reordered headers
 - Refactored more of EFI code into common code
Removed digest_info structure and instead used the common alg_to_mask
  and alg_to_len
Improved event log parsing in common code to get it equivalent to EFI
  Common code now extends PCR if previous bootloader stage couldn't
  No need to allocate memory in the common code, so EFI copies the
  discovered buffer like it did before
Rename efi measure_event function

Changes since v2:
 - Add documentation.
 - Changed reserved memory address to the top of the RAM for sandbox dts.
 - Add measure state to booti and bootz.
 - Skip measurement for EFI images that should be measured

Changes since v1:
 - Refactor TPM layer functions to allow EFI system to use them, and
   remove duplicate EFI functions.
 - Add test case
 - Drop #ifdefs for bootm
 - Add devicetree measurement config option
 - Update sandbox TPM driver

Eddie James (6):
  tpm: Fix spelling for tpmu_ha union
  tpm: sandbox: Update for needed TPM2 capabilities
  tpm: Support boot measurements
  bootm: Support boot measurement
  test: Add sandbox TPM boot measurement
  doc: Add measured boot documentation

Ilias Apalodimas (2):
  efi_loader: fix EFI_ENTRY point on get_active_pcr_banks
  test: use a non system PCR for testing PCR extend

 arch/sandbox/dts/sandbox.dtsi  |  13 +
 arch/sandbox/dts/test.dts  |  13 +
 boot/Kconfig   |  32 ++
 boot/bootm.c   |  74 +++
 cmd/booti.c|   1 +
 cmd/bootm.c|   2 +
 cmd/bootz.c|   1 +
 configs/sandbox_defconfig  |   1 +
 doc/usage/index.rst|   1 +
 doc/usage/measured_boot.rst|  23 +
 drivers/tpm/tpm2_tis_sandbox.c | 100 ++--
 include/bootm.h|  11 +
 include/efi_tcg2.h |  44 --
 include/image.h|   1 +
 include/test/suites.h  |   1 +
 include/tpm-v2.h   | 263 ++-
 lib/Kconfig|   4 +
 lib/efi_loader/Kconfig |   2 -
 lib/efi_loader/efi_tcg2.c  | 823 -
 lib/tpm-v2.c   | 814 
 test/boot/Makefile |   1 +
 test/boot/measurement.c|  66 +++
 test/cmd_ut.c

[PATCH v12 3/8] tpm: Support boot measurements

2023-10-12 Thread Eddie James
Add TPM2 functions to support boot measurement. This includes
starting up the TPM, initializing/appending the event log, and
measuring the U-Boot version. Much of the code was used in the
EFI subsystem, so remove it there and use the common functions.

Signed-off-by: Eddie James 
---
Changes since v10:
 - Fix compile warning for armv7 (thanks Ilias)

Changes since v8:
 - Fix log parsing again - any data corruption seen while replaying the
   event log was failing the entire measurement.
 - Added an option to ignore the existing log. This should only be used
   for systems that know that U-Boot is the first stage bootloader. This
   is necessary because the reserved memory region may persist through
   resets and so U-Boot attempts to append to the previous boot's log.

Changes since v7:
 - Change name of tcg2_init_log and add more documentation
 - Add a check, when parsing the event log header, to ensure that the
   previous stage bootloader used all the active PCRs.
 - Change name of tcg2_log_find_end
 - Fix the greater than or equal to check to exit the log parsing
 - Make sure log_position is 0 if there is any error discovering the log
 - Return errors parsing the log if the data is corrupt so that we don't
   end up with half a log

Changes since v6:
 - Added Linaro copyright for all the EFI moved code
 - Changed tcg2_init_log (and by extension, tcg2_measurement_init) to
   copy any discovered event log to the user's log if passed in.

Changes since v5:
 - Remove unused platform_get_eventlog in efi_tcg2.c
 - First look for tpm_event_log_* properties instead of linux,sml-*
 - Fix efi_tcg2.c compilation
 - Select SHA* configs

Changes since v4:
 - Remove tcg2_measure_event function and check for NULL data in
   tcg2_measure_data
 - Use tpm_auto_startup
 - Fix efi_tcg2.c compilation for removing tcg2_pcr_read function

Changes since v3:
 - Reordered headers
 - Refactored more of EFI code into common code
Removed digest_info structure and instead used the common alg_to_mask
  and alg_to_len
Improved event log parsing in common code to get it equivalent to EFI
  Common code now extends PCR if previous bootloader stage couldn't
  No need to allocate memory in the common code, so EFI copies the
  discovered buffer like it did before
Rename efi measure_event function

Changes since v1:
 - Refactor TPM layer functions to allow EFI system to use them, and
   remove duplicate EFI functions

 include/efi_tcg2.h|  44 --
 include/tpm-v2.h  | 259 
 lib/Kconfig   |   4 +
 lib/efi_loader/efi_tcg2.c | 821 --
 lib/tpm-v2.c  | 814 +
 5 files changed, 1154 insertions(+), 788 deletions(-)

diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
index b1c3abd097..b21c5cb3dd 100644
--- a/include/efi_tcg2.h
+++ b/include/efi_tcg2.h
@@ -129,50 +129,6 @@ struct efi_tcg2_boot_service_capability {
 #define BOOT_SERVICE_CAPABILITY_MIN \
offsetof(struct efi_tcg2_boot_service_capability, number_of_pcr_banks)
 
-#define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03"
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2
-
-/**
- *  struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm information
- *
- *  @algorithm_id: algorithm defined in enum tpm2_algorithms
- *  @digest_size:  size of the algorithm
- */
-struct tcg_efi_spec_id_event_algorithm_size {
-   u16  algorithm_id;
-   u16  digest_size;
-} __packed;
-
-/**
- * struct TCG_EfiSpecIDEventStruct - content of the event log header
- *
- * @signature: signature, set to Spec ID Event03
- * @platform_class:class defined in TCG ACPI Specification
- * Client  Common Header.
- * @spec_version_minor:minor version
- * @spec_version_major:major version
- * @spec_version_errata:   major version
- * @uintn_size:size of the efi_uintn_t fields used in 
various
- * data structures used in this specification.
- * 0x01 indicates u32  and 0x02  indicates u64
- * @number_of_algorithms:  hashing algorithms used in this event log
- * @digest_sizes:  array of number_of_algorithms pairs
- * 1st member defines the algorithm id
- * 2nd member defines the algorithm size
- */
-struct tcg_efi_spec_id_event {
-   u8 signature[16];
-   u32 platform_class;
-   u8 spec_version_minor;
-   u8 spec_version_major;
-   u8 spec_errata;
-   u8 uintn_size;
-   u32 number_of_algorithms;
-   struct tcg_efi_spec_id_event_algorithm_size digest_sizes[];
-} __packed;
-
 /**
  * struct tdEFI_TCG2_FINAL_EVENTS_TABLE - log entries after Get

[PATCH v12 1/8] tpm: Fix spelling for tpmu_ha union

2023-10-12 Thread Eddie James
tmpu -> tpmu

Signed-off-by: Eddie James 
Reviewed-by: Ilias Apalodimas 
---
 include/tpm-v2.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 2b6980e441..6684033deb 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -169,7 +169,7 @@ struct tcg_pcr_event {
 /**
  * Definition of TPMU_HA Union
  */
-union tmpu_ha {
+union tpmu_ha {
u8 sha1[TPM2_SHA1_DIGEST_SIZE];
u8 sha256[TPM2_SHA256_DIGEST_SIZE];
u8 sm3_256[TPM2_SM3_256_DIGEST_SIZE];
@@ -185,7 +185,7 @@ union tmpu_ha {
  */
 struct tpmt_ha {
u16 hash_alg;
-   union tmpu_ha digest;
+   union tpmu_ha digest;
 } __packed;
 
 /**
-- 
2.39.3



[PATCH v12 6/8] doc: Add measured boot documentation

2023-10-12 Thread Eddie James
Briefly describe the feature and specify the requirements.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
---
 doc/usage/index.rst |  1 +
 doc/usage/measured_boot.rst | 23 +++
 2 files changed, 24 insertions(+)
 create mode 100644 doc/usage/measured_boot.rst

diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index fa702920fa..fb043a8923 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -14,6 +14,7 @@ Use U-Boot
partitions
cmdline
semihosting
+   measured_boot
 
 Shell commands
 --
diff --git a/doc/usage/measured_boot.rst b/doc/usage/measured_boot.rst
new file mode 100644
index 00..8357b1f480
--- /dev/null
+++ b/doc/usage/measured_boot.rst
@@ -0,0 +1,23 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Measured Boot
+=
+
+U-Boot can perform a measured boot, the process of hashing various components
+of the boot process, extending the results in the TPM and logging the
+component's measurement in memory for the operating system to consume.
+
+Requirements
+-
+
+* A hardware TPM 2.0 supported by the U-Boot drivers
+* CONFIG_TPM=y
+* CONFIG_MEASURED_BOOT=y
+* Device-tree configuration of the TPM device to specify the memory area
+  for event logging. The TPM device node must either contain a phandle to
+  a reserved memory region or "linux,sml-base" and "linux,sml-size"
+  indicating the address and size of the memory region. An example can be
+  found in arch/sandbox/dts/test.dts
+* The operating system must also be configured to use the memory regions
+  specified in the U-Boot device-tree in order to make use of the event
+  log.
-- 
2.39.3



[PATCH v12 7/8] efi_loader: fix EFI_ENTRY point on get_active_pcr_banks

2023-10-12 Thread Eddie James
From: Ilias Apalodimas 

efi_tcg2_get_active_pcr_banks doesn't immediately call the
EFI_ENTRY() wrapper once it enters the function. Move the call a
few lines above to cover the error cases properly as well.

Signed-off-by: Ilias Apalodimas 
---
 lib/efi_loader/efi_tcg2.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index 7ada536568..dae1b166c8 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -949,16 +949,16 @@ efi_tcg2_get_active_pcr_banks(struct efi_tcg2_protocol 
*this,
struct udevice *dev;
efi_status_t ret;
 
+   EFI_ENTRY("%p, %p", this, active_pcr_banks);
+
if (!this || !active_pcr_banks) {
ret = EFI_INVALID_PARAMETER;
goto out;
}
-
ret = tcg2_platform_get_tpm2();
if (ret != EFI_SUCCESS)
goto out;
 
-   EFI_ENTRY("%p, %p", this, active_pcr_banks);
ret = tcg2_get_active_pcr_banks(dev, active_pcr_banks);
 
 out:
-- 
2.39.3



[PATCH v12 8/8] test: use a non system PCR for testing PCR extend

2023-10-12 Thread Eddie James
From: Ilias Apalodimas 

We currently use PCR 0 for testing the PCR read/extend functionality in
our selftests.  How ever those PCRs are defined by the TCG spec for
platform use.  For example if the tests run *after* the efi subsystem
initialization, which extends PCRs 0 & 7 it will give a false positive.

So let's switch over to a PCR which is more suitable and is defined for
OS use.  It's worth noting that we are using PCR10 here, since PCR9 is
used internally by U-Boot if we choose to measure the loaded DTB

Reviewed-by: Simon Glass 
Signed-off-by: Ilias Apalodimas 
---
 test/py/tests/test_tpm2.py | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/test/py/tests/test_tpm2.py b/test/py/tests/test_tpm2.py
index c2579fa02c..47392b87a9 100644
--- a/test/py/tests/test_tpm2.py
+++ b/test/py/tests/test_tpm2.py
@@ -239,7 +239,7 @@ def test_tpm2_dam_parameters(u_boot_console):
 def test_tpm2_pcr_read(u_boot_console):
 """Execute a TPM2_PCR_Read command.
 
-Perform a PCR read of the 0th PCR. Must be zero.
+Perform a PCR read of the 10th PCR. Must be zero.
 """
 if is_sandbox(u_boot_console):
 tpm2_sandbox_init(u_boot_console)
@@ -247,7 +247,7 @@ def test_tpm2_pcr_read(u_boot_console):
 force_init(u_boot_console)
 ram = u_boot_utils.find_ram_base(u_boot_console)
 
-read_pcr = u_boot_console.run_command('tpm2 pcr_read 0 0x%x' % ram)
+read_pcr = u_boot_console.run_command('tpm2 pcr_read 10 0x%x' % ram)
 output = u_boot_console.run_command('echo $?')
 assert output.endswith('0')
 
@@ -257,7 +257,7 @@ def test_tpm2_pcr_read(u_boot_console):
 updates = int(re.findall(r'\d+', str)[0])
 
 # Check the output value
-assert 'PCR #0 content' in read_pcr
+assert 'PCR #10 content' in read_pcr
 assert '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' in read_pcr
 
 @pytest.mark.buildconfigspec('cmd_tpm_v2')
@@ -275,19 +275,19 @@ def test_tpm2_pcr_extend(u_boot_console):
 force_init(u_boot_console)
 ram = u_boot_utils.find_ram_base(u_boot_console)
 
-read_pcr = u_boot_console.run_command('tpm2 pcr_read 0 0x%x' % (ram + 
0x20))
+read_pcr = u_boot_console.run_command('tpm2 pcr_read 10 0x%x' % (ram + 
0x20))
 output = u_boot_console.run_command('echo $?')
 assert output.endswith('0')
 str = re.findall(r'\d+ known updates', read_pcr)[0]
 updates = int(re.findall(r'\d+', str)[0])
 
-u_boot_console.run_command('tpm2 pcr_extend 0 0x%x' % ram)
+u_boot_console.run_command('tpm2 pcr_extend 10 0x%x' % ram)
 output = u_boot_console.run_command('echo $?')
 assert output.endswith('0')
 
 # Read the value back into a different place so we can still use 'ram' as
 # our zero bytes
-read_pcr = u_boot_console.run_command('tpm2 pcr_read 0 0x%x' % (ram + 
0x20))
+read_pcr = u_boot_console.run_command('tpm2 pcr_read 10 0x%x' % (ram + 
0x20))
 output = u_boot_console.run_command('echo $?')
 assert output.endswith('0')
 assert 'f5 a5 fd 42 d1 6a 20 30 27 98 ef 6e d3 09 97 9b' in read_pcr
@@ -297,11 +297,11 @@ def test_tpm2_pcr_extend(u_boot_console):
 new_updates = int(re.findall(r'\d+', str)[0])
 assert (updates + 1) == new_updates
 
-u_boot_console.run_command('tpm2 pcr_extend 0 0x%x' % ram)
+u_boot_console.run_command('tpm2 pcr_extend 10 0x%x' % ram)
 output = u_boot_console.run_command('echo $?')
 assert output.endswith('0')
 
-read_pcr = u_boot_console.run_command('tpm2 pcr_read 0 0x%x' % (ram + 
0x20))
+read_pcr = u_boot_console.run_command('tpm2 pcr_read 10 0x%x' % (ram + 
0x20))
 output = u_boot_console.run_command('echo $?')
 assert output.endswith('0')
 assert '7a 05 01 f5 95 7b df 9c b3 a8 ff 49 66 f0 22 65' in read_pcr
-- 
2.39.3



[PATCH v12 2/8] tpm: sandbox: Update for needed TPM2 capabilities

2023-10-12 Thread Eddie James
The driver needs to support getting the PCRs in the capabilities
command. Fix various other things and support the max number
of PCRs for TPM2.
Remove the !SANDBOX dependency for EFI TCG2 as well.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
Acked-by: Ilias Apalodimas 
---
Changes since v8:
 - Use >= for checking the property against TPM2_PROPERTIES_OFFSET

Changes since v5:
 - Remove the !SANDBOX dependency for EFI TCG2

 drivers/tpm/tpm2_tis_sandbox.c | 100 -
 lib/efi_loader/Kconfig |   2 -
 2 files changed, 72 insertions(+), 30 deletions(-)

diff --git a/drivers/tpm/tpm2_tis_sandbox.c b/drivers/tpm/tpm2_tis_sandbox.c
index e4004cfcca..d15a28d9fc 100644
--- a/drivers/tpm/tpm2_tis_sandbox.c
+++ b/drivers/tpm/tpm2_tis_sandbox.c
@@ -22,11 +22,6 @@ enum tpm2_hierarchy {
TPM2_HIERARCHY_NB,
 };
 
-/* Subset of supported capabilities */
-enum tpm2_capability {
-   TPM_CAP_TPM_PROPERTIES = 0x6,
-};
-
 /* Subset of supported properties */
 #define TPM2_PROPERTIES_OFFSET 0x020E
 
@@ -38,7 +33,8 @@ enum tpm2_cap_tpm_property {
TPM2_PROPERTY_NB,
 };
 
-#define SANDBOX_TPM_PCR_NB 1
+#define SANDBOX_TPM_PCR_NB TPM2_MAX_PCRS
+#define SANDBOX_TPM_PCR_SELECT_MAX ((SANDBOX_TPM_PCR_NB + 7) / 8)
 
 /*
  * Information about our TPM emulation. This is preserved in the sandbox
@@ -433,7 +429,7 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const u8 
*sendbuf,
int i, j;
 
/* TPM2_GetProperty */
-   u32 capability, property, property_count;
+   u32 capability, property, property_count, val;
 
/* TPM2_PCR_Read/Extend variables */
int pcr_index = 0;
@@ -542,19 +538,32 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const 
u8 *sendbuf,
case TPM2_CC_GET_CAPABILITY:
capability = get_unaligned_be32(sent);
sent += sizeof(capability);
-   if (capability != TPM_CAP_TPM_PROPERTIES) {
-   printf("Sandbox TPM only support TPM_CAPABILITIES\n");
-   return TPM2_RC_HANDLE;
-   }
-
property = get_unaligned_be32(sent);
sent += sizeof(property);
-   property -= TPM2_PROPERTIES_OFFSET;
-
property_count = get_unaligned_be32(sent);
sent += sizeof(property_count);
-   if (!property_count ||
-   property + property_count > TPM2_PROPERTY_NB) {
+
+   switch (capability) {
+   case TPM2_CAP_PCRS:
+   break;
+   case TPM2_CAP_TPM_PROPERTIES:
+   if (!property_count) {
+   rc = TPM2_RC_HANDLE;
+   return sandbox_tpm2_fill_buf(recv, recv_len,
+tag, rc);
+   }
+
+   if (property >= TPM2_PROPERTIES_OFFSET &&
+   ((property - TPM2_PROPERTIES_OFFSET) +
+property_count > TPM2_PROPERTY_NB)) {
+   rc = TPM2_RC_HANDLE;
+   return sandbox_tpm2_fill_buf(recv, recv_len,
+tag, rc);
+   }
+   break;
+   default:
+   printf("Sandbox TPM2 only supports TPM2_CAP_PCRS or "
+  "TPM2_CAP_TPM_PROPERTIES\n");
rc = TPM2_RC_HANDLE;
return sandbox_tpm2_fill_buf(recv, recv_len, tag, rc);
}
@@ -578,18 +587,53 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const 
u8 *sendbuf,
put_unaligned_be32(capability, recv);
recv += sizeof(capability);
 
-   /* Give the number of properties that follow */
-   put_unaligned_be32(property_count, recv);
-   recv += sizeof(property_count);
-
-   /* Fill with the properties */
-   for (i = 0; i < property_count; i++) {
-   put_unaligned_be32(TPM2_PROPERTIES_OFFSET + property +
-  i, recv);
-   recv += sizeof(property);
-   put_unaligned_be32(tpm->properties[property + i],
-  recv);
-   recv += sizeof(property);
+   switch (capability) {
+   case TPM2_CAP_PCRS:
+   /* Give the number of algorithms supported - just 
SHA256 */
+   put_unaligned_be32(1, recv);
+   recv += sizeof(u32);
+
+   /* Give SHA256 algorithm */
+   put_unaligned_be16(TPM2_ALG_SHA256, recv);
+   recv += sizeof(u16);
+
+   /* Se

[PATCH v12 4/8] bootm: Support boot measurement

2023-10-12 Thread Eddie James
Add a configuration option to measure the boot through the bootm
function. Add the measurement state to the booti and bootz paths
as well.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
---
Changes since v8:
 - Added a configuration option to select to ignore any existing
   event log. This would only be selected for systems that know
   that U-Boot is the first stage bootloader. This is necessary
   because the reserved memory region may persist through resets
   and so U-Boot attempts to append to the previous boot's log.

Changes since v6:
 - Added comment for bootm_measure
 - Fixed line length in bootm_measure

 boot/Kconfig| 32 +
 boot/bootm.c| 74 +
 cmd/booti.c |  1 +
 cmd/bootm.c |  2 ++
 cmd/bootz.c |  1 +
 include/bootm.h | 11 
 include/image.h |  1 +
 7 files changed, 122 insertions(+)

diff --git a/boot/Kconfig b/boot/Kconfig
index a01e6cb8aa..abbc72f4cf 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -685,6 +685,38 @@ config LEGACY_IMAGE_FORMAT
  loaded. If a board needs the legacy image format support in this
  case, enable it here.
 
+config MEASURED_BOOT
+   bool "Measure boot images and configuration to TPM and event log"
+   depends on HASH && TPM_V2
+   help
+ This option enables measurement of the boot process. Measurement
+ involves creating cryptographic hashes of the binary images that
+ are booting and storing them in the TPM. In addition, a log of
+ these hashes is stored in memory for the OS to verify the booted
+ images and configuration. Enable this if the OS has configured
+ some memory area for the event log and you intend to use some
+ attestation tools on your system.
+
+if MEASURED_BOOT
+   config MEASURE_DEVICETREE
+   bool "Measure the devicetree image"
+   default y if MEASURED_BOOT
+   help
+ On some platforms, the devicetree is not static as it may contain
+ random MAC addresses or other such data that changes each boot.
+ Therefore, it should not be measured into the TPM. In that case,
+ disable the measurement here.
+
+   config MEASURE_IGNORE_LOG
+   bool "Ignore the existing event log"
+   default n
+   help
+ On platforms that use an event log memory region that persists
+ through system resets and are the first stage bootloader, then
+ this option should be enabled to ignore any existing data in the
+ event log memory region.
+endif # MEASURED_BOOT
+
 config SUPPORT_RAW_INITRD
bool "Enable raw initrd images"
help
diff --git a/boot/bootm.c b/boot/bootm.c
index b1c3afe0a3..11b6b3c292 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #if defined(CONFIG_CMD_USB)
 #include 
 #endif
@@ -673,6 +674,75 @@ int bootm_process_cmdline_env(int flags)
return 0;
 }
 
+int bootm_measure(struct bootm_headers *images)
+{
+   int ret = 0;
+
+   /* Skip measurement if EFI is going to do it */
+   if (images->os.os == IH_OS_EFI &&
+   IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL) &&
+   IS_ENABLED(CONFIG_BOOTM_EFI))
+   return ret;
+
+   if (IS_ENABLED(CONFIG_MEASURED_BOOT)) {
+   struct tcg2_event_log elog;
+   struct udevice *dev;
+   void *initrd_buf;
+   void *image_buf;
+   const char *s;
+   u32 rd_len;
+   bool ign;
+
+   elog.log_size = 0;
+   ign = IS_ENABLED(CONFIG_MEASURE_IGNORE_LOG);
+   ret = tcg2_measurement_init(, , ign);
+   if (ret)
+   return ret;
+
+   image_buf = map_sysmem(images->os.image_start,
+  images->os.image_len);
+   ret = tcg2_measure_data(dev, , 8, images->os.image_len,
+   image_buf, EV_COMPACT_HASH,
+   strlen("linux") + 1, (u8 *)"linux");
+   if (ret)
+   goto unmap_image;
+
+   rd_len = images->rd_end - images->rd_start;
+   initrd_buf = map_sysmem(images->rd_start, rd_len);
+   ret = tcg2_measure_data(dev, , 9, rd_len, initrd_buf,
+   EV_COMPACT_HASH, strlen("initrd") + 1,
+   (u8 *)"initrd");
+   if (ret)
+   goto unmap_initrd;
+
+   if (IS_ENABLED(CONFIG_MEASURE_DEVICETREE)) {
+   ret = tcg2_measure_data(dev, , 0, images->ft_len,
+   (u8 *)images->ft_addr,
+  

Re: [PATCH v12 5/8] test: Add sandbox TPM boot measurement

2023-10-19 Thread Eddie James



On 10/13/23 12:22, Ilias Apalodimas wrote:

Hi Eddie,

This doesn't apply on -master, can you please rebase?



Ugh I thought you wanted -next... I can rebase again.




Thanks
/Ilias

On Thu, 12 Oct 2023 at 16:49, Eddie James  wrote:

Use the sandbox TPM driver to measure some boot images in a unit
test case.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
Acked-by: Ilias Apalodimas 
---
Changes since v5:
  - Only compile in the measurement u-boot command when
CONFIG_MEASURED_BOOT is enabled.

  arch/sandbox/dts/sandbox.dtsi | 13 +++
  arch/sandbox/dts/test.dts | 13 +++
  configs/sandbox_defconfig |  1 +
  include/test/suites.h |  1 +
  test/boot/Makefile|  1 +
  test/boot/measurement.c   | 66 +++
  test/cmd_ut.c |  4 +++
  7 files changed, 99 insertions(+)
  create mode 100644 test/boot/measurement.c

diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index ff7e5584c5..241f397ba6 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -4,11 +4,23 @@
   * and sandbox64 builds.
   */

+#include 
  #include 

  #define USB_CLASS_HUB  9

  / {
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   event_log: tcg_event_log {
+   no-map;
+   reg = <(CFG_SYS_SDRAM_SIZE - 0x2000) 0x2000>;
+   };
+   };
+
 binman {
 };

@@ -342,6 +354,7 @@

 tpm2 {
 compatible = "sandbox,tpm2";
+   memory-region = <_log>;
 };

 triangle {
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 9a863ea732..bb2ddd9bf2 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -9,6 +9,7 @@

  /dts-v1/;

+#include 
  #include 
  #include 
  #include 
@@ -68,6 +69,17 @@
 osd0 = "/osd";
 };

+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   event_log: tcg_event_log {
+   no-map;
+   reg = <(CFG_SYS_SDRAM_SIZE - 0x2000) 0x2000>;
+   };
+   };
+
 binman: binman {
 };

@@ -1422,6 +1434,7 @@

 tpm2 {
 compatible = "sandbox,tpm2";
+   memory-region = <_log>;
 };

 tpm {
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index d667cb9ae4..12c387a77e 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -349,3 +349,4 @@ CONFIG_UNIT_TEST=y
  CONFIG_UT_TIME=y
  CONFIG_UT_DM=y
  CONFIG_ARM_FFA_TRANSPORT=y
+CONFIG_MEASURED_BOOT=y
diff --git a/include/test/suites.h b/include/test/suites.h
index 1c7dc65966..48ed549c13 100644
--- a/include/test/suites.h
+++ b/include/test/suites.h
@@ -45,6 +45,7 @@ int do_ut_font(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[]);
  int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
  int do_ut_loadm(struct cmd_tbl *cmdtp, int flag, int argc, char *const 
argv[]);
  int do_ut_log(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]);
+int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc, char * const 
argv[]);
  int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
  int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const 
argv[]);
  int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc,
diff --git a/test/boot/Makefile b/test/boot/Makefile
index 52947580ae..068522cb9e 100644
--- a/test/boot/Makefile
+++ b/test/boot/Makefile
@@ -4,6 +4,7 @@

  obj-$(CONFIG_BOOTSTD) += bootdev.o bootstd_common.o bootflow.o bootmeth.o
  obj-$(CONFIG_FIT) += image.o
+obj-$(CONFIG_MEASURED_BOOT) += measurement.o

  obj-$(CONFIG_EXPO) += expo.o
  obj-$(CONFIG_CEDIT) += cedit.o
diff --git a/test/boot/measurement.c b/test/boot/measurement.c
new file mode 100644
index 00..9db2ed324c
--- /dev/null
+++ b/test/boot/measurement.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test for measured boot functions
+ *
+ * Copyright 2023 IBM Corp.
+ * Written by Eddie James 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MEASUREMENT_TEST(_name, _flags)\
+   UNIT_TEST(_name, _flags, measurement_test)
+
+static int measure(struct unit_test_state *uts)
+{
+   struct bootm_headers images;
+   const size_t size = 1024;
+   u8 *kernel;
+   u8 *initrd;
+   size_t i;
+
+   kernel = malloc(size);
+   initrd = malloc(size);
+
+   images.os.image_start = map_to_sysmem(kernel);
+   images.os.image_len = size;
+
+   images.rd_start = map_to_sysmem(initrd);
+   images.rd_end = images.r

[PATCH v13 3/8] tpm: Support boot measurements

2023-10-19 Thread Eddie James
Add TPM2 functions to support boot measurement. This includes
starting up the TPM, initializing/appending the event log, and
measuring the U-Boot version. Much of the code was used in the
EFI subsystem, so remove it there and use the common functions.

Signed-off-by: Eddie James 
---
Changes since v10:
 - Fix compile warning for armv7 (thanks Ilias)

Changes since v8:
 - Fix log parsing again - any data corruption seen while replaying the
   event log was failing the entire measurement.
 - Added an option to ignore the existing log. This should only be used
   for systems that know that U-Boot is the first stage bootloader. This
   is necessary because the reserved memory region may persist through
   resets and so U-Boot attempts to append to the previous boot's log.

Changes since v7:
 - Change name of tcg2_init_log and add more documentation
 - Add a check, when parsing the event log header, to ensure that the
   previous stage bootloader used all the active PCRs.
 - Change name of tcg2_log_find_end
 - Fix the greater than or equal to check to exit the log parsing
 - Make sure log_position is 0 if there is any error discovering the log
 - Return errors parsing the log if the data is corrupt so that we don't
   end up with half a log

Changes since v6:
 - Added Linaro copyright for all the EFI moved code
 - Changed tcg2_init_log (and by extension, tcg2_measurement_init) to
   copy any discovered event log to the user's log if passed in.

Changes since v5:
 - Remove unused platform_get_eventlog in efi_tcg2.c
 - First look for tpm_event_log_* properties instead of linux,sml-*
 - Fix efi_tcg2.c compilation
 - Select SHA* configs

Changes since v4:
 - Remove tcg2_measure_event function and check for NULL data in
   tcg2_measure_data
 - Use tpm_auto_startup
 - Fix efi_tcg2.c compilation for removing tcg2_pcr_read function

Changes since v3:
 - Reordered headers
 - Refactored more of EFI code into common code
Removed digest_info structure and instead used the common alg_to_mask
  and alg_to_len
Improved event log parsing in common code to get it equivalent to EFI
  Common code now extends PCR if previous bootloader stage couldn't
  No need to allocate memory in the common code, so EFI copies the
  discovered buffer like it did before
Rename efi measure_event function

Changes since v1:
 - Refactor TPM layer functions to allow EFI system to use them, and
   remove duplicate EFI functions

 include/efi_tcg2.h|  44 --
 include/tpm-v2.h  | 259 
 lib/Kconfig   |   4 +
 lib/efi_loader/efi_tcg2.c | 821 --
 lib/tpm-v2.c  | 814 +
 5 files changed, 1154 insertions(+), 788 deletions(-)

diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
index b1c3abd097..b21c5cb3dd 100644
--- a/include/efi_tcg2.h
+++ b/include/efi_tcg2.h
@@ -129,50 +129,6 @@ struct efi_tcg2_boot_service_capability {
 #define BOOT_SERVICE_CAPABILITY_MIN \
offsetof(struct efi_tcg2_boot_service_capability, number_of_pcr_banks)
 
-#define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03"
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2
-
-/**
- *  struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm information
- *
- *  @algorithm_id: algorithm defined in enum tpm2_algorithms
- *  @digest_size:  size of the algorithm
- */
-struct tcg_efi_spec_id_event_algorithm_size {
-   u16  algorithm_id;
-   u16  digest_size;
-} __packed;
-
-/**
- * struct TCG_EfiSpecIDEventStruct - content of the event log header
- *
- * @signature: signature, set to Spec ID Event03
- * @platform_class:class defined in TCG ACPI Specification
- * Client  Common Header.
- * @spec_version_minor:minor version
- * @spec_version_major:major version
- * @spec_version_errata:   major version
- * @uintn_size:size of the efi_uintn_t fields used in 
various
- * data structures used in this specification.
- * 0x01 indicates u32  and 0x02  indicates u64
- * @number_of_algorithms:  hashing algorithms used in this event log
- * @digest_sizes:  array of number_of_algorithms pairs
- * 1st member defines the algorithm id
- * 2nd member defines the algorithm size
- */
-struct tcg_efi_spec_id_event {
-   u8 signature[16];
-   u32 platform_class;
-   u8 spec_version_minor;
-   u8 spec_version_major;
-   u8 spec_errata;
-   u8 uintn_size;
-   u32 number_of_algorithms;
-   struct tcg_efi_spec_id_event_algorithm_size digest_sizes[];
-} __packed;
-
 /**
  * struct tdEFI_TCG2_FINAL_EVENTS_TABLE - log entries after Get

[PATCH v13 8/8] test: use a non system PCR for testing PCR extend

2023-10-19 Thread Eddie James
From: Ilias Apalodimas 

We currently use PCR 0 for testing the PCR read/extend functionality in
our selftests.  How ever those PCRs are defined by the TCG spec for
platform use.  For example if the tests run *after* the efi subsystem
initialization, which extends PCRs 0 & 7 it will give a false positive.

So let's switch over to a PCR which is more suitable and is defined for
OS use.  It's worth noting that we are using PCR10 here, since PCR9 is
used internally by U-Boot if we choose to measure the loaded DTB

Reviewed-by: Simon Glass 
Signed-off-by: Ilias Apalodimas 
---
 test/py/tests/test_tpm2.py | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/test/py/tests/test_tpm2.py b/test/py/tests/test_tpm2.py
index c2579fa02c..47392b87a9 100644
--- a/test/py/tests/test_tpm2.py
+++ b/test/py/tests/test_tpm2.py
@@ -239,7 +239,7 @@ def test_tpm2_dam_parameters(u_boot_console):
 def test_tpm2_pcr_read(u_boot_console):
 """Execute a TPM2_PCR_Read command.
 
-Perform a PCR read of the 0th PCR. Must be zero.
+Perform a PCR read of the 10th PCR. Must be zero.
 """
 if is_sandbox(u_boot_console):
 tpm2_sandbox_init(u_boot_console)
@@ -247,7 +247,7 @@ def test_tpm2_pcr_read(u_boot_console):
 force_init(u_boot_console)
 ram = u_boot_utils.find_ram_base(u_boot_console)
 
-read_pcr = u_boot_console.run_command('tpm2 pcr_read 0 0x%x' % ram)
+read_pcr = u_boot_console.run_command('tpm2 pcr_read 10 0x%x' % ram)
 output = u_boot_console.run_command('echo $?')
 assert output.endswith('0')
 
@@ -257,7 +257,7 @@ def test_tpm2_pcr_read(u_boot_console):
 updates = int(re.findall(r'\d+', str)[0])
 
 # Check the output value
-assert 'PCR #0 content' in read_pcr
+assert 'PCR #10 content' in read_pcr
 assert '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' in read_pcr
 
 @pytest.mark.buildconfigspec('cmd_tpm_v2')
@@ -275,19 +275,19 @@ def test_tpm2_pcr_extend(u_boot_console):
 force_init(u_boot_console)
 ram = u_boot_utils.find_ram_base(u_boot_console)
 
-read_pcr = u_boot_console.run_command('tpm2 pcr_read 0 0x%x' % (ram + 
0x20))
+read_pcr = u_boot_console.run_command('tpm2 pcr_read 10 0x%x' % (ram + 
0x20))
 output = u_boot_console.run_command('echo $?')
 assert output.endswith('0')
 str = re.findall(r'\d+ known updates', read_pcr)[0]
 updates = int(re.findall(r'\d+', str)[0])
 
-u_boot_console.run_command('tpm2 pcr_extend 0 0x%x' % ram)
+u_boot_console.run_command('tpm2 pcr_extend 10 0x%x' % ram)
 output = u_boot_console.run_command('echo $?')
 assert output.endswith('0')
 
 # Read the value back into a different place so we can still use 'ram' as
 # our zero bytes
-read_pcr = u_boot_console.run_command('tpm2 pcr_read 0 0x%x' % (ram + 
0x20))
+read_pcr = u_boot_console.run_command('tpm2 pcr_read 10 0x%x' % (ram + 
0x20))
 output = u_boot_console.run_command('echo $?')
 assert output.endswith('0')
 assert 'f5 a5 fd 42 d1 6a 20 30 27 98 ef 6e d3 09 97 9b' in read_pcr
@@ -297,11 +297,11 @@ def test_tpm2_pcr_extend(u_boot_console):
 new_updates = int(re.findall(r'\d+', str)[0])
 assert (updates + 1) == new_updates
 
-u_boot_console.run_command('tpm2 pcr_extend 0 0x%x' % ram)
+u_boot_console.run_command('tpm2 pcr_extend 10 0x%x' % ram)
 output = u_boot_console.run_command('echo $?')
 assert output.endswith('0')
 
-read_pcr = u_boot_console.run_command('tpm2 pcr_read 0 0x%x' % (ram + 
0x20))
+read_pcr = u_boot_console.run_command('tpm2 pcr_read 10 0x%x' % (ram + 
0x20))
 output = u_boot_console.run_command('echo $?')
 assert output.endswith('0')
 assert '7a 05 01 f5 95 7b df 9c b3 a8 ff 49 66 f0 22 65' in read_pcr
-- 
2.39.3



[PATCH v13 4/8] bootm: Support boot measurement

2023-10-19 Thread Eddie James
Add a configuration option to measure the boot through the bootm
function. Add the measurement state to the booti and bootz paths
as well.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
---
Changes since v8:
 - Added a configuration option to select to ignore any existing
   event log. This would only be selected for systems that know
   that U-Boot is the first stage bootloader. This is necessary
   because the reserved memory region may persist through resets
   and so U-Boot attempts to append to the previous boot's log.

Changes since v6:
 - Added comment for bootm_measure
 - Fixed line length in bootm_measure

 boot/Kconfig| 32 +
 boot/bootm.c| 74 +
 cmd/booti.c |  1 +
 cmd/bootm.c |  2 ++
 cmd/bootz.c |  1 +
 include/bootm.h | 11 
 include/image.h |  1 +
 7 files changed, 122 insertions(+)

diff --git a/boot/Kconfig b/boot/Kconfig
index a01e6cb8aa..abbc72f4cf 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -685,6 +685,38 @@ config LEGACY_IMAGE_FORMAT
  loaded. If a board needs the legacy image format support in this
  case, enable it here.
 
+config MEASURED_BOOT
+   bool "Measure boot images and configuration to TPM and event log"
+   depends on HASH && TPM_V2
+   help
+ This option enables measurement of the boot process. Measurement
+ involves creating cryptographic hashes of the binary images that
+ are booting and storing them in the TPM. In addition, a log of
+ these hashes is stored in memory for the OS to verify the booted
+ images and configuration. Enable this if the OS has configured
+ some memory area for the event log and you intend to use some
+ attestation tools on your system.
+
+if MEASURED_BOOT
+   config MEASURE_DEVICETREE
+   bool "Measure the devicetree image"
+   default y if MEASURED_BOOT
+   help
+ On some platforms, the devicetree is not static as it may contain
+ random MAC addresses or other such data that changes each boot.
+ Therefore, it should not be measured into the TPM. In that case,
+ disable the measurement here.
+
+   config MEASURE_IGNORE_LOG
+   bool "Ignore the existing event log"
+   default n
+   help
+ On platforms that use an event log memory region that persists
+ through system resets and are the first stage bootloader, then
+ this option should be enabled to ignore any existing data in the
+ event log memory region.
+endif # MEASURED_BOOT
+
 config SUPPORT_RAW_INITRD
bool "Enable raw initrd images"
help
diff --git a/boot/bootm.c b/boot/bootm.c
index 8f96a80d42..cb61485c22 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 #if defined(CONFIG_CMD_USB)
 #include 
 #endif
@@ -673,6 +674,75 @@ int bootm_process_cmdline_env(int flags)
return 0;
 }
 
+int bootm_measure(struct bootm_headers *images)
+{
+   int ret = 0;
+
+   /* Skip measurement if EFI is going to do it */
+   if (images->os.os == IH_OS_EFI &&
+   IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL) &&
+   IS_ENABLED(CONFIG_BOOTM_EFI))
+   return ret;
+
+   if (IS_ENABLED(CONFIG_MEASURED_BOOT)) {
+   struct tcg2_event_log elog;
+   struct udevice *dev;
+   void *initrd_buf;
+   void *image_buf;
+   const char *s;
+   u32 rd_len;
+   bool ign;
+
+   elog.log_size = 0;
+   ign = IS_ENABLED(CONFIG_MEASURE_IGNORE_LOG);
+   ret = tcg2_measurement_init(, , ign);
+   if (ret)
+   return ret;
+
+   image_buf = map_sysmem(images->os.image_start,
+  images->os.image_len);
+   ret = tcg2_measure_data(dev, , 8, images->os.image_len,
+   image_buf, EV_COMPACT_HASH,
+   strlen("linux") + 1, (u8 *)"linux");
+   if (ret)
+   goto unmap_image;
+
+   rd_len = images->rd_end - images->rd_start;
+   initrd_buf = map_sysmem(images->rd_start, rd_len);
+   ret = tcg2_measure_data(dev, , 9, rd_len, initrd_buf,
+   EV_COMPACT_HASH, strlen("initrd") + 1,
+   (u8 *)"initrd");
+   if (ret)
+   goto unmap_initrd;
+
+   if (IS_ENABLED(CONFIG_MEASURE_DEVICETREE)) {
+   ret = tcg2_measure_data(dev, , 0, images->ft_len,
+   (u8 *)images->ft_addr,
+  

[PATCH v13 6/8] doc: Add measured boot documentation

2023-10-19 Thread Eddie James
Briefly describe the feature and specify the requirements.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
---
Changes since v12:
 - Add a bit of detail about OS usage and what pieces are measured

 doc/usage/index.rst |  1 +
 doc/usage/measured_boot.rst | 31 +++
 2 files changed, 32 insertions(+)
 create mode 100644 doc/usage/measured_boot.rst

diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 98b4719c40..bf53bb6bda 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -14,6 +14,7 @@ Use U-Boot
partitions
cmdline
semihosting
+   measured_boot
 
 Shell commands
 --
diff --git a/doc/usage/measured_boot.rst b/doc/usage/measured_boot.rst
new file mode 100644
index 00..0aad590859
--- /dev/null
+++ b/doc/usage/measured_boot.rst
@@ -0,0 +1,31 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Measured Boot
+=
+
+U-Boot can perform a measured boot, the process of hashing various components
+of the boot process, extending the results in the TPM and logging the
+component's measurement in memory for the operating system to consume.
+
+By default, U-Boot will measure the operating system (linux) image, the
+initrd image, and the "bootargs" environment variable. By enabling
+CONFIG_MEASURE_DEVICETREE, U-Boot will also measure the devicetree image.
+
+The operating system typically would verify that the hashes found in the
+TPM PCRs match the contents of the event log. This can further be checked
+against the hash results of previous boots.
+
+Requirements
+-
+
+* A hardware TPM 2.0 supported by the U-Boot drivers
+* CONFIG_TPM=y
+* CONFIG_MEASURED_BOOT=y
+* Device-tree configuration of the TPM device to specify the memory area
+  for event logging. The TPM device node must either contain a phandle to
+  a reserved memory region or "linux,sml-base" and "linux,sml-size"
+  indicating the address and size of the memory region. An example can be
+  found in arch/sandbox/dts/test.dts
+* The operating system must also be configured to use the memory regions
+  specified in the U-Boot device-tree in order to make use of the event
+  log.
-- 
2.39.3



Re: [PATCH v12 6/8] doc: Add measured boot documentation

2023-10-19 Thread Eddie James



On 10/12/23 10:29, Simon Glass wrote:

Hi Eddie,

On Thu, 12 Oct 2023 at 08:08, Eddie James  wrote:

Briefly describe the feature and specify the requirements.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 

This could use a bit more detail. What pieces are measured? What DT
binding is used for the TPM? How is the info checked by the OS or
whatever?



Sure, I'll add a little bit more. The DT binding is described in the 
requirements section.







---
  doc/usage/index.rst |  1 +
  doc/usage/measured_boot.rst | 23 +++
  2 files changed, 24 insertions(+)
  create mode 100644 doc/usage/measured_boot.rst

diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index fa702920fa..fb043a8923 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -14,6 +14,7 @@ Use U-Boot
 partitions
 cmdline
 semihosting
+   measured_boot

  Shell commands
  --
diff --git a/doc/usage/measured_boot.rst b/doc/usage/measured_boot.rst
new file mode 100644
index 00..8357b1f480
--- /dev/null
+++ b/doc/usage/measured_boot.rst
@@ -0,0 +1,23 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Measured Boot
+=
+
+U-Boot can perform a measured boot, the process of hashing various components
+of the boot process, extending the results in the TPM and logging the
+component's measurement in memory for the operating system to consume.
+
+Requirements
+-
+
+* A hardware TPM 2.0 supported by the U-Boot drivers
+* CONFIG_TPM=y
+* CONFIG_MEASURED_BOOT=y
+* Device-tree configuration of the TPM device to specify the memory area
+  for event logging. The TPM device node must either contain a phandle to
+  a reserved memory region or "linux,sml-base" and "linux,sml-size"
+  indicating the address and size of the memory region. An example can be
+  found in arch/sandbox/dts/test.dts
+* The operating system must also be configured to use the memory regions
+  specified in the U-Boot device-tree in order to make use of the event
+  log.

Regards,
Simon


[PATCH v13 5/8] test: Add sandbox TPM boot measurement

2023-10-19 Thread Eddie James
Use the sandbox TPM driver to measure some boot images in a unit
test case.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
Acked-by: Ilias Apalodimas 
---
Changes since v5:
 - Only compile in the measurement u-boot command when
   CONFIG_MEASURED_BOOT is enabled.

 arch/sandbox/dts/sandbox.dtsi | 13 +++
 arch/sandbox/dts/test.dts | 13 +++
 configs/sandbox_defconfig |  1 +
 include/test/suites.h |  1 +
 test/boot/Makefile|  1 +
 test/boot/measurement.c   | 66 +++
 test/cmd_ut.c |  4 +++
 7 files changed, 99 insertions(+)
 create mode 100644 test/boot/measurement.c

diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index ff7e5584c5..241f397ba6 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -4,11 +4,23 @@
  * and sandbox64 builds.
  */
 
+#include 
 #include 
 
 #define USB_CLASS_HUB  9
 
 / {
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   event_log: tcg_event_log {
+   no-map;
+   reg = <(CFG_SYS_SDRAM_SIZE - 0x2000) 0x2000>;
+   };
+   };
+
binman {
};
 
@@ -342,6 +354,7 @@
 
tpm2 {
compatible = "sandbox,tpm2";
+   memory-region = <_log>;
};
 
triangle {
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index e430347356..67159b3d01 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -9,6 +9,7 @@
 
 /dts-v1/;
 
+#include 
 #include 
 #include 
 #include 
@@ -68,6 +69,17 @@
osd0 = "/osd";
};
 
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   event_log: tcg_event_log {
+   no-map;
+   reg = <(CFG_SYS_SDRAM_SIZE - 0x2000) 0x2000>;
+   };
+   };
+
binman: binman {
};
 
@@ -1423,6 +1435,7 @@
 
tpm2 {
compatible = "sandbox,tpm2";
+   memory-region = <_log>;
};
 
tpm {
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 47417cb039..757dcac4ca 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -349,3 +349,4 @@ CONFIG_TEST_FDTDEC=y
 CONFIG_UNIT_TEST=y
 CONFIG_UT_TIME=y
 CONFIG_UT_DM=y
+CONFIG_MEASURED_BOOT=y
diff --git a/include/test/suites.h b/include/test/suites.h
index 1c7dc65966..48ed549c13 100644
--- a/include/test/suites.h
+++ b/include/test/suites.h
@@ -45,6 +45,7 @@ int do_ut_font(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[]);
 int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_loadm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_log(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]);
+int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc, char * const 
argv[]);
 int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc,
diff --git a/test/boot/Makefile b/test/boot/Makefile
index 52947580ae..068522cb9e 100644
--- a/test/boot/Makefile
+++ b/test/boot/Makefile
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_BOOTSTD) += bootdev.o bootstd_common.o bootflow.o bootmeth.o
 obj-$(CONFIG_FIT) += image.o
+obj-$(CONFIG_MEASURED_BOOT) += measurement.o
 
 obj-$(CONFIG_EXPO) += expo.o
 obj-$(CONFIG_CEDIT) += cedit.o
diff --git a/test/boot/measurement.c b/test/boot/measurement.c
new file mode 100644
index 00..9db2ed324c
--- /dev/null
+++ b/test/boot/measurement.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test for measured boot functions
+ *
+ * Copyright 2023 IBM Corp.
+ * Written by Eddie James 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MEASUREMENT_TEST(_name, _flags)\
+   UNIT_TEST(_name, _flags, measurement_test)
+
+static int measure(struct unit_test_state *uts)
+{
+   struct bootm_headers images;
+   const size_t size = 1024;
+   u8 *kernel;
+   u8 *initrd;
+   size_t i;
+
+   kernel = malloc(size);
+   initrd = malloc(size);
+
+   images.os.image_start = map_to_sysmem(kernel);
+   images.os.image_len = size;
+
+   images.rd_start = map_to_sysmem(initrd);
+   images.rd_end = images.rd_start + size;
+
+   images.ft_addr = malloc(size);
+   images.ft_len = size;
+
+   env_set("bootargs", "measurement testing");
+
+   for (i = 0; i < size; ++i) {
+   kernel[i] = 0xf0 | (i & 0xf);
+   in

[PATCH v13 1/8] tpm: Fix spelling for tpmu_ha union

2023-10-19 Thread Eddie James
tmpu -> tpmu

Signed-off-by: Eddie James 
Reviewed-by: Ilias Apalodimas 
---
 include/tpm-v2.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 2b6980e441..6684033deb 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -169,7 +169,7 @@ struct tcg_pcr_event {
 /**
  * Definition of TPMU_HA Union
  */
-union tmpu_ha {
+union tpmu_ha {
u8 sha1[TPM2_SHA1_DIGEST_SIZE];
u8 sha256[TPM2_SHA256_DIGEST_SIZE];
u8 sm3_256[TPM2_SM3_256_DIGEST_SIZE];
@@ -185,7 +185,7 @@ union tmpu_ha {
  */
 struct tpmt_ha {
u16 hash_alg;
-   union tmpu_ha digest;
+   union tpmu_ha digest;
 } __packed;
 
 /**
-- 
2.39.3



[PATCH v13 0/8] tpm: Support boot measurements

2023-10-19 Thread Eddie James
This series adds support for measuring the boot images more generically
than the existing EFI support. Several EFI functions have been moved to
the TPM layer. The series includes optional measurement from the bootm 
command.
A new test case has been added for the bootm measurement to test the new
path, and the sandbox TPM2 driver has been updated to support this use
case.

Changes since v12:
 - Rebase on master.
 - Add detail to documentation.

Changes since v11:
 - Rebase on next. Sorry for the delay (been on leave).

Changes since v10:
 - Fix commit message on efi_loader change
 - Drop python test change
 - Squash armv7 fix from Ilias

Changes since v9:
 - Rebase and add Ilias' fixes (thanks!)

Changes since v8:
 - Fix a sandbox driver off-by-one error in checking the property type.
 - Fix log parsing again - any data corruption seen while replaying the
   event log was failing the entire measurement.
 - Added an option to ignore the existing log and a configuration option
   for systems to select that for the bootm measurement. This would only
   be selected for systems that know that U-Boot is the first stage
   bootloader. This is necessary because the reserved memory region may
   persist through resets and so U-Boot attempts to append to the
   previous boot's log.

Changes since v7:
 - Change name of tcg2_init_log and add more documentation
 - Add a check, when parsing the event log header, to ensure that the
   previous stage bootloader used all the active PCRs.
 - Change name of tcg2_log_find_end
 - Fix the greater than or equal to check to exit the log parsing
 - Make sure log_position is 0 if there is any error discovering the log
 - Return errors parsing the log if the data is corrupt so that we don't
   end up with half a log

Changes since v6:
 - Added comment for bootm_measure
 - Fixed line length in bootm_measure
 - Added Linaro copyright for all the EFI moved code
 - Changed tcg2_init_log (and by extension, tcg2_measurement_init) to
   copy any discovered event log to the user's log if passed in.

Changes since v5:
 - Re-ordered the patches to put the sandbox TPM driver patch second
 - Remove unused platform_get_eventlog in efi_tcg2.c
 - First look for tpm_event_log_* properties instead of linux,sml-*
 - Fix efi_tcg2.c compilation
 - Select SHA* configs
 - Remove the !SANDBOX dependency for EFI TCG2
 - Only compile in the measurement u-boot command when CONFIG_MEASURED_BOOT
   is enabled

Changes since v4:
 - Remove tcg2_measure_event function and check for NULL data in
   tcg2_measure_data
 - Use tpm_auto_startup
 - Fix efi_tcg2.c compilation for removing tcg2_pcr_read function
 - Change PCR indexes for initrd and dtb
 - Drop u8 casting in measurement test
 - Use bullets in documentation

Changes since v3:
 - Reordered headers
 - Refactored more of EFI code into common code
Removed digest_info structure and instead used the common alg_to_mask
  and alg_to_len
Improved event log parsing in common code to get it equivalent to EFI
  Common code now extends PCR if previous bootloader stage couldn't
  No need to allocate memory in the common code, so EFI copies the
  discovered buffer like it did before
Rename efi measure_event function

Changes since v2:
 - Add documentation.
 - Changed reserved memory address to the top of the RAM for sandbox dts.
 - Add measure state to booti and bootz.
 - Skip measurement for EFI images that should be measured

Changes since v1:
 - Refactor TPM layer functions to allow EFI system to use them, and
   remove duplicate EFI functions.
 - Add test case
 - Drop #ifdefs for bootm
 - Add devicetree measurement config option
 - Update sandbox TPM driver

Eddie James (6):
  tpm: Fix spelling for tpmu_ha union
  tpm: sandbox: Update for needed TPM2 capabilities
  tpm: Support boot measurements
  bootm: Support boot measurement
  test: Add sandbox TPM boot measurement
  doc: Add measured boot documentation

Ilias Apalodimas (2):
  efi_loader: fix EFI_ENTRY point on get_active_pcr_banks
  test: use a non system PCR for testing PCR extend

 arch/sandbox/dts/sandbox.dtsi  |  13 +
 arch/sandbox/dts/test.dts  |  13 +
 boot/Kconfig   |  32 ++
 boot/bootm.c   |  74 +++
 cmd/booti.c|   1 +
 cmd/bootm.c|   2 +
 cmd/bootz.c|   1 +
 configs/sandbox_defconfig  |   1 +
 doc/usage/index.rst|   1 +
 doc/usage/measured_boot.rst|  23 +
 drivers/tpm/tpm2_tis_sandbox.c | 100 ++--
 include/bootm.h|  11 +
 include/efi_tcg2.h |  44 --
 include/image.h|   1 +
 include/test/suites.h  |   1 +
 include/tpm-v2.h   | 263 ++-
 lib/Kconfig|   4 +
 lib/efi_loader/Kconfig |   2 -
 lib/efi_loader/efi_tcg2.c  | 823 -
 lib/tpm-v2.c   | 814 
 test/boot/Makefile |   1

[PATCH v13 2/8] tpm: sandbox: Update for needed TPM2 capabilities

2023-10-19 Thread Eddie James
The driver needs to support getting the PCRs in the capabilities
command. Fix various other things and support the max number
of PCRs for TPM2.
Remove the !SANDBOX dependency for EFI TCG2 as well.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
Acked-by: Ilias Apalodimas 
---
Changes since v8:
 - Use >= for checking the property against TPM2_PROPERTIES_OFFSET

Changes since v5:
 - Remove the !SANDBOX dependency for EFI TCG2

 drivers/tpm/tpm2_tis_sandbox.c | 100 -
 lib/efi_loader/Kconfig |   2 -
 2 files changed, 72 insertions(+), 30 deletions(-)

diff --git a/drivers/tpm/tpm2_tis_sandbox.c b/drivers/tpm/tpm2_tis_sandbox.c
index e4004cfcca..d15a28d9fc 100644
--- a/drivers/tpm/tpm2_tis_sandbox.c
+++ b/drivers/tpm/tpm2_tis_sandbox.c
@@ -22,11 +22,6 @@ enum tpm2_hierarchy {
TPM2_HIERARCHY_NB,
 };
 
-/* Subset of supported capabilities */
-enum tpm2_capability {
-   TPM_CAP_TPM_PROPERTIES = 0x6,
-};
-
 /* Subset of supported properties */
 #define TPM2_PROPERTIES_OFFSET 0x020E
 
@@ -38,7 +33,8 @@ enum tpm2_cap_tpm_property {
TPM2_PROPERTY_NB,
 };
 
-#define SANDBOX_TPM_PCR_NB 1
+#define SANDBOX_TPM_PCR_NB TPM2_MAX_PCRS
+#define SANDBOX_TPM_PCR_SELECT_MAX ((SANDBOX_TPM_PCR_NB + 7) / 8)
 
 /*
  * Information about our TPM emulation. This is preserved in the sandbox
@@ -433,7 +429,7 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const u8 
*sendbuf,
int i, j;
 
/* TPM2_GetProperty */
-   u32 capability, property, property_count;
+   u32 capability, property, property_count, val;
 
/* TPM2_PCR_Read/Extend variables */
int pcr_index = 0;
@@ -542,19 +538,32 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const 
u8 *sendbuf,
case TPM2_CC_GET_CAPABILITY:
capability = get_unaligned_be32(sent);
sent += sizeof(capability);
-   if (capability != TPM_CAP_TPM_PROPERTIES) {
-   printf("Sandbox TPM only support TPM_CAPABILITIES\n");
-   return TPM2_RC_HANDLE;
-   }
-
property = get_unaligned_be32(sent);
sent += sizeof(property);
-   property -= TPM2_PROPERTIES_OFFSET;
-
property_count = get_unaligned_be32(sent);
sent += sizeof(property_count);
-   if (!property_count ||
-   property + property_count > TPM2_PROPERTY_NB) {
+
+   switch (capability) {
+   case TPM2_CAP_PCRS:
+   break;
+   case TPM2_CAP_TPM_PROPERTIES:
+   if (!property_count) {
+   rc = TPM2_RC_HANDLE;
+   return sandbox_tpm2_fill_buf(recv, recv_len,
+tag, rc);
+   }
+
+   if (property >= TPM2_PROPERTIES_OFFSET &&
+   ((property - TPM2_PROPERTIES_OFFSET) +
+property_count > TPM2_PROPERTY_NB)) {
+   rc = TPM2_RC_HANDLE;
+   return sandbox_tpm2_fill_buf(recv, recv_len,
+tag, rc);
+   }
+   break;
+   default:
+   printf("Sandbox TPM2 only supports TPM2_CAP_PCRS or "
+  "TPM2_CAP_TPM_PROPERTIES\n");
rc = TPM2_RC_HANDLE;
return sandbox_tpm2_fill_buf(recv, recv_len, tag, rc);
}
@@ -578,18 +587,53 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const 
u8 *sendbuf,
put_unaligned_be32(capability, recv);
recv += sizeof(capability);
 
-   /* Give the number of properties that follow */
-   put_unaligned_be32(property_count, recv);
-   recv += sizeof(property_count);
-
-   /* Fill with the properties */
-   for (i = 0; i < property_count; i++) {
-   put_unaligned_be32(TPM2_PROPERTIES_OFFSET + property +
-  i, recv);
-   recv += sizeof(property);
-   put_unaligned_be32(tpm->properties[property + i],
-  recv);
-   recv += sizeof(property);
+   switch (capability) {
+   case TPM2_CAP_PCRS:
+   /* Give the number of algorithms supported - just 
SHA256 */
+   put_unaligned_be32(1, recv);
+   recv += sizeof(u32);
+
+   /* Give SHA256 algorithm */
+   put_unaligned_be16(TPM2_ALG_SHA256, recv);
+   recv += sizeof(u16);
+
+   /* Se

[PATCH v13 7/8] efi_loader: fix EFI_ENTRY point on get_active_pcr_banks

2023-10-19 Thread Eddie James
From: Ilias Apalodimas 

efi_tcg2_get_active_pcr_banks doesn't immediately call the
EFI_ENTRY() wrapper once it enters the function. Move the call a
few lines above to cover the error cases properly as well.

Signed-off-by: Ilias Apalodimas 
---
 lib/efi_loader/efi_tcg2.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index 7ada536568..dae1b166c8 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -949,16 +949,16 @@ efi_tcg2_get_active_pcr_banks(struct efi_tcg2_protocol 
*this,
struct udevice *dev;
efi_status_t ret;
 
+   EFI_ENTRY("%p, %p", this, active_pcr_banks);
+
if (!this || !active_pcr_banks) {
ret = EFI_INVALID_PARAMETER;
goto out;
}
-
ret = tcg2_platform_get_tpm2();
if (ret != EFI_SUCCESS)
goto out;
 
-   EFI_ENTRY("%p, %p", this, active_pcr_banks);
ret = tcg2_get_active_pcr_banks(dev, active_pcr_banks);
 
 out:
-- 
2.39.3



Re: [PATCH v13 0/8] tpm: Support boot measurements

2023-10-24 Thread Eddie James



On 10/19/23 17:49, Ilias Apalodimas wrote:

Hi Eddie,

Does the series compile for you against -master?
For qemu_arm64_defonfig I am getting compilation errors both locally
and on the CI
https://source.denx.de/u-boot/custodians/u-boot-tpm/-/jobs/717362#L39



Yea it was a problem rebasing. I'll send v14 soon.

Thanks,

Eddie




Thanks
/Ilias

On Thu, 19 Oct 2023 at 19:45, Ilias Apalodimas
 wrote:

Thanks Eddie

I've queued this up on public CI.  I also have an internal one, this
one failed to add the TF-A eventlog, but everything else looks fine.
I'll have a look tomorrow, but since this used to work on earlier
versions I suspect it's going to be trivial to fix

Cheers
/Ilias

On Thu, 19 Oct 2023 at 19:21, Eddie James  wrote:

This series adds support for measuring the boot images more generically
than the existing EFI support. Several EFI functions have been moved to
the TPM layer. The series includes optional measurement from the bootm
command.
A new test case has been added for the bootm measurement to test the new
path, and the sandbox TPM2 driver has been updated to support this use
case.

Changes since v12:
  - Rebase on master.
  - Add detail to documentation.

Changes since v11:
  - Rebase on next. Sorry for the delay (been on leave).

Changes since v10:
  - Fix commit message on efi_loader change
  - Drop python test change
  - Squash armv7 fix from Ilias

Changes since v9:
  - Rebase and add Ilias' fixes (thanks!)

Changes since v8:
  - Fix a sandbox driver off-by-one error in checking the property type.
  - Fix log parsing again - any data corruption seen while replaying the
event log was failing the entire measurement.
  - Added an option to ignore the existing log and a configuration option
for systems to select that for the bootm measurement. This would only
be selected for systems that know that U-Boot is the first stage
bootloader. This is necessary because the reserved memory region may
persist through resets and so U-Boot attempts to append to the
previous boot's log.

Changes since v7:
  - Change name of tcg2_init_log and add more documentation
  - Add a check, when parsing the event log header, to ensure that the
previous stage bootloader used all the active PCRs.
  - Change name of tcg2_log_find_end
  - Fix the greater than or equal to check to exit the log parsing
  - Make sure log_position is 0 if there is any error discovering the log
  - Return errors parsing the log if the data is corrupt so that we don't
end up with half a log

Changes since v6:
  - Added comment for bootm_measure
  - Fixed line length in bootm_measure
  - Added Linaro copyright for all the EFI moved code
  - Changed tcg2_init_log (and by extension, tcg2_measurement_init) to
copy any discovered event log to the user's log if passed in.

Changes since v5:
  - Re-ordered the patches to put the sandbox TPM driver patch second
  - Remove unused platform_get_eventlog in efi_tcg2.c
  - First look for tpm_event_log_* properties instead of linux,sml-*
  - Fix efi_tcg2.c compilation
  - Select SHA* configs
  - Remove the !SANDBOX dependency for EFI TCG2
  - Only compile in the measurement u-boot command when CONFIG_MEASURED_BOOT
is enabled

Changes since v4:
  - Remove tcg2_measure_event function and check for NULL data in
tcg2_measure_data
  - Use tpm_auto_startup
  - Fix efi_tcg2.c compilation for removing tcg2_pcr_read function
  - Change PCR indexes for initrd and dtb
  - Drop u8 casting in measurement test
  - Use bullets in documentation

Changes since v3:
  - Reordered headers
  - Refactored more of EFI code into common code
 Removed digest_info structure and instead used the common alg_to_mask
   and alg_to_len
 Improved event log parsing in common code to get it equivalent to EFI
   Common code now extends PCR if previous bootloader stage couldn't
   No need to allocate memory in the common code, so EFI copies the
   discovered buffer like it did before
 Rename efi measure_event function

Changes since v2:
  - Add documentation.
  - Changed reserved memory address to the top of the RAM for sandbox dts.
  - Add measure state to booti and bootz.
  - Skip measurement for EFI images that should be measured

Changes since v1:
  - Refactor TPM layer functions to allow EFI system to use them, and
remove duplicate EFI functions.
  - Add test case
  - Drop #ifdefs for bootm
  - Add devicetree measurement config option
  - Update sandbox TPM driver

Eddie James (6):
   tpm: Fix spelling for tpmu_ha union
   tpm: sandbox: Update for needed TPM2 capabilities
   tpm: Support boot measurements
   bootm: Support boot measurement
   test: Add sandbox TPM boot measurement
   doc: Add measured boot documentation

Ilias Apalodimas (2):
   efi_loader: fix EFI_ENTRY point on get_active_pcr_banks
   test: use a non system PCR for testing PCR extend

  arch/sandbox/dts/sandbox.dtsi  |  13 +
  arch/sandbox/dts/test.dts  |  13 +
  boot/Kconfig

[PATCH v14 0/8] tpm: Support boot measurements

2023-10-24 Thread Eddie James
This series adds support for measuring the boot images more generically
than the existing EFI support. Several EFI functions have been moved to
the TPM layer. The series includes optional measurement from the bootm 
command.
A new test case has been added for the bootm measurement to test the new
path, and the sandbox TPM2 driver has been updated to support this use
case.

Changes since v13:
 - Rebase without messing up efi_tcg2.c (duplicate functions)

Changes since v12:
 - Rebase on master.
 - Add detail to documentation.

Changes since v11:
 - Rebase on next. Sorry for the delay (been on leave).

Changes since v10:
 - Fix commit message on efi_loader change
 - Drop python test change
 - Squash armv7 fix from Ilias

Changes since v9:
 - Rebase and add Ilias' fixes (thanks!)

Changes since v8:
 - Fix a sandbox driver off-by-one error in checking the property type.
 - Fix log parsing again - any data corruption seen while replaying the
   event log was failing the entire measurement.
 - Added an option to ignore the existing log and a configuration option
   for systems to select that for the bootm measurement. This would only
   be selected for systems that know that U-Boot is the first stage
   bootloader. This is necessary because the reserved memory region may
   persist through resets and so U-Boot attempts to append to the
   previous boot's log.

Changes since v7:
 - Change name of tcg2_init_log and add more documentation
 - Add a check, when parsing the event log header, to ensure that the
   previous stage bootloader used all the active PCRs.
 - Change name of tcg2_log_find_end
 - Fix the greater than or equal to check to exit the log parsing
 - Make sure log_position is 0 if there is any error discovering the log
 - Return errors parsing the log if the data is corrupt so that we don't
   end up with half a log

Changes since v6:
 - Added comment for bootm_measure
 - Fixed line length in bootm_measure
 - Added Linaro copyright for all the EFI moved code
 - Changed tcg2_init_log (and by extension, tcg2_measurement_init) to
   copy any discovered event log to the user's log if passed in.

Changes since v5:
 - Re-ordered the patches to put the sandbox TPM driver patch second
 - Remove unused platform_get_eventlog in efi_tcg2.c
 - First look for tpm_event_log_* properties instead of linux,sml-*
 - Fix efi_tcg2.c compilation
 - Select SHA* configs
 - Remove the !SANDBOX dependency for EFI TCG2
 - Only compile in the measurement u-boot command when CONFIG_MEASURED_BOOT
   is enabled

Changes since v4:
 - Remove tcg2_measure_event function and check for NULL data in
   tcg2_measure_data
 - Use tpm_auto_startup
 - Fix efi_tcg2.c compilation for removing tcg2_pcr_read function
 - Change PCR indexes for initrd and dtb
 - Drop u8 casting in measurement test
 - Use bullets in documentation

Changes since v3:
 - Reordered headers
 - Refactored more of EFI code into common code
Removed digest_info structure and instead used the common alg_to_mask
  and alg_to_len
Improved event log parsing in common code to get it equivalent to EFI
  Common code now extends PCR if previous bootloader stage couldn't
  No need to allocate memory in the common code, so EFI copies the
  discovered buffer like it did before
Rename efi measure_event function

Changes since v2:
 - Add documentation.
 - Changed reserved memory address to the top of the RAM for sandbox dts.
 - Add measure state to booti and bootz.
 - Skip measurement for EFI images that should be measured

Changes since v1:
 - Refactor TPM layer functions to allow EFI system to use them, and
   remove duplicate EFI functions.
 - Add test case
 - Drop #ifdefs for bootm
 - Add devicetree measurement config option
 - Update sandbox TPM driver

Eddie James (6):
  tpm: Fix spelling for tpmu_ha union
  tpm: sandbox: Update for needed TPM2 capabilities
  tpm: Support boot measurements
  bootm: Support boot measurement
  test: Add sandbox TPM boot measurement
  doc: Add measured boot documentation

Ilias Apalodimas (2):
  efi_loader: fix EFI_ENTRY point on get_active_pcr_banks
  test: use a non system PCR for testing PCR extend

 arch/sandbox/dts/sandbox.dtsi  |   13 +
 arch/sandbox/dts/test.dts  |   13 +
 boot/Kconfig   |   32 +
 boot/bootm.c   |   74 +++
 cmd/booti.c|1 +
 cmd/bootm.c|2 +
 cmd/bootz.c|1 +
 configs/sandbox_defconfig  |1 +
 doc/usage/index.rst|1 +
 doc/usage/measured_boot.rst|   31 +
 drivers/tpm/tpm2_tis_sandbox.c |  100 ++-
 include/bootm.h|   11 +
 include/efi_tcg2.h |   44 --
 include/image.h|1 +
 include/test/suites.h  |1 +
 include/tpm-v2.h   |  263 +++-
 lib/Kconfig|4 +
 lib/efi_loader/Kconfig |2 -
 lib/efi_loader/efi_tcg2.c  | 1055 +++-
 lib/tpm-v2.c

[PATCH v14 5/8] test: Add sandbox TPM boot measurement

2023-10-24 Thread Eddie James
Use the sandbox TPM driver to measure some boot images in a unit
test case.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
Acked-by: Ilias Apalodimas 
---
Changes since v5:
 - Only compile in the measurement u-boot command when
   CONFIG_MEASURED_BOOT is enabled.

 arch/sandbox/dts/sandbox.dtsi | 13 +++
 arch/sandbox/dts/test.dts | 13 +++
 configs/sandbox_defconfig |  1 +
 include/test/suites.h |  1 +
 test/boot/Makefile|  1 +
 test/boot/measurement.c   | 66 +++
 test/cmd_ut.c |  4 +++
 7 files changed, 99 insertions(+)
 create mode 100644 test/boot/measurement.c

diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index ff7e5584c5..241f397ba6 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -4,11 +4,23 @@
  * and sandbox64 builds.
  */
 
+#include 
 #include 
 
 #define USB_CLASS_HUB  9
 
 / {
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   event_log: tcg_event_log {
+   no-map;
+   reg = <(CFG_SYS_SDRAM_SIZE - 0x2000) 0x2000>;
+   };
+   };
+
binman {
};
 
@@ -342,6 +354,7 @@
 
tpm2 {
compatible = "sandbox,tpm2";
+   memory-region = <_log>;
};
 
triangle {
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index e430347356..67159b3d01 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -9,6 +9,7 @@
 
 /dts-v1/;
 
+#include 
 #include 
 #include 
 #include 
@@ -68,6 +69,17 @@
osd0 = "/osd";
};
 
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   event_log: tcg_event_log {
+   no-map;
+   reg = <(CFG_SYS_SDRAM_SIZE - 0x2000) 0x2000>;
+   };
+   };
+
binman: binman {
};
 
@@ -1423,6 +1435,7 @@
 
tpm2 {
compatible = "sandbox,tpm2";
+   memory-region = <_log>;
};
 
tpm {
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 47417cb039..757dcac4ca 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -349,3 +349,4 @@ CONFIG_TEST_FDTDEC=y
 CONFIG_UNIT_TEST=y
 CONFIG_UT_TIME=y
 CONFIG_UT_DM=y
+CONFIG_MEASURED_BOOT=y
diff --git a/include/test/suites.h b/include/test/suites.h
index 1c7dc65966..48ed549c13 100644
--- a/include/test/suites.h
+++ b/include/test/suites.h
@@ -45,6 +45,7 @@ int do_ut_font(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[]);
 int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_loadm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_log(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]);
+int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc, char * const 
argv[]);
 int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc,
diff --git a/test/boot/Makefile b/test/boot/Makefile
index 52947580ae..068522cb9e 100644
--- a/test/boot/Makefile
+++ b/test/boot/Makefile
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_BOOTSTD) += bootdev.o bootstd_common.o bootflow.o bootmeth.o
 obj-$(CONFIG_FIT) += image.o
+obj-$(CONFIG_MEASURED_BOOT) += measurement.o
 
 obj-$(CONFIG_EXPO) += expo.o
 obj-$(CONFIG_CEDIT) += cedit.o
diff --git a/test/boot/measurement.c b/test/boot/measurement.c
new file mode 100644
index 00..9db2ed324c
--- /dev/null
+++ b/test/boot/measurement.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test for measured boot functions
+ *
+ * Copyright 2023 IBM Corp.
+ * Written by Eddie James 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MEASUREMENT_TEST(_name, _flags)\
+   UNIT_TEST(_name, _flags, measurement_test)
+
+static int measure(struct unit_test_state *uts)
+{
+   struct bootm_headers images;
+   const size_t size = 1024;
+   u8 *kernel;
+   u8 *initrd;
+   size_t i;
+
+   kernel = malloc(size);
+   initrd = malloc(size);
+
+   images.os.image_start = map_to_sysmem(kernel);
+   images.os.image_len = size;
+
+   images.rd_start = map_to_sysmem(initrd);
+   images.rd_end = images.rd_start + size;
+
+   images.ft_addr = malloc(size);
+   images.ft_len = size;
+
+   env_set("bootargs", "measurement testing");
+
+   for (i = 0; i < size; ++i) {
+   kernel[i] = 0xf0 | (i & 0xf);
+   in

[PATCH v14 6/8] doc: Add measured boot documentation

2023-10-24 Thread Eddie James
Briefly describe the feature and specify the requirements.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
---
Changes since v12:
 - Add a bit of detail about OS usage and what pieces are measured

 doc/usage/index.rst |  1 +
 doc/usage/measured_boot.rst | 31 +++
 2 files changed, 32 insertions(+)
 create mode 100644 doc/usage/measured_boot.rst

diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 98b4719c40..bf53bb6bda 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -14,6 +14,7 @@ Use U-Boot
partitions
cmdline
semihosting
+   measured_boot
 
 Shell commands
 --
diff --git a/doc/usage/measured_boot.rst b/doc/usage/measured_boot.rst
new file mode 100644
index 00..0aad590859
--- /dev/null
+++ b/doc/usage/measured_boot.rst
@@ -0,0 +1,31 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Measured Boot
+=
+
+U-Boot can perform a measured boot, the process of hashing various components
+of the boot process, extending the results in the TPM and logging the
+component's measurement in memory for the operating system to consume.
+
+By default, U-Boot will measure the operating system (linux) image, the
+initrd image, and the "bootargs" environment variable. By enabling
+CONFIG_MEASURE_DEVICETREE, U-Boot will also measure the devicetree image.
+
+The operating system typically would verify that the hashes found in the
+TPM PCRs match the contents of the event log. This can further be checked
+against the hash results of previous boots.
+
+Requirements
+-
+
+* A hardware TPM 2.0 supported by the U-Boot drivers
+* CONFIG_TPM=y
+* CONFIG_MEASURED_BOOT=y
+* Device-tree configuration of the TPM device to specify the memory area
+  for event logging. The TPM device node must either contain a phandle to
+  a reserved memory region or "linux,sml-base" and "linux,sml-size"
+  indicating the address and size of the memory region. An example can be
+  found in arch/sandbox/dts/test.dts
+* The operating system must also be configured to use the memory regions
+  specified in the U-Boot device-tree in order to make use of the event
+  log.
-- 
2.39.3



[PATCH v14 2/8] tpm: sandbox: Update for needed TPM2 capabilities

2023-10-24 Thread Eddie James
The driver needs to support getting the PCRs in the capabilities
command. Fix various other things and support the max number
of PCRs for TPM2.
Remove the !SANDBOX dependency for EFI TCG2 as well.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
Acked-by: Ilias Apalodimas 
---
Changes since v8:
 - Use >= for checking the property against TPM2_PROPERTIES_OFFSET

Changes since v5:
 - Remove the !SANDBOX dependency for EFI TCG2

 drivers/tpm/tpm2_tis_sandbox.c | 100 -
 lib/efi_loader/Kconfig |   2 -
 2 files changed, 72 insertions(+), 30 deletions(-)

diff --git a/drivers/tpm/tpm2_tis_sandbox.c b/drivers/tpm/tpm2_tis_sandbox.c
index e4004cfcca..d15a28d9fc 100644
--- a/drivers/tpm/tpm2_tis_sandbox.c
+++ b/drivers/tpm/tpm2_tis_sandbox.c
@@ -22,11 +22,6 @@ enum tpm2_hierarchy {
TPM2_HIERARCHY_NB,
 };
 
-/* Subset of supported capabilities */
-enum tpm2_capability {
-   TPM_CAP_TPM_PROPERTIES = 0x6,
-};
-
 /* Subset of supported properties */
 #define TPM2_PROPERTIES_OFFSET 0x020E
 
@@ -38,7 +33,8 @@ enum tpm2_cap_tpm_property {
TPM2_PROPERTY_NB,
 };
 
-#define SANDBOX_TPM_PCR_NB 1
+#define SANDBOX_TPM_PCR_NB TPM2_MAX_PCRS
+#define SANDBOX_TPM_PCR_SELECT_MAX ((SANDBOX_TPM_PCR_NB + 7) / 8)
 
 /*
  * Information about our TPM emulation. This is preserved in the sandbox
@@ -433,7 +429,7 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const u8 
*sendbuf,
int i, j;
 
/* TPM2_GetProperty */
-   u32 capability, property, property_count;
+   u32 capability, property, property_count, val;
 
/* TPM2_PCR_Read/Extend variables */
int pcr_index = 0;
@@ -542,19 +538,32 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const 
u8 *sendbuf,
case TPM2_CC_GET_CAPABILITY:
capability = get_unaligned_be32(sent);
sent += sizeof(capability);
-   if (capability != TPM_CAP_TPM_PROPERTIES) {
-   printf("Sandbox TPM only support TPM_CAPABILITIES\n");
-   return TPM2_RC_HANDLE;
-   }
-
property = get_unaligned_be32(sent);
sent += sizeof(property);
-   property -= TPM2_PROPERTIES_OFFSET;
-
property_count = get_unaligned_be32(sent);
sent += sizeof(property_count);
-   if (!property_count ||
-   property + property_count > TPM2_PROPERTY_NB) {
+
+   switch (capability) {
+   case TPM2_CAP_PCRS:
+   break;
+   case TPM2_CAP_TPM_PROPERTIES:
+   if (!property_count) {
+   rc = TPM2_RC_HANDLE;
+   return sandbox_tpm2_fill_buf(recv, recv_len,
+tag, rc);
+   }
+
+   if (property >= TPM2_PROPERTIES_OFFSET &&
+   ((property - TPM2_PROPERTIES_OFFSET) +
+property_count > TPM2_PROPERTY_NB)) {
+   rc = TPM2_RC_HANDLE;
+   return sandbox_tpm2_fill_buf(recv, recv_len,
+tag, rc);
+   }
+   break;
+   default:
+   printf("Sandbox TPM2 only supports TPM2_CAP_PCRS or "
+  "TPM2_CAP_TPM_PROPERTIES\n");
rc = TPM2_RC_HANDLE;
return sandbox_tpm2_fill_buf(recv, recv_len, tag, rc);
}
@@ -578,18 +587,53 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const 
u8 *sendbuf,
put_unaligned_be32(capability, recv);
recv += sizeof(capability);
 
-   /* Give the number of properties that follow */
-   put_unaligned_be32(property_count, recv);
-   recv += sizeof(property_count);
-
-   /* Fill with the properties */
-   for (i = 0; i < property_count; i++) {
-   put_unaligned_be32(TPM2_PROPERTIES_OFFSET + property +
-  i, recv);
-   recv += sizeof(property);
-   put_unaligned_be32(tpm->properties[property + i],
-  recv);
-   recv += sizeof(property);
+   switch (capability) {
+   case TPM2_CAP_PCRS:
+   /* Give the number of algorithms supported - just 
SHA256 */
+   put_unaligned_be32(1, recv);
+   recv += sizeof(u32);
+
+   /* Give SHA256 algorithm */
+   put_unaligned_be16(TPM2_ALG_SHA256, recv);
+   recv += sizeof(u16);
+
+   /* Se

[PATCH v14 1/8] tpm: Fix spelling for tpmu_ha union

2023-10-24 Thread Eddie James
tmpu -> tpmu

Signed-off-by: Eddie James 
Reviewed-by: Ilias Apalodimas 
---
 include/tpm-v2.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 2b6980e441..6684033deb 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -169,7 +169,7 @@ struct tcg_pcr_event {
 /**
  * Definition of TPMU_HA Union
  */
-union tmpu_ha {
+union tpmu_ha {
u8 sha1[TPM2_SHA1_DIGEST_SIZE];
u8 sha256[TPM2_SHA256_DIGEST_SIZE];
u8 sm3_256[TPM2_SM3_256_DIGEST_SIZE];
@@ -185,7 +185,7 @@ union tmpu_ha {
  */
 struct tpmt_ha {
u16 hash_alg;
-   union tmpu_ha digest;
+   union tpmu_ha digest;
 } __packed;
 
 /**
-- 
2.39.3



[PATCH v14 3/8] tpm: Support boot measurements

2023-10-24 Thread Eddie James
Add TPM2 functions to support boot measurement. This includes
starting up the TPM, initializing/appending the event log, and
measuring the U-Boot version. Much of the code was used in the
EFI subsystem, so remove it there and use the common functions.

Signed-off-by: Eddie James 
---
Changes since v13:
 - Fix rebase since v11 and prevent duplicate efi_tcg2.c functions

Changes since v10:
 - Fix compile warning for armv7 (thanks Ilias)

Changes since v8:
 - Fix log parsing again - any data corruption seen while replaying the
   event log was failing the entire measurement.
 - Added an option to ignore the existing log. This should only be used
   for systems that know that U-Boot is the first stage bootloader. This
   is necessary because the reserved memory region may persist through
   resets and so U-Boot attempts to append to the previous boot's log.

Changes since v7:
 - Change name of tcg2_init_log and add more documentation
 - Add a check, when parsing the event log header, to ensure that the
   previous stage bootloader used all the active PCRs.
 - Change name of tcg2_log_find_end
 - Fix the greater than or equal to check to exit the log parsing
 - Make sure log_position is 0 if there is any error discovering the log
 - Return errors parsing the log if the data is corrupt so that we don't
   end up with half a log

Changes since v6:
 - Added Linaro copyright for all the EFI moved code
 - Changed tcg2_init_log (and by extension, tcg2_measurement_init) to
   copy any discovered event log to the user's log if passed in.

Changes since v5:
 - Remove unused platform_get_eventlog in efi_tcg2.c
 - First look for tpm_event_log_* properties instead of linux,sml-*
 - Fix efi_tcg2.c compilation
 - Select SHA* configs

Changes since v4:
 - Remove tcg2_measure_event function and check for NULL data in
   tcg2_measure_data
 - Use tpm_auto_startup
 - Fix efi_tcg2.c compilation for removing tcg2_pcr_read function

Changes since v3:
 - Reordered headers
 - Refactored more of EFI code into common code
Removed digest_info structure and instead used the common alg_to_mask
  and alg_to_len
Improved event log parsing in common code to get it equivalent to EFI
  Common code now extends PCR if previous bootloader stage couldn't
  No need to allocate memory in the common code, so EFI copies the
  discovered buffer like it did before
Rename efi measure_event function

Changes since v1:
 - Refactor TPM layer functions to allow EFI system to use them, and
   remove duplicate EFI functions

 include/efi_tcg2.h|   44 --
 include/tpm-v2.h  |  259 +
 lib/Kconfig   |4 +
 lib/efi_loader/efi_tcg2.c | 1053 +++--
 lib/tpm-v2.c  |  814 
 5 files changed, 1154 insertions(+), 1020 deletions(-)

diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
index b1c3abd097..b21c5cb3dd 100644
--- a/include/efi_tcg2.h
+++ b/include/efi_tcg2.h
@@ -129,50 +129,6 @@ struct efi_tcg2_boot_service_capability {
 #define BOOT_SERVICE_CAPABILITY_MIN \
offsetof(struct efi_tcg2_boot_service_capability, number_of_pcr_banks)
 
-#define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03"
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2
-
-/**
- *  struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm information
- *
- *  @algorithm_id: algorithm defined in enum tpm2_algorithms
- *  @digest_size:  size of the algorithm
- */
-struct tcg_efi_spec_id_event_algorithm_size {
-   u16  algorithm_id;
-   u16  digest_size;
-} __packed;
-
-/**
- * struct TCG_EfiSpecIDEventStruct - content of the event log header
- *
- * @signature: signature, set to Spec ID Event03
- * @platform_class:class defined in TCG ACPI Specification
- * Client  Common Header.
- * @spec_version_minor:minor version
- * @spec_version_major:major version
- * @spec_version_errata:   major version
- * @uintn_size:size of the efi_uintn_t fields used in 
various
- * data structures used in this specification.
- * 0x01 indicates u32  and 0x02  indicates u64
- * @number_of_algorithms:  hashing algorithms used in this event log
- * @digest_sizes:  array of number_of_algorithms pairs
- * 1st member defines the algorithm id
- * 2nd member defines the algorithm size
- */
-struct tcg_efi_spec_id_event {
-   u8 signature[16];
-   u32 platform_class;
-   u8 spec_version_minor;
-   u8 spec_version_major;
-   u8 spec_errata;
-   u8 uintn_size;
-   u32 number_of_algorithms;
-   struct tcg_efi_spec_id_event_algorithm_size digest_sizes[];
-

[PATCH v14 4/8] bootm: Support boot measurement

2023-10-24 Thread Eddie James
Add a configuration option to measure the boot through the bootm
function. Add the measurement state to the booti and bootz paths
as well.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
---
Changes since v8:
 - Added a configuration option to select to ignore any existing
   event log. This would only be selected for systems that know
   that U-Boot is the first stage bootloader. This is necessary
   because the reserved memory region may persist through resets
   and so U-Boot attempts to append to the previous boot's log.

Changes since v6:
 - Added comment for bootm_measure
 - Fixed line length in bootm_measure

 boot/Kconfig| 32 +
 boot/bootm.c| 74 +
 cmd/booti.c |  1 +
 cmd/bootm.c |  2 ++
 cmd/bootz.c |  1 +
 include/bootm.h | 11 
 include/image.h |  1 +
 7 files changed, 122 insertions(+)

diff --git a/boot/Kconfig b/boot/Kconfig
index a01e6cb8aa..abbc72f4cf 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -685,6 +685,38 @@ config LEGACY_IMAGE_FORMAT
  loaded. If a board needs the legacy image format support in this
  case, enable it here.
 
+config MEASURED_BOOT
+   bool "Measure boot images and configuration to TPM and event log"
+   depends on HASH && TPM_V2
+   help
+ This option enables measurement of the boot process. Measurement
+ involves creating cryptographic hashes of the binary images that
+ are booting and storing them in the TPM. In addition, a log of
+ these hashes is stored in memory for the OS to verify the booted
+ images and configuration. Enable this if the OS has configured
+ some memory area for the event log and you intend to use some
+ attestation tools on your system.
+
+if MEASURED_BOOT
+   config MEASURE_DEVICETREE
+   bool "Measure the devicetree image"
+   default y if MEASURED_BOOT
+   help
+ On some platforms, the devicetree is not static as it may contain
+ random MAC addresses or other such data that changes each boot.
+ Therefore, it should not be measured into the TPM. In that case,
+ disable the measurement here.
+
+   config MEASURE_IGNORE_LOG
+   bool "Ignore the existing event log"
+   default n
+   help
+ On platforms that use an event log memory region that persists
+ through system resets and are the first stage bootloader, then
+ this option should be enabled to ignore any existing data in the
+ event log memory region.
+endif # MEASURED_BOOT
+
 config SUPPORT_RAW_INITRD
bool "Enable raw initrd images"
help
diff --git a/boot/bootm.c b/boot/bootm.c
index 8f96a80d42..cb61485c22 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 #if defined(CONFIG_CMD_USB)
 #include 
 #endif
@@ -673,6 +674,75 @@ int bootm_process_cmdline_env(int flags)
return 0;
 }
 
+int bootm_measure(struct bootm_headers *images)
+{
+   int ret = 0;
+
+   /* Skip measurement if EFI is going to do it */
+   if (images->os.os == IH_OS_EFI &&
+   IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL) &&
+   IS_ENABLED(CONFIG_BOOTM_EFI))
+   return ret;
+
+   if (IS_ENABLED(CONFIG_MEASURED_BOOT)) {
+   struct tcg2_event_log elog;
+   struct udevice *dev;
+   void *initrd_buf;
+   void *image_buf;
+   const char *s;
+   u32 rd_len;
+   bool ign;
+
+   elog.log_size = 0;
+   ign = IS_ENABLED(CONFIG_MEASURE_IGNORE_LOG);
+   ret = tcg2_measurement_init(, , ign);
+   if (ret)
+   return ret;
+
+   image_buf = map_sysmem(images->os.image_start,
+  images->os.image_len);
+   ret = tcg2_measure_data(dev, , 8, images->os.image_len,
+   image_buf, EV_COMPACT_HASH,
+   strlen("linux") + 1, (u8 *)"linux");
+   if (ret)
+   goto unmap_image;
+
+   rd_len = images->rd_end - images->rd_start;
+   initrd_buf = map_sysmem(images->rd_start, rd_len);
+   ret = tcg2_measure_data(dev, , 9, rd_len, initrd_buf,
+   EV_COMPACT_HASH, strlen("initrd") + 1,
+   (u8 *)"initrd");
+   if (ret)
+   goto unmap_initrd;
+
+   if (IS_ENABLED(CONFIG_MEASURE_DEVICETREE)) {
+   ret = tcg2_measure_data(dev, , 0, images->ft_len,
+   (u8 *)images->ft_addr,
+  

[PATCH v14 8/8] test: use a non system PCR for testing PCR extend

2023-10-24 Thread Eddie James
From: Ilias Apalodimas 

We currently use PCR 0 for testing the PCR read/extend functionality in
our selftests.  How ever those PCRs are defined by the TCG spec for
platform use.  For example if the tests run *after* the efi subsystem
initialization, which extends PCRs 0 & 7 it will give a false positive.

So let's switch over to a PCR which is more suitable and is defined for
OS use.  It's worth noting that we are using PCR10 here, since PCR9 is
used internally by U-Boot if we choose to measure the loaded DTB

Reviewed-by: Simon Glass 
Signed-off-by: Ilias Apalodimas 
---
 test/py/tests/test_tpm2.py | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/test/py/tests/test_tpm2.py b/test/py/tests/test_tpm2.py
index c2579fa02c..47392b87a9 100644
--- a/test/py/tests/test_tpm2.py
+++ b/test/py/tests/test_tpm2.py
@@ -239,7 +239,7 @@ def test_tpm2_dam_parameters(u_boot_console):
 def test_tpm2_pcr_read(u_boot_console):
 """Execute a TPM2_PCR_Read command.
 
-Perform a PCR read of the 0th PCR. Must be zero.
+Perform a PCR read of the 10th PCR. Must be zero.
 """
 if is_sandbox(u_boot_console):
 tpm2_sandbox_init(u_boot_console)
@@ -247,7 +247,7 @@ def test_tpm2_pcr_read(u_boot_console):
 force_init(u_boot_console)
 ram = u_boot_utils.find_ram_base(u_boot_console)
 
-read_pcr = u_boot_console.run_command('tpm2 pcr_read 0 0x%x' % ram)
+read_pcr = u_boot_console.run_command('tpm2 pcr_read 10 0x%x' % ram)
 output = u_boot_console.run_command('echo $?')
 assert output.endswith('0')
 
@@ -257,7 +257,7 @@ def test_tpm2_pcr_read(u_boot_console):
 updates = int(re.findall(r'\d+', str)[0])
 
 # Check the output value
-assert 'PCR #0 content' in read_pcr
+assert 'PCR #10 content' in read_pcr
 assert '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' in read_pcr
 
 @pytest.mark.buildconfigspec('cmd_tpm_v2')
@@ -275,19 +275,19 @@ def test_tpm2_pcr_extend(u_boot_console):
 force_init(u_boot_console)
 ram = u_boot_utils.find_ram_base(u_boot_console)
 
-read_pcr = u_boot_console.run_command('tpm2 pcr_read 0 0x%x' % (ram + 
0x20))
+read_pcr = u_boot_console.run_command('tpm2 pcr_read 10 0x%x' % (ram + 
0x20))
 output = u_boot_console.run_command('echo $?')
 assert output.endswith('0')
 str = re.findall(r'\d+ known updates', read_pcr)[0]
 updates = int(re.findall(r'\d+', str)[0])
 
-u_boot_console.run_command('tpm2 pcr_extend 0 0x%x' % ram)
+u_boot_console.run_command('tpm2 pcr_extend 10 0x%x' % ram)
 output = u_boot_console.run_command('echo $?')
 assert output.endswith('0')
 
 # Read the value back into a different place so we can still use 'ram' as
 # our zero bytes
-read_pcr = u_boot_console.run_command('tpm2 pcr_read 0 0x%x' % (ram + 
0x20))
+read_pcr = u_boot_console.run_command('tpm2 pcr_read 10 0x%x' % (ram + 
0x20))
 output = u_boot_console.run_command('echo $?')
 assert output.endswith('0')
 assert 'f5 a5 fd 42 d1 6a 20 30 27 98 ef 6e d3 09 97 9b' in read_pcr
@@ -297,11 +297,11 @@ def test_tpm2_pcr_extend(u_boot_console):
 new_updates = int(re.findall(r'\d+', str)[0])
 assert (updates + 1) == new_updates
 
-u_boot_console.run_command('tpm2 pcr_extend 0 0x%x' % ram)
+u_boot_console.run_command('tpm2 pcr_extend 10 0x%x' % ram)
 output = u_boot_console.run_command('echo $?')
 assert output.endswith('0')
 
-read_pcr = u_boot_console.run_command('tpm2 pcr_read 0 0x%x' % (ram + 
0x20))
+read_pcr = u_boot_console.run_command('tpm2 pcr_read 10 0x%x' % (ram + 
0x20))
 output = u_boot_console.run_command('echo $?')
 assert output.endswith('0')
 assert '7a 05 01 f5 95 7b df 9c b3 a8 ff 49 66 f0 22 65' in read_pcr
-- 
2.39.3



[PATCH v14 7/8] efi_loader: fix EFI_ENTRY point on get_active_pcr_banks

2023-10-24 Thread Eddie James
From: Ilias Apalodimas 

efi_tcg2_get_active_pcr_banks doesn't immediately call the
EFI_ENTRY() wrapper once it enters the function. Move the call a
few lines above to cover the error cases properly as well.

Signed-off-by: Ilias Apalodimas 
---
 lib/efi_loader/efi_tcg2.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index b87c7900a8..2eaa12b83b 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -717,16 +717,16 @@ efi_tcg2_get_active_pcr_banks(struct efi_tcg2_protocol 
*this,
struct udevice *dev;
efi_status_t ret;
 
+   EFI_ENTRY("%p, %p", this, active_pcr_banks);
+
if (!this || !active_pcr_banks) {
ret = EFI_INVALID_PARAMETER;
goto out;
}
-
ret = tcg2_platform_get_tpm2();
if (ret != EFI_SUCCESS)
goto out;
 
-   EFI_ENTRY("%p, %p", this, active_pcr_banks);
ret = tcg2_get_active_pcr_banks(dev, active_pcr_banks);
 
 out:
-- 
2.39.3



Re: [PATCH 2/2] tpm: add support for TPMv2.x I2C chips

2022-05-23 Thread Eddie James



On 5/23/22 01:12, Ilias Apalodimas wrote:

Hi Eddie,

Thanks for the patch.

[...]


+static const struct tpm_tis_chip_data tpm_tis_std_chip_data = {
+   .pcr_count = 24,
+   .pcr_select_min = 3,
+};
+
+static const struct udevice_id tpm_tis_i2c_ids[] = {
+   {
+   .compatible = "nuvoton,npct75x",
+   .data = (ulong)_tis_std_chip_data,
+   },
+   {
+   .compatible = "tcg,tpm-tis-i2c",
+   .data = (ulong)_tis_std_chip_data,
+   },
+   { }
+};
+
+U_BOOT_DRIVER(tpm_tis_i2c) = {
+   .name = "tpm_tis_i2c",
+   .id = UCLASS_TPM,
+   .of_match = tpm_tis_i2c_ids,
+   .ops = _tis_i2c_ops,
+   .probe = tpm_tis_i2c_probe,
+   .remove = tpm_tis_i2c_remove,
+   .priv_auto_alloc_size = sizeof(struct tpm_chip),

Shouldn't this be .priv_auto only? IIRC we got rid of the
.priv_auto_alloc_size a while back?  If so I can fix this while merging



Yes, I think so. I tested with an older u-boot (openbmc uses a modified 
v2019.04) with all the TPM core patches, and I think I missed this bit 
in rebasing.


Thanks,

Eddie




Regards
/Ilias


+};
--
2.27.0



[PATCH] arm: dts: ast2600: Add I2C pinctrl

2022-06-01 Thread Eddie James
Set the pinctrl groups for each I2C bus. These are essential to
I2C operating correctly.

Signed-off-by: Eddie James 
---
 arch/arm/dts/ast2600.dtsi | 33 +
 1 file changed, 33 insertions(+)

diff --git a/arch/arm/dts/ast2600.dtsi b/arch/arm/dts/ast2600.dtsi
index 64074309b7..ef5b131ac0 100644
--- a/arch/arm/dts/ast2600.dtsi
+++ b/arch/arm/dts/ast2600.dtsi
@@ -833,6 +833,8 @@
bus-frequency = <10>;
interrupts = ;
clocks = < ASPEED_CLK_APB2>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_i2c1_default>;
status = "disabled";
};
 
@@ -846,6 +848,8 @@
bus-frequency = <10>;
interrupts = ;
clocks = < ASPEED_CLK_APB2>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_i2c2_default>;
status = "disabled";
};
 
@@ -859,6 +863,8 @@
bus-frequency = <10>;
interrupts = ;
clocks = < ASPEED_CLK_APB2>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_i2c3_default>;
};
 
i2c3: i2c@200 {
@@ -871,6 +877,8 @@
bus-frequency = <10>;
interrupts = ;
clocks = < ASPEED_CLK_APB2>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_i2c4_default>;
};
 
i2c4: i2c@280 {
@@ -883,6 +891,8 @@
bus-frequency = <10>;
interrupts = ;
clocks = < ASPEED_CLK_APB2>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_i2c5_default>;
};
 
i2c5: i2c@300 {
@@ -895,6 +905,8 @@
bus-frequency = <10>;
interrupts = ;
clocks = < ASPEED_CLK_APB2>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_i2c6_default>;
};
 
i2c6: i2c@380 {
@@ -907,6 +919,8 @@
bus-frequency = <10>;
interrupts = ;
clocks = < ASPEED_CLK_APB2>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_i2c7_default>;
};
 
i2c7: i2c@400 {
@@ -919,6 +933,8 @@
bus-frequency = <10>;
interrupts = ;
clocks = < ASPEED_CLK_APB2>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_i2c8_default>;
};
 
i2c8: i2c@480 {
@@ -931,6 +947,8 @@
bus-frequency = <10>;
interrupts = ;
clocks = < ASPEED_CLK_APB2>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_i2c9_default>;
};
 
i2c9: i2c@500 {
@@ -943,6 +961,8 @@
bus-frequency = <10>;
interrupts = ;
clocks = < ASPEED_CLK_APB2>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_i2c10_default>;
status = "disabled";
};
 
@@ -956,6 +976,8 @@
bus-frequency = <10>;
interrupts = ;
clocks = < ASPEED_CLK_APB2>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_i2c11_default>;
status = "disabled";
};
 
@@ -969,6 +991,8 @@
bus-frequency = <10>;
interrupts = ;
clocks = < ASPEED_CLK_APB2>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_i2c12_default>;
status = "disabled";
};
 
@@ -982,6 +1006,8 @@
bus-frequency = <10>;
interrupts = ;
clocks = < ASPEED_CLK_APB2>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_i2c13_default>;
status = "disabled";
};
 
@@ -995,6 +1021,8 @@
bus-frequency = <10>;
interrupts = ;
clocks = < ASPEED_CLK_APB2>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_i2c14_default>;
status = "disabled";
};
 
@@ -1008,6 +1036,8 @@
bus-frequency = <10>;
interrupts = ;
clocks = < ASPEED_CLK_APB2>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_i2c15_default>;
status = "disabled";
};
 
@@ -1021,6 +1051,8 @@
bus-frequency = <10>;
interrupts = ;
clocks = < ASPEED_CLK_APB2>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_i2c16_default>;
status = "disabled";
};
 
@@ -1246,6 +1278,7 @@
function = "I2C1";
groups = "I2C1";
};
+
pinctrl_i2c2_default: i2c2_default {
function = "I2C2";
groups = "I2C2";
-- 
2.31.1



[PATCH 2/2] tpm: add support for TPMv2.x I2C chips

2022-05-13 Thread Eddie James
Add the tpm2_tis_i2c driver that should support any TPMv2 compliant
I2C chips, such as the NPCT75X chip.

Signed-off-by: Eddie James 
---
 drivers/tpm/Kconfig|   9 ++
 drivers/tpm/Makefile   |   1 +
 drivers/tpm/tpm2_tis_i2c.c | 171 +
 3 files changed, 181 insertions(+)
 create mode 100644 drivers/tpm/tpm2_tis_i2c.c

diff --git a/drivers/tpm/Kconfig b/drivers/tpm/Kconfig
index eceff27d5f..d59102d9a6 100644
--- a/drivers/tpm/Kconfig
+++ b/drivers/tpm/Kconfig
@@ -185,6 +185,15 @@ config TPM2_TIS_SPI
  to the device using the standard TPM Interface Specification (TIS)
  protocol.
 
+config TPM2_TIS_I2C
+   bool "Enable support for TPMv2.x I2C chips"
+   depends on TPM_V2 && DM_I2C
+   help
+ This driver supports TPMv2.x devices connected on the I2C bus.
+ The usual TPM operations and the 'tpm' command can be used to talk
+ to the device using the standard TPM Interface Specification (TIS)
+ protocol.
+
 config TPM2_FTPM_TEE
bool "TEE based fTPM Interface"
depends on TEE && OPTEE && TPM_V2
diff --git a/drivers/tpm/Makefile b/drivers/tpm/Makefile
index 51725230c7..9540fd7fe7 100644
--- a/drivers/tpm/Makefile
+++ b/drivers/tpm/Makefile
@@ -13,5 +13,6 @@ obj-$(CONFIG_TPM_ST33ZP24_SPI) += tpm_tis_st33zp24_spi.o
 obj-$(CONFIG_$(SPL_TPL_)TPM2_CR50_I2C) += cr50_i2c.o
 obj-$(CONFIG_TPM2_TIS_SANDBOX) += tpm2_tis_sandbox.o sandbox_common.o
 obj-$(CONFIG_TPM2_TIS_SPI) += tpm2_tis_core.o tpm2_tis_spi.o
+obj-$(CONFIG_TPM2_TIS_I2C) += tpm2_tis_core.o tpm2_tis_i2c.o
 obj-$(CONFIG_TPM2_FTPM_TEE) += tpm2_ftpm_tee.o
 obj-$(CONFIG_TPM2_MMIO) += tpm2_tis_core.o tpm2_tis_mmio.o
diff --git a/drivers/tpm/tpm2_tis_i2c.c b/drivers/tpm/tpm2_tis_i2c.c
new file mode 100644
index 00..33cd5bb84b
--- /dev/null
+++ b/drivers/tpm/tpm2_tis_i2c.c
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2022 IBM Corp.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "tpm_tis.h"
+#include "tpm_internal.h"
+
+struct tpm_tis_chip_data {
+   unsigned int pcr_count;
+   unsigned int pcr_select_min;
+};
+
+static uint tpm_tis_i2c_address_to_register(u32 addr)
+{
+   addr &= 0xFFF;
+
+   /*
+* Adapt register addresses that have changed compared to older TIS
+* version.
+*/
+   switch (addr) {
+   case TPM_ACCESS(0):
+   return 0x04;
+   case TPM_DID_VID(0):
+   return 0x48;
+   case TPM_RID(0):
+   return 0x4C;
+   default:
+   return addr;
+   }
+}
+
+static int tpm_tis_i2c_read(struct udevice *dev, u32 addr, u16 len, u8 *in)
+{
+   int rc;
+   int count = 0;
+   uint reg = tpm_tis_i2c_address_to_register(addr);
+
+   do {
+   rc = dm_i2c_read(dev, reg, in, len);
+   udelay(SLEEP_DURATION_US);
+   } while (rc && count++ < MAX_COUNT);
+
+   return rc;
+}
+
+static int tpm_tis_i2c_write(struct udevice *dev, u32 addr, u16 len,
+const u8 *out)
+{
+   int rc;
+   int count = 0;
+   uint reg = tpm_tis_i2c_address_to_register(addr);
+
+   do {
+   rc = dm_i2c_write(dev, reg, out, len);
+   udelay(SLEEP_DURATION_US);
+   } while (rc && count++ < MAX_COUNT);
+
+   return rc;
+}
+
+static int tpm_tis_i2c_read32(struct udevice *dev, u32 addr, u32 *result)
+{
+   __le32 result_le;
+   int rc;
+
+   rc = tpm_tis_i2c_read(dev, addr, sizeof(u32), (u8 *)_le);
+   if (!rc)
+   *result = le32_to_cpu(result_le);
+
+   return rc;
+}
+
+static int tpm_tis_i2c_write32(struct udevice *dev, u32 addr, u32 value)
+{
+   __le32 value_le = cpu_to_le32(value);
+
+   return tpm_tis_i2c_write(dev, addr, sizeof(value), (u8 *)_le);
+}
+
+static struct tpm_tis_phy_ops phy_ops = {
+   .read_bytes = tpm_tis_i2c_read,
+   .write_bytes = tpm_tis_i2c_write,
+   .read32 = tpm_tis_i2c_read32,
+   .write32 = tpm_tis_i2c_write32,
+};
+
+static int tpm_tis_i2c_probe(struct udevice *udev)
+{
+   struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(udev);
+   struct tpm_chip_priv *priv = dev_get_uclass_priv(udev);
+   int rc;
+   u8 loc = 0;
+
+   tpm_tis_ops_register(udev, _ops);
+
+   /*
+* Force locality 0. The core driver doesn't actually write the
+* locality register and instead just reads/writes various access
+* bits of the selected locality.
+*/
+   rc = dm_i2c_write(udev, 0, , 1);
+   if (rc)
+   return rc;
+
+   rc = tpm_tis_init(udev);
+   if (rc)
+   return rc;
+
+   priv->pcr_count = drv_data->pcr_count;
+   priv->pcr_select_m

[PATCH 1/2] tpm: core: Set timeouts before requesting locality

2022-05-13 Thread Eddie James
Requesting the locality uses the timeout values, so they need
to be set beforehand.

Signed-off-by: Eddie James 
---
 drivers/tpm/tpm2_tis_core.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/tpm/tpm2_tis_core.c b/drivers/tpm/tpm2_tis_core.c
index 51392c4584..985a816219 100644
--- a/drivers/tpm/tpm2_tis_core.c
+++ b/drivers/tpm/tpm2_tis_core.c
@@ -433,15 +433,16 @@ int tpm_tis_init(struct udevice *dev)
log_err("Driver bug. No bus ops defined\n");
return -1;
}
-   ret = tpm_tis_request_locality(dev, 0);
-   if (ret)
-   return ret;
 
chip->timeout_a = TIS_SHORT_TIMEOUT_MS;
chip->timeout_b = TIS_LONG_TIMEOUT_MS;
chip->timeout_c = TIS_SHORT_TIMEOUT_MS;
chip->timeout_d = TIS_SHORT_TIMEOUT_MS;
 
+   ret = tpm_tis_request_locality(dev, 0);
+   if (ret)
+   return ret;
+
/* Disable interrupts */
phy_ops->read32(dev, TPM_INT_ENABLE(chip->locality), );
tmp |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT |
-- 
2.27.0



[PATCH 0/2] tpm: Add support for TPMv2.x I2C chips

2022-05-13 Thread Eddie James
Add a tpm driver that should support any TPMv2 compliant I2C chips,
such as the NPCT75X chip. In my testing I also noticed that the timeouts
weren't set before requesting the locality so I have included a fix.

Eddie James (2):
  tpm: core: Set timeouts before requesting locality
  tpm: add support for TPMv2.x I2C chips

 drivers/tpm/Kconfig |   9 ++
 drivers/tpm/Makefile|   1 +
 drivers/tpm/tpm2_tis_core.c |   7 +-
 drivers/tpm/tpm2_tis_i2c.c  | 171 
 4 files changed, 185 insertions(+), 3 deletions(-)
 create mode 100644 drivers/tpm/tpm2_tis_i2c.c

-- 
2.27.0



[PATCH] i2c: ast_i2c: Remove SCL direct drive mode

2022-05-11 Thread Eddie James
SCL direct drive mode prevents communication with devices that
do clock stretching, so disable. The Linux driver doesn't use
this mode, and the engine can handle clock stretching.

Signed-off-by: Eddie James 
---
 drivers/i2c/ast_i2c.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i2c/ast_i2c.c b/drivers/i2c/ast_i2c.c
index 2d3fecaa14..8b24a260c0 100644
--- a/drivers/i2c/ast_i2c.c
+++ b/drivers/i2c/ast_i2c.c
@@ -76,7 +76,7 @@ static void ast_i2c_init_bus(struct udevice *dev)
/* Enable Master Mode. Assuming single-master */
writel(I2CD_MASTER_EN
   | I2CD_M_SDA_LOCK_EN
-  | I2CD_MULTI_MASTER_DIS | I2CD_M_SCL_DRIVE_EN,
+  | I2CD_MULTI_MASTER_DIS,
   >regs->fcr);
/* Enable Interrupts */
writel(I2CD_INTR_TX_ACK
-- 
2.27.0



Re: [PATCH v2 5/5] test: Add sandbox TPM boot measurement

2023-01-10 Thread Eddie James



On 1/9/23 17:26, Heinrich Schuchardt wrote:

On 1/10/23 00:13, Heinrich Schuchardt wrote:

On 1/9/23 22:55, Eddie James wrote:

Use the sandbox TPM driver to measure some boot images in a unit
test case.

$ ./u-boot -T -c "ut measurement"
Running 1 measurement tests
Test: measure: measurement.c
Failures: 0

Signed-off-by: Eddie James 
---
  arch/sandbox/dts/test.dts | 12 +++
  configs/sandbox_defconfig |  1 +
  include/test/suites.h |  1 +
  test/boot/Makefile    |  1 +
  test/boot/measurement.c   | 66 
+++

  test/cmd_ut.c |  2 ++
  6 files changed, 83 insertions(+)
  create mode 100644 test/boot/measurement.c

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index dffe10adbf..ad90bf0541 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -66,6 +66,17 @@
  osd0 = "/osd";
  };

+    reserved-memory {
+    #address-cells = <1>;
+    #size-cells = <1>;
+    ranges;
+
+    event_log: tcg_event_log@d0e000 {
+    no-map;
+    reg = <0x00d0e000 0x2000>;


How should this work if you don't define linux,sml-base and 
linux,sml-size?



I have sent a patch to the linux list for using a reserved memory 
region, as I have also added in the u-boot TPM layer for the event log.


https://patchwork.kernel.org/project/linux-integrity/patch/20230103162010.381214-1-eaja...@linux.ibm.com/


Thanks,

Eddie




Best regards

Heinrich



This would limit the file loaded at $loadaddr = 0x0 to 13 MiB. Please,
choose a much higher address. Or change $loadaddr, e.g. use loadaddr =
kernel_addr_r = 0x100. I would prefer raising loadaddr.

Best regards

Heinrich


+    };
+    };
+
  binman: binman {
  };

@@ -1332,6 +1343,7 @@

  tpm2 {
  compatible = "sandbox,tpm2";
+    memory-region = <_log>;
  };

  uart0: serial {
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index de799b5cea..5ac115f2d8 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -335,3 +335,4 @@ CONFIG_TEST_FDTDEC=y
  CONFIG_UNIT_TEST=y
  CONFIG_UT_TIME=y
  CONFIG_UT_DM=y
+CONFIG_MEASURED_BOOT=y
diff --git a/include/test/suites.h b/include/test/suites.h
index a01000e127..f9284871b0 100644
--- a/include/test/suites.h
+++ b/include/test/suites.h
@@ -43,6 +43,7 @@ int do_ut_font(struct cmd_tbl *cmdtp, int flag, int
argc, char *const argv[]);
  int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const
argv[]);
  int do_ut_loadm(struct cmd_tbl *cmdtp, int flag, int argc, char
*const argv[]);
  int do_ut_log(struct cmd_tbl *cmdtp, int flag, int argc, char *
const argv[]);
+int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc, char
* const argv[]);
  int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const
argv[]);
  int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char
*const argv[]);
  int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc,
diff --git a/test/boot/Makefile b/test/boot/Makefile
index d724629d3b..24cc20bdff 100644
--- a/test/boot/Makefile
+++ b/test/boot/Makefile
@@ -4,6 +4,7 @@

  obj-$(CONFIG_BOOTSTD) += bootdev.o bootstd_common.o bootflow.o
bootmeth.o
  obj-$(CONFIG_FIT) += image.o
+obj-$(CONFIG_MEASURED_BOOT) += measurement.o

  ifdef CONFIG_OF_LIVE
  obj-$(CONFIG_BOOTMETH_VBE_SIMPLE) += vbe_simple.o
diff --git a/test/boot/measurement.c b/test/boot/measurement.c
new file mode 100644
index 00..2155208894
--- /dev/null
+++ b/test/boot/measurement.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test for measured boot functions
+ *
+ * Copyright 2023 IBM Corp.
+ * Written by Eddie James 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MEASUREMENT_TEST(_name, _flags)    \
+    UNIT_TEST(_name, _flags, measurement_test)
+
+static int measure(struct unit_test_state *uts)
+{
+    struct bootm_headers images;
+    const size_t size = 1024;
+    u8 *kernel;
+    u8 *initrd;
+    size_t i;
+
+    kernel = malloc(size);
+    initrd = malloc(size);
+
+    images.os.image_start = map_to_sysmem(kernel);
+    images.os.image_len = size;
+
+    images.rd_start = map_to_sysmem(initrd);
+    images.rd_end = images.rd_start + size;
+
+    images.ft_addr = malloc(size);
+    images.ft_len = size;
+
+    env_set("bootargs", "measurement testing");
+
+    for (i = 0; i < size; ++i) {
+    kernel[i] = (u8)(0xf0 | (i & 0xf));
+    initrd[i] = (u8)((i & 0xf0) | 0xf);
+    ((u8 *)images.ft_addr)[i] = (u8)(i & 0xff);
+    }
+
+    ut_assertok(bootm_measure());
+
+    free(images.ft_addr);
+    free(initrd);
+    free(kernel);
+
+    return 0;
+}
+MEASUREMENT_TEST(measure, 0);
+
+int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc,
+  char *const argv[])
+{
+    struct unit_test *tests = UNIT_TEST_SUIT

Re: [PATCH v2 0/5] tpm: Support boot measurements

2023-01-10 Thread Eddie James



On 1/9/23 17:35, Heinrich Schuchardt wrote:

On 1/9/23 22:55, Eddie James wrote:

This series adds support for measuring the boot images more generically
than the existing EFI support. Several EFI functions have been moved to
the TPM layer. The series includes optional measurement from the bootm
command.
A new test case has been added for the bootm measurement to test the new
path, and the sandbox TPM2 driver has been updated to support this use
case.

Changes since v1:
  - Refactor TPM layer functions to allow EFI system to use them, and
    remove duplicate EFI functions.
  - Add test case
  - Drop #ifdefs for bootm
  - Add devicetree measurement config option
  - Update sandbox TPM driver


This looks like a useful feature to me. Some questions remain:

How about the booti and bootz commands. Are they covered by the change?



No, not yet.




What are the consequences of your changes for UEFI FIT images (cf.
CONFIG_BOOTM_EFI)?



I suppose the image would be measured twice, but only if the user 
selected both of the relevant config options.







Eddie James (5):
   tpm: Fix spelling for tpmu_ha union
   tpm: Support boot measurements
   bootm: Support boot measurement
   tpm: sandbox: Update for needed TPM2 capabilities
   test: Add sandbox TPM boot measurement


I am missing the documentation changes. These should describe which
changes in the device-tree and in the configuration are needed to enable
measurements. This should be in doc/usage/



Sure.

Thanks,

Eddie




@Ilias:
Could you contribute the UEFI part for the document, please.

Best regards

Heinrich



  arch/sandbox/dts/test.dts  |  12 +
  boot/Kconfig   |  23 ++
  boot/bootm.c   |  64 +++
  cmd/bootm.c    |   2 +
  configs/sandbox_defconfig  |   1 +
  drivers/tpm/tpm2_tis_sandbox.c | 100 +++--
  include/bootm.h    |   2 +
  include/efi_tcg2.h |  44 --
  include/image.h    |   1 +
  include/test/suites.h  |   1 +
  include/tpm-v2.h   | 215 +-
  lib/efi_loader/efi_tcg2.c  | 362 +
  lib/tpm-v2.c   | 708 +
  test/boot/Makefile |   1 +
  test/boot/measurement.c    |  66 +++
  test/cmd_ut.c  |   2 +
  16 files changed, 1187 insertions(+), 417 deletions(-)
  create mode 100644 test/boot/measurement.c





Re: [PATCH v2 5/5] test: Add sandbox TPM boot measurement

2023-01-10 Thread Eddie James



On 1/10/23 16:02, Heinrich Schuchardt wrote:

On 1/10/23 17:38, Eddie James wrote:


On 1/9/23 17:26, Heinrich Schuchardt wrote:

On 1/10/23 00:13, Heinrich Schuchardt wrote:

On 1/9/23 22:55, Eddie James wrote:

Use the sandbox TPM driver to measure some boot images in a unit
test case.

$ ./u-boot -T -c "ut measurement"
Running 1 measurement tests
Test: measure: measurement.c
Failures: 0

Signed-off-by: Eddie James 
---
  arch/sandbox/dts/test.dts | 12 +++
  configs/sandbox_defconfig |  1 +
  include/test/suites.h |  1 +
  test/boot/Makefile    |  1 +
  test/boot/measurement.c   | 66
+++
  test/cmd_ut.c |  2 ++
  6 files changed, 83 insertions(+)
  create mode 100644 test/boot/measurement.c

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index dffe10adbf..ad90bf0541 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -66,6 +66,17 @@
  osd0 = "/osd";
  };

+    reserved-memory {
+    #address-cells = <1>;
+    #size-cells = <1>;
+    ranges;
+
+    event_log: tcg_event_log@d0e000 {
+    no-map;
+    reg = <0x00d0e000 0x2000>;


How should this work if you don't define linux,sml-base and
linux,sml-size?



I have sent a patch to the linux list for using a reserved memory
region, as I have also added in the u-boot TPM layer for the event log.

https://patchwork.kernel.org/project/linux-integrity/patch/20230103162010.381214-1-eaja...@linux.ibm.com/ 



Thank you for the clarification.

The kernel patch seems to need rework:
https://lore.kernel.org/all/202301040834.ysmhdmpw-...@intel.com/



Yes I'll address that.




Shouldn't the sandbox device-tree support these properties? This will
allow us to write a test application that the sandbox can run via
booti/bootz (depending on bitness) and bootm. This test application can
retrieve the event log and print it via Linux system calls.



OK, I can add it to the main sandbox device-tree as well then. It is 
added to the sandbox test device-tree, used by the unit test case I added.



Thanks,

Eddie




Best regards

Heinrich


Re: [PATCH 3/3] bootm: Support boot measurement

2023-01-04 Thread Eddie James



On 1/4/23 03:56, Etienne Carriere wrote:

Hello Eddie and all,

On Tue, 3 Jan 2023 at 21:42, Eddie James  wrote:

Add a configuration option to measure the boot through the bootm
function.

Signed-off-by: Eddie James 
---
  boot/bootm.c| 53 +
  cmd/bootm.c |  2 ++
  common/Kconfig  |  6 ++
  include/image.h |  1 +
  4 files changed, 62 insertions(+)

diff --git a/boot/bootm.c b/boot/bootm.c
index a4c0870c0f..7f64d79035 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -22,6 +22,9 @@
  #include 
  #include 
  #include 
+#if defined(CONFIG_MEASURED_BOOT)
+#include 
+#endif
  #if defined(CONFIG_CMD_USB)
  #include 
  #endif
@@ -713,6 +716,56 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int 
argc,
 if (!ret && (states & BOOTM_STATE_FINDOTHER))
 ret = bootm_find_other(cmdtp, flag, argc, argv);

+#if defined(CONFIG_MEASURED_BOOT)
+   if (!ret && (states & BOOTM_STATE_MEASURE)) {
+   void *initrd_buf;
+   void *image_buf;
+   const char *s;
+   u32 rd_len;
+
+   ret = tcg2_measurement_init();
+   if (ret)
+   goto measure_err;
+
+   image_buf = map_sysmem(images->os.image_start,
+  images->os.image_len);
+   ret = tcg2_measure_data(8, images->os.image_len, image_buf,
+   EV_COMPACT_HASH, strlen("linux") + 1,
+   (u8 *)"linux");
+   if (ret)
+   goto unmap_image;
+
+   rd_len = images->rd_end - images->rd_start;
+   initrd_buf = map_sysmem(images->rd_start, rd_len);
+   ret = tcg2_measure_data(8, rd_len, initrd_buf, EV_COMPACT_HASH,
+   strlen("initrd") + 1, (u8 *)"initrd");
+   if (ret)
+   goto unmap_initrd;
+
+   ret = tcg2_measure_data(9, images->ft_len,
+   (u8 *)images->ft_addr,
+   EV_TABLE_OF_DEVICES, strlen("dts") + 1,
+   (u8 *)"dts");

This unconditionally measures DTB content but maybe there are
information that may differ at each boot as a random MAC address or an
ASLR seed.
Do you think something should condition measurement of the passed DTB
as proposed using a config switch in [1]?

[1] 
https://lore.kernel.org/all/20221207151110.529106-1-etienne.carri...@linaro.org/



That would make sense, I am happy to add that in v2. Should I use that 
config switch as-is or add a new one for the bootm measurement?


Thanks

Eddie




Regards,
Etienne


+   if (ret)
+   goto unmap_initrd;
+
+   s = env_get("bootargs");
+   if (!s)
+   s = "";
+   tcg2_measure_data(1, strlen(s) + 1, (u8 *)s,
+ EV_PLATFORM_CONFIG_FLAGS, strlen(s) + 1,
+ (u8 *)s);
+
+unmap_initrd:
+   unmap_sysmem(initrd_buf);
+unmap_image:
+   unmap_sysmem(image_buf);
+   tcg2_measurement_term();
+measure_err:
+   ret = 0;
+   }
+#endif
+
 /* Load the OS */
 if (!ret && (states & BOOTM_STATE_LOADOS)) {
 iflag = bootm_disable_interrupts();
diff --git a/cmd/bootm.c b/cmd/bootm.c
index 37c2af96e0..0c4a713e02 100644
--- a/cmd/bootm.c
+++ b/cmd/bootm.c
@@ -161,6 +161,8 @@ int do_bootm(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[])
 BOOTM_STATE_OS_GO;
 if (IS_ENABLED(CONFIG_SYS_BOOT_RAMDISK_HIGH))
 states |= BOOTM_STATE_RAMDISK;
+   if (IS_ENABLED(CONFIG_MEASURED_BOOT))
+   states |= BOOTM_STATE_MEASURE;
 if (IS_ENABLED(CONFIG_PPC) || IS_ENABLED(CONFIG_MIPS))
 states |= BOOTM_STATE_OS_CMDLINE;
 ret = do_bootm_states(cmdtp, flag, argc, argv, states, , 1);
diff --git a/common/Kconfig b/common/Kconfig
index 21434c5cf1..57ef68e4f3 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -799,6 +799,12 @@ config AVB_BUF_SIZE

  endif # AVB_VERIFY

+config MEASURED_BOOT
+   bool "Measure the boot to TPM and event log"
+   depends on HASH && TPM_V2
+   help
+ This option enables measurement of the boot process.
+
  config SCP03
 bool "Build SCP03 - Secure Channel Protocol O3 - controls"
 depends on OPTEE || SANDBOX
diff --git a/include/image.h b/include/image.h
index 6f21dafba8..b00803eeac 100644
--- a/include/image.h
+++ b/include/image.h
@@ -406,6 +406,7 @@ struct bootm_headers {
  #define BOOTM_STATE_OS_FAKE_GO 0x0200  /* 'Almost' run the

Re: [PATCH 0/3] tpm: Support boot measurements

2023-01-04 Thread Eddie James



On 1/4/23 01:47, Ilias Apalodimas wrote:

Hi Eddie,
Thanks for the patch

Looking at the patch there's a lot of code duplication with
lib/efi_loader/efi_tcg2.c.
Any reason why we aren't reusing that ?



Hi,

Well the EFI code can't be used directly without configuring to include 
the EFI subsystem and exporting a bunch of those functions in a header 
file somewhere, so I added the functions in the generic tpm librrary. 
Now it's a matter of doing the work to use the generic functions in the 
EFI system. I can do that in this series if necesssary, I just haven't 
gotten to it.


Thanks,

Eddie




Regards
/Ilias

On Tue, 3 Jan 2023 at 22:42, Eddie James  wrote:

This series adds support for measuring the boot images more generically
than the existing EFI support. The series includes optional measurement
from the bootm command.
Eventually the EFI code could be refactored to use the generic functions.

Eddie James (3):
   tpm: Fix spelling for tpmu_ha union
   tpm: Support boot measurements
   bootm: Support boot measurement

  boot/bootm.c   |  53 
  cmd/bootm.c|   2 +
  common/Kconfig |   6 +
  include/efi_tcg2.h |  44 ---
  include/image.h|   1 +
  include/tpm-v2.h   | 139 -
  lib/tpm-v2.c   | 700 +
  7 files changed, 899 insertions(+), 46 deletions(-)

--
2.31.1



[PATCH v3 1/6] tpm: Fix spelling for tpmu_ha union

2023-01-12 Thread Eddie James
tmpu -> tpmu

Signed-off-by: Eddie James 
Reviewed-by: Ilias Apalodimas 
---
 include/tpm-v2.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 737e57551d..85feda3e06 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -167,7 +167,7 @@ struct tcg_pcr_event {
 /**
  * Definition of TPMU_HA Union
  */
-union tmpu_ha {
+union tpmu_ha {
u8 sha1[TPM2_SHA1_DIGEST_SIZE];
u8 sha256[TPM2_SHA256_DIGEST_SIZE];
u8 sm3_256[TPM2_SM3_256_DIGEST_SIZE];
@@ -183,7 +183,7 @@ union tmpu_ha {
  */
 struct tpmt_ha {
u16 hash_alg;
-   union tmpu_ha digest;
+   union tpmu_ha digest;
 } __packed;
 
 /**
-- 
2.31.1



[PATCH v3 6/6] doc: Add measured boot documentation

2023-01-12 Thread Eddie James
Briefly describe the feature and specify the requirements.

Signed-off-by: Eddie James 
---
 doc/usage/index.rst |  1 +
 doc/usage/measured_boot.rst | 23 +++
 2 files changed, 24 insertions(+)
 create mode 100644 doc/usage/measured_boot.rst

diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index bbd40a6e18..cf2cd81966 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -12,6 +12,7 @@ Use U-Boot
partitions
cmdline
semihosting
+   measured_boot
 
 Shell commands
 --
diff --git a/doc/usage/measured_boot.rst b/doc/usage/measured_boot.rst
new file mode 100644
index 00..13fd42a2fb
--- /dev/null
+++ b/doc/usage/measured_boot.rst
@@ -0,0 +1,23 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Measured Boot
+=
+
+U-Boot can perform a measured boot, the process of hashing various components
+of the boot process, extending the results in the TPM and logging the
+component's measurement in memory for the operating system to consume.
+
+Requirements
+-
+
+A hardware TPM 2.0 supported by the U-Boot drivers
+CONFIG_TPM=y
+CONFIG_MEASURED_BOOT=y
+Device-tree configuration of the TPM device to specify the memory area
+for event logging. The TPM device node must either contain a phandle to
+a reserved memory region or "linux,sml-base" and "linux,sml-size"
+indicating the address and size of the memory region. An example can be
+found in arch/sandbox/dts/test.dts
+The operating system must also be configured to use the memory regions
+specified in the U-Boot device-tree in order to make use of the event
+log.
-- 
2.31.1



[PATCH v3 3/6] bootm: Support boot measurement

2023-01-12 Thread Eddie James
Add a configuration option to measure the boot through the bootm
function. Add the measurement state to the booti and bootz paths
as well.

Signed-off-by: Eddie James 
---
 boot/Kconfig| 23 
 boot/bootm.c| 70 +
 cmd/booti.c |  1 +
 cmd/bootm.c |  2 ++
 cmd/bootz.c |  1 +
 include/bootm.h |  2 ++
 include/image.h |  1 +
 7 files changed, 100 insertions(+)

diff --git a/boot/Kconfig b/boot/Kconfig
index 30bc182fcd..e90d61412e 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -587,6 +587,29 @@ config LEGACY_IMAGE_FORMAT
  loaded. If a board needs the legacy image format support in this
  case, enable it here.
 
+config MEASURED_BOOT
+   bool "Measure boot images and configuration to TPM and event log"
+   depends on HASH && TPM_V2
+   help
+ This option enables measurement of the boot process. Measurement
+ involves creating cryptographic hashes of the binary images that
+ are booting and storing them in the TPM. In addition, a log of
+ these hashes is stored in memory for the OS to verify the booted
+ images and configuration. Enable this if the OS has configured
+ some memory area for the event log and you intend to use some
+ attestation tools on your system.
+
+if MEASURED_BOOT
+   config MEASURE_DEVICETREE
+   bool "Measure the devicetree image"
+   default y if MEASURED_BOOT
+   help
+ On some platforms, the devicetree is not static as it may contain
+ random MAC addresses or other such data that changes each boot.
+ Therefore, it should not be measured into the TPM. In that case,
+ disable the measurement here.
+endif # MEASURED_BOOT
+
 config SUPPORT_RAW_INITRD
bool "Enable raw initrd images"
help
diff --git a/boot/bootm.c b/boot/bootm.c
index 15fce8ad95..c8423f2c60 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #if defined(CONFIG_CMD_USB)
 #include 
 #endif
@@ -659,6 +660,72 @@ int bootm_process_cmdline_env(int flags)
return 0;
 }
 
+int bootm_measure(struct bootm_headers *images)
+{
+   int ret = 0;
+
+   /* Skip measurement if EFI is going to do it */
+   if (images->os.os == IH_OS_EFI &&
+   IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL) &&
+   IS_ENABLED(CONFIG_BOOTM_EFI))
+   return ret;
+
+   if (IS_ENABLED(CONFIG_MEASURED_BOOT)) {
+   struct tcg2_event_log elog;
+   struct udevice *dev;
+   void *initrd_buf;
+   void *image_buf;
+   const char *s;
+   u32 rd_len;
+
+   ret = tcg2_measurement_init(, );
+   if (ret)
+   return ret;
+
+   image_buf = map_sysmem(images->os.image_start,
+  images->os.image_len);
+   ret = tcg2_measure_data(dev, , 8, images->os.image_len,
+   image_buf, EV_COMPACT_HASH,
+   strlen("linux") + 1, (u8 *)"linux");
+   if (ret)
+   goto unmap_image;
+
+   rd_len = images->rd_end - images->rd_start;
+   initrd_buf = map_sysmem(images->rd_start, rd_len);
+   ret = tcg2_measure_data(dev, , 8, rd_len, initrd_buf,
+   EV_COMPACT_HASH, strlen("initrd") + 1,
+   (u8 *)"initrd");
+   if (ret)
+   goto unmap_initrd;
+
+   if (IS_ENABLED(CONFIG_MEASURE_DEVICETREE)) {
+   ret = tcg2_measure_data(dev, , 9, images->ft_len,
+   (u8 *)images->ft_addr,
+   EV_TABLE_OF_DEVICES,
+   strlen("dts") + 1,
+   (u8 *)"dts");
+   if (ret)
+   goto unmap_initrd;
+   }
+
+   s = env_get("bootargs");
+   if (!s)
+   s = "";
+   ret = tcg2_measure_data(dev, , 1, strlen(s) + 1, (u8 *)s,
+   EV_PLATFORM_CONFIG_FLAGS,
+   strlen(s) + 1, (u8 *)s);
+
+unmap_initrd:
+   unmap_sysmem(initrd_buf);
+
+unmap_image:
+   unmap_sysmem(image_buf);
+   tcg2_measurement_term(dev, , ret != 0);
+   }
+
+   return ret;
+}
+
 /**
  * Execute selected states of the bootm command.
  *
@@ -710,6 +777,9 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int 
argc,
if (!ret &&

[PATCH v3 5/6] test: Add sandbox TPM boot measurement

2023-01-12 Thread Eddie James
Use the sandbox TPM driver to measure some boot images in a unit
test case.

Signed-off-by: Eddie James 
---
 arch/sandbox/dts/sandbox.dtsi | 14 
 arch/sandbox/dts/test.dts | 13 +++
 configs/sandbox_defconfig |  1 +
 include/test/suites.h |  1 +
 test/boot/Makefile|  1 +
 test/boot/measurement.c   | 66 +++
 test/cmd_ut.c |  2 ++
 7 files changed, 98 insertions(+)
 create mode 100644 test/boot/measurement.c

diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index afe598a4f5..eb9df8f4e3 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -4,9 +4,22 @@
  * and sandbox64 builds.
  */
 
+#include 
+
 #define USB_CLASS_HUB  9
 
 / {
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   event_log: tcg_event_log {
+   no-map;
+   reg = <(CFG_SYS_SDRAM_SIZE - 0x2000) 0x2000>;
+   };
+   };
+
binman {
};
 
@@ -345,6 +358,7 @@
 
tpm2 {
compatible = "sandbox,tpm2";
+   memory-region = <_log>;
};
 
triangle {
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index dffe10adbf..920d4de140 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -9,6 +9,7 @@
 
 /dts-v1/;
 
+#include 
 #include 
 #include 
 #include 
@@ -66,6 +67,17 @@
osd0 = "/osd";
};
 
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   event_log: tcg_event_log {
+   no-map;
+   reg = <(CFG_SYS_SDRAM_SIZE - 0x2000) 0x2000>;
+   };
+   };
+
binman: binman {
};
 
@@ -1332,6 +1344,7 @@
 
tpm2 {
compatible = "sandbox,tpm2";
+   memory-region = <_log>;
};
 
uart0: serial {
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index de799b5cea..5ac115f2d8 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -335,3 +335,4 @@ CONFIG_TEST_FDTDEC=y
 CONFIG_UNIT_TEST=y
 CONFIG_UT_TIME=y
 CONFIG_UT_DM=y
+CONFIG_MEASURED_BOOT=y
diff --git a/include/test/suites.h b/include/test/suites.h
index 9ce49cbb03..4c284bbeaa 100644
--- a/include/test/suites.h
+++ b/include/test/suites.h
@@ -44,6 +44,7 @@ int do_ut_font(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[]);
 int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_loadm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_log(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]);
+int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc, char * const 
argv[]);
 int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc,
diff --git a/test/boot/Makefile b/test/boot/Makefile
index d724629d3b..24cc20bdff 100644
--- a/test/boot/Makefile
+++ b/test/boot/Makefile
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_BOOTSTD) += bootdev.o bootstd_common.o bootflow.o bootmeth.o
 obj-$(CONFIG_FIT) += image.o
+obj-$(CONFIG_MEASURED_BOOT) += measurement.o
 
 ifdef CONFIG_OF_LIVE
 obj-$(CONFIG_BOOTMETH_VBE_SIMPLE) += vbe_simple.o
diff --git a/test/boot/measurement.c b/test/boot/measurement.c
new file mode 100644
index 00..2155208894
--- /dev/null
+++ b/test/boot/measurement.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test for measured boot functions
+ *
+ * Copyright 2023 IBM Corp.
+ * Written by Eddie James 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MEASUREMENT_TEST(_name, _flags)\
+   UNIT_TEST(_name, _flags, measurement_test)
+
+static int measure(struct unit_test_state *uts)
+{
+   struct bootm_headers images;
+   const size_t size = 1024;
+   u8 *kernel;
+   u8 *initrd;
+   size_t i;
+
+   kernel = malloc(size);
+   initrd = malloc(size);
+
+   images.os.image_start = map_to_sysmem(kernel);
+   images.os.image_len = size;
+
+   images.rd_start = map_to_sysmem(initrd);
+   images.rd_end = images.rd_start + size;
+
+   images.ft_addr = malloc(size);
+   images.ft_len = size;
+
+   env_set("bootargs", "measurement testing");
+
+   for (i = 0; i < size; ++i) {
+   kernel[i] = (u8)(0xf0 | (i & 0xf));
+   initrd[i] = (u8)((i & 0xf0) | 0xf);
+   ((u8 *)images.ft_addr)[i] = (u8)(i & 0xff);
+   }
+
+   ut_assertok(bootm_measure());
+
+

[PATCH v3 4/6] tpm: sandbox: Update for needed TPM2 capabilities

2023-01-12 Thread Eddie James
The driver needs to support getting the PCRs in the capabilities
command. Fix various other things and support the max number
of PCRs for TPM2.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
---
 drivers/tpm/tpm2_tis_sandbox.c | 100 -
 1 file changed, 72 insertions(+), 28 deletions(-)

diff --git a/drivers/tpm/tpm2_tis_sandbox.c b/drivers/tpm/tpm2_tis_sandbox.c
index dd94bdc31f..ea7fb5e3cb 100644
--- a/drivers/tpm/tpm2_tis_sandbox.c
+++ b/drivers/tpm/tpm2_tis_sandbox.c
@@ -22,11 +22,6 @@ enum tpm2_hierarchy {
TPM2_HIERARCHY_NB,
 };
 
-/* Subset of supported capabilities */
-enum tpm2_capability {
-   TPM_CAP_TPM_PROPERTIES = 0x6,
-};
-
 /* Subset of supported properties */
 #define TPM2_PROPERTIES_OFFSET 0x020E
 
@@ -38,7 +33,8 @@ enum tpm2_cap_tpm_property {
TPM2_PROPERTY_NB,
 };
 
-#define SANDBOX_TPM_PCR_NB 1
+#define SANDBOX_TPM_PCR_NB TPM2_MAX_PCRS
+#define SANDBOX_TPM_PCR_SELECT_MAX ((SANDBOX_TPM_PCR_NB + 7) / 8)
 
 /*
  * Information about our TPM emulation. This is preserved in the sandbox
@@ -433,7 +429,7 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const u8 
*sendbuf,
int i, j;
 
/* TPM2_GetProperty */
-   u32 capability, property, property_count;
+   u32 capability, property, property_count, val;
 
/* TPM2_PCR_Read/Extend variables */
int pcr_index = 0;
@@ -542,19 +538,32 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const 
u8 *sendbuf,
case TPM2_CC_GET_CAPABILITY:
capability = get_unaligned_be32(sent);
sent += sizeof(capability);
-   if (capability != TPM_CAP_TPM_PROPERTIES) {
-   printf("Sandbox TPM only support TPM_CAPABILITIES\n");
-   return TPM2_RC_HANDLE;
-   }
-
property = get_unaligned_be32(sent);
sent += sizeof(property);
-   property -= TPM2_PROPERTIES_OFFSET;
-
property_count = get_unaligned_be32(sent);
sent += sizeof(property_count);
-   if (!property_count ||
-   property + property_count > TPM2_PROPERTY_NB) {
+
+   switch (capability) {
+   case TPM2_CAP_PCRS:
+   break;
+   case TPM2_CAP_TPM_PROPERTIES:
+   if (!property_count) {
+   rc = TPM2_RC_HANDLE;
+   return sandbox_tpm2_fill_buf(recv, recv_len,
+tag, rc);
+   }
+
+   if (property > TPM2_PROPERTIES_OFFSET &&
+   ((property - TPM2_PROPERTIES_OFFSET) +
+property_count > TPM2_PROPERTY_NB)) {
+   rc = TPM2_RC_HANDLE;
+   return sandbox_tpm2_fill_buf(recv, recv_len,
+tag, rc);
+   }
+   break;
+   default:
+   printf("Sandbox TPM2 only supports TPM2_CAP_PCRS or "
+  "TPM2_CAP_TPM_PROPERTIES\n");
rc = TPM2_RC_HANDLE;
return sandbox_tpm2_fill_buf(recv, recv_len, tag, rc);
}
@@ -578,18 +587,53 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const 
u8 *sendbuf,
put_unaligned_be32(capability, recv);
recv += sizeof(capability);
 
-   /* Give the number of properties that follow */
-   put_unaligned_be32(property_count, recv);
-   recv += sizeof(property_count);
-
-   /* Fill with the properties */
-   for (i = 0; i < property_count; i++) {
-   put_unaligned_be32(TPM2_PROPERTIES_OFFSET + property +
-  i, recv);
-   recv += sizeof(property);
-   put_unaligned_be32(tpm->properties[property + i],
-  recv);
-   recv += sizeof(property);
+   switch (capability) {
+   case TPM2_CAP_PCRS:
+   /* Give the number of algorithms supported - just 
SHA256 */
+   put_unaligned_be32(1, recv);
+   recv += sizeof(u32);
+
+   /* Give SHA256 algorithm */
+   put_unaligned_be16(TPM2_ALG_SHA256, recv);
+   recv += sizeof(u16);
+
+   /* Select the PCRs supported */
+   *recv = SANDBOX_TPM_PCR_SELECT_MAX;
+   recv++;
+
+   /* Activate all the PCR bits */
+   for (i = 0; i < SANDBOX_TPM_PCR_SELECT_

[PATCH v3 0/6] tpm: Support boot measurements

2023-01-12 Thread Eddie James
This series adds support for measuring the boot images more generically
than the existing EFI support. Several EFI functions have been moved to
the TPM layer. The series includes optional measurement from the bootm 
command.
A new test case has been added for the bootm measurement to test the new
path, and the sandbox TPM2 driver has been updated to support this use
case.

Changes since v2:
 - Add documentation.
 - Changed reserved memory address to the top of the RAM for sandbox dts.
 - Add measure state to booti and bootz.
 - Skip measurement for EFI images that should be measured

Changes since v1:
 - Refactor TPM layer functions to allow EFI system to use them, and
   remove duplicate EFI functions.
 - Add test case
 - Drop #ifdefs for bootm
 - Add devicetree measurement config option
 - Update sandbox TPM driver

Eddie James (6):
  tpm: Fix spelling for tpmu_ha union
  tpm: Support boot measurements
  bootm: Support boot measurement
  tpm: sandbox: Update for needed TPM2 capabilities
  test: Add sandbox TPM boot measurement
  doc: Add measured boot documentation

 arch/sandbox/dts/sandbox.dtsi  |  14 +
 arch/sandbox/dts/test.dts  |  13 +
 boot/Kconfig   |  23 ++
 boot/bootm.c   |  70 
 cmd/booti.c|   1 +
 cmd/bootm.c|   2 +
 cmd/bootz.c|   1 +
 configs/sandbox_defconfig  |   1 +
 doc/usage/index.rst|   1 +
 doc/usage/measured_boot.rst|  23 ++
 drivers/tpm/tpm2_tis_sandbox.c | 100 +++--
 include/bootm.h|   2 +
 include/efi_tcg2.h |  44 --
 include/image.h|   1 +
 include/test/suites.h  |   1 +
 include/tpm-v2.h   | 215 +-
 lib/efi_loader/efi_tcg2.c  | 362 +
 lib/tpm-v2.c   | 708 +
 test/boot/Makefile |   1 +
 test/boot/measurement.c|  66 +++
 test/cmd_ut.c  |   2 +
 21 files changed, 1234 insertions(+), 417 deletions(-)
 create mode 100644 doc/usage/measured_boot.rst
 create mode 100644 test/boot/measurement.c

-- 
2.31.1



[PATCH v3 2/6] tpm: Support boot measurements

2023-01-12 Thread Eddie James
Add TPM2 functions to support boot measurement. This includes
starting up the TPM, initializing/appending the event log, and
measuring the U-Boot version. Much of the code was used in the
EFI subsystem, so remove it there and use the common functions.

Signed-off-by: Eddie James 
---
 include/efi_tcg2.h|  44 ---
 include/tpm-v2.h  | 211 
 lib/efi_loader/efi_tcg2.c | 362 +--
 lib/tpm-v2.c  | 708 ++
 4 files changed, 938 insertions(+), 387 deletions(-)

diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
index 874306dc11..23016773f4 100644
--- a/include/efi_tcg2.h
+++ b/include/efi_tcg2.h
@@ -129,50 +129,6 @@ struct efi_tcg2_boot_service_capability {
 #define BOOT_SERVICE_CAPABILITY_MIN \
offsetof(struct efi_tcg2_boot_service_capability, number_of_pcr_banks)
 
-#define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03"
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2
-
-/**
- *  struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm information
- *
- *  @algorithm_id: algorithm defined in enum tpm2_algorithms
- *  @digest_size:  size of the algorithm
- */
-struct tcg_efi_spec_id_event_algorithm_size {
-   u16  algorithm_id;
-   u16  digest_size;
-} __packed;
-
-/**
- * struct TCG_EfiSpecIDEventStruct - content of the event log header
- *
- * @signature: signature, set to Spec ID Event03
- * @platform_class:class defined in TCG ACPI Specification
- * Client  Common Header.
- * @spec_version_minor:minor version
- * @spec_version_major:major version
- * @spec_version_errata:   major version
- * @uintn_size:size of the efi_uintn_t fields used in 
various
- * data structures used in this specification.
- * 0x01 indicates u32  and 0x02  indicates u64
- * @number_of_algorithms:  hashing algorithms used in this event log
- * @digest_sizes:  array of number_of_algorithms pairs
- * 1st member defines the algorithm id
- * 2nd member defines the algorithm size
- */
-struct tcg_efi_spec_id_event {
-   u8 signature[16];
-   u32 platform_class;
-   u8 spec_version_minor;
-   u8 spec_version_major;
-   u8 spec_errata;
-   u8 uintn_size;
-   u32 number_of_algorithms;
-   struct tcg_efi_spec_id_event_algorithm_size digest_sizes[];
-} __packed;
-
 /**
  * struct tdEFI_TCG2_FINAL_EVENTS_TABLE - log entries after Get Event Log
  * @version:   version number for this structure
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 85feda3e06..e3db3419dd 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -214,6 +214,50 @@ struct tcg_pcr_event2 {
u8 event[];
 } __packed;
 
+/**
+ *  struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm information
+ *
+ *  @algorithm_id: algorithm defined in enum tpm2_algorithms
+ *  @digest_size:  size of the algorithm
+ */
+struct tcg_efi_spec_id_event_algorithm_size {
+   u16  algorithm_id;
+   u16  digest_size;
+} __packed;
+
+#define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03"
+#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2
+#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0
+#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2
+
+/**
+ * struct TCG_EfiSpecIDEventStruct - content of the event log header
+ *
+ * @signature: signature, set to Spec ID Event03
+ * @platform_class:class defined in TCG ACPI Specification
+ * Client  Common Header.
+ * @spec_version_minor:minor version
+ * @spec_version_major:major version
+ * @spec_version_errata:   major version
+ * @uintn_size:size of the efi_uintn_t fields used in 
various
+ * data structures used in this specification.
+ * 0x01 indicates u32  and 0x02  indicates u64
+ * @number_of_algorithms:  hashing algorithms used in this event log
+ * @digest_sizes:  array of number_of_algorithms pairs
+ * 1st member defines the algorithm id
+ * 2nd member defines the algorithm size
+ */
+struct tcg_efi_spec_id_event {
+   u8 signature[16];
+   u32 platform_class;
+   u8 spec_version_minor;
+   u8 spec_version_major;
+   u8 spec_errata;
+   u8 uintn_size;
+   u32 number_of_algorithms;
+   struct tcg_efi_spec_id_event_algorithm_size digest_sizes[];
+} __packed;
+
 /**
  * TPM2 Structure Tags for command/response buffers.
  *
@@ -340,6 +384,24 @@ enum tpm2_algorithms {

Re: [PATCH v3 2/6] tpm: Support boot measurements

2023-01-13 Thread Eddie James



On 1/12/23 17:43, Simon Glass wrote:

Hi Eddie,

On Thu, 12 Jan 2023 at 09:16, Eddie James  wrote:

Add TPM2 functions to support boot measurement. This includes
starting up the TPM, initializing/appending the event log, and
measuring the U-Boot version. Much of the code was used in the
EFI subsystem, so remove it there and use the common functions.

Signed-off-by: Eddie James 
---
  include/efi_tcg2.h|  44 ---
  include/tpm-v2.h  | 211 
  lib/efi_loader/efi_tcg2.c | 362 +--
  lib/tpm-v2.c  | 708 ++
  4 files changed, 938 insertions(+), 387 deletions(-)

[..]


diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index 697b982e07..00e1b04d74 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -4,13 +4,597 @@
   * Author: Miquel Raynal 
   */

+#include 
+#include 

Please check header order:

https://u-boot.readthedocs.io/en/latest/develop/codingstyle.html#include-files



Sure, however I did have a compile error with sandbox build due to 
missing phys_addr_t definition in asm/io.h...






  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
  #include "tpm-utils.h"


[..]


+static int tcg2_log_init(struct udevice *dev, struct tcg2_event_log *elog)
+{
+   struct tcg_efi_spec_id_event *ev;

We cannot add EFI things to generic TPM code.



Ah, this is NOT an EFI thing even though it is named as such. Please see 
https://trustedcomputinggroup.org/wp-content/uploads/TCG_ServerManagDomainFWProfile_r1p00_pub.pdf 
section 9 and 
https://trustedcomputinggroup.org/wp-content/uploads/TCG_PCClient_Specific_Platform_Profile_for_TPM_2p0_1p04_PUBLIC.pdf 
section 9



Neither of these documents are specific to EFI.





+   struct tcg_pcr_event *log;
+   u32 event_size;
+   u32 count = 0;
+   u32 log_size;
+   u32 active;
+   u32 mask;
+   size_t i;
+   u16 len;
+   int rc;
+
+   rc = tcg2_get_active_pcr_banks(dev, );
+   if (rc)
+   return rc;
+
+   event_size = offsetof(struct tcg_efi_spec_id_event, digest_sizes);
+   for (i = 0; i < ARRAY_SIZE(tcg2algos); ++i) {
+   mask = tpm2_algorithm_to_mask(tcg2algos[i]);
+
+   if (!(active & mask))
+   continue;
+
+   switch (tcg2algos[i]) {
+   case TPM2_ALG_SHA1:
+   case TPM2_ALG_SHA256:
+   case TPM2_ALG_SHA384:
+   case TPM2_ALG_SHA512:
+   count++;
+   break;
+   default:
+   continue;
+   }
+   }
+
+   event_size += 1 +
+   (sizeof(struct tcg_efi_spec_id_event_algorithm_size) * count);
+   log_size = offsetof(struct tcg_pcr_event, event) + event_size;
+
+   if (log_size > elog->log_size) {
+   printf("%s: log too large: %u > %u\n", __func__, log_size,
+  elog->log_size);
+   return -ENOBUFS;
+   }
+
+   log = (struct tcg_pcr_event *)elog->log;
+   put_unaligned_le32(0, >pcr_index);
+   put_unaligned_le32(EV_NO_ACTION, >event_type);
+   memset(>digest, 0, sizeof(log->digest));
+   put_unaligned_le32(event_size, >event_size);
+
+   ev = (struct tcg_efi_spec_id_event *)log->event;
+   strlcpy((char *)ev->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03,

Same with all of this.


+   sizeof(ev->signature));
+   put_unaligned_le32(0, >platform_class);
+   ev->spec_version_minor = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2;
+   ev->spec_version_major = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2;
+   ev->spec_errata = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2;

I'm not quite sure what is going on here...is this log in a format
defined by the EFI spec? What if we are not using EFI? How would a
different format be used?

Put another way, people using a TPM should not pull in EFI things just
to do that.



Agreed, however the EFI spec is not involved. These specifications and 
structures are general to any boot measurement. I would guess EFI was 
the first to do this and therefore defined some structures that the TCG 
re-used when writing the specs.





I'm just not quite sure of the best approach here...

Regards,
Simon


[PATCH v2 3/5] bootm: Support boot measurement

2023-01-09 Thread Eddie James
Add a configuration option to measure the boot through the bootm
function.

Signed-off-by: Eddie James 
---
 boot/Kconfig| 23 ++
 boot/bootm.c| 64 +
 cmd/bootm.c |  2 ++
 include/bootm.h |  2 ++
 include/image.h |  1 +
 5 files changed, 92 insertions(+)

diff --git a/boot/Kconfig b/boot/Kconfig
index 30bc182fcd..e90d61412e 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -587,6 +587,29 @@ config LEGACY_IMAGE_FORMAT
  loaded. If a board needs the legacy image format support in this
  case, enable it here.
 
+config MEASURED_BOOT
+   bool "Measure boot images and configuration to TPM and event log"
+   depends on HASH && TPM_V2
+   help
+ This option enables measurement of the boot process. Measurement
+ involves creating cryptographic hashes of the binary images that
+ are booting and storing them in the TPM. In addition, a log of
+ these hashes is stored in memory for the OS to verify the booted
+ images and configuration. Enable this if the OS has configured
+ some memory area for the event log and you intend to use some
+ attestation tools on your system.
+
+if MEASURED_BOOT
+   config MEASURE_DEVICETREE
+   bool "Measure the devicetree image"
+   default y if MEASURED_BOOT
+   help
+ On some platforms, the devicetree is not static as it may contain
+ random MAC addresses or other such data that changes each boot.
+ Therefore, it should not be measured into the TPM. In that case,
+ disable the measurement here.
+endif # MEASURED_BOOT
+
 config SUPPORT_RAW_INITRD
bool "Enable raw initrd images"
help
diff --git a/boot/bootm.c b/boot/bootm.c
index 15fce8ad95..932961ceb7 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #if defined(CONFIG_CMD_USB)
 #include 
 #endif
@@ -659,6 +660,66 @@ int bootm_process_cmdline_env(int flags)
return 0;
 }
 
+int bootm_measure(struct bootm_headers *images)
+{
+   int ret = 0;
+
+   if (IS_ENABLED(CONFIG_MEASURED_BOOT)) {
+   struct tcg2_event_log elog;
+   struct udevice *dev;
+   void *initrd_buf;
+   void *image_buf;
+   const char *s;
+   u32 rd_len;
+
+   ret = tcg2_measurement_init(, );
+   if (ret)
+   return ret;
+
+   image_buf = map_sysmem(images->os.image_start,
+  images->os.image_len);
+   ret = tcg2_measure_data(dev, , 8, images->os.image_len,
+   image_buf, EV_COMPACT_HASH,
+   strlen("linux") + 1, (u8 *)"linux");
+   if (ret)
+   goto unmap_image;
+
+   rd_len = images->rd_end - images->rd_start;
+   initrd_buf = map_sysmem(images->rd_start, rd_len);
+   ret = tcg2_measure_data(dev, , 8, rd_len, initrd_buf,
+   EV_COMPACT_HASH, strlen("initrd") + 1,
+   (u8 *)"initrd");
+   if (ret)
+   goto unmap_initrd;
+
+   if (IS_ENABLED(CONFIG_MEASURE_DEVICETREE)) {
+   ret = tcg2_measure_data(dev, , 9, images->ft_len,
+   (u8 *)images->ft_addr,
+   EV_TABLE_OF_DEVICES,
+   strlen("dts") + 1,
+   (u8 *)"dts");
+   if (ret)
+   goto unmap_initrd;
+   }
+
+   s = env_get("bootargs");
+   if (!s)
+   s = "";
+   ret = tcg2_measure_data(dev, , 1, strlen(s) + 1, (u8 *)s,
+   EV_PLATFORM_CONFIG_FLAGS,
+   strlen(s) + 1, (u8 *)s);
+
+unmap_initrd:
+   unmap_sysmem(initrd_buf);
+
+unmap_image:
+   unmap_sysmem(image_buf);
+   tcg2_measurement_term(dev, , ret != 0);
+   }
+
+   return ret;
+}
+
 /**
  * Execute selected states of the bootm command.
  *
@@ -710,6 +771,9 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int 
argc,
if (!ret && (states & BOOTM_STATE_FINDOTHER))
ret = bootm_find_other(cmdtp, flag, argc, argv);
 
+   if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !ret && (states & 
BOOTM_STATE_MEASURE))
+   bootm_measure(images);
+
/* Load the OS */
if (!ret && (states & BOOTM_STATE_LOADOS)) {

[PATCH v2 4/5] tpm: sandbox: Update for needed TPM2 capabilities

2023-01-09 Thread Eddie James
The driver needs to support getting the PCRs in the capabilities
command. Fix various other things and support the max number
of PCRs for TPM2.

Signed-off-by: Eddie James 
---
 drivers/tpm/tpm2_tis_sandbox.c | 100 -
 1 file changed, 72 insertions(+), 28 deletions(-)

diff --git a/drivers/tpm/tpm2_tis_sandbox.c b/drivers/tpm/tpm2_tis_sandbox.c
index dd94bdc31f..ea7fb5e3cb 100644
--- a/drivers/tpm/tpm2_tis_sandbox.c
+++ b/drivers/tpm/tpm2_tis_sandbox.c
@@ -22,11 +22,6 @@ enum tpm2_hierarchy {
TPM2_HIERARCHY_NB,
 };
 
-/* Subset of supported capabilities */
-enum tpm2_capability {
-   TPM_CAP_TPM_PROPERTIES = 0x6,
-};
-
 /* Subset of supported properties */
 #define TPM2_PROPERTIES_OFFSET 0x020E
 
@@ -38,7 +33,8 @@ enum tpm2_cap_tpm_property {
TPM2_PROPERTY_NB,
 };
 
-#define SANDBOX_TPM_PCR_NB 1
+#define SANDBOX_TPM_PCR_NB TPM2_MAX_PCRS
+#define SANDBOX_TPM_PCR_SELECT_MAX ((SANDBOX_TPM_PCR_NB + 7) / 8)
 
 /*
  * Information about our TPM emulation. This is preserved in the sandbox
@@ -433,7 +429,7 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const u8 
*sendbuf,
int i, j;
 
/* TPM2_GetProperty */
-   u32 capability, property, property_count;
+   u32 capability, property, property_count, val;
 
/* TPM2_PCR_Read/Extend variables */
int pcr_index = 0;
@@ -542,19 +538,32 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const 
u8 *sendbuf,
case TPM2_CC_GET_CAPABILITY:
capability = get_unaligned_be32(sent);
sent += sizeof(capability);
-   if (capability != TPM_CAP_TPM_PROPERTIES) {
-   printf("Sandbox TPM only support TPM_CAPABILITIES\n");
-   return TPM2_RC_HANDLE;
-   }
-
property = get_unaligned_be32(sent);
sent += sizeof(property);
-   property -= TPM2_PROPERTIES_OFFSET;
-
property_count = get_unaligned_be32(sent);
sent += sizeof(property_count);
-   if (!property_count ||
-   property + property_count > TPM2_PROPERTY_NB) {
+
+   switch (capability) {
+   case TPM2_CAP_PCRS:
+   break;
+   case TPM2_CAP_TPM_PROPERTIES:
+   if (!property_count) {
+   rc = TPM2_RC_HANDLE;
+   return sandbox_tpm2_fill_buf(recv, recv_len,
+tag, rc);
+   }
+
+   if (property > TPM2_PROPERTIES_OFFSET &&
+   ((property - TPM2_PROPERTIES_OFFSET) +
+property_count > TPM2_PROPERTY_NB)) {
+   rc = TPM2_RC_HANDLE;
+   return sandbox_tpm2_fill_buf(recv, recv_len,
+tag, rc);
+   }
+   break;
+   default:
+   printf("Sandbox TPM2 only supports TPM2_CAP_PCRS or "
+  "TPM2_CAP_TPM_PROPERTIES\n");
rc = TPM2_RC_HANDLE;
return sandbox_tpm2_fill_buf(recv, recv_len, tag, rc);
}
@@ -578,18 +587,53 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const 
u8 *sendbuf,
put_unaligned_be32(capability, recv);
recv += sizeof(capability);
 
-   /* Give the number of properties that follow */
-   put_unaligned_be32(property_count, recv);
-   recv += sizeof(property_count);
-
-   /* Fill with the properties */
-   for (i = 0; i < property_count; i++) {
-   put_unaligned_be32(TPM2_PROPERTIES_OFFSET + property +
-  i, recv);
-   recv += sizeof(property);
-   put_unaligned_be32(tpm->properties[property + i],
-  recv);
-   recv += sizeof(property);
+   switch (capability) {
+   case TPM2_CAP_PCRS:
+   /* Give the number of algorithms supported - just 
SHA256 */
+   put_unaligned_be32(1, recv);
+   recv += sizeof(u32);
+
+   /* Give SHA256 algorithm */
+   put_unaligned_be16(TPM2_ALG_SHA256, recv);
+   recv += sizeof(u16);
+
+   /* Select the PCRs supported */
+   *recv = SANDBOX_TPM_PCR_SELECT_MAX;
+   recv++;
+
+   /* Activate all the PCR bits */
+   for (i = 0; i < SANDBOX_TPM_PCR_SELECT_MAX; ++i) {
+ 

[PATCH v2 1/5] tpm: Fix spelling for tpmu_ha union

2023-01-09 Thread Eddie James
tmpu -> tpmu

Signed-off-by: Eddie James 
Reviewed-by: Ilias Apalodimas 
---
 include/tpm-v2.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 737e57551d..85feda3e06 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -167,7 +167,7 @@ struct tcg_pcr_event {
 /**
  * Definition of TPMU_HA Union
  */
-union tmpu_ha {
+union tpmu_ha {
u8 sha1[TPM2_SHA1_DIGEST_SIZE];
u8 sha256[TPM2_SHA256_DIGEST_SIZE];
u8 sm3_256[TPM2_SM3_256_DIGEST_SIZE];
@@ -183,7 +183,7 @@ union tmpu_ha {
  */
 struct tpmt_ha {
u16 hash_alg;
-   union tmpu_ha digest;
+   union tpmu_ha digest;
 } __packed;
 
 /**
-- 
2.31.1



[PATCH v2 2/5] tpm: Support boot measurements

2023-01-09 Thread Eddie James
Add TPM2 functions to support boot measurement. This includes
starting up the TPM, initializing/appending the event log, and
measuring the U-Boot version. Much of the code was used in the
EFI subsystem, so remove it there and use the common functions.

Signed-off-by: Eddie James 
---
 include/efi_tcg2.h|  44 ---
 include/tpm-v2.h  | 211 
 lib/efi_loader/efi_tcg2.c | 362 +--
 lib/tpm-v2.c  | 708 ++
 4 files changed, 938 insertions(+), 387 deletions(-)

diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
index 874306dc11..23016773f4 100644
--- a/include/efi_tcg2.h
+++ b/include/efi_tcg2.h
@@ -129,50 +129,6 @@ struct efi_tcg2_boot_service_capability {
 #define BOOT_SERVICE_CAPABILITY_MIN \
offsetof(struct efi_tcg2_boot_service_capability, number_of_pcr_banks)
 
-#define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03"
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2
-
-/**
- *  struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm information
- *
- *  @algorithm_id: algorithm defined in enum tpm2_algorithms
- *  @digest_size:  size of the algorithm
- */
-struct tcg_efi_spec_id_event_algorithm_size {
-   u16  algorithm_id;
-   u16  digest_size;
-} __packed;
-
-/**
- * struct TCG_EfiSpecIDEventStruct - content of the event log header
- *
- * @signature: signature, set to Spec ID Event03
- * @platform_class:class defined in TCG ACPI Specification
- * Client  Common Header.
- * @spec_version_minor:minor version
- * @spec_version_major:major version
- * @spec_version_errata:   major version
- * @uintn_size:size of the efi_uintn_t fields used in 
various
- * data structures used in this specification.
- * 0x01 indicates u32  and 0x02  indicates u64
- * @number_of_algorithms:  hashing algorithms used in this event log
- * @digest_sizes:  array of number_of_algorithms pairs
- * 1st member defines the algorithm id
- * 2nd member defines the algorithm size
- */
-struct tcg_efi_spec_id_event {
-   u8 signature[16];
-   u32 platform_class;
-   u8 spec_version_minor;
-   u8 spec_version_major;
-   u8 spec_errata;
-   u8 uintn_size;
-   u32 number_of_algorithms;
-   struct tcg_efi_spec_id_event_algorithm_size digest_sizes[];
-} __packed;
-
 /**
  * struct tdEFI_TCG2_FINAL_EVENTS_TABLE - log entries after Get Event Log
  * @version:   version number for this structure
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 85feda3e06..e3db3419dd 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -214,6 +214,50 @@ struct tcg_pcr_event2 {
u8 event[];
 } __packed;
 
+/**
+ *  struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm information
+ *
+ *  @algorithm_id: algorithm defined in enum tpm2_algorithms
+ *  @digest_size:  size of the algorithm
+ */
+struct tcg_efi_spec_id_event_algorithm_size {
+   u16  algorithm_id;
+   u16  digest_size;
+} __packed;
+
+#define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03"
+#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2
+#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0
+#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2
+
+/**
+ * struct TCG_EfiSpecIDEventStruct - content of the event log header
+ *
+ * @signature: signature, set to Spec ID Event03
+ * @platform_class:class defined in TCG ACPI Specification
+ * Client  Common Header.
+ * @spec_version_minor:minor version
+ * @spec_version_major:major version
+ * @spec_version_errata:   major version
+ * @uintn_size:size of the efi_uintn_t fields used in 
various
+ * data structures used in this specification.
+ * 0x01 indicates u32  and 0x02  indicates u64
+ * @number_of_algorithms:  hashing algorithms used in this event log
+ * @digest_sizes:  array of number_of_algorithms pairs
+ * 1st member defines the algorithm id
+ * 2nd member defines the algorithm size
+ */
+struct tcg_efi_spec_id_event {
+   u8 signature[16];
+   u32 platform_class;
+   u8 spec_version_minor;
+   u8 spec_version_major;
+   u8 spec_errata;
+   u8 uintn_size;
+   u32 number_of_algorithms;
+   struct tcg_efi_spec_id_event_algorithm_size digest_sizes[];
+} __packed;
+
 /**
  * TPM2 Structure Tags for command/response buffers.
  *
@@ -340,6 +384,24 @@ enum tpm2_algorithms {

[PATCH v2 5/5] test: Add sandbox TPM boot measurement

2023-01-09 Thread Eddie James
Use the sandbox TPM driver to measure some boot images in a unit
test case.

$ ./u-boot -T -c "ut measurement"
Running 1 measurement tests
Test: measure: measurement.c
Failures: 0

Signed-off-by: Eddie James 
---
 arch/sandbox/dts/test.dts | 12 +++
 configs/sandbox_defconfig |  1 +
 include/test/suites.h |  1 +
 test/boot/Makefile|  1 +
 test/boot/measurement.c   | 66 +++
 test/cmd_ut.c |  2 ++
 6 files changed, 83 insertions(+)
 create mode 100644 test/boot/measurement.c

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index dffe10adbf..ad90bf0541 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -66,6 +66,17 @@
osd0 = "/osd";
};
 
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   event_log: tcg_event_log@d0e000 {
+   no-map;
+   reg = <0x00d0e000 0x2000>;
+   };
+   };
+
binman: binman {
};
 
@@ -1332,6 +1343,7 @@
 
tpm2 {
compatible = "sandbox,tpm2";
+   memory-region = <_log>;
};
 
uart0: serial {
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index de799b5cea..5ac115f2d8 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -335,3 +335,4 @@ CONFIG_TEST_FDTDEC=y
 CONFIG_UNIT_TEST=y
 CONFIG_UT_TIME=y
 CONFIG_UT_DM=y
+CONFIG_MEASURED_BOOT=y
diff --git a/include/test/suites.h b/include/test/suites.h
index a01000e127..f9284871b0 100644
--- a/include/test/suites.h
+++ b/include/test/suites.h
@@ -43,6 +43,7 @@ int do_ut_font(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[]);
 int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_loadm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_log(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]);
+int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc, char * const 
argv[]);
 int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc,
diff --git a/test/boot/Makefile b/test/boot/Makefile
index d724629d3b..24cc20bdff 100644
--- a/test/boot/Makefile
+++ b/test/boot/Makefile
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_BOOTSTD) += bootdev.o bootstd_common.o bootflow.o bootmeth.o
 obj-$(CONFIG_FIT) += image.o
+obj-$(CONFIG_MEASURED_BOOT) += measurement.o
 
 ifdef CONFIG_OF_LIVE
 obj-$(CONFIG_BOOTMETH_VBE_SIMPLE) += vbe_simple.o
diff --git a/test/boot/measurement.c b/test/boot/measurement.c
new file mode 100644
index 00..2155208894
--- /dev/null
+++ b/test/boot/measurement.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test for measured boot functions
+ *
+ * Copyright 2023 IBM Corp.
+ * Written by Eddie James 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MEASUREMENT_TEST(_name, _flags)\
+   UNIT_TEST(_name, _flags, measurement_test)
+
+static int measure(struct unit_test_state *uts)
+{
+   struct bootm_headers images;
+   const size_t size = 1024;
+   u8 *kernel;
+   u8 *initrd;
+   size_t i;
+
+   kernel = malloc(size);
+   initrd = malloc(size);
+
+   images.os.image_start = map_to_sysmem(kernel);
+   images.os.image_len = size;
+
+   images.rd_start = map_to_sysmem(initrd);
+   images.rd_end = images.rd_start + size;
+
+   images.ft_addr = malloc(size);
+   images.ft_len = size;
+
+   env_set("bootargs", "measurement testing");
+
+   for (i = 0; i < size; ++i) {
+   kernel[i] = (u8)(0xf0 | (i & 0xf));
+   initrd[i] = (u8)((i & 0xf0) | 0xf);
+   ((u8 *)images.ft_addr)[i] = (u8)(i & 0xff);
+   }
+
+   ut_assertok(bootm_measure());
+
+   free(images.ft_addr);
+   free(initrd);
+   free(kernel);
+
+   return 0;
+}
+MEASUREMENT_TEST(measure, 0);
+
+int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+   struct unit_test *tests = UNIT_TEST_SUITE_START(measurement_test);
+   const int n_ents = UNIT_TEST_SUITE_COUNT(measurement_test);
+
+   return cmd_ut_category("measurement", "measurement_test_", tests,
+  n_ents, argc, argv);
+}
diff --git a/test/cmd_ut.c b/test/cmd_ut.c
index 2736582f11..819031c0f8 100644
--- a/test/cmd_ut.c
+++ b/test/cmd_ut.c
@@ -100,6 +100,8 @@ static struct cmd_tbl cmd_ut_sub[] = {
 "", ""),
U_BOOT_CMD_MKENT(bloblist, CONFIG_SYS_MAXARGS, 1,

[PATCH v2 0/5] tpm: Support boot measurements

2023-01-09 Thread Eddie James
This series adds support for measuring the boot images more generically
than the existing EFI support. Several EFI functions have been moved to
the TPM layer. The series includes optional measurement from the bootm 
command.
A new test case has been added for the bootm measurement to test the new
path, and the sandbox TPM2 driver has been updated to support this use
case.

Changes since v1:
 - Refactor TPM layer functions to allow EFI system to use them, and
   remove duplicate EFI functions.
 - Add test case
 - Drop #ifdefs for bootm
 - Add devicetree measurement config option
 - Update sandbox TPM driver

Eddie James (5):
  tpm: Fix spelling for tpmu_ha union
  tpm: Support boot measurements
  bootm: Support boot measurement
  tpm: sandbox: Update for needed TPM2 capabilities
  test: Add sandbox TPM boot measurement

 arch/sandbox/dts/test.dts  |  12 +
 boot/Kconfig   |  23 ++
 boot/bootm.c   |  64 +++
 cmd/bootm.c|   2 +
 configs/sandbox_defconfig  |   1 +
 drivers/tpm/tpm2_tis_sandbox.c | 100 +++--
 include/bootm.h|   2 +
 include/efi_tcg2.h |  44 --
 include/image.h|   1 +
 include/test/suites.h  |   1 +
 include/tpm-v2.h   | 215 +-
 lib/efi_loader/efi_tcg2.c  | 362 +
 lib/tpm-v2.c   | 708 +
 test/boot/Makefile |   1 +
 test/boot/measurement.c|  66 +++
 test/cmd_ut.c  |   2 +
 16 files changed, 1187 insertions(+), 417 deletions(-)
 create mode 100644 test/boot/measurement.c

-- 
2.31.1



Re: [PATCH v2 5/5] test: Add sandbox TPM boot measurement

2023-01-11 Thread Eddie James



On 1/10/23 16:37, Heinrich Schuchardt wrote:

On 1/10/23 23:32, Heinrich Schuchardt wrote:

On 1/9/23 22:55, Eddie James wrote:

Use the sandbox TPM driver to measure some boot images in a unit
test case.

$ ./u-boot -T -c "ut measurement"
Running 1 measurement tests
Test: measure: measurement.c
Failures: 0

Signed-off-by: Eddie James 
---
  arch/sandbox/dts/test.dts | 12 +++
  configs/sandbox_defconfig |  1 +
  include/test/suites.h |  1 +
  test/boot/Makefile    |  1 +
  test/boot/measurement.c   | 66 
+++

  test/cmd_ut.c |  2 ++
  6 files changed, 83 insertions(+)
  create mode 100644 test/boot/measurement.c

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index dffe10adbf..ad90bf0541 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -66,6 +66,17 @@
  osd0 = "/osd";
  };

+    reserved-memory {
+    #address-cells = <1>;
+    #size-cells = <1>;
+    ranges;
+
+    event_log: tcg_event_log@d0e000 {
+    no-map;


Isn't no-map misplaced? Shouldn't it be a reserved-memory property?


The placement is correct. But I still wonder why we should have this
area as no-map.



If the memory region is not mapped, Linux can never access it as
described in
Documentation/devicetree/bindings/reserved-memory/reserved-memory.yaml.



I read the documentation as meaning that Linux won't map it as part of 
it's standard mappings. It's still available for a device driver (TPM 
driver in this case). I believe no-map is appropriate here since we 
don't want anything except the TPM driver to access that memory.



Thanks,

Eddie




Please, document all changes to the device-tree semantics via patches
for the Linux kernels documentation and provide a full example.

Best regards

Heinrich




[PATCH 2/3] tpm: Support boot measurements

2023-01-03 Thread Eddie James
Add TPM2 functions to support boot measurement. This includes
starting up the TPM, initializing/appending the event log, and
measuring the U-Boot version.

Signed-off-by: Eddie James 
---
 include/efi_tcg2.h |  44 ---
 include/tpm-v2.h   | 135 +
 lib/tpm-v2.c   | 700 +
 3 files changed, 835 insertions(+), 44 deletions(-)

diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
index 874306dc11..23016773f4 100644
--- a/include/efi_tcg2.h
+++ b/include/efi_tcg2.h
@@ -129,50 +129,6 @@ struct efi_tcg2_boot_service_capability {
 #define BOOT_SERVICE_CAPABILITY_MIN \
offsetof(struct efi_tcg2_boot_service_capability, number_of_pcr_banks)
 
-#define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03"
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2
-
-/**
- *  struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm information
- *
- *  @algorithm_id: algorithm defined in enum tpm2_algorithms
- *  @digest_size:  size of the algorithm
- */
-struct tcg_efi_spec_id_event_algorithm_size {
-   u16  algorithm_id;
-   u16  digest_size;
-} __packed;
-
-/**
- * struct TCG_EfiSpecIDEventStruct - content of the event log header
- *
- * @signature: signature, set to Spec ID Event03
- * @platform_class:class defined in TCG ACPI Specification
- * Client  Common Header.
- * @spec_version_minor:minor version
- * @spec_version_major:major version
- * @spec_version_errata:   major version
- * @uintn_size:size of the efi_uintn_t fields used in 
various
- * data structures used in this specification.
- * 0x01 indicates u32  and 0x02  indicates u64
- * @number_of_algorithms:  hashing algorithms used in this event log
- * @digest_sizes:  array of number_of_algorithms pairs
- * 1st member defines the algorithm id
- * 2nd member defines the algorithm size
- */
-struct tcg_efi_spec_id_event {
-   u8 signature[16];
-   u32 platform_class;
-   u8 spec_version_minor;
-   u8 spec_version_major;
-   u8 spec_errata;
-   u8 uintn_size;
-   u32 number_of_algorithms;
-   struct tcg_efi_spec_id_event_algorithm_size digest_sizes[];
-} __packed;
-
 /**
  * struct tdEFI_TCG2_FINAL_EVENTS_TABLE - log entries after Get Event Log
  * @version:   version number for this structure
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 85feda3e06..62a245e9d9 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -214,6 +214,50 @@ struct tcg_pcr_event2 {
u8 event[];
 } __packed;
 
+/**
+ *  struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm information
+ *
+ *  @algorithm_id: algorithm defined in enum tpm2_algorithms
+ *  @digest_size:  size of the algorithm
+ */
+struct tcg_efi_spec_id_event_algorithm_size {
+   u16  algorithm_id;
+   u16  digest_size;
+} __packed;
+
+#define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03"
+#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2
+#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0
+#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2
+
+/**
+ * struct TCG_EfiSpecIDEventStruct - content of the event log header
+ *
+ * @signature: signature, set to Spec ID Event03
+ * @platform_class:class defined in TCG ACPI Specification
+ * Client  Common Header.
+ * @spec_version_minor:minor version
+ * @spec_version_major:major version
+ * @spec_version_errata:   major version
+ * @uintn_size:size of the efi_uintn_t fields used in 
various
+ * data structures used in this specification.
+ * 0x01 indicates u32  and 0x02  indicates u64
+ * @number_of_algorithms:  hashing algorithms used in this event log
+ * @digest_sizes:  array of number_of_algorithms pairs
+ * 1st member defines the algorithm id
+ * 2nd member defines the algorithm size
+ */
+struct tcg_efi_spec_id_event {
+   u8 signature[16];
+   u32 platform_class;
+   u8 spec_version_minor;
+   u8 spec_version_major;
+   u8 spec_errata;
+   u8 uintn_size;
+   u32 number_of_algorithms;
+   struct tcg_efi_spec_id_event_algorithm_size digest_sizes[];
+} __packed;
+
 /**
  * TPM2 Structure Tags for command/response buffers.
  *
@@ -340,6 +384,24 @@ enum tpm2_algorithms {
TPM2_ALG_SM3_256= 0x12,
 };
 
+static inline u16 tpm2_algorithm_to_len(enum tpm2_algorithms a)
+{
+   switch (a) {
+   case TPM2_ALG_SHA1:
+ 

[PATCH 3/3] bootm: Support boot measurement

2023-01-03 Thread Eddie James
Add a configuration option to measure the boot through the bootm
function.

Signed-off-by: Eddie James 
---
 boot/bootm.c| 53 +
 cmd/bootm.c |  2 ++
 common/Kconfig  |  6 ++
 include/image.h |  1 +
 4 files changed, 62 insertions(+)

diff --git a/boot/bootm.c b/boot/bootm.c
index a4c0870c0f..7f64d79035 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -22,6 +22,9 @@
 #include 
 #include 
 #include 
+#if defined(CONFIG_MEASURED_BOOT)
+#include 
+#endif
 #if defined(CONFIG_CMD_USB)
 #include 
 #endif
@@ -713,6 +716,56 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int 
argc,
if (!ret && (states & BOOTM_STATE_FINDOTHER))
ret = bootm_find_other(cmdtp, flag, argc, argv);
 
+#if defined(CONFIG_MEASURED_BOOT)
+   if (!ret && (states & BOOTM_STATE_MEASURE)) {
+   void *initrd_buf;
+   void *image_buf;
+   const char *s;
+   u32 rd_len;
+
+   ret = tcg2_measurement_init();
+   if (ret)
+   goto measure_err;
+
+   image_buf = map_sysmem(images->os.image_start,
+  images->os.image_len);
+   ret = tcg2_measure_data(8, images->os.image_len, image_buf,
+   EV_COMPACT_HASH, strlen("linux") + 1,
+   (u8 *)"linux");
+   if (ret)
+   goto unmap_image;
+
+   rd_len = images->rd_end - images->rd_start;
+   initrd_buf = map_sysmem(images->rd_start, rd_len);
+   ret = tcg2_measure_data(8, rd_len, initrd_buf, EV_COMPACT_HASH,
+   strlen("initrd") + 1, (u8 *)"initrd");
+   if (ret)
+   goto unmap_initrd;
+
+   ret = tcg2_measure_data(9, images->ft_len,
+   (u8 *)images->ft_addr,
+   EV_TABLE_OF_DEVICES, strlen("dts") + 1,
+   (u8 *)"dts");
+   if (ret)
+   goto unmap_initrd;
+
+   s = env_get("bootargs");
+   if (!s)
+   s = "";
+   tcg2_measure_data(1, strlen(s) + 1, (u8 *)s,
+ EV_PLATFORM_CONFIG_FLAGS, strlen(s) + 1,
+ (u8 *)s);
+
+unmap_initrd:
+   unmap_sysmem(initrd_buf);
+unmap_image:
+   unmap_sysmem(image_buf);
+   tcg2_measurement_term();
+measure_err:
+   ret = 0;
+   }
+#endif
+
/* Load the OS */
if (!ret && (states & BOOTM_STATE_LOADOS)) {
iflag = bootm_disable_interrupts();
diff --git a/cmd/bootm.c b/cmd/bootm.c
index 37c2af96e0..0c4a713e02 100644
--- a/cmd/bootm.c
+++ b/cmd/bootm.c
@@ -161,6 +161,8 @@ int do_bootm(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[])
BOOTM_STATE_OS_GO;
if (IS_ENABLED(CONFIG_SYS_BOOT_RAMDISK_HIGH))
states |= BOOTM_STATE_RAMDISK;
+   if (IS_ENABLED(CONFIG_MEASURED_BOOT))
+   states |= BOOTM_STATE_MEASURE;
if (IS_ENABLED(CONFIG_PPC) || IS_ENABLED(CONFIG_MIPS))
states |= BOOTM_STATE_OS_CMDLINE;
ret = do_bootm_states(cmdtp, flag, argc, argv, states, , 1);
diff --git a/common/Kconfig b/common/Kconfig
index 21434c5cf1..57ef68e4f3 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -799,6 +799,12 @@ config AVB_BUF_SIZE
 
 endif # AVB_VERIFY
 
+config MEASURED_BOOT
+   bool "Measure the boot to TPM and event log"
+   depends on HASH && TPM_V2
+   help
+ This option enables measurement of the boot process.
+
 config SCP03
bool "Build SCP03 - Secure Channel Protocol O3 - controls"
depends on OPTEE || SANDBOX
diff --git a/include/image.h b/include/image.h
index 6f21dafba8..b00803eeac 100644
--- a/include/image.h
+++ b/include/image.h
@@ -406,6 +406,7 @@ struct bootm_headers {
 #define BOOTM_STATE_OS_FAKE_GO 0x0200  /* 'Almost' run the OS */
 #define BOOTM_STATE_OS_GO  0x0400
 #define BOOTM_STATE_PRE_LOAD   0x0800
+#define BOOTM_STATE_MEASURE0x1000
int state;
 
 #if defined(CONFIG_LMB) && !defined(USE_HOSTCC)
-- 
2.31.1



[PATCH 0/3] tpm: Support boot measurements

2023-01-03 Thread Eddie James
This series adds support for measuring the boot images more generically
than the existing EFI support. The series includes optional measurement
from the bootm command.
Eventually the EFI code could be refactored to use the generic functions.

Eddie James (3):
  tpm: Fix spelling for tpmu_ha union
  tpm: Support boot measurements
  bootm: Support boot measurement

 boot/bootm.c   |  53 
 cmd/bootm.c|   2 +
 common/Kconfig |   6 +
 include/efi_tcg2.h |  44 ---
 include/image.h|   1 +
 include/tpm-v2.h   | 139 -
 lib/tpm-v2.c   | 700 +
 7 files changed, 899 insertions(+), 46 deletions(-)

-- 
2.31.1



[PATCH 1/3] tpm: Fix spelling for tpmu_ha union

2023-01-03 Thread Eddie James
tmpu -> tpmu

Signed-off-by: Eddie James 
---
 include/tpm-v2.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 737e57551d..85feda3e06 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -167,7 +167,7 @@ struct tcg_pcr_event {
 /**
  * Definition of TPMU_HA Union
  */
-union tmpu_ha {
+union tpmu_ha {
u8 sha1[TPM2_SHA1_DIGEST_SIZE];
u8 sha256[TPM2_SHA256_DIGEST_SIZE];
u8 sm3_256[TPM2_SM3_256_DIGEST_SIZE];
@@ -183,7 +183,7 @@ union tmpu_ha {
  */
 struct tpmt_ha {
u16 hash_alg;
-   union tmpu_ha digest;
+   union tpmu_ha digest;
 } __packed;
 
 /**
-- 
2.31.1



[PATCH v4 2/6] tpm: Support boot measurements

2023-01-25 Thread Eddie James
Add TPM2 functions to support boot measurement. This includes
starting up the TPM, initializing/appending the event log, and
measuring the U-Boot version. Much of the code was used in the
EFI subsystem, so remove it there and use the common functions.

Signed-off-by: Eddie James 
---
 include/efi_tcg2.h|  44 --
 include/tpm-v2.h  | 254 ++
 lib/efi_loader/efi_tcg2.c | 975 +++---
 lib/tpm-v2.c  | 799 +++
 4 files changed, 1129 insertions(+), 943 deletions(-)

diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
index 874306dc11..23016773f4 100644
--- a/include/efi_tcg2.h
+++ b/include/efi_tcg2.h
@@ -129,50 +129,6 @@ struct efi_tcg2_boot_service_capability {
 #define BOOT_SERVICE_CAPABILITY_MIN \
offsetof(struct efi_tcg2_boot_service_capability, number_of_pcr_banks)
 
-#define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03"
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2
-
-/**
- *  struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm information
- *
- *  @algorithm_id: algorithm defined in enum tpm2_algorithms
- *  @digest_size:  size of the algorithm
- */
-struct tcg_efi_spec_id_event_algorithm_size {
-   u16  algorithm_id;
-   u16  digest_size;
-} __packed;
-
-/**
- * struct TCG_EfiSpecIDEventStruct - content of the event log header
- *
- * @signature: signature, set to Spec ID Event03
- * @platform_class:class defined in TCG ACPI Specification
- * Client  Common Header.
- * @spec_version_minor:minor version
- * @spec_version_major:major version
- * @spec_version_errata:   major version
- * @uintn_size:size of the efi_uintn_t fields used in 
various
- * data structures used in this specification.
- * 0x01 indicates u32  and 0x02  indicates u64
- * @number_of_algorithms:  hashing algorithms used in this event log
- * @digest_sizes:  array of number_of_algorithms pairs
- * 1st member defines the algorithm id
- * 2nd member defines the algorithm size
- */
-struct tcg_efi_spec_id_event {
-   u8 signature[16];
-   u32 platform_class;
-   u8 spec_version_minor;
-   u8 spec_version_major;
-   u8 spec_errata;
-   u8 uintn_size;
-   u32 number_of_algorithms;
-   struct tcg_efi_spec_id_event_algorithm_size digest_sizes[];
-} __packed;
-
 /**
  * struct tdEFI_TCG2_FINAL_EVENTS_TABLE - log entries after Get Event Log
  * @version:   version number for this structure
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 85feda3e06..7057f67176 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -214,6 +214,50 @@ struct tcg_pcr_event2 {
u8 event[];
 } __packed;
 
+/**
+ *  struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm information
+ *
+ *  @algorithm_id: algorithm defined in enum tpm2_algorithms
+ *  @digest_size:  size of the algorithm
+ */
+struct tcg_efi_spec_id_event_algorithm_size {
+   u16  algorithm_id;
+   u16  digest_size;
+} __packed;
+
+#define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03"
+#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2
+#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0
+#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2
+
+/**
+ * struct TCG_EfiSpecIDEventStruct - content of the event log header
+ *
+ * @signature: signature, set to Spec ID Event03
+ * @platform_class:class defined in TCG ACPI Specification
+ * Client  Common Header.
+ * @spec_version_minor:minor version
+ * @spec_version_major:major version
+ * @spec_version_errata:   major version
+ * @uintn_size:size of the efi_uintn_t fields used in 
various
+ * data structures used in this specification.
+ * 0x01 indicates u32  and 0x02  indicates u64
+ * @number_of_algorithms:  hashing algorithms used in this event log
+ * @digest_sizes:  array of number_of_algorithms pairs
+ * 1st member defines the algorithm id
+ * 2nd member defines the algorithm size
+ */
+struct tcg_efi_spec_id_event {
+   u8 signature[16];
+   u32 platform_class;
+   u8 spec_version_minor;
+   u8 spec_version_major;
+   u8 spec_errata;
+   u8 uintn_size;
+   u32 number_of_algorithms;
+   struct tcg_efi_spec_id_event_algorithm_size digest_sizes[];
+} __packed;
+
 /**
  * TPM2 Structure Tags for command/response buffers.
  *
@@ -340,6 +384,26 @@ 

[PATCH v4 3/6] bootm: Support boot measurement

2023-01-25 Thread Eddie James
Add a configuration option to measure the boot through the bootm
function. Add the measurement state to the booti and bootz paths
as well.

Signed-off-by: Eddie James 
---
 boot/Kconfig| 23 
 boot/bootm.c| 70 +
 cmd/booti.c |  1 +
 cmd/bootm.c |  2 ++
 cmd/bootz.c |  1 +
 include/bootm.h |  2 ++
 include/image.h |  1 +
 7 files changed, 100 insertions(+)

diff --git a/boot/Kconfig b/boot/Kconfig
index fdcfbae7b2..831b9e954c 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -601,6 +601,29 @@ config LEGACY_IMAGE_FORMAT
  loaded. If a board needs the legacy image format support in this
  case, enable it here.
 
+config MEASURED_BOOT
+   bool "Measure boot images and configuration to TPM and event log"
+   depends on HASH && TPM_V2
+   help
+ This option enables measurement of the boot process. Measurement
+ involves creating cryptographic hashes of the binary images that
+ are booting and storing them in the TPM. In addition, a log of
+ these hashes is stored in memory for the OS to verify the booted
+ images and configuration. Enable this if the OS has configured
+ some memory area for the event log and you intend to use some
+ attestation tools on your system.
+
+if MEASURED_BOOT
+   config MEASURE_DEVICETREE
+   bool "Measure the devicetree image"
+   default y if MEASURED_BOOT
+   help
+ On some platforms, the devicetree is not static as it may contain
+ random MAC addresses or other such data that changes each boot.
+ Therefore, it should not be measured into the TPM. In that case,
+ disable the measurement here.
+endif # MEASURED_BOOT
+
 config SUPPORT_RAW_INITRD
bool "Enable raw initrd images"
help
diff --git a/boot/bootm.c b/boot/bootm.c
index 15fce8ad95..c8423f2c60 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #if defined(CONFIG_CMD_USB)
 #include 
 #endif
@@ -659,6 +660,72 @@ int bootm_process_cmdline_env(int flags)
return 0;
 }
 
+int bootm_measure(struct bootm_headers *images)
+{
+   int ret = 0;
+
+   /* Skip measurement if EFI is going to do it */
+   if (images->os.os == IH_OS_EFI &&
+   IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL) &&
+   IS_ENABLED(CONFIG_BOOTM_EFI))
+   return ret;
+
+   if (IS_ENABLED(CONFIG_MEASURED_BOOT)) {
+   struct tcg2_event_log elog;
+   struct udevice *dev;
+   void *initrd_buf;
+   void *image_buf;
+   const char *s;
+   u32 rd_len;
+
+   ret = tcg2_measurement_init(, );
+   if (ret)
+   return ret;
+
+   image_buf = map_sysmem(images->os.image_start,
+  images->os.image_len);
+   ret = tcg2_measure_data(dev, , 8, images->os.image_len,
+   image_buf, EV_COMPACT_HASH,
+   strlen("linux") + 1, (u8 *)"linux");
+   if (ret)
+   goto unmap_image;
+
+   rd_len = images->rd_end - images->rd_start;
+   initrd_buf = map_sysmem(images->rd_start, rd_len);
+   ret = tcg2_measure_data(dev, , 8, rd_len, initrd_buf,
+   EV_COMPACT_HASH, strlen("initrd") + 1,
+   (u8 *)"initrd");
+   if (ret)
+   goto unmap_initrd;
+
+   if (IS_ENABLED(CONFIG_MEASURE_DEVICETREE)) {
+   ret = tcg2_measure_data(dev, , 9, images->ft_len,
+   (u8 *)images->ft_addr,
+   EV_TABLE_OF_DEVICES,
+   strlen("dts") + 1,
+   (u8 *)"dts");
+   if (ret)
+   goto unmap_initrd;
+   }
+
+   s = env_get("bootargs");
+   if (!s)
+   s = "";
+   ret = tcg2_measure_data(dev, , 1, strlen(s) + 1, (u8 *)s,
+   EV_PLATFORM_CONFIG_FLAGS,
+   strlen(s) + 1, (u8 *)s);
+
+unmap_initrd:
+   unmap_sysmem(initrd_buf);
+
+unmap_image:
+   unmap_sysmem(image_buf);
+   tcg2_measurement_term(dev, , ret != 0);
+   }
+
+   return ret;
+}
+
 /**
  * Execute selected states of the bootm command.
  *
@@ -710,6 +777,9 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int 
argc,
if (!ret &&

[PATCH v4 5/6] test: Add sandbox TPM boot measurement

2023-01-25 Thread Eddie James
Use the sandbox TPM driver to measure some boot images in a unit
test case.

Signed-off-by: Eddie James 
---
 arch/sandbox/dts/sandbox.dtsi | 14 
 arch/sandbox/dts/test.dts | 13 +++
 configs/sandbox_defconfig |  1 +
 include/test/suites.h |  1 +
 test/boot/Makefile|  1 +
 test/boot/measurement.c   | 66 +++
 test/cmd_ut.c |  2 ++
 7 files changed, 98 insertions(+)
 create mode 100644 test/boot/measurement.c

diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index 18bf1cb5b6..3f0e192a83 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -4,9 +4,22 @@
  * and sandbox64 builds.
  */
 
+#include 
+
 #define USB_CLASS_HUB  9
 
 / {
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   event_log: tcg_event_log {
+   no-map;
+   reg = <(CFG_SYS_SDRAM_SIZE - 0x2000) 0x2000>;
+   };
+   };
+
binman {
};
 
@@ -332,6 +345,7 @@
 
tpm2 {
compatible = "sandbox,tpm2";
+   memory-region = <_log>;
};
 
triangle {
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 9d96e479ca..c334b89faa 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -9,6 +9,7 @@
 
 /dts-v1/;
 
+#include 
 #include 
 #include 
 #include 
@@ -66,6 +67,17 @@
osd0 = "/osd";
};
 
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   event_log: tcg_event_log {
+   no-map;
+   reg = <(CFG_SYS_SDRAM_SIZE - 0x2000) 0x2000>;
+   };
+   };
+
binman: binman {
};
 
@@ -1343,6 +1355,7 @@
 
tpm2 {
compatible = "sandbox,tpm2";
+   memory-region = <_log>;
};
 
uart0: serial {
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 34c342b6f5..9c4985adcf 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -337,3 +337,4 @@ CONFIG_TEST_FDTDEC=y
 CONFIG_UNIT_TEST=y
 CONFIG_UT_TIME=y
 CONFIG_UT_DM=y
+CONFIG_MEASURED_BOOT=y
diff --git a/include/test/suites.h b/include/test/suites.h
index 9ce49cbb03..4c284bbeaa 100644
--- a/include/test/suites.h
+++ b/include/test/suites.h
@@ -44,6 +44,7 @@ int do_ut_font(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[]);
 int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_loadm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_log(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]);
+int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc, char * const 
argv[]);
 int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc,
diff --git a/test/boot/Makefile b/test/boot/Makefile
index 22ed61c8fa..2dbb032a7e 100644
--- a/test/boot/Makefile
+++ b/test/boot/Makefile
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_BOOTSTD) += bootdev.o bootstd_common.o bootflow.o bootmeth.o
 obj-$(CONFIG_FIT) += image.o
+obj-$(CONFIG_MEASURED_BOOT) += measurement.o
 
 obj-$(CONFIG_EXPO) += expo.o
 
diff --git a/test/boot/measurement.c b/test/boot/measurement.c
new file mode 100644
index 00..2155208894
--- /dev/null
+++ b/test/boot/measurement.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test for measured boot functions
+ *
+ * Copyright 2023 IBM Corp.
+ * Written by Eddie James 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MEASUREMENT_TEST(_name, _flags)\
+   UNIT_TEST(_name, _flags, measurement_test)
+
+static int measure(struct unit_test_state *uts)
+{
+   struct bootm_headers images;
+   const size_t size = 1024;
+   u8 *kernel;
+   u8 *initrd;
+   size_t i;
+
+   kernel = malloc(size);
+   initrd = malloc(size);
+
+   images.os.image_start = map_to_sysmem(kernel);
+   images.os.image_len = size;
+
+   images.rd_start = map_to_sysmem(initrd);
+   images.rd_end = images.rd_start + size;
+
+   images.ft_addr = malloc(size);
+   images.ft_len = size;
+
+   env_set("bootargs", "measurement testing");
+
+   for (i = 0; i < size; ++i) {
+   kernel[i] = (u8)(0xf0 | (i & 0xf));
+   initrd[i] = (u8)((i & 0xf0) | 0xf);
+   ((u8 *)images.ft_addr)[i] = (u8)(i & 0xff);
+   }
+
+   ut_assertok(bootm_measure());
+
+   free(images.ft_addr);
+   free(ini

[PATCH v4 0/6] tpm: Support boot measurements

2023-01-25 Thread Eddie James
This series adds support for measuring the boot images more generically
than the existing EFI support. Several EFI functions have been moved to
the TPM layer. The series includes optional measurement from the bootm 
command.
A new test case has been added for the bootm measurement to test the new
path, and the sandbox TPM2 driver has been updated to support this use
case.

Changes since v3:
 - Reordered headers
 - Refactored more of EFI code into common code
Removed digest_info structure and instead used the common alg_to_mask
  and alg_to_len
Improved event log parsing in common code to get it equivalent to EFI
  Common code now extends PCR if previous bootloader stage couldn't
  No need to allocate memory in the common code, so EFI copies the
  discovered buffer like it did before
Rename efi measure_event function

Changes since v2:
 - Add documentation.
 - Changed reserved memory address to the top of the RAM for sandbox dts.
 - Add measure state to booti and bootz.
 - Skip measurement for EFI images that should be measured

Changes since v1:
 - Refactor TPM layer functions to allow EFI system to use them, and
   remove duplicate EFI functions.
 - Add test case
 - Drop #ifdefs for bootm
 - Add devicetree measurement config option
 - Update sandbox TPM driver

Eddie James (6):
  tpm: Fix spelling for tpmu_ha union
  tpm: Support boot measurements
  bootm: Support boot measurement
  tpm: sandbox: Update for needed TPM2 capabilities
  test: Add sandbox TPM boot measurement
  doc: Add measured boot documentation

 arch/sandbox/dts/sandbox.dtsi  |  14 +
 arch/sandbox/dts/test.dts  |  13 +
 boot/Kconfig   |  23 +
 boot/bootm.c   |  70 +++
 cmd/booti.c|   1 +
 cmd/bootm.c|   2 +
 cmd/bootz.c|   1 +
 configs/sandbox_defconfig  |   1 +
 doc/usage/index.rst|   1 +
 doc/usage/measured_boot.rst|  23 +
 drivers/tpm/tpm2_tis_sandbox.c | 100 +++-
 include/bootm.h|   2 +
 include/efi_tcg2.h |  44 --
 include/image.h|   1 +
 include/test/suites.h  |   1 +
 include/tpm-v2.h   | 258 -
 lib/efi_loader/efi_tcg2.c  | 975 +++--
 lib/tpm-v2.c   | 799 +++
 test/boot/Makefile |   1 +
 test/boot/measurement.c|  66 +++
 test/cmd_ut.c  |   2 +
 21 files changed, 1425 insertions(+), 973 deletions(-)
 create mode 100644 doc/usage/measured_boot.rst
 create mode 100644 test/boot/measurement.c

-- 
2.31.1



[PATCH v4 6/6] doc: Add measured boot documentation

2023-01-25 Thread Eddie James
Briefly describe the feature and specify the requirements.

Signed-off-by: Eddie James 
---
 doc/usage/index.rst |  1 +
 doc/usage/measured_boot.rst | 23 +++
 2 files changed, 24 insertions(+)
 create mode 100644 doc/usage/measured_boot.rst

diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 7d4a1cbc10..c3efdf61df 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -12,6 +12,7 @@ Use U-Boot
partitions
cmdline
semihosting
+   measured_boot
 
 Shell commands
 --
diff --git a/doc/usage/measured_boot.rst b/doc/usage/measured_boot.rst
new file mode 100644
index 00..13fd42a2fb
--- /dev/null
+++ b/doc/usage/measured_boot.rst
@@ -0,0 +1,23 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Measured Boot
+=
+
+U-Boot can perform a measured boot, the process of hashing various components
+of the boot process, extending the results in the TPM and logging the
+component's measurement in memory for the operating system to consume.
+
+Requirements
+-
+
+A hardware TPM 2.0 supported by the U-Boot drivers
+CONFIG_TPM=y
+CONFIG_MEASURED_BOOT=y
+Device-tree configuration of the TPM device to specify the memory area
+for event logging. The TPM device node must either contain a phandle to
+a reserved memory region or "linux,sml-base" and "linux,sml-size"
+indicating the address and size of the memory region. An example can be
+found in arch/sandbox/dts/test.dts
+The operating system must also be configured to use the memory regions
+specified in the U-Boot device-tree in order to make use of the event
+log.
-- 
2.31.1



[PATCH v4 1/6] tpm: Fix spelling for tpmu_ha union

2023-01-25 Thread Eddie James
tmpu -> tpmu

Signed-off-by: Eddie James 
Reviewed-by: Ilias Apalodimas 
---
 include/tpm-v2.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 737e57551d..85feda3e06 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -167,7 +167,7 @@ struct tcg_pcr_event {
 /**
  * Definition of TPMU_HA Union
  */
-union tmpu_ha {
+union tpmu_ha {
u8 sha1[TPM2_SHA1_DIGEST_SIZE];
u8 sha256[TPM2_SHA256_DIGEST_SIZE];
u8 sm3_256[TPM2_SM3_256_DIGEST_SIZE];
@@ -183,7 +183,7 @@ union tmpu_ha {
  */
 struct tpmt_ha {
u16 hash_alg;
-   union tmpu_ha digest;
+   union tpmu_ha digest;
 } __packed;
 
 /**
-- 
2.31.1



[PATCH v4 4/6] tpm: sandbox: Update for needed TPM2 capabilities

2023-01-25 Thread Eddie James
The driver needs to support getting the PCRs in the capabilities
command. Fix various other things and support the max number
of PCRs for TPM2.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
---
 drivers/tpm/tpm2_tis_sandbox.c | 100 -
 1 file changed, 72 insertions(+), 28 deletions(-)

diff --git a/drivers/tpm/tpm2_tis_sandbox.c b/drivers/tpm/tpm2_tis_sandbox.c
index dd94bdc31f..ea7fb5e3cb 100644
--- a/drivers/tpm/tpm2_tis_sandbox.c
+++ b/drivers/tpm/tpm2_tis_sandbox.c
@@ -22,11 +22,6 @@ enum tpm2_hierarchy {
TPM2_HIERARCHY_NB,
 };
 
-/* Subset of supported capabilities */
-enum tpm2_capability {
-   TPM_CAP_TPM_PROPERTIES = 0x6,
-};
-
 /* Subset of supported properties */
 #define TPM2_PROPERTIES_OFFSET 0x020E
 
@@ -38,7 +33,8 @@ enum tpm2_cap_tpm_property {
TPM2_PROPERTY_NB,
 };
 
-#define SANDBOX_TPM_PCR_NB 1
+#define SANDBOX_TPM_PCR_NB TPM2_MAX_PCRS
+#define SANDBOX_TPM_PCR_SELECT_MAX ((SANDBOX_TPM_PCR_NB + 7) / 8)
 
 /*
  * Information about our TPM emulation. This is preserved in the sandbox
@@ -433,7 +429,7 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const u8 
*sendbuf,
int i, j;
 
/* TPM2_GetProperty */
-   u32 capability, property, property_count;
+   u32 capability, property, property_count, val;
 
/* TPM2_PCR_Read/Extend variables */
int pcr_index = 0;
@@ -542,19 +538,32 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const 
u8 *sendbuf,
case TPM2_CC_GET_CAPABILITY:
capability = get_unaligned_be32(sent);
sent += sizeof(capability);
-   if (capability != TPM_CAP_TPM_PROPERTIES) {
-   printf("Sandbox TPM only support TPM_CAPABILITIES\n");
-   return TPM2_RC_HANDLE;
-   }
-
property = get_unaligned_be32(sent);
sent += sizeof(property);
-   property -= TPM2_PROPERTIES_OFFSET;
-
property_count = get_unaligned_be32(sent);
sent += sizeof(property_count);
-   if (!property_count ||
-   property + property_count > TPM2_PROPERTY_NB) {
+
+   switch (capability) {
+   case TPM2_CAP_PCRS:
+   break;
+   case TPM2_CAP_TPM_PROPERTIES:
+   if (!property_count) {
+   rc = TPM2_RC_HANDLE;
+   return sandbox_tpm2_fill_buf(recv, recv_len,
+tag, rc);
+   }
+
+   if (property > TPM2_PROPERTIES_OFFSET &&
+   ((property - TPM2_PROPERTIES_OFFSET) +
+property_count > TPM2_PROPERTY_NB)) {
+   rc = TPM2_RC_HANDLE;
+   return sandbox_tpm2_fill_buf(recv, recv_len,
+tag, rc);
+   }
+   break;
+   default:
+   printf("Sandbox TPM2 only supports TPM2_CAP_PCRS or "
+  "TPM2_CAP_TPM_PROPERTIES\n");
rc = TPM2_RC_HANDLE;
return sandbox_tpm2_fill_buf(recv, recv_len, tag, rc);
}
@@ -578,18 +587,53 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const 
u8 *sendbuf,
put_unaligned_be32(capability, recv);
recv += sizeof(capability);
 
-   /* Give the number of properties that follow */
-   put_unaligned_be32(property_count, recv);
-   recv += sizeof(property_count);
-
-   /* Fill with the properties */
-   for (i = 0; i < property_count; i++) {
-   put_unaligned_be32(TPM2_PROPERTIES_OFFSET + property +
-  i, recv);
-   recv += sizeof(property);
-   put_unaligned_be32(tpm->properties[property + i],
-  recv);
-   recv += sizeof(property);
+   switch (capability) {
+   case TPM2_CAP_PCRS:
+   /* Give the number of algorithms supported - just 
SHA256 */
+   put_unaligned_be32(1, recv);
+   recv += sizeof(u32);
+
+   /* Give SHA256 algorithm */
+   put_unaligned_be16(TPM2_ALG_SHA256, recv);
+   recv += sizeof(u16);
+
+   /* Select the PCRs supported */
+   *recv = SANDBOX_TPM_PCR_SELECT_MAX;
+   recv++;
+
+   /* Activate all the PCR bits */
+   for (i = 0; i < SANDBOX_TPM_PCR_SELECT_

Re: [PATCH v4 3/6] bootm: Support boot measurement

2023-01-26 Thread Eddie James



On 1/25/23 19:41, Simon Glass wrote:

Hi Eddie,

On Wed, 25 Jan 2023 at 10:18, Eddie James  wrote:

Add a configuration option to measure the boot through the bootm
function. Add the measurement state to the booti and bootz paths
as well.

Signed-off-by: Eddie James 
---
  boot/Kconfig| 23 
  boot/bootm.c| 70 +
  cmd/booti.c |  1 +
  cmd/bootm.c |  2 ++
  cmd/bootz.c |  1 +
  include/bootm.h |  2 ++
  include/image.h |  1 +
  7 files changed, 100 insertions(+)

Can you please add a change log? I recall making comments but cannot
see the changes here.



Sorry, sure. I put them all in the cover letter, but I can add them here 
too.


Thanks,

Eddie




Regards,
Simon


Re: [PATCH v3 2/6] tpm: Support boot measurements

2023-01-23 Thread Eddie James



On 1/16/23 06:00, Ilias Apalodimas wrote:

Hi Eddie



+static inline u16 tpm2_algorithm_to_len(enum tpm2_algorithms a)
+{
+   switch (a) {
+   case TPM2_ALG_SHA1:
+   return TPM2_SHA1_DIGEST_SIZE;
+   case TPM2_ALG_SHA256:
+   return TPM2_SHA256_DIGEST_SIZE;
+   case TPM2_ALG_SHA384:
+   return TPM2_SHA384_DIGEST_SIZE;
+   case TPM2_ALG_SHA512:
+   return TPM2_SHA512_DIGEST_SIZE;
+   default:
+   return 0;
+   }
+}

Any reason we can't move the static 'const struct digest_info
hash_algo_list' from the efi_tcg.c here?  We can then move the
functions defined in there alg_to_mask and alg_to_len.

And since alg_to_mask is really just a bitshift maybe replace that?



Hi,

It seems more efficient to keep the switch statement rather than iterate 
through the structure array looking for the matching hash algorithm? I 
could remove the 'static const struct digest_info hash_algo_list' in 
efi_tcg2.c and instead use the tpm2_algorithm_to_len and 
tpm2_algorithm_to_mask in efi_tcg2.c. What do you think?




+
+#define tpm2_algorithm_to_mask(a)  (1 << (a))
+
  /* NV index attributes */
  enum tpm_index_attrs {
TPMA_NV_PPWRITE = 1UL << 0,
@@ -419,6 +481,142 @@ enum {
HR_NV_INDEX = TPM_HT_NV_INDEX << HR_SHIFT,
  };

+/**
+ * struct tcg2_event_log - Container for managing the platform event log
+ *
+ * @log:   Address of the log
+ * @log_position:  Current entry position
+ * @log_size:  Log space available
+ */
+struct tcg2_event_log {
+   u8 *log;
+   u32 log_position;



-   }
-   }
-
-   *pcr_banks = pcrs.count;
-
-   return 0;
-out:
-   return -1;
-}
-
  /**
   * __get_active_pcr_banks() - returns the currently active PCR banks
   *
@@ -638,7 +378,7 @@ static efi_status_t __get_active_pcr_banks(u32 
*active_pcr_banks)
efi_status_t ret;
int err;

-   ret = platform_get_tpm2_device();
+   ret = tcg2_platform_get_tpm2();
if (ret != EFI_SUCCESS)
goto out;


We can get rid of this entirely and just define the
efi_tcg2_get_active_pcr_banks in the efi_tcg.c now.
__get_active_pcr_banks == tcg2_get_active_pcr_banks with the only
diffence being the udevice which is now an argument



Ack.





@@ -654,70 +394,6 @@ out:
return ret;
  }

   * efi_tcg2_get_capability() - protocol capability information and state 
information
   *
@@ -759,7 +435,7 @@ efi_tcg2_get_capability(struct efi_tcg2_protocol *this,
capability->protocol_version.major = 1;
capability->protocol_version.minor = 1;



+
+static int tcg2_log_append_check(struct tcg2_event_log *elog, u32 pcr_index,
+u32 event_type,
+struct tpml_digest_values *digest_list,
+u32 size, const u8 *event)
+{
+   u32 event_size;
+   u8 *log;
+
+   event_size = size + tcg2_event_get_size(digest_list);
+   if (elog->log_position + event_size > elog->log_size) {
+   printf("%s: log too large: %u + %u > %u\n", __func__,
+  elog->log_position, event_size, elog->log_size);
+   return -ENOBUFS;
+   }
+
+   log = elog->log + elog->log_position;
+   elog->log_position += event_size;
+
+   tcg2_log_append(pcr_index, event_type, digest_list, size, event, log);
+
+   return 0;
+}
+
+static int tcg2_log_init(struct udevice *dev, struct tcg2_event_log *elog)
+{

I think we need to re-use efi_init_event_log here.  The reason is that on
Arm devices TF-A is capable of constructing an eventlog and passing it
along in memory.  That code takes that into account and tries to reuse the
existing EventLog passed from previous boot stages.

The main difference between the EFI function and this one
is the allocated memory of the EventLog itself.  But even in this case, it
would be better to tweak the EFI code and do
create log -> Allocate EFI memory -> copy log and then use that for EFI



OK... I'll try and get that to work. I see some potential issues like 
the fact that EFI finds the platform event log differently.






+   struct tcg_efi_spec_id_event *ev;
+   struct tcg_pcr_event *log;
+   u32 event_size;
+   u32 count = 0;
+   u32 log_size;
+   u32 active;
+   u32 mask;
+   size_t i;
+   u16 len;
+   int rc;
+
+   rc = tcg2_get_active_pcr_banks(dev, );
+   if (rc)
+   return rc;
+
+   event_size = offsetof(struct tcg_efi_spec_id_event, digest_sizes);
+   for (i = 0; i < ARRAY_SIZE(tcg2algos); ++i) {
+   mask = tpm2_algorithm_to_mask(tcg2algos[i]);
+
+   if (!(active & mask))
+   continue;
+
+   switch (tcg2algos[i]) {
+   case TPM2_ALG_SHA1:
+   case TPM2_ALG_SHA256:
+   case TPM2_ALG_SHA384:
+   case 

[PATCH v9 0/6] tpm: Support boot measurements

2023-03-08 Thread Eddie James
This series adds support for measuring the boot images more generically
than the existing EFI support. Several EFI functions have been moved to
the TPM layer. The series includes optional measurement from the bootm 
command.
A new test case has been added for the bootm measurement to test the new
path, and the sandbox TPM2 driver has been updated to support this use
case.
This series is based on Ilias' auto-startup series and Simon's additions.

Changes since v8:
 - Fix a sandbox driver off-by-one error in checking the property type.
 - Fix log parsing again - any data corruption seen while replaying the
   event log was failing the entire measurement.
 - Added an option to ignore the existing log and a configuration option
   for systems to select that for the bootm measurement. This would only
   be selected for systems that know that U-Boot is the first stage
   bootloader. This is necessary because the reserved memory region may
   persist through resets and so U-Boot attempts to append to the
   previous boot's log.

Changes since v7:
 - Change name of tcg2_init_log and add more documentation
 - Add a check, when parsing the event log header, to ensure that the
   previous stage bootloader used all the active PCRs.
 - Change name of tcg2_log_find_end
 - Fix the greater than or equal to check to exit the log parsing
 - Make sure log_position is 0 if there is any error discovering the log
 - Return errors parsing the log if the data is corrupt so that we don't
   end up with half a log

Changes since v6:
 - Added comment for bootm_measure
 - Fixed line length in bootm_measure
 - Added Linaro copyright for all the EFI moved code
 - Changed tcg2_init_log (and by extension, tcg2_measurement_init) to
   copy any discovered event log to the user's log if passed in.

Changes since v5:
 - Re-ordered the patches to put the sandbox TPM driver patch second
 - Remove unused platform_get_eventlog in efi_tcg2.c
 - First look for tpm_event_log_* properties instead of linux,sml-*
 - Fix efi_tcg2.c compilation
 - Select SHA* configs
 - Remove the !SANDBOX dependency for EFI TCG2
 - Only compile in the measurement u-boot command when CONFIG_MEASURED_BOOT
   is enabled

Changes since v4:
 - Remove tcg2_measure_event function and check for NULL data in
   tcg2_measure_data
 - Use tpm_auto_startup
 - Fix efi_tcg2.c compilation for removing tcg2_pcr_read function
 - Change PCR indexes for initrd and dtb
 - Drop u8 casting in measurement test
 - Use bullets in documentation

Changes since v3:
 - Reordered headers
 - Refactored more of EFI code into common code
Removed digest_info structure and instead used the common alg_to_mask
  and alg_to_len
Improved event log parsing in common code to get it equivalent to EFI
  Common code now extends PCR if previous bootloader stage couldn't
  No need to allocate memory in the common code, so EFI copies the
  discovered buffer like it did before
Rename efi measure_event function

Changes since v2:
 - Add documentation.
 - Changed reserved memory address to the top of the RAM for sandbox dts.
 - Add measure state to booti and bootz.
 - Skip measurement for EFI images that should be measured

Changes since v1:
 - Refactor TPM layer functions to allow EFI system to use them, and
   remove duplicate EFI functions.
 - Add test case
 - Drop #ifdefs for bootm
 - Add devicetree measurement config option
 - Update sandbox TPM driver

Eddie James (6):
  tpm: Fix spelling for tpmu_ha union
  tpm: sandbox: Update for needed TPM2 capabilities
  tpm: Support boot measurements
  bootm: Support boot measurement
  test: Add sandbox TPM boot measurement
  doc: Add measured boot documentation

 arch/sandbox/dts/sandbox.dtsi  |   13 +
 arch/sandbox/dts/test.dts  |   13 +
 boot/Kconfig   |   32 +
 boot/bootm.c   |   74 +++
 cmd/booti.c|1 +
 cmd/bootm.c|2 +
 cmd/bootz.c|1 +
 configs/sandbox_defconfig  |1 +
 doc/usage/index.rst|1 +
 doc/usage/measured_boot.rst|   23 +
 drivers/tpm/tpm2_tis_sandbox.c |  100 ++-
 include/bootm.h|   11 +
 include/efi_tcg2.h |   44 --
 include/image.h|1 +
 include/test/suites.h  |1 +
 include/tpm-v2.h   |  263 +++-
 lib/Kconfig|4 +
 lib/efi_loader/Kconfig |2 -
 lib/efi_loader/efi_tcg2.c  | 1054 +++-
 lib/tpm-v2.c   |  814 
 test/boot/Makefile |1 +
 test/boot/measurement.c|   66 ++
 test/cmd_ut.c  |4 +
 23 files changed, 1473 insertions(+), 1053 deletions(-)
 create mode 100644 doc/usage/measured_boot.rst
 create mode 100644 test/boot/measurement.c

-- 
2.31.1



[PATCH v9 5/6] test: Add sandbox TPM boot measurement

2023-03-08 Thread Eddie James
Use the sandbox TPM driver to measure some boot images in a unit
test case.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
Acked-by: Ilias Apalodimas 
---
Changes since v5:
 - Only compile in the measurement u-boot command when
   CONFIG_MEASURED_BOOT is enabled.

 arch/sandbox/dts/sandbox.dtsi | 13 +++
 arch/sandbox/dts/test.dts | 13 +++
 configs/sandbox_defconfig |  1 +
 include/test/suites.h |  1 +
 test/boot/Makefile|  1 +
 test/boot/measurement.c   | 66 +++
 test/cmd_ut.c |  4 +++
 7 files changed, 99 insertions(+)
 create mode 100644 test/boot/measurement.c

diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index 7e7fcff6d2..3442be7634 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -4,11 +4,23 @@
  * and sandbox64 builds.
  */
 
+#include 
 #include 
 
 #define USB_CLASS_HUB  9
 
 / {
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   event_log: tcg_event_log {
+   no-map;
+   reg = <(CFG_SYS_SDRAM_SIZE - 0x2000) 0x2000>;
+   };
+   };
+
binman {
};
 
@@ -336,6 +348,7 @@
 
tpm2 {
compatible = "sandbox,tpm2";
+   memory-region = <_log>;
};
 
triangle {
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 9717103f10..7659effa71 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -9,6 +9,7 @@
 
 /dts-v1/;
 
+#include 
 #include 
 #include 
 #include 
@@ -66,6 +67,17 @@
osd0 = "/osd";
};
 
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   event_log: tcg_event_log {
+   no-map;
+   reg = <(CFG_SYS_SDRAM_SIZE - 0x2000) 0x2000>;
+   };
+   };
+
binman: binman {
};
 
@@ -1365,6 +1377,7 @@
 
tpm2 {
compatible = "sandbox,tpm2";
+   memory-region = <_log>;
};
 
tpm {
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 77ade1f1d8..43b15b8446 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -335,3 +335,4 @@ CONFIG_TEST_FDTDEC=y
 CONFIG_UNIT_TEST=y
 CONFIG_UT_TIME=y
 CONFIG_UT_DM=y
+CONFIG_MEASURED_BOOT=y
diff --git a/include/test/suites.h b/include/test/suites.h
index 7c4960c004..b552fea9a9 100644
--- a/include/test/suites.h
+++ b/include/test/suites.h
@@ -44,6 +44,7 @@ int do_ut_font(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[]);
 int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_loadm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_log(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]);
+int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc, char * const 
argv[]);
 int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc,
diff --git a/test/boot/Makefile b/test/boot/Makefile
index 22ed61c8fa..2dbb032a7e 100644
--- a/test/boot/Makefile
+++ b/test/boot/Makefile
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_BOOTSTD) += bootdev.o bootstd_common.o bootflow.o bootmeth.o
 obj-$(CONFIG_FIT) += image.o
+obj-$(CONFIG_MEASURED_BOOT) += measurement.o
 
 obj-$(CONFIG_EXPO) += expo.o
 
diff --git a/test/boot/measurement.c b/test/boot/measurement.c
new file mode 100644
index 00..9db2ed324c
--- /dev/null
+++ b/test/boot/measurement.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test for measured boot functions
+ *
+ * Copyright 2023 IBM Corp.
+ * Written by Eddie James 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MEASUREMENT_TEST(_name, _flags)\
+   UNIT_TEST(_name, _flags, measurement_test)
+
+static int measure(struct unit_test_state *uts)
+{
+   struct bootm_headers images;
+   const size_t size = 1024;
+   u8 *kernel;
+   u8 *initrd;
+   size_t i;
+
+   kernel = malloc(size);
+   initrd = malloc(size);
+
+   images.os.image_start = map_to_sysmem(kernel);
+   images.os.image_len = size;
+
+   images.rd_start = map_to_sysmem(initrd);
+   images.rd_end = images.rd_start + size;
+
+   images.ft_addr = malloc(size);
+   images.ft_len = size;
+
+   env_set("bootargs", "measurement testing");
+
+   for (i = 0; i < size; ++i) {
+   kernel[i] = 0xf0 | (i & 0xf);
+   initrd[i] = (i & 0xf0) | 0xf;
+

[PATCH v9 1/6] tpm: Fix spelling for tpmu_ha union

2023-03-08 Thread Eddie James
tmpu -> tpmu

Signed-off-by: Eddie James 
Reviewed-by: Ilias Apalodimas 
---
 include/tpm-v2.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 2b6980e441..6684033deb 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -169,7 +169,7 @@ struct tcg_pcr_event {
 /**
  * Definition of TPMU_HA Union
  */
-union tmpu_ha {
+union tpmu_ha {
u8 sha1[TPM2_SHA1_DIGEST_SIZE];
u8 sha256[TPM2_SHA256_DIGEST_SIZE];
u8 sm3_256[TPM2_SM3_256_DIGEST_SIZE];
@@ -185,7 +185,7 @@ union tmpu_ha {
  */
 struct tpmt_ha {
u16 hash_alg;
-   union tmpu_ha digest;
+   union tpmu_ha digest;
 } __packed;
 
 /**
-- 
2.31.1



Re: [PATCH v8 0/6] tpm: Support boot measurements

2023-03-08 Thread Eddie James



On 3/6/23 00:58, Ilias Apalodimas wrote:

Hi Eddie,

This has a few failures on the CI [0].
Please have a look and let me know if you can't understand the failures



Hi, I think I have fixed the sandbox ones for v9. I'm unsure about the 
EFI selftest one in qemu targets...



Thanks,

Eddie




[0] https://source.denx.de/u-boot/custodians/u-boot-tpm/-/pipelines/15471

Regards
/Ilias
On Fri, Mar 03, 2023 at 01:25:00PM -0600, Eddie James wrote:

This series adds support for measuring the boot images more generically
than the existing EFI support. Several EFI functions have been moved to
the TPM layer. The series includes optional measurement from the bootm
command.
A new test case has been added for the bootm measurement to test the new
path, and the sandbox TPM2 driver has been updated to support this use
case.
This series is based on Ilias' auto-startup series and Simon's additions.

Changes since v7:
  - Change name of tcg2_init_log and add more documentation
  - Add a check, when parsing the event log header, to ensure that the
previous stage bootloader used all the active PCRs.
  - Change name of tcg2_log_find_end
  - Fix the greater than or equal to check to exit the log parsing
  - Make sure log_position is 0 if there is any error discovering the log
  - Return errors parsing the log if the data is corrupt so that we don't
end up with half a log

Changes since v6:
  - Added comment for bootm_measure
  - Fixed line length in bootm_measure
  - Added Linaro copyright for all the EFI moved code
  - Changed tcg2_init_log (and by extension, tcg2_measurement_init) to
copy any discovered event log to the user's log if passed in.

Changes since v5:
  - Re-ordered the patches to put the sandbox TPM driver patch second
  - Remove unused platform_get_eventlog in efi_tcg2.c
  - First look for tpm_event_log_* properties instead of linux,sml-*
  - Fix efi_tcg2.c compilation
  - Select SHA* configs
  - Remove the !SANDBOX dependency for EFI TCG2
  - Only compile in the measurement u-boot command when CONFIG_MEASURED_BOOT
is enabled

Changes since v4:
  - Remove tcg2_measure_event function and check for NULL data in
tcg2_measure_data
  - Use tpm_auto_startup
  - Fix efi_tcg2.c compilation for removing tcg2_pcr_read function
  - Change PCR indexes for initrd and dtb
  - Drop u8 casting in measurement test
  - Use bullets in documentation

Changes since v3:
  - Reordered headers
  - Refactored more of EFI code into common code
 Removed digest_info structure and instead used the common alg_to_mask
   and alg_to_len
 Improved event log parsing in common code to get it equivalent to EFI
   Common code now extends PCR if previous bootloader stage couldn't
   No need to allocate memory in the common code, so EFI copies the
   discovered buffer like it did before
 Rename efi measure_event function

Changes since v2:
  - Add documentation.
  - Changed reserved memory address to the top of the RAM for sandbox dts.
  - Add measure state to booti and bootz.
  - Skip measurement for EFI images that should be measured

Changes since v1:
  - Refactor TPM layer functions to allow EFI system to use them, and
remove duplicate EFI functions.
  - Add test case
  - Drop #ifdefs for bootm
  - Add devicetree measurement config option
  - Update sandbox TPM driver

Eddie James (6):
   tpm: Fix spelling for tpmu_ha union
   tpm: sandbox: Update for needed TPM2 capabilities
   tpm: Support boot measurements
   bootm: Support boot measurement
   test: Add sandbox TPM boot measurement
   doc: Add measured boot documentation

  arch/sandbox/dts/sandbox.dtsi  |   13 +
  arch/sandbox/dts/test.dts  |   13 +
  boot/Kconfig   |   23 +
  boot/bootm.c   |   72 +++
  cmd/booti.c|1 +
  cmd/bootm.c|2 +
  cmd/bootz.c|1 +
  configs/sandbox_defconfig  |1 +
  doc/usage/index.rst|1 +
  doc/usage/measured_boot.rst|   23 +
  drivers/tpm/tpm2_tis_sandbox.c |  100 ++-
  include/bootm.h|   11 +
  include/efi_tcg2.h |   44 --
  include/image.h|1 +
  include/test/suites.h  |1 +
  include/tpm-v2.h   |  255 +++-
  lib/Kconfig|4 +
  lib/efi_loader/Kconfig |2 -
  lib/efi_loader/efi_tcg2.c  | 1054 +++-
  lib/tpm-v2.c   |  815 
  test/boot/Makefile |1 +
  test/boot/measurement.c|   66 ++
  test/cmd_ut.c  |4 +
  23 files changed, 1455 insertions(+), 1053 deletions(-)
  create mode 100644 doc/usage/measured_boot.rst
  create mode 100644 test/boot/measurement.c

--
2.31.1



[PATCH v9 2/6] tpm: sandbox: Update for needed TPM2 capabilities

2023-03-08 Thread Eddie James
The driver needs to support getting the PCRs in the capabilities
command. Fix various other things and support the max number
of PCRs for TPM2.
Remove the !SANDBOX dependency for EFI TCG2 as well.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
Acked-by: Ilias Apalodimas 
---
Changes since v8:
 - Use >= for checking the property against TPM2_PROPERTIES_OFFSET

Changes since v5:
 - Remove the !SANDBOX dependency for EFI TCG2

 drivers/tpm/tpm2_tis_sandbox.c | 100 -
 lib/efi_loader/Kconfig |   2 -
 2 files changed, 72 insertions(+), 30 deletions(-)

diff --git a/drivers/tpm/tpm2_tis_sandbox.c b/drivers/tpm/tpm2_tis_sandbox.c
index e4004cfcca..d15a28d9fc 100644
--- a/drivers/tpm/tpm2_tis_sandbox.c
+++ b/drivers/tpm/tpm2_tis_sandbox.c
@@ -22,11 +22,6 @@ enum tpm2_hierarchy {
TPM2_HIERARCHY_NB,
 };
 
-/* Subset of supported capabilities */
-enum tpm2_capability {
-   TPM_CAP_TPM_PROPERTIES = 0x6,
-};
-
 /* Subset of supported properties */
 #define TPM2_PROPERTIES_OFFSET 0x020E
 
@@ -38,7 +33,8 @@ enum tpm2_cap_tpm_property {
TPM2_PROPERTY_NB,
 };
 
-#define SANDBOX_TPM_PCR_NB 1
+#define SANDBOX_TPM_PCR_NB TPM2_MAX_PCRS
+#define SANDBOX_TPM_PCR_SELECT_MAX ((SANDBOX_TPM_PCR_NB + 7) / 8)
 
 /*
  * Information about our TPM emulation. This is preserved in the sandbox
@@ -433,7 +429,7 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const u8 
*sendbuf,
int i, j;
 
/* TPM2_GetProperty */
-   u32 capability, property, property_count;
+   u32 capability, property, property_count, val;
 
/* TPM2_PCR_Read/Extend variables */
int pcr_index = 0;
@@ -542,19 +538,32 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const 
u8 *sendbuf,
case TPM2_CC_GET_CAPABILITY:
capability = get_unaligned_be32(sent);
sent += sizeof(capability);
-   if (capability != TPM_CAP_TPM_PROPERTIES) {
-   printf("Sandbox TPM only support TPM_CAPABILITIES\n");
-   return TPM2_RC_HANDLE;
-   }
-
property = get_unaligned_be32(sent);
sent += sizeof(property);
-   property -= TPM2_PROPERTIES_OFFSET;
-
property_count = get_unaligned_be32(sent);
sent += sizeof(property_count);
-   if (!property_count ||
-   property + property_count > TPM2_PROPERTY_NB) {
+
+   switch (capability) {
+   case TPM2_CAP_PCRS:
+   break;
+   case TPM2_CAP_TPM_PROPERTIES:
+   if (!property_count) {
+   rc = TPM2_RC_HANDLE;
+   return sandbox_tpm2_fill_buf(recv, recv_len,
+tag, rc);
+   }
+
+   if (property >= TPM2_PROPERTIES_OFFSET &&
+   ((property - TPM2_PROPERTIES_OFFSET) +
+property_count > TPM2_PROPERTY_NB)) {
+   rc = TPM2_RC_HANDLE;
+   return sandbox_tpm2_fill_buf(recv, recv_len,
+tag, rc);
+   }
+   break;
+   default:
+   printf("Sandbox TPM2 only supports TPM2_CAP_PCRS or "
+  "TPM2_CAP_TPM_PROPERTIES\n");
rc = TPM2_RC_HANDLE;
return sandbox_tpm2_fill_buf(recv, recv_len, tag, rc);
}
@@ -578,18 +587,53 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const 
u8 *sendbuf,
put_unaligned_be32(capability, recv);
recv += sizeof(capability);
 
-   /* Give the number of properties that follow */
-   put_unaligned_be32(property_count, recv);
-   recv += sizeof(property_count);
-
-   /* Fill with the properties */
-   for (i = 0; i < property_count; i++) {
-   put_unaligned_be32(TPM2_PROPERTIES_OFFSET + property +
-  i, recv);
-   recv += sizeof(property);
-   put_unaligned_be32(tpm->properties[property + i],
-  recv);
-   recv += sizeof(property);
+   switch (capability) {
+   case TPM2_CAP_PCRS:
+   /* Give the number of algorithms supported - just 
SHA256 */
+   put_unaligned_be32(1, recv);
+   recv += sizeof(u32);
+
+   /* Give SHA256 algorithm */
+   put_unaligned_be16(TPM2_ALG_SHA256, recv);
+   recv += sizeof(u16);
+
+   /* Se

[PATCH v9 4/6] bootm: Support boot measurement

2023-03-08 Thread Eddie James
Add a configuration option to measure the boot through the bootm
function. Add the measurement state to the booti and bootz paths
as well.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
---
Changes since v8:
 - Added a configuration option to select to ignore any existing
   event log. This would only be selected for systems that know
   that U-Boot is the first stage bootloader. This is necessary
   because the reserved memory region may persist through resets
   and so U-Boot attempts to append to the previous boot's log.

Changes since v6:
 - Added comment for bootm_measure
 - Fixed line length in bootm_measure

 boot/Kconfig| 32 +
 boot/bootm.c| 74 +
 cmd/booti.c |  1 +
 cmd/bootm.c |  2 ++
 cmd/bootz.c |  1 +
 include/bootm.h | 11 
 include/image.h |  1 +
 7 files changed, 122 insertions(+)

diff --git a/boot/Kconfig b/boot/Kconfig
index 5f491625c8..8119519c9f 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -629,6 +629,38 @@ config LEGACY_IMAGE_FORMAT
  loaded. If a board needs the legacy image format support in this
  case, enable it here.
 
+config MEASURED_BOOT
+   bool "Measure boot images and configuration to TPM and event log"
+   depends on HASH && TPM_V2
+   help
+ This option enables measurement of the boot process. Measurement
+ involves creating cryptographic hashes of the binary images that
+ are booting and storing them in the TPM. In addition, a log of
+ these hashes is stored in memory for the OS to verify the booted
+ images and configuration. Enable this if the OS has configured
+ some memory area for the event log and you intend to use some
+ attestation tools on your system.
+
+if MEASURED_BOOT
+   config MEASURE_DEVICETREE
+   bool "Measure the devicetree image"
+   default y if MEASURED_BOOT
+   help
+ On some platforms, the devicetree is not static as it may contain
+ random MAC addresses or other such data that changes each boot.
+ Therefore, it should not be measured into the TPM. In that case,
+ disable the measurement here.
+
+   config MEASURE_IGNORE_LOG
+   bool "Ignore the existing event log"
+   default n
+   help
+ On platforms that use an event log memory region that persists
+ through system resets and are the first stage bootloader, then
+ this option should be enabled to ignore any existing data in the
+ event log memory region.
+endif # MEASURED_BOOT
+
 config SUPPORT_RAW_INITRD
bool "Enable raw initrd images"
help
diff --git a/boot/bootm.c b/boot/bootm.c
index 2eec60ec7b..2685bdbd74 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #if defined(CONFIG_CMD_USB)
 #include 
 #endif
@@ -659,6 +660,75 @@ int bootm_process_cmdline_env(int flags)
return 0;
 }
 
+int bootm_measure(struct bootm_headers *images)
+{
+   int ret = 0;
+
+   /* Skip measurement if EFI is going to do it */
+   if (images->os.os == IH_OS_EFI &&
+   IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL) &&
+   IS_ENABLED(CONFIG_BOOTM_EFI))
+   return ret;
+
+   if (IS_ENABLED(CONFIG_MEASURED_BOOT)) {
+   struct tcg2_event_log elog;
+   struct udevice *dev;
+   void *initrd_buf;
+   void *image_buf;
+   const char *s;
+   u32 rd_len;
+   bool ign;
+
+   elog.log_size = 0;
+   ign = IS_ENABLED(CONFIG_MEASURE_IGNORE_LOG);
+   ret = tcg2_measurement_init(, , ign);
+   if (ret)
+   return ret;
+
+   image_buf = map_sysmem(images->os.image_start,
+  images->os.image_len);
+   ret = tcg2_measure_data(dev, , 8, images->os.image_len,
+   image_buf, EV_COMPACT_HASH,
+   strlen("linux") + 1, (u8 *)"linux");
+   if (ret)
+   goto unmap_image;
+
+   rd_len = images->rd_end - images->rd_start;
+   initrd_buf = map_sysmem(images->rd_start, rd_len);
+   ret = tcg2_measure_data(dev, , 9, rd_len, initrd_buf,
+   EV_COMPACT_HASH, strlen("initrd") + 1,
+   (u8 *)"initrd");
+   if (ret)
+   goto unmap_initrd;
+
+   if (IS_ENABLED(CONFIG_MEASURE_DEVICETREE)) {
+   ret = tcg2_measure_data(dev, , 0, images->ft_len,
+   (u8 *)images->ft_addr,
+  

[PATCH v9 6/6] doc: Add measured boot documentation

2023-03-08 Thread Eddie James
Briefly describe the feature and specify the requirements.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
---
 doc/usage/index.rst |  1 +
 doc/usage/measured_boot.rst | 23 +++
 2 files changed, 24 insertions(+)
 create mode 100644 doc/usage/measured_boot.rst

diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 840c20c934..1cb6988d8a 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -12,6 +12,7 @@ Use U-Boot
partitions
cmdline
semihosting
+   measured_boot
 
 Shell commands
 --
diff --git a/doc/usage/measured_boot.rst b/doc/usage/measured_boot.rst
new file mode 100644
index 00..8357b1f480
--- /dev/null
+++ b/doc/usage/measured_boot.rst
@@ -0,0 +1,23 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Measured Boot
+=
+
+U-Boot can perform a measured boot, the process of hashing various components
+of the boot process, extending the results in the TPM and logging the
+component's measurement in memory for the operating system to consume.
+
+Requirements
+-
+
+* A hardware TPM 2.0 supported by the U-Boot drivers
+* CONFIG_TPM=y
+* CONFIG_MEASURED_BOOT=y
+* Device-tree configuration of the TPM device to specify the memory area
+  for event logging. The TPM device node must either contain a phandle to
+  a reserved memory region or "linux,sml-base" and "linux,sml-size"
+  indicating the address and size of the memory region. An example can be
+  found in arch/sandbox/dts/test.dts
+* The operating system must also be configured to use the memory regions
+  specified in the U-Boot device-tree in order to make use of the event
+  log.
-- 
2.31.1



[PATCH v9 3/6] tpm: Support boot measurements

2023-03-08 Thread Eddie James
Add TPM2 functions to support boot measurement. This includes
starting up the TPM, initializing/appending the event log, and
measuring the U-Boot version. Much of the code was used in the
EFI subsystem, so remove it there and use the common functions.

Signed-off-by: Eddie James 
---
Changes since v8:
 - Fix log parsing again - any data corruption seen while replaying the
   event log was failing the entire measurement.
 - Added an option to ignore the existing log. This should only be used
   for systems that know that U-Boot is the first stage bootloader. This
   is necessary because the reserved memory region may persist through
   resets and so U-Boot attempts to append to the previous boot's log.

Changes since v7:
 - Change name of tcg2_init_log and add more documentation
 - Add a check, when parsing the event log header, to ensure that the
   previous stage bootloader used all the active PCRs.
 - Change name of tcg2_log_find_end
 - Fix the greater than or equal to check to exit the log parsing
 - Make sure log_position is 0 if there is any error discovering the log
 - Return errors parsing the log if the data is corrupt so that we don't
   end up with half a log

Changes since v6:
 - Added Linaro copyright for all the EFI moved code
 - Changed tcg2_init_log (and by extension, tcg2_measurement_init) to
   copy any discovered event log to the user's log if passed in.

Changes since v5:
 - Remove unused platform_get_eventlog in efi_tcg2.c
 - First look for tpm_event_log_* properties instead of linux,sml-*
 - Fix efi_tcg2.c compilation
 - Select SHA* configs

Changes since v4:
 - Remove tcg2_measure_event function and check for NULL data in
   tcg2_measure_data
 - Use tpm_auto_startup
 - Fix efi_tcg2.c compilation for removing tcg2_pcr_read function

Changes since v3:
 - Reordered headers
 - Refactored more of EFI code into common code
Removed digest_info structure and instead used the common alg_to_mask
  and alg_to_len
Improved event log parsing in common code to get it equivalent to EFI
  Common code now extends PCR if previous bootloader stage couldn't
  No need to allocate memory in the common code, so EFI copies the
  discovered buffer like it did before
Rename efi measure_event function

Changes since v1:
 - Refactor TPM layer functions to allow EFI system to use them, and
   remove duplicate EFI functions

 include/efi_tcg2.h|   44 --
 include/tpm-v2.h  |  259 +
 lib/Kconfig   |4 +
 lib/efi_loader/efi_tcg2.c | 1054 +++--
 lib/tpm-v2.c  |  814 
 5 files changed, 1154 insertions(+), 1021 deletions(-)

diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
index b1c3abd097..b21c5cb3dd 100644
--- a/include/efi_tcg2.h
+++ b/include/efi_tcg2.h
@@ -129,50 +129,6 @@ struct efi_tcg2_boot_service_capability {
 #define BOOT_SERVICE_CAPABILITY_MIN \
offsetof(struct efi_tcg2_boot_service_capability, number_of_pcr_banks)
 
-#define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03"
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0
-#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2
-
-/**
- *  struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm information
- *
- *  @algorithm_id: algorithm defined in enum tpm2_algorithms
- *  @digest_size:  size of the algorithm
- */
-struct tcg_efi_spec_id_event_algorithm_size {
-   u16  algorithm_id;
-   u16  digest_size;
-} __packed;
-
-/**
- * struct TCG_EfiSpecIDEventStruct - content of the event log header
- *
- * @signature: signature, set to Spec ID Event03
- * @platform_class:class defined in TCG ACPI Specification
- * Client  Common Header.
- * @spec_version_minor:minor version
- * @spec_version_major:major version
- * @spec_version_errata:   major version
- * @uintn_size:size of the efi_uintn_t fields used in 
various
- * data structures used in this specification.
- * 0x01 indicates u32  and 0x02  indicates u64
- * @number_of_algorithms:  hashing algorithms used in this event log
- * @digest_sizes:  array of number_of_algorithms pairs
- * 1st member defines the algorithm id
- * 2nd member defines the algorithm size
- */
-struct tcg_efi_spec_id_event {
-   u8 signature[16];
-   u32 platform_class;
-   u8 spec_version_minor;
-   u8 spec_version_major;
-   u8 spec_errata;
-   u8 uintn_size;
-   u32 number_of_algorithms;
-   struct tcg_efi_spec_id_event_algorithm_size digest_sizes[];
-} __packed;
-
 /**
  * struct tdEFI_TCG2_FINAL_EVENTS_TABLE - log entries after Get Event Log
  * @version:   version number for this structure

Re: [PATCH v5 0/6] tpm: Support boot measurements

2023-02-22 Thread Eddie James



On 2/22/23 05:33, Ilias Apalodimas wrote:

Hi Eddie,

On Tue, Feb 21, 2023 at 04:38:58PM -0600, Eddie James wrote:

On 2/6/23 06:20, Ilias Apalodimas wrote:

Thanks Eddie,

I quickly tested this but the EFI subsystem fails to initialize the TCG
protocol properly now.  Unfortunately I am on a business trip and I won't
be able to take a look into why till next week


Hi Ilias,


I haven't had the opportunity to test this, have you?


Thanks,

Eddie



Cheers
/Ilias


Still going through the code so bear with me.
It seems that the EFI failure is coming from tcg2_platform_get_log()
specifically if none of linux,sml-base nor tpm_event_log_addr if present in
the dtb.
One thing we should change here is look for tpm_event_log_addr first.  The
reason is that this is a very 'special' case in which TF-A fills in an
eventlog for us, while linux,sml-base is more generic so I'd rather
explicitly prefer TF-A id it prepared an eventlog for us.



OK, thanks, this is helpful, I'll have a look.




On the failure now, if none of the nodes is present we are looking for
'memory-region' within the TPM node?  Looking at the DT specs the tpm
should only support "compatible, label, linux,sml-base/size' am I missing
something?



I just had a commit merged for the reserved memory region: 
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/drivers/char/tpm/eventlog/of.c?id=1e2714bb83fc783d58701967391bea242c65eaff


It isn't documented anywhere so far...


Thanks,

Eddie




I also had to apply [0] for this to compile.  You can 'easily' test the EFI
changes by doing a 'printenv -e'.  This will at least initialize the efi
subsystem and install the needed EFI tables (you need CMD_NVEDIT_EFI=y)

[0] 
https://source.denx.de/u-boot/custodians/u-boot-tpm/-/commit/d473596cd6900117485014476c70c49f202bd8da


Hope this helps a bit. Let me know if I can help in any other way.
Don't bother *testing* the eventlog for EFI on a full linux boot. I'll run
that on v6

/Ilias



On Thu, Feb 02, 2023 at 11:05:25AM -0600, Eddie James wrote:

This series adds support for measuring the boot images more generically
than the existing EFI support. Several EFI functions have been moved to
the TPM layer. The series includes optional measurement from the bootm
command.
A new test case has been added for the bootm measurement to test the new
path, and the sandbox TPM2 driver has been updated to support this use
case.
This series is based on Ilias' auto-startup series:
https://lore.kernel.org/u-boot/20230126081844.591148-1-ilias.apalodi...@linaro.org/

Changes since v4:
   - Remove tcg2_measure_event function and check for NULL data in
 tcg2_measure_data
   - Use tpm_auto_startup
   - Fix efi_tcg2.c compilation for removing tcg2_pcr_read function
   - Change PCR indexes for initrd and dtb
   - Drop u8 casting in measurement test
   - Use bullets in documentation

Changes since v3:
   - Reordered headers
   - Refactored more of EFI code into common code
  Removed digest_info structure and instead used the common alg_to_mask
and alg_to_len
  Improved event log parsing in common code to get it equivalent to EFI
Common code now extends PCR if previous bootloader stage couldn't
No need to allocate memory in the common code, so EFI copies the
discovered buffer like it did before
  Rename efi measure_event function

Changes since v2:
   - Add documentation.
   - Changed reserved memory address to the top of the RAM for sandbox dts.
   - Add measure state to booti and bootz.
   - Skip measurement for EFI images that should be measured

Changes since v1:
   - Refactor TPM layer functions to allow EFI system to use them, and
 remove duplicate EFI functions.
   - Add test case
   - Drop #ifdefs for bootm
   - Add devicetree measurement config option
   - Update sandbox TPM driver

Eddie James (6):
tpm: Fix spelling for tpmu_ha union
tpm: Support boot measurements
bootm: Support boot measurement
tpm: sandbox: Update for needed TPM2 capabilities
test: Add sandbox TPM boot measurement
doc: Add measured boot documentation

   arch/sandbox/dts/sandbox.dtsi  |   14 +
   arch/sandbox/dts/test.dts  |   13 +
   boot/Kconfig   |   23 +
   boot/bootm.c   |   70 +++
   cmd/booti.c|1 +
   cmd/bootm.c|2 +
   cmd/bootz.c|1 +
   configs/sandbox_defconfig  |1 +
   doc/usage/index.rst|1 +
   doc/usage/measured_boot.rst|   23 +
   drivers/tpm/tpm2_tis_sandbox.c |  100 +++-
   include/bootm.h|2 +
   include/efi_tcg2.h |   44 --
   include/image.h|1 +
   include/test/suites.h  |1 +
   include/tpm-v2.h   |  246 +++-
   lib/efi_loader/efi_tcg2.c  | 1010 +++-
   lib/tpm-v2.c   |  771 
   test/boot/Mak

[PATCH v8 5/6] test: Add sandbox TPM boot measurement

2023-03-03 Thread Eddie James
Use the sandbox TPM driver to measure some boot images in a unit
test case.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
Acked-by: Ilias Apalodimas 
---
Changes since v5:
 - Only compile in the measurement u-boot command when CONFIG_MEASURED_BOOT
   is enabled

 arch/sandbox/dts/sandbox.dtsi | 13 +++
 arch/sandbox/dts/test.dts | 13 +++
 configs/sandbox_defconfig |  1 +
 include/test/suites.h |  1 +
 test/boot/Makefile|  1 +
 test/boot/measurement.c   | 66 +++
 test/cmd_ut.c |  4 +++
 7 files changed, 99 insertions(+)
 create mode 100644 test/boot/measurement.c

diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index 7e7fcff6d2..3442be7634 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -4,11 +4,23 @@
  * and sandbox64 builds.
  */
 
+#include 
 #include 
 
 #define USB_CLASS_HUB  9
 
 / {
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   event_log: tcg_event_log {
+   no-map;
+   reg = <(CFG_SYS_SDRAM_SIZE - 0x2000) 0x2000>;
+   };
+   };
+
binman {
};
 
@@ -336,6 +348,7 @@
 
tpm2 {
compatible = "sandbox,tpm2";
+   memory-region = <_log>;
};
 
triangle {
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 9717103f10..7659effa71 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -9,6 +9,7 @@
 
 /dts-v1/;
 
+#include 
 #include 
 #include 
 #include 
@@ -66,6 +67,17 @@
osd0 = "/osd";
};
 
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   event_log: tcg_event_log {
+   no-map;
+   reg = <(CFG_SYS_SDRAM_SIZE - 0x2000) 0x2000>;
+   };
+   };
+
binman: binman {
};
 
@@ -1365,6 +1377,7 @@
 
tpm2 {
compatible = "sandbox,tpm2";
+   memory-region = <_log>;
};
 
tpm {
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 77ade1f1d8..43b15b8446 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -335,3 +335,4 @@ CONFIG_TEST_FDTDEC=y
 CONFIG_UNIT_TEST=y
 CONFIG_UT_TIME=y
 CONFIG_UT_DM=y
+CONFIG_MEASURED_BOOT=y
diff --git a/include/test/suites.h b/include/test/suites.h
index 7c4960c004..b552fea9a9 100644
--- a/include/test/suites.h
+++ b/include/test/suites.h
@@ -44,6 +44,7 @@ int do_ut_font(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[]);
 int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_loadm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_log(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]);
+int do_ut_measurement(struct cmd_tbl *cmdtp, int flag, int argc, char * const 
argv[]);
 int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
 int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc,
diff --git a/test/boot/Makefile b/test/boot/Makefile
index 22ed61c8fa..2dbb032a7e 100644
--- a/test/boot/Makefile
+++ b/test/boot/Makefile
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_BOOTSTD) += bootdev.o bootstd_common.o bootflow.o bootmeth.o
 obj-$(CONFIG_FIT) += image.o
+obj-$(CONFIG_MEASURED_BOOT) += measurement.o
 
 obj-$(CONFIG_EXPO) += expo.o
 
diff --git a/test/boot/measurement.c b/test/boot/measurement.c
new file mode 100644
index 00..9db2ed324c
--- /dev/null
+++ b/test/boot/measurement.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test for measured boot functions
+ *
+ * Copyright 2023 IBM Corp.
+ * Written by Eddie James 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MEASUREMENT_TEST(_name, _flags)\
+   UNIT_TEST(_name, _flags, measurement_test)
+
+static int measure(struct unit_test_state *uts)
+{
+   struct bootm_headers images;
+   const size_t size = 1024;
+   u8 *kernel;
+   u8 *initrd;
+   size_t i;
+
+   kernel = malloc(size);
+   initrd = malloc(size);
+
+   images.os.image_start = map_to_sysmem(kernel);
+   images.os.image_len = size;
+
+   images.rd_start = map_to_sysmem(initrd);
+   images.rd_end = images.rd_start + size;
+
+   images.ft_addr = malloc(size);
+   images.ft_len = size;
+
+   env_set("bootargs", "measurement testing");
+
+   for (i = 0; i < size; ++i) {
+   kernel[i] = 0xf0 | (i & 0xf);
+   initrd[i] = (i & 0xf0) | 0xf;
+

[PATCH v8 2/6] tpm: sandbox: Update for needed TPM2 capabilities

2023-03-03 Thread Eddie James
The driver needs to support getting the PCRs in the capabilities
command. Fix various other things and support the max number
of PCRs for TPM2.
Remove the !SANDBOX dependency for EFI TCG2 as well.

Signed-off-by: Eddie James 
Reviewed-by: Simon Glass 
Acked-by: Ilias Apalodimas 
---
Changes since v5:
 - Remove the !SANDBOX dependency for EFI TCG2

 drivers/tpm/tpm2_tis_sandbox.c | 100 -
 lib/efi_loader/Kconfig |   2 -
 2 files changed, 72 insertions(+), 30 deletions(-)

diff --git a/drivers/tpm/tpm2_tis_sandbox.c b/drivers/tpm/tpm2_tis_sandbox.c
index e4004cfcca..f63c72814f 100644
--- a/drivers/tpm/tpm2_tis_sandbox.c
+++ b/drivers/tpm/tpm2_tis_sandbox.c
@@ -22,11 +22,6 @@ enum tpm2_hierarchy {
TPM2_HIERARCHY_NB,
 };
 
-/* Subset of supported capabilities */
-enum tpm2_capability {
-   TPM_CAP_TPM_PROPERTIES = 0x6,
-};
-
 /* Subset of supported properties */
 #define TPM2_PROPERTIES_OFFSET 0x020E
 
@@ -38,7 +33,8 @@ enum tpm2_cap_tpm_property {
TPM2_PROPERTY_NB,
 };
 
-#define SANDBOX_TPM_PCR_NB 1
+#define SANDBOX_TPM_PCR_NB TPM2_MAX_PCRS
+#define SANDBOX_TPM_PCR_SELECT_MAX ((SANDBOX_TPM_PCR_NB + 7) / 8)
 
 /*
  * Information about our TPM emulation. This is preserved in the sandbox
@@ -433,7 +429,7 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const u8 
*sendbuf,
int i, j;
 
/* TPM2_GetProperty */
-   u32 capability, property, property_count;
+   u32 capability, property, property_count, val;
 
/* TPM2_PCR_Read/Extend variables */
int pcr_index = 0;
@@ -542,19 +538,32 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const 
u8 *sendbuf,
case TPM2_CC_GET_CAPABILITY:
capability = get_unaligned_be32(sent);
sent += sizeof(capability);
-   if (capability != TPM_CAP_TPM_PROPERTIES) {
-   printf("Sandbox TPM only support TPM_CAPABILITIES\n");
-   return TPM2_RC_HANDLE;
-   }
-
property = get_unaligned_be32(sent);
sent += sizeof(property);
-   property -= TPM2_PROPERTIES_OFFSET;
-
property_count = get_unaligned_be32(sent);
sent += sizeof(property_count);
-   if (!property_count ||
-   property + property_count > TPM2_PROPERTY_NB) {
+
+   switch (capability) {
+   case TPM2_CAP_PCRS:
+   break;
+   case TPM2_CAP_TPM_PROPERTIES:
+   if (!property_count) {
+   rc = TPM2_RC_HANDLE;
+   return sandbox_tpm2_fill_buf(recv, recv_len,
+tag, rc);
+   }
+
+   if (property > TPM2_PROPERTIES_OFFSET &&
+   ((property - TPM2_PROPERTIES_OFFSET) +
+property_count > TPM2_PROPERTY_NB)) {
+   rc = TPM2_RC_HANDLE;
+   return sandbox_tpm2_fill_buf(recv, recv_len,
+tag, rc);
+   }
+   break;
+   default:
+   printf("Sandbox TPM2 only supports TPM2_CAP_PCRS or "
+  "TPM2_CAP_TPM_PROPERTIES\n");
rc = TPM2_RC_HANDLE;
return sandbox_tpm2_fill_buf(recv, recv_len, tag, rc);
}
@@ -578,18 +587,53 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const 
u8 *sendbuf,
put_unaligned_be32(capability, recv);
recv += sizeof(capability);
 
-   /* Give the number of properties that follow */
-   put_unaligned_be32(property_count, recv);
-   recv += sizeof(property_count);
-
-   /* Fill with the properties */
-   for (i = 0; i < property_count; i++) {
-   put_unaligned_be32(TPM2_PROPERTIES_OFFSET + property +
-  i, recv);
-   recv += sizeof(property);
-   put_unaligned_be32(tpm->properties[property + i],
-  recv);
-   recv += sizeof(property);
+   switch (capability) {
+   case TPM2_CAP_PCRS:
+   /* Give the number of algorithms supported - just 
SHA256 */
+   put_unaligned_be32(1, recv);
+   recv += sizeof(u32);
+
+   /* Give SHA256 algorithm */
+   put_unaligned_be16(TPM2_ALG_SHA256, recv);
+   recv += sizeof(u16);
+
+   /* Select the PCRs supported */
+   *recv = SAN

  1   2   >