Skip to content

Commit 5cfcc73

Browse files
committed
Addressing review and fix TPM counter file bugs
Signed-off-by: Thierry Laurion <[email protected]>
1 parent d731e1c commit 5cfcc73

12 files changed

+175
-182
lines changed

initrd/.bash_history

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ find /boot/kexec*.txt | gpg --verify /boot/kexec.sig -
55
#remove invalid kexec_* signed files
66
mount /dev/sda1 /boot && mount -o remount,rw /boot && rm /boot/kexec* && mount -o remount,ro /boot
77
#Generate keys on OpenPGP smartcard:
8-
mount-usb && gpg --home=/.gnupg/ --card-edit
8+
mount-usb --mode rw && gpg --home=/.gnupg/ --card-edit
99
#Copy generated public key, private_subkey, trustdb and artifacts to external media for backup:
10-
mount -o remount,rw /media && mkdir -p /media/gpg_keys; gpg --export-secret-keys --armor [email protected] > /media/gpg_keys/private.key && gpg --export --armor [email protected] > /media/gpg_keys/public.key && gpg --export-ownertrust > /media/gpg_keys/otrust.txt && cp -r ./.gnupg/* /media/gpg_keys/ 2> /dev/null
10+
mkdir -p /media/gpg_keys; gpg --export-secret-keys --armor [email protected] > /media/gpg_keys/private.key && gpg --export --armor [email protected] > /media/gpg_keys/public.key && gpg --export-ownertrust > /media/gpg_keys/otrust.txt && cp -r ./.gnupg/* /media/gpg_keys/ 2> /dev/null
1111
#Insert public key and trustdb export into reproducible rom:
1212
cbfs -o /media/coreboot.rom -a "heads/initrd/.gnupg/keys/public.key" -f /media/gpg_keys/public.key && cbfs -o /media/coreboot.rom -a "heads/initrd/.gnupg/keys/otrust.txt" -f /media/gpg_keys/otrust.txt
1313
#Flush changes to external media:

initrd/bin/gui-init

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,9 +270,9 @@ update_hotp() {
270270
fi
271271

272272
if [[ "$HOTP" = "Invalid code" ]]; then
273-
#TODO: we shouldn't propose to generate a new secret if there is no /boot/kexec_hotp_counter
274-
# as this passed tpm unseal, so the secret is correct: we should propose to reset TPM instead
275-
# Otherwise, tpm_counter is also inexistent: The OS was most probably reinstalled wihile TPM can still unseal the secret
273+
#Do not propose to generate a new secret if there is no /boot/kexec_hotp_counter
274+
# tpm unseal succeeded: so the sealed secret is correct: we should propose to reset TPM if not already
275+
# Here: the OS was most probably reinstalled since TPM can still unseal the secret
276276
whiptail_error --title "ERROR: HOTP Validation Failed!" \
277277
--menu "ERROR: $CONFIG_BRAND_NAME couldn't validate the HOTP code.\n\nIf you just reflashed your BIOS, you should generate a new TOTP/HOTP secret.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nHow would you like to proceed?" 0 80 4 \
278278
'g' ' Generate new TOTP/HOTP secret' \

initrd/bin/kexec-save-default

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ TRACE_FUNC
88

99
while getopts "b:d:p:i:" arg; do
1010
case $arg in
11-
b) bootdir="$OPTARG" ;;
12-
d) paramsdev="$OPTARG" ;;
13-
p) paramsdir="$OPTARG" ;;
14-
i) index="$OPTARG" ;;
11+
b) bootdir="$OPTARG" ;;
12+
d) paramsdev="$OPTARG" ;;
13+
p) paramsdir="$OPTARG" ;;
14+
i) index="$OPTARG" ;;
1515
esac
1616
done
1717

initrd/bin/kexec-select-boot

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,25 @@ force_boot="n"
2020
skip_confirm="n"
2121
while getopts "b:d:p:a:r:c:uimgfs" arg; do
2222
case $arg in
23-
b) bootdir="$OPTARG" ;;
24-
d) paramsdev="$OPTARG" ;;
25-
p) paramsdir="$OPTARG" ;;
26-
a) add="$OPTARG" ;;
27-
r) remove="$OPTARG" ;;
28-
c) config="$OPTARG" ;;
29-
u) unique="y" ;;
30-
m) force_menu="y" ;;
31-
i)
32-
valid_hash="y"
33-
valid_rollback="y"
34-
;;
35-
g) gui_menu="y" ;;
36-
f)
37-
force_boot="y"
38-
valid_hash="y"
39-
valid_rollback="y"
40-
;;
41-
s) skip_confirm="y" ;;
23+
b) bootdir="$OPTARG" ;;
24+
d) paramsdev="$OPTARG" ;;
25+
p) paramsdir="$OPTARG" ;;
26+
a) add="$OPTARG" ;;
27+
r) remove="$OPTARG" ;;
28+
c) config="$OPTARG" ;;
29+
u) unique="y" ;;
30+
m) force_menu="y" ;;
31+
i)
32+
valid_hash="y"
33+
valid_rollback="y"
34+
;;
35+
g) gui_menu="y" ;;
36+
f)
37+
force_boot="y"
38+
valid_hash="y"
39+
valid_rollback="y"
40+
;;
41+
s) skip_confirm="y" ;;
4242
esac
4343
done
4444

initrd/bin/kexec-sign-config

Lines changed: 96 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#!/bin/bash
2-
# filepath: /home/user/heads/initrd/bin/kexec-sign-config
32
# Sign a valid directory of kexec params
43
set -e -o pipefail
54
. /tmp/config
@@ -10,19 +9,19 @@ TRACE_FUNC
109
rollback="n"
1110
update="n"
1211
while getopts "p:c:ur" arg; do
13-
case $arg in
14-
p) paramsdir="$OPTARG" ;;
15-
c)
16-
counter="$OPTARG"
17-
rollback="y"
18-
;;
19-
u) update="y" ;;
20-
r) rollback="y" ;;
21-
esac
12+
case $arg in
13+
p) paramsdir="$OPTARG" ;;
14+
c)
15+
counter="$OPTARG"
16+
rollback="y"
17+
;;
18+
u) update="y" ;;
19+
r) rollback="y" ;;
20+
esac
2221
done
2322

2423
if [ -z "$paramsdir" ]; then
25-
die "Usage: $0 -p /boot [ -u | -c counter ]"
24+
die "Usage: $0 -p /boot [ -u | -c counter ]"
2625
fi
2726

2827
paramsdir="${paramsdir%%/}"
@@ -40,96 +39,102 @@ DEBUG "Signing kexec parameters in $paramsdir, rollback=$rollback, update=$updat
4039

4140
# update hashes in /boot before signing
4241
if [ "$update" = "y" ]; then
43-
(
44-
TRACE_FUNC
45-
DEBUG "update=y: Updating kexec hashes in /boot"
46-
cd /boot
47-
find ./ -type f ! -path './kexec*' -print0 | xargs -0 sha256sum >/boot/kexec_hashes.txt
48-
if [ -e /boot/kexec_default_hashes.txt ]; then
49-
DEBUG "/boot/kexec_default_hashes.txt exists, updating /boot/kexec_default_hashes.txt"
50-
DEFAULT_FILES=$(cat /boot/kexec_default_hashes.txt | cut -f3 -d ' ')
51-
echo $DEFAULT_FILES | xargs sha256sum >/boot/kexec_default_hashes.txt
52-
fi
53-
54-
#also save the file & directory structure to detect added files
55-
print_tree >/boot/kexec_tree.txt
56-
TRACE_FUNC
57-
)
58-
[ $? -eq 0 ] || die "$paramsdir: Failed to update hashes."
59-
60-
# Remove any package trigger log files
61-
# We don't need them after the user decides to sign
62-
rm -f /boot/kexec_package_trigger*
42+
(
43+
TRACE_FUNC
44+
DEBUG "update=y: Updating kexec hashes in /boot"
45+
cd /boot
46+
find ./ -type f ! -path './kexec*' -print0 | xargs -0 sha256sum >/boot/kexec_hashes.txt
47+
if [ -e /boot/kexec_default_hashes.txt ]; then
48+
DEBUG "/boot/kexec_default_hashes.txt exists, updating /boot/kexec_default_hashes.txt"
49+
DEFAULT_FILES=$(cat /boot/kexec_default_hashes.txt | cut -f3 -d ' ')
50+
echo $DEFAULT_FILES | xargs sha256sum >/boot/kexec_default_hashes.txt
51+
fi
52+
53+
#also save the file & directory structure to detect added files
54+
print_tree >/boot/kexec_tree.txt
55+
TRACE_FUNC
56+
)
57+
[ $? -eq 0 ] || die "$paramsdir: Failed to update hashes."
58+
59+
# Remove any package trigger log files
60+
# We don't need them after the user decides to sign
61+
rm -f /boot/kexec_package_trigger*
6362
fi
6463

6564
if [ "$rollback" = "y" ]; then
66-
67-
# this script was called with -c $OPTARG (counter=$OPTARG) or -r (rollback=y)
68-
DEBUG "rollback=y, counter=$counter, paramsdir=$paramsdir"
69-
TRACE_FUNC
70-
71-
rollback_file="$paramsdir/kexec_rollback.txt"
72-
73-
if [ -n "$counter" ]; then
74-
DEBUG "rollback=y: counter=$counter, will read tpm counter next"
75-
TRACE_FUNC
76-
77-
# use existing tpm counter
78-
DO_WITH_DEBUG read_tpm_counter $counter >/dev/null 2>&1 ||
79-
die "$paramsdir: Unable to read tpm counter '$counter'"
80-
else
81-
DEBUG "rollback=y: counter is empty: checking for existing TPM counter"
82-
TRACE_FUNC
83-
84-
if [ ! -e $rollback_file ]; then
85-
DEBUG "Rollback file $rollback_file does not exist. Creating new TPM counter."
86-
DO_WITH_DEBUG check_tpm_counter $rollback_file ||
87-
die "$paramsdir: Unable to find/create tpm counter"
88-
89-
TRACE_FUNC
90-
DEBUG "rollback=y: checked for existing counter under $rollback_file, found TPM_COUNTER=$TPM_COUNTER"
91-
# we checked for existing counter and didn't die; increment it
92-
DEBUG "rollback=y: Incrementing counter:$TPM_COUNTER."
93-
94-
DO_WITH_DEBUG increment_tpm_counter $counter >/dev/null 2>&1 ||
95-
die "$paramsdir: Unable to increment tpm counter"
96-
TRACE_FUNC
97-
DEBUG "rollback=y: Incremented counter $counter"
98-
else
99-
die "$paramsdir: No rollback file existing. Please reset TPM through the Heads menu: Options -> TPM/TOTP/HOTP Options -> Reset the TPM"
100-
fi
101-
fi
102-
103-
# Ensure the TPM counter file exists
104-
DEBUG "Checking if TPM counter file '/tmp/counter-$counter exists."
105-
if [ ! -e "/tmp/counter-$counter" ]; then
106-
die "$paramsdir: TPM counter file '/tmp/counter-$counter' not found after incrementing."
107-
fi
108-
109-
# Create the rollback file
110-
sha256sum /tmp/counter-$counter >$rollback_file ||
111-
die "$paramsdir: Unable to create rollback file"
65+
rollback_file="$paramsdir/kexec_rollback.txt"
66+
67+
DEBUG "rollback=y, counter=$counter, paramsdir=$paramsdir, rollback_file=$rollback_file"
68+
TRACE_FUNC
69+
70+
if [ -n "$counter" ]; then
71+
DEBUG "rollback=y: provided counter=$counter, will read tpm counter next"
72+
TRACE_FUNC
73+
74+
# use existing tpm counter
75+
DO_WITH_DEBUG read_tpm_counter "$counter" >/dev/null 2>&1 ||
76+
die "$paramsdir: Unable to read tpm counter '$counter'"
77+
else
78+
DEBUG "rollback=y: counter was not provided: checking for existing TPM counter from TPM rollback_file=$rollback_file"
79+
TRACE_FUNC
80+
81+
if [ -e "$rollback_file" ]; then
82+
# Extract TPM_COUNTER from rollback file
83+
TPM_COUNTER=$(grep -o 'counter-[0-9a-f]*' "$rollback_file" | cut -d- -f2)
84+
DEBUG "rollback=y: Found TPM counter $TPM_COUNTER in rollback file $rollback_file"
85+
else
86+
DEBUG "Rollback file $rollback_file does not exist. Creating new TPM counter."
87+
DO_WITH_DEBUG check_tpm_counter $rollback_file ||
88+
die "$paramsdir: Unable to find/create tpm counter"
89+
90+
TRACE_FUNC
91+
TPM_COUNTER=$(cut -d: -f1 </tmp/counter)
92+
DEBUG "rollback=y: Created new TPM counter $TPM_COUNTER"
93+
fi
94+
fi
95+
96+
TRACE_FUNC
97+
98+
# Increment the TPM counter
99+
DEBUG "rollback=y: Incrementing counter $TPM_COUNTER."
100+
DO_WITH_DEBUG increment_tpm_counter $TPM_COUNTER >/dev/null 2>&1 ||
101+
die "$paramsdir: Unable to increment tpm counter"
102+
103+
# Ensure the incremented counter file exists
104+
incremented_counter_file="/tmp/counter-$TPM_COUNTER"
105+
if [ ! -e "$incremented_counter_file" ]; then
106+
DEBUG "TPM counter file '$incremented_counter_file' not found. Attempting to read it again."
107+
DO_WITH_DEBUG read_tpm_counter "$TPM_COUNTER" >/dev/null 2>&1 ||
108+
die "$paramsdir: TPM counter file '$incremented_counter_file' not found after incrementing."
109+
fi
110+
111+
DEBUG "TPM counter file '$incremented_counter_file' found."
112+
113+
# Create the rollback file
114+
sha256sum "$incremented_counter_file" >$rollback_file ||
115+
die "$paramsdir: Unable to create rollback file"
112116
fi
113117

118+
TRACE_FUNC
114119
param_files=$(find $paramsdir/kexec*.txt)
115120
if [ -z "$param_files" ]; then
116-
die "$paramsdir: No kexec parameter files to sign"
121+
die "$paramsdir: No kexec parameter files to sign"
117122
fi
118123

119124
for tries in 1 2 3; do
120-
if DO_WITH_DEBUG sha256sum $param_files | gpg \
121-
--detach-sign \
122-
-a \
123-
>$paramsdir/kexec.sig \
124-
; then
125-
# successful - update the validated params
126-
check_config $paramsdir
127-
128-
# remount /boot as ro
129-
mount -o remount,ro /boot
130-
131-
exit 0
132-
fi
125+
if DO_WITH_DEBUG sha256sum $param_files | gpg \
126+
--detach-sign \
127+
-a \
128+
>$paramsdir/kexec.sig \
129+
; then
130+
# successful - update the validated params
131+
check_config $paramsdir
132+
133+
# remount /boot as ro
134+
mount -o remount,ro /boot
135+
136+
exit 0
137+
fi
133138
done
134139

135140
# remount /boot as ro

initrd/bin/key-init

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ TRACE_FUNC
1010
# Good system clock is required for GPG to work properly.
1111
# if system year is less then 2024, prompt user to set correct time
1212
if [ "$(date +%Y)" -lt 2024 ]; then
13-
if whiptail_warning --title "System Time Incorrect" \
14-
--yesno "The system time is incorrect. Please set the correct time." \
15-
0 80 --yes-button Continue --no-button Skip --clear; then
16-
change-time.sh
17-
fi
13+
if whiptail_warning --title "System Time Incorrect" \
14+
--yesno "The system time is incorrect. Please set the correct time." \
15+
0 80 --yes-button Continue --no-button Skip --clear; then
16+
change-time.sh
17+
fi
1818
fi
1919

2020
# Import user's keys if they exist
2121
if [ -d /.gnupg/keys ]; then
22-
# This is legacy location for user's keys. cbfs-init takes for granted that keyring and trustdb are in /.gnupg
23-
# oem-factory-reset generates keyring and trustdb which cbfs-init dumps to /.gnupg
24-
# TODO: Remove individual key imports. This is still valid for distro keys only below.
25-
gpg --import /.gnupg/keys/*.key /.gnupg/keys/*.asc 2>/dev/null || warn "Importing user's keys failed"
22+
# This is legacy location for user's keys. cbfs-init takes for granted that keyring and trustdb are in /.gnupg
23+
# oem-factory-reset generates keyring and trustdb which cbfs-init dumps to /.gnupg
24+
# TODO: Remove individual key imports. This is still valid for distro keys only below.
25+
gpg --import /.gnupg/keys/*.key /.gnupg/keys/*.asc 2>/dev/null || warn "Importing user's keys failed"
2626
fi
2727

2828
# Import trusted distro keys allowed for ISO signing

initrd/bin/reboot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ TRACE_FUNC
55

66
if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then
77
#Generalize user prompt to continue reboot or go to recovery shell
8-
read -r -n 1 -s -p "Press any key to continue reboot or 'r' to go to recovery shell: " REPLY
8+
read -r -n 1 -s -p "Press Enter to continue reboot or 'r' to go to recovery shell: " REPLY
99
echo
1010
if [ "$REPLY" = "r" ] || [ "$REPLY" = "R" ]; then
1111
recovery "Reboot call bypassed to go into recovery shell to debug"

initrd/bin/tpmr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ tpm2_unseal() {
589589
# can't do anything without a primary handle.
590590
if [ ! -f "$PRIMARY_HANDLE_FILE" ]; then
591591
DEBUG "tpm2_unseal: No primary handle, cannot attempt to unseal"
592-
warn "No TPM primary handle. You must reset TPM to seal secret to TPM NVRAM"
592+
warn "No TPM primary handle. You must reset the TPM to seal secret to TPM NVRAM"
593593
exit 1
594594
fi
595595

0 commit comments

Comments
 (0)