Re: [PATCH 7/7] tpm: allow the user to select the compiled algorithms

2024-06-22 Thread Ilias Apalodimas
On Sat, 22 Jun 2024 at 19:34, Heinrich Schuchardt  wrote:
>
> On 22.06.24 16:35, Ilias Apalodimas wrote:
> > Simon reports that after enabling all algorithms on the TPM some boards
> > fail since they don't have enough storage to accommodate the ~5KB growth.
> >
> > The choice of hash algorithms are determined by the platform and the TPM
> > configuration. Failing to cap a PCR in a bank which the platform left
> > active is a security vulnerability. It might allow  unsealing of secrets
> > if an attacker can replay a good set of measurements into an unused bank.
> >
> > If MEASURED_BOOT or EFI_TCG2_PROTOCOL is enabled our Kconfig will enable
> > all supported hashing algorithms. We still want to allow users to add a
> > TPM and not enable measured boot via EFI or bootm though and at the same
> > time, control the compiled algorithms for size reasons.
> >
> > So let's add a function tpm2_allow_extend() which checks the TPM active
> > PCRs banks against the one U-Boot was compiled with.
> > If all the active PCRs banks are not enabled refuse to extend a PCR but
> > otherwise leave the TPM functional.
>
> The paragraph above is bit hard to read. I guess you mean:
>
> We only allow extending PCRs using one of the algorithms selected in the
> configuration.

Yes

>
> >
> > It's worth noting that this is only added on TPM2.0, since TPM1.2 is
> > lacking a lot of code at the moment to read the available PCRs.
> > We unconditionally enable SHA1 when a TPM is selected, which is the only
> > hashing algorithm v1.2 supports.
>
> Why do we need SHA1 if we cannot access PCRs on a TPM1.2?

You can. On TPM1.2 we don't have the functions to check for the active
PCR banks. So I am unconditionally enabling SHA1, which is the only
hashing algo TPM1.2 supports.

