1#!/bin/bash -eux 2# Copyright 2018 The ChromiumOS Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6me=${0##*/} 7TMP="$me.tmp" 8 9# Test --sys_props (primitive test needed for future updating tests). 10test_sys_props() { 11 ! "${FUTILITY}" --debug update --sys_props "$*" 2>&1 | 12 sed -n 's/.*property\[\(.*\)].value = \(.*\)/\1,\2,/p' | 13 tr '\n' ' ' 14} 15 16test "$(test_sys_props "1,2,3")" = "0,1, 1,2, 2,3, " 17test "$(test_sys_props "1 2 3")" = "0,1, 1,2, 2,3, " 18test "$(test_sys_props "1, 2,3 ")" = "0,1, 1,2, 2,3, " 19test "$(test_sys_props " 1,, 2")" = "0,1, 2,2, " 20test "$(test_sys_props " , 4,")" = "1,4, " 21 22test_quirks() { 23 ! "${FUTILITY}" --debug update --quirks "$*" 2>&1 | 24 sed -n 's/.*Set quirk \(.*\) to \(.*\)./\1,\2/p' | 25 tr '\n' ' ' 26} 27 28test "$(test_quirks "enlarge_image")" = "enlarge_image,1 " 29test "$(test_quirks "enlarge_image=2")" = "enlarge_image,2 " 30test "$(test_quirks " enlarge_image, enlarge_image=2")" = \ 31 "enlarge_image,1 enlarge_image,2 " 32 33# Test data files 34DATA_DIR="${SCRIPT_DIR}/futility/data" 35GERALT_BIOS="${DATA_DIR}/bios_geralt_cbfs.bin" 36LINK_BIOS="${DATA_DIR}/bios_link_mp.bin" 37PEPPY_BIOS="${DATA_DIR}/bios_peppy_mp.bin" 38VOXEL_BIOS="${DATA_DIR}/bios_voxel_dev.bin" 39RO_VPD_BLOB="${DATA_DIR}/ro_vpd.bin" 40SIGNER_CONFIG="${DATA_DIR}/signer_config.csv" 41 42# Work in scratch directory 43cd "${OUTDIR}" 44set -o pipefail 45 46# Re-create the temp folders 47TMP_FROM="${TMP}/from" 48TMP_TO="${TMP}/to" 49EXPECTED="${TMP}/expected" 50rm -rf "${TMP}" 51mkdir -p "${TMP_FROM}" "${TMP_TO}" "${EXPECTED}" 52 53# In all the test scenario, we want to test "updating from PEPPY to LINK". 54TO_IMAGE="${TMP}/src.link" 55FROM_IMAGE="${TMP}/src.peppy" 56TO_HWID="X86 LINK TEST 6638" 57FROM_HWID="X86 PEPPY TEST 4211" 58cp -f "${LINK_BIOS}" "${TO_IMAGE}" 59cp -f "${PEPPY_BIOS}" "${FROM_IMAGE}" 60"${FUTILITY}" load_fmap "${FROM_IMAGE}" \ 61 RO_VPD:"${RO_VPD_BLOB}" RW_VPD:"${RO_VPD_BLOB}" 62cp -f "${FROM_IMAGE}" "${FROM_IMAGE}".unpatched 63 64patch_file() { 65 local file="$1" 66 local section="$2" 67 local section_offset="$3" 68 local data="$4" 69 70 # NAME OFFSET SIZE 71 local fmap_info 72 local base 73 local offset 74 75 fmap_info="$("${FUTILITY}" dump_fmap -p "${file}" "${section}")" 76 base="$(echo "${fmap_info}" | sed 's/^[^ ]* //; s/ [^ ]*$//')" 77 offset=$((base + section_offset)) 78 echo "offset: ${offset}" 79 printf "%b" "${data}" | dd of="${file}" bs=1 seek="${offset}" \ 80 conv=notrunc 81} 82 83# PEPPY and LINK have different platform element ("Google_Link" and 84# "Google_Peppy") in firmware ID so we want to hack them by changing 85# "Google_" to "Google.". 86patch_file "${TO_IMAGE}" RW_FWID_A 0 Google. 87patch_file "${TO_IMAGE}" RW_FWID_B 0 Google. 88patch_file "${TO_IMAGE}" RO_FRID 0 Google. 89patch_file "${FROM_IMAGE}" RW_FWID_A 0 Google. 90patch_file "${FROM_IMAGE}" RW_FWID_B 0 Google. 91patch_file "${FROM_IMAGE}" RO_FRID 0 Google. 92 93unpack_image() { 94 local folder="${TMP}/$1" 95 local image="$2" 96 mkdir -p "${folder}" 97 (cd "${folder}" && "${FUTILITY}" dump_fmap -x "../../${image}") 98 "${FUTILITY}" gbb -g --rootkey="${folder}/rootkey" "${image}" 99} 100 101# Unpack images so we can prepare expected results by individual sections. 102unpack_image "to" "${TO_IMAGE}" 103unpack_image "from" "${FROM_IMAGE}" 104 105# Hack FROM_IMAGE so it has same root key as TO_IMAGE (for RW update). 106FROM_DIFFERENT_ROOTKEY_IMAGE="${FROM_IMAGE}2" 107cp -f "${FROM_IMAGE}" "${FROM_DIFFERENT_ROOTKEY_IMAGE}" 108"${FUTILITY}" gbb -s --rootkey="${TMP_TO}/rootkey" "${FROM_IMAGE}" 109 110# Hack for quirks 111cp -f "${FROM_IMAGE}" "${FROM_IMAGE}.large" 112truncate -s $((8388608 * 2)) "${FROM_IMAGE}.large" 113 114# Create the FROM_SAME_RO_IMAGE using the RO from TO_IMAGE." 115FROM_SAME_RO_IMAGE="${FROM_IMAGE}.same_ro" 116cp -f "${FROM_IMAGE}" "${FROM_SAME_RO_IMAGE}" 117"${FUTILITY}" load_fmap "${FROM_SAME_RO_IMAGE}" \ 118 "RO_SECTION:${TMP_TO}/RO_SECTION" 119 120# Create GBB v1.2 images (for checking digest) 121GBB_OUTPUT="$("${FUTILITY}" gbb --digest "${TO_IMAGE}")" 122[ "${GBB_OUTPUT}" = "digest: <none>" ] 123TO_IMAGE_GBB12="${TO_IMAGE}.gbb12" 124HWID_DIGEST="adf64d2a434b610506153da42440b0b498d7369c0e98b629ede65eb59f4784fa" 125cp -f "${TO_IMAGE}" "${TO_IMAGE_GBB12}" 126patch_file "${TO_IMAGE_GBB12}" GBB 6 "\x02" 127"${FUTILITY}" gbb -s --hwid="${TO_HWID}" "${TO_IMAGE_GBB12}" 128GBB_OUTPUT="$("${FUTILITY}" gbb --digest "${TO_IMAGE_GBB12}")" 129[ "${GBB_OUTPUT}" = "digest: ${HWID_DIGEST} valid" ] 130 131# Create images with (empty) AP RO verification 132# (Patch FMAP to rename 'RO_UNUSED' to 'RO_GSCVD') 133cp -f "${FROM_IMAGE}" "${FROM_IMAGE}.locked" 134patch_file "${FROM_IMAGE}.locked" FMAP 0x0430 "RO_GSCVD\x00" 135cp -f "${FROM_IMAGE}.locked" "${FROM_IMAGE}.locked_same_desc" 136cp -f "${FROM_IMAGE}.locked" "${FROM_IMAGE}.unlocked" 137patch_file "${FROM_IMAGE}.unlocked" SI_DESC 0x60 \ 138 "\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff" 139"${FUTILITY}" load_fmap "${FROM_IMAGE}.locked_same_desc" \ 140 "SI_DESC:${TMP_TO}/SI_DESC" 141 142# Generate expected results. 143cp -f "${TO_IMAGE}" "${EXPECTED}/full" 144cp -f "${FROM_IMAGE}" "${EXPECTED}/rw" 145cp -f "${FROM_IMAGE}" "${EXPECTED}/a" 146cp -f "${FROM_IMAGE}" "${EXPECTED}/b" 147cp -f "${FROM_SAME_RO_IMAGE}" "${EXPECTED}/FROM_SAME_RO_IMAGE.b" 148cp -f "${FROM_IMAGE}" "${EXPECTED}/legacy" 149"${FUTILITY}" gbb -s --hwid="${FROM_HWID}" "${EXPECTED}/full" 150"${FUTILITY}" load_fmap "${EXPECTED}/full" \ 151 "RW_VPD:${TMP_FROM}/RW_VPD" \ 152 "RO_VPD:${TMP_FROM}/RO_VPD" 153"${FUTILITY}" load_fmap "${EXPECTED}/rw" \ 154 "RW_SECTION_A:${TMP_TO}/RW_SECTION_A" \ 155 "RW_SECTION_B:${TMP_TO}/RW_SECTION_B" \ 156 "RW_SHARED:${TMP_TO}/RW_SHARED" \ 157 "RW_LEGACY:${TMP_TO}/RW_LEGACY" 158"${FUTILITY}" load_fmap "${EXPECTED}/a" \ 159 "RW_SECTION_A:${TMP_TO}/RW_SECTION_A" 160"${FUTILITY}" load_fmap "${EXPECTED}/b" \ 161 "RW_SECTION_B:${TMP_TO}/RW_SECTION_B" 162"${FUTILITY}" load_fmap "${EXPECTED}/FROM_SAME_RO_IMAGE.b" \ 163 "RW_SECTION_B:${TMP_TO}/RW_SECTION_B" 164"${FUTILITY}" load_fmap "${EXPECTED}/legacy" \ 165 "RW_LEGACY:${TMP_TO}/RW_LEGACY" 166cp -f "${EXPECTED}/full" "${EXPECTED}/full.gbb12" 167patch_file "${EXPECTED}/full.gbb12" GBB 6 "\x02" 168"${FUTILITY}" gbb -s --hwid="${FROM_HWID}" "${EXPECTED}/full.gbb12" 169cp -f "${EXPECTED}/full" "${EXPECTED}/full.gbb0" 170"${FUTILITY}" gbb -s --flags=0 "${EXPECTED}/full.gbb0" 171cp -f "${FROM_IMAGE}" "${FROM_IMAGE}.gbb0" 172"${FUTILITY}" gbb -s --flags=0 "${FROM_IMAGE}.gbb0" 173cp -f "${EXPECTED}/full" "${EXPECTED}/full.gbb0x27" 174"${FUTILITY}" gbb -s --flags=0x27 "${EXPECTED}/full.gbb0x27" 175cp -f "${EXPECTED}/full" "${EXPECTED}/large" 176dd if=/dev/zero bs=8388608 count=1 | tr '\000' '\377' >>"${EXPECTED}/large" 177cp -f "${EXPECTED}/full" "${EXPECTED}/me_unlocked_eve" 178patch_file "${EXPECTED}/me_unlocked_eve" SI_DESC 0x60 \ 179 "\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff" 180cp -f "${EXPECTED}/full" "${EXPECTED}/me_preserved" 181"${FUTILITY}" load_fmap "${EXPECTED}/me_preserved" \ 182 "SI_ME:${TMP_FROM}/SI_ME" 183cp -f "${EXPECTED}/rw" "${EXPECTED}/rw.locked" 184patch_file "${EXPECTED}/rw.locked" FMAP 0x0430 "RO_GSCVD\x00" 185 186# A special set of images that only RO_VPD is preserved (RW_VPD is wiped) using 187# FMAP_AREA_PRESERVE (\010=0x08). 188TO_IMAGE_WIPE_RW_VPD="${TO_IMAGE}.wipe_rw_vpd" 189cp -f "${TO_IMAGE}" "${TO_IMAGE_WIPE_RW_VPD}" 190patch_file "${TO_IMAGE_WIPE_RW_VPD}" FMAP 0x3fc "$(printf '\010')" 191cp -f "${EXPECTED}/full" "${EXPECTED}/full.empty_rw_vpd" 192"${FUTILITY}" load_fmap "${EXPECTED}/full.empty_rw_vpd" \ 193 RW_VPD:"${TMP_TO}/RW_VPD" 194patch_file "${EXPECTED}/full.empty_rw_vpd" FMAP 0x3fc "$(printf '\010')" 195 196# Generate images for testing --unlock_me. 197# There are two ways to detect the platform: 198# - Read CONFIG_IFD_CHIPSET from config file in CBFS 199# - Fallback for nissa: check if CONFIG_IFD_BIN_PATH contains 'nissa' 200 201# Rename BOOT_STUB to COREBOOT, which is the default region used by cbfstool. 202rename_boot_stub() { 203 local image="$1" 204 local fmap_file="${TMP}/fmap" 205 206 "${FUTILITY}" dump_fmap "${image}" -x "FMAP:${fmap_file}" 207 sed -i 's/BOOT_STUB/COREBOOT\x00/g' "${fmap_file}" 208 "${FUTILITY}" load_fmap "${image}" "FMAP:${fmap_file}" 209} 210 211# Add the given line to the config file in CBFS. 212add_config() { 213 local image="$1" 214 local config_line="$2" 215 local config_file="${TMP}/config" 216 217 rename_boot_stub "${image}" 218 219 cbfstool "${image}" extract -n config -f "${config_file}" 220 echo "${config_line}" >>"${config_file}" 221 cbfstool "${image}" remove -n config 222 cbfstool "${image}" add -n config -f "${config_file}" -t raw 223} 224 225unlock_me() { 226 local image="$1" 227 228 patch_file "${image}" SI_DESC 0x60 \ 229 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" 230 patch_file "${image}" SI_DESC 0x154 \ 231 "\x00\x00\x00\x00" 232} 233 234IFD_CHIPSET='CONFIG_IFD_CHIPSET="adl"' 235IFD_PATH='CONFIG_IFD_BIN_PATH="3rdparty/blobs/mainboard/google/nissa/descriptor-craask.bin"' 236cp -f "${TO_IMAGE}" "${TO_IMAGE}.ifd_chipset" 237cp -f "${TO_IMAGE}" "${TO_IMAGE}.ifd_path" 238cp -f "${EXPECTED}/full" "${EXPECTED}/ifd_chipset" 239cp -f "${EXPECTED}/full" "${EXPECTED}/ifd_path" 240add_config "${TO_IMAGE}.ifd_chipset" "${IFD_CHIPSET}" 241add_config "${TO_IMAGE}.ifd_path" "${IFD_PATH}" 242add_config "${EXPECTED}/ifd_chipset" "${IFD_CHIPSET}" 243add_config "${EXPECTED}/ifd_path" "${IFD_PATH}" 244 245cp -f "${EXPECTED}/ifd_chipset" "${EXPECTED}/me_unlocked.ifd_chipset" 246cp -f "${EXPECTED}/ifd_path" "${EXPECTED}/me_unlocked.ifd_path" 247unlock_me "${EXPECTED}/me_unlocked.ifd_chipset" 248unlock_me "${EXPECTED}/me_unlocked.ifd_path" 249 250# Has 3 modes: 251# 1. $3 = "!something", run command, expect failure, 252# grep for something in log, fail if it is not present 253# 2. $3 = "something", run command, expect success, 254# cmp output to file named $3, fail if they are not the same 255# 3. $3 = "!", run command, expect success, fail to find a file named ! 256test_update() { 257 local test_name="$1" 258 local emu_src="$2" 259 local expected="$3" 260 local error_msg="${expected#!}" 261 local emu="${TMP}/emu" 262 local msg 263 264 shift 3 265 cp -f "${emu_src}" "${emu}" 266 echo "*** Test Item: ${test_name}" 267 if [ "${error_msg}" != "${expected}" ] && [ -n "${error_msg}" ]; then 268 msg="$(! "${FUTILITY}" update --emulate "${emu}" "$@" 2>&1)" 269 grep -qF -- "${error_msg}" <<<"${msg}" 270 else 271 "${FUTILITY}" update --emulate "${emu}" "$@" 272 cmp "${emu}" "${expected}" 273 fi 274} 275 276# --sys_props: mainfw_act, tpm_fwver, platform_ver, [wp_hw, wp_sw] 277# tpm_fwver = <data key version:16><firmware version:16>. 278# TO_IMAGE is signed with data key version = 1, firmware version = 4 => 0x10004. 279 280# Test Full update. 281test_update "Full update" \ 282 "${FROM_IMAGE}" "${EXPECTED}/full" \ 283 -i "${TO_IMAGE}" --wp=0 284 285test_update "Full update (incompatible platform)" \ 286 "${FROM_IMAGE}" "!platform is not compatible" \ 287 -i "${LINK_BIOS}" --wp=0 288 289test_update "Full update (TPM Anti-rollback: data key)" \ 290 "${FROM_IMAGE}" "!Data key version rollback detected (2->1)" \ 291 -i "${TO_IMAGE}" --wp=0 --sys_props 1,0x20001 292 293test_update "Full update (TPM Anti-rollback: kernel key)" \ 294 "${FROM_IMAGE}" "!Firmware version rollback detected (5->4)" \ 295 -i "${TO_IMAGE}" --wp=0 --sys_props 1,0x10005 296 297test_update "Full update (TPM Anti-rollback: 0 as tpm_fwver)" \ 298 "${FROM_IMAGE}" "${EXPECTED}/full" \ 299 -i "${TO_IMAGE}" --wp=0 --sys_props ,0x0 300 301test_update "Full update (TPM check failure due to invalid tpm_fwver)" \ 302 "${FROM_IMAGE}" "!Invalid tpm_fwver: -1" \ 303 -i "${TO_IMAGE}" --wp=0 --sys_props ,-1 304 305test_update "Full update (Skip TPM check with --force)" \ 306 "${FROM_IMAGE}" "${EXPECTED}/full" \ 307 -i "${TO_IMAGE}" --wp=0 --sys_props ,-1 --force 308 309test_update "Full update (from stdin)" \ 310 "${FROM_IMAGE}" "${EXPECTED}/full" \ 311 -i - --wp=0 --sys_props ,-1 --force <"${TO_IMAGE}" 312 313test_update "Full update (GBB=0 -> 0)" \ 314 "${FROM_IMAGE}.gbb0" "${EXPECTED}/full.gbb0" \ 315 -i "${TO_IMAGE}" --wp=0 316 317test_update "Full update (GBB flags -> 0x27)" \ 318 "${FROM_IMAGE}" "${EXPECTED}/full.gbb0x27" \ 319 -i "${TO_IMAGE}" --gbb_flags=0x27 --wp=0 320 321test_update "Full update (--host_only)" \ 322 "${FROM_IMAGE}" "${EXPECTED}/full" \ 323 -i "${TO_IMAGE}" --wp=0 --host_only --ec_image non-exist.bin 324 325test_update "Full update (GBB1.2 hwid digest)" \ 326 "${FROM_IMAGE}" "${EXPECTED}/full.gbb12" \ 327 -i "${TO_IMAGE_GBB12}" --wp=0 328 329test_update "Full update (Preserve VPD using FMAP_AREA_PRESERVE)" \ 330 "${FROM_IMAGE}" "${EXPECTED}/full.empty_rw_vpd" \ 331 -i "${TO_IMAGE_WIPE_RW_VPD}" --wp=0 332 333 334# Test RW-only update. 335test_update "RW update" \ 336 "${FROM_IMAGE}" "${EXPECTED}/rw" \ 337 -i "${TO_IMAGE}" --wp=1 338 339test_update "RW update (incompatible platform)" \ 340 "${FROM_IMAGE}" "!platform is not compatible" \ 341 -i "${LINK_BIOS}" --wp=1 342 343test_update "RW update (incompatible rootkey)" \ 344 "${FROM_DIFFERENT_ROOTKEY_IMAGE}" "!RW signed by incompatible root key" \ 345 -i "${TO_IMAGE}" --wp=1 346 347test_update "RW update (TPM Anti-rollback: data key)" \ 348 "${FROM_IMAGE}" "!Data key version rollback detected (2->1)" \ 349 -i "${TO_IMAGE}" --wp=1 --sys_props 1,0x20001 350 351test_update "RW update (TPM Anti-rollback: kernel key)" \ 352 "${FROM_IMAGE}" "!Firmware version rollback detected (5->4)" \ 353 -i "${TO_IMAGE}" --wp=1 --sys_props 1,0x10005 354 355# Test Try-RW update (vboot2). 356test_update "RW update (A->B)" \ 357 "${FROM_IMAGE}" "${EXPECTED}/b" \ 358 -i "${TO_IMAGE}" -t --wp=1 --sys_props 0 359 360test_update "RW update (B->A)" \ 361 "${FROM_IMAGE}" "${EXPECTED}/a" \ 362 -i "${TO_IMAGE}" -t --wp=1 --sys_props 1 363 364test_update "RW update, same RO, wp=0 (A->B)" \ 365 "${FROM_SAME_RO_IMAGE}" "${EXPECTED}/FROM_SAME_RO_IMAGE.b" \ 366 -i "${TO_IMAGE}" -t --wp=0 --sys_props 0 367 368test_update "RW update, same RO, wp=1 (A->B)" \ 369 "${FROM_SAME_RO_IMAGE}" "${EXPECTED}/FROM_SAME_RO_IMAGE.b" \ 370 -i "${TO_IMAGE}" -t --wp=1 --sys_props 0 371 372test_update "RW update -> fallback to RO+RW Full update" \ 373 "${FROM_IMAGE}" "${EXPECTED}/full" \ 374 -i "${TO_IMAGE}" -t --wp=0 --sys_props 1,0x10002 375test_update "RW update (incompatible platform)" \ 376 "${FROM_IMAGE}" "!platform is not compatible" \ 377 -i "${LINK_BIOS}" -t --wp=1 378 379test_update "RW update (incompatible rootkey)" \ 380 "${FROM_DIFFERENT_ROOTKEY_IMAGE}" "!RW signed by incompatible root key" \ 381 -i "${TO_IMAGE}" -t --wp=1 382 383test_update "RW update (TPM Anti-rollback: data key)" \ 384 "${FROM_IMAGE}" "!Data key version rollback detected (2->1)" \ 385 -i "${TO_IMAGE}" -t --wp=1 --sys_props 1,0x20001 386 387test_update "RW update (TPM Anti-rollback: kernel key)" \ 388 "${FROM_IMAGE}" "!Firmware version rollback detected (5->4)" \ 389 -i "${TO_IMAGE}" -t --wp=1 --sys_props 1,0x10005 390 391test_update "RW update -> fallback to RO+RW Full update (TPM Anti-rollback)" \ 392 "${FROM_IMAGE}" "!Firmware version rollback detected (6->4)" \ 393 -i "${TO_IMAGE}" -t --wp=0 --sys_props 1,0x10006 394 395# Test 'factory mode' 396test_update "Factory mode update (WP=0)" \ 397 "${FROM_IMAGE}" "${EXPECTED}/full" \ 398 -i "${TO_IMAGE}" --wp=0 --mode=factory 399 400test_update "Factory mode update (WP=0)" \ 401 "${FROM_IMAGE}" "${EXPECTED}/full" \ 402 --factory -i "${TO_IMAGE}" --wp=0 403 404test_update "Factory mode update (WP=1)" \ 405 "${FROM_IMAGE}" "!remove write protection for factory mode" \ 406 -i "${TO_IMAGE}" --wp=1 --mode=factory 407 408test_update "Factory mode update (WP=1)" \ 409 "${FROM_IMAGE}" "!remove write protection for factory mode" \ 410 --factory -i "${TO_IMAGE}" --wp=1 411 412test_update "Factory mode update (GBB=0 -> 0x39)" \ 413 "${FROM_IMAGE}.gbb0" "${EXPECTED}/full" \ 414 --factory -i "${TO_IMAGE}" --wp=0 415 416# Test 'AP RO locked with verification turned on' 417test_update "AP RO locked update (locked, SI_DESC is different)" \ 418 "${FROM_IMAGE}.locked" "${EXPECTED}/rw.locked" \ 419 -i "${TO_IMAGE}" --wp=0 --debug 420 421test_update "AP RO locked update (locked, SI_DESC is the same)" \ 422 "${FROM_IMAGE}.locked_same_desc" "${EXPECTED}/full" \ 423 -i "${TO_IMAGE}" --wp=0 --debug 424 425test_update "AP RO locked update (unlocked)" \ 426 "${FROM_IMAGE}.unlocked" "${EXPECTED}/full" \ 427 -i "${TO_IMAGE}" --wp=0 --debug 428 429# Test legacy update 430test_update "Legacy update" \ 431 "${FROM_IMAGE}" "${EXPECTED}/legacy" \ 432 -i "${TO_IMAGE}" --mode=legacy 433 434# Test quirks 435test_update "Full update (wrong size)" \ 436 "${FROM_IMAGE}.large" "!Failed writing firmware" \ 437 -i "${TO_IMAGE}" --wp=0 \ 438 --quirks unlock_csme_eve,eve_smm_store 439 440test_update "Full update (--quirks enlarge_image)" \ 441 "${FROM_IMAGE}.large" "${EXPECTED}/large" --quirks enlarge_image \ 442 -i "${TO_IMAGE}" --wp=0 443 444test_update "Full update (multi-line --quirks enlarge_image)" \ 445 "${FROM_IMAGE}.large" "${EXPECTED}/large" --quirks ' 446 enlarge_image 447 ' -i "${TO_IMAGE}" --wp=0 448 449test_update "Full update (--quirks unlock_csme_eve)" \ 450 "${FROM_IMAGE}" "${EXPECTED}/me_unlocked_eve" \ 451 --quirks unlock_csme_eve \ 452 -i "${TO_IMAGE}" --wp=0 453 454test_update "Full update (failure by --quirks min_platform_version)" \ 455 "${FROM_IMAGE}" "!Need platform version >= 3 (current is 2)" \ 456 --quirks min_platform_version=3 \ 457 -i "${TO_IMAGE}" --wp=0 --sys_props ,,2 458 459test_update "Full update (--quirks min_platform_version)" \ 460 "${FROM_IMAGE}" "${EXPECTED}/full" \ 461 --quirks min_platform_version=3 \ 462 -i "${TO_IMAGE}" --wp=0 --sys_props ,,3 463 464test_update "Full update (incompatible platform)" \ 465 "${FROM_IMAGE}".unpatched "!platform is not compatible" \ 466 -i "${TO_IMAGE}" --wp=0 467 468test_update "Full update (--quirks no_check_platform)" \ 469 "${FROM_IMAGE}".unpatched "${EXPECTED}/full" \ 470 --quirks no_check_platform \ 471 -i "${TO_IMAGE}" --wp=0 472 473test_update "Full update (--quirks preserve_me with non-host programmer)" \ 474 "${FROM_IMAGE}" "${EXPECTED}/full" \ 475 --quirks preserve_me \ 476 -i "${TO_IMAGE}" --wp=0 \ 477 -p raiden_debug_spi:target=AP 478 479test_update "Full update (--quirks preserve_me)" \ 480 "${FROM_IMAGE}" "${EXPECTED}/full" \ 481 --quirks preserve_me \ 482 -i "${TO_IMAGE}" --wp=0 483 484test_update "Full update (--quirks preserve_me, autoupdate)" \ 485 "${FROM_IMAGE}" "${EXPECTED}/me_preserved" \ 486 --quirks preserve_me -m autoupdate \ 487 -i "${TO_IMAGE}" --wp=0 488 489test_update "Full update (--quirks preserve_me, deferupdate_hold)" \ 490 "${FROM_IMAGE}" "${EXPECTED}/me_preserved" \ 491 --quirks preserve_me -m deferupdate_hold \ 492 -i "${TO_IMAGE}" --wp=0 493 494test_update "Full update (--quirks preserve_me, factory)" \ 495 "${FROM_IMAGE}" "${EXPECTED}/full" \ 496 --quirks preserve_me -m factory \ 497 -i "${TO_IMAGE}" --wp=0 498 499# Test manifest. 500TMP_JSON_OUT="${TMP}/json.out" 501echo "TEST: Manifest (--manifest, --image)" 502cp -f "${GERALT_BIOS}" "${TMP}/image.bin" 503(cd "${TMP}" && 504 "${FUTILITY}" update -i image.bin --manifest) >"${TMP_JSON_OUT}" 505cmp \ 506 <(jq -S <"${TMP_JSON_OUT}") \ 507 <(jq -S <"${SCRIPT_DIR}/futility/bios_geralt_cbfs.manifest.json") 508 509# Test archive and manifest. CL_TAG is for custom_label_tag. 510A="${TMP}/archive" 511mkdir -p "${A}/bin" 512echo 'echo "${CL_TAG}"' >"${A}/bin/vpd" 513chmod +x "${A}/bin/vpd" 514 515cp -f "${LINK_BIOS}" "${A}/bios.bin" 516echo "TEST: Manifest (--manifest, -a, bios.bin)" 517"${FUTILITY}" update -a "${A}" --manifest >"${TMP_JSON_OUT}" 518cmp \ 519 <(jq -S <"${TMP_JSON_OUT}") \ 520 <(jq -S <"${SCRIPT_DIR}/futility/link_bios.manifest.json") 521 522mv -f "${A}/bios.bin" "${A}/image.bin" 523echo "TEST: Manifest (--manifest, -a, image.bin)" 524"${FUTILITY}" update -a "${A}" --manifest >"${TMP_JSON_OUT}" 525cmp \ 526 <(jq -S <"${TMP_JSON_OUT}") \ 527 <(jq -S <"${SCRIPT_DIR}/futility/link_image.manifest.json") 528 529 530cp -f "${TO_IMAGE}" "${A}/image.bin" 531test_update "Full update (--archive, single package)" \ 532 "${FROM_IMAGE}" "${EXPECTED}/full" \ 533 -a "${A}" --wp=0 --sys_props ,,3 534 535echo "TEST: Output (--archive, --mode=output)" 536TMP_OUTPUT="${TMP}/out_archive" && mkdir -p "${TMP_OUTPUT}" 537"${FUTILITY}" update -a "${A}" --mode=output \ 538 --output_dir="${TMP_OUTPUT}" 539cmp "${TMP_OUTPUT}/image.bin" "${TO_IMAGE}" 540 541# Test Unified Build archives. 542mkdir -p "${A}/keyset" "${A}/images" 543cp -f "${SIGNER_CONFIG}" "${A}/" 544cp -f "${LINK_BIOS}" "${A}/image.bin" 545"${FUTILITY}" gbb -s --rootkey="${TMP_FROM}/rootkey" "${A}/image.bin" 546"${FUTILITY}" load_fmap "${A}/image.bin" VBLOCK_A:"${TMP_FROM}/VBLOCK_A" 547"${FUTILITY}" load_fmap "${A}/image.bin" VBLOCK_B:"${TMP_FROM}/VBLOCK_B" 548mv -f "${A}/image.bin" "${A}/images/bios_coral.bin" 549cp -f "${PEPPY_BIOS}" "${A}/images/bios_peppy.bin" 550cp -f "${LINK_BIOS}" "${A}/images/bios_link.bin" 551cp -f "${TMP_TO}/rootkey" "${A}/keyset/rootkey.customtip-cl" 552cp -f "${TMP_TO}/VBLOCK_A" "${A}/keyset/vblock_A.customtip-cl" 553cp -f "${TMP_TO}/VBLOCK_B" "${A}/keyset/vblock_B.customtip-cl" 554cp -f "${PEPPY_BIOS}" "${FROM_IMAGE}.ap" 555cp -f "${LINK_BIOS}" "${FROM_IMAGE}.al" 556cp -f "${VOXEL_BIOS}" "${FROM_IMAGE}.av" 557patch_file "${FROM_IMAGE}.ap" FW_MAIN_A 0 "corrupted" 558patch_file "${FROM_IMAGE}.al" FW_MAIN_A 0 "corrupted" 559patch_file "${FROM_IMAGE}.av" FW_MAIN_A 0 "corrupted" 560test_update "Full update (--archive, model=link)" \ 561 "${FROM_IMAGE}.al" "${LINK_BIOS}" \ 562 -a "${A}" --wp=0 --sys_props 0,0x10001,3 --model=link 563test_update "Full update (--archive, model=peppy)" \ 564 "${FROM_IMAGE}.ap" "${PEPPY_BIOS}" \ 565 -a "${A}" --wp=0 --sys_props 0,0x10001,3 --model=peppy 566test_update "Full update (--archive, model=unknown)" \ 567 "${FROM_IMAGE}.ap" "!Unsupported model: 'unknown'" \ 568 -a "${A}" --wp=0 --sys_props 0,0x10001,3 --model=unknown 569 570test_update "Full update (--archive, detect-model)" \ 571 "${FROM_IMAGE}.ap" "${PEPPY_BIOS}" \ 572 -a "${A}" --wp=0 --sys_props 0,0x10001,3 \ 573 --programmer raiden_debug_spi:target=AP 574test_update "Full update (--archive, detect-model, unsupported FRID)" \ 575 "${FROM_IMAGE}.av" "!Unsupported FRID: 'Google_Voxel'" \ 576 -a "${A}" --wp=0 --sys_props 0,0x10001,3 \ 577 --programmer raiden_debug_spi:target=AP 578 579echo "*** Test Item: Detect model (--archive, --detect-model-only)" 580"${FUTILITY}" update -a "${A}" \ 581 --emulate "${FROM_IMAGE}.ap" --detect-model-only >"${TMP}/model.out" 582cmp "${TMP}/model.out" <(echo peppy) 583 584test_update "Full update (--archive, custom label with tag specified)" \ 585 "${FROM_IMAGE}.al" "${LINK_BIOS}" \ 586 -a "${A}" --wp=0 --sys_props 0,0x10001,3 --model=customtip-cl 587CL_TAG="bad" PATH="${A}/bin:${PATH}" \ 588 test_update "Full update (--archive, custom label, wrong image)" \ 589 "${FROM_IMAGE}.al" "!The firmware image for custom label" \ 590 -a "${A}" --wp=0 --sys_props 0,0x10001,3 --debug --model=customtip 591CL_TAG="cl" PATH="${A}/bin:${PATH}" \ 592 test_update "Full update (--archive, custom label, fake VPD)" \ 593 "${FROM_IMAGE}.al" "${LINK_BIOS}" \ 594 -a "${A}" --wp=0 --sys_props 0,0x10001,3 --model=customtip 595 596# The output mode (without specifying signature id) for custom label would still 597# need a source (emulate) image to decide the VPD, which is not a real use case. 598echo "TEST: Output (--archive, --mode=output, custom label with tag specified)" 599TMP_OUTPUT="${TMP}/out_custom_label" && mkdir -p "${TMP_OUTPUT}" 600"${FUTILITY}" update -a "${A}" --mode=output \ 601 --output_dir="${TMP_OUTPUT}" --model=customtip-cl 602cmp "${TMP_OUTPUT}/image.bin" "${LINK_BIOS}" 603 604# Custom label + Unibuild with default keys as model name 605cp -f "${TMP_TO}/rootkey" "${A}/keyset/rootkey.customtip" 606cp -f "${TMP_TO}/VBLOCK_A" "${A}/keyset/vblock_A.customtip" 607cp -f "${TMP_TO}/VBLOCK_B" "${A}/keyset/vblock_B.customtip" 608test_update "Full update (--archive, custom label, no VPD, default keys)" \ 609 "${FROM_IMAGE}.al" "${LINK_BIOS}" \ 610 -a "${A}" --wp=0 --sys_props 0,0x10001,3 --model=customtip 611 612# Test special programmer 613test_flashrom() { 614 echo "TEST: Full update (dummy programmer)" 615 local emu="${TMP}/emu" 616 cp -f "${FROM_IMAGE}" "${emu}" 617 "${FUTILITY}" update --programmer \ 618 dummy:emulate=VARIABLE_SIZE,image="${emu}",size=8388608 \ 619 -i "${TO_IMAGE}" --wp=0 --sys_props 0,0x10001,3 >&2 620 cmp "${emu}" "${EXPECTED}/full" 621} 622type flashrom >/dev/null 2>&1 && test_flashrom 623 624test_cbfstool() { 625 echo "TEST: Update with cbsfstool" 626 local smm="${TMP}/smm" 627 local cbfs="${TMP}/cbfs" 628 local quirk="${TMP}/quirk" 629 630 echo "SMM STORE" >"${smm}" 631 truncate -s 262144 "${smm}" 632 cp -f "${FROM_IMAGE}" "${TMP_FROM}.smm" 633 cp -f "${EXPECTED}/full" "${EXPECTED}/full_smm" 634 cbfstool "${TMP_FROM}.smm" add -r RW_LEGACY -n "smm_store" \ 635 -f "${smm}" -t raw 636 cbfstool "${EXPECTED}/full_smm" add -r RW_LEGACY -n "smm_store" \ 637 -f "${smm}" -t raw -b 0x1bf000 638 test_update "Legacy update (--quirks eve_smm_store)" \ 639 "${TMP_FROM}.smm" "${EXPECTED}/full_smm" \ 640 -i "${TO_IMAGE}" --wp=0 \ 641 --quirks eve_smm_store 642 643 echo "min_platform_version=3" >"${quirk}" 644 cp -f "${TO_IMAGE}" "${TO_IMAGE}.quirk" 645 "${FUTILITY}" dump_fmap -x "${TO_IMAGE}" "BOOT_STUB:${cbfs}" 646 # Create a fake CBFS using FW_MAIN_A size. 647 truncate -s $((0x000dffc0)) "${cbfs}" 648 "${FUTILITY}" load_fmap "${TO_IMAGE}.quirk" "FW_MAIN_A:${cbfs}" 649 cbfstool "${TO_IMAGE}.quirk" add -r FW_MAIN_A -n updater_quirks \ 650 -f "${quirk}" -t raw 651 test_update "Full update (failure by CBFS quirks)" \ 652 "${FROM_IMAGE}" "!Need platform version >= 3 (current is 2)" \ 653 -i "${TO_IMAGE}.quirk" --wp=0 --sys_props 0,0x10001,2 654} 655type cbfstool >/dev/null 2>&1 && test_cbfstool 656 657test_ifdtool() { 658 test_update "Full update (--quirks unlock_csme, IFD chipset)" \ 659 "${FROM_IMAGE}" "${EXPECTED}/me_unlocked.ifd_chipset" \ 660 --quirks unlock_csme -i "${TO_IMAGE}.ifd_chipset" --wp=0 661 662 test_update "Full update (--quirks unlock_csme, IFD bin path)" \ 663 "${FROM_IMAGE}" "${EXPECTED}/me_unlocked.ifd_path" \ 664 --quirks unlock_csme -i "${TO_IMAGE}.ifd_path" --wp=0 665 666 test_update "Full update (--unlock_me)" \ 667 "${FROM_IMAGE}" "${EXPECTED}/me_unlocked.ifd_chipset" \ 668 --unlock_me -i "${TO_IMAGE}.ifd_chipset" --wp=0 669 670 echo "TEST: Output (--mode=output, --quirks unlock_csme)" 671 TMP_OUTPUT="${TMP}/out_csme" && mkdir -p "${TMP_OUTPUT}" 672 mkdir -p "${TMP_OUTPUT}" 673 "${FUTILITY}" update -i "${EXPECTED}/ifd_chipset" --mode=output \ 674 --output_dir="${TMP_OUTPUT}" --quirks unlock_csme 675 cmp "${TMP_OUTPUT}/image.bin" "${EXPECTED}/me_unlocked.ifd_chipset" 676} 677type ifdtool >/dev/null 2>&1 && test_ifdtool 678 679rm -rf "${TMP}" 680exit 0 681