Re: [U-Boot] [PATCH v3 2/6] x86: baytrail: secureboot: Add functions for verification of U-Boot

2017-11-28 Thread Anatolij Gustschin
Hi Simon,

On Mon, 20 Nov 2017 08:40:22 -0700
Simon Glass s...@chromium.org wrote:

> Hi Anatolij,
> 
> On 16 November 2017 at 18:14, Anatolij Gustschin  wrote:
> > From: Markus Valentin 
> >
> > Introduce functions that check the integrity of U-Boot by utilising
> > the hashes stored in the OEM-data block in Secure Boot Manifest.
> >
> > The verification functions get called in fsp_init()
> >
> > Signed-off-by: Markus Valentin 
> > Signed-off-by: Anatolij Gustschin 
> > ---
> > Changes in v3:
> >  - lower case in hex numbers
> >  - fix RAM stage payload hash calculation and add comments
> >for associated macros
> >  - add comments explaining used stage indexes, s/*_ID/*_IDX
> >  - fixed two spaces in comment
> >  - s/devicetree/device tree
> >  - extend the output messages to give more hints when FIT key
> >verification fails
> >  -
> >
> > Changes in v2:
> >  - use 'const void *' for fdt property ptr, drop cast
> >  - s/u-boot/U-Boot/
> >  - fix function comment style and move comments to header with
> >prototypes. Use fsp_ prefix
> >  - fix multiline comment style
> >  - s/SB:/Secure Boot/ for non-debug messages
> >
> >  arch/x86/cpu/baytrail/Makefile |   1 +
> >  arch/x86/cpu/baytrail/secure_boot.c| 117 
> > +
> >  .../include/asm/arch-baytrail/fsp/fsp_configs.h|  24 +
> >  arch/x86/lib/fsp/fsp_support.c |  18 
> >  4 files changed, 160 insertions(+)
> >  create mode 100644 arch/x86/cpu/baytrail/secure_boot.c
> >  
> 
> Reviewed-by: Simon Glass 
> 
> Some nits below.
> 
> > diff --git a/arch/x86/cpu/baytrail/Makefile b/arch/x86/cpu/baytrail/Makefile
> > index a0216f3059..dbf9a82c39 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 00..eaf35c6e24
> > --- /dev/null
> > +++ b/arch/x86/cpu/baytrail/secure_boot.c
> > @@ -0,0 +1,117 @@
> > +/*
> > + * Copyright (C) 2017 Markus Valentin 
> > + *
> > + * SPDX-License-Identifier: GPL-2.0+
> > + */
> > +
> > +#include 
> > +
> > +#define SB_MANIFEST_BASE   0xfffe  
> 
> Is this something inside a binary blob, or can it be changed by the
> user? I'm just wondering if it should go in Kconfig.

Yes, this is the fixed offset inside the blob and must not be changed.
Otherwise booting will fail. I'll add a comment.

... 
> > +#define SB_MANIFEST_SIZE   0x400
> > +#define SB_MANIFEST_OEM_DATA_OFFSET0x58
> > +#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 FIT_KEY_NAME   "dev"  
> 
> This is just supposed to be a hint. I think you should probably check
> all keys, since you don't really know which one was used to sign. You
> could check this one first I suppose. But any signature that works
> should be good enough.

We allways used "dev" as a hint, but yes, the key name could vary. We use
only one key hash in the manifest, I'll change to check all keys in
subnodes of /signature node.

...
> > +/**
> > + * verify_oem_sha256() - oem data block verification
> > + *
> > + * 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.
> > + *
> > + * @hash_idx:  index of oem-data block with hash to compare
> > + * @start_address: address where the hash calculation should start
> > + * @size:  length of the region for hash calculation
> > + *
> > + * @retval:true on success, false on error  
> 
> @returns

OK, will fix.

...
> > +   /* Calculate the hash of the binary */
> > +   calculate_hash(start_address, size, "sha256", value, &value_len);
> > +
> > +#ifdef DEBUG
> > +   printf("SB: calculated hash:\t");
> > +   for (i = 0; i < SHA256_SUM_LEN; i++)
> > +   printf("%02X", value[i]);
> > +   printf("\n");
> > +#endif
> > +   /* Compare the two hash values */
> > +   if (memcmp(hash_to_verify, value, SHA256_SUM_LEN))
> > +   return false;
> > +   return true;  
> 
> I suggest returning 0 on success and an negative error on failure.

