Move the AMT functionality to the Intel MEI plugin

This commit is contained in:
Richard Hughes 2022-10-12 10:11:52 +01:00
parent 0f8ec55f46
commit 3a0f187a16
15 changed files with 85 additions and 151 deletions

View File

@ -42,7 +42,7 @@ USE_LDCONFIG= yes
SHEBANG_GLOB= *.py
MESON_ARGS= -Dgudev=disabled \
-Dplugin_amt=false \
-Dplugin_intel_me=false \
-Dpolkit=disabled \
-Dsystemd=disabled \
-Doffline=false \

View File

@ -15,7 +15,6 @@ option('gnutls', type: 'feature', description : 'GnuTLS support', deprecated: {'
option('sqlite', type: 'feature', description : 'sqlite support', deprecated: {'true': 'enabled', 'false': 'disabled'})
option('lzma', type: 'feature', description : 'LZMA support', deprecated: {'true': 'enabled', 'false': 'disabled'})
option('cbor', type: 'feature', description : 'CBOR support for coSWID and uSWID')
option('plugin_amt', type : 'feature', description : 'Intel AMT support', deprecated: {'true': 'enabled', 'false': 'disabled'})
option('plugin_acpi_phat', type : 'feature', description : 'ACPI PHAT support', deprecated: {'true': 'enabled', 'false': 'disabled'})
option('plugin_android_boot', type : 'feature', description : 'Android Boot support')
option('plugin_bcm57xx', type : 'feature', description : 'BCM57xx support', deprecated: {'true': 'enabled', 'false': 'disabled'})
@ -45,6 +44,7 @@ option('plugin_modem_manager', type : 'feature', description : 'ModemManager sup
option('plugin_msr', type : 'feature', description : 'MSR support', deprecated: {'true': 'enabled', 'false': 'disabled'})
option('plugin_mtd', type : 'feature', description : 'MTD support', deprecated: {'true': 'enabled', 'false': 'disabled'})
option('plugin_flashrom', type : 'feature', description : 'flashrom support', deprecated: {'true': 'enabled', 'false': 'disabled'})
option('plugin_intel_me', type : 'feature', description : 'enable Intel ME support')
option('plugin_intel_spi', type : 'boolean', value : false, description : 'enable Intel SPI support')
option('plugin_uf2', type : 'feature', description : 'support for UF2', deprecated: {'true': 'enabled', 'false': 'disabled'})
option('plugin_upower', type : 'feature', description : 'support for UPower', deprecated: {'true': 'enabled', 'false': 'disabled'})

View File

@ -1,27 +0,0 @@
# Intel Management Engine
## Introduction
This plugin is used to get the version number on the Intel Management Engine.
If AMT is enabled and provisioned and the AMT version is between 6.0 and 11.2,
and you have not upgraded your firmware, you are vulnerable to CVE-2017-5689 and
you should disable AMT in your system firmware.
This code is inspired by 'AMT status checker for Linux' by Matthew Garrett
which can be found here: <https://github.com/mjg59/mei-amt-check>
That tool in turn is heavily based on mei-amt-version from samples/mei in the
Linux source tree and copyright Intel Corporation.
## GUID Generation
These devices use the existing GUID provided by the AMT host interface.
## Vendor ID Security
The device is not upgradable and thus requires no vendor ID set.
## External Interface Access
This plugin requires read only access to `/dev/mei0`.

View File

@ -1,3 +0,0 @@
# PTHI client (via the HECI device)
[12f80028-b4b7-4b2d-aca8-46e0ff65814c]
Plugin = amt

View File

@ -1,12 +0,0 @@
/*
* Copyright (C) 2022 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#pragma once
#include <fwupdplugin.h>
#define FU_TYPE_AMT_DEVICE (fu_amt_device_get_type())
G_DECLARE_FINAL_TYPE(FuAmtDevice, fu_amt_device, FU, AMT_DEVICE, FuMeiDevice)

View File

@ -1,36 +0,0 @@
/*
* Copyright (C) 2022 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#include "config.h"
#include "fu-amt-device.h"
#include "fu-amt-plugin.h"
struct _FuAmtPlugin {
FuPlugin parent_instance;
};
G_DEFINE_TYPE(FuAmtPlugin, fu_amt_plugin, FU_TYPE_PLUGIN)
static void
fu_amt_plugin_init(FuAmtPlugin *self)
{
}
static void
fu_amt_plugin_constructed(GObject *obj)
{
FuPlugin *plugin = FU_PLUGIN(obj);
fu_plugin_add_udev_subsystem(plugin, "mei");
fu_plugin_add_device_gtype(plugin, FU_TYPE_AMT_DEVICE);
}
static void
fu_amt_plugin_class_init(FuAmtPluginClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS(klass);
object_class->constructed = fu_amt_plugin_constructed;
}

View File

@ -1,11 +0,0 @@
/*
* Copyright (C) 2022 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#pragma once
#include <fwupdplugin.h>
G_DECLARE_FINAL_TYPE(FuAmtPlugin, fu_amt_plugin, FU, AMT_PLUGIN, FuPlugin)

View File

@ -1,15 +0,0 @@
if get_option('plugin_amt').disable_auto_if(host_machine.system() != 'linux').allowed()
cargs = ['-DG_LOG_DOMAIN="FuPluginAmt"']
plugin_quirks += files('amt.quirk')
plugin_builtins += static_library('fu_plugin_amt',
sources: [
'fu-amt-plugin.c',
'fu-amt-device.c',
],
include_directories: plugin_incdirs,
link_with: plugin_libs,
c_args: cargs,
dependencies: plugin_deps,
)
endif

View File

@ -4,7 +4,18 @@
This plugin is used to talk to the Intel ME device, typically CSME.
It allows us to get the Platform Key as used for BootGuard.
It allows us to get the Platform Key as used for BootGuard and to get the
version number for the Intel AMT.
If AMT is enabled and provisioned and the AMT version is between 6.0 and 11.2,
and you have not upgraded your firmware, you are vulnerable to CVE-2017-5689 and
you should disable AMT in your system firmware.
This code is inspired by 'AMT status checker for Linux' by Matthew Garrett
which can be found here: <https://github.com/mjg59/mei-amt-check>
That tool in turn is heavily based on mei-amt-version from samples/mei in the
Linux source tree and copyright Intel Corporation.
## GUID Generation

View File

@ -8,13 +8,13 @@
#include "config.h"
#include "fu-amt-device.h"
#include "fu-intel-me-amt-device.h"
struct _FuAmtDevice {
struct _FuIntelMeAmtDevice {
FuMeiDevice parent_instance;
};
G_DEFINE_TYPE(FuAmtDevice, fu_amt_device, FU_TYPE_MEI_DEVICE)
G_DEFINE_TYPE(FuIntelMeAmtDevice, fu_intel_me_amt_device, FU_TYPE_MEI_DEVICE)
#define AMT_MAJOR_VERSION 1
#define AMT_MINOR_VERSION 1
@ -104,11 +104,12 @@ const struct amt_host_if_msg_header PROVISIONING_STATE_REQUEST = {
.length = 0};
struct amt_host_if {
FuAmtDevice self;
FuIntelMeAmtDevice self;
};
static gboolean
fu_amt_device_verify_code_versions(const struct amt_host_if_resp_header *resp, GError **error)
fu_intel_me_amt_device_verify_code_versions(const struct amt_host_if_resp_header *resp,
GError **error)
{
struct amt_code_versions *code_ver = (struct amt_code_versions *)resp->data;
gsize code_ver_len = resp->header.length - sizeof(guint32);
@ -140,7 +141,7 @@ fu_amt_device_verify_code_versions(const struct amt_host_if_resp_header *resp, G
}
static gboolean
fu_amt_device_status_set_error(guint32 status, GError **error)
fu_intel_me_amt_device_status_set_error(guint32 status, GError **error)
{
if (status == AMT_STATUS_SUCCESS)
return TRUE;
@ -172,14 +173,14 @@ fu_amt_device_status_set_error(guint32 status, GError **error)
}
static gboolean
fu_amt_device_host_if_call(FuAmtDevice *self,
const guchar *command,
gssize command_sz,
guint8 **read_buf,
guint32 rcmd,
guint expected_sz,
unsigned long send_timeout,
GError **error)
fu_intel_me_amt_device_host_if_call(FuIntelMeAmtDevice *self,
const guchar *command,
gssize command_sz,
guint8 **read_buf,
guint32 rcmd,
guint expected_sz,
unsigned long send_timeout,
GError **error)
{
gsize in_buf_sz = fu_mei_device_get_max_msg_length(FU_MEI_DEVICE(self));
gsize out_buf_sz;
@ -210,7 +211,7 @@ fu_amt_device_host_if_call(FuAmtDevice *self,
(guint)out_buf_sz);
return FALSE;
}
if (!fu_amt_device_status_set_error(msg_hdr->status, error))
if (!fu_intel_me_amt_device_status_set_error(msg_hdr->status, error))
return FALSE;
if (out_buf_sz < sizeof(struct amt_host_if_resp_header)) {
g_set_error_literal(error,
@ -249,17 +250,19 @@ fu_amt_device_host_if_call(FuAmtDevice *self,
}
static gboolean
fu_amt_device_get_provisioning_state(FuAmtDevice *self, guint8 *state, GError **error)
fu_intel_me_amt_device_get_provisioning_state(FuIntelMeAmtDevice *self,
guint8 *state,
GError **error)
{
g_autofree struct amt_host_if_resp_header *response = NULL;
if (!fu_amt_device_host_if_call(self,
(const guchar *)&PROVISIONING_STATE_REQUEST,
sizeof(PROVISIONING_STATE_REQUEST),
(guint8 **)&response,
AMT_HOST_IF_PROVISIONING_STATE_RESPONSE,
0,
5000,
error)) {
if (!fu_intel_me_amt_device_host_if_call(self,
(const guchar *)&PROVISIONING_STATE_REQUEST,
sizeof(PROVISIONING_STATE_REQUEST),
(guint8 **)&response,
AMT_HOST_IF_PROVISIONING_STATE_RESPONSE,
0,
5000,
error)) {
g_prefix_error(error, "unable to get provisioning state: ");
return FALSE;
}
@ -268,18 +271,18 @@ fu_amt_device_get_provisioning_state(FuAmtDevice *self, guint8 *state, GError **
}
static gboolean
fu_amt_device_open(FuDevice *device, GError **error)
fu_intel_me_amt_device_open(FuDevice *device, GError **error)
{
/* open then create context */
if (!FU_DEVICE_CLASS(fu_amt_device_parent_class)->open(device, error))
if (!FU_DEVICE_CLASS(fu_intel_me_amt_device_parent_class)->open(device, error))
return FALSE;
return fu_mei_device_connect(FU_MEI_DEVICE(device), 0, error);
}
static gboolean
fu_amt_device_setup(FuDevice *device, GError **error)
fu_intel_me_amt_device_setup(FuDevice *device, GError **error)
{
FuAmtDevice *self = FU_AMT_DEVICE(device);
FuIntelMeAmtDevice *self = FU_INTEL_ME_AMT_DEVICE(device);
guint8 state;
struct amt_code_versions ver;
g_autofree struct amt_host_if_resp_header *response = NULL;
@ -287,24 +290,24 @@ fu_amt_device_setup(FuDevice *device, GError **error)
g_autoptr(GString) version_fw = g_string_new(NULL);
/* check version */
if (!fu_amt_device_host_if_call(self,
(const guchar *)&CODE_VERSION_REQ,
sizeof(CODE_VERSION_REQ),
(guint8 **)&response,
AMT_HOST_IF_CODE_VERSIONS_RESPONSE,
0,
5000,
error)) {
if (!fu_intel_me_amt_device_host_if_call(self,
(const guchar *)&CODE_VERSION_REQ,
sizeof(CODE_VERSION_REQ),
(guint8 **)&response,
AMT_HOST_IF_CODE_VERSIONS_RESPONSE,
0,
5000,
error)) {
g_prefix_error(error, "Failed to check version: ");
return FALSE;
}
if (!fu_amt_device_verify_code_versions(response, error)) {
if (!fu_intel_me_amt_device_verify_code_versions(response, error)) {
g_prefix_error(error, "failed to verify code versions: ");
return FALSE;
}
memcpy(&ver, response->data, sizeof(struct amt_code_versions));
if (!fu_amt_device_get_provisioning_state(self, &state, error))
if (!fu_intel_me_amt_device_get_provisioning_state(self, &state, error))
return FALSE;
switch (state) {
case 0:
@ -353,8 +356,9 @@ fu_amt_device_setup(FuDevice *device, GError **error)
}
static void
fu_amt_device_init(FuAmtDevice *self)
fu_intel_me_amt_device_init(FuIntelMeAmtDevice *self)
{
fu_device_set_logical_id(FU_DEVICE(self), "AMT");
fu_device_set_version_format(FU_DEVICE(self), FWUPD_VERSION_FORMAT_INTEL_ME);
fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_INTERNAL);
fu_device_add_icon(FU_DEVICE(self), "computer");
@ -364,9 +368,9 @@ fu_amt_device_init(FuAmtDevice *self)
}
static void
fu_amt_device_class_init(FuAmtDeviceClass *klass)
fu_intel_me_amt_device_class_init(FuIntelMeAmtDeviceClass *klass)
{
FuDeviceClass *klass_device = FU_DEVICE_CLASS(klass);
klass_device->open = fu_amt_device_open;
klass_device->setup = fu_amt_device_setup;
klass_device->open = fu_intel_me_amt_device_open;
klass_device->setup = fu_intel_me_amt_device_setup;
}

View File

@ -0,0 +1,16 @@
/*
* Copyright (C) 2022 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#pragma once
#include <fwupdplugin.h>
#define FU_TYPE_INTEL_ME_AMT_DEVICE (fu_intel_me_amt_device_get_type())
G_DECLARE_FINAL_TYPE(FuIntelMeAmtDevice,
fu_intel_me_amt_device,
FU,
INTEL_ME_AMT_DEVICE,
FuMeiDevice)

View File

@ -6,6 +6,7 @@
#include "config.h"
#include "fu-intel-me-amt-device.h"
#include "fu-intel-me-mca-device.h"
#include "fu-intel-me-mkhi-device.h"
#include "fu-intel-me-plugin.h"
@ -26,6 +27,7 @@ fu_intel_me_plugin_constructed(GObject *obj)
{
FuPlugin *plugin = FU_PLUGIN(obj);
fu_plugin_add_udev_subsystem(plugin, "mei");
fu_plugin_add_device_gtype(plugin, FU_TYPE_INTEL_ME_AMT_DEVICE);
fu_plugin_add_device_gtype(plugin, FU_TYPE_INTEL_ME_MCA_DEVICE);
fu_plugin_add_device_gtype(plugin, FU_TYPE_INTEL_ME_MKHI_DEVICE);
}

View File

@ -1,3 +1,8 @@
# PTHI client (via the HECI device)
[12f80028-b4b7-4b2d-aca8-46e0ff65814c]
Plugin = intel_me
GType = FuIntelMeAmtDevice
# MKHI (legacy)
[8e6a6715-9abc-4043-88ef-9e39c6f63e0f]
Plugin = intel_me

View File

@ -1,4 +1,4 @@
if get_option('plugin_amt').disable_auto_if(host_machine.system() != 'linux').allowed()
if get_option('plugin_intel_me').disable_auto_if(host_machine.system() != 'linux').allowed()
cargs = ['-DG_LOG_DOMAIN="FuPluginIntelMe"']
plugin_quirks += files('intel-me.quirk')
@ -6,6 +6,7 @@ plugin_builtins += static_library('fu_plugin_intel_me',
sources: [
'fu-intel-me-common.c',
'fu-intel-me-plugin.c',
'fu-intel-me-amt-device.c',
'fu-intel-me-heci-device.c',
'fu-intel-me-mca-device.c',
'fu-intel-me-mkhi-device.c',

View File

@ -20,7 +20,6 @@ subdir('acpi-facp')
subdir('acpi-ivrs')
subdir('acpi-phat')
subdir('amd-pmc')
subdir('amt')
subdir('analogix')
subdir('android-boot')
subdir('ata')