fwupd/plugins/acpi-dmar/fu-acpi-dmar.c
Richard Hughes c1eda7d516 Add many new plugins to support for the Host Security ID
The HSI specification is currently incomplete and in active development.

Sample output for my Lenovo P50 Laptop:

    Host Security ID: HSI:2+UA!

    HSI-1
    ✔  UEFI dbx: OK
    ✔  TPM: v2.0
    ✔  SPI: Write disabled
    ✔  SPI: Lock enabled
    ✔  SPI: SMM required
    ✔  UEFI Secure Boot: Enabled

    HSI-2
    ✔  TPM Reconstruction: Matched PCR0 reading

    HSI-3
    ✘  Linux Kernel S3 Sleep: Deep sleep available

    HSI-4
    ✘  Intel CET: Unavailable

    Runtime Suffix -U
    ✔  Firmware Updates: Newest release is 8 months old

    Runtime Suffix -A
    ✔  Firmware Attestation: OK

    Runtime Suffix -!
    ✔  fwupd plugins: OK
    ✔  Linux Kernel: OK
    ✔  Linux Kernel: Locked down
    ✘  Linux Swap: Not encrypted
2020-05-12 21:20:18 +01:00

82 lines
2.0 KiB
C

/*
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#include "config.h"
#include <string.h>
#include "fu-common.h"
#include "fu-acpi-dmar.h"
struct _FuAcpiDmar {
GObject parent_instance;
gboolean opt_in;
};
G_DEFINE_TYPE (FuAcpiDmar, fu_acpi_dmar, G_TYPE_OBJECT)
#define DMAR_DMA_CTRL_PLATFORM_OPT_IN_FLAG 2
FuAcpiDmar *
fu_acpi_dmar_new (GBytes *blob, GError **error)
{
FuAcpiDmar *self = g_object_new (FU_TYPE_ACPI_DMAR, NULL);
gchar creator_id[5] = { '\0' };
gchar oem_table_id[9] = { '\0' };
gchar signature[5] = { '\0' };
gsize bufsz = 0;
guint8 flags = 0;
const guint8 *buf = g_bytes_get_data (blob, &bufsz);
/* parse table */
if (!fu_memcpy_safe ((guint8 *) signature, sizeof(signature), 0x0, /* dst */
buf, bufsz, 0x00, /* src */
sizeof(signature) - 1, error))
return FALSE;
if (strcmp (signature, "DMAR") != 0) {
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_NOT_SUPPORTED,
"Not a DMAR table, got %s",
signature);
return FALSE;
}
if (!fu_memcpy_safe ((guint8 *) oem_table_id, sizeof(oem_table_id), 0x0,/* dst */
buf, bufsz, 0x10, /* src */
sizeof(oem_table_id) - 1, error))
return FALSE;
g_debug ("OemTableId: %s", oem_table_id);
if (!fu_memcpy_safe ((guint8 *) creator_id, sizeof(creator_id), 0x0, /* dst */
buf, bufsz, 0x1c, /* src */
sizeof(creator_id) - 1, error))
return FALSE;
g_debug ("CreatorId: %s", creator_id);
if (!fu_memcpy_safe (&flags, sizeof(flags), 0x0, /* dst */
buf, bufsz, 0x25, /* src */
sizeof(flags), error))
return FALSE;
g_debug ("Flags: 0x%02x", flags);
self->opt_in = (flags & DMAR_DMA_CTRL_PLATFORM_OPT_IN_FLAG) > 0;
return self;
}
gboolean
fu_acpi_dmar_get_opt_in (FuAcpiDmar *self)
{
g_return_val_if_fail (FU_IS_ACPI_DMAR (self), FALSE);
return self->opt_in;
}
static void
fu_acpi_dmar_class_init (FuAcpiDmarClass *klass)
{
}
static void
fu_acpi_dmar_init (FuAcpiDmar *self)
{
}