Hello everyone! Sharing out a success, and steps for using the zymkey 4i for backing LUKS FDE under Ubuntu 21.10 on an Rpi4.
Image your boot device with Server or Desktop, and apply LUKS encryption according to the procedure at: raspberrypi - LUKS Disk Encryption on Raspberry Pi 4 and Ubuntu Desktop 20.10 - Ask Ubuntu
Desktop, unlike Server, doesn’t have cryptsetup in it’s initramfs at first. Therefore, like the follow-on comment suggests, boot it up, apt install cryptsetup-initramfs
and update-initramfs -u -k all
before applying LUKS.
For 21.10, you can leave splash
in the cmdline.txt entry because the splash screen understands the askpass
prompt, and channels it through to a pretty screen.
Notably, Adiantum performs much better on the rpi 1-4 family only because they don’t expose aes hardware intrinsics. This is a fallback encryption algorithm for lower-end hardware.
→ Feature detect this rather than always using adiantum: grep aes /proc/cpuinfo
Physically install the zymkey 4i:
From Ubuntu 20.04 (focal fossa) Support - #10 by kontrasec, the software kit must be slightly modified. We’re using packages from focal on impish. Use this as the contents of install.sh
, and then run it:
#!/bin/bash
#---------------------------------------------------------------------------------------------------------------------------------------------------------------
# Copyright (C) 2021 by copyright Zymbit
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without l> imitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#---------------------------------------------------------------------------------------------------------------------------------------------------------------
mod=""
# ensure running as root or exit
if [ "$(id -u)" != "0" ]; then
echo "run this as root or use sudo" 2>&1 && exit 1;
fi;
# insure that the group 'gpio' exists
grep "^gpio" /etc/group &>/dev/null
if [ $? -ne 0 ]
then
if [ "$1" == "-y" ]
then
answer="YES"
else
echo "Group 'gpio' does not exist. This group is necessary for zymbit software to operate normally."
read -p 'Type yes in all capital letters (YES) to create this group: ' answer <&1
fi
if [ "${answer}" == "YES" ]
then
# Add group 'gpio'
groupadd gpio
# Modify /etc/rc.local to change the group of /etc/sys/class/gpio
grep "chown -R root:gpio" /etc/rc.local &>/dev/null
if [ $? -ne 0 ]
then
echo "chown -R root:gpio /sys/class/gpio" >> /etc/rc.local
echo "chmod -R ug+rw /sys/class/gpio" >> /etc/rc.local
fi
# Check for existence of udev rule
if [ ! -f "/etc/udev/rules.d/80-gpio-noroot.rules" ]
then
echo "ACTION==\"add\", SUBSYSTEM==\"gpio\", PROGRAM=\"/bin/sh -c 'chown -R root:gpio /sys/${DEVPATH}; chmod -R g+w /sys/${DEVPATH}'\"" >> /etc/udev/rules.d/80-gpio-noroot.rules
fi
else
echo "Quitting..."
exit -1
fi
fi
function pip3()
{
python3 -m pip $@
}
distro=`lsb_release -c | cut -f2 -d$'\t'`
uname -m | grep "arm"
if [ $? -eq 0 ]
then
arch=""
else
arch="-"`uname -m`
fi
distro="focal"
# for older versions of Raspbian, insure that apt-transport-https is installed first
echo -n "Installing prerequisites (this might take a few minutes)..."
apt update --allow-releaseinfo-change -y
apt install -y libboost-thread-dev lsb-release libjansson4 &>/dev/null
apt install -y apt-transport-https curl libyaml-dev libssl-dev libcurl4-openssl-dev python3-pip python3-setuptools python3-dev i2c-tools &>/dev/null
pip3 install inotify
pip3 install pycurl
pip3 install progress
pip3 install python-gnupg
echo "done."
baseurl="https://zk-sw-repo${mod}.s3.amazonaws.com"
# import zymbit gpg key
gpg_key_url="$baseurl/apt-zymkey-pubkey.gpg"
echo -n "Importing Zymbit Packages gpg key... "
# import the gpg key
curl -L "${gpg_key_url}" 2> /dev/null | apt-key add - &>/dev/null
echo "done."
# add zymbit apt repo to sources list
apt_source_path="/etc/apt/sources.list.d/zymbit.list"
echo -n "Installing $apt_source_path..."
echo "deb $baseurl/apt-repo-${distro}${arch}/ ${distro} main" > $apt_source_path
echo "done...Updating now."
apt update -y
# install our packages
echo -n "Installing Zymkey Packages..."
apt install -y libzk libzymkeyssl zkbootrtc zkifc zkapputilslib zksaapps zkpkcs11 cryptsetup &>/dev/nul || exit
pip3 install --upgrade zku &>/dev/null
pip3 install --upgrade zk_luks &>/dev/null
curl -G https://s3.amazonaws.com/zk-sw-repo/zk_prep_encr > /usr/local/bin/zk_prep_encr
chmod +x /usr/local/bin/zk_prep_encr
systemctl restart zkifc
sync
sleep 10
# reboot
echo "Rebooting now..."
reboot
Let the rpi4 reboot, then add a new key to the LUKS drive, and lock it with the zymkey 4i. As root/sudo:
# https://run.tournament.org.il/ubuntu-20-04-and-tpm2-encrypted-system-disk/
pushd /root
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 64 > root.key
# Retry this next line till it works.... :facepalm:
zklockifs root.key > /var/lib/zymbit/key.bin.lock
cryptsetup luksAddKey /dev/mmcblk0p2 root.key
rm root.key
popd
Now, add new hooks for initramfs generation. Here, Zymbit’s mk_encr_ext_rfs.sh script has a copy:
# Zymbit mk_encr_ext_rfs.sh
# Copy /var/lib/zymbit and all standalone zymkey utilities to initramfs
cat > /etc/initramfs-tools/hooks/zymkey_cryptfs_cfg <<"EOF"
#!/bin/sh
PREREQ=""
prereqs() {
echo "$PREREQ"
}
case "$1" in
prereqs)
prereqs
exit 0
;;
esac
. /usr/share/initramfs-tools/hook-functions
mkdir -p ${DESTDIR}/var/lib/zymbit
cp -prf /var/lib/zymbit/* ${DESTDIR}/var/lib/zymbit
copy_exec /sbin/zkunlockifs /sbin
EOF
chmod +x /etc/initramfs-tools/hooks/zymkey_cryptfs_cfg
# Bring the i2c drivers into initramfs
grep -q "^i2c-dev" ${crfsvol}/etc/initramfs-tools/modules || echo "i2c-dev" >> ${crfsvol}/etc/initramfs-tools/modules
grep -q "^i2c-bcm2835" ${crfsvol}/etc/initramfs-tools/modules || echo "i2c-bcm2835" >> ${crfsvol}/etc/initramfs-tools/modules
grep -q "^i2c-bcm2708" ${crfsvol}/etc/initramfs-tools/modules || echo "i2c-bcm2708" >> ${crfsvol}/etc/initramfs-tools/modules
grep -q "^lan78xx" ${crfsvol}/etc/initramfs-tools/modules || echo "lan78xx" >> ${crfsvol}/etc/initramfs-tools/modules
From Raspberry pi4 Ubuntu not booting - #10 by kontrasec, the stock keyscript has no fallbacks in case the zymbit is missing, damaged, or the OS was updated. Use this instead:
cat > /lib/cryptsetup/scripts/zk_get_key <<'EOF'
#!/bin/sh
num_times=30
while [ ${num_times} -gt 0 ]
do
ls /sys/class/net/eth* 1>/dev/null 2>&1
eth=$?
ls /sys/class/net/enx* 1>/dev/null 2>&1
enx=$?
if [ ${eth} -ne 0 ] && [ ${enx} -ne 0 ]
then
num_times=$((num_times-1))
sleep 0.1
else
break
fi
done
num_times=30
while [ ${num_times} -gt 0 ]
do
if [ -d "/var/lib/zymbit" ]
then
break
else
num_times=$((num_times-1))
sleep 0.1
fi
done
if [ -e /var/lib/zymbit/zkenv.conf ]
then
export $(cat /var/lib/zymbit/zkenv.conf)
fi
/sbin/zkunlockifs /var/lib/zymbit/key.bin.lock
err=$?
if [ ${err} -ne 0 ]
then
/lib/cryptsetup/askpass "Zymbit key did not release LUKS key. Enter backup LUKS passphrase:"
fi
EOF
Now, rebuild the initramfs:
update-initramfs -u -k all
… and reboot!