fwupd/plugins/tpm/fu-tpm-v1-device.c
Richard Hughes e29c74180c Move the TPM handling into the TPM place
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
2021-11-01 14:51:27 +00:00

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));
}