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

Thomas Huth thuth at redhat.com
Thu Dec 10 04:01:39 AEDT 2015


On 30/11/15 23:01, Stefan Berger wrote:
> 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/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 ( )

When doing stack comments for Forth word definitions, please always use
the "( before -- after )" syntax, so in this case "( -- )".

> +    vtpm-debug? IF ." VTPM: Disabling RTAS bypass" cr THEN
> +    tpm-finalize
> +    vtpm-unit 0 rtas-set-tce-bypass
> +;
> +
> +: vtpm-init ( -- true | false )

I think that stack comment is wrong - as far as I can see, this Forth
word does not generate any items on the stack, so this should be
"( -- )" instead?

> +    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 ( )

That stack comment is also wrong, should be "( -- true )" instead.

> +    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

I think you don't need the above VALUE anymore...

> +40000 CONSTANT LOG-SIZE   \ 256k per VTPM FW spec.
> +
> +LOG-SIZE BUFFER: log-base

... since you create a new log-base buffer here.

> +\ 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/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;
> +}

Unless you stuff in some additional code into this function here in a
later patch (I haven't checked), I'd suggest to write it without "goto"
instead.

[...]
> 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

I think you could get rid of the "ELSE drop" if you'd use "?dup" instead
of "dup" before the "IF".

 Thomas



More information about the SLOF mailing list