[SLOF] [PATCH v3 02/17] Add TPM initialization support

Hon c Lo lo1 at us.ibm.com
Wed Feb 24 06:07:17 AEDT 2016


Stefan Berger/Watson/IBM at IBMUS wrote on 11/30/2015 05:01:45 PM:

> From: Stefan Berger/Watson/IBM at IBMUS
> To: slof at lists.ozlabs.org, nikunj at linux.vnet.ibm.com,
> aik at au1.ibm.com, pmac at au1.ibm.com
> Cc: George Wilson/Austin/IBM at IBMUS, Dimitrios Pendarakis/Watson/
> IBM at IBMUS, Joy Latten/Austin/IBM at IBMUS, Hon c Lo/Poughkeepsie/
> IBM at IBMUS, Stefan Berger/Watson/IBM at IBMUS, Tim Block/Rochester/
> IBM at IBMUS, Stefan Berger <stefanb at linux.vnet.ibm.com>
> Date: 11/30/2015 05:02 PM
> Subject: [PATCH v3 02/17] Add TPM initialization support
>
> From: Stefan Berger <stefanb at linux.vnet.ibm.com>
>
> This patch implements the main part of the firmware extensions. It
provides
> the following functionality:
>
> - initialization of the TPM by sending a sequence of commands to it
> - proper setup of the TPM before the firmware hands over control to
> the bootloader
>
> Structures that are needed in subsequent patches are also included in the
> private header file tcgbios_int.h at this point.
>
> Signed-off-by: Stefan Berger <stefanb at linux.vnet.ibm.com>
> ---
>  board-qemu/Makefile                 |   2 +-
>  board-qemu/slof/Makefile            |  10 +-
>  board-qemu/slof/tree.fs             |   3 +
>  board-qemu/slof/vio-vtpm-cdriver.fs |  72 ++++++++
>  board-qemu/slof/vtpm-sml.fs         |  62 +++++++
>  lib/Makefile                        |   2 +-
>  lib/libtpm/Makefile                 |   2 +-
>  lib/libtpm/tcgbios.c                | 335 +++++++++++++++++++++++++
> +++++++++++
>  lib/libtpm/tcgbios.h                |  22 +++
>  lib/libtpm/tcgbios_int.h            | 136 +++++++++++++++
>  lib/libtpm/tpm.code                 |  46 +++++
>  lib/libtpm/tpm.in                   |  18 ++
>  slof/fs/start-up.fs                 |   7 +
>  13 files changed, 711 insertions(+), 6 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/tcgbios_int.h
>  create mode 100644 lib/libtpm/tpm.code
>  create mode 100644 lib/libtpm/tpm.in
>
> diff --git a/board-qemu/Makefile b/board-qemu/Makefile
> index 29ee016..0c03e54 100644
> --- a/board-qemu/Makefile
> +++ b/board-qemu/Makefile
> @@ -15,7 +15,7 @@ BOARD_TARGETS = tools_build romfs_build
> clients_build stage1 subdirs
>  SUBDIRS = slof
>
>  COMMON_LIBS = libc libbootmsg libbases libnvram libelf libhvcall
> libvirtio libusb \
> -              libveth libe1k
> +              libveth libe1k libtpm
>
>  all: $(BOARD_TARGETS)
>     $(MAKE) boot_rom.bin
> diff --git a/board-qemu/slof/Makefile b/board-qemu/slof/Makefile
> index 283f77d..be6eec1 100644
> --- a/board-qemu/slof/Makefile
> +++ b/board-qemu/slof/Makefile
> @@ -21,7 +21,7 @@ all: version.o Makefile.dep OF.ffs paflof $
> (SLOFCMNDIR)/xvect.bin
>  CPPFLAGS = -I$(LIBCMNDIR)/libbootmsg -I$(LIBCMNDIR)/libhvcall \
>        -I$(LIBCMNDIR)/libvirtio -I$(LIBCMNDIR)/libnvram \
>        -I$(LIBCMNDIR)/libusb -I$(LIBCMNDIR)/libveth \
> -      -I$(LIBCMNDIR)/libe1k
> +      -I$(LIBCMNDIR)/libe1k -I$(LIBCMNDIR)/libtpm
>  SLOF_LIBS = \
>     $(LIBCMNDIR)/libbootmsg.a \
>     $(LIBCMNDIR)/libelf.a \
> @@ -30,7 +30,8 @@ SLOF_LIBS = \
>     $(LIBCMNDIR)/libusb.a \
>     $(LIBCMNDIR)/libnvram.a \
>     $(LIBCMNDIR)/libveth.a \
> -   $(LIBCMNDIR)/libe1k.a
> +   $(LIBCMNDIR)/libe1k.a \
> +   $(LIBCMNDIR)/libtpm.a
>  BOARD_SLOF_IN = \
>     $(LIBCMNDIR)/libhvcall/hvcall.in \
>     $(LIBCMNDIR)/libvirtio/virtio.in \
> @@ -40,7 +41,8 @@ BOARD_SLOF_IN = \
>     $(LIBCMNDIR)/libnvram/libnvram.in \
>     $(LIBCMNDIR)/libbases/libbases.in \
>     $(LIBCMNDIR)/libveth/veth.in \
> -   $(LIBCMNDIR)/libe1k/e1k.in
> +   $(LIBCMNDIR)/libe1k/e1k.in \
> +   $(LIBCMNDIR)/libtpm/tpm.in
>  BOARD_SLOF_CODE = $(BOARD_SLOF_IN:%.in=%.code)
>
>  include $(SLOFCMNDIR)/Makefile.inc
> @@ -71,6 +73,7 @@ VIO_FFS_FILES = \
>     $(SLOFBRDDIR)/pci-device_1af4_1009.fs \
>     $(SLOFBRDDIR)/vio-hvterm.fs \
>     $(SLOFBRDDIR)/vio-vscsi.fs \
> +   $(SLOFBRDDIR)/vio-vtpm-cdriver.fs \
>     $(SLOFBRDDIR)/vio-veth.fs \
>     $(SLOFBRDDIR)/rtas-nvram.fs \
>     $(SLOFBRDDIR)/virtio-net.fs \
> @@ -99,6 +102,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 4aba4c5..b71009d 100644
> --- a/board-qemu/slof/tree.fs
> +++ b/board-qemu/slof/tree.fs
> @@ -83,6 +83,9 @@ include fbuffer.fs
>         2dup " qemu,spapr-nvram" strequal IF
>            " rtas-nvram.fs" included
>         THEN
> +       2dup " IBM,vtpm" 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..f873456
> --- /dev/null
> +++ b/board-qemu/slof/vio-vtpm-cdriver.fs
> @@ -0,0 +1,72 @@
> +\
>
*****************************************************************************

