From patchwork Wed Dec 11 20:27:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Berger X-Patchwork-Id: 1207890 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 47Y7m31sfHz9sR8 for ; Thu, 12 Dec 2019 07:28:03 +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 47Y7m307fzzDqQl for ; Thu, 12 Dec 2019 07:28:03 +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.158.5; 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 (mx0b-001b2d01.pphosted.com [148.163.158.5]) (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 47Y7lk6ybJzDqKJ for ; Thu, 12 Dec 2019 07:27:43 +1100 (AEDT) Received: from pps.filterd (m0098421.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id xBBKGhGS004778; Wed, 11 Dec 2019 15:27:41 -0500 Received: from ppma03wdc.us.ibm.com (ba.79.3fa9.ip4.static.sl-reverse.com [169.63.121.186]) by mx0a-001b2d01.pphosted.com with ESMTP id 2wtdp4tuee-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 11 Dec 2019 15:27:40 -0500 Received: from pps.filterd (ppma03wdc.us.ibm.com [127.0.0.1]) by ppma03wdc.us.ibm.com (8.16.0.27/8.16.0.27) with SMTP id xBBKNQbO021863; 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 ppma03wdc.us.ibm.com with ESMTP id 2wr3q6r3x2-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 xBBKRebH51053020 (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 EC825B2065; Wed, 11 Dec 2019 20:27:39 +0000 (GMT) Received: from b01ledav003.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D455DB2064; Wed, 11 Dec 2019 20:27:39 +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:39 +0000 (GMT) From: Stefan Berger To: slof@lists.ozlabs.org Date: Wed, 11 Dec 2019 15:27:03 -0500 Message-Id: <20191211202728.127996-9-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 mlxlogscore=999 clxscore=1015 lowpriorityscore=0 malwarescore=0 spamscore=0 suspectscore=15 priorityscore=1501 mlxscore=0 phishscore=0 impostorscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-1910280000 definitions=main-1912110168 Subject: [SLOF] [PATCH v4 08/33] tpm: Implement measurements of the master boot record 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 adds support for measuring the boot block of the MBR and logging the measurement. It also puts an 'event' separator into the log that can then be seen in Linux's /sys/kernel/security/tpm0/ascii_bios_measurements. More low-level C functions are added for measuring and logging of disk related data, along with their FORTH-level counterparts. Logging follows the specifications found on the following page: http://www.trustedcomputinggroup.org/resources/pc_client_work_group_specific_implementation_specification_for_conventional_bios Signed-off-by: Stefan Berger --- board-qemu/slof/vtpm-sml.fs | 23 +++++++ lib/libtpm/tcgbios.c | 107 +++++++++++++++++++++++++++++++++ lib/libtpm/tcgbios.h | 6 ++ lib/libtpm/tpm.code | 23 +++++++ lib/libtpm/tpm.in | 2 + slof/fs/packages/disk-label.fs | 10 ++- 6 files changed, 170 insertions(+), 1 deletion(-) diff --git a/board-qemu/slof/vtpm-sml.fs b/board-qemu/slof/vtpm-sml.fs index 557aa62..b4a0fc1 100644 --- a/board-qemu/slof/vtpm-sml.fs +++ b/board-qemu/slof/vtpm-sml.fs @@ -88,6 +88,29 @@ log-base LOG-SIZE tpm-set-log-parameters \ internal API calls \ +: separator-event ( start-pcr end-pcr -- ) + tpm-add-event-separators ( errcode ) + dup 0<> IF + ." VTPM: Error code from tpm-add-event-separators: " . cr + ELSE + drop + THEN +; + +80 CONSTANT BCV_DEVICE_HDD + +: measure-hdd-mbr ( addr -- ) + 4 5 separator-event + 200 BCV_DEVICE_HDD ( addr length bootdrv ) + -rot ( bootdrv addr length ) + tpm-measure-bcv-mbr ( errcode ) + dup 0<> IF + ." VTPM: Error code from tpm-measure-hdd: " . cr + ELSE + drop + THEN +; + : unassert-physical-presence ( -- ) tpm-unassert-physical-presence ( errcode ) dup 0<> IF diff --git a/lib/libtpm/tcgbios.c b/lib/libtpm/tcgbios.c index d655ae1..401bb1c 100644 --- a/lib/libtpm/tcgbios.c +++ b/lib/libtpm/tcgbios.c @@ -421,6 +421,35 @@ static uint32_t hash_log_extend(struct pcpes *pcpes, return 0; } +/* + * Add a measurement to the log; + * + * Input parameters: + * @pcrindex : PCR to extend + * @event_type : type of event + * @info : pointer to info (i.e., string) to be added to the log as-is + * @info_length: length of the info + * @hashdata : pointer to data to be hashed + * @hashdata_length: length of the data + * + */ +static uint32_t tpm_add_measurement_to_log(uint32_t pcrindex, + uint32_t eventtype, + const char *info, + uint32_t infolen, + const uint8_t *hashdata, + uint32_t hashdatalen) +{ + struct pcpes pcpes; + + pcpes.pcrindex = pcrindex; + pcpes.eventtype = eventtype; + memset(&pcpes.digest, 0, sizeof(pcpes.digest)); + + return hash_log_extend(&pcpes, hashdata, hashdatalen, + info, infolen, true); +} + /* * tpm_hash_log_extend_event: Function for interfacing with the firmware API */ @@ -439,3 +468,81 @@ uint32_t tpm_hash_log_extend_event(struct pcpes *pcpes) &pcpes->event, pcpes->eventdatasize, event, event_length, true); } + +/* + * Add an EV_ACTION measurement to the list of measurements + */ +static uint32_t tpm_add_action(uint32_t pcrIndex, const char *string) +{ + uint32_t len = strlen(string); + + return tpm_add_measurement_to_log(pcrIndex, EV_ACTION, + string, len, (uint8_t *)string, len); +} + +/* + * Add event separators for a range of PCRs + */ +uint32_t tpm_add_event_separators(uint32_t start_pcr, uint32_t end_pcr) +{ + static const uint8_t evt_separator[] = {0xff,0xff,0xff,0xff}; + uint32_t rc = 0; + uint32_t pcrIndex; + + if (!tpm_is_working()) + return TCGBIOS_GENERAL_ERROR; + + if (start_pcr >= 24 || start_pcr > end_pcr) + return TCGBIOS_INVALID_INPUT_PARA; + + /* event separators need to be extended and logged for PCRs 0-7 */ + for (pcrIndex = start_pcr; pcrIndex <= end_pcr; pcrIndex++) { + rc = tpm_add_measurement_to_log(pcrIndex, EV_SEPARATOR, + NULL, 0, + evt_separator, + sizeof(evt_separator)); + if (rc) + break; + } + + return rc; +} + +uint32_t tpm_measure_bcv_mbr(uint32_t bootdrv, const uint8_t *addr, + uint32_t length) +{ + uint32_t rc; + const char *string; + + if (!tpm_is_working()) + return TCGBIOS_GENERAL_ERROR; + + if (length < 0x200) + return TCGBIOS_INVALID_INPUT_PARA; + + string = "Booting BCV device 00h (Floppy)"; + if (bootdrv == BCV_DEVICE_HDD) + string = "Booting BCV device 80h (HDD)"; + + rc = tpm_add_action(4, string); + if (rc) + return rc; + + /* + * equivalent to: dd if=/dev/hda ibs=1 count=440 | sha1sum + */ + string = "MBR"; + rc = tpm_add_measurement_to_log(4, EV_IPL, + string, strlen(string), + addr, 0x1b8); + if (rc) + return rc; + + /* + * equivalent to: dd if=/dev/hda ibs=1 count=72 skip=440 | sha1sum + */ + string = "MBR PARTITION TABLE"; + return tpm_add_measurement_to_log(5, EV_IPL_PARTITION_DATA, + string, strlen(string), + addr + 0x1b8, 0x48); +} diff --git a/lib/libtpm/tcgbios.h b/lib/libtpm/tcgbios.h index 592ae6d..3ccfca5 100644 --- a/lib/libtpm/tcgbios.h +++ b/lib/libtpm/tcgbios.h @@ -16,6 +16,9 @@ #include #include +#define BCV_DEVICE_FLOPPY 0x0 +#define BCV_DEVICE_HDD 0x80 + struct pcpes; uint32_t tpm_start(void); @@ -26,5 +29,8 @@ uint32_t tpm_get_logsize(void); uint32_t tpm_hash_log_extend_event(struct pcpes *pcpes); bool tpm_log_event(struct pcpes *pcpes); uint32_t tpm_hash_all(const void *data, uint32_t datalen, void *hashptr); +uint32_t tpm_measure_bcv_mbr(uint32_t bootdrv, const uint8_t *addr, + uint32_t length); +uint32_t tpm_add_event_separators(uint32_t start_pcr, uint32_t end_pcr); #endif /* TCGBIOS_H */ diff --git a/lib/libtpm/tpm.code b/lib/libtpm/tpm.code index eed9fbf..d4a1a72 100644 --- a/lib/libtpm/tpm.code +++ b/lib/libtpm/tpm.code @@ -97,3 +97,26 @@ PRIM(tpm_X2d_get_X2d_logsize) PUSH; TOS.n = tpm_get_logsize(); MIRP + +/**********************************************************************/ +/* Measure and log event separators */ +/* SLOF: tpm-add-event-separators ( start-pcr end-pcr -- errcode) */ +/* LIBTPM: errcode = tpm_add_event_separators(start_pcr, end_pcr) */ +/**********************************************************************/ +PRIM(tpm_X2d_add_X2d_event_X2d_separators) + int end_pcr = TOS.u; POP; + int start_pcr = TOS.u; + TOS.n = tpm_add_event_separators(start_pcr, end_pcr); +MIRP + +/*************************************************************************/ +/* Measure and log boot connect vector (bcv) device's master boot record */ +/* SLOF: tpm-measure-bcv-mbr ( bootdrv addr length -- errcode ) */ +/* LIBTPM: errcode = tpm_measure_bcv_mbr(bbotdrv, addr, length) */ +/*************************************************************************/ +PRIM(tpm_X2d_measure_X2d_bcv_X2d_mbr) + int length = TOS.u; POP; + void *addr = TOS.a; POP; + int bootdrv = TOS.u; + TOS.n = tpm_measure_bcv_mbr(bootdrv, addr, length); +MIRP diff --git a/lib/libtpm/tpm.in b/lib/libtpm/tpm.in index 1e8ffc1..2d3d75e 100644 --- a/lib/libtpm/tpm.in +++ b/lib/libtpm/tpm.in @@ -21,3 +21,5 @@ cod(tpm-get-logsize) cod(tpm-log-event) cod(tpm-hash-log-extend-event) cod(tpm-hash-all) +cod(tpm-add-event-separators) +cod(tpm-measure-bcv-mbr) diff --git a/slof/fs/packages/disk-label.fs b/slof/fs/packages/disk-label.fs index 8859fb0..b130743 100644 --- a/slof/fs/packages/disk-label.fs +++ b/slof/fs/packages/disk-label.fs @@ -550,7 +550,15 @@ B9E5 CONSTANT GPT-BASIC-DATA-PARTITION-2 \ load from a bootable partition : load-from-boot-partition ( addr -- size ) debug-disk-label? IF ." Trying DOS boot " .s cr THEN - dup load-from-dos-boot-partition ?dup 0 <> IF nip EXIT THEN + dup load-from-dos-boot-partition ?dup 0 <> IF + nip + block s" /ibm,vtpm" find-node dup IF + s" measure-hdd-mbr" rot $call-static + ELSE + 2drop + THEN + EXIT + THEN debug-disk-label? IF ." Trying CHRP boot " .s cr THEN 1 disk-chrp-boot !