From patchwork Wed Dec 11 20:27:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Berger X-Patchwork-Id: 1207904 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47Y7nk6Q6Zz9sR7 for ; Thu, 12 Dec 2019 07:29:30 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.vnet.ibm.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 47Y7nk599MzDqv1 for ; Thu, 12 Dec 2019 07:29:30 +1100 (AEDT) X-Original-To: slof@lists.ozlabs.org Delivered-To: slof@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=linux.vnet.ibm.com (client-ip=148.163.156.1; helo=mx0a-001b2d01.pphosted.com; envelope-from=stefanb@linux.vnet.ibm.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.vnet.ibm.com Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 47Y7ll6WMGzDqTh for ; Thu, 12 Dec 2019 07:27:44 +1100 (AEDT) Received: from pps.filterd (m0098409.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id xBBKGgaK006159; Wed, 11 Dec 2019 15:27:42 -0500 Received: from ppma05wdc.us.ibm.com (1b.90.2fa9.ip4.static.sl-reverse.com [169.47.144.27]) by mx0a-001b2d01.pphosted.com with ESMTP id 2wthkj76q7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 11 Dec 2019 15:27:41 -0500 Received: from pps.filterd (ppma05wdc.us.ibm.com [127.0.0.1]) by ppma05wdc.us.ibm.com (8.16.0.27/8.16.0.27) with SMTP id xBBKEtEd026499; Wed, 11 Dec 2019 20:27:40 GMT Received: from b01cxnp22033.gho.pok.ibm.com (b01cxnp22033.gho.pok.ibm.com [9.57.198.23]) by ppma05wdc.us.ibm.com with ESMTP id 2wtdq7b85j-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 11 Dec 2019 20:27:40 +0000 Received: from b01ledav003.gho.pok.ibm.com (b01ledav003.gho.pok.ibm.com [9.57.199.108]) by b01cxnp22033.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id xBBKReL751053024 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 11 Dec 2019 20:27:40 GMT Received: from b01ledav003.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2209CB2065; Wed, 11 Dec 2019 20:27:40 +0000 (GMT) Received: from b01ledav003.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 13728B2067; Wed, 11 Dec 2019 20:27:40 +0000 (GMT) Received: from newfield.pok.ibm.com (unknown [9.47.158.66]) by b01ledav003.gho.pok.ibm.com (Postfix) with ESMTP; Wed, 11 Dec 2019 20:27:40 +0000 (GMT) From: Stefan Berger To: slof@lists.ozlabs.org Date: Wed, 11 Dec 2019 15:27:05 -0500 Message-Id: <20191211202728.127996-11-stefanb@linux.vnet.ibm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191211202728.127996-1-stefanb@linux.vnet.ibm.com> References: <20191211202728.127996-1-stefanb@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.95, 18.0.572 definitions=2019-12-11_06:2019-12-11, 2019-12-11 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 malwarescore=0 clxscore=1015 priorityscore=1501 mlxscore=0 suspectscore=15 spamscore=0 mlxlogscore=999 bulkscore=0 phishscore=0 adultscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-1910280000 definitions=main-1912110168 Subject: [SLOF] [PATCH v4 10/33] tpm: Add support for a TPM menu to control the state of the TPM X-BeenThere: slof@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Patches for https://github.com/aik/SLOF" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kevin@koconnor.net MIME-Version: 1.0 Errors-To: slof-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "SLOF" 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 --- board-qemu/slof/OF.fs | 3 + board-qemu/slof/vtpm-sml.fs | 189 ++++++++++++++++++++++++++++++++++++ lib/libtpm/tcgbios.c | 30 +++++- lib/libtpm/tcgbios.h | 9 ++ lib/libtpm/tpm.code | 20 ++++ lib/libtpm/tpm.in | 2 + slof/fs/start-up.fs | 9 ++ 7 files changed, 261 insertions(+), 1 deletion(-) diff --git a/board-qemu/slof/OF.fs b/board-qemu/slof/OF.fs index 3e117ad..7bdd6ea 100644 --- a/board-qemu/slof/OF.fs +++ b/board-qemu/slof/OF.fs @@ -175,6 +175,9 @@ CREATE version-str 10 ALLOT version-str 8 + @ \ end over - dump-display-write " Press 's' to enter Open Firmware." dump-display-write + s" /ibm,vtpm" find-node IF + " Press 't' to enter TPM menu." terminal-write drop + THEN cr cr temp-ptr disp-size > IF temp-ptr disp-size MOD diff --git a/board-qemu/slof/vtpm-sml.fs b/board-qemu/slof/vtpm-sml.fs index b4a0fc1..60bd03c 100644 --- a/board-qemu/slof/vtpm-sml.fs +++ b/board-qemu/slof/vtpm-sml.fs @@ -120,6 +120,195 @@ log-base LOG-SIZE tpm-set-log-parameters THEN ; +\ +\ TPM menu +\ + +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 +: is-enabled-active? ( state -- ok? ) + 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 +\ +: tpm12-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 + is-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 +; + +\ Send a code to the C-driver to change the state of the vTPM +: process-opcode ( verbose? opcode -- ) + tpm-process-opcode + dup 0<> 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 +: vtpm12-menu + tpm-is-working IF + \ vtpm-empty-keybuffer + tpm12-menu-show + BEGIN + 0 \ loop end-flag ( 0 ) + key CASE + [char] e OF tpm-get-state ( 0 flags ) + TPM_ST_ENABLED AND TPM_ST_ENABLED <> IF + 0 PPI_OP_ENABLE process-opcode + tpm12-menu-show + THEN + ENDOF + [char] d OF tpm-get-state ( 0 flags ) + TPM_ST_ENABLED AND TPM_ST_ENABLED = IF + 0 PPI_OP_DISABLE process-opcode + tpm12-menu-show + THEN + ENDOF + [char] a OF tpm-get-state ( 0 flags ) + TPM_ST_ACTIVE AND TPM_ST_ACTIVE <> IF + 0 PPI_OP_ACTIVATE 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 ( 0 flags ) + TPM_ST_ACTIVE AND TPM_ST_ACTIVE = IF + 0 PPI_OP_DEACTIVATE process-opcode + tpm12-menu-show + THEN + ENDOF + [char] c OF tpm-get-state ( 0 flags ) + TPM_ST_OWNED AND TPM_ST_OWNED = IF + 0 PPI_OP_CLEAR process-opcode + tpm12-menu-show + THEN + ENDOF + [char] s OF tpm-get-state ( 0 flags ) + \ The TPM must be enabled and active to allow + \ owner installation mods + dup is-enabled-active? IF + TPM_ST_OWNERINSTALL AND TPM_ST_OWNERINSTALL <> IF + 0 PPI_OP_SETOWNERINSTALL_TRUE process-opcode + tpm12-menu-show + THEN + THEN + ENDOF + [char] p OF tpm-get-state ( 0 flags ) + \ The TPM must be enabled and active to allow + \ owner installation mods + dup is-enabled-active? IF + TPM_ST_OWNERINSTALL AND TPM_ST_OWNERINSTALL = IF + 0 PPI_OP_SETOWNERINSTALL_FALSE process-opcode + tpm12-menu-show + THEN + THEN + ENDOF + 1b OF ( 0 ) + drop 1 ( 1 ) + ENDOF + ENDCASE + UNTIL + THEN +; + +: vtpm-menu + vtpm12-menu +; + : open true ; : close ; diff --git a/lib/libtpm/tcgbios.c b/lib/libtpm/tcgbios.c index 8bd684c..3c9d2d7 100644 --- a/lib/libtpm/tcgbios.c +++ b/lib/libtpm/tcgbios.c @@ -206,7 +206,7 @@ static int tpm_extend(uint8_t *hash, uint32_t pcrindex) * Setup and Measurements ****************************************************************/ -static bool tpm_is_working(void) +bool tpm_is_working(void) { if (!tpm_state.tpm_probed) probe_tpm(); @@ -749,3 +749,31 @@ uint32_t tpm_process_opcode(uint8_t op, bool verbose) { return tpm12_process_cfg(op, verbose); } + +int tpm_get_state(void) +{ + int state = 0; + struct tpm_permanent_flags pf; + bool has_owner; + + if (tpm12_read_permanent_flags((char *)&pf, sizeof(pf)) || + tpm12_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; +} diff --git a/lib/libtpm/tcgbios.h b/lib/libtpm/tcgbios.h index b288778..956df43 100644 --- a/lib/libtpm/tcgbios.h +++ b/lib/libtpm/tcgbios.h @@ -34,4 +34,13 @@ uint32_t tpm_measure_bcv_mbr(uint32_t bootdrv, const uint8_t *addr, uint32_t tpm_add_event_separators(uint32_t start_pcr, uint32_t end_pcr); 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 1a5273f..3957028 100644 --- a/lib/libtpm/tpm.code +++ b/lib/libtpm/tpm.code @@ -132,3 +132,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 9fb30bb..0e942bc 100644 --- a/lib/libtpm/tpm.in +++ b/lib/libtpm/tpm.in @@ -24,3 +24,5 @@ cod(tpm-hash-all) cod(tpm-add-event-separators) cod(tpm-measure-bcv-mbr) 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 0715357..d72579b 100644 --- a/slof/fs/start-up.fs +++ b/slof/fs/start-up.fs @@ -55,6 +55,14 @@ nvramlog-write-string-cr ; +: (t-pressed) ( -- ) + s" /ibm,vtpm" find-node dup IF + s" vtpm-menu" rot $call-static + ELSE + drop + THEN +; + : (boot?) ( -- ) \ last step before we boot we give up physical presence on the TPM s" /ibm,vtpm" find-node dup IF @@ -107,6 +115,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