> +\ * Copyright (c) 2015 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
> +
> +: 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
> +        drop
> +        setup-alias
> +    ELSE
> +        ." VTPM: Error code from tpm-start: " . cr
> +    THEN
> +
> +    close-node
> +    r> to my-self
> +;
> +
> +: 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
> diff --git a/board-qemu/slof/vtpm-sml.fs b/board-qemu/slof/vtpm-sml.fs
> new file mode 100644
> index 0000000..4d63b70
> --- /dev/null
> +++ b/board-qemu/slof/vtpm-sml.fs
> @@ -0,0 +1,62 @@
> +\
>
*****************************************************************************

> +\ * Copyright (c) 2015 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.
> +
> +LOG-SIZE BUFFER: log-base
> +
> +\ create /ibm,vtpm
> +s" ibm,vtpm" 2dup device-name device-type
> +
> +: sml-get-allocated-size ( -- buffer-size)
> +    vtpm-debug? IF
> +        ." Call to sml-get-allocated-size; size = 0x" LOG-SIZE . cr
> +    THEN
> +    LOG-SIZE
> +;
> +
> +: sml-handover ( dest size -- )
> +    vtpm-debug? IF
> +        2dup
> +        ." Call to sml-handover; size = 0x" . ." dest = " . cr
> +    THEN
> +    log-base        ( dest size src )
> +    -rot            ( src dest size )
> +    move
> +;
> +
> +\
> +\ internal API calls
> +\
> +
> +: unassert-physical-presence ( -- )
> +    tpm-unassert-physical-presence                    ( -- errcode )
> +    dup 0<> IF
> +        ." VTPM: Error code from tpm-unassert-physical-presence: " . cr
> +    ELSE
> +        drop
> +    THEN
> +;
> +
> +: open  true ;
> +: close ;
> +
> +finish-device
> +device-end
> diff --git a/lib/Makefile b/lib/Makefile
> index ed8a359..9c802e2 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -11,7 +11,7 @@
>  #
>
****************************************************************************/

