Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for disk encryption and zfs #148

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions casper/scripts/99dell_bootstrap
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,18 @@ for seed in dell-recovery gfx wlan; do
fi
done

#HACK: make ubiquity think partitioning is done
if db_get dell-recovery/encryption && [ "$RET" = true ]; then
sed -i "s,self.partitioned = False,self.partitioned = True," /root/usr/lib/ubiquity/ubiquity/frontend/gtk_ui.py
rm -f /root/usr/lib/ubiquity/plugins/ubi-partman.py
fi

#HACK: make ubiquity think partitioning is done
if db_get dell-recovery/use_zfs && [ "$RET" = true ]; then
sed -i "s,self.partitioned = False,self.partitioned = True," /root/usr/lib/ubiquity/ubiquity/frontend/gtk_ui.py
rm -f /root/usr/lib/ubiquity/plugins/ubi-partman.py
fi

# Now load all the defaults included in all installs
casper-set-selections "/root/usr/share/dell/casper/seeds/ubuntu.seed"

Expand Down
3 changes: 3 additions & 0 deletions debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,16 @@ Conflicts: dell-oobe
Recommends: cryptsetup,
cryptsetup-bin,
dvd+rw-tools,
libtss2-esys0,
isolinux,
lsb-release,
lvm2,
mokutil,
mdadm (>> 4.1~rc1-2),
parted,
python3-progressbar,
openssl,
tpm2-tools,
fonts-dejavu,
usb-creator-gtk,
wodim,
Expand Down
10 changes: 10 additions & 0 deletions debian/dell-recovery.templates
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ Type: boolean
Default: false
Description: for internal use; determines if EFI enabled dual boot enabled

Template: dell-recovery/use_zfs
Type: boolean
Default: false
Description: determines whether to use ZFS filesystem

Template: dell-recovery/encryption
Type: boolean
Default: false
Description: for internal use; determines whether to encrypt the disk

Template: dell-recovery/os_partition
Type: string
Default:
Expand Down
35 changes: 35 additions & 0 deletions late/chroot_scripts/20-initramfs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/sh
#
# <20-initramfs>
#
# Rerun update-initramfs for any changes from added packages or logical
# partition support that was added.
#
# Copyright 2010 Dell Inc.
# Crag Wang <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
. /usr/share/dell/scripts/fifuncs ""

IFHALT "Rerun initramfs update"
for device in $(dmsetup info --target crypt -c -o blkdevs_used --noheadings); do
if cryptsetup isLuks /dev/$device ; then
ln -s /usr/share/dell/scripts-initramfs/dell-initramfs /usr/share/initramfs-tools/hooks/dell-initramfs
/usr/sbin/update-initramfs -u -k all
break
fi
done
IFHALT "Done with initramfs update"
19 changes: 19 additions & 0 deletions late/chroot_scripts/60-detect-no-recovery-patition.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,23 @@
root = basename(root.decode().strip())
root_device = ''

root_fstype = cmd.check_output("findmnt -M / -o fstype -n", shell=True).decode().strip()
if root_fstype == "zfs":
# alt-root for rootfs zpool
target = os.environ.get("TARGET")
if target == None:
target = "/target"
print("I: alt-root is using default /target")
# get zpools and its properties: name, mountpoint
lines = cmd.check_output("zfs list -o name,mountpoint -H -d 0 -t filesystem", shell=True).decode().strip().split("\n")
for line in lines:
# zfs -H behaves: no header, and separate the fields by a single tab
token = line.split('\t')
if token[1] == target:
rpart_uuid = cmd.check_output("zpool get guid -o value -H %s" % token[0], shell=True).decode().strip()
root = cmd.check_output("blkid -U %s" % rpart_uuid, shell=True).decode().strip()
root = basename(root)

cdrom = cmd.check_output("findmnt -M /cdrom -o source -v | tail -n1",
shell=True)
cdrom = basename(cdrom.decode().strip())
Expand All @@ -48,6 +65,8 @@

if root_device == cdrom_device:
exit(0)
else:
print("root_device=%s, cdrom_device=%s" % (root_device, cdrom_device))

print('No recovery partition is detected.')

Expand Down
33 changes: 33 additions & 0 deletions late/scripts-initramfs/dell-initramfs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/sh -e
# initramfs hook for dell-bootstrap
PREREQS=""
# Output pre-requisites
prereqs()
{
echo "$PREREQS"
}
case "$1" in
prereqs)
prereqs
exit 0
;;
esac
. /usr/share/initramfs-tools/hook-functions
copy_exec /usr/bin/openssl
copy_exec /usr/bin/flock

copy_exec /lib/x86_64-linux-gnu/libtss2-*

