Re: [PATCH v3 2/6] tpm: Support boot measurements

Ilias Apalodimas
2023-01-24T13:20:24Z

Hi Eddie,

On Mon, Jan 23, 2023 at 02:15:18PM -0600, Eddie James wrote:
>
> On 1/16/23 06:00, Ilias Apalodimas wrote:
> > Hi Eddie
> >
> >
> > > +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;
> > > + }
> > > +}
> > Any reason we can't move the static 'const struct digest_info
> > hash_algo_list' from the efi_tcg.c here? We can then move the
> > functions defined in there alg_to_mask and alg_to_len.
> >
> > And since alg_to_mask is really just a bitshift maybe replace that?
>
>
> Hi,
>
> It seems more efficient to keep the switch statement rather than iterate
> through the structure array looking for the matching hash algorithm? I could
> remove the 'static const struct digest_info hash_algo_list' in efi_tcg2.c
> and instead use the tpm2_algorithm_to_len and tpm2_algorithm_to_mask in
> efi_tcg2.c. What do you think?

Sure that's fine. I just prefer a single implementation of getting sizes and masks

>
>
> > > +
> > > +#define tpm2_algorithm_to_mask(a) (1 << (a))
> > > +
> > > /* NV index attributes */
> > > +

[...]

> > > + return 0;
> > > +}
> > > +
> > > +static int tcg2_log_init(struct udevice *dev, struct tcg2_event_log *elog)
> > > +{
> > I think we need to re-use efi_init_event_log here. The reason is that on
> > Arm devices TF-A is capable of constructing an eventlog and passing it
> > along in memory. That code takes that into account and tries to reuse the
> > existing EventLog passed from previous boot stages.
> >
> > The main difference between the EFI function and this one
> > is the allocated memory of the EventLog itself. But even in this case, it
> > would be better to tweak the EFI code and do
> > create log -> Allocate EFI memory -> copy log and then use that for EFI
>
>
> OK... I'll try and get that to work. I see some potential issues like the
> fact that EFI finds the platform event log differently.
>

It's been a while since I wrote this but from memory you should
1. move the code from efi_init_event_log() and replace the memory
allocation calls from efi -> calloc
2. get rid of that create_final_event() since it's part of the EFI TCG
protocol.
3. Pass the eventlog to the EFI code eventually, allocate EFI memory and
copy it and create the final events table.

The main problem I can see is handling of the EFI Final Events
table but I think it's doable.

>
> >
> > > + struct tcg_efi_spec_id_event *ev;
> > > + struct tcg_pcr_event *log;
> > > + u32 event_size;
> > > + u32 count = 0;
> > > + u32 log_size;
> > > + u32 active;
> > > + u32 mask;
> > > + size_t i;
> > > + u16 len;
> > > + int rc;
> > > +
> > > + rc = tcg2_get_active_pcr_banks(dev, &active);
> > > + if (rc)
> > > + return rc;
> > > +
> > > + event_size = offsetof(struct tcg_efi_spec_id_event, digest_sizes);
> > > + for (i = 0; i < ARRAY_SIZE(tcg2algos); ++i) {
> > > + mask = tpm2_algorithm_to_mask(tcg2algos[i]);
> > > +
> > > + if (!(active & mask))
> > > + continue;
> > > +
> > > + switch (tcg2algos[i]) {
> > > + case TPM2_ALG_SHA1:
> > > + case TPM2_ALG_SHA256:
> > > + case TPM2_ALG_SHA384:
> > > + case TPM2_ALG_SHA512:
> > > + count++;
> > > + break;
> > > + default:
> > > + continue;
> > > + }
> > > + }
> > > +
> > > + event_size += 1 +
> > > + (sizeof(struct tcg_efi_spec_id_event_algorithm_size) * count);
> > > + log_size = offsetof(struct tcg_pcr_event, event) + event_size;
> > > +
> > > + if (log_size > elog->log_size) {
> > > + printf("%s: log too large: %u > %u\n", __func__, log_size,
> > > + elog->log_size);
> > > + return -ENOBUFS;
> > > + }
> > > +
> <snip>
> > > +
> > > +int tcg2_measure_event(struct udevice *dev, struct tcg2_event_log *elog,
> > > + u32 pcr_index, u32 event_type, u32 size,
> > > + const u8 *event)
> > > +{
> > > + struct tpml_digest_values digest_list;
> > > + int rc;
> > > +
> > > + rc = tcg2_create_digest(dev, event, size, &digest_list);
> > > + if (rc)
> > > + return rc;
> > > +
> > > + rc = tcg2_pcr_extend(dev, pcr_index, &digest_list);
> > > + if (rc)
> > > + return rc;
> > > +
> > > + return tcg2_log_append_check(elog, pcr_index, event_type, &digest_list,
> > > + size, event);
> > > +}
> > There's a static efi_status_t tcg2_measure_event(...) left in efi_tcg.c
> > which breaks compilation. WE should just use the one you added in tpm-v2.c
>
>
> Hmm. The EFI version does a slightly different way of event logging, so I'm
> not sure it's that simple. There is EFI specific stuff (ExitBootServices?)
> so I'm not sure it can be common... I can change the name in efi_tcg2.c to
> compile correctly.

I think the only difference is the final events log table which is
described in the EFI TCG spec. Rename it on the next version, I'll have a
quick look in case we can unify these two as well

Thanks
/Ilias

>
>
> Thanks,
>
> Eddie
>
>
> >
> > > +
> > > + return 0;
> > > +}
> > > +
> > > u32 tpm2_dam_reset(struct udevice *dev, const char *pw, const ssize_t pw_sz)
> > > {
> > > u8 command_v2[COMMAND_BUFFER_SIZE] = {
> > > --
> > > 2.31.1
> > >
> > Regards
> > /Ilias