OK, will do in v4.

...
> > diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c
> > index d79a6e900a..c7e0a9eff4 100644
> > --- a/arch/x86/lib/fsp/fsp_suppor

Re: [U-Boot] [PATCH v3 2/6] x86: baytrail: secureboot: Add functions for verification of U-Boot

2017-11-20 Thread Simon Glass
Hi Anatolij,

On 16 November 2017 at 18:14, Anatolij Gustschin  wrote:
> From: Markus Valentin 
>
> Introduce functions that check the integrity of U-Boot by utilising
> the hashes stored in the OEM-data block in Secure Boot Manifest.
>
> The verification functions get called in fsp_init()
>
> Signed-off-by: Markus Valentin 
> Signed-off-by: Anatolij Gustschin 
> ---
> Changes in v3:
>  - lower case in hex numbers
>  - fix RAM stage payload hash calculation and add comments
>for associated macros
>  - add comments explaining used stage indexes, s/*_ID/*_IDX
>  - fixed two spaces in comment
>  - s/devicetree/device tree
>  - extend the output messages to give more hints when FIT key
>verification fails
>  -
>
> Changes in v2:
>  - use 'const void *' for fdt property ptr, drop cast
>  - s/u-boot/U-Boot/
>  - fix function comment style and move comments to header with
>prototypes. Use fsp_ prefix
>  - fix multiline comment style
>  - s/SB:/Secure Boot/ for non-debug messages
>
>  arch/x86/cpu/baytrail/Makefile |   1 +
>  arch/x86/cpu/baytrail/secure_boot.c| 117 
> +
>  .../include/asm/arch-baytrail/fsp/fsp_configs.h|  24 +
>  arch/x86/lib/fsp/fsp_support.c |  18 
>  4 files changed, 160 insertions(+)
>  create mode 100644 arch/x86/cpu/baytrail/secure_boot.c
>

Reviewed-by: Simon Glass 

Some nits below.

> diff --git a/arch/x86/cpu/baytrail/Makefile b/arch/x86/cpu/baytrail/Makefile
> index a0216f3059..dbf9a82c39 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 00..eaf35c6e24
> --- /dev/null
> +++ b/arch/x86/cpu/baytrail/secure_boot.c
> @@ -0,0 +1,117 @@
> +/*
> + * Copyright (C) 2017 Markus Valentin 
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include 
> +
> +#define SB_MANIFEST_BASE   0xfffe

Is this something inside a binary blob, or can it be changed by the
user? I'm just wondering if it should go in Kconfig.

> +#define SB_MANIFEST_SIZE   0x400
> +#define SB_MANIFEST_OEM_DATA_OFFSET0x58
> +#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 FIT_KEY_NAME   "dev"

This is just supposed to be a hint. I think you should probably check
all keys, since you don't really know which one was used to sign. You
could check this one first I suppose. But any signature that works
should be good enough.

> +#define PUB_KEY_MODULUS_SIZE   0x100
> +
> +/*
> + * U-Boot in RAM stage payload from reset vector to FSP Stage2:
> + * 0xfff to 0xfffc
> + */
> +#define U_BOOT_STAGE_START CONFIG_SYS_TEXT_BASE
> +#define U_BOOT_STAGE_SIZE  0xc
> +
> +/*
> + * Indexes of 32-byte blocks in the OEM-data area containing sha256 hashes
> + * of RAM stage payload, FSP Stage2 and other OEM specific data. The order
> + * of RAM stage payload and FSP Stage2 blocks is fixed (idx 0 and 1),
> + * do not change it. We do not verify FSP Stage2 here, it will be verified
> + * in FSP (FSP Stage2 idx 1 is not used). So, the first index of OEM specific
> + * data block hash must start from 2.
> + */
> +#define SHA256_U_BOOT_STAGE_IDX0
> +#define SHA256_FIT_PUB_KEY_IDX 2
> +
> +/**
> + * verify_oem_sha256() - oem data block verification
> + *
> + * 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.
> + *
> + * @hash_idx:  index of oem-data block with hash to compare
> + * @start_address: address where the hash calculation should start
> + * @size:  length of the region for hash calculation
> + *
> + * @retval:true on success, false on error

@returns

> + */
> +static bool verify_oem_sha256(unsigned int hash_idx,
> + const 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_idx);
> +#ifdef DEBUG
> +   unsigned int i = 0;
> +   uint8_t oem_value[SHA256_SUM_LEN];
> +
> +   memcpy

