public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Anatolij Gustschin <agust@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 3/5] x86: baytrail: secureboot: Add functions for verification of u-boot
Date: Thu, 11 May 2017 17:14:54 +0200	[thread overview]
Message-ID: <1494515696-2087-4-git-send-email-agust@denx.de> (raw)
In-Reply-To: <1494515696-2087-1-git-send-email-agust@denx.de>

From: Markus Valentin <mv@denx.de>

Introduce functions that check the integrity of u-boot by utilising the
hashes stored in the oem-data block.

The verification functions get called in fsp_init()

Signed-off-by: Markus Valentin <mv@denx.de>
---
 arch/x86/cpu/baytrail/Makefile                     |   1 +
 arch/x86/cpu/baytrail/secure_boot.c                | 117 +++++++++++++++++++++
 .../include/asm/arch-baytrail/fsp/fsp_configs.h    |   3 +
 arch/x86/lib/fsp/fsp_support.c                     |  15 +++
 4 files changed, 136 insertions(+)
 create mode 100644 arch/x86/cpu/baytrail/secure_boot.c

diff --git a/arch/x86/cpu/baytrail/Makefile b/arch/x86/cpu/baytrail/Makefile
index a0216f3..dbf9a82 100644
--- a/arch/x86/cpu/baytrail/Makefile
+++ b/arch/x86/cpu/baytrail/Makefile
@@ -8,4 +8,5 @@ obj-y += cpu.o
 obj-y += early_uart.o
 obj-y += fsp_configs.o
 obj-y += valleyview.o
+obj-$(CONFIG_BAYTRAIL_SECURE_BOOT) += secure_boot.o
 obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi.o
diff --git a/arch/x86/cpu/baytrail/secure_boot.c b/arch/x86/cpu/baytrail/secure_boot.c
new file mode 100644
index 0000000..37c83db
--- /dev/null
+++ b/arch/x86/cpu/baytrail/secure_boot.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2017 Markus Valentin <mv@denx.de>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+
+#define SB_MANIFEST_BASE		0xFFFE0000
+#define SB_MANIFEST_SIZE		0x400
+#define SB_MANIFEST_OEM_DATA_OFFSET	0x58
+#define SB_MANIFEST_OEM_HASH_OFFSET	(SB_MANIFEST_OEM_DATA_OFFSET + 4)
+#define SB_MANIFEST_OEM_HASH_BASE	(SB_MANIFEST_BASE +\
+					 SB_MANIFEST_OEM_HASH_OFFSET)
+#define SB_MANIFEST_END			(SB_MANIFEST_BASE + SB_MANIFEST_SIZE)
+
+#define PUB_KEY_MODULUS_SIZE		0x100
+#define U_BOOT_STAGE_SIZE		0xDD360
+#define U_BOOT_OFFSET			0x2CA0
+
+#define U_BOOT_STAGE_START		(CONFIG_SYS_TEXT_BASE + U_BOOT_OFFSET)
+#define U_BOOT_STAGE_END		(U_BOOT_STAGE_START + U_BOOT_STAGE_SIZE)
+
+#define SHA256_U_BOOT_STAGE_ID		0
+#define SHA256_FSP_STAGE2_ID		1
+#define SHA256_FIT_PUB_KEY_ID		2
+
+#define FIT_KEY_NAME			"dev"
+
+/**
+ * This function compares a hash which gets retrieved from the oem data block
+ * with the runtime calculated hash of start_address+size. If they match,
+ * this function returns true. If not, it returns false.
+ *
+ * @param hash_id	offset of oem-data block for hash to compare
+ * @param start_address	address where the hash calculation should start
+ * @param size		length of the region for hash calculation
+ * @return true on success, false on error
+ */
+static bool verify_oem_sha256(unsigned int hash_id,
+			      void *start_address,
+			      size_t size)
+{
+	uint8_t value[SHA256_SUM_LEN];
+	int value_len;
+
+	/* calculate address of hash to compare in the oemdata block*/
+	void *hash_to_verify = (void *)SB_MANIFEST_OEM_HASH_BASE +
+			       (SHA256_SUM_LEN * hash_id);
+#ifdef DEBUG
+	unsigned int i = 0;
+	uint8_t oem_value[SHA256_SUM_LEN];
+
+	memcpy(oem_value, hash_to_verify, SHA256_SUM_LEN);
+	printf("SB: Hash to verify:\t");
+	for (i = 0; i < SHA256_SUM_LEN; i++)
+		printf("%X", oem_value[i]);
+	printf("\n");
+#endif
+
+	/* caluclate the hash of the binary */
+	calculate_hash(start_address, size, "sha256", (unsigned char *)value,
+		       &value_len);
+
+#ifdef DEBUG
+	printf("SB: calculated hash:\t");
+	for (i = 0; i < SHA256_SUM_LEN; i++)
+		printf("%X", value[i]);
+	printf("\n");
+#endif
+	/* compare the two hash  values */
+	if (memcmp(hash_to_verify, value, SHA256_SUM_LEN))
+		return false;
+	return true;
+}
+
+/**
+ * This function verifies the integrity for u-boot, its devicetree and the ucode
+ * appended or inserted to the devicetree.
+ *
+ * @return true on success, false on error
+ */
+bool verify_u_boot_bin(void)
+{
+	return verify_oem_sha256(SHA256_U_BOOT_STAGE_ID,
+				 (void *)U_BOOT_STAGE_START,
+				 U_BOOT_STAGE_SIZE);
+}
+
+/**
+ * This function verifies the integrity for the modulus of the public key which
+ * is stored in the u-boot devicetree for fit image verification. It tries to
+ * find the "rsa,modulus" property in the dtb and then verifies it with the
+ * checksum stored in the oem-data block
+ *
+ * @return true on success, false on error
+ */
+bool verify_public_key(void)
+{
+	void *fit_public_key_modulus;
+
+	int offset = fdt_node_offset_by_prop_value(gd->fdt_blob, -1,
+						   "key-name-hint",
+						   FIT_KEY_NAME,
+						   4);
+
+	fit_public_key_modulus =  (void *)fdt_getprop(gd->fdt_blob, offset,
+						      "rsa,modulus", NULL);
+	if (!fit_public_key_modulus) {
+		debug("SB: Could not fetch public key from U-Boot Devicetree\n");
+		return false;
+	}
+
+	return verify_oem_sha256(SHA256_FIT_PUB_KEY_ID,
+				 fit_public_key_modulus,
+				 PUB_KEY_MODULUS_SIZE);
+}
diff --git a/arch/x86/include/asm/arch-baytrail/fsp/fsp_configs.h b/arch/x86/include/asm/arch-baytrail/fsp/fsp_configs.h
index e539890..b5dd5a4 100644
--- a/arch/x86/include/asm/arch-baytrail/fsp/fsp_configs.h
+++ b/arch/x86/include/asm/arch-baytrail/fsp/fsp_configs.h
@@ -16,4 +16,7 @@ struct fspinit_rtbuf {
 	struct common_buf	common;	/* FSP common runtime data structure */
 };
 
