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 SHEBANG_GLOB= *.py
MESON_ARGS= -Dgudev=disabled \ MESON_ARGS= -Dgudev=disabled \
-Dplugin_amt=false \ -Dplugin_intel_me=false \
-Dpolkit=disabled \ -Dpolkit=disabled \
-Dsystemd=disabled \ -Dsystemd=disabled \
-Doffline=false \ -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('sqlite', type: 'feature', description : 'sqlite support', deprecated: {'true': 'enabled', 'false': 'disabled'})
option('lzma', type: 'feature', description : 'LZMA 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('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_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_android_boot', type : 'feature', description : 'Android Boot support')
option('plugin_bcm57xx', type : 'feature', description : 'BCM57xx support', deprecated: {'true': 'enabled', 'false': 'disabled'}) 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_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_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_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_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_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'}) 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. 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 ## GUID Generation

View File

@ -8,13 +8,13 @@
#include "config.h" #include "config.h"
#include "fu-amt-device.h" #include "fu-intel-me-amt-device.h"
struct _FuAmtDevice { struct _FuIntelMeAmtDevice {
FuMeiDevice parent_instance; 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_MAJOR_VERSION 1
#define AMT_MINOR_VERSION 1 #define AMT_MINOR_VERSION 1
@ -104,11 +104,12 @@ const struct amt_host_if_msg_header PROVISIONING_STATE_REQUEST = {
.length = 0}; .length = 0};
struct amt_host_if { struct amt_host_if {
FuAmtDevice self; FuIntelMeAmtDevice self;
}; };
static gboolean 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; struct amt_code_versions *code_ver = (struct amt_code_versions *)resp->data;
gsize code_ver_len = resp->header.length - sizeof(guint32); 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 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) if (status == AMT_STATUS_SUCCESS)
return TRUE; return TRUE;
@ -172,14 +173,14 @@ fu_amt_device_status_set_error(guint32 status, GError **error)
} }
static gboolean static gboolean
fu_amt_device_host_if_call(FuAmtDevice *self, fu_intel_me_amt_device_host_if_call(FuIntelMeAmtDevice *self,
const guchar *command, const guchar *command,
gssize command_sz, gssize command_sz,
guint8 **read_buf, guint8 **read_buf,
guint32 rcmd, guint32 rcmd,
guint expected_sz, guint expected_sz,
unsigned long send_timeout, unsigned long send_timeout,
GError **error) GError **error)
{ {
gsize in_buf_sz = fu_mei_device_get_max_msg_length(FU_MEI_DEVICE(self)); gsize in_buf_sz = fu_mei_device_get_max_msg_length(FU_MEI_DEVICE(self));
gsize out_buf_sz; gsize out_buf_sz;
@ -210,7 +211,7 @@ fu_amt_device_host_if_call(FuAmtDevice *self,
(guint)out_buf_sz); (guint)out_buf_sz);
return FALSE; 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; return FALSE;
if (out_buf_sz < sizeof(struct amt_host_if_resp_header)) { if (out_buf_sz < sizeof(struct amt_host_if_resp_header)) {
g_set_error_literal(error, g_set_error_literal(error,
@ -249,17 +250,19 @@ fu_amt_device_host_if_call(FuAmtDevice *self,
} }
static gboolean 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; g_autofree struct amt_host_if_resp_header *response = NULL;
if (!fu_amt_device_host_if_call(self, if (!fu_intel_me_amt_device_host_if_call(self,
(const guchar *)&PROVISIONING_STATE_REQUEST, (const guchar *)&PROVISIONING_STATE_REQUEST,
sizeof(PROVISIONING_STATE_REQUEST), sizeof(PROVISIONING_STATE_REQUEST),
(guint8 **)&response, (guint8 **)&response,
AMT_HOST_IF_PROVISIONING_STATE_RESPONSE, AMT_HOST_IF_PROVISIONING_STATE_RESPONSE,
0, 0,
5000, 5000,
error)) { error)) {
g_prefix_error(error, "unable to get provisioning state: "); g_prefix_error(error, "unable to get provisioning state: ");
return FALSE; return FALSE;
} }
@ -268,18 +271,18 @@ fu_amt_device_get_provisioning_state(FuAmtDevice *self, guint8 *state, GError **
} }
static gboolean static gboolean
fu_amt_device_open(FuDevice *device, GError **error) fu_intel_me_amt_device_open(FuDevice *device, GError **error)
{ {
/* open then create context */ /* 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 FALSE;
return fu_mei_device_connect(FU_MEI_DEVICE(device), 0, error); return fu_mei_device_connect(FU_MEI_DEVICE(device), 0, error);
} }
static gboolean 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; guint8 state;
struct amt_code_versions ver; struct amt_code_versions ver;
g_autofree struct amt_host_if_resp_header *response = NULL; 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); g_autoptr(GString) version_fw = g_string_new(NULL);
/* check version */ /* check version */
if (!fu_amt_device_host_if_call(self, if (!fu_intel_me_amt_device_host_if_call(self,
(const guchar *)&CODE_VERSION_REQ, (const guchar *)&CODE_VERSION_REQ,
sizeof(CODE_VERSION_REQ), sizeof(CODE_VERSION_REQ),
(guint8 **)&response, (guint8 **)&response,
AMT_HOST_IF_CODE_VERSIONS_RESPONSE, AMT_HOST_IF_CODE_VERSIONS_RESPONSE,
0, 0,
5000, 5000,
error)) { error)) {
g_prefix_error(error, "Failed to check version: "); g_prefix_error(error, "Failed to check version: ");
return FALSE; 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: "); g_prefix_error(error, "failed to verify code versions: ");
return FALSE; return FALSE;
} }
memcpy(&ver, response->data, sizeof(struct amt_code_versions)); 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; return FALSE;
switch (state) { switch (state) {
case 0: case 0:
@ -353,8 +356,9 @@ fu_amt_device_setup(FuDevice *device, GError **error)
} }
static void 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_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_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_INTERNAL);
fu_device_add_icon(FU_DEVICE(self), "computer"); fu_device_add_icon(FU_DEVICE(self), "computer");
@ -364,9 +368,9 @@ fu_amt_device_init(FuAmtDevice *self)
} }
static void 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); FuDeviceClass *klass_device = FU_DEVICE_CLASS(klass);
klass_device->open = fu_amt_device_open; klass_device->open = fu_intel_me_amt_device_open;
klass_device->setup = fu_amt_device_setup; 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 "config.h"
#include "fu-intel-me-amt-device.h"
#include "fu-intel-me-mca-device.h" #include "fu-intel-me-mca-device.h"
#include "fu-intel-me-mkhi-device.h" #include "fu-intel-me-mkhi-device.h"
#include "fu-intel-me-plugin.h" #include "fu-intel-me-plugin.h"
@ -26,6 +27,7 @@ fu_intel_me_plugin_constructed(GObject *obj)
{ {
FuPlugin *plugin = FU_PLUGIN(obj); FuPlugin *plugin = FU_PLUGIN(obj);
fu_plugin_add_udev_subsystem(plugin, "mei"); 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_MCA_DEVICE);
fu_plugin_add_device_gtype(plugin, FU_TYPE_INTEL_ME_MKHI_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) # MKHI (legacy)
[8e6a6715-9abc-4043-88ef-9e39c6f63e0f] [8e6a6715-9abc-4043-88ef-9e39c6f63e0f]
Plugin = intel_me 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"'] cargs = ['-DG_LOG_DOMAIN="FuPluginIntelMe"']
plugin_quirks += files('intel-me.quirk') plugin_quirks += files('intel-me.quirk')
@ -6,6 +6,7 @@ plugin_builtins += static_library('fu_plugin_intel_me',
sources: [ sources: [
'fu-intel-me-common.c', 'fu-intel-me-common.c',
'fu-intel-me-plugin.c', 'fu-intel-me-plugin.c',
'fu-intel-me-amt-device.c',
'fu-intel-me-heci-device.c', 'fu-intel-me-heci-device.c',
'fu-intel-me-mca-device.c', 'fu-intel-me-mca-device.c',
'fu-intel-me-mkhi-device.c', 'fu-intel-me-mkhi-device.c',

View File

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