bancha: prepend an OpenTitan manifest to the EXT firmware image

This uses a fake test key. It is meant purely for demonstration.

Bypass-Presubmit-Reason: verified as part of topic

Change-Id: I1e14822216323660a8be3a2decf8b04adac8059d
diff --git a/platforms/bancha/bl0-manifest.hjson b/platforms/bancha/bl0-manifest.hjson
new file mode 100644
index 0000000..dbdcdbe
--- /dev/null
+++ b/platforms/bancha/bl0-manifest.hjson
@@ -0,0 +1,45 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+/**
+ * Manifest for BL0 boot images stored in external flash.
+ *
+ * Note: The definitions in
+ * sw/host/rom_ext_image_tools/signer/image/src/manifest.rs must be updated if
+ * this struct is modified. Please see the instructions in that file.
+ */
+{
+  /**
+   * Manifest identifier (CHIP_BL0_IDENTIFIER).
+   */
+  identifier: "0x3042544f"
+  /**
+   * Image major version.
+   */
+  version_major: "0x00000001"
+  /**
+   * Image minor version.
+   */
+  version_minor: "0x00000001"
+  /**
+   * Security version of the image used for anti-rollback protection.
+   */
+  security_version: "0x00000000"
+  /**
+   * Offset of the start of the executable region of the image from the start
+   * of the manifest in bytes.
+   */
+  code_start: "0x380"
+  /**
+   * Offset of the end of the executable region (exclusive) of the image from
+   * the start of the manifest in bytes.
+   * XXX anything > code_start and word-aligned works for now
+   */
+  code_end: "0x700"
+  /**
+   * Offset of the first instruction to execute in the image from the start of
+   * the manifest in bytes.
+   */
+  entry_point: "0x380"
+}
diff --git a/platforms/bancha/setup.sh b/platforms/bancha/setup.sh
index f9d2ea3..be257a3 100644
--- a/platforms/bancha/setup.sh
+++ b/platforms/bancha/setup.sh
@@ -24,3 +24,6 @@
 # Firmware image to build & load at boot.
 # NB: the pathname to the source directory is formulated in platform.mk
 export CHERIOT_FIRMWARE="soundstream"
+
+# Location of opentitantool used to sign firmware images
+export OT_TOOL="${ROOTDIR}/out/host/opentitantool"
diff --git a/platforms/bancha/sim.mk b/platforms/bancha/sim.mk
index 5c0dab2..9a58e6f 100644
--- a/platforms/bancha/sim.mk
+++ b/platforms/bancha/sim.mk
@@ -65,10 +65,35 @@
 	tar -C $(TMP_DEBUG) -cvhf $@ matcha-tock-bundle.bin kernel
 ext_flash_debug: $(EXT_FLASH_DEBUG)
 
-$(EXT_FLASH_RELEASE): $(CHERIOT_FIRMWARE_RELEASE) ${CANTRIP_MODEL_RELEASE} | $(TMP_RELEASE)
+# TODO(sleffler): maybe move to opentitan_sw.mk?
+
+TEST_PRIVATE_KEY_0 := ${OPENTITAN_SOURCE}/sw/device/silicon_creator/rom/keys/fake/test_key_0_rsa_3072_exp_f4.der
+
+opentitantool_: opentitantool_pkg
+	tar -C ${OUT}/host -xf $(MATCHA_OUT_DIR)/opentitantool_pkg.tar.gz
+
+## Construct a 2nd-level OpenTitan firmware image from a cheriot-rtos
+## firmware image.
+#
+# This assumes the cheriot-rtos image was built with the instruction
+# memory in the board config offset by 0x380 bytes (0x380 = 896 bytes
+# is the size of the OT manifest data structure). To build the image:
+# - strip symbol & linearize the ELF segments; data will start at offset 0 in the file
+# - copy the data up by the size of an OT manifest data structure
+# - use openttitantool to construct the manifest & sign the image
+# There are many ways we could do this. It might be better to have the
+# cheriot-rtos build glue help us leave room for the manifest instead
+# of adjusting the instruction memory but this works for now.
+cheriot_firmware_release: ${CHERIOT_FIRMWARE_RELEASE} opentitantool_ | ${TMP_RELEASE}
 	cp -f $(CHERIOT_FIRMWARE_RELEASE) $(TMP_RELEASE)/cheriot-firmware
-	${C_PREFIX}strip $(TMP_RELEASE)/cheriot-firmware
-	${C_PREFIX}objcopy -O binary -g $(TMP_RELEASE)/cheriot-firmware $(TMP_RELEASE)/cheriot-firmware.bin
+	${C_PREFIX}objcopy --strip-all -O binary -g $(TMP_RELEASE)/cheriot-firmware $(TMP_RELEASE)/cheriot-firmware.raw
+	dd if=$(TMP_RELEASE)/cheriot-firmware.raw of=${TMP_RELEASE}/cheriot-firmware.bin bs=896 seek=1
+	${OT_TOOL} image manifest update \
+		--manifest=${ROOTDIR}/build/platforms/bancha/bl0-manifest.hjson \
+		--sign --key-file=${TEST_PRIVATE_KEY_0} \
+		$(TMP_RELEASE)/cheriot-firmware.bin
+
+$(EXT_FLASH_RELEASE): ${CANTRIP_MODEL_RELEASE} cheriot_firmware_release | $(TMP_RELEASE)
 	tar -C $(TMP_RELEASE) -cvhf $@ cheriot-firmware.bin
 	if [[ -f "${CANTRIP_MODEL_RELEASE}" ]]; then \
 		${C_PREFIX}objcopy -O binary -g ${CANTRIP_MODEL_RELEASE} $(TMP_RELEASE)/kelvin.bin; \
@@ -170,5 +195,7 @@
 	rm -rf $(CHERIOT_SIM_OUT_DIR)
 
 .PHONY:: sim_configs clean_sim_configs simulate simulate-debug debug-simulation
+.PHONY:: opentitantool_
+.PHONY:: cheriot_firmware_release
 .PHONY:: cheriot_sim cheriot_sim_clean
 .PHONY:: cheriot_boot_rom cheriot_boot_rom_clean