diff options
Diffstat (limited to 'src/boot/efi/measure.c')
-rw-r--r-- | src/boot/efi/measure.c | 158 |
1 files changed, 88 insertions, 70 deletions
diff --git a/src/boot/efi/measure.c b/src/boot/efi/measure.c index 01c97c8..08a2ecd 100644 --- a/src/boot/efi/measure.c +++ b/src/boot/efi/measure.c @@ -5,43 +5,11 @@ #include "macro-fundamental.h" #include "measure.h" #include "memory-util-fundamental.h" +#include "proto/cc-measurement.h" #include "proto/tcg.h" #include "tpm2-pcr.h" #include "util.h" -static EFI_STATUS tpm1_measure_to_pcr_and_event_log( - const EFI_TCG_PROTOCOL *tcg, - uint32_t pcrindex, - EFI_PHYSICAL_ADDRESS buffer, - size_t buffer_size, - const char16_t *description) { - - _cleanup_free_ TCG_PCR_EVENT *tcg_event = NULL; - EFI_PHYSICAL_ADDRESS event_log_last; - uint32_t event_number = 1; - size_t desc_len; - - assert(tcg); - assert(description); - - desc_len = strsize16(description); - tcg_event = xmalloc(offsetof(TCG_PCR_EVENT, Event) + desc_len); - *tcg_event = (TCG_PCR_EVENT) { - .EventSize = desc_len, - .PCRIndex = pcrindex, - .EventType = EV_IPL, - }; - memcpy(tcg_event->Event, description, desc_len); - - return tcg->HashLogExtendEvent( - (EFI_TCG_PROTOCOL *) tcg, - buffer, buffer_size, - TCG_ALG_SHA, - tcg_event, - &event_number, - &event_log_last); -} - static EFI_STATUS tpm2_measure_to_pcr_and_tagged_event_log( EFI_TCG2_PROTOCOL *tcg, uint32_t pcrindex, @@ -123,35 +91,67 @@ static EFI_STATUS tpm2_measure_to_pcr_and_event_log( tcg_event); } -static EFI_TCG_PROTOCOL *tcg1_interface_check(void) { - EFI_PHYSICAL_ADDRESS event_log_location, event_log_last_entry; - EFI_TCG_BOOT_SERVICE_CAPABILITY capability = { +static EFI_STATUS cc_measure_to_mr_and_event_log( + EFI_CC_MEASUREMENT_PROTOCOL *cc, + uint32_t pcrindex, + EFI_PHYSICAL_ADDRESS buffer, + uint64_t buffer_size, + const char16_t *description) { + + _cleanup_free_ EFI_CC_EVENT *event = NULL; + uint32_t mr; + EFI_STATUS err; + size_t desc_len; + + assert(cc); + assert(description); + + /* MapPcrToMrIndex service provides callers information on + * how the TPM PCR registers are mapped to the CC measurement + * registers (MR) in the vendor implementation. */ + err = cc->MapPcrToMrIndex(cc, pcrindex, &mr); + if (err != EFI_SUCCESS) + return EFI_NOT_FOUND; + + desc_len = strsize16(description); + event = xmalloc(offsetof(EFI_CC_EVENT, Event) + desc_len); + *event = (EFI_CC_EVENT) { + .Size = offsetof(EFI_CC_EVENT, Event) + desc_len, + .Header.HeaderSize = sizeof(EFI_CC_EVENT_HEADER), + .Header.HeaderVersion = EFI_CC_EVENT_HEADER_VERSION, + .Header.MrIndex = mr, + .Header.EventType = EV_IPL, + }; + + memcpy(event->Event, description, desc_len); + + return cc->HashLogExtendEvent( + cc, + 0, + buffer, + buffer_size, + event); +} + +static EFI_CC_MEASUREMENT_PROTOCOL *cc_interface_check(void) { + EFI_CC_BOOT_SERVICE_CAPABILITY capability = { .Size = sizeof(capability), }; EFI_STATUS err; - uint32_t features; - EFI_TCG_PROTOCOL *tcg; + EFI_CC_MEASUREMENT_PROTOCOL *cc; - err = BS->LocateProtocol(MAKE_GUID_PTR(EFI_TCG_PROTOCOL), NULL, (void **) &tcg); + err = BS->LocateProtocol(MAKE_GUID_PTR(EFI_CC_MEASUREMENT_PROTOCOL), NULL, (void **) &cc); if (err != EFI_SUCCESS) return NULL; - err = tcg->StatusCheck( - tcg, - &capability, - &features, - &event_log_location, - &event_log_last_entry); + err = cc->GetCapability(cc, &capability); if (err != EFI_SUCCESS) return NULL; - if (capability.TPMDeactivatedFlag) + if (!(capability.SupportedEventLogs & EFI_CC_EVENT_LOG_FORMAT_TCG_2)) return NULL; - if (!capability.TPMPresentFlag) - return NULL; - - return tcg; + return cc; } static EFI_TCG2_PROTOCOL *tcg2_interface_check(void) { @@ -184,12 +184,42 @@ static EFI_TCG2_PROTOCOL *tcg2_interface_check(void) { } bool tpm_present(void) { - return tcg2_interface_check() || tcg1_interface_check(); + return tcg2_interface_check(); } -EFI_STATUS tpm_log_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, size_t buffer_size, const char16_t *description, bool *ret_measured) { +static EFI_STATUS tcg2_log_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, size_t buffer_size, const char16_t *description, bool *ret_measured) { EFI_TCG2_PROTOCOL *tpm2; + EFI_STATUS err = EFI_SUCCESS; + + assert(ret_measured); + + tpm2 = tcg2_interface_check(); + if (tpm2) + err = tpm2_measure_to_pcr_and_event_log(tpm2, pcrindex, buffer, buffer_size, description); + + *ret_measured = tpm2 && (err == EFI_SUCCESS); + + return err; +} + +static EFI_STATUS cc_log_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, size_t buffer_size, const char16_t *description, bool *ret_measured) { + EFI_CC_MEASUREMENT_PROTOCOL *cc; + EFI_STATUS err = EFI_SUCCESS; + + assert(ret_measured); + + cc = cc_interface_check(); + if (cc) + err = cc_measure_to_mr_and_event_log(cc, pcrindex, buffer, buffer_size, description); + + *ret_measured = cc && (err == EFI_SUCCESS); + + return err; +} + +EFI_STATUS tpm_log_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, size_t buffer_size, const char16_t *description, bool *ret_measured) { EFI_STATUS err; + bool tpm_ret_measured, cc_ret_measured; assert(description || pcrindex == UINT32_MAX); @@ -203,27 +233,15 @@ EFI_STATUS tpm_log_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, size_t return EFI_SUCCESS; } - tpm2 = tcg2_interface_check(); - if (tpm2) - err = tpm2_measure_to_pcr_and_event_log(tpm2, pcrindex, buffer, buffer_size, description); - else { - EFI_TCG_PROTOCOL *tpm1; - - tpm1 = tcg1_interface_check(); - if (tpm1) - err = tpm1_measure_to_pcr_and_event_log(tpm1, pcrindex, buffer, buffer_size, description); - else { - /* No active TPM found, so don't return an error */ - - if (ret_measured) - *ret_measured = false; + /* Measure into both CC and TPM if both are available to avoid a problem like CVE-2021-42299 */ + err = cc_log_event(pcrindex, buffer, buffer_size, description, &cc_ret_measured); + if (err != EFI_SUCCESS) + return err; - return EFI_SUCCESS; - } - } + err = tcg2_log_event(pcrindex, buffer, buffer_size, description, &tpm_ret_measured); if (err == EFI_SUCCESS && ret_measured) - *ret_measured = true; + *ret_measured = tpm_ret_measured || cc_ret_measured; return err; } |