User:Vixalien/Clevis
Clevis is a tool that allows, among many other things, to automatically decrypt LUKS volume at boot-time automatically using the TPM without requiring the manual input of a password.
Installation
To use clevis install the clevis package.
If you need the TPM functionality, you will also need to install tpm2-tools and tpm2-tss-tcti-device. See See issue:
# apk add -t clevis-tpm clevis tpm2-tools tpm2-tss-tcti-device
Testing
You may wish to encrypt some data using your TPM with clevis:
# echo 'hello, world' | clevis encrypt tpm2 '{}
eyJhbGciOiJkaXIiLCJjbGV2aXMiOnsicGluIjoidHBtMiIsInRwbTIiOnsiaGFzaCI6InNoYTI1NiIsImp3a19wcml2IjoiQU80QUlETDZOQlp1dFktZUg2YjdNUUFtazNxNE5MTGRDYWFrM2tJUHBsOWtRUmlxQUJEaFFGSks0MWVWQXMtUElKbmsxUW9MS0hVVnhoQmM5RVlZZ1hfc1MzaS1EYUQ1aXZQdmZybUxSY25TZGxYRWtvSE1qN0lMekFvY29ZQ2FnRGNxczBYcVFCRkhqTkxFaW5PM3NySjAxTlo3QkExX2tnR0t1THVISC1pVUpESGZNQklnUFFsMzUyb3dSeFdPVUhuWnFiRk5rTU9WekVRS1ZTYUlUUlZtMEhnZHEwTWtpYV9HSjB2bGFXYkJtUE45SU1weGZXTTU3dGdGSnBRYXBobkNoZUsyLUkzeHNnY01rb2N3eUNnTzRZUnlZOXcxZGx4aVhxYURoc0xpcnJMV3E3SFFuZkRCVXlvU2hTWC0iLCJqd2tfcHViIjoiQUM0QUNBQUxBQUFFMGdBQUFCQUFJTlBYYkNWd3BNRUVnUkRGVF9VVVZ6c3Flb3dpWW5PSEZiVmZfV3ZHTUFTOCIsImtleSI6ImVjYyJ9fSwiZW5jIjoiQTI1NkdDTSJ9..F117H8zDNXxuOzxr.KCPhBegjQRx3Sv6uFg.yC9EbXhI8twv48oohl3KOw
The result will be a base-64 encoded string encrypted with your computer's TPM2 key. This means that the message can only be decoded from this current computer (or more precisely, the same TPM2 chip that encoded it).
# echo "eyJhbGciOiJkaXIiLCJjbGV2aXMiOnsicGluIjoidHBtMiIsInRwbTIiOnsiaGFzaCI6InNoYTI1NiIsImp3a19wcml2IjoiQU80QUlETDZOQlp1dFktZUg2YjdNUUFtazNxNE5MTGRDYWFrM2tJUHBsOWtRUmlxQUJEaFFGSks0MWVWQXMtUElKbmsxUW9MS0hVVnhoQmM5RVlZZ1hfc1MzaS1EYUQ1aXZQdmZybUxSY25TZGxYRWtvSE1qN0lMekFvY29ZQ2FnRGNxczBYcVFCRkhqTkxFaW5PM3NySjAxTlo3QkExX2tnR0t1THVISC1pVUpESGZNQklnUFFsMzUyb3dSeFdPVUhuWnFiRk5rTU9WekVRS1ZTYUlUUlZtMEhnZHEwTWtpYV9HSjB2bGFXYkJtUE45SU1weGZXTTU3dGdGSnBRYXBobkNoZUsyLUkzeHNnY01rb2N3eUNnTzRZUnlZOXcxZGx4aVhxYURoc0xpcnJMV3E3SFFuZkRCVXlvU2hTWC0iLCJqd2tfcHViIjoiQUM0QUNBQUxBQUFFMGdBQUFCQUFJTlBYYkNWd3BNRUVnUkRGVF9VVVZ6c3Flb3dpWW5PSEZiVmZfV3ZHTUFTOCIsImtleSI6ImVjYyJ9fSwiZW5jIjoiQTI1NkdDTSJ9..F117H8zDNXxuOzxr.KCPhBegjQRx3Sv6uFg.yC9EbXhI8twv48oohl3KOw" | clevis decrypt tpm2 '{}'
hello, world
Encrypt a LUKS volume
# cryptsetup luksAddKey /dev/sda1
Use the following command to bind a LUKS volume to your TPM:
# clevis luks bind -d /dev/sda1 tpm2 '{}'
The '{}'
contains the configuration. For example, you can use the following command to seal the LUKS key against UEFI settings AND the Secure Boot policy, meaning clevis will be unable to unlock the device if either the UEFI settings changes or the SecureBoot keys are changed, and you'll need to rebind the volume after inputting your backup password
'{"pcr_ids":"1,7"}'
See 'man 1 clevis-encrypt-tpm2'
for all possible configuration options.
mkinitfs hook
After binding your LVM volume to your TPM, you may wish for it to be unlocked automatically when your device boots. Currently, this process is a bit tedious, but will hopefully be improved in the future.
mkinitfs feature
First, create the following files with the following content. They allow all the kernel modules and files needed to unlock LUKS devices with the TPM to be copied to the initramfs.
Contents of /etc/mkinitfs/features.d/clevis-tpm.modules
Contents of /etc/mkinitfs/features.d/clevis-tpm.files
Then, add the clevis-tpm
feature to /etc/mkinitfs/mkinitfs.conf:
features="ata base cdrom ext4 keymap kms mmc nvme raid scsi usb virtio clevis-tpm"
Don't forgot to regenerate your initramfs
# apk fix kernel-hooks
init script
Now, everything that's needed to unbind the LUKS device with the TPM is now included in the initramfs. All that's needed is to actually unlock the device in the initramfs. Since it's currently not possible to run custom scripts in the init, you will need to manually edit the init and allow it to decrypt the disk with clevis if possible.
Edit the file /usr/share/mkinitfs/initramfs-init, and replace the text:
if [ -n "$KOPT_cryptroot" ]; then cryptopts="-c ${KOPT_cryptroot}" if [ "$KOPT_cryptdiscards" = "yes" ]; then cryptopts="$cryptopts -D" fi if [ -n "$KOPT_cryptdm" ]; then cryptopts="$cryptopts -m ${KOPT_cryptdm}" fi if [ -n "$KOPT_cryptheader" ]; then cryptopts="$cryptopts -H ${KOPT_cryptheader}" fi if [ -n "$KOPT_cryptoffset" ]; then cryptopts="$cryptopts -o ${KOPT_cryptoffset}" fi if [ "$KOPT_cryptkey" = "yes" ]; then cryptopts="$cryptopts -k /crypto_keyfile.bin" elif [ -n "$KOPT_cryptkey" ]; then cryptopts="$cryptopts -k ${KOPT_cryptkey}" fi fi
And replace it with:
if [ -n "$KOPT_cryptroot" ]; then cryptopts="-c ${KOPT_cryptroot}" clevisopts="-d ${KOPT_cryptroot}" if [ "$KOPT_cryptdiscards" = "yes" ]; then cryptopts="$cryptopts -D" fi if [ -n "$KOPT_cryptdm" ]; then cryptopts="$cryptopts -m ${KOPT_cryptdm}" clevisopts="-n ${KOPT_cryptopts}" fi if [ -n "$KOPT_cryptheader" ]; then cryptopts="$cryptopts -H ${KOPT_cryptheader}" fi if [ -n "$KOPT_cryptoffset" ]; then cryptopts="$cryptopts -o ${KOPT_cryptoffset}" fi if [ "$KOPT_cryptkey" = "yes" ]; then cryptopts="$cryptopts -k /crypto_keyfile.bin" elif [ -n "$KOPT_cryptkey" ]; then cryptopts="$cryptopts -k ${KOPT_cryptkey}" fi fi if [ -n "$clevisopts" ]; then clevis luks unlock $clevisopts fi