Skip to content

Commit

Permalink
base: initramfs-framework: add support for luks2/cryptfs with pkcs11
Browse files Browse the repository at this point in the history
Signed-off-by: Ricardo Salveti <[email protected]>
  • Loading branch information
ricardosalveti committed Jul 23, 2022
1 parent b783c4f commit f406904
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ DESCRIPTION = "Linux microPlatform OSTree initramfs image"
PACKAGE_INSTALL = "initramfs-framework-base \
initramfs-module-udev \
initramfs-module-rootfs \
${@bb.utils.contains('MACHINE_FEATURES', 'optee', 'initramfs-module-cryptfs-pkcs11', '', d)} \
initramfs-module-ostree \
initramfs-module-ostree-factory-reset \
${VIRTUAL-RUNTIME_base-utils} \
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#!/bin/sh
# Copyright (C) 2022 Fondries.IO
# SPDX-License-Identifier: MIT
#
# Encrypt (reencrypt) the root device with LUKS2, with pkcs11 token support

cryptfs_pkcs11_enabled() {
return 0
}

cryptfs_gen_passphrase() {
# Static as at this point we just need a key for encrypting and later enrolling a new keyslot
mkdir -p /run/cryptsetup
echo -n "fiopassphrase" > /run/cryptsetup/passphrase
}

cryptfs_enroll_pkcs11() {
root_dev=$1

MODULE=/usr/lib/libckteec.so.0
# Use TEE Identity with user authentication - root
export CKTEEC_LOGIN_TYPE=user
pkcs11-tool --module $MODULE --init-token --slot 1 --label lmp --so-pin ""
pkcs11-tool --module $MODULE --token-label lmp --init-pin --so-pin foo --pin user:ef0180a3-13f3-5d1c-b7f5-888c0e21059a
pkcs11-tool --module $MODULE --token-label lmp --pin foo --keypairgen --key-type rsa:2048 --id 9d --label luks

mkdir -p /run/crypt
cat << EOF > /run/crypt/cert.cfg
[req]
distinguished_name = req_distinguished_name
[req_distinguished_name]
EOF
cat << EOF > /run/crypt/ssl.cfg
openssl_conf = openssl_def
[openssl_def]
engines = engine_section
[engine_section]
pkcs11 = pkcs11_section
[pkcs11_section]
engine_id = pkcs11
dynamic_path = /usr/lib/engines-3/pkcs11.so
MODULE_PATH = /usr/lib/libckteec.so.0
EOF
OPENSSL_CONF=/run/crypt/ssl.cfg openssl req -x509 -new -engine pkcs11 -keyform engine -key slot_1-label_luks -passin "pass:foo" -sha256 -config /run/crypt/cert.cfg -subj "/CN=LmP" -days 7300 -out /run/crypt/9d.crt
pkcs11-tool --module $MODULE --login --pin foo --write-object /run/crypt/9d.crt --type cert --label luks --token-label lmp --id 9d
rm -rf /run/crypt

PASSWORD=`cat /run/cryptsetup/passphrase` PIN=foo systemd-cryptenroll ${root_dev} --pkcs11-token-uri="pkcs11:token=lmp;object=luks" --wipe-slot=password
}

