[PATCH 1/2] tpm: add a function that performs selftest + startup

Heinrich Schuchardt xypron.glpk at gmx.de
Wed Jan 25 12:56:51 CET 2023


On 1/25/23 12:39, Ilias Apalodimas wrote:
> As described in [0] if a command requires use of an untested algorithm
> or functional module, the TPM performs the test and then completes the
> command actions.
>
> Since we don't check for TPM_RC_NEEDS_TEST (which is the return code of
> the TPM in that case) and even if we would, it would complicate our TPM
> code for no apparent reason,  add a wrapper function that performs both
> the selftest and the startup sequence of the TPM.
>
> It's worth noting that this is implemented on TPMv2.0.  The code for
> 1.2 would look similar,  but I don't have a device available to test.
>
> [0]
> https://trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-1-Architecture-01.07-2014-03-13.pdf
> §12.3 Self-test modes
>
> Signed-off-by: Ilias Apalodimas <ilias.apalodimas at linaro.org>
> ---
>   include/tpm-v2.h  |  8 ++++++++
>   include/tpm_api.h |  8 ++++++++
>   lib/tpm-v2.c      | 29 +++++++++++++++++++++++++++++
>   lib/tpm_api.c     |  8 ++++++++
>   4 files changed, 53 insertions(+)
>
> diff --git a/include/tpm-v2.h b/include/tpm-v2.h
> index 737e57551d73..3013f69a90ed 100644
> --- a/include/tpm-v2.h
> +++ b/include/tpm-v2.h
> @@ -688,4 +688,12 @@ u32 tpm2_report_state(struct udevice *dev, uint vendor_cmd, uint vendor_subcmd,
>   u32 tpm2_enable_nvcommits(struct udevice *dev, uint vendor_cmd,
>   			  uint vendor_subcmd);
>
> +/**
> + * tpm2_auto_start() - start up the TPM and perform selftests
> + *
> + * @param dev		TPM device
> + * Return: return code of the operation (0 = success)
> + */
> +u32 tpm2_auto_start(struct udevice *dev);
> +
>   #endif /* __TPM_V2_H */
> diff --git a/include/tpm_api.h b/include/tpm_api.h
> index 8979d9d6df7e..022a8bbaeca6 100644
> --- a/include/tpm_api.h
> +++ b/include/tpm_api.h
> @@ -331,4 +331,12 @@ static inline bool tpm_is_v2(struct udevice *dev)
>   	return IS_ENABLED(CONFIG_TPM_V2) && tpm_get_version(dev) == TPM_V2;
>   }
>
> +/**
> + * tpm_auto_start() - start up the TPM and perform selftests
> + *
> + * @param dev		TPM device
> + * Return: return code of the operation (0 = success)
> + */
> +u32 tpm_auto_start(struct udevice *dev);
> +
>   #endif /* __TPM_API_H */
> diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
> index 697b982e079f..c34e158e2bb4 100644
> --- a/lib/tpm-v2.c
> +++ b/lib/tpm-v2.c
> @@ -44,6 +44,35 @@ u32 tpm2_self_test(struct udevice *dev, enum tpm2_yes_no full_test)
>   	return tpm_sendrecv_command(dev, command_v2, NULL, NULL);
>   }
>
> +/*
> + * - If a testable function has not been tested and is requested the TPM2  will return
> + *   TPM_RC_NEEDS_TEST.
> + * - If TPM2 self-test has been received and the tests are not complete the
> + *   result will be TPM_RC_TESTING.
> + * - If testing of all functions is complete without functional failures the result
> + *   will be TPM_RC_SUCCESS.
> + * - If any test failed, the result will be TPM2_RC_FAILURE.
> + * - if the TPM hasn't started it will return TPM2_RC_INITIALIZE.
> + */

This comment block should be moved to include/tpm-v2.h to show up in the
HTML documentation.

> +u32 tpm2_auto_start(struct udevice *dev)
> +{
> +	u32 rc;
> +
> +	rc = tpm2_self_test(dev, TPMI_YES);
> +	if (rc && rc != TPM2_RC_INITIALIZE)
> +		return rc;

This if and return are superfluous. We anyway return rc.

Best regards

Heinrich

> +
> +	if (rc == TPM2_RC_INITIALIZE) {
> +		rc = tpm2_startup(dev, TPM2_SU_CLEAR);
> +		if (rc)
> +			return rc;
> +
> +		rc = tpm2_self_test(dev, TPMI_YES);
> +	}
> +
> +	return rc;
> +}
> +
>   u32 tpm2_clear(struct udevice *dev, u32 handle, const char *pw,
>   	       const ssize_t pw_sz)
>   {
> diff --git a/lib/tpm_api.c b/lib/tpm_api.c
> index 7e8df8795ef3..5b2c11a277cc 100644
> --- a/lib/tpm_api.c
> +++ b/lib/tpm_api.c
> @@ -35,6 +35,14 @@ u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode)
>   	}
>   }
>
> +u32 tpm_auto_start(struct udevice *dev)
> +{
> +	if (tpm_is_v2(dev))
> +		return tpm2_auto_start(dev);
> +
> +	return -ENOSYS;
> +}
> +
>   u32 tpm_resume(struct udevice *dev)
>   {
>   	if (tpm_is_v1(dev))



More information about the U-Boot mailing list