mirror of
https://git.proxmox.com/git/fwupd
synced 2025-05-25 18:44:54 +00:00

The fact that it currently lives in uefi-capsule is a historical accident, and it doesn't really belong to tpm-eventlog either. Fixes some of https://github.com/fwupd/fwupd/issues/3901
108 lines
2.4 KiB
C
108 lines
2.4 KiB
C
/*
|
|
* Copyright (C) 2018 Richard Hughes <richard@hughsie.com>
|
|
*
|
|
* SPDX-License-Identifier: LGPL-2.1+
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "fu-tpm-v1-device.h"
|
|
|
|
struct _FuTpmV1Device {
|
|
FuTpmDevice parent_instance;
|
|
};
|
|
|
|
G_DEFINE_TYPE(FuTpmV1Device, fu_tpm_v1_device, FU_TYPE_TPM_DEVICE)
|
|
|
|
static gboolean
|
|
_g_string_isxdigit(GString *str)
|
|
{
|
|
for (gsize i = 0; i < str->len; i++) {
|
|
if (!g_ascii_isxdigit(str->str[i]))
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
fu_tpm_device_parse_line(const gchar *line, gpointer user_data)
|
|
{
|
|
FuTpmDevice *self = FU_TPM_DEVICE(user_data);
|
|
guint64 idx;
|
|
g_autofree gchar *idxstr = NULL;
|
|
g_auto(GStrv) split = NULL;
|
|
g_autoptr(GString) str = NULL;
|
|
|
|
/* split into index:hash */
|
|
if (line == NULL || line[0] == '\0')
|
|
return;
|
|
split = g_strsplit(line, ":", -1);
|
|
if (g_strv_length(split) != 2) {
|
|
g_debug("unexpected format, skipping: %s", line);
|
|
return;
|
|
}
|
|
|
|
/* get index */
|
|
idxstr = fu_common_strstrip(split[0]);
|
|
idx = fu_common_strtoull(idxstr);
|
|
if (idx > 64) {
|
|
g_debug("unexpected index, skipping: %s", idxstr);
|
|
return;
|
|
}
|
|
|
|
/* parse hash */
|
|
str = g_string_new(split[1]);
|
|
fu_common_string_replace(str, " ", "");
|
|
if ((str->len != 40 && str->len != 64) || !_g_string_isxdigit(str)) {
|
|
g_debug("not SHA-1 or SHA-256, skipping: %s", split[1]);
|
|
return;
|
|
}
|
|
g_string_ascii_down(str);
|
|
fu_tpm_device_add_checksum(self, idx, str->str);
|
|
}
|
|
|
|
static gboolean
|
|
fu_tpm_v1_device_probe(FuDevice *device, GError **error)
|
|
{
|
|
FuTpmV1Device *self = FU_TPM_V1_DEVICE(device);
|
|
g_auto(GStrv) lines = NULL;
|
|
g_autofree gchar *buf_pcrs = NULL;
|
|
|
|
/* FuUdevDevice->probe */
|
|
if (!FU_DEVICE_CLASS(fu_tpm_v1_device_parent_class)->probe(device, error))
|
|
return FALSE;
|
|
|
|
/* get entire contents */
|
|
if (!g_file_get_contents(fu_udev_device_get_device_file(FU_UDEV_DEVICE(device)),
|
|
&buf_pcrs,
|
|
NULL,
|
|
error))
|
|
return FALSE;
|
|
|
|
/* find PCR lines */
|
|
lines = g_strsplit(buf_pcrs, "\n", -1);
|
|
for (guint i = 0; lines[i] != NULL; i++) {
|
|
if (g_str_has_prefix(lines[i], "PCR-"))
|
|
fu_tpm_device_parse_line(lines[i] + 4, self);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
fu_tpm_v1_device_init(FuTpmV1Device *self)
|
|
{
|
|
}
|
|
|
|
static void
|
|
fu_tpm_v1_device_class_init(FuTpmV1DeviceClass *klass)
|
|
{
|
|
FuDeviceClass *klass_device = FU_DEVICE_CLASS(klass);
|
|
klass_device->probe = fu_tpm_v1_device_probe;
|
|
}
|
|
|
|
FuTpmDevice *
|
|
fu_tpm_v1_device_new(FuContext *ctx)
|
|
{
|
|
return FU_TPM_DEVICE(g_object_new(FU_TYPE_TPM_V1_DEVICE, "context", ctx, NULL));
|
|
}
|