All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ilias Apalodimas <ilias.apalodimas@linaro.org>
To: Tim Harvey <tharvey@gateworks.com>
Cc: u-boot@lists.denx.de, Eddie James <eajames@linux.ibm.com>,
	slee@gateworks.com
Subject: Re: [PATCH v2] tpm-v2: allow algoirthm name to be configured for pcr_read and pcr_extend
Date: Sat, 30 Mar 2024 09:20:18 +0200	[thread overview]
Message-ID: <CAC_iWjLGdnB6H_mwNhjwG9smmw9j45=CK8odmjdJ-wVukNVEbg@mail.gmail.com> (raw)
In-Reply-To: <CAC_iWjKxcpWE1vpNX0uiwBdbiyYbtAm=6Q-T6_xnbnO2+pMewg@mail.gmail.com>

On Sat, 30 Mar 2024 at 09:15, Ilias Apalodimas
<ilias.apalodimas@linaro.org> wrote:
>
> Hi Tim
>
> On Sat, 30 Mar 2024 at 02:40, Tim Harvey <tharvey@gateworks.com> wrote:
> >
> > On Thu, Mar 28, 2024 at 11:18 PM Ilias Apalodimas
> > <ilias.apalodimas@linaro.org> wrote:
> > >
> > > Hi Tim,
> > >
> > > On Thu, 28 Mar 2024 at 19:01, Tim Harvey <tharvey@gateworks.com> wrote:
> > > >
> > > > For pcr_read and pcr_extend commands allow the digest algorithm to be
> > > > specified by an additional argument. If not specified it will default to
> > > > SHA256 for backwards compatibility.
> > > >
> > > > A follow-on to this could be to extend all PCR banks with the detected
> > > > algo when the <digest_algo> argument is 'auto'.
> > > >
> > > > Signed-off-by: Tim Harvey <tharvey@gateworks.com>
> > > > ---
> > > > v2:
> > > >  - use tpm2_algorithm_to_len
> > > >  - use enum tpm2_algorithms
> > > >  - make function names and parameter names more consistent with existing
> > > >    tpm-v2 functions
> > > >  - fix various spelling errors
> > > > ---
> > > >  cmd/tpm-v2.c     | 49 ++++++++++++++++++++++++++++++++++--------------
> > > >  include/tpm-v2.h | 18 ++++++++++++++++++
> > > >  lib/tpm-v2.c     | 34 +++++++++++++++++++++++++++++++++
> > > >  3 files changed, 87 insertions(+), 14 deletions(-)
> > > >
> > > > diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c
> > > > index 7e479b9dfe36..2343b4d9cb9e 100644
> > > > --- a/cmd/tpm-v2.c
> > > > +++ b/cmd/tpm-v2.c
> > > > @@ -99,11 +99,19 @@ static int do_tpm2_pcr_extend(struct cmd_tbl *cmdtp, int flag, int argc,
> > > >         struct tpm_chip_priv *priv;
> > > >         u32 index = simple_strtoul(argv[1], NULL, 0);
> > > >         void *digest = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0);
> > > > +       int algo = TPM2_ALG_SHA256;
> > > > +       int algo_len;
> > > >         int ret;
> > > >         u32 rc;
> > > >
> > > > -       if (argc != 3)
> > > > +       if (argc < 3 || argc > 4)
> > > >                 return CMD_RET_USAGE;
> > > > +       if (argc == 4) {
> > > > +               algo = tpm2_name_to_algorithm(argv[3]);
> > > > +               if (algo < 0)
> > > > +                       return CMD_RET_FAILURE;
> > > > +       }
> > > > +       algo_len = tpm2_algorithm_to_len(algo);
> > > >
> > > >         ret = get_tpm(&dev);
> > > >         if (ret)
> > > > @@ -116,8 +124,12 @@ static int do_tpm2_pcr_extend(struct cmd_tbl *cmdtp, int flag, int argc,
> > > >         if (index >= priv->pcr_count)
> > > >                 return -EINVAL;
> > > >
> > > > -       rc = tpm2_pcr_extend(dev, index, TPM2_ALG_SHA256, digest,
> > > > -                            TPM2_DIGEST_LEN);
> > > > +       rc = tpm2_pcr_extend(dev, index, algo, digest, algo_len);
> > > > +       if (!rc) {
> > > > +               printf("PCR #%u extended with %d byte %s digest\n", index,
> > > > +                      algo_len, tpm2_algorithm_name(algo));
> > > > +               print_byte_string(digest, algo_len);
> > > > +       }
> > > >
> > > >         unmap_sysmem(digest);
> > > >
> > > > @@ -127,15 +139,23 @@ static int do_tpm2_pcr_extend(struct cmd_tbl *cmdtp, int flag, int argc,
> > > >  static int do_tpm_pcr_read(struct cmd_tbl *cmdtp, int flag, int argc,
> > > >                            char *const argv[])
> > > >  {
> > > > +       enum tpm2_algorithms algo = TPM2_ALG_SHA256;
> > > >         struct udevice *dev;
> > > >         struct tpm_chip_priv *priv;
> > > >         u32 index, rc;
> > > > +       int algo_len;
> > > >         unsigned int updates;
> > > >         void *data;
> > > >         int ret;
> > > >
> > > > -       if (argc != 3)
> > > > +       if (argc < 3 || argc > 4)
> > > >                 return CMD_RET_USAGE;
> > > > +       if (argc == 4) {
> > > > +               algo = tpm2_name_to_algorithm(argv[3]);
> > > > +               if (algo < 0)
> > > > +                       return CMD_RET_FAILURE;
> > > > +       }
> > > > +       algo_len = tpm2_algorithm_to_len(algo);
> > > >
> > > >         ret = get_tpm(&dev);
> > > >         if (ret)
> > > > @@ -151,11 +171,12 @@ static int do_tpm_pcr_read(struct cmd_tbl *cmdtp, int flag, int argc,
> > > >
> > > >         data = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0);
> > > >
> > > > -       rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, TPM2_ALG_SHA256,
> > > > -                          data, TPM2_DIGEST_LEN, &updates);
> > > > +       rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, algo,
> > > > +                          data, algo_len, &updates);
> > > >         if (!rc) {
> > > > -               printf("PCR #%u content (%u known updates):\n", index, updates);
> > > > -               print_byte_string(data, TPM2_DIGEST_LEN);
> > > > +               printf("PCR #%u %s %d byte content (%u known updates):\n", index,
> > > > +                      tpm2_algorithm_name(algo), algo_len, updates);
> > > > +               print_byte_string(data, algo_len);
> > > >         }
> > > >
> > > >         unmap_sysmem(data);
> > > > @@ -415,14 +436,14 @@ U_BOOT_CMD(tpm2, CONFIG_SYS_MAXARGS, 1, do_tpm, "Issue a TPMv2.x command",
> > > >  "    <hierarchy> is one of:\n"
> > > >  "        * TPM2_RH_LOCKOUT\n"
> > > >  "        * TPM2_RH_PLATFORM\n"
> > > > -"pcr_extend <pcr> <digest_addr>\n"
> > > > -"    Extend PCR #<pcr> with digest at <digest_addr>.\n"
> > > > +"pcr_extend <pcr> <digest_addr> [<digest_algo>]\n"
> > > > +"    Extend PCR #<pcr> with digest at <digest_addr> with digest_algo.\n"
> > > >  "    <pcr>: index of the PCR\n"
> > > > -"    <digest_addr>: address of a 32-byte SHA256 digest\n"
> > > > -"pcr_read <pcr> <digest_addr>\n"
> > > > -"    Read PCR #<pcr> to memory address <digest_addr>.\n"
> > > > +"    <digest_addr>: address of digest of digest_algo type (defaults to SHA256)\n"
> > > > +"pcr_read <pcr> <digest_addr> [<digest_algo>]\n"
> > > > +"    Read PCR #<pcr> to memory address <digest_addr> with <digest_algo>.\n"
> > > >  "    <pcr>: index of the PCR\n"
> > > > -"    <digest_addr>: address to store the a 32-byte SHA256 digest\n"
> > > > +"    <digest_addr>: address of digest of digest_algo type (defaults to SHA256)\n"
> > > >  "get_capability <capability> <property> <addr> <count>\n"
> > > >  "    Read and display <count> entries indexed by <capability>/<property>.\n"
> > > >  "    Values are 4 bytes long and are written at <addr>.\n"
> > > > diff --git a/include/tpm-v2.h b/include/tpm-v2.h
> > > > index 33dd103767c4..933882fcbf97 100644
> > > > --- a/include/tpm-v2.h
> > > > +++ b/include/tpm-v2.h
> > > > @@ -965,4 +965,22 @@ u32 tpm2_enable_nvcommits(struct udevice *dev, uint vendor_cmd,
> > > >   */
> > > >  u32 tpm2_auto_start(struct udevice *dev);
> > > >
> > > > +/**
> > > > + * tpm2_name_to_algorithm() - Return an algorithm id given a supported
> > > > + *                           algorithm name
> > > > + *
> > > > + * @name: algorithm name
> > > > + * Return: enum tpm2_algorithms or -EINVAL
> > > > + */
> > > > +enum tpm2_algorithms tpm2_name_to_algorithm(const char *name);
> > > > +
> > > > +/**
> > > > + * tpm2_algorithm_name() - Return an algorithm name string for a
> > > > + *                        supported algorithm id
> > > > + *
> > > > + * @algorithm_id: algorithm defined in enum tpm2_algorithms
> > > > + * Return: algorithm name string or ""
> > > > + */
> > > > +const char *tpm2_algorithm_name(enum tpm2_algorithms);
> > > > +
> > > >  #endif /* __TPM_V2_H */
> > > > diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
> > > > index 68eaaa639f89..19b2535682e1 100644
> > > > --- a/lib/tpm-v2.c
> > > > +++ b/lib/tpm-v2.c
> > > > @@ -29,6 +29,13 @@ const enum tpm2_algorithms tpm2_supported_algorithms[4] = {
> > > >         TPM2_ALG_SHA512,
> > > >  };
> > > >
> > > > +const char *tpm2_supported_algorithm_names[4] = {
> > > > +       "sha1",
> > > > +       "sha256",
> > > > +       "sha384",
> > > > +       "sha512",
> > > > +};
> > > > +
> > >
> > > Overall this looks correct(but we don't need the [4] in the definition
> > > tbh). However, keeping the info in 2 different places is not ideal.
> > > We used to have a nice struct array that had all the info tightly together [0].
> > >
> > > The struct looked like
> > >
> > > struct digest_info {
> > > u16 hash_alg;
> > > u32 hash_mask;
> > > u16 hash_len;
> > > };
> > >
> > > static const struct digest_info hash_algo_list[] = {
> > > {
> > > TPM2_ALG_SHA1,
> > > EFI_TCG2_BOOT_HASH_ALG_SHA1,
> > > TPM2_SHA1_DIGEST_SIZE,
> > > },
> > > {
> > > TPM2_ALG_SHA256,
> > > EFI_TCG2_BOOT_HASH_ALG_SHA256,
> > > TPM2_SHA256_DIGEST_SIZE,
> > > },
> > > {
> > > TPM2_ALG_SHA384,
> > > EFI_TCG2_BOOT_HASH_ALG_SHA384,
> > > TPM2_SHA384_DIGEST_SIZE,
> > > },
> > > {
> > > TPM2_ALG_SHA512,
> > > EFI_TCG2_BOOT_HASH_ALG_SHA512,
> > > TPM2_SHA512_DIGEST_SIZE,
> > > },
> > > };
> > >
> > > In short, we need to
> > > - define the algorithm registry as defined by the TCG spec
> > >   /* Algorithm Registry */
> > >   #define EFI_TCG2_BOOT_HASH_ALG_SHA1    0x00000001
> > >   #define EFI_TCG2_BOOT_HASH_ALG_SHA256  0x00000002
> > >   #define EFI_TCG2_BOOT_HASH_ALG_SHA384  0x00000004
> > >   #define EFI_TCG2_BOOT_HASH_ALG_SHA512  0x00000008
> > >   #define EFI_TCG2_BOOT_HASH_ALG_SM3_256 0x00000010
> > >
> >
> > the above defines do not make sense to me if they are truely supposed
> > to be masks compared to what we currently have:
> >
> > enum tpm2_algorithms {
> >         TPM2_ALG_SHA1           = 0x04,
> >         TPM2_ALG_XOR            = 0x0A,
> >         TPM2_ALG_SHA256         = 0x0B,
> >         TPM2_ALG_SHA384         = 0x0C,
> >         TPM2_ALG_SHA512         = 0x0D,
> >         TPM2_ALG_NULL           = 0x10,
> >         TPM2_ALG_SM3_256        = 0x12,
> > };
> > #define tpm2_algorithm_to_mask(a)       (1 << (a))
>
> Yes, this is a bit confusing.  We are *not* using those definitions
> when calling tpm2_algorithm_to_mask(). Instead const enum of
> tpm2_supported_algorithms[] is used which yields the same values.
>
> >
> > Is digest_info.hash_mask from 2023.04 something else or were those
> > defines just wrong (struct digest_info didn't seem to be used anywhere
> > in 2023.04)
>
> It's probably present in 2022.X versions. The link included in the
> mail is from 2022.01
> https://source.denx.de/u-boot/custodians/u-boot-tpm/-/blob/v2022.01-rc3/lib/efi_loader/efi_tcg2.c?ref_type=tags#L75
>
> >
> > I'm ok with changing tpm2_supported_algorithms to a struct which
> > defines name, algorithm_id, mask and len if I understand what values
> > they should be.
>
> I hope that's clear now. Basically if you checkout v2023.01 all the
> functions are in lib/efi_loader/efi_tcg.c
> You will need
>
> static const struct digest_info hash_algo_list[], alg_to_len and
> alg_to_mask functions. You can then add a new const char filed with
> the names you want to support in the command line
>
> Thanks for picking this up!
>
> /Ilias
>
> >
> > Sounds like your suggesting:
> > - add back struct digest_info
> > - make tpm2_supported_algorithms be an array of struct digtest_info
> > - use that array for tpm2_algorithm_to_len, tpm2_algorithm_to_mask,
> > tpm2_algorithm_to_len and tpm2_name_to_algorithm

Forgot to answer this one
- add back struct digest_info
- get rid of supported algorithms, since you wont need it anymore
- on struct digest_info add a string you can use on the command line
and the functions you need to retrieve/compare it

makes sense?
Thanks
/Ilias
> >
> > Tim
> >
> > > - Bring back the functions that exist in that branch. Pre 2023.07 all
> > > measured boot code lived in lib/efi_loader/efi_tcg.c, so we just need
> > > to copy them over
> > > - Add a new struct member with the name and a new function to retrieve it.
> > >
> > > [0] https://source.denx.de/u-boot/custodians/u-boot-tpm/-/blob/v2022.01-rc3/lib/efi_loader/efi_tcg2.c?ref_type=tags#L75
> > >
> > > I understand that's more than what your patch tries to achieve here. I
> > > am fine pulling this as-is and you/I can fix it up later unless you
> > > don't mind doing it in a v3.
> > >
> > > Thanks
> > > /Ilias
> > > >  int tcg2_get_active_pcr_banks(struct udevice *dev, u32 *active_pcr_banks)
> > > >  {
> > > >         u32 supported = 0;
> > > > @@ -1555,3 +1562,30 @@ u32 tpm2_enable_nvcommits(struct udevice *dev, uint vendor_cmd,
> > > >
> > > >         return 0;
> > > >  }
> > > > +
> > > > +enum tpm2_algorithms tpm2_name_to_algorithm(const char *name)
> > > > +{
> > > > +       enum tpm2_algorithms algo;
> > > > +       size_t i;
> > > > +
> > > > +       for (i = 0; i < ARRAY_SIZE(tpm2_supported_algorithms); ++i) {
> > > > +               algo = tpm2_supported_algorithms[i];
> > > > +               if (!strcasecmp(name, tpm2_supported_algorithm_names[i]))
> > > > +                       return algo;
> > > > +       }
> > > > +       printf("%s: unsupported algorithm %s\n", __func__, name);
> > > > +
> > > > +       return -EINVAL;
> > > > +}
> > > > +
> > > > +const char *tpm2_algorithm_name(enum tpm2_algorithms algo)
> > > > +{
> > > > +       size_t i;
> > > > +
> > > > +       for (i = 0; i < ARRAY_SIZE(tpm2_supported_algorithms); ++i) {
> > > > +               if (tpm2_supported_algorithms[i] == algo)
> > > > +                       return tpm2_supported_algorithm_names[i];
> > > > +       }
> > > > +
> > > > +       return "";
> > > > +}
> > > > --
> > > > 2.25.1
> > > >

      reply	other threads:[~2024-03-30  7:21 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-28 17:01 [PATCH v2] tpm-v2: allow algoirthm name to be configured for pcr_read and pcr_extend Tim Harvey
2024-03-29  6:18 ` Ilias Apalodimas
2024-03-30  0:40   ` Tim Harvey
2024-03-30  7:15     ` Ilias Apalodimas
2024-03-30  7:20       ` Ilias Apalodimas [this message]

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='CAC_iWjLGdnB6H_mwNhjwG9smmw9j45=CK8odmjdJ-wVukNVEbg@mail.gmail.com' \
    --to=ilias.apalodimas@linaro.org \
    --cc=eajames@linux.ibm.com \
    --cc=slee@gateworks.com \
    --cc=tharvey@gateworks.com \
    --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.