copy_exec /usr/bin/tpm2_startauthsession
copy_exec /usr/bin/tpm2_flushcontext
copy_exec /usr/bin/tpm2_createprimary
copy_exec /usr/bin/tpm2_create
copy_exec /usr/bin/tpm2_evictcontrol
copy_exec /usr/bin/tpm2_policypcr
copy_exec /usr/bin/tpm2_unseal
copy_exec /usr/bin/tpm2_pcrread
copy_exec /usr/bin/tpm2_getcap
copy_exec /usr/bin/tpm2_load
copy_exec /usr/bin/tpm2_pcrextend

copy_modules_dir kernel/drivers/char/tpm
130 changes: 130 additions & 0 deletions late/scripts-initramfs/fs-unlock.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#!/bin/sh
set -x
name=$CRYPTTAB_NAME
tpm_obj=0x81000005

# skip fs-unlock early
[ -e "/dev/disk/by-partlabel/keystore" ] || exit 0

# redicrt console
exec 8<&1
exec 9<&2
logout=/run/initramfs/fs-unlock.out
logerr=/run/initramfs/fs-unlock.out
exec 1>>$logout
exec 2>>$logerr

# funcs
unlock_keystore_by_tpm(){
local dir4tpm=$(mktemp -d)
mkdir -p $dir4tpm
tpm2_startauthsession --policy-session --session $dir4tpm/session.ctx
tpm2_policypcr --session $dir4tpm/session.ctx --pcr-list sha256:7,8,9 --policy $dir4tpm/unsealing.pcr_sha256_789.policy
tpm2_unseal -p session:$dir4tpm/session.ctx -c $tpm_obj | cryptsetup open /dev/disk/by-partlabel/keystore keystore --key-slot 2 --priority prefer --key-file=-
rm -rf $dir4tpm
}

manipulate_keystore_with_hwid(){
local hwid=$(cat /sys/class/dmi/id/product_serial)
[ "$hwid" == "" ] && hwid=$(cat /sys/class/dmi/id/product_uuid)
case "$1" in
fallback)
local tmp4hwid=$(mktemp -d)
mkdir -p $tmp4hwid
cryptsetup luksKillSlot /dev/disk/by-partlabel/keystore 0 -q
local new_hwid_key=$tmp4hwid/luks-keystore.keyfile
printf $hwid | openssl dgst -sha256 -binary -out $new_hwid_key
plymouth ask-for-password --prompt "Enter PIN to update HWID" --number-of-tries=2 --command="cryptsetup luksAddKey /dev/disk/by-partlabel/keystore $new_hwid_key --key-slot=0 --key-file=-"
cryptsetup open /dev/disk/by-partlabel/keystore keystore --key-slot 0 --priority prefer --key-file=$new_hwid_key
return $?
;;
unlock)
printf $hwid | openssl dgst -sha256 -binary | cryptsetup open /dev/disk/by-partlabel/keystore keystore --key-slot 0 --priority prefer --key-file=-
return $?
;;
prepare)
local key_in_use="$2"
printf $hwid | openssl dgst -sha256 -binary | cryptsetup luksAddKey /dev/disk/by-partlabel/keystore --key-slot 0 --priority prefer --key-file=$key_in_use
return $?
;;
*)
return 1
;;
esac
}

unlock_name_by_keyfile(){
if [ -e /dev/mapper/keystore ]; then
tmpdir=$(mktemp -d)
mkdir -p $tmpdir
mount /dev/mapper/keystore $tmpdir
cat $tmpdir/luks-$name.keyfile >&8
umount $tmpdir
rm -rf $tmpdir
cryptsetup close keystore
fi
}

tpm2_salt_pcr789(){
tpm2_pcrextend 7:sha256=0x0000000000000000000000000000000000000000000000000000000000000000
tpm2_pcrextend 8:sha256=0x0000000000000000000000000000000000000000000000000000000000000000
tpm2_pcrextend 9:sha256=0x0000000000000000000000000000000000000000000000000000000000000000
}

