mirror of
https://git.proxmox.com/git/fwupd
synced 2025-05-22 09:12:32 +00:00
396 lines
14 KiB
C
396 lines
14 KiB
C
/*
|
|
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
|
*
|
|
* SPDX-License-Identifier: LGPL-2.1+
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "fu-mei-common.h"
|
|
|
|
const gchar *
|
|
fu_mei_common_family_to_string (FuMeiFamily family)
|
|
{
|
|
if (family == FU_MEI_FAMILY_SPS)
|
|
return "SPS";
|
|
if (family == FU_MEI_FAMILY_TXE)
|
|
return "TXE";
|
|
if (family == FU_MEI_FAMILY_ME)
|
|
return "ME";
|
|
if (family == FU_MEI_FAMILY_CSME)
|
|
return "CSME";
|
|
return "AMT";
|
|
}
|
|
|
|
static gint
|
|
fu_mei_common_cmp_version (FuMeiVersion *vers1, FuMeiVersion *vers2)
|
|
{
|
|
guint16 vers1buf[] = {
|
|
vers1->major,
|
|
vers1->minor,
|
|
vers1->hotfix,
|
|
vers1->buildno,
|
|
};
|
|
guint16 vers2buf[] = {
|
|
vers2->major,
|
|
vers2->minor,
|
|
vers2->hotfix,
|
|
vers2->buildno,
|
|
};
|
|
for (guint i = 0; i < 4; i++) {
|
|
if (vers1buf[i] < vers2buf[i])
|
|
return -1;
|
|
if (vers1buf[i] > vers2buf[i])
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
FuMeiIssue
|
|
fu_mei_common_is_csme_vulnerable (FuMeiVersion *vers)
|
|
{
|
|
if (vers->major == 11 && vers->minor == 8 && vers->hotfix >= 70)
|
|
return FU_MEI_ISSUE_PATCHED;
|
|
if (vers->major == 11 && vers->minor == 11 && vers->hotfix >= 70)
|
|
return FU_MEI_ISSUE_PATCHED;
|
|
if (vers->major == 11 && vers->minor == 22 && vers->hotfix >= 70)
|
|
return FU_MEI_ISSUE_PATCHED;
|
|
if (vers->major == 12 && vers->minor == 0 && (vers->hotfix == 49 || vers->hotfix >= 56))
|
|
return FU_MEI_ISSUE_PATCHED;
|
|
if (vers->major == 13 && vers->minor == 0 && vers->hotfix >= 21)
|
|
return FU_MEI_ISSUE_PATCHED;
|
|
if (vers->major == 14 && vers->minor == 0 && vers->hotfix >= 11)
|
|
return FU_MEI_ISSUE_PATCHED;
|
|
if (vers->major == 15)
|
|
return FU_MEI_ISSUE_NOT_VULNERABLE;
|
|
return FU_MEI_ISSUE_VULNERABLE;
|
|
}
|
|
|
|
FuMeiIssue
|
|
fu_mei_common_is_txe_vulnerable (FuMeiVersion *vers)
|
|
{
|
|
if (vers->major == 3 && vers->minor == 1 && vers->hotfix >= 70)
|
|
return FU_MEI_ISSUE_PATCHED;
|
|
if (vers->major == 4 && vers->minor == 0 && vers->hotfix >= 20)
|
|
return FU_MEI_ISSUE_PATCHED;
|
|
if (vers->major == 5)
|
|
return FU_MEI_ISSUE_NOT_VULNERABLE;
|
|
return FU_MEI_ISSUE_VULNERABLE;
|
|
}
|
|
|
|
FuMeiIssue
|
|
fu_mei_common_is_sps_vulnerable (FuMeiVersion *vers)
|
|
{
|
|
if (vers->major == 3 || vers->major > 5)
|
|
return FU_MEI_ISSUE_NOT_VULNERABLE;
|
|
if (vers->major == 4) {
|
|
if (vers->hotfix < 44)
|
|
return FU_MEI_ISSUE_VULNERABLE;
|
|
if (vers->platform == 0xA) { /* Purley */
|
|
FuMeiVersion ver2 = {
|
|
.major = 4,
|
|
.minor = 1,
|
|
.hotfix = 4,
|
|
.buildno = 339,
|
|
};
|
|
if (fu_mei_common_cmp_version (vers, &ver2) < 0)
|
|
return FU_MEI_ISSUE_VULNERABLE;
|
|
} else if (vers->platform == 0xE) { /* Bakerville */
|
|
FuMeiVersion ver2 = {
|
|
.major = 4,
|
|
.minor = 0,
|
|
.hotfix = 4,
|
|
.buildno = 112,
|
|
};
|
|
if (fu_mei_common_cmp_version (vers, &ver2) < 0)
|
|
return FU_MEI_ISSUE_VULNERABLE;
|
|
} else if (vers->platform == 0xB) { /* Harrisonville */
|
|
FuMeiVersion ver2 = {
|
|
.major = 4,
|
|
.minor = 0,
|
|
.hotfix = 4,
|
|
.buildno = 193,
|
|
};
|
|
if (fu_mei_common_cmp_version (vers, &ver2) < 0)
|
|
return FU_MEI_ISSUE_VULNERABLE;
|
|
} else if (vers->platform == 0x9) { /* Greenlow */
|
|
FuMeiVersion ver2 = {
|
|
.major = 4,
|
|
.minor = 1,
|
|
.hotfix = 4,
|
|
.buildno = 88,
|
|
};
|
|
if (vers->minor < 1)
|
|
return FU_MEI_ISSUE_NOT_VULNERABLE;
|
|
if (fu_mei_common_cmp_version (vers, &ver2) < 0)
|
|
return FU_MEI_ISSUE_VULNERABLE;
|
|
} else if (vers->platform == 0xD) { /* MonteVista */
|
|
FuMeiVersion ver2 = {
|
|
.major = 4,
|
|
.minor = 8,
|
|
.hotfix = 4,
|
|
.buildno = 51,
|
|
};
|
|
if (fu_mei_common_cmp_version (vers, &ver2) < 0)
|
|
return FU_MEI_ISSUE_VULNERABLE;
|
|
}
|
|
return FU_MEI_ISSUE_NOT_VULNERABLE;
|
|
}
|
|
if (vers->major == 5) {
|
|
if (vers->platform == 0x10) { /* Mehlow */
|
|
FuMeiVersion ver2 = { 5, 1, 3, 89 };
|
|
if (fu_mei_common_cmp_version (vers, &ver2) < 0)
|
|
return FU_MEI_ISSUE_VULNERABLE;
|
|
}
|
|
return FU_MEI_ISSUE_NOT_VULNERABLE;
|
|
}
|
|
return FU_MEI_ISSUE_PATCHED;
|
|
}
|
|
|
|
/* HFS1[3:0] Current Working State Values */
|
|
static const char *me_cws_values[] = {
|
|
[ME_HFS_CWS_RESET] = "reset",
|
|
[ME_HFS_CWS_INIT] = "initializing",
|
|
[ME_HFS_CWS_REC] = "recovery",
|
|
[ME_HFS_CWS_TEST] = "test",
|
|
[ME_HFS_CWS_DISABLED] = "disabled",
|
|
[ME_HFS_CWS_NORMAL] = "normal",
|
|
[ME_HFS_CWS_WAIT] = "wait",
|
|
[ME_HFS_CWS_TRANS] = "transition",
|
|
[ME_HFS_CWS_INVALID] = "invalid",
|
|
};
|
|
|
|
/* HFS1[8:6] Current Operation State Values */
|
|
static const char *me_opstate_values[] = {
|
|
[ME_HFS_STATE_PREBOOT] = "preboot",
|
|
[ME_HFS_STATE_M0_UMA] = "m0-with-uma",
|
|
[ME_HFS_STATE_M3] = "m3-without-uma",
|
|
[ME_HFS_STATE_M0] = "m0-without-uma",
|
|
[ME_HFS_STATE_BRINGUP] = "bring-up",
|
|
[ME_HFS_STATE_ERROR] = "error",
|
|
};
|
|
|
|
/* HFS[19:16] Current Operation Mode Values */
|
|
static const char *me_opmode_values[] = {
|
|
[ME_HFS_MODE_NORMAL] = "normal",
|
|
[ME_HFS_MODE_DEBUG] = "debug",
|
|
[ME_HFS_MODE_DIS] = "disable",
|
|
[ME_HFS_MODE_OVER_JMPR] = "override-jumper",
|
|
[ME_HFS_MODE_OVER_MEI] = "override-mei",
|
|
[ME_HFS_MODE_UNKNOWN_6] = "unknown-6",
|
|
[ME_HFS_MODE_MAYBE_SPS] = "maybe-sps",
|
|
};
|
|
|
|
/* HFS[15:12] Error Code Values */
|
|
static const char *me_error_values[] = {
|
|
[ME_HFS_ERROR_NONE] = "no-error",
|
|
[ME_HFS_ERROR_UNCAT] = "uncategorized-failure",
|
|
[ME_HFS_ERROR_DISABLED] = "disabled",
|
|
[ME_HFS_ERROR_IMAGE] = "image-failure",
|
|
[ME_HFS_ERROR_DEBUG] = "debug-failure",
|
|
};
|
|
|
|
void
|
|
fu_mei_hfsts1_to_string (FuMeiHfsts1 hfsts1, guint idt, GString *str)
|
|
{
|
|
fu_common_string_append_kv (str, idt, "WorkingState",
|
|
me_cws_values[hfsts1.fields.working_state]);
|
|
fu_common_string_append_kb (str, idt, "MfgMode",
|
|
hfsts1.fields.mfg_mode);
|
|
fu_common_string_append_kb (str, idt, "FptBad",
|
|
hfsts1.fields.fpt_bad);
|
|
fu_common_string_append_kv (str, idt, "OperationState",
|
|
me_opstate_values[hfsts1.fields.operation_state]);
|
|
fu_common_string_append_kb (str, idt, "FwInitComplete",
|
|
hfsts1.fields.fw_init_complete);
|
|
fu_common_string_append_kb (str, idt, "FtBupLdFlr",
|
|
hfsts1.fields.ft_bup_ld_flr);
|
|
fu_common_string_append_kb (str, idt, "UpdateInProgress",
|
|
hfsts1.fields.update_in_progress);
|
|
fu_common_string_append_kv (str, idt, "ErrorCode",
|
|
me_error_values[hfsts1.fields.error_code]);
|
|
fu_common_string_append_kv (str, idt, "OperationMode",
|
|
me_opmode_values[hfsts1.fields.operation_mode]);
|
|
fu_common_string_append_kx (str, idt, "ResetCount",
|
|
hfsts1.fields.reset_count);
|
|
fu_common_string_append_kb (str, idt, "BootOptions_present",
|
|
hfsts1.fields.boot_options_present);
|
|
fu_common_string_append_kb (str, idt, "BistFinished",
|
|
hfsts1.fields.bist_finished);
|
|
fu_common_string_append_kb (str, idt, "BistTestState",
|
|
hfsts1.fields.bist_test_state);
|
|
fu_common_string_append_kb (str, idt, "BistResetRequest",
|
|
hfsts1.fields.bist_reset_request);
|
|
fu_common_string_append_kx (str, idt, "CurrentPowerSource",
|
|
hfsts1.fields.current_power_source);
|
|
fu_common_string_append_kb (str, idt, "D3SupportValid",
|
|
hfsts1.fields.d3_support_valid);
|
|
fu_common_string_append_kb (str, idt, "D0i3SupportValid",
|
|
hfsts1.fields.d0i3_support_valid);
|
|
}
|
|
|
|
void
|
|
fu_mei_hfsts2_to_string (FuMeiHfsts2 hfsts2, guint idt, GString *str)
|
|
{
|
|
fu_common_string_append_kb (str, idt, "NftpLoadFailure",
|
|
hfsts2.fields.nftp_load_failure);
|
|
fu_common_string_append_kx (str, idt, "IccProgStatus",
|
|
hfsts2.fields.icc_prog_status);
|
|
fu_common_string_append_kb (str, idt, "InvokeMebx",
|
|
hfsts2.fields.invoke_mebx);
|
|
fu_common_string_append_kb (str, idt, "CpuReplaced",
|
|
hfsts2.fields.cpu_replaced);
|
|
fu_common_string_append_kb (str, idt, "Rsvd0",
|
|
hfsts2.fields.rsvd0);
|
|
fu_common_string_append_kb (str, idt, "MfsFailure",
|
|
hfsts2.fields.mfs_failure);
|
|
fu_common_string_append_kb (str, idt, "WarmResetRqst",
|
|
hfsts2.fields.warm_reset_rqst);
|
|
fu_common_string_append_kb (str, idt, "CpuReplacedValid",
|
|
hfsts2.fields.cpu_replaced_valid);
|
|
fu_common_string_append_kb (str, idt, "LowPowerState",
|
|
hfsts2.fields.low_power_state);
|
|
fu_common_string_append_kb (str, idt, "MePowerGate",
|
|
hfsts2.fields.me_power_gate);
|
|
fu_common_string_append_kb (str, idt, "IpuNeeded",
|
|
hfsts2.fields.ipu_needed);
|
|
fu_common_string_append_kb (str, idt, "ForcedSafeBoot",
|
|
hfsts2.fields.forced_safe_boot);
|
|
fu_common_string_append_kx (str, idt, "Rsvd1",
|
|
hfsts2.fields.rsvd1);
|
|
fu_common_string_append_kb (str, idt, "ListenerChange",
|
|
hfsts2.fields.listener_change);
|
|
fu_common_string_append_kx (str, idt, "StatusData",
|
|
hfsts2.fields.status_data);
|
|
fu_common_string_append_kx (str, idt, "CurrentPmevent",
|
|
hfsts2.fields.current_pmevent);
|
|
fu_common_string_append_kx (str, idt, "Phase",
|
|
hfsts2.fields.phase);
|
|
}
|
|
|
|
void
|
|
fu_mei_hfsts3_to_string (FuMeiHfsts3 hfsts3, guint idt, GString *str)
|
|
{
|
|
fu_common_string_append_kx (str, idt, "Chunk0",
|
|
hfsts3.fields.chunk0);
|
|
fu_common_string_append_kx (str, idt, "Chunk1",
|
|
hfsts3.fields.chunk1);
|
|
fu_common_string_append_kx (str, idt, "Chunk2",
|
|
hfsts3.fields.chunk2);
|
|
fu_common_string_append_kx (str, idt, "Chunk3",
|
|
hfsts3.fields.chunk3);
|
|
fu_common_string_append_kx (str, idt, "FwSku",
|
|
hfsts3.fields.fw_sku);
|
|
fu_common_string_append_kb (str, idt, "EncryptKeyCheck",
|
|
hfsts3.fields.encrypt_key_check);
|
|
fu_common_string_append_kb (str, idt, "PchConfigChange",
|
|
hfsts3.fields.pch_config_change);
|
|
fu_common_string_append_kb (str, idt, "IbbVerificationResult",
|
|
hfsts3.fields.ibb_verification_result);
|
|
fu_common_string_append_kb (str, idt, "IbbVerificationDone",
|
|
hfsts3.fields.ibb_verification_done);
|
|
fu_common_string_append_kx (str, idt, "Reserved11",
|
|
hfsts3.fields.reserved_11);
|
|
fu_common_string_append_kx (str, idt, "ActualIbbSize",
|
|
hfsts3.fields.actual_ibb_size * 1024);
|
|
fu_common_string_append_ku (str, idt, "NumberOfChunks",
|
|
hfsts3.fields.number_of_chunks);
|
|
fu_common_string_append_kb (str, idt, "EncryptKeyOverride",
|
|
hfsts3.fields.encrypt_key_override);
|
|
fu_common_string_append_kb (str, idt, "PowerDownMitigation",
|
|
hfsts3.fields.power_down_mitigation);
|
|
}
|
|
|
|
void
|
|
fu_mei_hfsts4_to_string (FuMeiHfsts4 hfsts4, guint idt, GString *str)
|
|
{
|
|
fu_common_string_append_kx (str, idt, "Rsvd0",
|
|
hfsts4.fields.rsvd0);
|
|
fu_common_string_append_kb (str, idt, "EnforcementFlow",
|
|
hfsts4.fields.enforcement_flow);
|
|
fu_common_string_append_kb (str, idt, "SxResumeType",
|
|
hfsts4.fields.sx_resume_type);
|
|
fu_common_string_append_kb (str, idt, "Rsvd1",
|
|
hfsts4.fields.rsvd1);
|
|
fu_common_string_append_kb (str, idt, "TpmsDisconnected",
|
|
hfsts4.fields.tpms_disconnected);
|
|
fu_common_string_append_kb (str, idt, "Rvsd2",
|
|
hfsts4.fields.rvsd2);
|
|
fu_common_string_append_kb (str, idt, "FwstsValid",
|
|
hfsts4.fields.fwsts_valid);
|
|
fu_common_string_append_kb (str, idt, "BootGuardSelfTest",
|
|
hfsts4.fields.boot_guard_self_test);
|
|
fu_common_string_append_kx (str, idt, "Rsvd3",
|
|
hfsts4.fields.rsvd3);
|
|
}
|
|
|
|
void
|
|
fu_mei_hfsts5_to_string (FuMeiHfsts5 hfsts5, guint idt, GString *str)
|
|
{
|
|
fu_common_string_append_kb (str, idt, "AcmActive",
|
|
hfsts5.fields.acm_active);
|
|
fu_common_string_append_kb (str, idt, "Valid",
|
|
hfsts5.fields.valid);
|
|
fu_common_string_append_kb (str, idt, "ResultCodeSource",
|
|
hfsts5.fields.result_code_source);
|
|
fu_common_string_append_kx (str, idt, "ErrorStatusCode",
|
|
hfsts5.fields.error_status_code);
|
|
fu_common_string_append_kx (str, idt, "AcmDoneSts",
|
|
hfsts5.fields.acm_done_sts);
|
|
fu_common_string_append_kx (str, idt, "TimeoutCount",
|
|
hfsts5.fields.timeout_count);
|
|
fu_common_string_append_kb (str, idt, "ScrtmIndicator",
|
|
hfsts5.fields.scrtm_indicator);
|
|
fu_common_string_append_kx (str, idt, "IncBootGuardAcm",
|
|
hfsts5.fields.inc_boot_guard_acm);
|
|
fu_common_string_append_kx (str, idt, "IncKeyManifest",
|
|
hfsts5.fields.inc_key_manifest);
|
|
fu_common_string_append_kx (str, idt, "IncBootPolicy",
|
|
hfsts5.fields.inc_boot_policy);
|
|
fu_common_string_append_kx (str, idt, "Rsvd0",
|
|
hfsts5.fields.rsvd0);
|
|
fu_common_string_append_kb (str, idt, "StartEnforcement",
|
|
hfsts5.fields.start_enforcement);
|
|
}
|
|
|
|
void
|
|
fu_mei_hfsts6_to_string (FuMeiHfsts6 hfsts6, guint idt, GString *str)
|
|
{
|
|
fu_common_string_append_kb (str, idt, "ForceBootGuardAcm",
|
|
hfsts6.fields.force_boot_guard_acm);
|
|
fu_common_string_append_kb (str, idt, "CpuDebugDisable",
|
|
hfsts6.fields.cpu_debug_disable);
|
|
fu_common_string_append_kb (str, idt, "BspInitDisable",
|
|
hfsts6.fields.bsp_init_disable);
|
|
fu_common_string_append_kb (str, idt, "ProtectBiosEnv",
|
|
hfsts6.fields.protect_bios_env);
|
|
fu_common_string_append_kx (str, idt, "Rsvd0",
|
|
hfsts6.fields.rsvd0);
|
|
fu_common_string_append_kx (str, idt, "ErrorEnforcePolicy",
|
|
hfsts6.fields.error_enforce_policy);
|
|
fu_common_string_append_kb (str, idt, "MeasuredBoot",
|
|
hfsts6.fields.measured_boot);
|
|
fu_common_string_append_kb (str, idt, "VerifiedBoot",
|
|
hfsts6.fields.verified_boot);
|
|
fu_common_string_append_kx (str, idt, "BootGuardAcmsvn",
|
|
hfsts6.fields.boot_guard_acmsvn);
|
|
fu_common_string_append_kx (str, idt, "Kmsvn",
|
|
hfsts6.fields.kmsvn);
|
|
fu_common_string_append_kx (str, idt, "Bpmsvn",
|
|
hfsts6.fields.bpmsvn);
|
|
fu_common_string_append_kx (str, idt, "KeyManifestId",
|
|
hfsts6.fields.key_manifest_id);
|
|
fu_common_string_append_kb (str, idt, "BootPolicyStatus",
|
|
hfsts6.fields.boot_policy_status);
|
|
fu_common_string_append_kb (str, idt, "Error",
|
|
hfsts6.fields.error);
|
|
fu_common_string_append_kb (str, idt, "BootGuardDisable",
|
|
hfsts6.fields.boot_guard_disable);
|
|
fu_common_string_append_kb (str, idt, "FpfDisable",
|
|
hfsts6.fields.fpf_disable);
|
|
fu_common_string_append_kb (str, idt, "FpfSocLock",
|
|
hfsts6.fields.fpf_soc_lock);
|
|
fu_common_string_append_kb (str, idt, "TxtSupport",
|
|
hfsts6.fields.txt_support);
|
|
}
|