Merge pull request #140 from Dasharo/fuse-key-verification

Fuse key verification
This commit is contained in:
Michał Iwanicki
2026-01-14 14:11:47 +01:00
committed by GitHub
6 changed files with 125 additions and 15 deletions
+3
View File
@@ -8,3 +8,6 @@ SBIN_DIR="/usr/sbin"
export DTS_FUNCS="$SBIN_DIR/dts-functions.sh"
export DTS_ENV="$SBIN_DIR/dts-environment.sh"
export DTS_SUBS="$SBIN_DIR/dts-subscription.sh"
export DTS_HAL="$SBIN_DIR/dts-hal.sh"
export DTS_MOCK_COMMON="$SBIN_DIR/common-mock-func.sh"
export ERR_LOG_FILE="/dev/null"
+31
View File
@@ -785,3 +785,34 @@ amdtool_on_amd_mock() {
fi
return 1
}
################################################################################
# cap_upd_tool
################################################################################
cap_upd_tool_common_mock() {
return 0
}
################################################################################
# cap_upd_tool
################################################################################
# Set this variable to:
# - leave empty - call original tool
# - "success" - key verification succeeded
# - "fail_hash" - key verification failed with hash error
# - anything else - return 1 and don't print anything
TEST_KEY_VALIDATOR_RESULT="${TEST_KEY_VALIDATOR_RESULT:-}"
btg_key_validator_common_mock() {
if [ -z "${TEST_KEY_VALIDATOR_RESULT}" ]; then
btg_key_validator "$@"
return
elif [ "${TEST_KEY_VALIDATOR_RESULT}" = "success" ]; then
echo "Firmware is signed with expected key hash"
return 0
elif [ "${TEST_KEY_VALIDATOR_RESULT}" = "fail_hash" ]; then
print_error "Firmware signature doesn't match expected hash"
fi
return 1
}
+1
View File
@@ -60,6 +60,7 @@ RDMSR="tool_wrapper rdmsr"
LSPCI="tool_wrapper lspci"
LSUSB="tool_wrapper lsusb"
DUMP_PCRS="tool_wrapper dump_pcrs"
BTG_KEY_VALIDATOR="tool_wrapper btg_key_validator"
################################################################################
# Tools wrapper.
+81 -9
View File
@@ -1,23 +1,95 @@
#!/bin/bash
ncm_mtl_key=e64b6b0e82c68fecc58f750d3696c26e1c98bf9e3149c81f3b2ed775eb9d2c157a99c103c62c44c0cdc61be971caeae1
# shellcheck source=../include/dts-environment.sh
source "$DTS_ENV"
# shellcheck source=../include/dts-functions.sh
source "$DTS_FUNCS"
rom=flashdump.bin
print_help() {
cat <<EOF
$(basename "$0") [OPTION]...
echo "Reading flash..."
flashrom -p internal --ifd -i bios -i me -i fd -r $rom >/dev/null 2>&1
Script that allows for verification whether firmware binary is signed with correct keys.
Options:
-f|--file <file> Path to firmware file for which to check key hash.
-k|--key-hash <hash> Expected key hash
-v|--verbose Enable trace output
-h|--help Print this help
EOF
}
parse_args() {
while [[ $# -gt 0 ]]; do
case $1 in
-v | --verbose)
set -x
shift
;;
-h | --help)
print_help
exit 0
;;
-f | --file)
if [ ! -f "$2" ]; then
error_exit "File '$2' doesn't exist"
fi
rom="$2"
shift 2
;;
-k | --key-hash)
if [ -z "$2" ]; then
error_exit "--key-hash argument cannot be empty"
fi
expected_hash="$2"
shift 2
;;
-*)
print_help
error_exit "Unknown option $1"
;;
*)
print_usage
error_exit "Script doesn't accept any positional arguments, but got $#"
;;
esac
done
}
expected_hash=
rom="flashdump.bin"
parse_args "$@"
if [ -z "$expected_hash" ]; then
board_config
error_check "Failed to download board configuration."
if [ -z "$INTEL_BTG_HASH" ]; then
error_exit "Platform configuration is missing expected key hash.
The most likely reason is that there is no fusing binary for your platform."
fi
expected_hash="$INTEL_BTG_HASH"
fi
if [ ! -f "$rom" ]; then
echo "Reading flash..."
$FLASHROM -p "$PROGRAMMER_BIOS" --ifd -i bios -i me -i fd -r "${rom}" >>"$FLASHROM_LOG_FILE" 2>>"$ERR_LOG_FILE"
error_check "Failed to read flash"
fi
echo "Extracting key manifest..."
bg-prov km-export $rom km.bin >/dev/null
bg-prov km-export "${rom}" km.bin 2>>"$ERR_LOG_FILE" >&2
error_check "Failed to export key manifest."
modulus=$(bg-prov km-show km.bin | grep "Key And Signature" -A 8 | grep Data | cut -d ' ' -f 10 | tail -c +11)
exponent=01000100
echo $modulus$exponent | awk '{gsub(/.{2}/,"& ")}1' | xxd -r -p | sha384sum | grep -q $ncm_mtl_key
fw_key_hash="$(echo "$modulus$exponent" | awk '{gsub(/.{2}/,"& ")}1' | xxd -r -p | sha384sum | awk '{print $1}')"
if [ $? -eq 0 ]; then
echo "Key matches NovaCustom Meteor Lake signing key."
if grep -q "${expected_hash}" <<<"${fw_key_hash}"; then
echo_green "Firmware is signed with expected key hash:"
echo_green " ${expected_hash}"
else
echo "Key does not match NovaCustom Meteor Lake signing key!"
echo_red "Firmware signature doesn't match expected hash:"
echo_red " Expected: ${expected_hash}"
echo_red " Signed : ${fw_key_hash}"
exit 1
fi
+6
View File
@@ -1573,6 +1573,9 @@ fuse_workflow() {
echo "No release with fusing support is available for your platform."
exit "${CANCEL}"
fi
if [ -z "$INTEL_BTG_HASH" ]; then
error_exit "Platform config is missing hash of the key used to sign firmware"
fi
BIOS_LINK="${EOM_LINK_COMM_CAP}"
BIOS_HASH_LINK="${EOM_HASH_LINK_COMM_CAP}"
@@ -1593,6 +1596,9 @@ fuse_workflow() {
check_if_ac
download_bios
verify_artifacts bios
$BTG_KEY_VALIDATOR --file "$BIOS_UPDATE_FILE" --key-hash "$INTEL_BTG_HASH"
error_check "Firmware Intel BootGuard signature check failed. Aborting...
Platform has not been fused and no changes were made."
# Ask user for confirmation:
display_warning
+3 -6
View File
@@ -7,11 +7,8 @@
SBIN_DIR="/usr/sbin"
FUM_EFIVAR="/sys/firmware/efi/efivars/FirmwareUpdateMode-d15b327e-ff2d-4fc1-abf6-c12bd08c1359"
export DTS_FUNCS="$SBIN_DIR/dts-functions.sh"
export DTS_ENV="$SBIN_DIR/dts-environment.sh"
export DTS_SUBS="$SBIN_DIR/dts-subscription.sh"
export DTS_HAL="$SBIN_DIR/dts-hal.sh"
export DTS_MOCK_COMMON="$SBIN_DIR/common-mock-func.sh"
# shellcheck source=../dts-profile.sh
source "/etc/profile.d/dts-profile.sh"
export BASH_ENV="$SBIN_DIR/logging"
export TMP_LOG_DIR="/tmp/logs"
export ERR_LOG_FILE_REALPATH
@@ -31,7 +28,7 @@ DTS_VERBOSE_LOG_FILE="$TMP_LOG_DIR/dts-verbose_$(basename "$(tty)").log"
source "$BASH_ENV"
start_trace_logging
start_logging
if [ -z "$ERR_LOG_FILE" ]; then
if [[ -z "$ERR_LOG_FILE" || "$ERR_LOG_FILE" == "/dev/null" ]]; then
# pass everything written to $ERR_LOG_FILE to logger function and save it's
# output to $ERR_LOG_FILE_REALPATH file
exec {ERR_LOG_FILE}> >(logger >>"$ERR_LOG_FILE_REALPATH")