[SLOF] [PATCH 07/16] Perform some initial measurements

Nikunj A Dadhania nikunj at linux.vnet.ibm.com
Mon Nov 9 20:22:53 AEDT 2015


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

> This patch 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. These functions
> will be called in subsequent patches.
>
> 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 <stefanb at linux.vnet.ibm.com>
> ---
>  board-qemu/slof/OF.fs     |   1 +
>  lib/libtpm/tcgbios.c      | 201 ++++++++++++++++++++++++++++++++++++++++++++++
>  lib/libtpm/tcgbios.h      |   9 +++
>  lib/libtpm/tpm.code       |  34 ++++++++
>  lib/libtpm/tpm.in         |   3 +
>  slof/fs/tpm/tpm-static.fs |  11 +++
>  6 files changed, 259 insertions(+)
>
> diff --git a/board-qemu/slof/OF.fs b/board-qemu/slof/OF.fs
> index bd9495e..1306371 100644
> --- a/board-qemu/slof/OF.fs
> +++ b/board-qemu/slof/OF.fs
> @@ -304,6 +304,7 @@ cr
>  #include "copyright-oss.fs"
>  cr cr
>
> +vtpm-add-event-separators
>  vtpm-unassert-pp
>
>  \ this CATCH is to ensure the code bellow always executes:  boot may ABORT!
> diff --git a/lib/libtpm/tcgbios.c b/lib/libtpm/tcgbios.c
> index e86cfc2..2f5b048 100644
> --- a/lib/libtpm/tcgbios.c
> +++ b/lib/libtpm/tcgbios.c
> @@ -66,6 +66,8 @@ static const uint8_t GetCapability_Durations[] = {
>  	0x00, 0x00, 0x01, 0x20
>  };
>
> +static uint8_t evt_separator[] = {0xff,0xff,0xff,0xff};
> +
>  struct tpm_state {
>  	uint8_t	  tpm_probed:1;
>  	uint8_t   tpm_found:1;
> @@ -690,3 +692,202 @@ static uint32_t hash_log_extend_event(const void *hashdata,
>
>  	return tpm_extend(pcpes->digest, pcrindex);
>  }
> +
> +/*
> + * 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
> + *  @data : pointer to data to be hashed
> + *  @data_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 *data,
> +					   uint32_t datalen)
> +{
> +	struct pcpes pcpes;
> +
> +	pcpes.pcrindex	= pcrindex;
> +	pcpes.eventtype = eventtype;
> +	memset(&pcpes.digest, 0, sizeof(pcpes.digest));
> +
> +	return hash_log_extend_event(data, datalen, &pcpes,
> +				     info, infolen, pcrindex);
> +}
> +
> +/*
> + * Add a measurement to the list of measurements
> + * pcrindex   : PCR to be extended
> + * event_type : type of event
> + * string     : string describing the event; used if event_type is EV_ACTION
> + */
> +static uint32_t tpm_add_measurement(uint32_t pcrindex,
> +				    uint16_t event_type,
> +				    const char *string)
> +{
> +	uint32_t rc;
> +	uint32_t len;
> +
> +	switch (event_type) {
> +	case EV_SEPARATOR:
> +		len = sizeof(evt_separator);
> +		rc = tpm_add_measurement_to_log(pcrindex, event_type,
> +			NULL, 0,
> +			(uint8_t *)evt_separator, len);
> +		break;
> +
> +	case EV_ACTION:
> +		rc = tpm_add_measurement_to_log(pcrindex, event_type,
> +			string, strlen(string),
> +			(uint8_t *)string, strlen(string));
> +		break;
> +
> +	default:
> +		rc = TCGBIOS_INVALID_INPUT_PARA;
> +	}
> +
> +	return rc;
> +}
> +
> +/*
> + * Add event separators for PCRs 0 to 7
> + */
> +uint32_t tpm_add_event_separators(void)
> +{
> +	uint32_t rc;
> +	uint32_t pcrindex = 0;
> +
> +	if (!has_working_tpm())
> +		return TCGBIOS_GENERAL_ERROR;
> +
> +	while (pcrindex <= 7) {
> +		rc = tpm_add_measurement(pcrindex, EV_SEPARATOR, NULL);
> +		if (rc)
> +			break;
> +		pcrindex ++;
> +	}
> +
> +	return rc;
> +}
> +
> +/*
> + * Add a measurement regarding the boot device (CDRom, Floppy, HDD) to
> + * the list of measurements.

Is network boot device supported ?

> + */
> +static uint32_t tpm_add_bootdevice(uint32_t bootcd, uint32_t bootdrv)
> +{
> +	const char *string;
> +
> +	dprintf("add bootdevice: bootcd = %d, bootdrv = 0x%x\n", bootcd, bootdrv);
> +
> +	if (!has_working_tpm())
> +		return TCGBIOS_GENERAL_ERROR;
> +
> +	switch (bootcd) {
> +	case 0:
> +		switch (bootdrv) {
> +		case 0:
> +			string = "Booting BCV device 00h (Floppy)";
> +			break;
> +
> +		case 0x80:
> +			string = "Booting BCV device 80h (HDD)";
> +			break;
> +
> +		default:
> +			string = "Booting unknown device";
> +			break;
> +		}
> +		break;
> +
> +	default:
> +		string = "Booting from CD ROM device";
> +	}
> +
> +	return tpm_add_measurement_to_log(4, EV_ACTION,
> +					  string, strlen(string),
> +					  (uint8_t *)string, strlen(string));
> +}
> +
> +/*
> + * Add a measurement to the log. Creates two log entries
> + *
> + * Input parameter:
> + *  bootcd : 0: MBR of hdd, 1: boot image, 2: boot catalog of El Torito
> + *  addr   : address where the IP data are located
> + *  length : IP data length in bytes
> + */
> +uint32_t tpm_ipl(enum ipltype bootcd, const uint8_t *addr, uint32_t length)
> +{
> +	uint32_t rc;
> +	const char *string;
> +
> +	dprintf("tpm_ipl: bootcd = %d, addr = %p, length = 0x%x\n",
> +		bootcd, addr, length);
> +
> +	if (!has_working_tpm())
> +		return TCGBIOS_GENERAL_ERROR;
> +
> +	switch (bootcd) {
> +	case IPL_EL_TORITO_1:
> +		/* specs: see section 'El Torito' */
> +		string = "EL TORITO IPL";
> +		rc = tpm_add_measurement_to_log(4, EV_IPL,
> +						string, strlen(string),
> +						addr, length);
> +	break;
> +
> +	case IPL_EL_TORITO_2:
> +		/* specs: see section 'El Torito' */
> +		string = "BOOT CATALOG";
> +		rc = tpm_add_measurement_to_log(5, EV_IPL_PARTITION_DATA,
> +						string, strlen(string),
> +						addr, length);
> +	break;
> +

Is EL_TORITO_X part of ISO9660 cdrom spec?

> +	default:
> +		/*
> +		 * 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)
> +			break;
> +
> +		/*
> +		 * equivalent to:
> +		 * dd if=/dev/hda ibs=1 count=72 skip=440 | sha1sum
> +		 */
> +		string = "MBR PARTITION TABLE";
> +		rc = tpm_add_measurement_to_log(5, EV_IPL_PARTITION_DATA,
> +						string, strlen(string),
> +						addr + 0x1b8, 0x48);
> +	}

We also support GPT, dont we need support for that ?
Most of the distros are moving to GPT.

> +
> +	return rc;
> +}
> +
> +uint32_t tpm_add_bcv(uint32_t bootdrv, const uint8_t *addr, uint32_t
> length)

tpm_add_bcv: what does bcv mean ?

> +{
> +	uint32_t rc;
> +
> +	if (!has_working_tpm())
> +		return TCGBIOS_GENERAL_ERROR;
> +
> +	rc = tpm_add_bootdevice(0, bootdrv);
> +	if (rc)
> +		return rc;
> +
> +	return tpm_ipl(IPL_BCV, addr, length);
> +}
> diff --git a/lib/libtpm/tcgbios.h b/lib/libtpm/tcgbios.h
> index b217dd1..9b43ce3 100644
> --- a/lib/libtpm/tcgbios.h
> +++ b/lib/libtpm/tcgbios.h
> @@ -15,9 +15,18 @@
>
>  #include <stdint.h>
>
> +enum ipltype {
> +    IPL_BCV = 0,
> +    IPL_EL_TORITO_1,
> +    IPL_EL_TORITO_2
> +};
> +
>  uint32_t tpm_start(void);
>  uint32_t tpm_unassert_pp(void);
>  void tpm_set_log_parameters(void *address, unsigned int size);
>  uint32_t tpm_get_logsize(void);
> +uint32_t tpm_ipl(enum ipltype bootcd, const uint8_t *addr, uint32_t length);
> +uint32_t tpm_add_bcv(uint32_t bootdrv, const uint8_t *addr, uint32_t length);
> +uint32_t tpm_add_event_separators(void);
>
>  #endif /* TCGBIOS_H */
> diff --git a/lib/libtpm/tpm.code b/lib/libtpm/tpm.code
> index b868ca3..de90717 100644
> --- a/lib/libtpm/tpm.code
> +++ b/lib/libtpm/tpm.code
> @@ -56,3 +56,37 @@ PRIM(tpm_X2d_get_X2d_logsize)
>  	PUSH;
>  	TOS.n = tpm_get_logsize();
>  MIRP
> +
> +/************************************************/
> +/* Measure and log event separators             */
> +/* SLOF:   tpm-add-event-separators  ( -- )     */
> +/* LIBTPM: tpm_add_event_separators(void)       */
> +/************************************************/
> +PRIM(tpm_X2d_add_X2d_event_X2d_separators)
> +	PUSH;
> +	TOS.n = tpm_add_event_separators();
> +MIRP
> +
> +/************************************************/
> +/* Measure and log IPL                          */
> +/* SLOF:   tpm-ipl  ( ipltype addr length -- )  */

Does not return anything, missed in the comment?

/* SLOF:   tpm-ipl  ( ipltype addr length --  return ) */

> +/* LIBTPM: tpm_ipl(void)                        */
> +/************************************************/
> +PRIM(tpm_X2d_ipl)
> +	int length = TOS.u; POP;
> +	void *addr = TOS.a; POP;
> +	int bootcd = TOS.u;
> +	TOS.n = tpm_ipl(bootcd, addr, length);
> +MIRP
> +
> +/****************************************************/
> +/* Measure and log bcv IPL                          */
> +/* SLOF:   tpm-add-bcv  ( bootdrv addr length -- )  */

ditto, forgot return in comment ?

> +/* LIBTPM: tpm_add_bcv(void)                        */
> +/****************************************************/
> +PRIM(tpm_X2d_add_X2d_bcv)
> +	int length = TOS.u; POP;
> +	void *addr = TOS.a; POP;
> +	int bootdrv = TOS.u;
> +	TOS.n = tpm_add_bcv(bootdrv, addr, length);
> +MIRP
> diff --git a/lib/libtpm/tpm.in b/lib/libtpm/tpm.in
> index 32d675f..06b0672 100644
> --- a/lib/libtpm/tpm.in
> +++ b/lib/libtpm/tpm.in
> @@ -17,3 +17,6 @@ cod(tpm-start)
>  cod(tpm-unassert-pp)
>  cod(tpm-set-log-parameters)
>  cod(tpm-get-logsize)
> +cod(tpm-add-event-separators)
> +cod(tpm-ipl)
> +cod(tpm-add-bcv)
> diff --git a/slof/fs/tpm/tpm-static.fs b/slof/fs/tpm/tpm-static.fs
> index 11e4ad5..d425693 100644
> --- a/slof/fs/tpm/tpm-static.fs
> +++ b/slof/fs/tpm/tpm-static.fs
> @@ -22,6 +22,17 @@ false VALUE vtpm-debug?
>      THEN
>  ;
>
> +: vtpm-add-event-separators
> +    vtpm-available? IF
> +        tpm-add-event-separators                  ( -- errcode )

Why do we ignore the error code?

> +        vtpm-debug? IF
> +            ." VTPM: Error code from tpm-add-event-separators: " . cr
> +        ELSE
> +            drop
> +        THEN
> +    THEN
> +;
> +
>  : vtpm-unassert-pp
>      vtpm-available? IF
>          tpm-unassert-pp                                    ( -- errcode )
> -- 
> 1.9.3

Regards
Nikunj



More information about the SLOF mailing list