On Wed, Jul 05, 2017 at 02:19:57PM -0700, Matthew Garrett wrote: > Add support for performing basic TPM measurements. Right now this only > supports extending PCRs statically and only on UEFI. > --- > grub-core/Makefile.core.def | 7 + > grub-core/commands/efi/tpm.c | 282 > +++++++++++++++++++++++++++++++++++++++++ > grub-core/commands/tpm.c | 87 +++++++++++++ > grub-core/kern/i386/efi/init.c | 1 + > include/grub/efi/tpm.h | 153 ++++++++++++++++++++++ > include/grub/tpm.h | 74 +++++++++++ > 6 files changed, 604 insertions(+) > create mode 100644 grub-core/commands/efi/tpm.c > create mode 100644 grub-core/commands/tpm.c > create mode 100644 include/grub/efi/tpm.h > create mode 100644 include/grub/tpm.h > > diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def > index 16c4d0ea5..ca1caa1fe 100644 > --- a/grub-core/Makefile.core.def > +++ b/grub-core/Makefile.core.def > @@ -2375,6 +2375,13 @@ module = { > common = commands/testspeed.c; > }; > > +module = { > + name = tpm; > + common = commands/tpm.c; > + efi = commands/efi/tpm.c; > + enable = efi; > +}; > + > module = { > name = tr; > common = commands/tr.c; > diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c > new file mode 100644 > index 000000000..c9fb3c133 > --- /dev/null > +++ b/grub-core/commands/efi/tpm.c > @@ -0,0 +1,282 @@ > +#include <grub/err.h> > +#include <grub/i18n.h> > +#include <grub/efi/api.h> > +#include <grub/efi/efi.h> > +#include <grub/efi/tpm.h> > +#include <grub/mm.h> > +#include <grub/tpm.h> > +#include <grub/term.h> > + > +static grub_efi_guid_t tpm_guid = EFI_TPM_GUID; > +static grub_efi_guid_t tpm2_guid = EFI_TPM2_GUID; > + > +static grub_efi_boolean_t grub_tpm_present(grub_efi_tpm_protocol_t *tpm) > +{ > + grub_efi_status_t status; > + TCG_EFI_BOOT_SERVICE_CAPABILITY caps; > + grub_uint32_t flags; > + grub_efi_physical_address_t eventlog, lastevent; > + > + caps.Size = (grub_uint8_t)sizeof(caps); > + > + status = efi_call_5(tpm->status_check, tpm, &caps, &flags, &eventlog, > + &lastevent); > + > + if (status != GRUB_EFI_SUCCESS || caps.TPMDeactivatedFlag > + || !caps.TPMPresentFlag) > + return 0; > + > + return 1; > +} > + > +static grub_efi_boolean_t grub_tpm2_present(grub_efi_tpm2_protocol_t *tpm) > +{ > + grub_efi_status_t status; > + EFI_TCG2_BOOT_SERVICE_CAPABILITY caps; > + > + caps.Size = (grub_uint8_t)sizeof(caps); > + > + status = efi_call_2(tpm->get_capability, tpm, &caps); > + > + if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag) > + return 0; > + > + return 1; > +} > + > +static grub_efi_boolean_t grub_tpm_handle_find(grub_efi_handle_t *tpm_handle, > + grub_efi_uint8_t > *protocol_version) > +{ > + grub_efi_handle_t *handles; > + grub_efi_uintn_t num_handles; > + > + handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm_guid, NULL, > + &num_handles); > + if (handles && num_handles > 0) { > + *tpm_handle = handles[0]; > + *protocol_version = 1; > + return 1; > + } > + > + handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm2_guid, NULL, > + &num_handles); > + if (handles && num_handles > 0) { > + *tpm_handle = handles[0]; > + *protocol_version = 2; > + return 1; > + } > + > + return 0; > +} > + > +static grub_err_t > +grub_tpm1_execute(grub_efi_handle_t tpm_handle, > + PassThroughToTPM_InputParamBlock *inbuf, > + PassThroughToTPM_OutputParamBlock *outbuf) > +{ > + grub_efi_status_t status; > + grub_efi_tpm_protocol_t *tpm; > + grub_uint32_t inhdrsize = sizeof(*inbuf) - sizeof(inbuf->TPMOperandIn); > + grub_uint32_t outhdrsize = sizeof(*outbuf) - sizeof(outbuf->TPMOperandOut); > + > + tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid, > + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); > + > + if (!grub_tpm_present(tpm)) > + return 0; > + > + /* UEFI TPM protocol takes the raw operand block, no param block header */ > + status = efi_call_5 (tpm->pass_through_to_tpm, tpm, > + inbuf->IPBLength - inhdrsize, inbuf->TPMOperandIn, > + outbuf->OPBLength - outhdrsize, outbuf->TPMOperandOut); > + > + switch (status) { > + case GRUB_EFI_SUCCESS: > + return 0; > + case GRUB_EFI_DEVICE_ERROR: > + return grub_error (GRUB_ERR_IO, N_("Command failed")); > + case GRUB_EFI_INVALID_PARAMETER: > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); > + case GRUB_EFI_BUFFER_TOO_SMALL: > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small")); > + case GRUB_EFI_NOT_FOUND: > + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); > + default: > + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); > + } > +} > + > +static grub_err_t > +grub_tpm2_execute(grub_efi_handle_t tpm_handle, > + PassThroughToTPM_InputParamBlock *inbuf, > + PassThroughToTPM_OutputParamBlock *outbuf) > +{ > + grub_efi_status_t status; > + grub_efi_tpm2_protocol_t *tpm; > + grub_uint32_t inhdrsize = sizeof(*inbuf) - sizeof(inbuf->TPMOperandIn); > + grub_uint32_t outhdrsize = sizeof(*outbuf) - sizeof(outbuf->TPMOperandOut); > + > + tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid, > + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); > + > + if (!grub_tpm2_present(tpm)) > + return 0; > + > + /* UEFI TPM protocol takes the raw operand block, no param block header */ > + status = efi_call_5 (tpm->submit_command, tpm, > + inbuf->IPBLength - inhdrsize, inbuf->TPMOperandIn, > + outbuf->OPBLength - outhdrsize, outbuf->TPMOperandOut); > + > + switch (status) { > + case GRUB_EFI_SUCCESS: > + return 0; > + case GRUB_EFI_DEVICE_ERROR: > + return grub_error (GRUB_ERR_IO, N_("Command failed")); > + case GRUB_EFI_INVALID_PARAMETER: > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); > + case GRUB_EFI_BUFFER_TOO_SMALL: > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small")); > + case GRUB_EFI_NOT_FOUND: > + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); > + default: > + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); > + } > +} > + > +grub_err_t > +grub_tpm_execute(PassThroughToTPM_InputParamBlock *inbuf, > + PassThroughToTPM_OutputParamBlock *outbuf) > +{ > + grub_efi_handle_t tpm_handle; > + grub_uint8_t protocol_version; > + > + /* It's not a hard failure for there to be no TPM */ > + if (!grub_tpm_handle_find(&tpm_handle, &protocol_version)) > + return 0; > + > + if (protocol_version == 1) { > + return grub_tpm1_execute(tpm_handle, inbuf, outbuf); > + } else { > + return grub_tpm2_execute(tpm_handle, inbuf, outbuf); > + } > +} > + > +typedef struct { > + grub_uint32_t pcrindex; > + grub_uint32_t eventtype; > + grub_uint8_t digest[20]; > + grub_uint32_t eventsize; > + grub_uint8_t event[1]; > +} Event;
The struct is the same with TCG_PCR_EVENT defined in efi/tpm.h, what's the point to locally redefine here ? > + > + > +static grub_err_t > +grub_tpm1_log_event(grub_efi_handle_t tpm_handle, unsigned char *buf, > + grub_size_t size, grub_uint8_t pcr, > + const char *description) > +{ > + Event *event; > + grub_efi_status_t status; > + grub_efi_tpm_protocol_t *tpm; > + grub_efi_physical_address_t lastevent; > + grub_uint32_t algorithm; > + grub_uint32_t eventnum = 0; > + > + tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid, > + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); > + > + if (!grub_tpm_present(tpm)) > + return 0; > + > + event = grub_zalloc(sizeof (Event) + grub_strlen(description) + 1); > + if (!event) > + return grub_error (GRUB_ERR_OUT_OF_MEMORY, > + N_("cannot allocate TPM event buffer")); > + > + event->pcrindex = pcr; > + event->eventtype = EV_IPL; > + event->eventsize = grub_strlen(description) + 1; > + grub_memcpy(event->event, description, event->eventsize); > + > + algorithm = TCG_ALG_SHA; > + status = efi_call_7 (tpm->log_extend_event, tpm, buf, (grub_uint64_t) size, > + algorithm, event, &eventnum, &lastevent); > + > + switch (status) { > + case GRUB_EFI_SUCCESS: > + return 0; > + case GRUB_EFI_DEVICE_ERROR: > + return grub_error (GRUB_ERR_IO, N_("Command failed")); > + case GRUB_EFI_INVALID_PARAMETER: > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); > + case GRUB_EFI_BUFFER_TOO_SMALL: > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small")); > + case GRUB_EFI_NOT_FOUND: > + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); > + default: > + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); > + } > +} > + > +static grub_err_t > +grub_tpm2_log_event(grub_efi_handle_t tpm_handle, unsigned char *buf, > + grub_size_t size, grub_uint8_t pcr, > + const char *description) > +{ > + EFI_TCG2_EVENT *event; > + grub_efi_status_t status; > + grub_efi_tpm2_protocol_t *tpm; > + > + tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid, > + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); > + > + if (!grub_tpm2_present(tpm)) > + return 0; > + > + event = grub_zalloc(sizeof (EFI_TCG2_EVENT) + grub_strlen(description) + > 1); > + if (!event) > + return grub_error (GRUB_ERR_OUT_OF_MEMORY, > + N_("cannot allocate TPM event buffer")); > + > + event->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER); > + event->Header.HeaderVersion = 1; > + event->Header.PCRIndex = pcr; > + event->Header.EventType = EV_IPL; > + event->Size = sizeof(*event) - sizeof(event->Event) + > grub_strlen(description) + 1; > + grub_memcpy(event->Event, description, grub_strlen(description) + 1); > + > + status = efi_call_5 (tpm->hash_log_extend_event, tpm, 0, buf, > + (grub_uint64_t) size, event); > + > + switch (status) { > + case GRUB_EFI_SUCCESS: > + return 0; > + case GRUB_EFI_DEVICE_ERROR: > + return grub_error (GRUB_ERR_IO, N_("Command failed")); > + case GRUB_EFI_INVALID_PARAMETER: > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); > + case GRUB_EFI_BUFFER_TOO_SMALL: > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small")); > + case GRUB_EFI_NOT_FOUND: > + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); > + default: > + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); > + } > +} > + > +grub_err_t > +grub_tpm_log_event(unsigned char *buf, grub_size_t size, grub_uint8_t pcr, > + const char *description) > +{ > + grub_efi_handle_t tpm_handle; > + grub_efi_uint8_t protocol_version; > + > + if (!grub_tpm_handle_find(&tpm_handle, &protocol_version)) > + return 0; > + > + if (protocol_version == 1) { > + return grub_tpm1_log_event(tpm_handle, buf, size, pcr, description); > + } else { > + return grub_tpm2_log_event(tpm_handle, buf, size, pcr, description); > + } > +} > diff --git a/grub-core/commands/tpm.c b/grub-core/commands/tpm.c > new file mode 100644 > index 000000000..e047b5fe0 > --- /dev/null > +++ b/grub-core/commands/tpm.c > @@ -0,0 +1,87 @@ > +#include <grub/err.h> > +#include <grub/i18n.h> > +#include <grub/misc.h> > +#include <grub/mm.h> > +#include <grub/tpm.h> > +#include <grub/term.h> > +#include <grub/verify.h> > +#include <grub/dl.h> > + > +GRUB_MOD_LICENSE ("GPLv3+") > + > +grub_err_t > +grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, > + const char *description) > +{ > + return grub_tpm_log_event (buf, size, pcr, description); > +} > + > +static grub_err_t > +grub_tpm_verify_init (grub_file_t io, > + enum grub_file_type type __attribute__ ((unused)), > + void **context, enum grub_verify_flags *flags) > +{ > + *context = io->name; > + *flags |= GRUB_VERIFY_FLAGS_SINGLE_CHUNK; > + return GRUB_ERR_NONE; > +} > + > +static grub_err_t > +grub_tpm_verify_write (void *context, void *buf, grub_size_t size) > +{ > + return grub_tpm_measure (buf, size, 9, context); > +} > + > +static void > +grub_tpm_verify_close (void *ctxt __attribute__ ((unused))) > +{ > + return; > +} > + > +static grub_err_t > +grub_tpm_verify_string (char *str, enum grub_verify_string_type type) > +{ > + const char *prefix = NULL; > + char *description; > + grub_err_t status; > + > + switch (type) > + { > + case GRUB_VERIFY_KERNEL_CMDLINE: > + prefix = "kernel_cmdline: "; > + break; > + case GRUB_VERIFY_MODULE_CMDLINE: > + prefix = "module_cmdline: "; > + break; > + case GRUB_VERIFY_COMMAND: > + prefix = "grub_cmd: "; > + break; > + } > + description = grub_malloc(grub_strlen(str) + grub_strlen(prefix) + 1); > + if (!description) > + return grub_errno; > + grub_memcpy(description, prefix, grub_strlen(prefix)); > + grub_memcpy(description + grub_strlen(prefix), str, grub_strlen(str) + 1); > + status = grub_tpm_measure ((unsigned char *) str, grub_strlen (str), 8, > + description); > + grub_free(description); > + return status; > +} > + > +struct grub_file_verifier grub_tpm_verifier = { > + .name = "tpm", > + .init = grub_tpm_verify_init, > + .write = grub_tpm_verify_write, > + .close = grub_tpm_verify_close, > + .verify_string = grub_tpm_verify_string, > +}; > + > +GRUB_MOD_INIT(tpm) > +{ > + grub_verifier_register (&grub_tpm_verifier); > +} > + > +GRUB_MOD_FINI(tpm) > +{ > + grub_verifier_unregister (&grub_tpm_verifier); > +} > diff --git a/grub-core/kern/i386/efi/init.c b/grub-core/kern/i386/efi/init.c > index a28316cc6..da499aba0 100644 > --- a/grub-core/kern/i386/efi/init.c > +++ b/grub-core/kern/i386/efi/init.c > @@ -27,6 +27,7 @@ > #include <grub/efi/efi.h> > #include <grub/i386/tsc.h> > #include <grub/loader.h> > +#include <grub/tpm.h> > > void > grub_machine_init (void) > diff --git a/include/grub/efi/tpm.h b/include/grub/efi/tpm.h > new file mode 100644 > index 000000000..e2aff4a3c > --- /dev/null > +++ b/include/grub/efi/tpm.h > @@ -0,0 +1,153 @@ > +/* > + * GRUB -- GRand Unified Bootloader > + * Copyright (C) 2015 Free Software Foundation, Inc. > + * > + * GRUB is free software: you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation, either version 3 of the License, or > + * (at your option) any later version. > + * > + * GRUB is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. > + */ > + > +#ifndef GRUB_EFI_TPM_HEADER > +#define GRUB_EFI_TPM_HEADER 1 > + > +#define EFI_TPM_GUID {0xf541796d, 0xa62e, 0x4954, {0xa7, 0x75, 0x95, 0x84, > 0xf6, 0x1b, 0x9c, 0xdd }}; > +#define EFI_TPM2_GUID {0x607f766c, 0x7455, 0x42be, {0x93, 0x0b, 0xe4, 0xd7, > 0x6d, 0xb2, 0x72, 0x0f }}; > + > +typedef struct { > + grub_efi_uint8_t Major; > + grub_efi_uint8_t Minor; > + grub_efi_uint8_t RevMajor; > + grub_efi_uint8_t RevMinor; > +} TCG_VERSION; > + > +typedef struct _TCG_EFI_BOOT_SERVICE_CAPABILITY { > + grub_efi_uint8_t Size; /// Size of this structure. > + TCG_VERSION StructureVersion; > + TCG_VERSION ProtocolSpecVersion; > + grub_efi_uint8_t HashAlgorithmBitmap; /// Hash algorithms . > + char TPMPresentFlag; /// 00h = TPM not present. > + char TPMDeactivatedFlag; /// 01h = TPM currently deactivated. > +} TCG_EFI_BOOT_SERVICE_CAPABILITY; > + > +typedef struct { > + grub_efi_uint32_t PCRIndex; > + grub_efi_uint32_t EventType; > + grub_efi_uint8_t digest[20]; > + grub_efi_uint32_t EventSize; > + grub_efi_uint8_t Event[1]; > +} TCG_PCR_EVENT; > + > +struct grub_efi_tpm_protocol > +{ > + grub_efi_status_t (*status_check) (struct grub_efi_tpm_protocol *this, > + TCG_EFI_BOOT_SERVICE_CAPABILITY > *ProtocolCapability, > + grub_efi_uint32_t *TCGFeatureFlags, > + grub_efi_physical_address_t > *EventLogLocation, > + grub_efi_physical_address_t > *EventLogLastEntry); > + grub_efi_status_t (*hash_all) (struct grub_efi_tpm_protocol *this, > + grub_efi_uint8_t *HashData, > + grub_efi_uint64_t HashLen, > + grub_efi_uint32_t AlgorithmId, > + grub_efi_uint64_t *HashedDataLen, > + grub_efi_uint8_t **HashedDataResult); > + grub_efi_status_t (*log_event) (struct grub_efi_tpm_protocol *this, > + TCG_PCR_EVENT *TCGLogData, > + grub_efi_uint32_t *EventNumber, > + grub_efi_uint32_t Flags); > + grub_efi_status_t (*pass_through_to_tpm) (struct grub_efi_tpm_protocol > *this, > + grub_efi_uint32_t > TpmInputParameterBlockSize, > + grub_efi_uint8_t > *TpmInputParameterBlock, > + grub_efi_uint32_t > TpmOutputParameterBlockSize, > + grub_efi_uint8_t > *TpmOutputParameterBlock); > + grub_efi_status_t (*log_extend_event) (struct grub_efi_tpm_protocol *this, > + grub_efi_physical_address_t HashData, > + grub_efi_uint64_t HashDataLen, > + grub_efi_uint32_t AlgorithmId, > + TCG_PCR_EVENT *TCGLogData, > + grub_efi_uint32_t *EventNumber, > + grub_efi_physical_address_t > *EventLogLastEntry); > +}; > + > +typedef struct grub_efi_tpm_protocol grub_efi_tpm_protocol_t; > + > +typedef grub_efi_uint32_t EFI_TCG2_EVENT_LOG_BITMAP; > +typedef grub_efi_uint32_t EFI_TCG2_EVENT_LOG_FORMAT; > +typedef grub_efi_uint32_t EFI_TCG2_EVENT_ALGORITHM_BITMAP; > + > +typedef struct tdEFI_TCG2_VERSION { > + grub_efi_uint8_t Major; > + grub_efi_uint8_t Minor; > +} GRUB_PACKED EFI_TCG2_VERSION; > + > +typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY { > + grub_efi_uint8_t Size; > + EFI_TCG2_VERSION StructureVersion; > + EFI_TCG2_VERSION ProtocolVersion; > + EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap; > + EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs; > + grub_efi_boolean_t TPMPresentFlag; > + grub_efi_uint16_t MaxCommandSize; > + grub_efi_uint16_t MaxResponseSize; > + grub_efi_uint32_t ManufacturerID; > + grub_efi_uint32_t NumberOfPcrBanks; > + EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks; > +} EFI_TCG2_BOOT_SERVICE_CAPABILITY; > + > +typedef grub_efi_uint32_t TCG_PCRINDEX; > +typedef grub_efi_uint32_t TCG_EVENTTYPE; > + > +typedef struct tdEFI_TCG2_EVENT_HEADER { > + grub_efi_uint32_t HeaderSize; > + grub_efi_uint16_t HeaderVersion; > + TCG_PCRINDEX PCRIndex; > + TCG_EVENTTYPE EventType; > +} GRUB_PACKED EFI_TCG2_EVENT_HEADER; > + > +typedef struct tdEFI_TCG2_EVENT { > + grub_efi_uint32_t Size; > + EFI_TCG2_EVENT_HEADER Header; > + grub_efi_uint8_t Event[1]; > +} GRUB_PACKED EFI_TCG2_EVENT; > + > +struct grub_efi_tpm2_protocol > +{ > + grub_efi_status_t (*get_capability) (struct grub_efi_tpm2_protocol *this, > + EFI_TCG2_BOOT_SERVICE_CAPABILITY > *ProtocolCapability); > + grub_efi_status_t (*get_event_log) (struct grub_efi_tpm2_protocol *this, > + EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat, > + grub_efi_physical_address_t > *EventLogLocation, > + grub_efi_physical_address_t > *EventLogLastEntry, > + grub_efi_boolean_t *EventLogTruncated); > + grub_efi_status_t (*hash_log_extend_event) (struct grub_efi_tpm2_protocol > *this, > + grub_efi_uint64_t Flags, > + grub_efi_physical_address_t > *DataToHash, According to EFI TCG Protocol specification the DataToHash should be defined as grub_efi_physical_address_t DataToHash It seems problematic to use "grub_efi_physical_address_t *" as on IA32 build that will result in different length of address "value" (32bit vs 64bit) to the parameters of caller and callee, likely a ABI breakage. Thanks, Michael > + grub_efi_uint64_t DataToHashLen, > + EFI_TCG2_EVENT *EfiTcgEvent); > + grub_efi_status_t (*submit_command) (struct grub_efi_tpm2_protocol *this, > + grub_efi_uint32_t > InputParameterBlockSize, > + grub_efi_uint8_t *InputParameterBlock, > + grub_efi_uint32_t > OutputParameterBlockSize, > + grub_efi_uint8_t *OutputParameterBlock); > + grub_efi_status_t (*get_active_pcr_blanks) (struct grub_efi_tpm2_protocol > *this, > + grub_efi_uint32_t > *ActivePcrBanks); > + grub_efi_status_t (*set_active_pcr_banks) (struct grub_efi_tpm2_protocol > *this, > + grub_efi_uint32_t ActivePcrBanks); > + grub_efi_status_t (*get_result_of_set_active_pcr_banks) (struct > grub_efi_tpm2_protocol *this, > + grub_efi_uint32_t > *OperationPresent, > + grub_efi_uint32_t > *Response); > +}; > + > +typedef struct grub_efi_tpm2_protocol grub_efi_tpm2_protocol_t; > + > +#define TCG_ALG_SHA 0x00000004 > + > +#endif > diff --git a/include/grub/tpm.h b/include/grub/tpm.h > new file mode 100644 > index 000000000..d6757b57b > --- /dev/null > +++ b/include/grub/tpm.h > @@ -0,0 +1,74 @@ > +/* > + * GRUB -- GRand Unified Bootloader > + * Copyright (C) 2015 Free Software Foundation, Inc. > + * > + * GRUB is free software: you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation, either version 3 of the License, or > + * (at your option) any later version. > + * > + * GRUB is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. > + */ > + > +#ifndef GRUB_TPM_HEADER > +#define GRUB_TPM_HEADER 1 > + > +#define SHA1_DIGEST_SIZE 20 > + > +#define TPM_BASE 0x0 > +#define TPM_SUCCESS TPM_BASE > +#define TPM_AUTHFAIL (TPM_BASE + 0x1) > +#define TPM_BADINDEX (TPM_BASE + 0x2) > + > +#define TPM_TAG_RQU_COMMAND 0x00C1 > +#define TPM_ORD_Extend 0x14 > + > +#define EV_IPL 0x0d > + > +/* TCG_PassThroughToTPM Input Parameter Block */ > +typedef struct { > + grub_uint16_t IPBLength; > + grub_uint16_t Reserved1; > + grub_uint16_t OPBLength; > + grub_uint16_t Reserved2; > + grub_uint8_t TPMOperandIn[1]; > +} GRUB_PACKED PassThroughToTPM_InputParamBlock; > + > +/* TCG_PassThroughToTPM Output Parameter Block */ > +typedef struct { > + grub_uint16_t OPBLength; > + grub_uint16_t Reserved; > + grub_uint8_t TPMOperandOut[1]; > +} GRUB_PACKED PassThroughToTPM_OutputParamBlock; > + > +typedef struct { > + grub_uint16_t tag; > + grub_uint32_t paramSize; > + grub_uint32_t ordinal; > + grub_uint32_t pcrNum; > + grub_uint8_t inDigest[SHA1_DIGEST_SIZE]; /* The 160 > bit value representing the event to be recorded. */ > +} GRUB_PACKED ExtendIncoming; > + > +/* TPM_Extend Outgoing Operand */ > +typedef struct { > + grub_uint16_t tag; > + grub_uint32_t paramSize; > + grub_uint32_t returnCode; > + grub_uint8_t outDigest[SHA1_DIGEST_SIZE]; /* The PCR > value after execution of the command. */ > +} GRUB_PACKED ExtendOutgoing; > + > +grub_err_t grub_tpm_measure (unsigned char *buf, grub_size_t size, > + grub_uint8_t pcr, > + const char *description); > +grub_err_t grub_tpm_init(void); > +grub_err_t grub_tpm_execute(PassThroughToTPM_InputParamBlock *inbuf, > + PassThroughToTPM_OutputParamBlock *outbuf); > +grub_err_t grub_tpm_log_event(unsigned char *buf, grub_size_t size, > + grub_uint8_t pcr, const char *description); > +#endif > -- > 2.13.2.725.g09c95d1e9-goog > > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel