From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1014EC7619A for ; Tue, 11 Apr 2023 10:54:13 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 7DCE185F66; Tue, 11 Apr 2023 12:53:41 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="N9vKe0m8"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id B256985EC3; Tue, 11 Apr 2023 10:47:23 +0200 (CEST) Received: from mail-lf1-x12a.google.com (mail-lf1-x12a.google.com [IPv6:2a00:1450:4864:20::12a]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id D3FE285DA2 for ; Tue, 11 Apr 2023 10:47:04 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ilias.apalodimas@linaro.org Received: by mail-lf1-x12a.google.com with SMTP id d7so20505309lfj.3 for ; Tue, 11 Apr 2023 01:47:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1681202824; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=0q8qnfKiljAmgGe+xdg3rt1GKVANekqgB/Zvoo05R1A=; b=N9vKe0m8uI2V04YqdzdqJenS1/dYeBAdYkiROXxOiqMFpMHJwbKtPw57wB6bXGtmv0 0oIVb9CNMFJRhIMeNHh1ywoPb4jWsYot6Z+nIkFx8ig+9baXuYc2DbKTetFZFgLworxX Fnid4zrg+4stvdnEmGmVgL7WFvGaNl9XZIR97IrjRohe7BOWKdPpBacgmBrfmZMpOSNO AuGA4zYo8U4Um9FkibvRrBWRkJV4swd6aGacqY/qtp1ORSXJ9aflzKAu5QH9Z99G1J22 3GmPePK0pQNR5hrMKtbfgQb/BD0I5LlCVTgJZMJSTD/RYdM/SMVfwkBNsJXeuZBFrycQ tN0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1681202824; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=0q8qnfKiljAmgGe+xdg3rt1GKVANekqgB/Zvoo05R1A=; b=qGB2D8BtEC2+bPnAXyuOAtu4BSMKhcLTgbd7A/ASYCqWE4NNG8NjBd8U3Zis3C4E4I rVuRUrqcOLJ/XixfBk3tJePSyae5gciN+IGdzIyWCjxJ8po2T3zQ5ZfXRH8hA1m5sV7i Lsn+EQ44KxGGy7VRvqFPdbRxkd/cZ9qiz2qv4x8AUtdq17PIWzeawXYfc09G7XEa34LG EyKrAqg6cuLnj9s4z+oXlTp7azLn4AfWuxUy7u1pKnG1VulMKe9ld+bU5NesTysOkryU 5p0hIsGJrYgK1Oi0BliyBx3ltBHfNR1Xk82SgbfIx9hx1/+QALq9odm5GApaCsaG2SJk 7yxA== X-Gm-Message-State: AAQBX9eEXJ0qcRInaIq2RSmsR5GGe1l5Z++GBtjiJJ6hNPm5jCloLLl5 cVB/bqv7ivVjai1mmjXuso91p/GYTJyHJ1sR7hwBKQ== X-Google-Smtp-Source: AKy350Z71bnBGk4jk/jGZDnOAABo94m5NCdoNJ2I77oHxXHXwgEKjsTR0FuPlL+4lXNZ7iWzVmevBWX+8KVEIgr2QYQ= X-Received: by 2002:ac2:54a2:0:b0:4ec:878c:b0ac with SMTP id w2-20020ac254a2000000b004ec878cb0acmr1885601lfk.6.1681202823539; Tue, 11 Apr 2023 01:47:03 -0700 (PDT) MIME-Version: 1.0 References: <20230308212537.1725343-1-eajames@linux.ibm.com> <20230308212537.1725343-4-eajames@linux.ibm.com> <2975d7df-87d7-41f3-4409-536210c74c6c@linux.ibm.com> In-Reply-To: <2975d7df-87d7-41f3-4409-536210c74c6c@linux.ibm.com> From: Ilias Apalodimas Date: Tue, 11 Apr 2023 11:46:51 +0300 Message-ID: Subject: Re: [PATCH v9 3/6] tpm: Support boot measurements To: Eddie James Cc: U-Boot Mailing List , Simon Glass , Heinrich Schuchardt , Joel Stanley X-Mailman-Approved-At: Tue, 11 Apr 2023 12:53:18 +0200 Content-Type: text/plain; charset="UTF-8" X-Content-Filtered-By: Mailman/MimeDel 2.1.39 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Ok thanks. I am on PTO this week. I'll have a look once I get back Cheers Ilias On Mon, Apr 10, 2023, 19:18 Eddie James wrote: > > On 4/6/23 04:18, Ilias Apalodimas wrote: > > Hi Eddie, > > > > Do you plan on resending this? > > If yes, I can spend some time trying to figure out the CI failures and > > send you a patch. > > > Hi, > > Yes I do, I have been short on time. I was a bit confused by the CI, it > didn't seem to run with the updated v9? I believed I had fixed at least > some of the failures with patch 2 to update the sandbox driver. I also > haven't figured out how to run the ci suite locally > > Thanks, > > Eddie > > > > > Thanks > > /Ilias > > > > > > On Wed, 8 Mar 2023 at 23:25, Eddie James wrote: > >> Add TPM2 functions to support boot measurement. This includes > >> starting up the TPM, initializing/appending the event log, and > >> measuring the U-Boot version. Much of the code was used in the > >> EFI subsystem, so remove it there and use the common functions. > >> > >> Signed-off-by: Eddie James > >> --- > >> Changes since v8: > >> - Fix log parsing again - any data corruption seen while replaying the > >> event log was failing the entire measurement. > >> - Added an option to ignore the existing log. This should only be used > >> for systems that know that U-Boot is the first stage bootloader. > This > >> is necessary because the reserved memory region may persist through > >> resets and so U-Boot attempts to append to the previous boot's log. > >> > >> Changes since v7: > >> - Change name of tcg2_init_log and add more documentation > >> - Add a check, when parsing the event log header, to ensure that the > >> previous stage bootloader used all the active PCRs. > >> - Change name of tcg2_log_find_end > >> - Fix the greater than or equal to check to exit the log parsing > >> - Make sure log_position is 0 if there is any error discovering the > log > >> - Return errors parsing the log if the data is corrupt so that we > don't > >> end up with half a log > >> > >> Changes since v6: > >> - Added Linaro copyright for all the EFI moved code > >> - Changed tcg2_init_log (and by extension, tcg2_measurement_init) to > >> copy any discovered event log to the user's log if passed in. > >> > >> Changes since v5: > >> - Remove unused platform_get_eventlog in efi_tcg2.c > >> - First look for tpm_event_log_* properties instead of linux,sml-* > >> - Fix efi_tcg2.c compilation > >> - Select SHA* configs > >> > >> Changes since v4: > >> - Remove tcg2_measure_event function and check for NULL data in > >> tcg2_measure_data > >> - Use tpm_auto_startup > >> - Fix efi_tcg2.c compilation for removing tcg2_pcr_read function > >> > >> Changes since v3: > >> - Reordered headers > >> - Refactored more of EFI code into common code > >> Removed digest_info structure and instead used the common > alg_to_mask > >> and alg_to_len > >> Improved event log parsing in common code to get it equivalent to > EFI > >> Common code now extends PCR if previous bootloader stage couldn't > >> No need to allocate memory in the common code, so EFI copies the > >> discovered buffer like it did before > >> Rename efi measure_event function > >> > >> Changes since v1: > >> - Refactor TPM layer functions to allow EFI system to use them, and > >> remove duplicate EFI functions > >> > >> include/efi_tcg2.h | 44 -- > >> include/tpm-v2.h | 259 +++++++++ > >> lib/Kconfig | 4 + > >> lib/efi_loader/efi_tcg2.c | 1054 +++---------------------------------- > >> lib/tpm-v2.c | 814 ++++++++++++++++++++++++++++ > >> 5 files changed, 1154 insertions(+), 1021 deletions(-) > >> > >> diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h > >> index b1c3abd097..b21c5cb3dd 100644 > >> --- a/include/efi_tcg2.h > >> +++ b/include/efi_tcg2.h > >> @@ -129,50 +129,6 @@ struct efi_tcg2_boot_service_capability { > >> #define BOOT_SERVICE_CAPABILITY_MIN \ > >> offsetof(struct efi_tcg2_boot_service_capability, > number_of_pcr_banks) > >> > >> -#define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03" > >> -#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2 > >> -#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0 > >> -#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2 > >> - > >> -/** > >> - * struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm > information > >> - * > >> - * @algorithm_id: algorithm defined in enum tpm2_algorithms > >> - * @digest_size: size of the algorithm > >> - */ > >> -struct tcg_efi_spec_id_event_algorithm_size { > >> - u16 algorithm_id; > >> - u16 digest_size; > >> -} __packed; > >> - > >> -/** > >> - * struct TCG_EfiSpecIDEventStruct - content of the event log header > >> - * > >> - * @signature: signature, set to Spec ID Event03 > >> - * @platform_class: class defined in TCG ACPI Specification > >> - * Client Common Header. > >> - * @spec_version_minor: minor version > >> - * @spec_version_major: major version > >> - * @spec_version_errata: major version > >> - * @uintn_size: size of the efi_uintn_t fields > used in various > >> - * data structures used in this > specification. > >> - * 0x01 indicates u32 and 0x02 indicates > u64 > >> - * @number_of_algorithms: hashing algorithms used in this event > log > >> - * @digest_sizes: array of number_of_algorithms pairs > >> - * 1st member defines the algorithm id > >> - * 2nd member defines the algorithm size > >> - */ > >> -struct tcg_efi_spec_id_event { > >> - u8 signature[16]; > >> - u32 platform_class; > >> - u8 spec_version_minor; > >> - u8 spec_version_major; > >> - u8 spec_errata; > >> - u8 uintn_size; > >> - u32 number_of_algorithms; > >> - struct tcg_efi_spec_id_event_algorithm_size digest_sizes[]; > >> -} __packed; > >> - > >> /** > >> * struct tdEFI_TCG2_FINAL_EVENTS_TABLE - log entries after Get Event > Log > >> * @version: version number for this structure > >> diff --git a/include/tpm-v2.h b/include/tpm-v2.h > >> index 6684033deb..33dd103767 100644 > >> --- a/include/tpm-v2.h > >> +++ b/include/tpm-v2.h > >> @@ -216,6 +216,50 @@ struct tcg_pcr_event2 { > >> u8 event[]; > >> } __packed; > >> > >> +/** > >> + * struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm > information > >> + * > >> + * @algorithm_id: algorithm defined in enum tpm2_algorithms > >> + * @digest_size: size of the algorithm > >> + */ > >> +struct tcg_efi_spec_id_event_algorithm_size { > >> + u16 algorithm_id; > >> + u16 digest_size; > >> +} __packed; > >> + > >> +#define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03" > >> +#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2 > >> +#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0 > >> +#define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2 > >> + > >> +/** > >> + * struct TCG_EfiSpecIDEventStruct - content of the event log header > >> + * > >> + * @signature: signature, set to Spec ID Event03 > >> + * @platform_class: class defined in TCG ACPI Specification > >> + * Client Common Header. > >> + * @spec_version_minor: minor version > >> + * @spec_version_major: major version > >> + * @spec_version_errata: major version > >> + * @uintn_size: size of the efi_uintn_t fields > used in various > >> + * data structures used in this > specification. > >> + * 0x01 indicates u32 and 0x02 indicates > u64 > >> + * @number_of_algorithms: hashing algorithms used in this event > log > >> + * @digest_sizes: array of number_of_algorithms pairs > >> + * 1st member defines the algorithm id > >> + * 2nd member defines the algorithm size > >> + */ > >> +struct tcg_efi_spec_id_event { > >> + u8 signature[16]; > >> + u32 platform_class; > >> + u8 spec_version_minor; > >> + u8 spec_version_major; > >> + u8 spec_errata; > >> + u8 uintn_size; > >> + u32 number_of_algorithms; > >> + struct tcg_efi_spec_id_event_algorithm_size digest_sizes[]; > >> +} __packed; > >> + > >> /** > >> * TPM2 Structure Tags for command/response buffers. > >> * > >> @@ -342,6 +386,26 @@ enum tpm2_algorithms { > >> TPM2_ALG_SM3_256 = 0x12, > >> }; > >> > >> +extern const enum tpm2_algorithms tpm2_supported_algorithms[4]; > >> + > >> +static inline u16 tpm2_algorithm_to_len(enum tpm2_algorithms a) > >> +{ > >> + switch (a) { > >> + case TPM2_ALG_SHA1: > >> + return TPM2_SHA1_DIGEST_SIZE; > >> + case TPM2_ALG_SHA256: > >> + return TPM2_SHA256_DIGEST_SIZE; > >> + case TPM2_ALG_SHA384: > >> + return TPM2_SHA384_DIGEST_SIZE; > >> + case TPM2_ALG_SHA512: > >> + return TPM2_SHA512_DIGEST_SIZE; > >> + default: > >> + return 0; > >> + } > >> +} > >> + > >> +#define tpm2_algorithm_to_mask(a) (1 << (a)) > >> + > >> /* NV index attributes */ > >> enum tpm_index_attrs { > >> TPMA_NV_PPWRITE = 1UL << 0, > >> @@ -421,6 +485,188 @@ enum { > >> HR_NV_INDEX = TPM_HT_NV_INDEX << HR_SHIFT, > >> }; > >> > >> +/** > >> + * struct tcg2_event_log - Container for managing the platform event > log > >> + * > >> + * @log: Address of the log > >> + * @log_position: Current entry position > >> + * @log_size: Log space available > >> + * @found: Boolean indicating if an existing log was > discovered > >> + */ > >> +struct tcg2_event_log { > >> + u8 *log; > >> + u32 log_position; > >> + u32 log_size; > >> + bool found; > >> +}; > >> + > >> +/** > >> + * Create a list of digests of the supported PCR banks for a given > input data > >> + * > >> + * @dev TPM device > >> + * @input Data > >> + * @length Length of the data to calculate the digest > >> + * @digest_list List of digests to fill in > >> + * > >> + * Return: zero on success, negative errno otherwise > >> + */ > >> +int tcg2_create_digest(struct udevice *dev, const u8 *input, u32 > length, > >> + struct tpml_digest_values *digest_list); > >> + > >> +/** > >> + * Get the event size of the specified digests > >> + * > >> + * @digest_list List of digests for the event > >> + * > >> + * Return: Size in bytes of the event > >> + */ > >> +u32 tcg2_event_get_size(struct tpml_digest_values *digest_list); > >> + > >> +/** > >> + * tcg2_get_active_pcr_banks > >> + * > >> + * @dev TPM device > >> + * @active_pcr_banks Bitmask of PCR algorithms supported > >> + * > >> + * Return: zero on success, negative errno otherwise > >> + */ > >> +int tcg2_get_active_pcr_banks(struct udevice *dev, u32 > *active_pcr_banks); > >> + > >> +/** > >> + * tcg2_log_append - Append an event to an event log > >> + * > >> + * @pcr_index Index of the PCR > >> + * @event_type Type of event > >> + * @digest_list List of digests to add > >> + * @size Size of event > >> + * @event Event data > >> + * @log Log buffer to append the event to > >> + */ > >> +void tcg2_log_append(u32 pcr_index, u32 event_type, > >> + struct tpml_digest_values *digest_list, u32 size, > >> + const u8 *event, u8 *log); > >> + > >> +/** > >> + * Extend the PCR with specified digests > >> + * > >> + * @dev TPM device > >> + * @pcr_index Index of the PCR > >> + * @digest_list List of digests to extend > >> + * > >> + * Return: zero on success, negative errno otherwise > >> + */ > >> +int tcg2_pcr_extend(struct udevice *dev, u32 pcr_index, > >> + struct tpml_digest_values *digest_list); > >> + > >> +/** > >> + * Read the PCR into a list of digests > >> + * > >> + * @dev TPM device > >> + * @pcr_index Index of the PCR > >> + * @digest_list List of digests to extend > >> + * > >> + * Return: zero on success, negative errno otherwise > >> + */ > >> +int tcg2_pcr_read(struct udevice *dev, u32 pcr_index, > >> + struct tpml_digest_values *digest_list); > >> + > >> +/** > >> + * Measure data into the TPM PCRs and the platform event log. > >> + * > >> + * @dev TPM device > >> + * @log Platform event log > >> + * @pcr_index Index of the PCR > >> + * @size Size of the data or 0 for event only > >> + * @data Pointer to the data or NULL for event only > >> + * @event_type Event log type > >> + * @event_size Size of the event > >> + * @event Pointer to the event > >> + * > >> + * Return: zero on success, negative errno otherwise > >> + */ > >> +int tcg2_measure_data(struct udevice *dev, struct tcg2_event_log *elog, > >> + u32 pcr_index, u32 size, const u8 *data, u32 > event_type, > >> + u32 event_size, const u8 *event); > >> + > >> +#define tcg2_measure_event(dev, elog, pcr_index, event_type, size, > event) \ > >> + tcg2_measure_data(dev, elog, pcr_index, 0, NULL, event_type, > size, \ > >> + event) > >> + > >> +/** > >> + * Prepare the event log buffer. This function tries to discover an > existing > >> + * event log in memory from a previous bootloader stage. If such a log > exists > >> + * and the PCRs are not extended, the log is "replayed" to extend the > PCRs. > >> + * If no log is discovered, create the log header. > >> + * > >> + * @dev TPM device > >> + * @elog Platform event log. The log pointer and log_size > >> + * members must be initialized to either 0 or to a > valid > >> + * memory region, in which case any existing log > >> + * discovered will be copied to the specified > memory > >> + * region. > >> + * @ignore_existing_log Boolean to indicate whether or not to > ignore an > >> + * existing platform log in memory > >> + * > >> + * Return: zero on success, negative errno otherwise > >> + */ > >> +int tcg2_log_prepare_buffer(struct udevice *dev, struct tcg2_event_log > *elog, > >> + bool ignore_existing_log); > >> + > >> +/** > >> + * Begin measurements. > >> + * > >> + * @dev TPM device > >> + * @elog Platform event log. The log pointer and log_size > >> + * members must be initialized to either 0 or to a > valid > >> + * memory region, in which case any existing log > >> + * discovered will be copied to the specified > memory > >> + * region. > >> + * @ignore_existing_log Boolean to indicate whether or not to ignore an > >> + * existing platform log in memory > >> + * > >> + * Return: zero on success, negative errno otherwise > >> + */ > >> +int tcg2_measurement_init(struct udevice **dev, struct tcg2_event_log > *elog, > >> + bool ignore_existing_log); > >> + > >> +/** > >> + * Stop measurements and record separator events. > >> + * > >> + * @dev TPM device > >> + * @elog Platform event log > >> + * @error Boolean to indicate whether an error ocurred or not > >> + */ > >> +void tcg2_measurement_term(struct udevice *dev, struct tcg2_event_log > *elog, > >> + bool error); > >> + > >> +/** > >> + * Get the platform event log address and size. > >> + * > >> + * @dev TPM device > >> + * @addr Address of the log > >> + * @size Size of the log > >> + * > >> + * Return: zero on success, negative errno otherwise > >> + */ > >> +int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size); > >> + > >> +/** > >> + * Get the first TPM2 device found. > >> + * > >> + * @dev TPM device > >> + * > >> + * Return: zero on success, negative errno otherwise > >> + */ > >> +int tcg2_platform_get_tpm2(struct udevice **dev); > >> + > >> +/** > >> + * Platform-specific function for handling TPM startup errors > >> + * > >> + * @dev TPM device > >> + * @rc The TPM response code > >> + */ > >> +void tcg2_platform_startup_error(struct udevice *dev, int rc); > >> + > >> /** > >> * Issue a TPM2_Startup command. > >> * > >> @@ -540,6 +786,19 @@ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, > unsigned int idx_min_sz, > >> u32 tpm2_get_capability(struct udevice *dev, u32 capability, u32 > property, > >> void *buf, size_t prop_count); > >> > >> +/** > >> + * tpm2_get_pcr_info() - get the supported, active PCRs and number of > banks > >> + * > >> + * @dev: TPM device > >> + * @supported_pcr: bitmask with the algorithms supported > >> + * @active_pcr: bitmask with the active algorithms > >> + * @pcr_banks: number of PCR banks > >> + * > >> + * @return 0 on success, code of operation or negative errno on failure > >> + */ > >> +int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 > *active_pcr, > >> + u32 *pcr_banks); > >> + > >> /** > >> * Issue a TPM2_DictionaryAttackLockReset command. > >> * > >> diff --git a/lib/Kconfig b/lib/Kconfig > >> index 83e5edd73b..7a146c293f 100644 > >> --- a/lib/Kconfig > >> +++ b/lib/Kconfig > >> @@ -411,6 +411,10 @@ config TPM > >> bool "Trusted Platform Module (TPM) Support" > >> depends on DM > >> imply DM_RNG > >> + select SHA1 > >> + select SHA256 > >> + select SHA384 > >> + select SHA512 > >> help > >> This enables support for TPMs which can be used to provide > security > >> features for your board. The TPM can be connected via LPC or > I2C > >> diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c > >> index a83ae7a46c..5f0f4b5dd2 100644 > >> --- a/lib/efi_loader/efi_tcg2.c > >> +++ b/lib/efi_loader/efi_tcg2.c > >> @@ -66,35 +66,6 @@ static bool tcg2_efi_app_invoked; > >> static const efi_guid_t efi_guid_tcg2_protocol = > EFI_TCG2_PROTOCOL_GUID; > >> static const efi_guid_t efi_guid_final_events = > EFI_TCG2_FINAL_EVENTS_TABLE_GUID; > >> > >> -struct digest_info { > >> - u16 hash_alg; > >> - u32 hash_mask; > >> - u16 hash_len; > >> -}; > >> - > >> -static const struct digest_info hash_algo_list[] = { > >> - { > >> - TPM2_ALG_SHA1, > >> - EFI_TCG2_BOOT_HASH_ALG_SHA1, > >> - TPM2_SHA1_DIGEST_SIZE, > >> - }, > >> - { > >> - TPM2_ALG_SHA256, > >> - EFI_TCG2_BOOT_HASH_ALG_SHA256, > >> - TPM2_SHA256_DIGEST_SIZE, > >> - }, > >> - { > >> - TPM2_ALG_SHA384, > >> - EFI_TCG2_BOOT_HASH_ALG_SHA384, > >> - TPM2_SHA384_DIGEST_SIZE, > >> - }, > >> - { > >> - TPM2_ALG_SHA512, > >> - EFI_TCG2_BOOT_HASH_ALG_SHA512, > >> - TPM2_SHA512_DIGEST_SIZE, > >> - }, > >> -}; > >> - > >> struct variable_info { > >> const u16 *name; > >> bool accept_empty; > >> @@ -113,46 +84,6 @@ static struct variable_info secure_variables[] = { > >> {u"AuditMode", false, 1}, > >> }; > >> > >> -#define MAX_HASH_COUNT ARRAY_SIZE(hash_algo_list) > >> - > >> -/** > >> - * alg_to_mask - Get a TCG hash mask for algorithms > >> - * > >> - * @hash_alg: TCG defined algorithm > >> - * > >> - * @Return: TCG hashing algorithm bitmaps, 0 if the algorithm is not > supported > >> - */ > >> -static u32 alg_to_mask(u16 hash_alg) > >> -{ > >> - size_t i; > >> - > >> - for (i = 0; i < MAX_HASH_COUNT; i++) { > >> - if (hash_algo_list[i].hash_alg == hash_alg) > >> - return hash_algo_list[i].hash_mask; > >> - } > >> - > >> - return 0; > >> -} > >> - > >> -/** > >> - * alg_to_len - Get a TCG hash len for algorithms > >> - * > >> - * @hash_alg: TCG defined algorithm > >> - * > >> - * @Return: len of chosen algorithm, 0 if the algorithm is not > supported > >> - */ > >> -static u16 alg_to_len(u16 hash_alg) > >> -{ > >> - size_t i; > >> - > >> - for (i = 0; i < MAX_HASH_COUNT; i++) { > >> - if (hash_algo_list[i].hash_alg == hash_alg) > >> - return hash_algo_list[i].hash_len; > >> - } > >> - > >> - return 0; > >> -} > >> - > >> static bool is_tcg2_protocol_installed(void) > >> { > >> struct efi_handler *handler; > >> @@ -162,145 +93,6 @@ static bool is_tcg2_protocol_installed(void) > >> return ret == EFI_SUCCESS; > >> } > >> > >> -static u32 tcg_event_final_size(struct tpml_digest_values *digest_list) > >> -{ > >> - u32 len; > >> - size_t i; > >> - > >> - len = offsetof(struct tcg_pcr_event2, digests); > >> - len += offsetof(struct tpml_digest_values, digests); > >> - for (i = 0; i < digest_list->count; i++) { > >> - u16 hash_alg = digest_list->digests[i].hash_alg; > >> - > >> - len += offsetof(struct tpmt_ha, digest); > >> - len += alg_to_len(hash_alg); > >> - } > >> - len += sizeof(u32); /* tcg_pcr_event2 event_size*/ > >> - > >> - return len; > >> -} > >> - > >> -/* tcg2_pcr_extend - Extend PCRs for a TPM2 device for a given > tpml_digest_values > >> - * > >> - * @dev: device > >> - * @digest_list: list of digest algorithms to extend > >> - * > >> - * @Return: status code > >> - */ > >> -static efi_status_t tcg2_pcr_extend(struct udevice *dev, u32 pcr_index, > >> - struct tpml_digest_values > *digest_list) > >> -{ > >> - u32 rc; > >> - size_t i; > >> - > >> - for (i = 0; i < digest_list->count; i++) { > >> - u32 alg = digest_list->digests[i].hash_alg; > >> - > >> - rc = tpm2_pcr_extend(dev, pcr_index, alg, > >> - (u8 > *)&digest_list->digests[i].digest, > >> - alg_to_len(alg)); > >> - if (rc) { > >> - EFI_PRINT("Failed to extend PCR\n"); > >> - return EFI_DEVICE_ERROR; > >> - } > >> - } > >> - > >> - return EFI_SUCCESS; > >> -} > >> - > >> -/* tcg2_pcr_read - Read PCRs for a TPM2 device for a given > tpml_digest_values > >> - * > >> - * @dev: device > >> - * @pcr_index: PCR index > >> - * @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 > >> - * @event_type: type of event added > >> - * @digest_list: list of digest algorithms to add > >> - * @size: size of event > >> - * @event: event to add > >> - * @log: log buffer to append the event > >> - * > >> - */ > >> -static void put_event(u32 pcr_index, u32 event_type, > >> - struct tpml_digest_values *digest_list, u32 size, > >> - u8 event[], void *log) > >> -{ > >> - size_t pos; > >> - size_t i; > >> - u32 event_size; > >> - > >> - /* > >> - * size refers to the length of event[] only, we need to check > against > >> - * the final tcg_pcr_event2 size > >> - */ > >> - event_size = size + tcg_event_final_size(digest_list); > >> - > >> - put_unaligned_le32(pcr_index, log); > >> - pos = offsetof(struct tcg_pcr_event2, event_type); > >> - put_unaligned_le32(event_type, (void *)((uintptr_t)log + pos)); > >> - pos = offsetof(struct tcg_pcr_event2, digests); /* count */ > >> - put_unaligned_le32(digest_list->count, (void *)((uintptr_t)log > + pos)); > >> - > >> - pos += offsetof(struct tpml_digest_values, digests); > >> - 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; > >> - > >> - put_unaligned_le16(hash_alg, (void *)((uintptr_t)log + > pos)); > >> - pos += offsetof(struct tpmt_ha, digest); > >> - memcpy((void *)((uintptr_t)log + pos), digest, > alg_to_len(hash_alg)); > >> - pos += alg_to_len(hash_alg); > >> - } > >> - > >> - put_unaligned_le32(size, (void *)((uintptr_t)log + pos)); > >> - pos += sizeof(u32); /* tcg_pcr_event2 event_size*/ > >> - memcpy((void *)((uintptr_t)log + pos), event, size); > >> - pos += size; > >> - > >> - /* > >> - * make sure the calculated buffer is what we checked against > >> - * This check should never fail. It checks the code above is > >> - * calculating the right length for the event we are adding > >> - */ > >> - if (pos != event_size) > >> - log_err("Appending to the EventLog failed\n"); > >> -} > >> - > >> /* tcg2_agile_log_append - Append an agile event to an eventlog > >> * > >> * @pcr_index: PCR index > >> @@ -317,7 +109,7 @@ static efi_status_t tcg2_agile_log_append(u32 > pcr_index, u32 event_type, > >> u32 size, u8 event[]) > >> { > >> void *log = (void *)((uintptr_t)event_log.buffer + > event_log.pos); > >> - u32 event_size = size + tcg_event_final_size(digest_list); > >> + u32 event_size = size + tcg2_event_get_size(digest_list); > >> struct efi_tcg2_final_events_table *final_event; > >> efi_status_t ret = EFI_SUCCESS; > >> > >> @@ -328,7 +120,7 @@ static efi_status_t tcg2_agile_log_append(u32 > pcr_index, u32 event_type, > >> event_log.truncated = true; > >> return EFI_VOLUME_FULL; > >> } > >> - put_event(pcr_index, event_type, digest_list, size, > event, log); > >> + tcg2_log_append(pcr_index, event_type, digest_list, > size, event, log); > >> event_log.pos += event_size; > >> event_log.last_event_size = event_size; > >> } > >> @@ -341,7 +133,7 @@ static efi_status_t tcg2_agile_log_append(u32 > pcr_index, u32 event_type, > >> return EFI_VOLUME_FULL; > >> > >> log = (void *)((uintptr_t)event_log.final_buffer + > event_log.final_pos); > >> - put_event(pcr_index, event_type, digest_list, size, event, log); > >> + tcg2_log_append(pcr_index, event_type, digest_list, size, > event, log); > >> > >> final_event = event_log.final_buffer; > >> final_event->number_of_events++; > >> @@ -350,66 +142,6 @@ static efi_status_t tcg2_agile_log_append(u32 > pcr_index, u32 event_type, > >> return ret; > >> } > >> > >> -/** > >> - * platform_get_tpm_device() - retrieve TPM device > >> - * > >> - * This function retrieves the udevice implementing a TPM > >> - * > >> - * This function may be overridden if special initialization is needed. > >> - * > >> - * @dev: udevice > >> - * Return: status code > >> - */ > >> -__weak efi_status_t platform_get_tpm2_device(struct udevice **dev) > >> -{ > >> - for_each_tpm_device(*dev) { > >> - /* Only support TPMv2 devices */ > >> - if (tpm_get_version(*dev) == TPM_V2) > >> - return EFI_SUCCESS; > >> - } > >> - > >> - return EFI_NOT_FOUND; > >> -} > >> - > >> -/** > >> - * platform_get_eventlog() - retrieve the eventlog address and size > >> - * > >> - * This function retrieves the eventlog address and size if the > underlying > >> - * firmware has done some measurements and passed them. > >> - * > >> - * This function may be overridden based on platform specific method of > >> - * passing the eventlog address and size. > >> - * > >> - * @dev: udevice > >> - * @addr: eventlog address > >> - * @sz: eventlog size > >> - * Return: status code > >> - */ > >> -__weak efi_status_t platform_get_eventlog(struct udevice *dev, u64 > *addr, > >> - u32 *sz) > >> -{ > >> - const u64 *basep; > >> - const u32 *sizep; > >> - > >> - basep = dev_read_prop(dev, "tpm_event_log_addr", NULL); > >> - if (!basep) > >> - return EFI_NOT_FOUND; > >> - > >> - *addr = be64_to_cpup((__force __be64 *)basep); > >> - > >> - sizep = dev_read_prop(dev, "tpm_event_log_size", NULL); > >> - if (!sizep) > >> - return EFI_NOT_FOUND; > >> - > >> - *sz = be32_to_cpup((__force __be32 *)sizep); > >> - if (*sz == 0) { > >> - log_debug("event log empty\n"); > >> - return EFI_NOT_FOUND; > >> - } > >> - > >> - return EFI_SUCCESS; > >> -} > >> - > >> /** > >> * tpm2_get_max_command_size() - get the supported max command size > >> * > >> @@ -485,239 +217,6 @@ static int tpm2_get_manufacturer_id(struct > udevice *dev, u32 *manufacturer_id) > >> return 0; > >> } > >> > >> -/** > >> - * tpm2_get_num_pcr() - get the number of PCRs > >> - * > >> - * @dev: TPM device > >> - * @manufacturer_id: output buffer for the number > >> - * > >> - * Return: 0 on success, -1 on error > >> - */ > >> -static int tpm2_get_num_pcr(struct udevice *dev, u32 *num_pcr) > >> -{ > >> - u8 response[TPM2_RESPONSE_BUFFER_SIZE]; > >> - u32 ret; > >> - > >> - memset(response, 0, sizeof(response)); > >> - ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES, > >> - TPM2_PT_PCR_COUNT, response, 1); > >> - if (ret) > >> - return -1; > >> - > >> - *num_pcr = get_unaligned_be32(response + properties_offset); > >> - if (*num_pcr > TPM2_MAX_PCRS) > >> - return -1; > >> - > >> - return 0; > >> -} > >> - > >> -/** > >> - * is_active_pcr() - Check if a supported algorithm is active > >> - * > >> - * @dev: TPM device > >> - * @selection: struct of PCR information > >> - * > >> - * Return: true if PCR is active > >> - */ > >> -static bool is_active_pcr(struct tpms_pcr_selection *selection) > >> -{ > >> - int i; > >> - /* > >> - * check the pcr_select. If at least one of the PCRs supports > the > >> - * algorithm add it on the active ones > >> - */ > >> - for (i = 0; i < selection->size_of_select; i++) { > >> - if (selection->pcr_select[i]) > >> - return true; > >> - } > >> - > >> - return false; > >> -} > >> - > >> -/** > >> - * tpm2_get_pcr_info() - get the supported, active PCRs and number of > banks > >> - * > >> - * @dev: TPM device > >> - * @supported_pcr: bitmask with the algorithms supported > >> - * @active_pcr: bitmask with the active algorithms > >> - * @pcr_banks: number of PCR banks > >> - * > >> - * Return: 0 on success, -1 on error > >> - */ > >> -static int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, > >> - u32 *active_pcr, u32 *pcr_banks) > >> -{ > >> - u8 response[TPM2_RESPONSE_BUFFER_SIZE]; > >> - struct tpml_pcr_selection pcrs; > >> - u32 ret, num_pcr; > >> - size_t i; > >> - int tpm_ret; > >> - > >> - *supported_pcr = 0; > >> - *active_pcr = 0; > >> - *pcr_banks = 0; > >> - memset(response, 0, sizeof(response)); > >> - ret = tpm2_get_capability(dev, TPM2_CAP_PCRS, 0, response, 1); > >> - if (ret) > >> - goto out; > >> - > >> - pcrs.count = get_unaligned_be32(response); > >> - /* > >> - * We only support 5 algorithms for now so check against that > >> - * instead of TPM2_NUM_PCR_BANKS > >> - */ > >> - if (pcrs.count > MAX_HASH_COUNT || pcrs.count < 1) > >> - goto out; > >> - > >> - tpm_ret = tpm2_get_num_pcr(dev, &num_pcr); > >> - if (tpm_ret) > >> - goto out; > >> - > >> - for (i = 0; i < pcrs.count; i++) { > >> - /* > >> - * Definition of TPMS_PCR_SELECTION Structure > >> - * hash: u16 > >> - * size_of_select: u8 > >> - * pcr_select: u8 array > >> - * > >> - * The offsets depend on the number of the device PCRs > >> - * so we have to calculate them based on that > >> - */ > >> - u32 hash_offset = offsetof(struct tpml_pcr_selection, > selection) + > >> - i * offsetof(struct tpms_pcr_selection, > pcr_select) + > >> - i * ((num_pcr + 7) / 8); > >> - u32 size_select_offset = > >> - hash_offset + offsetof(struct > tpms_pcr_selection, > >> - size_of_select); > >> - u32 pcr_select_offset = > >> - hash_offset + offsetof(struct > tpms_pcr_selection, > >> - pcr_select); > >> - > >> - pcrs.selection[i].hash = > >> - get_unaligned_be16(response + hash_offset); > >> - pcrs.selection[i].size_of_select = > >> - __get_unaligned_be(response + > size_select_offset); > >> - if (pcrs.selection[i].size_of_select > > TPM2_PCR_SELECT_MAX) > >> - goto out; > >> - /* copy the array of pcr_select */ > >> - memcpy(pcrs.selection[i].pcr_select, response + > pcr_select_offset, > >> - pcrs.selection[i].size_of_select); > >> - } > >> - > >> - for (i = 0; i < pcrs.count; i++) { > >> - u32 hash_mask = alg_to_mask(pcrs.selection[i].hash); > >> - > >> - if (hash_mask) { > >> - *supported_pcr |= hash_mask; > >> - if (is_active_pcr(&pcrs.selection[i])) > >> - *active_pcr |= hash_mask; > >> - } else { > >> - EFI_PRINT("Unknown algorithm %x\n", > pcrs.selection[i].hash); > >> - } > >> - } > >> - > >> - *pcr_banks = pcrs.count; > >> - > >> - return 0; > >> -out: > >> - return -1; > >> -} > >> - > >> -/** > >> - * __get_active_pcr_banks() - returns the currently active PCR banks > >> - * > >> - * @active_pcr_banks: pointer for receiving the bitmap of > currently > >> - * active PCR banks > >> - * > >> - * Return: status code > >> - */ > >> -static efi_status_t __get_active_pcr_banks(u32 *active_pcr_banks) > >> -{ > >> - struct udevice *dev; > >> - u32 active = 0, supported = 0, pcr_banks = 0; > >> - efi_status_t ret; > >> - int err; > >> - > >> - ret = platform_get_tpm2_device(&dev); > >> - if (ret != EFI_SUCCESS) > >> - goto out; > >> - > >> - err = tpm2_get_pcr_info(dev, &supported, &active, &pcr_banks); > >> - if (err) { > >> - ret = EFI_DEVICE_ERROR; > >> - goto out; > >> - } > >> - > >> - *active_pcr_banks = active; > >> - > >> -out: > >> - return ret; > >> -} > >> - > >> -/* tcg2_create_digest - create a list of digests of the supported PCR > banks > >> - * for a given memory range > >> - * > >> - * @input: input memory > >> - * @length: length of buffer to calculate the digest > >> - * @digest_list: list of digests to fill in > >> - * > >> - * Return: status code > >> - */ > >> -static efi_status_t tcg2_create_digest(const u8 *input, u32 length, > >> - struct tpml_digest_values > *digest_list) > >> -{ > >> - sha1_context ctx; > >> - sha256_context ctx_256; > >> - sha512_context ctx_512; > >> - u8 final[TPM2_SHA512_DIGEST_SIZE]; > >> - efi_status_t ret; > >> - u32 active; > >> - size_t i; > >> - > >> - ret = __get_active_pcr_banks(&active); > >> - if (ret != EFI_SUCCESS) > >> - return ret; > >> - > >> - digest_list->count = 0; > >> - for (i = 0; i < MAX_HASH_COUNT; i++) { > >> - u16 hash_alg = hash_algo_list[i].hash_alg; > >> - > >> - if (!(active & alg_to_mask(hash_alg))) > >> - continue; > >> - switch (hash_alg) { > >> - case TPM2_ALG_SHA1: > >> - sha1_starts(&ctx); > >> - sha1_update(&ctx, input, length); > >> - sha1_finish(&ctx, final); > >> - break; > >> - case TPM2_ALG_SHA256: > >> - sha256_starts(&ctx_256); > >> - sha256_update(&ctx_256, input, length); > >> - sha256_finish(&ctx_256, final); > >> - break; > >> - case TPM2_ALG_SHA384: > >> - sha384_starts(&ctx_512); > >> - sha384_update(&ctx_512, input, length); > >> - sha384_finish(&ctx_512, final); > >> - break; > >> - case TPM2_ALG_SHA512: > >> - sha512_starts(&ctx_512); > >> - sha512_update(&ctx_512, input, length); > >> - sha512_finish(&ctx_512, final); > >> - break; > >> - default: > >> - EFI_PRINT("Unsupported algorithm %x\n", > hash_alg); > >> - return EFI_INVALID_PARAMETER; > >> - } > >> - digest_list->digests[digest_list->count].hash_alg = > hash_alg; > >> - > memcpy(&digest_list->digests[digest_list->count].digest, final, > >> - (u32)alg_to_len(hash_alg)); > >> - digest_list->count++; > >> - } > >> - > >> - return EFI_SUCCESS; > >> -} > >> - > >> /** > >> * efi_tcg2_get_capability() - protocol capability information and > state information > >> * > >> @@ -759,7 +258,7 @@ efi_tcg2_get_capability(struct efi_tcg2_protocol > *this, > >> capability->protocol_version.major = 1; > >> capability->protocol_version.minor = 1; > >> > >> - efi_ret = platform_get_tpm2_device(&dev); > >> + efi_ret = tcg2_platform_get_tpm2(&dev); > >> if (efi_ret != EFI_SUCCESS) { > >> capability->supported_event_logs = 0; > >> capability->hash_algorithm_bitmap = 0; > >> @@ -855,7 +354,7 @@ efi_tcg2_get_eventlog(struct efi_tcg2_protocol > *this, > >> goto out; > >> } > >> > >> - ret = platform_get_tpm2_device(&dev); > >> + ret = tcg2_platform_get_tpm2(&dev); > >> if (ret != EFI_SUCCESS) { > >> event_log_location = NULL; > >> event_log_last_entry = NULL; > >> @@ -890,6 +389,7 @@ static efi_status_t tcg2_hash_pe_image(void *efi, > u64 efi_size, > >> struct efi_image_regions *regs = NULL; > >> void *new_efi = NULL; > >> u8 hash[TPM2_SHA512_DIGEST_SIZE]; > >> + struct udevice *dev; > >> efi_status_t ret; > >> u32 active; > >> int i; > >> @@ -905,16 +405,20 @@ static efi_status_t tcg2_hash_pe_image(void *efi, > u64 efi_size, > >> goto out; > >> } > >> > >> - ret = __get_active_pcr_banks(&active); > >> + ret = tcg2_platform_get_tpm2(&dev); > >> + if (ret != EFI_SUCCESS) > >> + goto out; > >> + > >> + ret = tcg2_get_active_pcr_banks(dev, &active); > >> if (ret != EFI_SUCCESS) { > >> goto out; > >> } > >> > >> digest_list->count = 0; > >> - for (i = 0; i < MAX_HASH_COUNT; i++) { > >> - u16 hash_alg = hash_algo_list[i].hash_alg; > >> + for (i = 0; i < ARRAY_SIZE(tpm2_supported_algorithms); i++) { > >> + u16 hash_alg = tpm2_supported_algorithms[i]; > >> > >> - if (!(active & alg_to_mask(hash_alg))) > >> + if (!(active & tpm2_algorithm_to_mask(hash_alg))) > >> continue; > >> switch (hash_alg) { > >> case TPM2_ALG_SHA1: > >> @@ -935,7 +439,7 @@ static efi_status_t tcg2_hash_pe_image(void *efi, > u64 efi_size, > >> } > >> digest_list->digests[digest_list->count].hash_alg = > hash_alg; > >> > memcpy(&digest_list->digests[digest_list->count].digest, hash, > >> - (u32)alg_to_len(hash_alg)); > >> + (u32)tpm2_algorithm_to_len(hash_alg)); > >> digest_list->count++; > >> } > >> > >> @@ -975,7 +479,7 @@ efi_status_t tcg2_measure_pe_image(void *efi, u64 > efi_size, > >> if (!is_tcg2_protocol_installed()) > >> return EFI_SUCCESS; > >> > >> - ret = platform_get_tpm2_device(&dev); > >> + ret = tcg2_platform_get_tpm2(&dev); > >> if (ret != EFI_SUCCESS) > >> return EFI_SECURITY_VIOLATION; > >> > >> @@ -1084,7 +588,7 @@ efi_tcg2_hash_log_extend_event(struct > efi_tcg2_protocol *this, u64 flags, > >> goto out; > >> } > >> > >> - ret = platform_get_tpm2_device(&dev); > >> + ret = tcg2_platform_get_tpm2(&dev); > >> if (ret != EFI_SUCCESS) > >> goto out; > >> > >> @@ -1119,7 +623,7 @@ efi_tcg2_hash_log_extend_event(struct > efi_tcg2_protocol *this, u64 flags, > >> ret = tcg2_hash_pe_image((void > *)(uintptr_t)data_to_hash, > >> data_to_hash_len, > &digest_list); > >> } else { > >> - ret = tcg2_create_digest((u8 *)(uintptr_t)data_to_hash, > >> + ret = tcg2_create_digest(dev, (u8 > *)(uintptr_t)data_to_hash, > >> data_to_hash_len, > &digest_list); > >> } > >> > >> @@ -1182,7 +686,7 @@ efi_tcg2_submit_command(struct efi_tcg2_protocol > *this, > >> goto out; > >> } > >> > >> - ret = platform_get_tpm2_device(&dev); > >> + ret = tcg2_platform_get_tpm2(&dev); > >> if (ret != EFI_SUCCESS) > >> goto out; > >> > >> @@ -1211,6 +715,7 @@ static efi_status_t EFIAPI > >> efi_tcg2_get_active_pcr_banks(struct efi_tcg2_protocol *this, > >> u32 *active_pcr_banks) > >> { > >> + struct udevice *dev; > >> efi_status_t ret; > >> > >> if (!this || !active_pcr_banks) { > >> @@ -1218,8 +723,12 @@ efi_tcg2_get_active_pcr_banks(struct > efi_tcg2_protocol *this, > >> goto out; > >> } > >> > >> + ret = tcg2_platform_get_tpm2(&dev); > >> + if (ret != EFI_SUCCESS) > >> + goto out; > >> + > >> EFI_ENTRY("%p, %p", this, active_pcr_banks); > >> - ret = __get_active_pcr_banks(active_pcr_banks); > >> + ret = tcg2_get_active_pcr_banks(dev, active_pcr_banks); > >> > >> out: > >> return EFI_EXIT(ret); > >> @@ -1270,397 +779,6 @@ static const struct efi_tcg2_protocol > efi_tcg2_protocol = { > >> .get_result_of_set_active_pcr_banks = > efi_tcg2_get_result_of_set_active_pcr_banks, > >> }; > >> > >> -/** > >> - * parse_event_log_header() - Parse and verify the event log header > fields > >> - * > >> - * @buffer: Pointer to the start of the eventlog > >> - * @size: Size of the eventlog > >> - * @pos: Return offset of the next event in > buffer right > >> - * after the event header i.e specID > >> - * > >> - * Return: status code > >> - */ > >> -static efi_status_t parse_event_log_header(void *buffer, u32 size, u32 > *pos) > >> -{ > >> - struct tcg_pcr_event *event_header = (struct tcg_pcr_event > *)buffer; > >> - int i = 0; > >> - > >> - if (size < sizeof(*event_header)) > >> - return EFI_COMPROMISED_DATA; > >> - > >> - if (get_unaligned_le32(&event_header->pcr_index) != 0 || > >> - get_unaligned_le32(&event_header->event_type) != > EV_NO_ACTION) > >> - return EFI_COMPROMISED_DATA; > >> - > >> - for (i = 0; i < sizeof(event_header->digest); i++) { > >> - if (event_header->digest[i]) > >> - return EFI_COMPROMISED_DATA; > >> - } > >> - > >> - *pos += sizeof(*event_header); > >> - > >> - return EFI_SUCCESS; > >> -} > >> - > >> -/** > >> - * parse_specid_event() - Parse and verify the specID Event in the > eventlog > >> - * > >> - * @dev: udevice > >> - * @buffer: Pointer to the start of the eventlog > >> - * @log_size: Size of the eventlog > >> - * @pos: [in] Offset of specID event in the eventlog > buffer > >> - * [out] Return offset of the next event in the > buffer > >> - * after the specID > >> - * @digest_list: list of digests in the event > >> - * > >> - * Return: status code > >> - * @pos Offset in the eventlog where the specID > event ends > >> - * @digest_list: list of digests in the event > >> - */ > >> -static efi_status_t parse_specid_event(struct udevice *dev, void > *buffer, > >> - u32 log_size, u32 *pos, > >> - struct tpml_digest_values > *digest_list) > >> -{ > >> - struct tcg_efi_spec_id_event *spec_event; > >> - struct tcg_pcr_event *event_header = (struct tcg_pcr_event > *)buffer; > >> - size_t spec_event_size; > >> - u32 active = 0, supported = 0, pcr_count = 0, alg_count = 0; > >> - u32 spec_active = 0; > >> - u16 hash_alg; > >> - u8 vendor_sz; > >> - int err, i; > >> - > >> - if (*pos >= log_size || (*pos + sizeof(*spec_event)) > log_size) > >> - return EFI_COMPROMISED_DATA; > >> - > >> - /* Check specID event data */ > >> - spec_event = (struct tcg_efi_spec_id_event *)((uintptr_t)buffer > + *pos); > >> - /* Check for signature */ > >> - if (memcmp(spec_event->signature, > TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03, > >> - sizeof(TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03))) { > >> - log_err("specID Event: Signature mismatch\n"); > >> - return EFI_COMPROMISED_DATA; > >> - } > >> - > >> - if (spec_event->spec_version_minor != > >> - TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 || > >> - spec_event->spec_version_major != > >> - TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2) > >> - return EFI_COMPROMISED_DATA; > >> - > >> - if (spec_event->number_of_algorithms > MAX_HASH_COUNT || > >> - spec_event->number_of_algorithms < 1) { > >> - log_err("specID Event: Number of algorithms > incorrect\n"); > >> - return EFI_COMPROMISED_DATA; > >> - } > >> - > >> - alg_count = spec_event->number_of_algorithms; > >> - > >> - err = tpm2_get_pcr_info(dev, &supported, &active, &pcr_count); > >> - if (err) > >> - return EFI_DEVICE_ERROR; > >> - > >> - digest_list->count = 0; > >> - /* > >> - * We have to take care that the sequence of algorithms that we > record > >> - * in digest_list matches the sequence in eventlog. > >> - */ > >> - for (i = 0; i < alg_count; i++) { > >> - hash_alg = > >> - > get_unaligned_le16(&spec_event->digest_sizes[i].algorithm_id); > >> - > >> - if (!(supported & alg_to_mask(hash_alg))) { > >> - log_err("specID Event: Unsupported > algorithm\n"); > >> - return EFI_COMPROMISED_DATA; > >> - } > >> - digest_list->digests[digest_list->count++].hash_alg = > hash_alg; > >> - > >> - spec_active |= alg_to_mask(hash_alg); > >> - } > >> - > >> - /* > >> - * TCG specification expects the event log to have hashes for > all > >> - * active PCR's > >> - */ > >> - if (spec_active != active) { > >> - /* > >> - * Previous stage bootloader should know all the active > PCR's > >> - * and use them in the Eventlog. > >> - */ > >> - log_err("specID Event: All active hash alg not > present\n"); > >> - return EFI_COMPROMISED_DATA; > >> - } > >> - > >> - /* > >> - * the size of the spec event and placement of vendor_info_size > >> - * depends on supported algoriths > >> - */ > >> - spec_event_size = > >> - offsetof(struct tcg_efi_spec_id_event, digest_sizes) + > >> - alg_count * sizeof(spec_event->digest_sizes[0]); > >> - > >> - if (*pos + spec_event_size >= log_size) > >> - return EFI_COMPROMISED_DATA; > >> - > >> - vendor_sz = *(uint8_t *)((uintptr_t)buffer + *pos + > spec_event_size); > >> - > >> - spec_event_size += sizeof(vendor_sz) + vendor_sz; > >> - *pos += spec_event_size; > >> - > >> - if (get_unaligned_le32(&event_header->event_size) != > spec_event_size) { > >> - log_err("specID event: header event size mismatch\n"); > >> - /* Right way to handle this can be to call SetActive > PCR's */ > >> - return EFI_COMPROMISED_DATA; > >> - } > >> - > >> - return EFI_SUCCESS; > >> -} > >> - > >> -/** > >> - * tcg2_parse_event() - Parse the event in the eventlog > >> - * > >> - * @dev: udevice > >> - * @buffer: Pointer to the start of the eventlog > >> - * @log_size: Size of the eventlog > >> - * @offset: [in] Offset of the event in the eventlog buffer > >> - * [out] Return offset of the next event in the > buffer > >> - * @digest_list: list of digests in the event > >> - * @pcr Index of the PCR in the event > >> - * > >> - * Return: status code > >> - */ > >> -static efi_status_t tcg2_parse_event(struct udevice *dev, void *buffer, > >> - u32 log_size, u32 *offset, > >> - struct tpml_digest_values > *digest_list, > >> - u32 *pcr) > >> -{ > >> - struct tcg_pcr_event2 *event = NULL; > >> - u32 count, size, event_size; > >> - size_t pos; > >> - > >> - event_size = tcg_event_final_size(digest_list); > >> - if (*offset >= log_size || *offset + event_size > log_size) { > >> - log_err("Event exceeds log size\n"); > >> - return EFI_COMPROMISED_DATA; > >> - } > >> - > >> - event = (struct tcg_pcr_event2 *)((uintptr_t)buffer + *offset); > >> - *pcr = get_unaligned_le32(&event->pcr_index); > >> - > >> - /* get the count */ > >> - count = get_unaligned_le32(&event->digests.count); > >> - if (count != digest_list->count) > >> - return EFI_COMPROMISED_DATA; > >> - > >> - pos = offsetof(struct tcg_pcr_event2, digests); > >> - pos += offsetof(struct tpml_digest_values, digests); > >> - > >> - for (int i = 0; i < digest_list->count; i++) { > >> - u16 alg; > >> - u16 hash_alg = digest_list->digests[i].hash_alg; > >> - u8 *digest = (u8 *)&digest_list->digests[i].digest; > >> - > >> - alg = get_unaligned_le16((void *)((uintptr_t)event + > pos)); > >> - > >> - if (alg != hash_alg) > >> - return EFI_COMPROMISED_DATA; > >> - > >> - pos += offsetof(struct tpmt_ha, digest); > >> - memcpy(digest, (void *)((uintptr_t)event + pos), > alg_to_len(hash_alg)); > >> - pos += alg_to_len(hash_alg); > >> - } > >> - > >> - size = get_unaligned_le32((void *)((uintptr_t)event + pos)); > >> - event_size += size; > >> - pos += sizeof(u32); /* tcg_pcr_event2 event_size*/ > >> - pos += size; > >> - > >> - /* make sure the calculated buffer is what we checked against */ > >> - if (pos != event_size) > >> - return EFI_COMPROMISED_DATA; > >> - > >> - if (pos > log_size) > >> - return EFI_COMPROMISED_DATA; > >> - > >> - *offset += pos; > >> - > >> - return EFI_SUCCESS; > >> -} > >> - > >> -/** > >> - * tcg2_get_fw_eventlog() - Get the eventlog address and size > >> - * > >> - * If the previous firmware has passed some eventlog, this function > get it's > >> - * location and check for it's validity. > >> - * > >> - * @dev: udevice > >> - * @log_buffer: eventlog address > >> - * @log_sz: eventlog size > >> - * > >> - * Return: status code > >> - */ > >> -static efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void > *log_buffer, > >> - size_t *log_sz) > >> -{ > >> - struct tpml_digest_values digest_list; > >> - void *buffer; > >> - efi_status_t ret; > >> - u32 pcr, pos; > >> - u64 base; > >> - u32 sz; > >> - bool extend_pcr = false; > >> - int i; > >> - > >> - ret = platform_get_eventlog(dev, &base, &sz); > >> - if (ret != EFI_SUCCESS) > >> - return ret; > >> - > >> - if (sz > TPM2_EVENT_LOG_SIZE) > >> - return EFI_VOLUME_FULL; > >> - > >> - buffer = (void *)(uintptr_t)base; > >> - pos = 0; > >> - /* Parse the eventlog to check for its validity */ > >> - ret = parse_event_log_header(buffer, sz, &pos); > >> - if (ret) > >> - return ret; > >> - > >> - ret = parse_specid_event(dev, buffer, sz, &pos, &digest_list); > >> - if (ret) { > >> - log_err("Error parsing SPEC ID Event\n"); > >> - return ret; > >> - } > >> - > >> - 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 hash_buf[TPM2_SHA512_DIGEST_SIZE] = { 0 }; > >> - u16 hash_alg = digest_list.digests[i].hash_alg; > >> - > >> - if (!memcmp((u8 *)&digest_list.digests[i].digest, > hash_buf, > >> - alg_to_len(hash_alg))) > >> - extend_pcr = true; > >> - } > >> - > >> - while (pos < sz) { > >> - ret = tcg2_parse_event(dev, buffer, sz, &pos, > &digest_list, > >> - &pcr); > >> - if (ret) { > >> - 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); > >> - *log_sz = sz; > >> - > >> - return ret; > >> -} > >> - > >> -/** > >> - * create_specid_event() - Create the first event in the eventlog > >> - * > >> - * @dev: tpm device > >> - * @event_header: Pointer to the final event header > >> - * @event_size: final spec event size > >> - * > >> - * Return: status code > >> - */ > >> -static efi_status_t create_specid_event(struct udevice *dev, void > *buffer, > >> - size_t *event_size) > >> -{ > >> - struct tcg_efi_spec_id_event *spec_event; > >> - size_t spec_event_size; > >> - efi_status_t ret = EFI_DEVICE_ERROR; > >> - u32 active = 0, supported = 0, pcr_count = 0, alg_count = 0; > >> - int err; > >> - size_t i; > >> - > >> - /* > >> - * Create Spec event. This needs to be the first event in the > log > >> - * according to the TCG EFI protocol spec > >> - */ > >> - > >> - /* Setup specID event data */ > >> - spec_event = (struct tcg_efi_spec_id_event *)buffer; > >> - memcpy(spec_event->signature, > TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03, > >> - sizeof(spec_event->signature)); > >> - put_unaligned_le32(0, &spec_event->platform_class); /* type > client */ > >> - spec_event->spec_version_minor = > >> - TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2; > >> - spec_event->spec_version_major = > >> - TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2; > >> - spec_event->spec_errata = > >> - TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2; > >> - spec_event->uintn_size = sizeof(efi_uintn_t) / sizeof(u32); > >> - > >> - err = tpm2_get_pcr_info(dev, &supported, &active, &pcr_count); > >> - > >> - if (err) > >> - goto out; > >> - > >> - for (i = 0; i < pcr_count; i++) { > >> - u16 hash_alg = hash_algo_list[i].hash_alg; > >> - u16 hash_len = hash_algo_list[i].hash_len; > >> - > >> - if (active & alg_to_mask(hash_alg)) { > >> - put_unaligned_le16(hash_alg, > >> - > &spec_event->digest_sizes[alg_count].algorithm_id); > >> - put_unaligned_le16(hash_len, > >> - > &spec_event->digest_sizes[alg_count].digest_size); > >> - alg_count++; > >> - } > >> - } > >> - > >> - spec_event->number_of_algorithms = alg_count; > >> - if (spec_event->number_of_algorithms > MAX_HASH_COUNT || > >> - spec_event->number_of_algorithms < 1) > >> - goto out; > >> - > >> - /* > >> - * the size of the spec event and placement of vendor_info_size > >> - * depends on supported algoriths > >> - */ > >> - spec_event_size = > >> - offsetof(struct tcg_efi_spec_id_event, digest_sizes) + > >> - spec_event->number_of_algorithms * > sizeof(spec_event->digest_sizes[0]); > >> - /* no vendor info for us */ > >> - memset(buffer + spec_event_size, 0, 1); > >> - /* add a byte for vendor_info_size in the spec event */ > >> - spec_event_size += 1; > >> - *event_size = spec_event_size; > >> - > >> - return EFI_SUCCESS; > >> - > >> -out: > >> - return ret; > >> -} > >> - > >> /** > >> * tcg2_uninit - remove the final event table and free efi memory on > failures > >> */ > >> @@ -1722,7 +840,7 @@ out: > >> } > >> > >> /** > >> - * tcg2_measure_event() - common function to add event log and extend > PCR > >> + * measure_event() - common function to add event log and extend PCR > >> * > >> * @dev: TPM device > >> * @pcr_index: PCR index > >> @@ -1732,14 +850,13 @@ out: > >> * > >> * Return: status code > >> */ > >> -static efi_status_t > >> -tcg2_measure_event(struct udevice *dev, u32 pcr_index, u32 event_type, > >> - u32 size, u8 event[]) > >> +static efi_status_t measure_event(struct udevice *dev, u32 pcr_index, > >> + u32 event_type, u32 size, u8 event[]) > >> { > >> struct tpml_digest_values digest_list; > >> efi_status_t ret; > >> > >> - ret = tcg2_create_digest(event, size, &digest_list); > >> + ret = tcg2_create_digest(dev, event, size, &digest_list); > >> if (ret != EFI_SUCCESS) > >> goto out; > >> > >> @@ -1766,9 +883,8 @@ static efi_status_t > efi_append_scrtm_version(struct udevice *dev) > >> { > >> efi_status_t ret; > >> > >> - ret = tcg2_measure_event(dev, 0, EV_S_CRTM_VERSION, > >> - strlen(version_string) + 1, > >> - (u8 *)version_string); > >> + ret = measure_event(dev, 0, EV_S_CRTM_VERSION, > >> + strlen(version_string) + 1, (u8 > *)version_string); > >> > >> return ret; > >> } > >> @@ -1784,12 +900,11 @@ static efi_status_t efi_init_event_log(void) > >> * vendor_info_size is currently set to 0, we need to change > the length > >> * and allocate the flexible array member if this changes > >> */ > >> - struct tcg_pcr_event *event_header = NULL; > >> + struct tcg2_event_log elog; > >> struct udevice *dev; > >> - size_t spec_event_size; > >> efi_status_t ret; > >> > >> - ret = platform_get_tpm2_device(&dev); > >> + ret = tcg2_platform_get_tpm2(&dev); > >> if (ret != EFI_SUCCESS) > >> return ret; > >> > >> @@ -1808,7 +923,6 @@ static efi_status_t efi_init_event_log(void) > >> * The log header is defined to be in SHA1 event log entry > format. > >> * Setup event header > >> */ > >> - event_header = (struct tcg_pcr_event *)event_log.buffer; > >> event_log.pos = 0; > >> event_log.last_event_size = 0; > >> event_log.get_event_called = false; > >> @@ -1819,34 +933,20 @@ static efi_status_t efi_init_event_log(void) > >> * Check if earlier firmware have passed any eventlog. > Different > >> * platforms can use different ways to do so. > >> */ > >> - ret = tcg2_get_fw_eventlog(dev, event_log.buffer, > &event_log.pos); > >> + elog.log = event_log.buffer; > >> + elog.log_size = TPM2_EVENT_LOG_SIZE; > >> + ret = tcg2_log_prepare_buffer(dev, &elog, false); > >> + if (ret != EFI_SUCCESS) > >> + goto free_pool; > >> + > >> + event_log.pos = elog.log_position; > >> + > >> /* > >> - * If earlier firmware hasn't passed any eventlog, go ahead and > >> - * create the eventlog header. > >> + * Add SCRTM version to the log if previous firmmware > >> + * doesn't pass an eventlog. > >> */ > >> - if (ret == EFI_NOT_FOUND) { > >> - put_unaligned_le32(0, &event_header->pcr_index); > >> - put_unaligned_le32(EV_NO_ACTION, > &event_header->event_type); > >> - memset(&event_header->digest, 0, > sizeof(event_header->digest)); > >> - ret = create_specid_event(dev, > >> - (void > *)((uintptr_t)event_log.buffer + > >> - > sizeof(*event_header)), > >> - &spec_event_size); > >> - if (ret != EFI_SUCCESS) > >> - goto free_pool; > >> - put_unaligned_le32(spec_event_size, > &event_header->event_size); > >> - event_log.pos = spec_event_size + sizeof(*event_header); > >> - event_log.last_event_size = event_log.pos; > >> - > >> - /* > >> - * Add SCRTM version to the log if previous firmmware > >> - * doesn't pass an eventlog. > >> - */ > >> + if (!elog.found) > >> ret = efi_append_scrtm_version(dev); > >> - } > >> - > >> - if (ret != EFI_SUCCESS) > >> - goto free_pool; > >> > >> ret = create_final_event(); > >> if (ret != EFI_SUCCESS) > >> @@ -1899,8 +999,8 @@ static efi_status_t tcg2_measure_variable(struct > udevice *dev, u32 pcr_index, > >> memcpy((u16 *)event->unicode_name + > event->unicode_name_length, > >> data, data_size); > >> } > >> - ret = tcg2_measure_event(dev, pcr_index, event_type, event_size, > >> - (u8 *)event); > >> + ret = measure_event(dev, pcr_index, event_type, event_size, > >> + (u8 *)event); > >> free(event); > >> return ret; > >> } > >> @@ -2011,8 +1111,8 @@ tcg2_measure_smbios(struct udevice *dev, > >> > >> smbios_prepare_measurement(entry, smbios_copy); > >> > >> - ret = tcg2_measure_event(dev, 1, EV_EFI_HANDOFF_TABLES2, > event_size, > >> - (u8 *)event); > >> + ret = measure_event(dev, 1, EV_EFI_HANDOFF_TABLES2, event_size, > >> + (u8 *)event); > >> if (ret != EFI_SUCCESS) > >> goto out; > >> > >> @@ -2163,7 +1263,7 @@ tcg2_measure_gpt_data(struct udevice *dev, > >> gpt_e = (gpt_entry *)((u8 *)gpt_e + > gpt_h->sizeof_partition_entry); > >> } > >> > >> - ret = tcg2_measure_event(dev, 5, EV_EFI_GPT_EVENT, event_size, > (u8 *)event); > >> + ret = measure_event(dev, 5, EV_EFI_GPT_EVENT, event_size, (u8 > *)event); > >> > >> out2: > >> free(gpt_h); > >> @@ -2217,7 +1317,7 @@ efi_status_t efi_tcg2_measure_dtb(void *dtb) > >> if (!is_tcg2_protocol_installed()) > >> return EFI_SUCCESS; > >> > >> - ret = platform_get_tpm2_device(&dev); > >> + ret = tcg2_platform_get_tpm2(&dev); > >> if (ret != EFI_SUCCESS) > >> return EFI_SECURITY_VIOLATION; > >> > >> @@ -2242,7 +1342,7 @@ efi_status_t efi_tcg2_measure_dtb(void *dtb) > >> sha256_update(&hash_ctx, (u8 *)dtb + fdt_off_mem_rsvmap(dtb), > rsvmap_size); > >> sha256_finish(&hash_ctx, blob->data + > blob->blob_description_size); > >> > >> - ret = tcg2_measure_event(dev, 0, EV_POST_CODE, event_size, (u8 > *)blob); > >> + ret = measure_event(dev, 0, EV_POST_CODE, event_size, (u8 > *)blob); > >> > >> free(blob); > >> return ret; > >> @@ -2267,7 +1367,7 @@ efi_status_t > efi_tcg2_measure_efi_app_invocation(struct efi_loaded_image_obj *ha > >> if (tcg2_efi_app_invoked) > >> return EFI_SUCCESS; > >> > >> - ret = platform_get_tpm2_device(&dev); > >> + ret = tcg2_platform_get_tpm2(&dev); > >> if (ret != EFI_SUCCESS) > >> return EFI_SECURITY_VIOLATION; > >> > >> @@ -2275,9 +1375,9 @@ efi_status_t > efi_tcg2_measure_efi_app_invocation(struct efi_loaded_image_obj *ha > >> if (ret != EFI_SUCCESS) > >> goto out; > >> > >> - ret = tcg2_measure_event(dev, 4, EV_EFI_ACTION, > >> - strlen(EFI_CALLING_EFI_APPLICATION), > >> - (u8 *)EFI_CALLING_EFI_APPLICATION); > >> + ret = measure_event(dev, 4, EV_EFI_ACTION, > >> + strlen(EFI_CALLING_EFI_APPLICATION), > >> + (u8 *)EFI_CALLING_EFI_APPLICATION); > >> if (ret != EFI_SUCCESS) > >> goto out; > >> > >> @@ -2293,8 +1393,8 @@ efi_status_t > efi_tcg2_measure_efi_app_invocation(struct efi_loaded_image_obj *ha > >> goto out; > >> > >> for (pcr_index = 0; pcr_index <= 7; pcr_index++) { > >> - ret = tcg2_measure_event(dev, pcr_index, EV_SEPARATOR, > >> - sizeof(event), (u8 *)&event); > >> + ret = measure_event(dev, pcr_index, EV_SEPARATOR, > >> + sizeof(event), (u8 *)&event); > >> if (ret != EFI_SUCCESS) > >> goto out; > >> } > >> @@ -2317,13 +1417,13 @@ efi_status_t efi_tcg2_measure_efi_app_exit(void) > >> if (!is_tcg2_protocol_installed()) > >> return EFI_SUCCESS; > >> > >> - ret = platform_get_tpm2_device(&dev); > >> + ret = tcg2_platform_get_tpm2(&dev); > >> if (ret != EFI_SUCCESS) > >> return ret; > >> > >> - ret = tcg2_measure_event(dev, 4, EV_EFI_ACTION, > >> - > strlen(EFI_RETURNING_FROM_EFI_APPLICATION), > >> - (u8 > *)EFI_RETURNING_FROM_EFI_APPLICATION); > >> + ret = measure_event(dev, 4, EV_EFI_ACTION, > >> + strlen(EFI_RETURNING_FROM_EFI_APPLICATION), > >> + (u8 *)EFI_RETURNING_FROM_EFI_APPLICATION); > >> return ret; > >> } > >> > >> @@ -2348,19 +1448,19 @@ efi_tcg2_notify_exit_boot_services(struct > efi_event *event, void *context) > >> goto out; > >> } > >> > >> - ret = platform_get_tpm2_device(&dev); > >> + ret = tcg2_platform_get_tpm2(&dev); > >> if (ret != EFI_SUCCESS) > >> goto out; > >> > >> - ret = tcg2_measure_event(dev, 5, EV_EFI_ACTION, > >> - > strlen(EFI_EXIT_BOOT_SERVICES_INVOCATION), > >> - (u8 > *)EFI_EXIT_BOOT_SERVICES_INVOCATION); > >> + ret = measure_event(dev, 5, EV_EFI_ACTION, > >> + strlen(EFI_EXIT_BOOT_SERVICES_INVOCATION), > >> + (u8 *)EFI_EXIT_BOOT_SERVICES_INVOCATION); > >> if (ret != EFI_SUCCESS) > >> goto out; > >> > >> - ret = tcg2_measure_event(dev, 5, EV_EFI_ACTION, > >> - > strlen(EFI_EXIT_BOOT_SERVICES_SUCCEEDED), > >> - (u8 > *)EFI_EXIT_BOOT_SERVICES_SUCCEEDED); > >> + ret = measure_event(dev, 5, EV_EFI_ACTION, > >> + strlen(EFI_EXIT_BOOT_SERVICES_SUCCEEDED), > >> + (u8 *)EFI_EXIT_BOOT_SERVICES_SUCCEEDED); > >> > >> out: > >> EFI_EXIT(ret); > >> @@ -2380,19 +1480,19 @@ efi_status_t > efi_tcg2_notify_exit_boot_services_failed(void) > >> if (!is_tcg2_protocol_installed()) > >> return EFI_SUCCESS; > >> > >> - ret = platform_get_tpm2_device(&dev); > >> + ret = tcg2_platform_get_tpm2(&dev); > >> if (ret != EFI_SUCCESS) > >> goto out; > >> > >> - ret = tcg2_measure_event(dev, 5, EV_EFI_ACTION, > >> - > strlen(EFI_EXIT_BOOT_SERVICES_INVOCATION), > >> - (u8 > *)EFI_EXIT_BOOT_SERVICES_INVOCATION); > >> + ret = measure_event(dev, 5, EV_EFI_ACTION, > >> + strlen(EFI_EXIT_BOOT_SERVICES_INVOCATION), > >> + (u8 *)EFI_EXIT_BOOT_SERVICES_INVOCATION); > >> if (ret != EFI_SUCCESS) > >> goto out; > >> > >> - ret = tcg2_measure_event(dev, 5, EV_EFI_ACTION, > >> - strlen(EFI_EXIT_BOOT_SERVICES_FAILED), > >> - (u8 *)EFI_EXIT_BOOT_SERVICES_FAILED); > >> + ret = measure_event(dev, 5, EV_EFI_ACTION, > >> + strlen(EFI_EXIT_BOOT_SERVICES_FAILED), > >> + (u8 *)EFI_EXIT_BOOT_SERVICES_FAILED); > >> > >> out: > >> return ret; > >> @@ -2462,7 +1562,7 @@ efi_status_t efi_tcg2_do_initial_measurement(void) > >> if (!is_tcg2_protocol_installed()) > >> return EFI_SUCCESS; > >> > >> - ret = platform_get_tpm2_device(&dev); > >> + ret = tcg2_platform_get_tpm2(&dev); > >> if (ret != EFI_SUCCESS) > >> return EFI_SECURITY_VIOLATION; > >> > >> @@ -2488,7 +1588,7 @@ efi_status_t efi_tcg2_register(void) > >> struct efi_event *event; > >> u32 err; > >> > >> - ret = platform_get_tpm2_device(&dev); > >> + ret = tcg2_platform_get_tpm2(&dev); > >> if (ret != EFI_SUCCESS) { > >> log_warning("Missing TPMv2 device for > EFI_TCG_PROTOCOL\n"); > >> return EFI_SUCCESS; > >> diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c > >> index 9ab5b46df1..d22e21985b 100644 > >> --- a/lib/tpm-v2.c > >> +++ b/lib/tpm-v2.c > >> @@ -1,16 +1,705 @@ > >> // SPDX-License-Identifier: GPL-2.0+ > >> /* > >> + * Copyright (c) 2023 Linaro Limited > >> * Copyright (c) 2018 Bootlin > >> * Author: Miquel Raynal > >> */ > >> > >> #include > >> #include > >> +#include > >> +#include > >> #include > >> #include > >> +#include > >> +#include > >> +#include > >> +#include > >> +#include > >> #include > >> +#include > >> +#include > >> +#include > >> + > >> #include "tpm-utils.h" > >> > >> +const enum tpm2_algorithms tpm2_supported_algorithms[4] = { > >> + TPM2_ALG_SHA1, > >> + TPM2_ALG_SHA256, > >> + TPM2_ALG_SHA384, > >> + TPM2_ALG_SHA512, > >> +}; > >> + > >> +int tcg2_get_active_pcr_banks(struct udevice *dev, u32 > *active_pcr_banks) > >> +{ > >> + u32 supported = 0; > >> + u32 pcr_banks = 0; > >> + u32 active = 0; > >> + int rc; > >> + > >> + rc = tpm2_get_pcr_info(dev, &supported, &active, &pcr_banks); > >> + if (rc) > >> + return rc; > >> + > >> + *active_pcr_banks = active; > >> + > >> + return 0; > >> +} > >> + > >> +u32 tcg2_event_get_size(struct tpml_digest_values *digest_list) > >> +{ > >> + u32 len; > >> + size_t i; > >> + > >> + len = offsetof(struct tcg_pcr_event2, digests); > >> + len += offsetof(struct tpml_digest_values, digests); > >> + for (i = 0; i < digest_list->count; ++i) { > >> + u16 l = > tpm2_algorithm_to_len(digest_list->digests[i].hash_alg); > >> + > >> + if (!l) > >> + continue; > >> + > >> + len += l + offsetof(struct tpmt_ha, digest); > >> + } > >> + len += sizeof(u32); > >> + > >> + return len; > >> +} > >> + > >> +int tcg2_create_digest(struct udevice *dev, const u8 *input, u32 > length, > >> + struct tpml_digest_values *digest_list) > >> +{ > >> + u8 final[sizeof(union tpmu_ha)]; > >> + sha256_context ctx_256; > >> + sha512_context ctx_512; > >> + sha1_context ctx; > >> + u32 active; > >> + size_t i; > >> + u32 len; > >> + int rc; > >> + > >> + rc = tcg2_get_active_pcr_banks(dev, &active); > >> + if (rc) > >> + return rc; > >> + > >> + digest_list->count = 0; > >> + for (i = 0; i < ARRAY_SIZE(tpm2_supported_algorithms); ++i) { > >> + u32 mask = > >> + > tpm2_algorithm_to_mask(tpm2_supported_algorithms[i]); > >> + > >> + if (!(active & mask)) > >> + continue; > >> + > >> + switch (tpm2_supported_algorithms[i]) { > >> + case TPM2_ALG_SHA1: > >> + sha1_starts(&ctx); > >> + sha1_update(&ctx, input, length); > >> + sha1_finish(&ctx, final); > >> + len = TPM2_SHA1_DIGEST_SIZE; > >> + break; > >> + case TPM2_ALG_SHA256: > >> + sha256_starts(&ctx_256); > >> + sha256_update(&ctx_256, input, length); > >> + sha256_finish(&ctx_256, final); > >> + len = TPM2_SHA256_DIGEST_SIZE; > >> + break; > >> + case TPM2_ALG_SHA384: > >> + sha384_starts(&ctx_512); > >> + sha384_update(&ctx_512, input, length); > >> + sha384_finish(&ctx_512, final); > >> + len = TPM2_SHA384_DIGEST_SIZE; > >> + break; > >> + case TPM2_ALG_SHA512: > >> + sha512_starts(&ctx_512); > >> + sha512_update(&ctx_512, input, length); > >> + sha512_finish(&ctx_512, final); > >> + len = TPM2_SHA512_DIGEST_SIZE; > >> + break; > >> + default: > >> + printf("%s: unsupported algorithm %x\n", > __func__, > >> + tpm2_supported_algorithms[i]); > >> + continue; > >> + } > >> + > >> + digest_list->digests[digest_list->count].hash_alg = > >> + tpm2_supported_algorithms[i]; > >> + > memcpy(&digest_list->digests[digest_list->count].digest, final, > >> + len); > >> + digest_list->count++; > >> + } > >> + > >> + return 0; > >> +} > >> + > >> +void tcg2_log_append(u32 pcr_index, u32 event_type, > >> + struct tpml_digest_values *digest_list, u32 size, > >> + const u8 *event, u8 *log) > >> +{ > >> + size_t len; > >> + size_t pos; > >> + u32 i; > >> + > >> + pos = offsetof(struct tcg_pcr_event2, pcr_index); > >> + put_unaligned_le32(pcr_index, log); > >> + pos = offsetof(struct tcg_pcr_event2, event_type); > >> + put_unaligned_le32(event_type, log + pos); > >> + pos = offsetof(struct tcg_pcr_event2, digests) + > >> + offsetof(struct tpml_digest_values, count); > >> + put_unaligned_le32(digest_list->count, log + pos); > >> + > >> + pos = offsetof(struct tcg_pcr_event2, digests) + > >> + offsetof(struct tpml_digest_values, digests); > >> + for (i = 0; i < digest_list->count; ++i) { > >> + u16 hash_alg = digest_list->digests[i].hash_alg; > >> + > >> + len = tpm2_algorithm_to_len(hash_alg); > >> + if (!len) > >> + continue; > >> + > >> + pos += offsetof(struct tpmt_ha, hash_alg); > >> + put_unaligned_le16(hash_alg, log + pos); > >> + pos += offsetof(struct tpmt_ha, digest); > >> + memcpy(log + pos, (u8 > *)&digest_list->digests[i].digest, len); > >> + pos += len; > >> + } > >> + > >> + put_unaligned_le32(size, log + pos); > >> + pos += sizeof(u32); > >> + memcpy(log + pos, event, size); > >> +} > >> + > >> +static int tcg2_log_append_check(struct tcg2_event_log *elog, u32 > pcr_index, > >> + u32 event_type, > >> + struct tpml_digest_values *digest_list, > >> + u32 size, const u8 *event) > >> +{ > >> + u32 event_size; > >> + u8 *log; > >> + > >> + event_size = size + tcg2_event_get_size(digest_list); > >> + if (elog->log_position + event_size > elog->log_size) { > >> + printf("%s: log too large: %u + %u > %u\n", __func__, > >> + elog->log_position, event_size, elog->log_size); > >> + return -ENOBUFS; > >> + } > >> + > >> + log = elog->log + elog->log_position; > >> + elog->log_position += event_size; > >> + > >> + tcg2_log_append(pcr_index, event_type, digest_list, size, > event, log); > >> + > >> + return 0; > >> +} > >> + > >> +static int tcg2_log_init(struct udevice *dev, struct tcg2_event_log > *elog) > >> +{ > >> + struct tcg_efi_spec_id_event *ev; > >> + struct tcg_pcr_event *log; > >> + u32 event_size; > >> + u32 count = 0; > >> + u32 log_size; > >> + u32 active; > >> + u32 mask; > >> + size_t i; > >> + u16 len; > >> + int rc; > >> + > >> + rc = tcg2_get_active_pcr_banks(dev, &active); > >> + if (rc) > >> + return rc; > >> + > >> + event_size = offsetof(struct tcg_efi_spec_id_event, > digest_sizes); > >> + for (i = 0; i < ARRAY_SIZE(tpm2_supported_algorithms); ++i) { > >> + mask = > tpm2_algorithm_to_mask(tpm2_supported_algorithms[i]); > >> + > >> + if (!(active & mask)) > >> + continue; > >> + > >> + switch (tpm2_supported_algorithms[i]) { > >> + case TPM2_ALG_SHA1: > >> + case TPM2_ALG_SHA256: > >> + case TPM2_ALG_SHA384: > >> + case TPM2_ALG_SHA512: > >> + count++; > >> + break; > >> + default: > >> + continue; > >> + } > >> + } > >> + > >> + event_size += 1 + > >> + (sizeof(struct tcg_efi_spec_id_event_algorithm_size) * > count); > >> + log_size = offsetof(struct tcg_pcr_event, event) + event_size; > >> + > >> + if (log_size > elog->log_size) { > >> + printf("%s: log too large: %u > %u\n", __func__, > log_size, > >> + elog->log_size); > >> + return -ENOBUFS; > >>