+bool verify_u_boot_bin(void);
+bool verify_public_key(void);
+
 #endif /* __FSP_CONFIGS_H__ */
diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c
index 3a537d0..5669700 100644
--- a/arch/x86/lib/fsp/fsp_support.c
+++ b/arch/x86/lib/fsp/fsp_support.c
@@ -149,6 +149,21 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf)
 	 */
 	printf("FSP: Secure Boot %sabled\n",
 	       fsp_vpd->enable_secure_boot == 1 ? "en" : "dis");
+	if (!verify_u_boot_bin()) {
+		/* if our u-boot binary checksum isn't equal to
+		 * our expected checksum we need to stop booting
+		 */
+		puts("SB: Failed to verify u-boot and dtb\n");
+		hang();
+	}
+
+	/*
+	 * verification of the public key happens with verification of
+	 * the devicetree binary (thats where its stored), this check is
+	 * not necessary, but nice to see its integer
+	 */
+	if (!verify_public_key())
+		puts("SB: Failed to verify public key for fit-image\n");
 #endif
 	/* Copy default data from Flash */
 	memcpy(fsp_upd, (void *)(fsp_hdr->img_base + fsp_vpd->upd_offset),
-- 
2.7.4

  parent reply	other threads:[~2017-05-11 15:14 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-11 15:14 [U-Boot] [PATCH 0/5] Introduce secure boot for Baytrail Anatolij Gustschin
2017-05-11 15:14 ` [U-Boot] [PATCH 1/5] x86: congatec: add secureboot enabled defconfig for conga-qeval20-qa3-e3845 Anatolij Gustschin
2017-05-15  3:03   ` Simon Glass
2017-05-11 15:14 ` [U-Boot] [PATCH 2/5] x86: baytrail: Add fsp-header verification for secure boot fsp Anatolij Gustschin
2017-05-15  3:03   ` Simon Glass
2017-05-15  7:20     ` Anatolij Gustschin
2017-05-11 15:14 ` Anatolij Gustschin [this message]
2017-05-12  8:25   ` [U-Boot] [PATCH 3/5] x86: baytrail: secureboot: Add functions for verification of u-boot Lothar Waßmann
2017-05-12  8:56     ` Anatolij Gustschin
2017-05-15  3:03   ` Simon Glass
2017-05-15  7:29     ` Anatolij Gustschin
2017-05-11 15:14 ` [U-Boot] [PATCH 4/5] tools: add secure_boot_helper.py Anatolij Gustschin
2017-05-15  3:03   ` Simon Glass
2017-05-11 15:14 ` [U-Boot] [PATCH 5/5] doc: x86: Add section about secure boot on Baytrail Anatolij Gustschin
2017-05-15  3:03   ` Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1494515696-2087-4-git-send-email-agust@denx.de \
    --to=agust@denx.de \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox