summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Werner <jwerner@chromium.org>2020-06-02 16:09:22 -0700
committerCommit Bot <commit-bot@chromium.org>2020-06-06 00:17:55 +0000
commit08c2ee1bc9ed96f6f124b428b6027cad9a508937 (patch)
treeec26d00b44673f16992301bf19eaa1155ee9357f
parentddf24c46aa59b5432de5aec776b2777a440c75fd (diff)
downloadvboot-08c2ee1bc9ed96f6f124b428b6027cad9a508937.tar.gz
chromeos-tpm-recovery: Add support for v1 secdata_kernel
The recent format changes to the kernel TPM NVRAM space weren't reflected in the chromeos-tpm-recovery utility yet. This patch fixes that. Since this may require upgrading from the old to the new format (or even the other way around), we also have to fix the longstanding limitation of not recreating TPM spaces for TPM 2.0. We still cannot do that for the firmware TPM space, but at least we can add it for the kernel one. BRANCH=none BUG=chromium:1020578,b:155149943 TEST=Ran on a Trogdor Signed-off-by: Julius Werner <jwerner@chromium.org> Change-Id: Iaf9bc6b29f76cfeaab90ae4f99099735c4f9441b Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/2227260 Reviewed-by: Andrey Pronin <apronin@chromium.org> Reviewed-by: Joel Kitching <kitching@chromium.org>
-rwxr-xr-xutility/chromeos-tpm-recovery89
1 files changed, 71 insertions, 18 deletions
diff --git a/utility/chromeos-tpm-recovery b/utility/chromeos-tpm-recovery
index e2b0a8de..28a8fa3d 100755
--- a/utility/chromeos-tpm-recovery
+++ b/utility/chromeos-tpm-recovery
@@ -16,6 +16,8 @@ awk=/usr/bin/awk
initctl=/sbin/initctl
daemon_was_running=
err=0
+secdata_firmware=0x1007
+secdata_kernel=0x1008
tpm2_target() {
# This is not an ideal way to tell if we are running on a tpm2 target, but
@@ -27,6 +29,32 @@ tpm2_target() {
fi
}
+use_v0_secdata_kernel() {
+ local fwid=$(crossystem ro_fwid)
+ local major=$(printf "$fwid" | cut -d. -f2)
+ local minor=$(printf "$fwid" | cut -d. -f3)
+
+ # TPM1 firmware never supports the v1 kernel space format.
+ if ! tpm2_target; then
+ return 0
+ fi
+
+ # First some sanity checks: X -eq X checks that X is a number. cut may return
+ # the whole string if no delimiter found, so major != minor checks that the
+ # version was at least somewhat correctly formatted.
+ if [ $major -eq $major ] && [ $minor -eq $minor ] && [ $major -ne $minor ]; then
+ # Now what we really care about: is this firmware older than CL:2041695?
+ if [ $major -lt 12953 ]; then
+ return 0
+ else
+ return 1
+ fi
+ else
+ log "Cannot parse FWID. Assuming local build that supports v1 kernel space."
+ return 1
+ fi
+}
+
log() {
echo "$*"
}
@@ -63,27 +91,49 @@ tpm_clear_and_reenable () {
$tpmc activate
}
-reset_space () {
+write_space () {
+ # do not quote "$2", as we mean to expand it here
+ if ! $tpmc write $1 $2; then
+ log_error "writing to $1 failed"
+ else
+ log "$1 written successfully"
+ fi
+}
+
+reset_ro_space () {
local index=$1
- local permissions=$2
- local size=$3
- local bytes="$4"
+ local bytes="$2"
+ local size=$(printf "$bytes" | wc -w)
+ local permissions=0x8001
- if ! tpm2_target; then
- # definespace is not yet supported for tpm2 (crosbug.com/p/59361), let's
- # just rely on the firmware having created the required spaces for now.
+ if tpm2_target; then
+ log "Cannot redefine RO space for TPM2 (b/140958855). Let's just hope it looks good..."
+ else
if ! $tpmc definespace $index $size $permissions; then
- log "could not redefine space $index"
- return 1
+ log_error "could not redefine RO space $index"
+ # try writing it anyway, just in case it works...
fi
fi
- # do not quote "$bytes", as we mean to expand it here
- if ! $tpmc write $index $bytes; then
- log "writing to $index failed"
- return 1
+ write_space $index "$bytes"
+}
+
+reset_rw_space () {
+ local index=$1
+ local bytes="$2"
+ local size=$(printf "$bytes" | wc -w)
+ local permissions=0x1
+
+ if tpm2_target; then
+ permissions=0x40050001
+ fi
+
+ if ! $tpmc definespace $index $size $permissions; then
+ log_error "could not redefine RW space $index"
+ # try writing it anyway, just in case it works...
fi
- log "space $index was recreated successfully"
+
+ write_space $index "$bytes"
}
restart_daemon_if_needed() {
@@ -161,10 +211,13 @@ fi
tpm_clear_and_reenable
# Reset firmware and kernel spaces to default (rollback version 1/1)
-reset_space 0x1007 0x8001 0xa "02 00 01 00 01 00 00 00 00 4f" || \
- log_error "could not fix firmware space"
-reset_space 0x1008 0x1 0xd "02 4c 57 52 47 01 00 01 00 00 00 00 55" || \
- log_error "could not fix kernel space"
+reset_ro_space $secdata_firmware "02 0 1 0 1 0 0 0 0 4f"
+
+if use_v0_secdata_kernel; then
+ reset_rw_space $secdata_kernel "02 4c 57 52 47 1 0 1 0 0 0 0 55"
+else
+ reset_rw_space $secdata_kernel "10 28 0c 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"
+fi
restart_daemon_if_needed