[SLOF] [PATCH v6 6/7] tcgbios: Add TPM 2.0 support and firmware API

Alexey Kardashevskiy aik at ozlabs.ru
Wed Jan 22 13:24:42 AEDT 2020



On 21/01/2020 04:08, Stefan Berger wrote:
> On 1/20/20 3:09 AM, Alexey Kardashevskiy wrote:
>>
>> On 16/01/2020 07:00, Stefan Berger wrote:
>>> This patch adds TPM 2.0 support along with the firmware API
>>> that Linux uses to transfer the firmware log.
>>>
>>> Signed-off-by: Stefan Berger <stefanb at linux.ibm.com>
>>> ---
>>>   board-qemu/slof/Makefile            |  13 +-
>>>   board-qemu/slof/tree.fs             |   3 +
>>>   board-qemu/slof/vio-vtpm-cdriver.fs | 134 ++++
>>>   board-qemu/slof/vtpm-sml.fs         | 115 ++++
>>>   include/helpers.h                   |   1 +
>>>   lib/libtpm/Makefile                 |   2 +-
>>>   lib/libtpm/tcgbios.c                | 918 ++++++++++++++++++++++++++++
>>>   lib/libtpm/tcgbios.h                |  32 +
>>>   lib/libtpm/tcgbios_int.h            | 240 ++++++++
>>>   lib/libtpm/tpm.code                 | 130 ++++
>>>   lib/libtpm/tpm.in                   |  26 +
>>>   slof/fs/packages/disk-label.fs      |  10 +-
>>>   slof/fs/start-up.fs                 |   5 +
>>>   13 files changed, 1624 insertions(+), 5 deletions(-)
>>>   create mode 100644 board-qemu/slof/vio-vtpm-cdriver.fs
>>>   create mode 100644 board-qemu/slof/vtpm-sml.fs
>>>   create mode 100644 lib/libtpm/tcgbios.c
>>>   create mode 100644 lib/libtpm/tcgbios.h
>>>   create mode 100644 lib/libtpm/tpm.code
>>>   create mode 100644 lib/libtpm/tpm.in
>>>
>>> diff --git a/board-qemu/slof/Makefile b/board-qemu/slof/Makefile
>>> index d7ed2d7..a8cff6d 100644
>>> --- a/board-qemu/slof/Makefile
>>> +++ b/board-qemu/slof/Makefile
>>> @@ -22,7 +22,8 @@ CPPFLAGS = -I$(LIBCMNDIR)/libbootmsg
>>> -I$(LIBCMNDIR)/libhvcall \
>>>          -I$(LIBCMNDIR)/libvirtio -I$(LIBCMNDIR)/libnvram \
>>>          -I$(LIBCMNDIR)/libusb -I$(LIBCMNDIR)/libveth \
>>>          -I$(LIBCMNDIR)/libe1k -I$(LIBCMNDIR)/libnet \
>>> -       -I$(LIBCMNDIR)/libbootmenu
>>> +       -I$(LIBCMNDIR)/libbootmenu -I$(LIBCMNDIR)/libtpm
>>> +
>>>   SLOF_LIBS = \
>>>       $(LIBCMNDIR)/libbootmsg.a \
>>>       $(LIBCMNDIR)/libelf.a \
>>> @@ -33,7 +34,9 @@ SLOF_LIBS = \
>>>       $(LIBCMNDIR)/libveth.a \
>>>       $(LIBCMNDIR)/libe1k.a \
>>>       $(LIBCMNDIR)/libnet.a \
>>> -    $(LIBCMNDIR)/libbootmenu.a
>>> +    $(LIBCMNDIR)/libbootmenu.a \
>>> +    $(LIBCMNDIR)/libtpm.a
>>> +
>>>   BOARD_SLOF_IN = \
>>>       $(LIBCMNDIR)/libhvcall/hvcall.in \
>>>       $(LIBCMNDIR)/libvirtio/virtio.in \
>>> @@ -45,7 +48,9 @@ BOARD_SLOF_IN = \
>>>       $(LIBCMNDIR)/libveth/veth.in \
>>>       $(LIBCMNDIR)/libe1k/e1k.in \
>>>       $(LIBCMNDIR)/libnet/libnet.in \
>>> -    $(LIBCMNDIR)/libbootmenu/bootmenu.in
>>> +    $(LIBCMNDIR)/libbootmenu/bootmenu.in \
>>> +    $(LIBCMNDIR)/libtpm/tpm.in
>>> +
>>>   BOARD_SLOF_CODE = $(BOARD_SLOF_IN:%.in=%.code)
>>>     include $(SLOFCMNDIR)/Makefile.inc
>>> @@ -83,6 +88,7 @@ VIO_FFS_FILES = \
>>>       $(SLOFBRDDIR)/pci-device_1af4_1050.fs \
>>>       $(SLOFBRDDIR)/vio-hvterm.fs \
>>>       $(SLOFBRDDIR)/vio-vscsi.fs \
>>> +    $(SLOFBRDDIR)/vio-vtpm-cdriver.fs \
>>
>> s/vio-vtpm-cdriver.fs/vio-vtpm.fs/ ?
>>
>>
>>>       $(SLOFBRDDIR)/vio-veth.fs \
>>>       $(SLOFBRDDIR)/rtas-nvram.fs \
>>>       $(SLOFBRDDIR)/virtio-net.fs \
>>> @@ -114,6 +120,7 @@ OF_FFS_FILES = \
>>>       $(SLOFBRDDIR)/default-font.bin \
>>>       $(SLOFBRDDIR)/pci-phb.fs \
>>>       $(SLOFBRDDIR)/rtas.fs \
>>> +    $(SLOFBRDDIR)/vtpm-sml.fs \
>>>       $(SLOFBRDDIR)/pci-device_1234_1111.fs \
>>>       $(SLOFBRDDIR)/pci-device_1013_00b8.fs \
>>>       $(SLOFBRDDIR)/pci-device_8086_100e.fs \
>>> diff --git a/board-qemu/slof/tree.fs b/board-qemu/slof/tree.fs
>>> index d95fde3..7b34125 100644
>>> --- a/board-qemu/slof/tree.fs
>>> +++ b/board-qemu/slof/tree.fs
>>> @@ -87,6 +87,9 @@ include fbuffer.fs
>>>           2dup " qemu,spapr-nvram" strequal IF
>>>               " rtas-nvram.fs" included
>>>           THEN
>>> +        2dup " IBM,vtpm20" strequal IF
>>> +                " vio-vtpm-cdriver.fs" included
>>> +        THEN
>>>               2drop
>>>          THEN
>>>          peer
>>> diff --git a/board-qemu/slof/vio-vtpm-cdriver.fs
>>> b/board-qemu/slof/vio-vtpm-cdriver.fs
>>> new file mode 100644
>>> index 0000000..8d17d0e
>>> --- /dev/null
>>> +++ b/board-qemu/slof/vio-vtpm-cdriver.fs
>>> @@ -0,0 +1,134 @@
>>> +\
>>> *****************************************************************************
>>>
>>> +\ * Copyright (c) 2015-2020 IBM Corporation
>>> +\ * All rights reserved.
>>> +\ * This program and the accompanying materials
>>> +\ * are made available under the terms of the BSD License
>>> +\ * which accompanies this distribution, and is available at
>>> +\ * http://www.opensource.org/licenses/bsd-license.php
>>> +\ *
>>> +\ * Contributors:
>>> +\ *     IBM Corporation - initial implementation
>>> +\
>>> ****************************************************************************/
>>>
>>> +
>>> +." Populating " pwd
>>> +
>>> +false VALUE vtpm-debug?
>>> +0     VALUE vtpm-unit
>>> +0     VALUE vtpm-ihandle
>>> +
>>> +: setup-alias
>>> +    " ibm,vtpm" find-alias 0= IF
>>> +        " ibm,vtpm" get-node node>path set-alias
>>> +    ELSE
>>> +        drop
>>> +    THEN
>>> +;
>>> +
>>> +: vtpm-cleanup ( )
>>> +    vtpm-debug? IF ." VTPM: Disabling RTAS bypass" cr THEN
>>> +    tpm-finalize
>>> +    vtpm-unit 0 rtas-set-tce-bypass
>>> +;
>>> +
>>> +: vtpm-init ( -- true | false )
>>> +    0 0 get-node open-node ?dup 0= IF EXIT THEN
>>> +    my-self >r
>>> +    dup to my-self
>>> +
>>> +    vtpm-debug? IF ." VTPM: Initializing for c-driver" cr THEN
>>> +
>>> +    my-unit to vtpm-unit
>>> +
>>> +    \ Enable TCE bypass special qemu feature
>>> +    vtpm-unit 1 rtas-set-tce-bypass
>>> +
>>> +    \ Have TCE bypass cleaned up
>>> +    ['] vtpm-cleanup add-quiesce-xt
>>> +
>>> +    tpm-start ?dup 0= IF
>>> +        vtpm-debug? IF ." VTPM: Success from tpm-start" cr THEN
>>> +        setup-alias
>>> +    ELSE
>>> +        ." VTPM: Error code from tpm-start: " . cr
>>> +    THEN
>>> +
>>> +    close-node
>>> +    r> to my-self
>>> +;
>>> +
>>> +\ forward a call to /ibm,vtpm, which implements the function with the
>>> +\ given name
>>> +: vtpm-call-forward ( arg ... arg name namelen -- ret ... ret
>>> failure? )
>>> +    \ assign /ibm,vtpm node to vtpm-ihandle, if not assigned
>>> +    vtpm-ihandle 0= IF
>>> +        s" /ibm,vtpm" open-dev to vtpm-ihandle
>>
>> Why does not "open" do this? Is this vtpm supposed to run even before
>> the client tries using the vtpm services? It does not look like it.
> 
> Initialization of the vTPM is supposed to happen before any client can
> talk to the firmware.


And how doing it in "open" breaks this rule? If the client does not open
the node, it cannot use the vtpm.



> 
>>
>>
>>> +    THEN
>>> +
>>> +    vtpm-ihandle 0<> IF
>>> +        vtpm-ihandle                   ( arg ... arg name namelen
>>> ihandle )
>>> +        $call-method                   ( ret ... ret )
>>> +        false                          ( ret ... ret false )
>>> +    ELSE
>>> +        true                           ( true )
>>> +    THEN
>>> +;
>>> +
>>> +\ firmware API call
>>> +: sml-get-allocated-size ( -- buffer-size)
>>> +    " sml-get-allocated-size" vtpm-call-forward IF
>>> +        \ vtpm-call-forward failed
>>> +        0
>>> +    THEN
>>> +;
>>> +
>>> +\ firmware API call
>>> +: sml-get-handover-size ( -- size)
>>> +    " sml-get-handover-size" vtpm-call-forward IF
>>> +        \ vtpm-call-forward failed
>>> +        0
>>> +    THEN
>>> +;
>>> +
>>> +\ firmware API call
>>> +: sml-handover ( dest size -- )
>>> +    " sml-handover" vtpm-call-forward IF
>>> +        \ vtpm-call-forward failed; clean up stack
>>> +        2drop
>>> +    THEN
>>> +;
>>> +
>>> +\ firmware API call
>>> +: get-failure-reason ( -- reason )
>>> +    " get-failure-reason" vtpm-call-forward IF
>>> +        \ vtpm-call-forward failed; return a value
>>> +        0 \ invalid
>>> +    THEN
>>> +;
>>> +
>>> +0 0 s" ibm,sml-efi-reformat-supported" property
>>> +
>>> +\ firmware API call
>>> +: reformat-sml-to-efi-alignment ( -- success )
>>> +    " reformat-sml-to-efi-alignment" vtpm-call-forward IF
>>> +        false
>>> +    THEN
>>> +;
>>> +
>>> +: open ( )
>>> +    vtpm-debug? IF ." VTPM: vTPM open()" cr THEN
>>> +    true
>>> +;
>>> +
>>> +: close ( )
>>> +    vtpm-debug? IF ." VTPM: vTPM close()" cr THEN
>>> +;
>>> +
>>> +\ setup alias and the RTAS bypass
>>> +vtpm-init
>>> +
>>> +\ setup the log
>>> +include vtpm-sml.fs
>>> +
>>> +s" /ibm,vtpm" find-node ?dup IF
>>> +  s" measure-scrtm" rot $call-static
>>> +THEN
>>
>> The above 22 lines confuse me a lot.
>> Why vtpm-sml.fs?
> 
> You mean why does vtpm-sml.fs exist at all?Or why not just put all vTPM
> code into one file?

Yes.



> 
>> Why "open" does not open?
>> Why vtpm-init is not in "open"?
>> Why the device methods are in vtpm-sml.fs?
>>
>> The Linux finds the device, opens it and calls methods (passing
>> ihandle), why this complication?
>>
>> I am missing the point in all of this and 2 lines commit log does not
>> help at all.
>>
>>
>>
>>
>>> diff --git a/board-qemu/slof/vtpm-sml.fs b/board-qemu/slof/vtpm-sml.fs
>>> new file mode 100644
>>> index 0000000..865dce6
>>> --- /dev/null
>>> +++ b/board-qemu/slof/vtpm-sml.fs
>>> @@ -0,0 +1,115 @@
>>> +\
>>> *****************************************************************************
>>>
>>> +\ * Copyright (c) 2015-2020 IBM Corporation
>>> +\ * All rights reserved.
>>> +\ * This program and the accompanying materials
>>> +\ * are made available under the terms of the BSD License
>>> +\ * which accompanies this distribution, and is available at
>>> +\ * http://www.opensource.org/licenses/bsd-license.php
>>> +\ *
>>> +\ * Contributors:
>>> +\ *     IBM Corporation - initial implementation
>>> +\
>>> ****************************************************************************/
>>>
>>> +
>>> +\ KVM/qemu TPM Stored Measurement Log (SML) entries in /ibm,vtpm
>>> +
>>> +" /" find-device
>>> +
>>> +new-device
>>> +
>>> +false VALUE    vtpm-debug?
>>> +0     VALUE    log-base
>>> +40000 CONSTANT LOG-SIZE   \ 256k per VTPM FW spec.
>>
>> What is this spec's name exactly? It may not be available to the public
>> but I could try and get it in IBM internally.
> 
> 
> "PFW Virtual TPM Driver" Version 1.1 (or later)


Put this to the commit log.


> 
> 
> --- /dev/null
>>> +++ b/lib/libtpm/tcgbios.c
>>> @@ -0,0 +1,918 @@
>>> +/*****************************************************************************
>>>
>>> + * Copyright (c) 2015-2020 IBM Corporation
>>> + * All rights reserved.
>>> + * This program and the accompanying materials
>>> + * are made available under the terms of the BSD License
>>> + * which accompanies this distribution, and is available at
>>> + * http://www.opensource.org/licenses/bsd-license.php
>>> + *
>>> + * Contributors:
>>> + *     IBM Corporation - initial implementation
>>> + *     Stefan Berger, stefanb at linux.ibm.com
>>> + *     Kevin O'Connor, kevin at koconnor.net
>>> +
>>> *****************************************************************************/
>>>
>>> +
>>> +/*
>>> + *  Implementation of the TPM BIOS extension according to the
>>> specification
>>> + *  described in the IBM VTPM Firmware document
>>
>> Is this "A Protocol for VTPM Communications" from
>> M_vtpm_protocol_v0r3.pdf or something else?
> 
> The title of the document is 'PFW Virtual TPM Driver'.
> PFW_CTPM_CLDD_1.1-1.pdf is the file I have.
> 

Cool, save it in the comment or commit log.


> 
>>
>>
>>> and the TCG Specification
>>> + *  that can be found here under the following link:
>>> + * 
>>> http://www.trustedcomputinggroup.org/resources/pc_client_work_group_specific_implementation_specification_for_conventional_bios
>>>
>>
>> The link is broken.
> 
> 
> https://trustedcomputinggroup.org/resource/pc-client-work-group-specific-implementation-specification-for-conventional-bios/


and this one.

> 
> 
> 
> 
>>
>>
>>> + */
>>> +
>>> +#include <stddef.h>
>>> +#include <stdlib.h>
>>> +
>>> +#include "types.h"
>>> +#include "byteorder.h"
>>> +#include "tpm_drivers.h"
>>> +#include "string.h"
>>> +#include "tcgbios.h"
>>> +#include "tcgbios_int.h"
>>> +#include "stdio.h"
>>> +#include "sha256.h"
>>> +#include "helpers.h"
>>> +#include "version.h"
>>> +#include "OF.h"
>>> +
>>> +#undef TCGBIOS_DEBUG
>>> +//#define TCGBIOS_DEBUG
>>> +#ifdef TCGBIOS_DEBUG
>>> +#define dprintf(_x ...) do { printf("TCGBIOS: " _x); } while(0)
>>> +#else
>>> +#define dprintf(_x ...)
>>> +#endif
>>> +
>>> +#define MIN(a, b) ((a) < (b) ? (a) : (b))
>>> +
>>> +struct tpm_state {
>>> +    unsigned tpm_probed:1;
>>> +    unsigned tpm_found:1;
>>> +    unsigned tpm_working:1;
>>> +
>>> +    /* base address of the log area */
>>> +    uint8_t *log_base;
>>> +
>>> +    /* size of the logging area */
>>> +    size_t log_area_size;
>>> +
>>> +    /* where to write the next log entry to */
>>> +    uint8_t *log_area_next_entry;
>>> +};
>>> +
>>> +static struct tpm_state tpm_state;
>> You do not pass a pointer to tpm_state anywhere (it would great if you
>> did - this way a reader could tell what functions actually need it) so
>> you do not need "struct tpm_state" type, can be just "struct tpm_state {
>> ... } tpm_state;"
> 
> 
> It's all global variables collected in one structure. I removed the name
> of the structure.
> 
> 
> 
>>
>>
>>
>>
>>> +
>>> +/*
>>> + * TPM 2 logs are written in little endian format.
>>> + */
>>> +static inline uint32_t log32_to_cpu(uint32_t val)
>>> +{
>>> +    return le32_to_cpu(val);
>>> +}
>>> +
>>> +static inline uint32_t cpu_to_log32(uint32_t val)
>>> +{
>>> +    return cpu_to_le32(val);
>>> +}
>>> +
>>> +static inline uint16_t cpu_to_log16(uint16_t val)
>>> +{
>>> +    return cpu_to_le16(val);
>>> +}
>>> +
>>> +/********************************************************
>>> +  Extensions for TCG-enabled BIOS
>>> + *******************************************************/
>>> +
>>> +static void probe_tpm(void)
>>> +{
>>> +    tpm_state.tpm_probed = true;
>>> +    tpm_state.tpm_found = spapr_is_vtpm_present();
>>> +    tpm_state.tpm_working = tpm_state.tpm_found;
>>> +}
>>> +
>>> +/****************************************************************
>>> + * Digest formatting
>>> + ****************************************************************/
>>> +
>>> +static uint32_t tpm20_pcr_selection_size;
>>> +static struct tpml_pcr_selection *tpm20_pcr_selection;
>>
>> Any reason these are not in tpm_state?
> 
> I will move them there.
> 
> 
>>
>>
>>> +
>>> +/* A 'struct tpm_log_entry' is a local data structure containing a
>>> + * 'tpm_log_header' followed by space for the maximum supported
>>> + * digest. The digest is a series of tpm2_digest_value structs on
>>> tpm2.0.
>>> + */
>> This comment is rather useless, what I would really be interested to is
>> the endianness (little endian because it is v2.0?) and the name of the
>> spec which defines it.
> 
> PPC64 TPM 2.0 logging is supposed to be compatible with client code
> written for x86_64 Linux. While TPM 1.2 logs on PPC64 were big endian,
> TPM 2.0 logs are now little endian. I am cc'in Christopher Engel who may
> have a more recent spec. and told me this is how it's supposed to work.
> 
> 
> 
>>
>>
>>> +struct tpm_log_entry {
>>> +    struct tpm_log_header hdr;
>>> +    uint8_t pad[sizeof(struct tpm2_digest_values)
>>> +       + 5 * sizeof(struct tpm2_digest_value)
>>> +       + SHA1_BUFSIZE + SHA256_BUFSIZE + SHA384_BUFSIZE
>>> +       + SHA512_BUFSIZE + SM3_256_BUFSIZE];
>>> +} __attribute__((packed));
>>> +
>>> +static const struct hash_parameters {
>>> +    uint16_t hashalg;
>>> +    uint8_t  hashalg_flag;
>>> +    uint8_t  hash_buffersize;
>>> +    const char *name;
>> name and hashalg_flag are not used.
> 
> True. This occurred when re-splitting the patch.
> 
> 
>>
>>> +} hash_parameters[] = {
>>> +    {
>>> +        .hashalg = TPM2_ALG_SHA1,
>>
>> TPM2_ALG_xxx are basically 1<<index_in_this_array and can be dropped,
>> can't they?
> 
> 
> No:
> 
> lib/libtpm/tcgbios_int.h:#define TPM2_ALG_SHA1 0x0004
> lib/libtpm/tcgbios_int.h:#define TPM2_ALG_SHA256 0x000b
> lib/libtpm/tcgbios_int.h:#define TPM2_ALG_SHA384 0x000c
> lib/libtpm/tcgbios_int.h:#define TPM2_ALG_SHA512 0x000d
> lib/libtpm/tcgbios_int.h:#define TPM2_ALG_SM3_256 0x0012

Oh right, I confused this with the other set:

#define TPM2_ALG_SHA1_FLAG          (1 << 0)
#define TPM2_ALG_SHA256_FLAG        (1 << 1)
#define TPM2_ALG_SHA384_FLAG        (1 << 2)
#define TPM2_ALG_SHA512_FLAG        (1 << 3)
#define TPM2_ALG_SM3_256_FLAG       (1 << 4)


It is not used by this patch, 7/7 uses it and even then it would make
more sense to define these as indexes into the hash_parameters[]. Or
just drop.


> 
> 
>>
>>
>>> +        .hash_buffersize = SHA1_BUFSIZE,
>>> +    }, {
>>> +        .hashalg = TPM2_ALG_SHA256,
>>> +        .hash_buffersize = SHA256_BUFSIZE,
>>> +    }, {
>>> +        .hashalg = TPM2_ALG_SHA384,
>>> +        .hash_buffersize = SHA384_BUFSIZE,
>>> +    }, {
>>> +        .hashalg = TPM2_ALG_SHA512,
>>> +        .hash_buffersize = SHA512_BUFSIZE,
>>> +    }, {
>>> +        .hashalg = TPM2_ALG_SM3_256,
>>> +        .hash_buffersize = SM3_256_BUFSIZE,
>>> +    }
>>> +};
>>> +
>>> +static int
>>> +tpm20_get_hash_buffersize(uint16_t hashAlg)
>>> +{
>>> +    unsigned i;
>>> +
>>> +    for (i = 0; i < ARRAY_SIZE(hash_parameters); i++) {
>>> +        if (hash_parameters[i].hashalg == hashAlg)
>>> +            return hash_parameters[i].hash_buffersize;
>>> +    }
>>> +    return -1;
>> Just make it return (const struct hash_parameters *) as 7/7 adds one
>> helper like this for every field of hash_parameters.
> 
> 
> OK.
> 
> 
>>
>>
>>> +}
>>> +
>>> +/*
>>> + * Build the TPM2 tpm2_digest_values data structure from the given
>>> hash.
>>> + * Follow the PCR bank configuration of the TPM and write the same hash
>>> + * in either truncated or zero-padded form in the areas of all the
>>> other
>>> + * hashes. For example, write the sha1 hash in the area of the sha256
>>> + * hash and fill the remaining bytes with zeros. Or truncate the sha256
>>> + * hash when writing it in the area of the sha1 hash.
>> It must be correct since you did this but what is the point of this? If
>> the digest does not fit, fill it with 0xBAADF00D and return an error?
> 
> A TPM 2 has typically 24 platform control registers (PCRs). These
> registers are storing each a hash (rather than an integer). Basically
> there is one operation on a hash, which is an 'extend':
> 
> pcr1 = sha256(pcr1 || hash)
> 
> So it takes the current value of PCR 1 and concatenates it with the
> 'hash' to extend it and hashes this concatenation and assigns the result
> to PCR 1.
> 
> A TPM 2 may have several hash banks, such as for sha1, sha256, sha384,
> sha512, sm3-256 etc.  So there may be multiple PCR 1 registers, one for
> the sha1 bank, one for the sha256 bank etc.
> 
> For the logging of measurements we are only using one hash, that is
> sha256 now, and extend this in PCR1 of sha1, sha256, etc. We do this for
> all the 'active' PCR banks basically.

Do we have to do this for all active PCR banks? Sorry for stupid
questions :)

> We log the 'hash' value that a PCR
> was extended so that someone looking at the current PCR value can use
> the log to replay (simulate) the extensions of the PCRs. Since we are
> now using sha256 for hashing we will need to truncate the sha256 when
> logging it for the sha1 bank and zero pad it for sha384 since sha384 has
> more bytes. There is the integrity measurement architecture (IMA) in
> Linux that basically does the same thing:

Something is missing after ":"?


> 
> 
> 
>>
>>
>>> + *
>>> + * le: the log entry to build the digest in
>>> + * sha1: the sha1 hash value to use
>>> + * bigEndian: whether to build in big endian format for the TPM or log
>>> + *            little endian for the log (TPM 2.0)
>>> + *
>>> + * Returns the digest size; -1 on fatal error
>>> + */
>>> +static int tpm20_build_digest(struct tpm_log_entry *le, const
>>> uint8_t *sha256,
>>> +                  bool bigEndian)
>>
>> Is not it always little endian as it is v2.0 only?
> 
> There are callers for this function who want to send the resulting data
> structures to the TPM. Other callers want this for the log written in
> little endian.


The function prototype suggests it is always for the log which is always
little endian as it is v2.0 only.


> 
>>
>>> +{
>>> +    struct tpms_pcr_selection *sel;
>>> +    void *nsel, *end;
>>> +    void *dest = le->hdr.digest + sizeof(struct tpm2_digest_values);
>>> +    uint32_t count;
>>> +    struct tpm2_digest_value *v;
>>> +    struct tpm2_digest_values *vs;
>>> +
>>> +    if (!tpm20_pcr_selection)
>>
>> This is allocated at tpm20_startup() and if allocation failed, then we
>> should not get this far, or can we?
> 
> 
> It's a safety net. Cannot keep ?

It is moving into tpm_state and you already have
tpm_probed/tpm_found/..., some are tested in various places, how many
nets do you really need?



-- 
Alexey


More information about the SLOF mailing list