summaryrefslogtreecommitdiffstats
path: root/src/boot/efi/measure.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/boot/efi/measure.c')
-rw-r--r--src/boot/efi/measure.c158
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;
}