[SLOF] [PATCH 09/16] Add support for a TPM menu to control the state of the TPM

Nikunj A Dadhania nikunj at linux.vnet.ibm.com
Mon Nov 9 21:51:04 AEDT 2015


Stefan Berger <stefanb at linux.vnet.ibm.com> writes:

> This patch provides an addtional menu that enables the user to control
> certain aspects of the TPM's state.
>
> If a working TPM has been detected, the menu will look like this:
>
> The TPM is enabled, active, does not have an owner but one can be installed.
>
> To configure the TPM, choose one of the following actions:
>
> d. Disable the TPM
> v. Deactivate the TPM
> p. Prevent installation of an owner
>
>
> Note: To fully use the TPM it must be enabled and activated.
>
> Press escape to continue boot.
>
>
> This menu can be access by pressing the 't' key during boot. The menu will not
> be shown if no TPM is available.
>
> Signed-off-by: Stefan Berger <stefanb at linux.vnet.ibm.com>
> ---
>  board-qemu/slof/OF.fs     |   2 +-
>  lib/libtpm/tcgbios.c      |  33 ++++++++
>  lib/libtpm/tcgbios.h      |   9 +++
>  lib/libtpm/tpm.code       |  20 +++++
>  lib/libtpm/tpm.in         |   2 +
>  slof/fs/start-up.fs       |   9 +++
>  slof/fs/tpm/tpm-static.fs | 193 ++++++++++++++++++++++++++++++++++++++++++++++
>  7 files changed, 267 insertions(+), 1 deletion(-)
>
> diff --git a/board-qemu/slof/OF.fs b/board-qemu/slof/OF.fs
> index 1306371..cb63455 100644
> --- a/board-qemu/slof/OF.fs
> +++ b/board-qemu/slof/OF.fs
> @@ -180,6 +180,7 @@ CREATE version-str 10 ALLOT
>      version-str 8 + @               \ end
>      over - terminal-write drop
>      " Press 's' to enter Open Firmware." terminal-write drop
> +    vtpm-available? IF "  Press 't' to enter TPM menu." terminal-write drop THEN
>      cr cr
>      temp-ptr disp-size > IF
>  	temp-ptr disp-size MOD
> @@ -305,7 +306,6 @@ cr
>  cr cr
>
>  vtpm-add-event-separators
> -vtpm-unassert-pp
>
>  \ this CATCH is to ensure the code bellow always executes:  boot may ABORT!
>  ' start-it CATCH drop
> diff --git a/lib/libtpm/tcgbios.c b/lib/libtpm/tcgbios.c
> index cabd980..40557d6 100644
> --- a/lib/libtpm/tcgbios.c
> +++ b/lib/libtpm/tcgbios.c
> @@ -1350,3 +1350,36 @@ uint32_t tpm_process_opcode(uint8_t op, bool verbose)
>
>  	return tpm_process_cfg(&cfg, verbose, &returnCode);
>  }
> +
> +int tpm_get_state(void)
> +{
> +	int state = 0;
> +	struct tpm_permanent_flags pf;
> +	bool has_owner;
> +
> +	if (read_permanent_flags((char *)&pf, sizeof(pf)) ||
> +	    read_has_owner(&has_owner))
> +		return ~0;
> +
> +	if (!pf.flags[PERM_FLAG_IDX_DISABLE])
> +		state |= TPM_STATE_ENABLED; /* enabled */
> +
> +	if (!pf.flags[PERM_FLAG_IDX_DEACTIVATED])
> +		state |= TPM_STATE_ACTIVE; /* active */
> +
> +	if (has_owner) {
> +		state |= TPM_STATE_OWNED; /* has owner */
> +	} else {
> +		if (pf.flags[PERM_FLAG_IDX_OWNERSHIP])
> +			state |= TPM_STATE_OWNERINSTALL; /* owner can be installed */
> +	}
> +
> +	dprintf("TPM state flags = 0x%x\n", state);
> +
> +	return state;
> +}
> +
> +bool tpm_is_working(void)
> +{
> +	return has_working_tpm();
> +}
> diff --git a/lib/libtpm/tcgbios.h b/lib/libtpm/tcgbios.h
> index e0a7045..902ea1f 100644
> --- a/lib/libtpm/tcgbios.h
> +++ b/lib/libtpm/tcgbios.h
> @@ -31,4 +31,13 @@ uint32_t tpm_add_bcv(uint32_t bootdrv, const uint8_t *addr, uint32_t length);
>  uint32_t tpm_add_event_separators(void);
>  uint32_t tpm_process_opcode(uint8_t op, bool verbose);
>
> +/* flags returned by tpm_get_state */
> +#define TPM_STATE_ENABLED        1
> +#define TPM_STATE_ACTIVE         2
> +#define TPM_STATE_OWNED          4
> +#define TPM_STATE_OWNERINSTALL   8
> +
> +int tpm_get_state(void);
> +bool tpm_is_working(void);
> +
>  #endif /* TCGBIOS_H */
> diff --git a/lib/libtpm/tpm.code b/lib/libtpm/tpm.code
> index 7728317..66250d5 100644
> --- a/lib/libtpm/tpm.code
> +++ b/lib/libtpm/tpm.code
> @@ -102,3 +102,23 @@ PRIM(tpm_X2d_process_X2d_opcode)
>  	bool verbose = TOS.u;
>  	TOS.n = tpm_process_opcode(opcode, verbose);
>  MIRP
> +
> +/************************************************/
> +/* Get state of the TPM in form of flags        */
> +/* SLOF:   tpm-get-state  ( -- flags )          */
> +/* LIBTPM: state = tpm_get_state()              */
> +/************************************************/
> +PRIM(tpm_X2d_get_X2d_state)
> +	PUSH;
> +	TOS.n = tpm_get_state();
> +MIRP
> +
> +/************************************************/
> +/* Check whether the TPM is working             */
> +/* SLOF:   tpm-is-working  ( -- true | false )  */
> +/* LIBTPM: bool = tpm_is_working()              */
> +/************************************************/
> +PRIM(tpm_X2d_is_X2d_working)
> +	PUSH;
> +	TOS.n = tpm_is_working();
> +MIRP
> diff --git a/lib/libtpm/tpm.in b/lib/libtpm/tpm.in
> index e5dbc25..f2cc81e 100644
> --- a/lib/libtpm/tpm.in
> +++ b/lib/libtpm/tpm.in
> @@ -21,3 +21,5 @@ cod(tpm-add-event-separators)
>  cod(tpm-ipl)
>  cod(tpm-add-bcv)
>  cod(tpm-process-opcode)
> +cod(tpm-get-state)
> +cod(tpm-is-working)
> diff --git a/slof/fs/start-up.fs b/slof/fs/start-up.fs
> index f1488fa..015e6c1 100644
> --- a/slof/fs/start-up.fs
> +++ b/slof/fs/start-up.fs
> @@ -55,7 +55,15 @@
>     nvramlog-write-string-cr
>  ;
>
> +: (t-pressed) ( -- )
> +   vtpm-menu
> +;
> +
>  : (boot?) ( -- )
> +   \ before we boot (and after the TPM menu) make sure we give up
> +   \ physical presence on the TPM and lock it -> call vtpm-unassert-pp
> +   vtpm-unassert-pp
> +