>
>  SUBDIRS = libc libipmi libbootmsg libbases libnvram libelf
> libhvcall libvirtio \
> -          libusb libveth libe1k libbcm
> +          libusb libveth libe1k libbcm libtpm
>
>  all:  subdirs
>
> diff --git a/lib/libtpm/Makefile b/lib/libtpm/Makefile
> index ff19e1c..012fe37 100644
> --- a/lib/libtpm/Makefile
> +++ b/lib/libtpm/Makefile
> @@ -23,7 +23,7 @@ TARGET = ../libtpm.a
>
>  all: $(TARGET)
>
> -SRCS = tpm_drivers.c
> +SRCS = tpm_drivers.c tcgbios.c
>
>  OBJS = $(SRCS:%.c=%.o)
>
> diff --git a/lib/libtpm/tcgbios.c b/lib/libtpm/tcgbios.c
> new file mode 100644
> index 0000000..dd0d801
> --- /dev/null
> +++ b/lib/libtpm/tcgbios.c
> @@ -0,0 +1,335 @@
> +
> +/
>
*****************************************************************************

> + * Copyright (c) 2015 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
> +
>
*****************************************************************************/

> +
> +/*
> + *  Implementation of the TPM BIOS extension according to the
specification
> + *  described in the IBM VTPM Firmware document 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

> + */
> +
> +#include "types.h"
> +#include "byteorder.h"
> +#include "tpm_drivers.h"
> +#include "string.h"
> +#include "tcgbios.h"
> +#include "tcgbios_int.h"
> +#include "stdio.h"
> +
> +#undef TCGBIOS_DEBUG
> +//#define TCGBIOS_DEBUG
> +#ifdef TCGBIOS_DEBUG
> +#define dprintf(_x ...) do { printf("TCGBIOS: " _x); } while(0)
> +#else
> +#define dprintf(_x ...)
> +#endif
> +

