From nobody Thu Mar 28 09:31:13 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 78.46.105.101 is neither permitted nor denied by domain of seabios.org) client-ip=78.46.105.101; envelope-from=seabios-bounces@seabios.org; helo=coreboot.org; Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 78.46.105.101 is neither permitted nor denied by domain of seabios.org) smtp.mailfrom=seabios-bounces@seabios.org Return-Path: Received: from coreboot.org (coreboot.org [78.46.105.101]) by mx.zohomail.com with SMTPS id 1547494144165821.5311569704139; Mon, 14 Jan 2019 11:29:04 -0800 (PST) Received: from [172.30.0.99] (mailu_mailman-core_1.mailu_default [172.30.0.99]) by coreboot.org (Postfix) with ESMTP id 5921E10A1844; Mon, 14 Jan 2019 19:29:01 +0000 (UTC) Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by coreboot.org (Postfix) with ESMTP id 2A8B310A1841 for ; Mon, 14 Jan 2019 19:28:58 +0000 (UTC) Received: from pps.filterd (m0098404.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id x0EJOOUv021161 for ; Mon, 14 Jan 2019 14:28:56 -0500 Received: from e11.ny.us.ibm.com (e11.ny.us.ibm.com [129.33.205.201]) by mx0a-001b2d01.pphosted.com with ESMTP id 2q0xjjw598-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 14 Jan 2019 14:28:56 -0500 Received: from localhost by e11.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 14 Jan 2019 19:28:55 -0000 Received: from b01cxnp22036.gho.pok.ibm.com (9.57.198.26) by e11.ny.us.ibm.com (146.89.104.198) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Mon, 14 Jan 2019 19:28:52 -0000 Received: from b01ledav003.gho.pok.ibm.com (b01ledav003.gho.pok.ibm.com [9.57.199.108]) by b01cxnp22036.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x0EJSpLL10289162 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 14 Jan 2019 19:28:51 GMT Received: from b01ledav003.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 16252B2066; Mon, 14 Jan 2019 19:28:51 +0000 (GMT) Received: from b01ledav003.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id F0604B205F; Mon, 14 Jan 2019 19:28:50 +0000 (GMT) Received: from sbct-3.pok.ibm.com (unknown [9.47.158.153]) by b01ledav003.gho.pok.ibm.com (Postfix) with ESMTP; Mon, 14 Jan 2019 19:28:50 +0000 (GMT) From: Stefan Berger To: seabios@seabios.org, kevin@koconnor.net Date: Mon, 14 Jan 2019 14:28:48 -0500 X-Mailer: git-send-email 2.17.2 X-TM-AS-GCONF: 00 x-cbid: 19011419-2213-0000-0000-0000033D4BB8 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00010405; HX=3.00000242; KW=3.00000007; PH=3.00000004; SC=3.00000274; SDB=6.01146475; UDB=6.00597121; IPR=6.00926761; MB=3.00025124; MTD=3.00000008; XFM=3.00000015; UTC=2019-01-14 19:28:53 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19011419-2214-0000-0000-00005CF8827A Message-Id: <20190114192848.1993980-1-stefanb@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-01-14_10:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1901140150 X-Spam-Level: * Message-ID-Hash: UNVQVONCZ77WJGDM3AKIL34P37PSG32R X-Message-ID-Hash: UNVQVONCZ77WJGDM3AKIL34P37PSG32R X-MailFrom: stefanb@linux.vnet.ibm.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: Stefan Berger X-Mailman-Version: 3.2.0 Precedence: list Subject: [SeaBIOS] [PATCH] tcgbios: Implement TPM 2.0 menu item to activate and deactivate PCR banks List-Id: SeaBIOS mailing list Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Spamd-Bar: / Authentication-Results: coreboot.org Content-Type: text/plain; charset="utf-8" Implement a TPM 2.0 menu item that allows a user to toggle the activation of PCR banks of the TPM 2.0. After successful activation we shut down the TPM 2.0 and reset the machine. Signed-off-by: Stefan Berger --- src/std/tcg.h | 18 ++++ src/tcgbios.c | 235 +++++++++++++++++++++++++++++++++++++++++++++++++- src/util.h | 2 + 3 files changed, 253 insertions(+), 2 deletions(-) diff --git a/src/std/tcg.h b/src/std/tcg.h index 09a92d8..eb9e67d 100644 --- a/src/std/tcg.h +++ b/src/std/tcg.h @@ -336,6 +336,12 @@ struct tpm_res_sha1complete { #define TPM2_ALG_SHA512 0x000d #define TPM2_ALG_SM3_256 0x0012 =20 +#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) + /* TPM 2 command tags */ #define TPM2_ST_NO_SESSIONS 0x8001 #define TPM2_ST_SESSIONS 0x8002 @@ -345,8 +351,10 @@ struct tpm_res_sha1complete { #define TPM2_CC_Clear 0x126 #define TPM2_CC_ClearControl 0x127 #define TPM2_CC_HierarchyChangeAuth 0x129 +#define TPM2_CC_PCR_Allocate 0x12b #define TPM2_CC_SelfTest 0x143 #define TPM2_CC_Startup 0x144 +#define TPM2_CC_Shutdown 0x145 #define TPM2_CC_StirRandom 0x146 #define TPM2_CC_GetCapability 0x17a #define TPM2_CC_GetRandom 0x17b @@ -442,6 +450,15 @@ struct tpm2_res_getcapability { u8 data[0]; /* capability dependent data */ } PACKED; =20 +struct tpm2_req_pcr_allocate { + struct tpm_req_header hdr; + u32 authhandle; + u32 authblocksize; + struct tpm2_authblock authblock; + u32 count; + u8 tpms_pcr_selections[4]; +} PACKED; + struct tpms_pcr_selection { u16 hashAlg; u8 sizeOfSelect; @@ -550,5 +567,6 @@ struct pcctes_romex #define TPM_PPI_OP_CLEAR 5 #define TPM_PPI_OP_SET_OWNERINSTALL_TRUE 8 #define TPM_PPI_OP_SET_OWNERINSTALL_FALSE 9 +#define TPM_PPI_OP_SET_PCR_BANKS 23 =20 #endif // tcg.h diff --git a/src/tcgbios.c b/src/tcgbios.c index 24846d3..ae0020e 100644 --- a/src/tcgbios.c +++ b/src/tcgbios.c @@ -180,6 +180,60 @@ tpm20_get_hash_buffersize(u16 hashAlg) } } =20 +static u8 +tpm20_hashalg_to_flag(u16 hashAlg) +{ + switch (hashAlg) { + case TPM2_ALG_SHA1: + return TPM2_ALG_SHA1_FLAG; + case TPM2_ALG_SHA256: + return TPM2_ALG_SHA256_FLAG; + case TPM2_ALG_SHA384: + return TPM2_ALG_SHA384_FLAG; + case TPM2_ALG_SHA512: + return TPM2_ALG_SHA512_FLAG; + case TPM2_ALG_SM3_256: + return TPM2_ALG_SM3_256_FLAG; + default: + return 0; + } +} + +static u16 +tpm20_hashalg_flag_to_hashalg(u8 hashalg_flag) +{ + switch (hashalg_flag) { + case TPM2_ALG_SHA1_FLAG: + return TPM2_ALG_SHA1; + case TPM2_ALG_SHA256_FLAG: + return TPM2_ALG_SHA256; + case TPM2_ALG_SHA384_FLAG: + return TPM2_ALG_SHA384; + case TPM2_ALG_SHA512_FLAG: + return TPM2_ALG_SHA512; + case TPM2_ALG_SM3_256_FLAG: + return TPM2_ALG_SM3_256; + default: + return 0; + } +} + +static const char * +tpm20_hashalg_flag_to_name(u8 hashalg_flag) +{ + switch (hashalg_flag) { + case TPM2_ALG_SHA1_FLAG: + return "SHA1"; + case TPM2_ALG_SHA256_FLAG: + return "SHA256"; + case TPM2_ALG_SHA384_FLAG: + return "SHA384"; + case TPM2_ALG_SHA512_FLAG: + return "SHA512"; + } + return NULL; +} + // Add an entry at the start of the log describing digest formats static int tpm20_write_EfiSpecIdEventStruct(void) @@ -432,6 +486,104 @@ tpm20_get_pcrbanks(void) return ret; } =20 +static int +tpm20_get_suppt_pcrbanks(u8 *suppt_pcrbanks, u8 *active_pcrbanks) +{ + *suppt_pcrbanks =3D 0; + *active_pcrbanks =3D 0; + + if (!tpm20_pcr_selection) + return -1; + + struct tpms_pcr_selection *sel =3D tpm20_pcr_selection->selections; + void *end =3D (void*)tpm20_pcr_selection + tpm20_pcr_selection_size; + + while (1) { + u8 sizeOfSelect =3D sel->sizeOfSelect; + void *nsel =3D (void*)sel + sizeof(*sel) + sizeOfSelect; + if (nsel > end) + return 0; + + u16 hashalg =3D be16_to_cpu(sel->hashAlg); + u8 hashalg_flag =3D tpm20_hashalg_to_flag(hashalg); + + *suppt_pcrbanks |=3D hashalg_flag; + + unsigned i; + for (i =3D 0; i < sizeOfSelect; i++) { + if (sel->pcrSelect[i]) { + *active_pcrbanks |=3D hashalg_flag; + break; + } + } + + sel =3D nsel; + } +} + +static int +tpm20_set_pcrbanks(u32 active_banks) +{ + struct tpm2_req_pcr_allocate trpa =3D { + .hdr.tag =3D cpu_to_be16(TPM2_ST_SESSIONS), + .hdr.ordinal =3D cpu_to_be32(TPM2_CC_PCR_Allocate), + .authhandle =3D cpu_to_be32(TPM2_RH_PLATFORM), + .authblocksize =3D cpu_to_be32(sizeof(trpa.authblock)), + .authblock =3D { + .handle =3D cpu_to_be32(TPM2_RS_PW), + .noncesize =3D cpu_to_be16(0), + .contsession =3D TPM2_YES, + .pwdsize =3D cpu_to_be16(0), + }, + }; + struct tpms_pcr_selection3 { + u16 hashAlg; + u8 sizeOfSelect; + u8 pcrSelect[3]; + } tps[ARRAY_SIZE(trpa.tpms_pcr_selections)]; + int i =3D 0; + u8 hashalg_flag =3D TPM2_ALG_SHA1_FLAG; + u8 dontcare, suppt_banks; + + tpm20_get_suppt_pcrbanks(&suppt_banks, &dontcare); + + while (hashalg_flag) { + if ((hashalg_flag & suppt_banks)) { + u16 hashalg =3D tpm20_hashalg_flag_to_hashalg(hashalg_flag); + + if (hashalg) { + u8 mask =3D 0; + tps[i].hashAlg =3D cpu_to_be16(hashalg); + tps[i].sizeOfSelect =3D 3; + + if (active_banks & hashalg_flag) + mask =3D 0xff; + + tps[i].pcrSelect[0] =3D mask; + tps[i].pcrSelect[1] =3D mask; + tps[i].pcrSelect[2] =3D mask; + i++; + } + } + hashalg_flag <<=3D 1; + } + + trpa.count =3D cpu_to_be32(i); + memcpy(trpa.tpms_pcr_selections, tps, i * sizeof(tps[0])); + trpa.hdr.totlen =3D cpu_to_be32(offsetof(struct tpm2_req_pcr_allocate, + tpms_pcr_selections) + + i * sizeof(tps[0])); + + struct tpm_rsp_header rsp; + u32 resp_length =3D sizeof(rsp); + + int ret =3D tpmhw_transmit(0, &trpa.hdr, &rsp, &resp_length, + TPM_DURATION_TYPE_SHORT); + ret =3D ret ? -1 : be32_to_cpu(rsp.errcode); + + return ret; +} + static int tpm12_get_capability(u32 cap, u32 subcap, struct tpm_rsp_header *rsp, u32 = rsize) { @@ -1752,7 +1904,7 @@ tpm20_clear(void) } =20 static int -tpm20_process_cfg(tpm_ppi_code msgCode, int verbose) +tpm20_process_cfg(tpm_ppi_code msgCode, u32 pprm, int verbose) { int ret =3D 0; =20 @@ -1765,6 +1917,13 @@ tpm20_process_cfg(tpm_ppi_code msgCode, int verbose) if (!ret) ret =3D tpm20_clear(); break; + + case TPM_PPI_OP_SET_PCR_BANKS: + ret =3D tpm20_set_pcrbanks(pprm); + if (!ret) + ret =3D tpm_simple_cmd(0, TPM2_CC_Shutdown, + 2, TPM2_SU_CLEAR, TPM_DURATION_TYPE_S= HORT); + break; } =20 if (ret) @@ -1947,14 +2106,77 @@ tpm12_menu(void) } } =20 +static int +tpm20_menu_change_active_pcrbanks(u8 *activate_banks) +{ + u8 active_banks, suppt_banks; + + tpm20_get_suppt_pcrbanks(&suppt_banks, &active_banks); + + *activate_banks =3D active_banks; + + while (1) { + u8 hashalg_flag =3D TPM2_ALG_SHA1_FLAG; + u8 i =3D 0; + + printf("\nToggle active PCR banks by pressing number key\n\n"); + + while (hashalg_flag) { + u8 flag =3D hashalg_flag & suppt_banks; + const char *hashname =3D tpm20_hashalg_flag_to_name(flag); + + i++; + if (hashname) { + printf(" %d: %s", i, hashname); + if (*activate_banks & hashalg_flag) + printf(" (enabled)"); + printf("\n"); + } + + hashalg_flag <<=3D 1; + } + printf("\n" + "ESC: return to previous menu without changing active PCR b= anks\n" + "A : activate selection\n"); + u8 flagnum; + int show =3D 0; + while (!show) { + int scancode =3D get_keystroke(1000); + + switch (scancode) { + case ~0: + continue; + case 1: /* ESC */ + printf("\n"); + return -1; + case 2 ... 6: /* keys 1 .. 5 */ + flagnum =3D scancode - 1; + if (flagnum > i) + continue; + if (suppt_banks & (1 << (flagnum - 1))) { + *activate_banks ^=3D 1 << (flagnum - 1); + show =3D 1; + } + break; + case SCANCODE_A: + return 0; + } + } + } +} + static void tpm20_menu(void) { int scan_code; tpm_ppi_code msgCode; + u32 pprm; + u8 active_banks; + int do_reset =3D 0; =20 for (;;) { printf("1. Clear TPM\n"); + printf("2. Change active PCR banks\n"); =20 printf("\nIf no change is desired or if this menu was reached by " "mistake, press ESC to\n" @@ -1973,11 +2195,20 @@ tpm20_menu(void) case 2: msgCode =3D TPM_PPI_OP_CLEAR; break; + case 3: + if (tpm20_menu_change_active_pcrbanks(&active_banks) < 0) + continue; + msgCode =3D TPM_PPI_OP_SET_PCR_BANKS; + pprm =3D active_banks; + do_reset =3D 1; + break; default: continue; } =20 - tpm20_process_cfg(msgCode, 0); + tpm20_process_cfg(msgCode, pprm, 0); + if (do_reset) + reset(); } } =20 diff --git a/src/util.h b/src/util.h index 6dd080f..b7169dd 100644 --- a/src/util.h +++ b/src/util.h @@ -38,6 +38,8 @@ struct usbdevice_s; int bootprio_find_usb(struct usbdevice_s *usbdev, int lun); int get_keystroke(int msec); =20 +#define SCANCODE_A 0x1e + // bootsplash.c void enable_vga_console(void); void enable_bootsplash(void); --=20 2.17.2 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org