keystore_refresh_randkey_by_pin(){
local tmp4rand=$(mktemp -d)
mkdir -p $tmp4rand

# add new rand key to luks key slot
cryptsetup luksKillSlot /dev/disk/by-partlabel/keystore 2 -q
local new_rand_key=$tmp4rand/luks-keystore.keyfile
openssl rand -out $new_rand_key 128
plymouth ask-for-password --prompt "Enter PIN to update TPM" --number-of-tries=2 --command="cryptsetup luksAddKey /dev/disk/by-partlabel/keystore $new_rand_key --key-slot=2 --key-file=-"
cryptsetup open /dev/disk/by-partlabel/keystore keystore --key-slot 2 --priority prefer --key-file=$new_rand_key

# persist new key to tpm
tpm2_evictcontrol --hierarchy o --object-context $tpm_obj
tpm2_startauthsession --session $tmp4rand/session.ctx
tpm2_policypcr --session $tmp4rand/session.ctx --pcr-list sha256:7,8,9 --policy $tmp4rand/pcr_sha256_789.policy
tpm2_flushcontext $tmp4rand/session.ctx
rm -f $tmp4rand/session.ctx
tpm2_createprimary --hierarchy o --hash-algorithm sha256 --key-algorithm rsa --key-context $tmp4rand/prim.ctx
tpm2_create --parent-context $tmp4rand/prim.ctx --hash-algorithm sha256 --public $tmp4rand/pcr_seal_key.pub --private $tmp4rand/pcr_seal_key.priv --sealing-input $new_rand_key --policy $tmp4rand/pcr_sha256_789.policy
tpm2_load -C $tmp4rand/prim.ctx -u $tmp4rand/pcr_seal_key.pub -r $tmp4rand/pcr_seal_key.priv -n $tmp4rand/pcr_seal_key.name -c $tmp4rand/pcr_seal_key.ctx
tpm2_flushcontext --transient
tpm2_evictcontrol --hierarchy o --object-context $tmp4rand/pcr_seal_key.ctx $tpm_obj
[ $? -eq 0 ] && {
cryptsetup luksKillSlot /dev/disk/by-partlabel/keystore 0 -q
} || {
manipulate_keystore_with_hwid "prepare" "$new_rand_key"
cryptsetup luksKillSlot /dev/disk/by-partlabel/keystore 2 -q
return 2
}
tpm2_flushcontext --transient
rm -rf $tmp4rand
return 0
}

# keystore luks key slots:
# 0: hwid
# 1: pin
# 2: rand --> persist to TPM
{
flock -s 9
if tpm2_getcap handles-persistent | grep $tpm_obj > /dev/null; then
unlock_keystore_by_tpm
[ ! -e /dev/mapper/keystore ] && {
keystore_refresh_randkey_by_pin
[ $? -ne 0 ] && manipulate_keystore_with_hwid "unlock"
}
tpm2_salt_pcr789
else
manipulate_keystore_with_hwid "unlock"
[ $? -ne 0 ] && manipulate_keystore_with_hwid "fallback"
fi
unlock_name_by_keyfile
} 9>$logout.lock

# redirect console
exec 1<&8
exec 2<&9
16 changes: 15 additions & 1 deletion late/scripts/chroot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ fi

export BOOTDEV=${DEVICE%%[0-9]*}
DEVICE=$(mount | sed -n 's/\ on\ \/target .*//p')
if [ "$(findmnt -M $TARGET -o fstype -n )" = "zfs" ]; then
DEVICE=$(zfs get -o name mountpoint $TARGET -H | sed 's/\/.*//' | xargs -I {} blkid -L {})
fi
export TARGETDEV=${DEVICE%%[0-9]*}

LOG="var/log"
Expand Down Expand Up @@ -120,10 +123,15 @@ fi
#Make sure fifuncs and target_chroot are available
if [ ! -d $TARGET/usr/share/dell/scripts ]; then
mkdir -p $TARGET/usr/share/dell/scripts
DIR_CLEANUP="$TARGET/usr/share/dell/scripts $DIR_CLEANUP"
mount --bind /usr/share/dell/scripts $TARGET/usr/share/dell/scripts
DIR_CLEANUP="$TARGET/usr/share/dell/scripts $DIR_CLEANUP"
MOUNT_CLEANUP="$TARGET/usr/share/dell/scripts $MOUNT_CLEANUP"
fi
if [ ! -d $TARGET/usr/share/dell/scripts-initramfs ]; then
mkdir -p $TARGET/usr/share/dell/scripts-initramfs
mount --bind /usr/share/dell/scripts-initramfs $TARGET/usr/share/dell/scripts-initramfs
MOUNT_CLEANUP="$TARGET/usr/share/dell/scripts-initramfs $MOUNT_CLEANUP"
fi

#If we are loop mounted, this will have been done during the ubiquity
if [ -d /isodevice ]; then
Expand All @@ -136,6 +144,12 @@ if [ -d /dell/fist ] && ! grep "^GRUB_DISABLE_OS_PROBER" $TARGET/etc/default/gru
echo "GRUB_DISABLE_OS_PROBER=true" >> $TARGET/etc/default/grub
fi

# zfs: create dataset for new created user and root, run if zfs in use
if chroot $TARGET findmnt -M / -t zfs > /dev/null; then
. /usr/share/dell/scripts/zfs_finalize.sh
. /usr/share/dell/scripts/zfs_encrypt_home.sh
fi

#Run chroot scripts
chroot $TARGET /usr/share/dell/scripts/target_chroot.sh

Expand Down
Loading