[PATCH v6 3/3] efi_loader: Extend PCR's for firmware measurements

Heinrich Schuchardt xypron.glpk at gmx.de
Fri Nov 26 08:33:25 CET 2021


On 11/26/21 06:00, Ruchika Gupta wrote:
> Firmwares before U-Boot may be capable of doing tpm measurements
> and passing them to U-Boot in the form of eventlog. However there
> may be scenarios where the firmwares don't have TPM driver and
> are not capable of extending the measurements in the PCRs.
> Based on TCG spec, if previous firnware has extended PCR's, PCR0
> would not be 0. So, read the PCR0 to determine if the PCR's need
> to be extended as eventlog is parsed or not.
>
> Signed-off-by: Ruchika Gupta <ruchika.gupta at linaro.org>
> Reviewed-by: Ilias Apalodimas <ilias.apalodimas at linaro.org>
> Tested-by: Ilias Apalodimas <ilias.apalodimas at linaro.org>
> ---
> v6: Changed TPM2_DIGEST_LEN to TPM2_SHA512_DIGEST_SIZE
>
> v5 : No change
>
> v4 : No change
>
> v3 :
> Rebase changes on top of changes made in first patch series
>
> v2 :
> Removed check for PCR0 in eventlog
>
>   lib/efi_loader/efi_tcg2.c | 75 +++++++++++++++++++++++++++++++++++++++
>   1 file changed, 75 insertions(+)
>
> diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
> index a789c44660..295070f3d8 100644
> --- a/lib/efi_loader/efi_tcg2.c
> +++ b/lib/efi_loader/efi_tcg2.c
> @@ -199,6 +199,43 @@ static efi_status_t tcg2_pcr_extend(struct udevice *dev, u32 pcr_index,
>   	return EFI_SUCCESS;
>   }
>
> +/* tcg2_pcr_read - Read PCRs for a TPM2 device for a given tpml_digest_values
> + *
> + * @dev:		device

pcr_index is missing

Best regards

Heinrich

> + * @digest_list:	list of digest algorithms to extend
> + *
> + * @Return: status code
> + */
> +static efi_status_t tcg2_pcr_read(struct udevice *dev, u32 pcr_index,
> +				  struct tpml_digest_values *digest_list)
> +{
> +	struct tpm_chip_priv *priv;
> +	unsigned int updates, pcr_select_min;
> +	u32 rc;
> +	size_t i;
> +
> +	priv = dev_get_uclass_priv(dev);
> +	if (!priv)
> +		return EFI_DEVICE_ERROR;
> +
> +	pcr_select_min = priv->pcr_select_min;
> +
> +	for (i = 0; i < digest_list->count; i++) {
> +		u16 hash_alg = digest_list->digests[i].hash_alg;
> +		u8 *digest = (u8 *)&digest_list->digests[i].digest;
> +
> +		rc = tpm2_pcr_read(dev, pcr_index, pcr_select_min,
> +				   hash_alg, digest, alg_to_len(hash_alg),
> +				   &updates);
> +		if (rc) {
> +			EFI_PRINT("Failed to read PCR\n");
> +			return EFI_DEVICE_ERROR;
> +		}
> +	}
> +
> +	return EFI_SUCCESS;
> +}
> +
>   /* put_event - Append an agile event to an eventlog
>    *
>    * @pcr_index:		PCR index
> @@ -1428,6 +1465,8 @@ efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer,
>   	u32 pcr, pos;
>   	u64 base;
>   	u32 sz;
> +	bool extend_pcr = false;
> +	int i;
>
>   	ret = platform_get_eventlog(dev, &base, &sz);
>   	if (ret != EFI_SUCCESS)
> @@ -1449,6 +1488,26 @@ efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer,
>   		return EFI_COMPROMISED_DATA;
>   	}
>
> +	ret = tcg2_pcr_read(dev, 0, &digest_list);
> +	if (ret) {
> +		log_err("Error reading PCR 0\n");
> +		return ret;
> +	}
> +
> +	/*
> +	 * If PCR0 is 0, previous firmware didn't have the capability
> +	 * to extend the PCR. In this scenario, extend the PCR as
> +	 * the eventlog is parsed.
> +	 */
> +	for (i = 0; i < digest_list.count; i++) {
> +		u8 buffer[TPM2_SHA512_DIGEST_SIZE] =  { 0 };
> +		u16 hash_alg = digest_list.digests[i].hash_alg;
> +
> +		if (!memcmp((u8 *)&digest_list.digests[i].digest, buffer,
> +			    alg_to_len(hash_alg)))
> +			extend_pcr = true;
> +	}
> +
>   	while (pos < sz) {
>   		ret = tcg2_parse_event(dev, buffer, sz, &pos, &digest_list,
>   				       &pcr);
> @@ -1456,6 +1515,22 @@ efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer,
>   			log_err("Error parsing event\n");
>   			return ret;
>   		}
> +		if (extend_pcr) {
> +			ret = tcg2_pcr_extend(dev, pcr, &digest_list);
> +			if (ret != EFI_SUCCESS) {
> +				log_err("Error in extending PCR\n");
> +				return ret;
> +			}
> +
> +			/* Clear the digest for next event */
> +			for (i = 0; i < digest_list.count; i++) {
> +				u16 hash_alg = digest_list.digests[i].hash_alg;
> +				u8 *digest =
> +				   (u8 *)&digest_list.digests[i].digest;
> +
> +				memset(digest, 0, alg_to_len(hash_alg));
> +			}
> +		}
>   	}
>
>   	memcpy(log_buffer, buffer, sz);
>



More information about the U-Boot mailing list