Coverage Report

Created: 2026-04-28 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fwupd/libfwupdplugin/fu-tpm-eventlog.c
Line
Count
Source
1
/*
2
 * Copyright 2019 Richard Hughes <richard@hughsie.com>
3
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
5
 */
6
7
#include "config.h"
8
9
#include "fu-bytes.h"
10
#include "fu-tpm-eventlog-common.h"
11
#include "fu-tpm-eventlog-item.h"
12
#include "fu-tpm-eventlog.h"
13
14
0
G_DEFINE_TYPE(FuTpmEventlog, fu_tpm_eventlog, FU_TYPE_FIRMWARE)
15
0
16
0
/**
17
0
 * fu_tpm_eventlog_calc_checksums:
18
0
 * @self: a #FuTpmEventlog
19
0
 * @pcr: a PCR value
20
0
 * @error: (nullable): optional return location for an error
21
0
 *
22
0
 * Calculate the possible checksums for a given PCR.
23
0
 *
24
0
 * Returns: (element-type utf8) (transfer container): checksum strings
25
0
 *
26
0
 * Since: 2.1.1
27
0
 **/
28
0
GPtrArray *
29
0
fu_tpm_eventlog_calc_checksums(FuTpmEventlog *self, guint8 pcr, GError **error)
30
0
{
31
0
  guint cnt_sha1 = 0;
32
0
  guint cnt_sha256 = 0;
33
0
  guint cnt_sha384 = 0;
34
0
  guint8 digest_sha1[FU_TPM_DIGEST_SIZE_SHA1] = {0x0};
35
0
  guint8 digest_sha256[FU_TPM_DIGEST_SIZE_SHA256] = {0x0};
36
0
  guint8 digest_sha384[FU_TPM_DIGEST_SIZE_SHA384] = {0x0};
37
0
  gsize digest_sha1_len = sizeof(digest_sha1);
38
0
  gsize digest_sha256_len = sizeof(digest_sha256);
39
0
  gsize digest_sha384_len = sizeof(digest_sha384);
40
0
  g_autoptr(GPtrArray) csums = g_ptr_array_new_with_free_func(g_free);
41
0
  g_autoptr(GPtrArray) items = fu_firmware_get_images(FU_FIRMWARE(self));
42
43
  /* sanity check */
44
0
  if (items->len == 0) {
45
0
    g_set_error_literal(error,
46
0
            FWUPD_ERROR,
47
0
            FWUPD_ERROR_INVALID_DATA,
48
0
            "no event log data");
49
0
    return NULL;
50
0
  }
51
52
  /* take existing PCR hash, append new measurement to that,
53
   * hash that with the same algorithm */
54
0
  for (guint i = 0; i < items->len; i++) {
55
0
    FuTpmEventlogItem *item = g_ptr_array_index(items, i);
56
0
    FuTpmEventlogItemKind item_kind = fu_tpm_eventlog_item_get_kind(item);
57
0
    guint8 item_pcr = fu_tpm_eventlog_item_get_pcr(item);
58
0
    g_autoptr(GBytes) item_blob = fu_firmware_get_bytes(FU_FIRMWARE(item), NULL);
59
0
    g_autoptr(GBytes) item_checksum_sha1 = NULL;
60
0
    g_autoptr(GBytes) item_checksum_sha256 = NULL;
61
0
    g_autoptr(GBytes) item_checksum_sha384 = NULL;
62
63
0
    if (item_pcr != pcr)
64
0
      continue;
65
66
    /* if TXT is enabled then the first event for PCR0 should be a StartupLocality */
67
0
    if (item_kind == FU_TPM_EVENTLOG_ITEM_KIND_NO_ACTION && item_pcr == 0 &&
68
0
        item_blob != NULL && i == 0) {
69
0
      g_autoptr(FuStructTpmEfiStartupLocalityEvent) st_loc = NULL;
70
0
      st_loc = fu_struct_tpm_efi_startup_locality_event_parse_bytes(item_blob,
71
0
                          0x0,
72
0
                          NULL);
73
0
      if (st_loc != NULL) {
74
0
        guint8 locality =
75
0
            fu_struct_tpm_efi_startup_locality_event_get_locality(st_loc);
76
0
        digest_sha384[FU_TPM_DIGEST_SIZE_SHA384 - 1] = locality;
77
0
        digest_sha256[FU_TPM_DIGEST_SIZE_SHA256 - 1] = locality;
78
0
        digest_sha1[FU_TPM_DIGEST_SIZE_SHA1 - 1] = locality;
79
0
        continue;
80
0
      }
81
0
    }
82
83
    /* ignore all subsequent no-action events */
84
0
    if (item_kind == FU_TPM_EVENTLOG_ITEM_KIND_NO_ACTION)
85
0
      continue;
86
87
0
    item_checksum_sha1 = fu_tpm_eventlog_item_get_checksum(item, FU_TPM_ALG_SHA1, NULL);
88
0
    if (item_checksum_sha1 != NULL) {
89
0
      g_autoptr(GChecksum) csum_sha1 = g_checksum_new(G_CHECKSUM_SHA1);
90
0
      g_checksum_update(csum_sha1, (const guchar *)digest_sha1, digest_sha1_len);
91
0
      g_checksum_update(
92
0
          csum_sha1,
93
0
          (const guchar *)g_bytes_get_data(item_checksum_sha1, NULL),
94
0
          g_bytes_get_size(item_checksum_sha1));
95
0
      g_checksum_get_digest(csum_sha1, digest_sha1, &digest_sha1_len);
96
0
      cnt_sha1++;
97
0
    }
98
0
    item_checksum_sha256 =
99
0
        fu_tpm_eventlog_item_get_checksum(item, FU_TPM_ALG_SHA256, NULL);
100
0
    if (item_checksum_sha256 != NULL) {
101
0
      g_autoptr(GChecksum) csum_sha256 = g_checksum_new(G_CHECKSUM_SHA256);
102
0
      g_checksum_update(csum_sha256,
103
0
            (const guchar *)digest_sha256,
104
0
            digest_sha256_len);
105
0
      g_checksum_update(
106
0
          csum_sha256,
107
0
          (const guchar *)g_bytes_get_data(item_checksum_sha256, NULL),
108
0
          g_bytes_get_size(item_checksum_sha256));
109
0
      g_checksum_get_digest(csum_sha256, digest_sha256, &digest_sha256_len);
110
0
      cnt_sha256++;
111
0
    }
112
0
    item_checksum_sha384 =
113
0
        fu_tpm_eventlog_item_get_checksum(item, FU_TPM_ALG_SHA384, NULL);
114
0
    if (item_checksum_sha384 != NULL) {
115
0
      g_autoptr(GChecksum) csum_sha384 = g_checksum_new(G_CHECKSUM_SHA384);
116
0
      g_checksum_update(csum_sha384,
117
0
            (const guchar *)digest_sha384,
118
0
            digest_sha384_len);
119
0
      g_checksum_update(
120
0
          csum_sha384,
121
0
          (const guchar *)g_bytes_get_data(item_checksum_sha384, NULL),
122
0
          g_bytes_get_size(item_checksum_sha384));
123
0
      g_checksum_get_digest(csum_sha384, digest_sha384, &digest_sha384_len);
124
0
      cnt_sha384++;
125
0
    }
126
0
  }
127
0
  if (cnt_sha1 == 0 && cnt_sha256 == 0 && cnt_sha384 == 0) {
128
0
    g_set_error_literal(error,
129
0
            FWUPD_ERROR,
130
0
            FWUPD_ERROR_INVALID_DATA,
131
0
            "no SHA1, SHA256, or SHA384 data");
132
0
    return NULL;
133
0
  }
134
0
  if (cnt_sha1 > 0) {
135
0
    g_autoptr(GBytes) blob_sha1 = NULL;
136
0
    blob_sha1 = g_bytes_new_static(digest_sha1, sizeof(digest_sha1));
137
0
    g_ptr_array_add(csums, fu_bytes_to_string(blob_sha1));
138
0
  }
139
0
  if (cnt_sha256 > 0) {
140
0
    g_autoptr(GBytes) blob_sha256 = NULL;
141
0
    blob_sha256 = g_bytes_new_static(digest_sha256, sizeof(digest_sha256));
142
0
    g_ptr_array_add(csums, fu_bytes_to_string(blob_sha256));
143
0
  }
144
0
  if (cnt_sha384 > 0) {
145
0
    g_autoptr(GBytes) blob_sha384 = NULL;
146
0
    blob_sha384 = g_bytes_new_static(digest_sha384, sizeof(digest_sha384));
147
0
    g_ptr_array_add(csums, fu_bytes_to_string(blob_sha384));
148
0
  }
149
0
  return g_steal_pointer(&csums);
150
0
}
151
152
static void
153
fu_tpm_eventlog_init(FuTpmEventlog *self)
154
0
{
155
0
}
156
157
static void
158
fu_tpm_eventlog_class_init(FuTpmEventlogClass *klass)
159
0
{
160
0
}