cryptfs_pkcs11_run() {
# Similar to rootfs, we need to wait for the device to become available
C=0
delay=${bootparam_rootdelay:-1}
timeout=${bootparam_roottimeout:-5}
while true; do
if [ $(( $C * $delay )) -gt $timeout ]; then
fatal "root '$bootparam_root' doesn't exist or does not contain a /dev."
fi

if [ -n "$bootparam_root" ]; then
root_dev="$bootparam_root"
if [ "`echo ${bootparam_root} | cut -c1-5`" = "UUID=" ]; then
root_uuid=`echo $bootparam_root | cut -c6-`
root_dev=`readlink -f /dev/disk/by-uuid/$root_uuid`
elif [ "`echo ${bootparam_root} | cut -c1-9`" = "PARTUUID=" ]; then
root_partuuid=`echo $bootparam_root | cut -c10-`
root_dev=`readlink -f /dev/disk/by-partuuid/$root_partuuid`
elif [ "`echo ${bootparam_root} | cut -c1-10`" = "PARTLABEL=" ]; then
root_partlabel=`echo $bootparam_root | cut -c11-`
root_dev=`readlink -f /dev/disk/by-partlabel/$root_partlabel`
elif [ "`echo ${bootparam_root} | cut -c1-6`" = "LABEL=" ]; then
root_label=`echo $bootparam_root | cut -c7-`
root_dev=`readlink -f /dev/disk/by-label/$root_label`
fi

[ -e "$root_dev" ] && break
fi
debug "Sleeping for $delay second(s) to wait root to settle..."
sleep $delay
C=$(( $C + 1 ))
done

flags=""
if [ -n "$bootparam_rootflags" ]; then
flags="$flags -o$bootparam_rootflags"
fi
if [ -n "$bootparam_rootfstype" ]; then
flags="$flags -t$bootparam_rootfstype"
fi

cryptfs_gen_passphrase

if ! cryptsetup isLuks ${root_dev}; then
# Partition not yet encrypted
msg "${root_dev} not yet encrypted, encrypting with LUKS2"
e2fsck -p -f ${root_dev}
block_size=`dumpe2fs -h ${root_dev} 2>/dev/null | grep "^Block size" | cut -d ':' -f 2 | tr -d ' '`
block_count=`dumpe2fs -h ${root_dev} 2>/dev/null | grep "^Block count" | cut -d ':' -f 2 | tr -d ' '`
luks_size=33554432 # 32M
new_block_count=$(($block_count - $luks_size / $block_size))
resize2fs -p ${root_dev} ${new_block_count}

cat /run/cryptsetup/passphrase | cryptsetup -v reencrypt --encrypt --disable-locks --reduce-device-size 32m ${root_dev}

# Align label and UUID if used as boot parameter (not safe, better use the proper device path instead)
if [ -n "$root_label" ]; then
cryptsetup config --label ${root_label} ${root_dev}
fi
if [ -n "$root_uuid" ]; then
yes | cryptsetup luksUUID --uuid ${root_uuid} ${root_dev}
fi
fi

luks_name="`basename ${root_dev}`_crypt"

# Check if online encryption is still in progress
if cryptsetup luksDump ${root_dev} | grep -q "online-reencrypt"; then
# Run recovery process
cat /run/cryptsetup/passphrase | cryptsetup luksOpen ${root_dev} ${luks_name}
e2fsck -p -f /dev/mapper/${luks_name}
cat /run/cryptsetup/passphrase | cryptsetup -v reencrypt --resume-only ${root_dev}
cryptsetup close ${luks_name}
fi

# tee-supplicant is needed for OP-TEE related operations
start-stop-daemon -S -b /usr/sbin/tee-supplicant

if ! cryptsetup luksDump ${root_dev} | grep -q "systemd-pkcs11"; then
msg "Enrolling LUKS2 keyslot based on PKCS11 token"
cryptfs_enroll_pkcs11 ${root_dev}
fi

! cryptsetup luksOpen ${root_dev} ${luks_name} &&
fatal "Unable to open the LUKS partition ${root_dev} with the enrolled pkcs11 token"

e2fsck -p -f /dev/mapper/${luks_name}

mount ${flags} /dev/mapper/${luks_name} $ROOTFS_DIR ||
(cryptsetup luksClose ${luks_name} && fatal "Failed to mount LUKS ${luks_name}")

start-stop-daemon -K -x /usr/sbin/tee-supplicant
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"

SRC_URI:append = " \
file://cryptfs_pkcs11 \
file://ostree \
file://ostree_factory_reset \
file://ostree_recovery \
file://run-tmpfs.patch \
"

PACKAGES:append = " \
initramfs-module-cryptfs-pkcs11 \
initramfs-module-ostree \
initramfs-module-ostree-factory-reset \
initramfs-module-ostree-recovery \
"

SUMMARY:initramfs-module-cryptfs-pkcs11 = "initramfs support for encrypted filesystems with support for pkcs11"
RDEPENDS:initramfs-module-cryptfs-pkcs11 = "${PN}-base cryptsetup libgcc e2fsprogs-resize2fs e2fsprogs-e2fsck e2fsprogs-dumpe2fs systemd-crypt optee-client optee-os-fio-ta opensc openssl-bin libp11"
FILES:initramfs-module-cryptfs-pkcs11 = "/init.d/80-cryptfs_pkcs11"

SUMMARY:initramfs-module-ostree = "initramfs support for ostree based filesystems"
RDEPENDS:initramfs-module-ostree = "${PN}-base ostree-switchroot"
FILES:initramfs-module-ostree = "/init.d/98-ostree"
Expand All @@ -26,6 +32,7 @@ RDEPENDS:initramfs-module-ostree-recovery = "${PN}-base ostree"
FILES:initramfs-module-ostree-recovery = "/init.d/98-ostree_recovery"

do_install:append() {
install -m 0755 ${WORKDIR}/cryptfs_pkcs11 ${D}/init.d/80-cryptfs_pkcs11
install -m 0755 ${WORKDIR}/ostree ${D}/init.d/98-ostree
install -m 0755 ${WORKDIR}/ostree_factory_reset ${D}/init.d/98-ostree_factory_reset
install -m 0755 ${WORKDIR}/ostree_recovery ${D}/init.d/98-ostree_recovery
Expand Down

0 comments on commit f406904

Please sign in to comment.