Thanks
/Ilias
>
> Best regards
>
> Heinrich
>
> >
> > Signed-off-by: Ilias Apalodimas 
> > ---
> >   boot/Kconfig |  4 
> >   include/tpm-v2.h | 59 +++-
> >   lib/Kconfig  |  6 ++---
> >   lib/tpm-v2.c | 40 +---
> >   4 files changed, 87 insertions(+), 22 deletions(-)
> >
> > diff --git a/boot/Kconfig b/boot/Kconfig
> > index 6f3096c15a6f..b061891e109c 100644
> > --- a/boot/Kconfig
> > +++ b/boot/Kconfig
> > @@ -734,6 +734,10 @@ config LEGACY_IMAGE_FORMAT
> >   config MEASURED_BOOT
> >   bool "Measure boot images and configuration when booting without EFI"
> >   depends on HASH && TPM_V2
> > + select SHA1
> > + select SHA256
> > + select SHA384
> > + select SHA512
> >   help
> > This option enables measurement of the boot process when booting
> > without UEFI . Measurement involves creating cryptographic hashes
> > diff --git a/include/tpm-v2.h b/include/tpm-v2.h
> > index eac04d1c6831..fccb07fa4695 100644
> > --- a/include/tpm-v2.h
> > +++ b/include/tpm-v2.h
> > @@ -277,48 +277,40 @@ struct digest_info {
> >   #define TCG2_BOOT_HASH_ALG_SM3_256 0x0010
> >
> >   static const struct digest_info hash_algo_list[] = {
> > +#if IS_ENABLED(CONFIG_SHA1)
> >   {
> >   "sha1",
> >   TPM2_ALG_SHA1,
> >   TCG2_BOOT_HASH_ALG_SHA1,
> >   TPM2_SHA1_DIGEST_SIZE,
> >   },
> > +#endif
> > +#if IS_ENABLED(CONFIG_SHA256)
> >   {
> >   "sha256",
> >   TPM2_ALG_SHA256,
> >   TCG2_BOOT_HASH_ALG_SHA256,
> >   TPM2_SHA256_DIGEST_SIZE,
> >   },
> > +#endif
> > +#if IS_ENABLED(CONFIG_SHA384)
> >   {
> >   "sha384",
> >   TPM2_ALG_SHA384,
> >   TCG2_BOOT_HASH_ALG_SHA384,
> >   TPM2_SHA384_DIGEST_SIZE,
> >   },
> > +#endif
> > +#if IS_ENABLED(CONFIG_SHA512)
> >   {
> >   "sha512",
> >   TPM2_ALG_SHA512,
> >   TCG2_BOOT_HASH_ALG_SHA512,
> >   TPM2_SHA512_DIGEST_SIZE,
> >   },
> > +#endif
> >   };
> >
> > -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;
> > - }
> > -}
> > -
> >   /* NV index attributes */
> >   enum tpm_index_attrs {
> >   TPMA_NV_PPWRITE = 1UL << 0,
> > @@ -711,6 +703,41 @@ enum tpm2_algorithms tpm2_name_to_algorithm(const char 
> > *name);
> >*/
> >   const char *tpm2_algorithm_name(enum tpm2_algorithms);
> >
> > +/**
> > + * tpm2_algorithm_to_len() - Return an algorithm length for supported 
> > algorithm id
> > + *
> > + * @algorithm_id: algorithm defined in enum tpm2_algorithms
> > + * Return: len or 0 if not supported
> > + */
> > +u16 tpm2_algorithm_to_len(enum tpm2_algorithms algo);
> > +
> 

Re: [PATCH 7/7] tpm: allow the user to select the compiled algorithms

2024-06-22 Thread Heinrich Schuchardt

On 22.06.24 16:35, Ilias Apalodimas wrote:

Simon reports that after enabling all algorithms on the TPM some boards
fail since they don't have enough storage to accommodate the ~5KB growth.

The choice of hash algorithms are determined by the platform and the TPM
configuration. Failing to cap a PCR in a bank which the platform left
active is a security vulnerability. It might allow  unsealing of secrets
if an attacker can replay a good set of measurements into an unused bank.

If MEASURED_BOOT or EFI_TCG2_PROTOCOL is enabled our Kconfig will enable
all supported hashing algorithms. We still want to allow users to add a
TPM and not enable measured boot via EFI or bootm though and at the same
time, control the compiled algorithms for size reasons.

So let's add a function tpm2_allow_extend() which checks the TPM active
PCRs banks against the one U-Boot was compiled with.
If all the active PCRs banks are not enabled refuse to extend a PCR but
otherwise leave the TPM functional.


The paragraph above is bit hard to read. I guess you mean:

We only allow extending PCRs using one of the algorithms selected in the
configuration.



It's worth noting that this is only added on TPM2.0, since TPM1.2 is
lacking a lot of code at the moment to read the available PCRs.
We unconditionally enable SHA1 when a TPM is selected, which is the only
hashing algorithm v1.2 supports.


Why do we need SHA1 if we cannot access PCRs on a TPM1.2?

Best regards

Heinrich



Signed-off-by: Ilias Apalodimas 
---
  boot/Kconfig |  4 
  include/tpm-v2.h | 59 +++-
  lib/Kconfig  |  6 ++---
  lib/tpm-v2.c | 40 +---
  4 files changed, 87 insertions(+), 22 deletions(-)

diff --git a/boot/Kconfig b/boot/Kconfig
index 6f3096c15a6f..b061891e109c 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -734,6 +734,10 @@ config LEGACY_IMAGE_FORMAT
  config MEASURED_BOOT
bool "Measure boot images and configuration when booting without EFI"
depends on HASH && TPM_V2
+   select SHA1
+   select SHA256
+   select SHA384
+   select SHA512
help
  This option enables measurement of the boot process when booting
  without UEFI . Measurement involves creating cryptographic hashes
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index eac04d1c6831..fccb07fa4695 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -277,48 +277,40 @@ struct digest_info {
  #define TCG2_BOOT_HASH_ALG_SM3_256 0x0010

  static const struct digest_info hash_algo_list[] = {
+#if IS_ENABLED(CONFIG_SHA1)
{
"sha1",
TPM2_ALG_SHA1,
TCG2_BOOT_HASH_ALG_SHA1,
TPM2_SHA1_DIGEST_SIZE,
},
+#endif
+#if IS_ENABLED(CONFIG_SHA256)
{
"sha256",
TPM2_ALG_SHA256,
TCG2_BOOT_HASH_ALG_SHA256,
TPM2_SHA256_DIGEST_SIZE,
},
+#endif
+#if IS_ENABLED(CONFIG_SHA384)
{
"sha384",
TPM2_ALG_SHA384,
TCG2_BOOT_HASH_ALG_SHA384,
TPM2_SHA384_DIGEST_SIZE,
},
+#endif
+#if IS_ENABLED(CONFIG_SHA512)
{
"sha512",
TPM2_ALG_SHA512,
TCG2_BOOT_HASH_ALG_SHA512,
TPM2_SHA512_DIGEST_SIZE,
},
+#endif
  };

-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;
-   }
-}
-
  /* NV index attributes */
  enum tpm_index_attrs {
TPMA_NV_PPWRITE = 1UL << 0,
@@ -711,6 +703,41 @@ enum tpm2_algorithms tpm2_name_to_algorithm(const char 
*name);
   */
  const char *tpm2_algorithm_name(enum tpm2_algorithms);

+/**
+ * tpm2_algorithm_to_len() - Return an algorithm length for supported 
algorithm id
+ *
+ * @algorithm_id: algorithm defined in enum tpm2_algorithms
+ * Return: len or 0 if not supported
+ */
+u16 tpm2_algorithm_to_len(enum tpm2_algorithms algo);
+
+/*
+ * When measured boot is enabled via EFI or bootX commands all the algorithms
+ * above are selected by our Kconfigs. Due to U-Boots nature of being small 
there
+ * are cases where we need some functionality from the TPM -- e.g storage or 
RNG
+ * but we don't want to support measurements.
+ *
+ * The choice of hash algorithms are determined by the platform and the TPM
+ * configuration. Failing to cap a PCR in a bank which the platform left
+ * active is a security vulnerability. It permits the unsealing of secrets
+ * if an attacker can replay a good set of measurements into an unused bank.
+ *
+ * On top of that a previous stage bootl

[PATCH 7/7] tpm: allow the user to select the compiled algorithms

2024-06-22 Thread Ilias Apalodimas
Simon reports that after enabling all algorithms on the TPM some boards
fail since they don't have enough storage to accommodate the ~5KB growth.

The choice of hash algorithms are determined by the platform and the TPM
configuration. Failing to cap a PCR in a bank which the platform left
active is a security vulnerability. It might allow  unsealing of secrets
if an attacker can replay a good set of measurements into an unused bank.

If MEASURED_BOOT or EFI_TCG2_PROTOCOL is enabled our Kconfig will enable
all supported hashing algorithms. We still want to allow users to add a
TPM and not enable measured boot via EFI or bootm though and at the same
time, control the compiled algorithms for size reasons.

So let's add a function tpm2_allow_extend() which checks the TPM active
PCRs banks against the one U-Boot was compiled with.
If all the active PCRs banks are not enabled refuse to extend a PCR but
otherwise leave the TPM functional.

It's worth noting that this is only added on TPM2.0, since TPM1.2 is
lacking a lot of code at the moment to read the available PCRs.
We unconditionally enable SHA1 when a TPM is selected, which is the only
hashing algorithm v1.2 supports.

Signed-off-by: Ilias Apalodimas 
---
 boot/Kconfig |  4 
 include/tpm-v2.h | 59 +++-
 lib/Kconfig  |  6 ++---
 lib/tpm-v2.c | 40 +---
 4 files changed, 87 insertions(+), 22 deletions(-)

diff --git a/boot/Kconfig b/boot/Kconfig
index 6f3096c15a6f..b061891e109c 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -734,6 +734,10 @@ config LEGACY_IMAGE_FORMAT
 config MEASURED_BOOT
bool "Measure boot images and configuration when booting without EFI"
depends on HASH && TPM_V2
+   select SHA1
+   select SHA256
+   select SHA384
+   select SHA512
help
  This option enables measurement of the boot process when booting
  without UEFI . Measurement involves creating cryptographic hashes
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index eac04d1c6831..fccb07fa4695 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -277,48 +277,40 @@ struct digest_info {
 #define TCG2_BOOT_HASH_ALG_SM3_256 0x0010
 
 static const struct digest_info hash_algo_list[] = {
+#if IS_ENABLED(CONFIG_SHA1)
{
"sha1",
TPM2_ALG_SHA1,
TCG2_BOOT_HASH_ALG_SHA1,
TPM2_SHA1_DIGEST_SIZE,
},
+#endif
+#if IS_ENABLED(CONFIG_SHA256)
{
"sha256",
TPM2_ALG_SHA256,
TCG2_BOOT_HASH_ALG_SHA256,
TPM2_SHA256_DIGEST_SIZE,
},
+#endif
+#if IS_ENABLED(CONFIG_SHA384)
{
"sha384",
TPM2_ALG_SHA384,
TCG2_BOOT_HASH_ALG_SHA384,
TPM2_SHA384_DIGEST_SIZE,
},
+#endif
+#if IS_ENABLED(CONFIG_SHA512)
{
"sha512",
TPM2_ALG_SHA512,
TCG2_BOOT_HASH_ALG_SHA512,
TPM2_SHA512_DIGEST_SIZE,
},
+#endif
 };
 
-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;
-   }
-}
-
 /* NV index attributes */
 enum tpm_index_attrs {
TPMA_NV_PPWRITE = 1UL << 0,
@@ -711,6 +703,41 @@ enum tpm2_algorithms tpm2_name_to_algorithm(const char 
*name);
  */
 const char *tpm2_algorithm_name(enum tpm2_algorithms);
 
+/**
+ * tpm2_algorithm_to_len() - Return an algorithm length for supported 
algorithm id
+ *
+ * @algorithm_id: algorithm defined in enum tpm2_algorithms
+ * Return: len or 0 if not supported
+ */
+u16 tpm2_algorithm_to_len(enum tpm2_algorithms algo);
+
+/*
+ * When measured boot is enabled via EFI or bootX commands all the algorithms
+ * above are selected by our Kconfigs. Due to U-Boots nature of being small 
there
+ * are cases where we need some functionality from the TPM -- e.g storage or 
RNG
+ * but we don't want to support measurements.
+ *
+ * The choice of hash algorithms are determined by the platform and the TPM
+ * configuration. Failing to cap a PCR in a bank which the platform left
+ * active is a security vulnerability. It permits the unsealing of secrets
+ * if an attacker can replay a good set of measurements into an unused bank.
+ *
+ * On top of that a previous stage bootloader (e.g TF-A), migh pass an eventlog
+ * since it doesn't have a TPM driver, which U-Boot needs to replace. The 
algorit h
+ * choice is a compile time option in that case and we need to make sure we 
conform.
+ *
+ * Add a variable here that sums the supported algorithms U-Boot was compil