From nobody Sat May 10 07:22:00 2025 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 80.81.252.135 is neither permitted nor denied by domain of seabios.org) client-ip=80.81.252.135; envelope-from=seabios-bounces@seabios.org; helo=mail.coreboot.org; Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 80.81.252.135 is neither permitted nor denied by domain of seabios.org) smtp.mailfrom=seabios-bounces@seabios.org Return-Path: Received: from mail.coreboot.org (mail.coreboot.org [80.81.252.135]) by mx.zohomail.com with SMTPS id 1513188084958906.5299223523392; Wed, 13 Dec 2017 10:01:24 -0800 (PST) Received: from [127.0.0.1] (helo=ra.coreboot.org) by mail.coreboot.org with esmtp (Exim 4.86_2) (envelope-from ) id 1ePBL3-0008FM-Nk; Wed, 13 Dec 2017 19:01:01 +0100 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]) by mail.coreboot.org with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.86_2) (envelope-from ) id 1ePBKm-0005Bl-G1 for seabios@seabios.org; Wed, 13 Dec 2017 19:00:59 +0100 Received: from pps.filterd (m0098399.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id vBDHxZ2x139621 for ; Wed, 13 Dec 2017 13:00:45 -0500 Received: from e17.ny.us.ibm.com (e17.ny.us.ibm.com [129.33.205.207]) by mx0a-001b2d01.pphosted.com with ESMTP id 2eu7sb43w9-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Wed, 13 Dec 2017 13:00:44 -0500 Received: from localhost by e17.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 13 Dec 2017 13:00:43 -0500 Received: from b01cxnp23032.gho.pok.ibm.com (9.57.198.27) by e17.ny.us.ibm.com (146.89.104.204) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 13 Dec 2017 13:00:41 -0500 Received: from b01ledav003.gho.pok.ibm.com (b01ledav003.gho.pok.ibm.com [9.57.199.108]) by b01cxnp23032.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id vBDI0eP732833744; Wed, 13 Dec 2017 18:00:40 GMT Received: from b01ledav003.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9A72BB2050; Wed, 13 Dec 2017 12:57:46 -0500 (EST) Received: from sbct-3.watson.ibm.com (unknown [9.47.158.153]) by b01ledav003.gho.pok.ibm.com (Postfix) with ESMTP id 8B701B2052; Wed, 13 Dec 2017 12:57:46 -0500 (EST) From: Stefan Berger To: seabios@seabios.org Date: Wed, 13 Dec 2017 13:00:31 -0500 X-Mailer: git-send-email 2.5.5 In-Reply-To: <1513188032-1373-1-git-send-email-stefanb@linux.vnet.ibm.com> References: <1513188032-1373-1-git-send-email-stefanb@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 17121318-0040-0000-0000-000003D0C4B8 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00008200; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000244; SDB=6.00959713; UDB=6.00485388; IPR=6.00739733; BA=6.00005740; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00018523; XFM=3.00000015; UTC=2017-12-13 18:00:42 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17121318-0041-0000-0000-000007C60774 Message-Id: <1513188032-1373-2-git-send-email-stefanb@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-12-13_09:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1712130253 X-Spam-Score: -2.5 (--) Subject: [SeaBIOS] [PATCH 1/2] tcbios: Add menu item to create an EK for TPM 2 X-BeenThere: seabios@seabios.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SeaBIOS mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: seabios-bounces@seabios.org Sender: "SeaBIOS" X-Duff: Orig. Duff, Duff Lite, Duff Dry, Duff Dark, Raspberry Duff, Lady Duff, Red Duff, Tartar Control Duff X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Add a menu item to create an EK with the handle 0x81010001 per the Infrastructure Work Group specification TCG TPM v2.0 Provisioning Guidance; Version 1.0, Rev 1.0, March 15, 2017 https://trustedcomputinggroup.org/tcg-tpm-v2-0-provisioning-guidance/ For the creation flags to set on the EK we follow the spec TCG EK Credential Profile For TPM Family 2.0; Level 0; Rev 14, Nov. 4 2014 https://trustedcomputinggroup.org/tcg-ek-credential-profile-tpm-family-2-0/ Signed-off-by: Stefan Berger --- src/std/tcg.h | 62 ++++++++++++++ src/tcgbios.c | 270 ++++++++++++++++++++++++++++++++++++++++++++++++++++++= ---- 2 files changed, 316 insertions(+), 16 deletions(-) diff --git a/src/std/tcg.h b/src/std/tcg.h index 09a92d8..beecd1f 100644 --- a/src/std/tcg.h +++ b/src/std/tcg.h @@ -330,21 +330,27 @@ struct tpm_res_sha1complete { #define TPM2_RH_ENDORSEMENT 0x4000000b #define TPM2_RH_PLATFORM 0x4000000c =20 +#define TPM2_ALG_RSA 0x0001 #define TPM2_ALG_SHA1 0x0004 +#define TPM2_ALG_AES 0x0006 #define TPM2_ALG_SHA256 0x000b #define TPM2_ALG_SHA384 0x000c #define TPM2_ALG_SHA512 0x000d +#define TPM2_ALG_NULL 0x0010 #define TPM2_ALG_SM3_256 0x0012 +#define TPM2_ALG_CFB 0x0043 =20 /* TPM 2 command tags */ #define TPM2_ST_NO_SESSIONS 0x8001 #define TPM2_ST_SESSIONS 0x8002 =20 /* TPM 2 commands */ +#define TPM2_CC_EvictControl 0x120 #define TPM2_CC_HierarchyControl 0x121 #define TPM2_CC_Clear 0x126 #define TPM2_CC_ClearControl 0x127 #define TPM2_CC_HierarchyChangeAuth 0x129 +#define TPM2_CC_CreatePrimary 0x131 #define TPM2_CC_SelfTest 0x143 #define TPM2_CC_Startup 0x144 #define TPM2_CC_StirRandom 0x146 @@ -356,8 +362,25 @@ struct tpm_res_sha1complete { #define TPM2_RC_INITIALIZE 0x100 =20 /* TPM 2 Capabilities */ +#define TPM2_CAP_HANDLES 0x00000001 #define TPM2_CAP_PCRS 0x00000005 =20 +/* TPM 2 Handle types */ +#define TPM2_HT_PERSISTENT 0x81000000 + +/* TPM 2 Object flags */ +#define TPM2_OBJECT_FIXEDTPM (1 << 1) +#define TPM2_OBJECT_STCLEAR (1 << 2) +#define TPM2_OBJECT_FIXEDPARENT (1 << 4) +#define TPM2_OBJECT_SENSITIVEDATAORIGIN (1 << 5) +#define TPM2_OBJECT_USERWITHAUTH (1 << 6) +#define TPM2_OBJECT_ADMINWITHPOLICY (1 << 7) +#define TPM2_OBJECT_NODA (1 << 10) +#define TPM2_OBJECT_ENCRYPTEDDUPLICATION (1 << 11) +#define TPM2_OBJECT_RESTRICTED (1 << 16) +#define TPM2_OBJECT_DECRYPT (1 << 17) +#define TPM2_OBJECT_SIGN (1 << 18) + /* TPM 2 data structures */ =20 struct tpm2_req_stirrandom { @@ -453,6 +476,39 @@ struct tpml_pcr_selection { struct tpms_pcr_selection selections[0]; } PACKED; =20 +struct tpml_handle { + u32 count; + u32 handle[0]; +} PACKED; + +struct tpm2_req_createprimary_p1 { + struct tpm_req_header hdr; + u32 authhandle; + u32 authblocksize; + struct tpm2_authblock authblock; + u16 sensitive_len; + u8 sensitive[4]; /* set to 0 */ + /* + TPM2B_PUBLIC inPublic; + TPM2B_DATA outsideInfo + TPML_PCR_SELECTION creationPCR; + */ +} PACKED; + +struct tpm2_res_createprimary { + struct tpm_rsp_header hdr; + u32 keyhandle; + /* lots more data */ +} PACKED; + +struct tpm20_evictcontrol { + struct tpm_req_header hdr; + u32 authhandle; + u32 keyhandle; + u32 authblocksize; + struct tpm2_authblock authblock; + u32 persistentHandle; +} PACKED; =20 /**************************************************************** * ACPI TCPA table interface @@ -542,6 +598,9 @@ struct pcctes_romex #define TPM_STATE_OWNED 4 #define TPM_STATE_OWNERINSTALL 8 =20 +#define TPM2_STATE_CREATE_EK 1 +#define TPM2_STATE_CREATE_PSK 2 + #define TPM_PPI_OP_NOOP 0 #define TPM_PPI_OP_ENABLE 1 #define TPM_PPI_OP_DISABLE 2 @@ -551,4 +610,7 @@ struct pcctes_romex #define TPM_PPI_OP_SET_OWNERINSTALL_TRUE 8 #define TPM_PPI_OP_SET_OWNERINSTALL_FALSE 9 =20 +/* additional operations */ +#define TPM_PPI_EXT_OP_CREATE_EK (0xe0 + 0) + #endif // tcg.h diff --git a/src/tcgbios.c b/src/tcgbios.c index 40b3028..e5b5678 100644 --- a/src/tcgbios.c +++ b/src/tcgbios.c @@ -1752,9 +1752,157 @@ tpm20_clear(void) } =20 static int +tpm20_createprimary(u32 authhandle, + void *pubdata, size_t pubdata_len, + u32 *keyhandle) +{ + u8 buffer[128]; + struct tpm2_req_createprimary_p1 trcp =3D { + .hdr.tag =3D cpu_to_be16(TPM2_ST_SESSIONS), + .hdr.totlen =3D 0, + .hdr.ordinal =3D cpu_to_be32(TPM2_CC_CreatePrimary), + .authhandle =3D cpu_to_be32(authhandle), + .authblocksize =3D cpu_to_be32(sizeof(trcp.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), + }, + .sensitive_len =3D cpu_to_be16(sizeof(trcp.sensitive)), + .sensitive =3D {0, }, + }; + u16 outsideInfoLen =3D cpu_to_be16(0); + struct tpml_pcr_selection { + u32 count; + u16 hash; + } PACKED tps =3D { + .count =3D cpu_to_be32(0), + .hash =3D cpu_to_be16(0), + }; + + u32 off =3D sizeof(trcp); + memcpy(&buffer[off], pubdata, pubdata_len); + + off +=3D pubdata_len; + memcpy(&buffer[off], &outsideInfoLen, sizeof(outsideInfoLen)); + + off +=3D sizeof(outsideInfoLen); + memcpy(&buffer[off], &tps, sizeof(tps)); + + off +=3D sizeof(tps); + if (off > sizeof(buffer)) + warn_internalerror(); + /* complete header and copy */ + trcp.hdr.totlen =3D cpu_to_be32(off); + memcpy(buffer, &trcp, sizeof(trcp)); + + struct tpm2_res_createprimary rsp; + u32 resp_length =3D sizeof(rsp); + + int ret =3D tpmhw_transmit(0, (struct tpm_req_header *)buffer, + &rsp, &resp_length, + TPM_DURATION_TYPE_LONG); + dprintf(DEBUG_tcg, "TCGBIOS: ret=3D 0x%08x, resp_length =3D %d (%d), e= rrcode=3D0x%08x\n", + ret, resp_length, sizeof(rsp), rsp.hdr.errcode); + if (ret || rsp.hdr.errcode) + ret =3D -1; + + *keyhandle =3D be32_to_cpu(rsp.keyhandle); + + dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_CreateP= irmary =3D 0x%08x, keyhandle=3D0x%08x\n", + ret, *keyhandle); + + return ret; +} + +static int +tpm20_create_ek(int verbose, u32 *keyhandle) +{ + struct tpm2_tpmt_public { + u16 publen; + u16 alg_key; + u16 alg_hash; + u32 keyflags; + u16 authpolicylen; + u8 authpolicy[32]; + struct symkeydata { + u16 algorithm; + u16 keyBits; + u16 mode; + } symkeydata; + u16 scheme; + u16 keyBits; + u32 exponent; + } PACKED ttp =3D { + .publen =3D cpu_to_be16(sizeof(ttp)), + .alg_key =3D cpu_to_be16(TPM2_ALG_RSA), + .alg_hash =3D cpu_to_be16(TPM2_ALG_SHA256), + .keyflags =3D cpu_to_be32(TPM2_OBJECT_FIXEDTPM | + TPM2_OBJECT_FIXEDPARENT | + TPM2_OBJECT_SENSITIVEDATAORIGIN | + TPM2_OBJECT_ADMINWITHPOLICY | + TPM2_OBJECT_RESTRICTED | + TPM2_OBJECT_DECRYPT), + .authpolicylen =3D cpu_to_be16(sizeof(ttp.authpolicy)), + .authpolicy =3D { + 0x83, 0x71, 0x97, 0x67, 0x44, 0x84, 0xb3, 0xf8, + 0x1a, 0x90, 0xcc, 0x8d, 0x46, 0xa5, 0xd7, 0x24, + 0xfd, 0x52, 0xd7, 0x6e, 0x06, 0x52, 0x0b, 0x64, + 0xf2, 0xa1, 0xda, 0x1b, 0x33, 0x14, 0x69, 0xaa + }, + .symkeydata =3D { + .algorithm =3D cpu_to_be16(TPM2_ALG_AES), + .keyBits =3D cpu_to_be16(128), + .mode =3D cpu_to_be16(TPM2_ALG_CFB), + }, + .scheme =3D cpu_to_be16(TPM2_ALG_NULL), + .keyBits =3D cpu_to_be16(2048), + .exponent =3D cpu_to_be32(0), + }; + + return tpm20_createprimary(TPM2_RH_ENDORSEMENT, &ttp, sizeof(ttp), + keyhandle); +} + +static int +tpm20_evictcontrol(u32 authhandle, u32 keyhandle, + u32 persistentHandle) +{ + struct tpm20_evictcontrol te =3D { + .hdr.tag =3D cpu_to_be16(TPM2_ST_SESSIONS), + .hdr.totlen =3D cpu_to_be32(sizeof(te)), + .hdr.ordinal =3D cpu_to_be32(TPM2_CC_EvictControl), + .authhandle =3D cpu_to_be32(authhandle), + .keyhandle =3D cpu_to_be32(keyhandle), + .authblocksize =3D cpu_to_be32(sizeof(te.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), + }, + .persistentHandle =3D cpu_to_be32(persistentHandle), + }; + + struct tpm_rsp_header rsp; + u32 resp_length =3D sizeof(rsp); + int ret =3D tpmhw_transmit(0, &te.hdr, &rsp, &resp_length, + TPM_DURATION_TYPE_SHORT); + if (ret || resp_length !=3D sizeof(rsp) || rsp.errcode) + ret =3D -1; + + dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_EvictCo= ntrol =3D 0x%08x\n", + ret); + + return ret; +} + +static int tpm20_process_cfg(tpm_ppi_code msgCode, int verbose) { int ret =3D 0; + u32 keyhandle; =20 switch (msgCode) { case TPM_PPI_OP_NOOP: /* no-op */ @@ -1765,6 +1913,15 @@ tpm20_process_cfg(tpm_ppi_code msgCode, int verbose) if (!ret) ret =3D tpm20_clear(); break; + + case TPM_PPI_EXT_OP_CREATE_EK: + ret =3D tpm20_create_ek(verbose, &keyhandle); + if (ret) + break; + ret =3D tpm20_evictcontrol(TPM2_RH_OWNER, + keyhandle, + 0x81010001); + break; } =20 if (ret) @@ -1947,14 +2104,75 @@ tpm12_menu(void) } } =20 +static int +tpm20_get_tpm_state(void) +{ + int state =3D 0; + u8 buffer[256]; + struct tpm2_res_getcapability *trg =3D + (struct tpm2_res_getcapability *)&buffer; + u32 i, num_handles; + + int ret =3D tpm20_getcapability(TPM2_CAP_HANDLES, TPM2_HT_PERSISTENT, + (sizeof(buffer) - offsetof(struct tpm2_res_getcapability, data))= / 4, + &trg->hdr, sizeof(buffer)); + if (ret) + return ~0; + + struct tpml_handle *handles =3D (struct tpml_handle *)&trg->data; + int has_ek =3D 0; + + num_handles =3D be32_to_cpu(handles->count); + + for (i =3D 0; i < num_handles; i++) { + u32 h =3D be32_to_cpu(handles->handle[i]); + if (h >=3D 0x81010000 && h <=3D 0x8101ffff) + has_ek =3D 1; + } + + if (!has_ek) + state |=3D TPM2_STATE_CREATE_EK; + + return state; +} + +static void +tpm20_show_tpm_menu(int state, int next_scancodes[4]) +{ + int i =3D 0; + + printf("\nThe current state of the TPM is:\n"); + if (state & TPM2_STATE_CREATE_EK) + printf(" - does not have"); + else + printf(" - has"); + printf(" a persistent endorsement key.\n"); + + printf("\n1. Clear TPM\n"); + next_scancodes[i++] =3D 2; + + if (state & TPM2_STATE_CREATE_EK) { + printf("2. Create a persistent endorsement primary key\n"); + next_scancodes[i++] =3D 3; + } + next_scancodes[i++] =3D 0; +} + static void tpm20_menu(void) { - int scan_code; + int scan_code, next_scancodes[4]; tpm_ppi_code msgCode; + int state, i; + int waitkey; =20 for (;;) { - printf("1. Clear TPM\n"); + if ((state =3D tpm20_get_tpm_state()) !=3D ~0) { + tpm20_show_tpm_menu(state, next_scancodes); + } else { + printf("TPM is not working correctly.\n"); + return; + } =20 printf("\nIf no change is desired or if this menu was reached by " "mistake, press ESC to\n" @@ -1962,22 +2180,42 @@ tpm20_menu(void) =20 msgCode =3D TPM_PPI_OP_NOOP; =20 - while ((scan_code =3D get_keystroke(1000)) =3D=3D ~0) - ; + waitkey =3D 1; =20 - switch (scan_code) { - case 1: - // ESC - reset(); - break; - case 2: - msgCode =3D TPM_PPI_OP_CLEAR; - break; - default: - continue; - } + while (waitkey) { + while ((scan_code =3D get_keystroke(1000)) =3D=3D ~0) + ; + + switch (scan_code) { + case 1: + // ESC + reset(); + break; + case 2: + msgCode =3D TPM_PPI_OP_CLEAR; + break; + case 3: + msgCode =3D TPM_PPI_EXT_OP_CREATE_EK; + break; + default: + continue; + } =20 - tpm20_process_cfg(msgCode, 0); + /* + * Using the next_scancodes array, check whether the + * pressed key is currently a valid option. + */ + for (i =3D 0; i < sizeof(next_scancodes); i++) { + if (next_scancodes[i] =3D=3D 0) + break; + + if (next_scancodes[i] =3D=3D scan_code) { + tpm20_process_cfg(msgCode, 0); + waitkey =3D 0; + break; + } + } + } } } =20 --=20 2.5.5 _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org https://mail.coreboot.org/mailman/listinfo/seabios