All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.