[SLOF] [PATCH v2 07/20] Perform some initial measurements

Thomas Huth thuth at redhat.com
Thu Nov 19 21:14:32 AEDT 2015


On 17/11/15 18:02, Stefan Berger wrote:
> From: Stefan Berger <stefanb at linux.vnet.ibm.com>
> 
> 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>
> ---
[...]
>  \ 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 dbc77d7..6dd8077 100644
> --- a/lib/libtpm/tcgbios.c
> +++ b/lib/libtpm/tcgbios.c
[...]
> +
> +/*
> + * 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) {

Simply use a for-loop? That would be a little bit easier to read.
Also what does this magic value "7" mean here?

> +		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.
> + */
> +static uint32_t tpm_measure_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 BCV_DEVICE_FLOPPY:
> +			string = "Booting BCV device 00h (Floppy)";
> +			break;
> +
> +		case BCV_DEVICE_HDD:
> +			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. This function creates two log entries
> + * of the Initial Program Load (IPL).
> + *
> + * 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_measure_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;

Again, there is no "El Torito" boot on POWER - so I fail to see why you
need this code here ?

Also please indent the break statements at the same level as the
previous code.

> +	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;
> +
> +	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);
> +	}
> +
> +	return rc;
> +}
> +
> +uint32_t tpm_measure_bcv_mbr(uint32_t bootdrv, const uint8_t *addr,
> +                             uint32_t length)
> +{
> +	uint32_t rc;
> +
> +	if (!has_working_tpm())
> +		return TCGBIOS_GENERAL_ERROR;
> +
> +	rc = tpm_measure_bootdevice(0, bootdrv);
> +	if (rc)
> +		return rc;
> +
> +	return tpm_measure_ipl(IPL_BCV, addr, length);
> +}

 Thomas




More information about the SLOF mailing list