Index: grub-2.12/include/grub/tpm.h =================================================================== --- grub-2.12.orig/include/grub/tpm.h +++ grub-2.12/include/grub/tpm.h @@ -36,6 +36,12 @@ #define EV_IPL 0x0d +struct grub_tpm_digest { + const char * algorithm; + unsigned int size; + unsigned char value[1]; /* variable length */ +}; + grub_err_t grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, const char *description); int grub_tpm_present (void); @@ -45,5 +51,7 @@ grub_is_tpm_fail_fatal (void) { return grub_env_get_bool ("tpm_fail_fatal", false); } +struct grub_tpm_digest *grub_tpm_read_pcr (grub_uint8_t index, const char *algo); +void grub_tpm_digest_free (struct grub_tpm_digest *d); #endif Index: grub-2.12/grub-core/commands/efi/tpm.c =================================================================== --- grub-2.12.orig/grub-core/commands/efi/tpm.c +++ grub-2.12/grub-core/commands/efi/tpm.c @@ -28,6 +28,8 @@ #include #include +#include + typedef TCG_PCR_EVENT grub_tpm_event_t; static grub_guid_t tpm_guid = EFI_TPM_GUID; @@ -186,6 +188,91 @@ grub_tpm1_log_event (grub_efi_handle_t t return grub_efi_log_event_status (status); } +static void +grub_tpm2_select_pcr (TPML_PCR_SELECTION_t *o, unsigned int pcrIndex, unsigned int algo) +{ + TPMS_PCR_SELECTION_t *pcr; + + pcr = &o->pcrSelections[o->count++]; + pcr->hash = algo; + pcr->sizeOfSelect = 3; + TPMS_PCR_SELECTION_SelectPCR (pcr, pcrIndex); +} + +struct grub_tpm_hash_info { + const char *name; + grub_size_t size; + int id; +}; + +static const struct grub_tpm_hash_info * +grub_tpm2_get_digest_info (const char *algo) +{ + static struct grub_tpm_hash_info __hashes[] = { + { "sha256", 32, TPM_ALG_SHA256 }, /* first entry is the default */ + { "sha512", 64, TPM_ALG_SHA512 }, + { "sha1", 20, TPM_ALG_SHA1 }, + { NULL } + }; + struct grub_tpm_hash_info *h; + + if (algo == NULL) + return &__hashes[0]; + + for (h = __hashes; h->name; ++h) + if (!grub_strcmp(h->name, algo)) + return h; + + return NULL; +} + +static grub_err_t +grub_tpm2_read_pcr (grub_int8_t pcrIndex, const char *algo, struct grub_tpm_digest **ret) +{ + const struct grub_tpm_hash_info *info; + TPML_PCR_SELECTION_t inSelection, outSelection; + grub_uint32_t pcrUpdateCounter; + TPML_DIGEST_t digests = { 0 }; + TPM2B_DIGEST_t *d; + struct grub_tpm_digest *result; + int rc; + + info = grub_tpm2_get_digest_info (algo); + if (info == NULL) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Unknown digest algorithm %s"), algo); + + grub_memset(&inSelection, 0, sizeof(inSelection)); + grub_memset(&outSelection, 0, sizeof(outSelection)); + grub_tpm2_select_pcr(&inSelection, pcrIndex, info->id); + + rc = grub_tpm2_pcr_read( + NULL, + &inSelection, + &pcrUpdateCounter, + &outSelection, + &digests, + NULL + ); + + if (rc != 0) + return grub_error (GRUB_ERR_BAD_DEVICE, "TPM2_PCR_Read failed, status=%d", rc); + + d = &digests.digests[0]; + + *ret = result = grub_malloc (sizeof (*result) + d->size); + grub_memcpy (result->value, d->buffer, d->size); + result->algorithm = info->name; + result->size = d->size; + + return GRUB_ERR_NONE; +} + +void +grub_tpm_digest_free (struct grub_tpm_digest *d) +{ + grub_free (d); +} + 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, @@ -323,3 +410,26 @@ grub_tpm_present (void) return grub_tpm2_present (tpm); } } + +struct grub_tpm_digest * +grub_tpm_read_pcr (grub_uint8_t pcr, const char *algo) +{ + grub_efi_handle_t tpm_handle; + grub_efi_uint8_t protocol_version; + struct grub_tpm_digest *result = NULL; + + + if (!grub_tpm_handle_find (&tpm_handle, &protocol_version)) + return 0; + + if (protocol_version != 2) + { + grub_error (GRUB_ERR_BAD_DEVICE, N_("%s: TPM version %d not implemented"), __func__, protocol_version); + return NULL; + } + + if (grub_tpm2_read_pcr (pcr, algo, &result)) + return NULL; + + return result; +} Index: grub-2.12/grub-core/Makefile.core.def =================================================================== --- grub-2.12.orig/grub-core/Makefile.core.def +++ grub-2.12/grub-core/Makefile.core.def @@ -2606,6 +2606,7 @@ module = { common = commands/tpm.c; efi = commands/efi/tpm.c; enable = efi; + cppflags = '-I$(srcdir)/lib/tss2'; }; module = {