> +static const uint8_t startup_st_clear[] = { 0x00, TPM_ST_CLEAR };
> +static const uint8_t startup_st_state[] = { 0x00, TPM_ST_STATE };
> +
> +static const uint8_t physical_presence_cmd_enable[]  = { 0x00, 0x20 };
> +static const uint8_t physical_presence_cmd_disable[] = { 0x01, 0x00 };
> +static const uint8_t physical_presence_present[]     = { 0x00, 0x08 };
> +static const uint8_t physical_presence_not_present_lock[] = { 0x00,
0x14 };
> +
> +static const uint8_t command_flag_false[] = { 0x00 };
> +static const uint8_t command_flag_true[]  = { 0x01 };
> +
> +static const uint8_t get_capability_permanent_flags[] = {
> +   0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04,
> +   0x00, 0x00, 0x01, 0x08
> +};
> +
> +static const uint8_t get_capability_owner_auth[] = {
> +   0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04,
> +   0x00, 0x00, 0x01, 0x11
> +};
> +
> +static const uint8_t get_capability_timeouts[] = {
> +   0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04,
> +   0x00, 0x00, 0x01, 0x15
> +};
> +
> +static const uint8_t get_capability_durations[] = {
> +   0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04,
> +   0x00, 0x00, 0x01, 0x20
> +};
> +
> +struct tpm_state {
> +   unsigned tpm_probed:1;
> +   unsigned tpm_found:1;
> +   unsigned tpm_working:1;
> +};
> +
> +static struct tpm_state tpm_state;
> +
> +/********************************************************
> +  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;
> +}
> +
> +static bool has_working_tpm(void)
> +{
> +   if (!tpm_state.tpm_probed)
> +      probe_tpm();
> +
> +   return tpm_state.tpm_working;
> +}
> +
> +static uint32_t transmit(struct tpm_req_header *req,
> +          uint8_t *respbuffer, uint32_t *respbufferlen,
> +          enum tpm_duration_type to_t)
> +{
> +   if (!spapr_vtpm_transmit((uint8_t *)req, be32_to_cpu(req->totlen),
> +                            to_t, respbuffer, respbufferlen))
> +      goto err_exit;
> +
> +   return 0;
> +
> +err_exit:
> +   /* do not send any commands */
> +   tpm_state.tpm_working = false;
> +
> +   return TCGBIOS_FATAL_COM_ERROR;
> +}
> +

I would get rid of the goto stmt and the label, and directly put the last
two lines of code inside the If-statement.



> +/*
> + * Send a TPM command with the given ordinal. Append the given buffer
> + * containing all data in network byte order to the command (this is
> + * the custom part per command) and expect a response of the given size.
> + * If a buffer is provided, the response will be copied into it.
> + */
> +static uint32_t build_and_send_cmd(uint32_t ordinal,
> +               const uint8_t *append,
> +               uint32_t append_size,
> +               uint8_t *resbuffer,
> +               uint32_t return_size,
> +               uint32_t *return_code,
> +               enum tpm_duration_type to_t)
> +{
> +   uint32_t rc;
> +   struct {
> +      struct tpm_req_header trqh;
> +      uint8_t cmd[64];
> +   } __attribute__((packed)) req = {
> +      .trqh.tag = cpu_to_be16(TPM_TAG_RQU_CMD),
> +      .trqh.totlen = cpu_to_be32(TPM_REQ_HEADER_SIZE + append_size),
> +      .trqh.ordinal = cpu_to_be32(ordinal),
> +   };
> +   uint8_t obuffer[64];
> +   struct tpm_rsp_header *trsh = (struct tpm_rsp_header *)obuffer;


I'm not sure whether this cast is possible.  I was expecting the response
to be a similar structure, like 'req', which would contain both header and
a buffer for TPM response commands.
I dont see how obuffer can be mapped into the following definition:

struct tpm_rsp_header {
	uint16_t tag;
	uint32_t totlen;
	uint32_t errcode;
} __attribute__((packed));

Wouldn't we need a structure like 'req' for response? Am I missing
something?


> +   uint32_t obuffer_len = sizeof(obuffer);
> +
> +   if (return_size > sizeof(obuffer) || append_size > sizeof(req.cmd)) {
> +      printf("TCGBIOS: Error: size of requested response buffer too
big.");
> +      return TCGBIOS_FIRMWARE_ERROR;
> +   }
> +
> +   memset(obuffer, 0, sizeof(obuffer));
> +
> +   if (append_size)
> +      memcpy(req.cmd, append, append_size);
> +
> +   rc = transmit(&req.trqh, obuffer, &obuffer_len, to_t);
> +   if (rc)
> +      return rc;
> +
> +   *return_code = be32_to_cpu(trsh->errcode);
> +
> +   if (resbuffer)
> +      memcpy(resbuffer, trsh, return_size);
> +
> +   return 0;
> +}
> +
> +static void tpm_set_failure(void)
> +{
> +   uint32_t return_code;
> +
> +   /* we will try to deactivate the TPM now - ignoring all errors */
> +   build_and_send_cmd(TPM_ORD_PHYSICAL_PRESENCE,
> +            physical_presence_cmd_enable,
> +            sizeof(physical_presence_cmd_enable),
> +            NULL, 0, &return_code,
> +            TPM_DURATION_TYPE_SHORT);
> +
> +   build_and_send_cmd(TPM_ORD_PHYSICAL_PRESENCE,
> +            physical_presence_present,
> +            sizeof(physical_presence_present),
> +            NULL, 0, &return_code,
> +            TPM_DURATION_TYPE_SHORT);
> +
> +   build_and_send_cmd(TPM_ORD_SET_TEMP_DEACTIVATED,
> +            NULL, 0, NULL, 0, &return_code,
> +            TPM_DURATION_TYPE_SHORT);
> +
> +   tpm_state.tpm_working = false;
> +}
> +
> +static uint32_t determine_timeouts(void)
> +{
> +   uint32_t rc;
> +   uint32_t return_code;
> +   struct tpm_rsp_getcap_durations durations;
> +   unsigned int i;
> +
> +   rc = build_and_send_cmd(TPM_ORD_GET_CAPABILITY,
> +            get_capability_durations,
> +            sizeof(get_capability_durations),
> +            (uint8_t *)&durations, sizeof(durations),
> +            &return_code, TPM_DURATION_TYPE_SHORT);
> +
> +   dprintf("Return code from TPM_GetCapability(Durations) = 0x%08x\n",
> +      return_code);
> +
> +   if (rc || return_code)
> +      goto err_exit;
> +
> +   for (i = 0; i < TPM_NUM_DURATIONS; i++)
> +      durations.durations[i] = be32_to_cpu(durations.durations[i]);
> +
> +   dprintf("durations: %u %u %u\n",
> +      durations.durations[0],
> +      durations.durations[1],
> +      durations.durations[2]);
> +
> +   spapr_vtpm_set_durations(durations.durations);
> +
> +   return 0;
> +
> +err_exit:
> +   dprintf("TPM malfunctioning (line %d).\n", __LINE__);
> +
> +   tpm_set_failure();
> +   if (rc)
> +      return rc;
> +   return TCGBIOS_COMMAND_ERROR;
> +}

Again, I would get rid of the goto stmt to branch off for readability,
unless there are multiple instances of the 'goto' stmts, like the following
function.


> +
> +static uint32_t tpm_startup(void)
> +{
> +   uint32_t rc;
> +   uint32_t return_code;
> +
> +   if (!())
> +      return TCGBIOS_GENERAL_ERROR;
> +
> +   dprintf("Starting with TPM_Startup(ST_CLEAR)\n");
> +   rc = build_and_send_cmd(TPM_ORD_STARTUP,
> +            startup_st_clear, sizeof(startup_st_clear),
> +            NULL, 0, &return_code,
> +            TPM_DURATION_TYPE_SHORT);
> +
> +   dprintf("Return code from TPM_Startup = 0x%08x\n",
> +      return_code);
> +
> +   if (rc || return_code)
> +      goto err_exit;
> +
> +   rc = build_and_send_cmd(TPM_ORD_SELF_TEST_FULL, NULL, 0,
> +            NULL, 0, &return_code,
> +            TPM_DURATION_TYPE_LONG);
> +
> +   dprintf("Return code from TPM_SelfTestFull = 0x%08x\n",
> +      return_code);
> +
> +   if (rc || return_code)
> +      goto err_exit;
> +
> +   rc = determine_timeouts();
> +   if (rc)
> +      goto err_exit;
> +
> +   return 0;
> +
> +err_exit:
> +   dprintf("TPM malfunctioning (line %d).\n", __LINE__);
> +
> +   tpm_set_failure();
> +   if (rc)
> +      return rc;
> +   return TCGBIOS_COMMAND_ERROR;
> +}
> +
> +uint32_t tpm_start(void)
> +{
> +   tpm_state.tpm_probed = false;
> +   tpm_state.tpm_found = false;
> +   tpm_state.tpm_working = false;
> +
> +   if (!has_working_tpm()) {
> +      dprintf("%s: Machine does not have a working TPM\n",
> +         __func__);
> +      return TCGBIOS_FATAL_COM_ERROR;
> +   }
> +
> +   return tpm_startup();
> +}
> +
> +void tpm_finalize(void)
> +{
> +   spapr_vtpm_finalize();
> +}
> +
> +/*
> + * Give up physical presence; this function has to be called before
> + * the firmware transitions to the boot loader.
> + */
> +uint32_t tpm_unassert_physical_presence(void)
> +{
> +   uint32_t rc;
> +   uint32_t return_code;
> +
> +   if (!has_working_tpm())
> +      return TCGBIOS_GENERAL_ERROR;
> +
> +   rc = build_and_send_cmd(TPM_ORD_PHYSICAL_PRESENCE,
> +            physical_presence_cmd_enable,
> +            sizeof(physical_presence_cmd_enable),
> +            NULL, 0, &return_code,
> +            TPM_DURATION_TYPE_SHORT);
> +
> +   dprintf("Return code from TPM_PhysicalPresence(CMD_ENABLE) = 0x%08x
\n",
> +      return_code);
> +
> +   if (rc || return_code)
> +      goto err_exit;
> +
> +   rc = build_and_send_cmd(TPM_ORD_PHYSICAL_PRESENCE,
> +            physical_presence_not_present_lock,
> +            sizeof(physical_presence_not_present_lock),
> +            NULL, 0, &return_code,
> +            TPM_DURATION_TYPE_SHORT);
> +
> +   dprintf("Return code from TPM_PhysicalPresence(NOT_PRESENT_LOCK)
> = 0x%08x\n",
> +      return_code);
> +
> +   if (rc || return_code)
> +      goto err_exit;
> +
> +   return 0;
> +
> +err_exit:
> +   dprintf("TPM malfunctioning (line %d).\n", __LINE__);
> +
> +   tpm_set_failure();
> +   if (rc)
> +      return rc;
> +   return TCGBIOS_COMMAND_ERROR;
> +}
> diff --git a/lib/libtpm/tcgbios.h b/lib/libtpm/tcgbios.h
> new file mode 100644
> index 0000000..5b5e481
> --- /dev/null
> +++ b/lib/libtpm/tcgbios.h
> @@ -0,0 +1,22 @@
> +/
>
*****************************************************************************

> + * Copyright (c) 2015 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
> +
>
*****************************************************************************/

> +
> +#ifndef TCGBIOS_H
> +#define TCGBIOS_H
> +
> +#include <stdint.h>
> +
> +uint32_t tpm_start(void);
> +void tpm_finalize(void);
> +uint32_t tpm_unassert_physical_presence(void);
> +
> +#endif /* TCGBIOS_H */
> diff --git a/lib/libtpm/tcgbios_int.h b/lib/libtpm/tcgbios_int.h
> new file mode 100644
> index 0000000..c0cb960
> --- /dev/null
> +++ b/lib/libtpm/tcgbios_int.h
> @@ -0,0 +1,136 @@
> +/
>
*****************************************************************************

> + * Copyright (c) 2015 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
> +
>
*****************************************************************************/

> +
> +#ifndef TCGBIOS_INT_H
> +#define TCGBIOS_INT_H
> +
> +#include <stdint.h>
> +
> +#include "tpm_drivers.h"
> +
> +/* internal error codes */
> +#define TCGBIOS_OK                       0x0
> +#define TCGBIOS_LOGOVERFLOW              0x1
> +#define TCGBIOS_GENERAL_ERROR            0x2
> +#define TCGBIOS_FIRMWARE_ERROR           0x3
> +#define TCGBIOS_FATAL_COM_ERROR          0x4
> +#define TCGBIOS_INVALID_INPUT_PARA       0x5
> +#define TCGBIOS_COMMAND_ERROR            0x6
> +#define TCGBIOS_INTERFACE_SHUTDOWN       0x7
> +
> +#define TPM_ORD_SELF_TEST_FULL           0x00000050
> +#define TPM_ORD_FORCE_CLEAR              0x0000005d
> +#define TPM_ORD_GET_CAPABILITY           0x00000065
> +#define TPM_ORD_PHYSICAL_ENABLE          0x0000006f
> +#define TPM_ORD_PHYSICAL_DISABLE         0x00000070
> +#define TPM_ORD_SET_OWNER_INSTALL        0x00000071
> +#define TPM_ORD_PHYSICAL_SET_DEACTIVATED 0x00000072
> +#define TPM_ORD_SET_TEMP_DEACTIVATED     0x00000073
> +#define TPM_ORD_STARTUP                  0x00000099
> +#define TPM_ORD_PHYSICAL_PRESENCE        0x4000000a
> +#define TPM_ORD_EXTEND                   0x00000014
> +
> +#define TPM_ST_CLEAR                     0x1
> +#define TPM_ST_STATE                     0x2
> +#define TPM_ST_DEACTIVATED               0x3
> +
> +#define TPM_TAG_RQU_CMD                  0x00c1
> +
> +/* TPM command error codes */
> +#define TPM_INVALID_POSTINIT             0x26
> +
> +/* event types */
> +#define EV_POST_CODE                     1
> +#define EV_SEPARATOR                     4
> +#define EV_ACTION                        5
> +#define EV_EVENT_TAG                     6
> +#define EV_IPL                          13
> +#define EV_IPL_PARTITION_DATA           14
> +
> +#define SHA1_BUFSIZE                    20
> +
> +/* Input and Output blocks for the TCG BIOS commands */
> +
> +/* PCClient_PCREventStruct -- format of log entries; compatible with x86
*/
> +struct pcpes {
> +   uint32_t pcrindex;
> +   uint32_t eventtype;
> +   uint8_t digest[SHA1_BUFSIZE];
> +   uint32_t eventdatasize;
> +   uint32_t event;
> +} __attribute__((packed));
> +
> +struct tpm_req_header {
> +   uint16_t tag;
> +   uint32_t totlen;
> +   uint32_t ordinal;
> +} __attribute__((packed));
> +
> +#define TPM_REQ_HEADER_SIZE (sizeof(struct tpm_req_header))
> +
> +struct tpm_rsp_header {
> +   uint16_t tag;
> +   uint32_t totlen;
> +   uint32_t errcode;
> +} __attribute__((packed));
> +
> +#define TPM_RSP_HEADER_SIZE (sizeof(struct tpm_rsp_header))
> +
> +struct tpm_req_extend {
> +   struct tpm_req_header hdr;
> +   uint32_t pcrindex;
> +   uint8_t digest[SHA1_BUFSIZE];
> +} __attribute__((packed));
> +
> +struct tpm_rsp_extend {
> +   struct tpm_rsp_header hdr;
> +   uint8_t digest[SHA1_BUFSIZE];
> +} __attribute__((packed));
> +
> +struct tpm_req_getcap_perm_flags {
> +   struct tpm_req_header hdr;
> +   uint32_t cap_area;
> +   uint32_t sub_cap_zize;
> +   uint32_t sub_cap;
> +} __attribute__((packed));
> +
> +struct tpm_permanent_flags {
> +   uint16_t tag;
> +   uint8_t flags[20];
> +} __attribute__((packed));
> +
> +#define PERM_FLAG_IDX_DISABLE 0
> +#define PERM_FLAG_IDX_OWNERSHIP 1
> +#define PERM_FLAG_IDX_DEACTIVATED 2
> +#define PERM_FLAG_IDX_DISABLEOWNERCLEAR 4
> +#define PERM_FLAG_IDX_PHYSICAL_PRESENCE_LIFETIME_LOCK 6
> +#define PERM_FLAG_IDX_PHYSICAL_PRESENCE_HW_ENABLE 7
> +
> +struct tpm_rsp_getcap_perm_flags {
> +   struct tpm_rsp_header hdr;
> +   uint32_t size;
> +   struct tpm_permanent_flags perm_flags;
> +} __attribute__((packed));
> +
> +struct tpm_rsp_getcap_ownerauth {
> +   struct tpm_rsp_header hdr;
> +   uint32_t size;
> +   uint8_t flag;
> +} __attribute__((packed));
> +
> +struct  {
> +   struct tpm_rsp_header hdr;
> +   uint32_t size;
> +   uint32_t durations[TPM_NUM_DURATIONS];
> +} __attribute__((packed));
> +
> +#endif /* TCGBIOS_INT_H */
> diff --git a/lib/libtpm/tpm.code b/lib/libtpm/tpm.code
> new file mode 100644
> index 0000000..08f52e9
> --- /dev/null
> +++ b/lib/libtpm/tpm.code
> @@ -0,0 +1,46 @@
> +/
>
******************************************************************************

> + * Copyright (c) 2015 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
> +
>
*****************************************************************************/

> +/*
> + * libtpm bindings for SLOF - implementation
> + */
> +
> +#include <tcgbios.h>
> +
> +
> +/************************************************/
> +/* Startup TPM code                             */
> +/* SLOF:   tpm-start  ( -- errcode )            */
> +/* LIBTPM: tpm_start(void)                      */
> +/************************************************/
> +PRIM(tpm_X2d_start)
> +   PUSH;
> +   TOS.n = tpm_start();
> +MIRP
> +
> +/************************************************/
> +/* Shutdown TPM layer before OS takes over      */
> +/* SLOF:   tpm-finalize  ( -- )                 */
> +/* LIBTPM: tpm_finalize(void)                   */
> +/************************************************/
> +PRIM(tpm_X2d_finalize)
> +   tpm_finalize();
> +MIRP
> +
> +/***************************************************************/
> +/* Prepare TPM state for bootloader                            */
> +/* SLOF:   tpm-unassert-physical-presence ( -- errcode )       */
> +/* LIBTPM: tpm_unassert_physical-presence(void)                */
> +/***************************************************************/
> +PRIM(tpm_X2d_unassert_X2d_physical_X2d_presence)
> +   PUSH;
> +   TOS.n = tpm_unassert_physical_presence();
> +MIRP
> diff --git a/lib/libtpm/tpm.in b/lib/libtpm/tpm.in
> new file mode 100644
> index 0000000..e212483
> --- /dev/null
> +++ b/lib/libtpm/tpm.in
> @@ -0,0 +1,18 @@
> +/
>
******************************************************************************

> + * Copyright (c) 2015 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
> +
>
*****************************************************************************/

> +/*
> + * libtpm bindings for SLOF - definitions
> + */
> +
> +cod(tpm-start)
> +cod(tpm-finalize)
> +cod(tpm-unassert-physical-presence)
> diff --git a/slof/fs/start-up.fs b/slof/fs/start-up.fs
> index f1488fa..f115b89 100644
> --- a/slof/fs/start-up.fs
> +++ b/slof/fs/start-up.fs
> @@ -56,6 +56,13 @@
>  ;
>
>  : (boot?) ( -- )
> +   \ last step before we boot we give up physical presence on the TPM
> +   s" /ibm,vtpm" find-node dup IF
> +      s" unassert-physical-presence" rot $call-static
> +   ELSE
> +      drop
> +   THEN
> +
>     of-prompt? not auto-boot? and IF
>        (boot)
>     THEN
> --
> 2.4.3
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/slof/attachments/20160223/6c07a8a9/attachment-0001.html>


More information about the SLOF mailing list