[U-Boot] [PATCH v3 2/6] x86: baytrail: secureboot: Add functions for verification of U-Boot

2017-11-16 Thread Anatolij Gustschin
From: Markus Valentin 

Introduce functions that check the integrity of U-Boot by utilising
the hashes stored in the OEM-data block in Secure Boot Manifest.

The verification functions get called in fsp_init()

Signed-off-by: Markus Valentin 
Signed-off-by: Anatolij Gustschin 
---
Changes in v3:
 - lower case in hex numbers 
 - fix RAM stage payload hash calculation and add comments
   for associated macros
 - add comments explaining used stage indexes, s/*_ID/*_IDX
 - fixed two spaces in comment
 - s/devicetree/device tree
 - extend the output messages to give more hints when FIT key
   verification fails
 -

Changes in v2:
 - use 'const void *' for fdt property ptr, drop cast
 - s/u-boot/U-Boot/
 - fix function comment style and move comments to header with
   prototypes. Use fsp_ prefix
 - fix multiline comment style
 - s/SB:/Secure Boot/ for non-debug messages

 arch/x86/cpu/baytrail/Makefile |   1 +
 arch/x86/cpu/baytrail/secure_boot.c| 117 +
 .../include/asm/arch-baytrail/fsp/fsp_configs.h|  24 +
 arch/x86/lib/fsp/fsp_support.c |  18 
 4 files changed, 160 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 a0216f3059..dbf9a82c39 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 00..eaf35c6e24
--- /dev/null
+++ b/arch/x86/cpu/baytrail/secure_boot.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2017 Markus Valentin 
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include 
+
+#define SB_MANIFEST_BASE   0xfffe
+#define SB_MANIFEST_SIZE   0x400
+#define SB_MANIFEST_OEM_DATA_OFFSET0x58
+#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 FIT_KEY_NAME   "dev"
+#define PUB_KEY_MODULUS_SIZE   0x100
+
+/*
+ * U-Boot in RAM stage payload from reset vector to FSP Stage2:
+ * 0xfff to 0xfffc
+ */
+#define U_BOOT_STAGE_START CONFIG_SYS_TEXT_BASE
+#define U_BOOT_STAGE_SIZE  0xc
+
+/*
+ * Indexes of 32-byte blocks in the OEM-data area containing sha256 hashes
+ * of RAM stage payload, FSP Stage2 and other OEM specific data. The order
+ * of RAM stage payload and FSP Stage2 blocks is fixed (idx 0 and 1),
+ * do not change it. We do not verify FSP Stage2 here, it will be verified
+ * in FSP (FSP Stage2 idx 1 is not used). So, the first index of OEM specific
+ * data block hash must start from 2.
+ */
+#define SHA256_U_BOOT_STAGE_IDX0
+#define SHA256_FIT_PUB_KEY_IDX 2
+
+/**
+ * verify_oem_sha256() - oem data block verification
+ *
+ * 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.
+ *
+ * @hash_idx:  index of oem-data block with hash to compare
+ * @start_address: address where the hash calculation should start
+ * @size:  length of the region for hash calculation
+ *
+ * @retval:true on success, false on error
+ */
+static bool verify_oem_sha256(unsigned int hash_idx,
+ const 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_idx);
+#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("%02X", oem_value[i]);
+   printf("\n");
+#endif
+
+   /* Calculate the hash of the binary */
+   calculate_hash(start_address, size, "sha256", value, &value_len);
+
+#ifdef DEBUG
+   printf("SB: calculated hash:\t");
+   for (i = 0; i < SHA256_SUM_LEN; i++)
+   printf("%02X", value[i]);
+   printf("\n");
+#endif
+   /* Compare the two hash values */
+   if (memcmp(hash_to_verify, value, SHA256_SUM_LEN))
+   return false;
+   return true;
+}
+
+bool fsp_verify_u_boot_bin(void)
+{
+   return ver