-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
base: initramfs-framework: add support for luks2/cryptfs with pkcs11
Signed-off-by: Ricardo Salveti <[email protected]>
- Loading branch information
1 parent
b783c4f
commit f406904
Showing
3 changed files
with
151 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
143 changes: 143 additions & 0 deletions
143
meta-lmp-base/recipes-core/initrdscripts/initramfs-framework/cryptfs_pkcs11
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters