diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index f31301e04..e16fb06ba 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -2427,6 +2427,13 @@ module = { common = commands/testspeed.c; }; +module = { + name = tpm; + common = commands/tpm.c; + efi = commands/efi/tpm.c; + enable = x86_64_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..563ceba7a --- /dev/null +++ b/grub-core/commands/efi/tpm.c @@ -0,0 +1,333 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 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 . + * + * EFI TPM support code. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef TCG_PCR_EVENT grub_tpm_event_t; + +static grub_efi_guid_t tpm_guid = EFI_TPM_GUID; +static grub_efi_guid_t tpm2_guid = EFI_TPM2_GUID; + +static grub_efi_handle_t *grub_tpm_handle; +static grub_uint8_t grub_tpm_version; + +static grub_int8_t tpm1_present = -1; +static grub_int8_t tpm2_present = -1; + +static grub_efi_boolean_t +grub_tpm1_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; + + if (tpm1_present != -1) + return (grub_efi_boolean_t) tpm1_present; + + 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 tpm1_present = 0; + + return tpm1_present = 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); + + if (tpm2_present != -1) + return (grub_efi_boolean_t) tpm2_present; + + status = efi_call_2 (tpm->get_capability, tpm, &caps); + + if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag) + return tpm2_present = 0; + + return tpm2_present = 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; + + if (grub_tpm_handle != NULL) + { + *tpm_handle = &grub_tpm_handle; + *protocol_version = grub_tpm_version; + return 1; + } + + handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm_guid, NULL, + &num_handles); + if (handles && num_handles > 0) + { + grub_tpm_handle = handles[0]; + *tpm_handle = handles[0]; + grub_tpm_version = 1; + *protocol_version = 1; + return 1; + } + + handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm2_guid, NULL, + &num_handles); + if (handles && num_handles > 0) + { + grub_tpm_handle = handles[0]; + *tpm_handle = handles[0]; + grub_tpm_version = 2; + *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_tpm1_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; + + /* Absence of a TPM isn't a failure. */ + 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); +} + +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) +{ + grub_tpm_event_t *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_tpm1_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..1441c494d --- /dev/null +++ b/grub-core/commands/tpm.c @@ -0,0 +1,102 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 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 . + * + * Core TPM support code. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +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, GRUB_BINARY_PCR, context); +} + +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), + GRUB_STRING_PCR, 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, + .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 #include #include +#include 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..79c478832 --- /dev/null +++ b/include/grub/efi/tpm.h @@ -0,0 +1,198 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 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 . + */ + +#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 }}; + +#define TCG_ALG_SHA 0x00000004 + +/* These structs are as defined in the TCG EFI Protocol Specification, family 2.0. */ + +struct __TCG_VERSION +{ + grub_efi_uint8_t Major; + grub_efi_uint8_t Minor; + grub_efi_uint8_t RevMajor; + grub_efi_uint8_t RevMinor; +}; +typedef struct __TCG_VERSION TCG_VERSION; + +struct __TCG_EFI_BOOT_SERVICE_CAPABILITY +{ + /* Size of this structure. */ + grub_efi_uint8_t Size; + TCG_VERSION StructureVersion; + TCG_VERSION ProtocolSpecVersion; + /* Hash algorithms supported by this TPM. */ + grub_efi_uint8_t HashAlgorithmBitmap; + /* 1 if TPM present. */ + char TPMPresentFlag; + /* 1 if TPM deactivated. */ + char TPMDeactivatedFlag; +}; +typedef struct __TCG_EFI_BOOT_SERVICE_CAPABILITY TCG_EFI_BOOT_SERVICE_CAPABILITY; + +struct tdTCG_PCR_EVENT +{ + 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]; +}; +typedef struct tdTCG_PCR_EVENT 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; + +struct tdEFI_TCG2_VERSION +{ + grub_efi_uint8_t Major; + grub_efi_uint8_t Minor; +} GRUB_PACKED; +typedef struct tdEFI_TCG2_VERSION EFI_TCG2_VERSION; + +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; +}; +typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY EFI_TCG2_BOOT_SERVICE_CAPABILITY; + +typedef grub_efi_uint32_t TCG_PCRINDEX; +typedef grub_efi_uint32_t TCG_EVENTTYPE; + +struct tdEFI_TCG2_EVENT_HEADER +{ + grub_efi_uint32_t HeaderSize; + grub_efi_uint16_t HeaderVersion; + TCG_PCRINDEX PCRIndex; + TCG_EVENTTYPE EventType; +} GRUB_PACKED; +typedef struct tdEFI_TCG2_EVENT_HEADER EFI_TCG2_EVENT_HEADER; + +struct tdEFI_TCG2_EVENT +{ + grub_efi_uint32_t Size; + EFI_TCG2_EVENT_HEADER Header; + grub_efi_uint8_t Event[1]; +} GRUB_PACKED; +typedef struct tdEFI_TCG2_EVENT 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, + 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; + +#endif diff --git a/include/grub/tpm.h b/include/grub/tpm.h new file mode 100644 index 000000000..dfcbe8372 --- /dev/null +++ b/include/grub/tpm.h @@ -0,0 +1,82 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 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 . + */ + +#ifndef GRUB_TPM_HEADER +#define GRUB_TPM_HEADER 1 + +#define GRUB_STRING_PCR 8 +#define GRUB_BINARY_PCR 9 + +#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; + /* The 160 bit value representing the event to be recorded. */ + grub_uint8_t inDigest[SHA1_DIGEST_SIZE]; +} GRUB_PACKED ExtendIncoming; + +/* TPM_Extend Outgoing Operand. */ +typedef struct +{ + grub_uint16_t tag; + grub_uint32_t paramSize; + grub_uint32_t returnCode; + /* The PCR value after execution of the command. */ + grub_uint8_t outDigest[SHA1_DIGEST_SIZE]; +} 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