0) vtpm-unassert-pp returns uint32_t, that remains in the stack.
1) Why dont you check if TPM is available before calling this ?
2) Why are errors not handled?

>     of-prompt? not auto-boot? and IF
>        (boot)
>     THEN
> @@ -147,6 +155,7 @@ TRUE VALUE use-load-watchdog?
>     key? IF
>        key CASE
>  	 [char] s  OF (s-pressed) ENDOF
> +	 [char] t  OF (t-pressed) (boot?) ENDOF
>  	 1b        OF
>  	     (esc-sequence) CASE
>  		 1   OF
> diff --git a/slof/fs/tpm/tpm-static.fs b/slof/fs/tpm/tpm-static.fs
> index d425693..7954be2 100644
> --- a/slof/fs/tpm/tpm-static.fs
> +++ b/slof/fs/tpm/tpm-static.fs
> @@ -43,3 +43,196 @@ false VALUE vtpm-debug?
>          THEN
>      THEN
>  ;
> +
> +1 CONSTANT TPM_ST_ENABLED
> +2 CONSTANT TPM_ST_ACTIVE
> +4 CONSTANT TPM_ST_OWNED
> +8 CONSTANT TPM_ST_OWNERINSTALL
> +
> +\ helper to test whether the TPM is enabled and active
> +: vtpm-enabled-active ( state -- ok? )
> +    TPM_ST_ENABLED TPM_ST_ACTIVE OR AND TPM_ST_ENABLED TPM_ST_ACTIVE OR =
> +;

Use the stack :-)

TPM_ST_ENABLED TPM_ST_ACTIVE OR dup rot AND = 

> +
> +\ display the menu for manipulating TPM state; we get
> +\ the state of the TPM in form of flags from the C-driver
> +\
> +\ Some info about the TPM's states:
> +\ - enabling/disabling can be done at any time
> +\ - activating/deactivating the TPM requires an enabled TPM
> +\ - clearing ownership can be done even if the TPM is deactivated and disabled
> +\ - allowing/preventing owner installation requires an enabled and active TPM
> +\
> +: vtpm-menu-show ( -- )
> +    tpm-is-working IF
> +        ." The TPM is "
> +
> +        tpm-get-state                   ( -- flags )
> +
> +        dup TPM_ST_ENABLED AND TPM_ST_ENABLED <> IF
> +            ." disabled"
> +        ELSE
> +            ." enabled"
> +        THEN
> +
> +        dup TPM_ST_ACTIVE AND TPM_ST_ACTIVE <> IF
> +            ." , deactivated"
> +        ELSE
> +            ." , active"
> +        THEN
> +
> +        dup TPM_ST_OWNED AND TPM_ST_OWNED <> IF
> +            ." , does not have an owner "
> +            dup TPM_ST_OWNERINSTALL AND TPM_ST_OWNERINSTALL <> IF
> +                ." and an owner cannot be installed."
> +            ELSE
> +                ." but one can be installed."
> +            THEN
> +        ELSE
> +            ." , and has an owner."
> +        THEN
> +
> +        cr cr
> +        ." To configure the TPM, choose one of the following actions:"
> +        cr cr
> +
> +        dup TPM_ST_ENABLED AND TPM_ST_ENABLED <> IF
> +            ." e. Enable the TPM" cr
> +        ELSE
> +            ." d. Disable the TPM" cr
> +
> +            dup TPM_ST_ACTIVE AND TPM_ST_ACTIVE <> IF
> +                ." a. Activate the TPM" cr
> +            ELSE
> +                ." v. Deactivate the TPM" cr
> +
> +                dup TPM_ST_OWNERINSTALL AND TPM_ST_OWNERINSTALL <> IF
> +                    ." s. Allow installation of an owner" cr
> +                ELSE
> +                    ." p. Prevent installation of an owner" cr
> +                THEN
> +            THEN
> +
> +        THEN
> +
> +        dup TPM_ST_OWNED AND TPM_ST_OWNED = IF
> +           ." c. Clear ownership" cr
> +        THEN
> +
> +        cr
> +        \ If the TPM is either disabled or deactivated, show message
> +        vtpm-enabled-active 0= IF
> +            ." Note: To be able to use all features of the TPM, it must be enabled and active."
> +            cr cr
> +        THEN
> +
> +    ELSE
> +       ." The TPM is not working correctly." cr
> +    THEN
> +
> +    ." Press escape to continue boot." cr cr
> +;
> +
> +\ wait for keyboard input
> +: vtpm-menu-key-get
> +    0 0 DO
> +       key? IF
> +           key
> +           UNLOOP EXIT
> +       THEN
> +       100 MS
> +    LOOP
> +    1b
> +;
> +
> +\ Send a code to the C-driver to change the state of the vTPM
> +: vtpm-process-opcode ( verbose? opcode -- )
> +    tpm-process-opcode
> +    vtpm-debug? IF
> +        ." VTPM: Error code from tpm-process-opcode: " . cr
> +    ELSE
> +        drop
> +    THEN
> +;
> +
> +
> +1  CONSTANT PPI_OP_ENABLE
> +2  CONSTANT PPI_OP_DISABLE
> +3  CONSTANT PPI_OP_ACTIVATE
> +4  CONSTANT PPI_OP_DEACTIVATE
> +5  CONSTANT PPI_OP_CLEAR
> +8  CONSTANT PPI_OP_SETOWNERINSTALL_TRUE
> +9  CONSTANT PPI_OP_SETOWNERINSTALL_FALSE
> +
> +\ if there's a vtpm available, display the menu
> +\ wait for keyboard input and have the C-driver
> +\ process opcodes we derive from the chosen menu
> +\ item
> +: vtpm-menu
> +    vtpm-available? IF
> +        tpm-is-working IF
> +            \ vtpm-empty-keybuffer
> +            vtpm-menu-show
> +            0 0  DO
> +                CASE vtpm-menu-key-get
> +                [char] e OF  tpm-get-state                                  ( -- flags )
> +                             TPM_ST_ENABLED AND TPM_ST_ENABLED <> IF
> +                                 0 PPI_OP_ENABLE     vtpm-process-opcode
> +                                 vtpm-menu-show
> +                             THEN
> +                         ENDOF
> +                [char] d OF  tpm-get-state                                  ( -- flags )
> +                             TPM_ST_ENABLED AND TPM_ST_ENABLED = IF
> +                                 0 PPI_OP_DISABLE    vtpm-process-opcode
> +                                 vtpm-menu-show
> +                             THEN
> +                         ENDOF
> +                [char] a OF  tpm-get-state                                  ( -- flags )
> +                             TPM_ST_ACTIVE AND TPM_ST_ACTIVE <> IF
> +                                 0 PPI_OP_ACTIVATE   vtpm-process-opcode
> +                                 tpm-get-state
> +                                 TPM_ST_ACTIVE AND TPM_ST_ACTIVE = IF
> +                                     ." The system needs to reboot to activate the TPM."
> +                                     100 MS \ so the message shows
> +                                     reset-all
> +                                 THEN
> +                             THEN
> +                         ENDOF
> +                [char] v OF  tpm-get-state                                  ( -- flags )
> +                             TPM_ST_ACTIVE AND TPM_ST_ACTIVE = IF
> +                                 0 PPI_OP_DEACTIVATE vtpm-process-opcode
> +                                 vtpm-menu-show
> +                             THEN
> +                         ENDOF
> +                [char] c OF  tpm-get-state                                  ( -- flags )
> +                             TPM_ST_OWNED AND TPM_ST_OWNED = IF
> +                                 0 PPI_OP_CLEAR      vtpm-process-opcode
> +                                 vtpm-menu-show
> +                             THEN
> +                         ENDOF
> +                [char] s OF  tpm-get-state
> +                             \ The TPM must be enabled and active to allow
> +                             \ owner installation mods
> +                             dup vtpm-enabled-active IF
> +                                 TPM_ST_OWNERINSTALL AND TPM_ST_OWNERINSTALL <> IF
> +                                     0 PPI_OP_SETOWNERINSTALL_TRUE  vtpm-process-opcode
> +                                     vtpm-menu-show
> +                                 THEN
> +                             THEN
> +                         ENDOF
> +                [char] p OF  tpm-get-state
> +                             \ The TPM must be enabled and active to allow
> +                             \ owner installation mods
> +                             dup vtpm-enabled-active IF
> +                                 TPM_ST_OWNERINSTALL AND TPM_ST_OWNERINSTALL = IF
> +                                     0 PPI_OP_SETOWNERINSTALL_FALSE vtpm-process-opcode
> +                                     vtpm-menu-show
> +                                 THEN
> +                             THEN
> +                         ENDOF
> +                1b OF UNLOOP EXIT ENDOF
> +                ENDCASE
> +            LOOP
> +        THEN
> +    THEN
> +;
> -- 
> 1.9.3

Regards
Nikunj



More information about the SLOF mailing list