Skip to content

Commit f440ad3

Browse files
authored
Merge pull request #1284 from tlaurion/hardenedvault-crypttab-path_remix_enable_discard
WiP : TPM disk unlock key setup (kexec-save-key) reuses OS initrd's crypttab files as base for /secret.key override (kexec-insert-key)
2 parents c1ae44d + 150b95a commit f440ad3

File tree

2 files changed

+72
-5
lines changed

2 files changed

+72
-5
lines changed

initrd/bin/kexec-insert-key

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,12 @@ fi
3030
cat "$TMP_KEY_DEVICES" | cut -d\ -f1 | xargs /bin/qubes-measure-luks \
3131
|| die "LUKS measure failed"
3232

33-
# Unpack the initrd and fixup the /etc/crypttab
33+
# Unpack the initrd and fixup the crypttab
3434
# this is a hack to split it into two parts since
3535
# we know that the first 0x3400 bytes are the microcode
3636
INITRD_DIR=/tmp/secret/initrd
3737
SECRET_CPIO=/tmp/secret/initrd.cpio
38+
bootdir=$(dirname "$INITRD")
3839
mkdir -p "$INITRD_DIR/etc"
3940

4041
# Attempt to unseal the disk key from the TPM
@@ -73,9 +74,29 @@ dd if="$INITRD" of="$SECRET_CPIO" bs=512 conv=sync \
7374
|| die "Failed to copy initrd to /tmp"
7475

7576
if [ "$unseal_failed" = "n" ]; then
76-
# overwrite /etc/crypttab to mirror the behavior for in seal-key
77-
for uuid in `cat "$TMP_KEY_DEVICES" | cut -d\ -f2`; do
78-
echo "luks-$uuid UUID=$uuid /secret.key" >> "$INITRD_DIR/etc/crypttab"
79-
done
77+
# kexec-save-default might have created crypttab overrides to be injected in initramfs through additional cpio
78+
if [ -r "$bootdir/kexec_initrd_crypttab_overrides.txt" ]; then
79+
echo "$bootdir/kexec_initrd_crypttab_overrides.txt found..."
80+
echo "Preparing initramfs crypttab overrides as defined under $bootdir/kexec_initrd_crypttab_overrides.txt to be injected through cpio at next kexec call..."
81+
# kexec-save-default has found crypttab files under initrd and saved them
82+
cat "$bootdir/kexec_initrd_crypttab_overrides.txt" | while read line; do
83+
crypttab_file=$(echo "$line" | awk -F ':' {'print $1'})
84+
crypttab_entry=$(echo "$line" | awk -F ':' {'print $NF'})
85+
# Replace each initrd crypttab file with modified entry containing /secret.key path
86+
mkdir -p "$INITRD_DIR/$(dirname $crypttab_file)"
87+
echo "$crypttab_entry" | tee -a "$INITRD_DIR/$crypttab_file" > /dev/null
88+
echo "initramfs's $crypttab_file will be overriden with $crypttab_entry"
89+
done
90+
else
91+
# No crypttab files were found under selected default boot option's initrd file
92+
crypttab_file="etc/crypttab"
93+
mkdir -p "$INITRD_DIR/$(dirname $crypttab_file)"
94+
# overwrite crypttab to mirror behavior of seal-key
95+
echo "The following /etc/crypttab lines will be passed through cpio into kexec call for default boot option:"
96+
for uuid in `cat "$TMP_KEY_DEVICES" | cut -d\ -f2`; do
97+
# NOTE: discard operation (TRIM) is activated by default if no crypptab found in initrd
98+
echo "luks-$uuid UUID=$uuid /secret.key luks,discard" | tee -a "$INITRD_DIR/$crypttab_file"
99+
done
100+
fi
80101
( cd "$INITRD_DIR" ; find . -type f | cpio -H newc -o ) >> "$SECRET_CPIO"
81102
fi

initrd/bin/kexec-save-default

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,52 @@ if [ ! -r $ENTRY_FILE -o ! -r $HASH_FILE ]; then
129129
die "Failed to write default config"
130130
fi
131131

132+
if [ "$save_key" = "y" ]; then
133+
# logic to parse OS initrd to extract crypttab, its filepaths and its OS defined options
134+
mkdir -p /tmp/initrd_extract
135+
cd /tmp/initrd_extract
136+
# Get initrd filename selected to be default initrd that OS could be using to configure LUKS on boot by deploying crypttab files
137+
current_default_initrd=$(cat /boot/kexec_default_hashes.txt | grep initr | awk -F " " {'print $NF'} | sed 's/\.\//\/boot\//g')
138+
139+
# Get crypttab files paths from initrd
140+
echo "Checking current selected default boot's $current_default_initrd for existing crypttab files..."
141+
# First either decompress or use the original if it's not compressed
142+
initrd_decompressed="/tmp/initrd_extract/initrd_decompressed.cpio"
143+
zcat < "$current_default_initrd" > "$initrd_decompressed" 2> /dev/null || initrd_decompressed="$current_default_initrd"
144+
crypttab_files=$(cpio --list --quiet < "$initrd_decompressed" | grep crypttab 2> /dev/null) || true
145+
146+
if [ ! -z "$crypttab_files" ]; then
147+
echo "Extracting current selected default boot's $current_default_initrd for found crypttab files analysis..."
148+
cpio -id --quiet < $initrd_decompressed $crypttab_files 2> /dev/null
149+
rm -f $bootdir/kexec_initrd_crypttab_overrides.txt || true
150+
151+
#Parsing each crypttab file found
152+
echo "$crypttab_files" | while read filepath; do
153+
# Keep only non-commented lines
154+
current_filepath_entries=$(cat "$filepath" | grep -v "^#")
155+
# Modify each retained crypttab line to contain to be injected /secret.key at next default boots
156+
modified_filepath_entries=$(echo "$current_filepath_entries" | sed 's/none/\/secret.key/g')
157+
echo "$modified_filepath_entries" | while read single_modified_filepath_entry; do
158+
# Append each found filepath:entry into additional kexec_ file that will be part of detached signed digest
159+
echo "$filepath:$single_modified_filepath_entry" >> $bootdir/kexec_initrd_crypttab_overrides.txt
160+
done
161+
done
162+
163+
cd - > /dev/null
164+
165+
#insert current default boot's initrd crypttab locations into tracking file to be overwritten into initramfs at kexec-inject-key
166+
echo "The following OS crypttab file:entry were modified from default boot's initrd:"
167+
cat $bootdir/kexec_initrd_crypttab_overrides.txt
168+
echo "Heads added /secret.key in those entries and saved them under $bootdir/kexec_initrd_crypttab_overrides.txt"
169+
echo "Those overrides will be part of detached signed digests and used to prepare cpio injected at kexec of selected default boot entry."
170+
else
171+
echo "No crypttab file found in extracted initrd. Removing $bootdir/kexec_initrd_crypttab_overrides.txt"
172+
rm -f "$bootdir/kexec_initrd_crypttab_overrides.txt" || true
173+
fi
174+
# Cleanup
175+
rm -rf /tmp/initrd_extract || true
176+
fi
177+
132178
# sign and auto-roll config counter
133179
extparam=
134180
if [ "$CONFIG_TPM" = "y" ]; then

0 commit comments

Comments
 (0)