diff --git a/features/clevis/README.md b/features/clevis/README.md new file mode 100644 index 00000000..b2e46e99 --- /dev/null +++ b/features/clevis/README.md @@ -0,0 +1,28 @@ +# clevis + +The `clevis` feature adds optional support for Clevis-based LUKS unlock in +initrd. + +When this feature is enabled, the `luks` handler tries to unlock a LUKS device +with Clevis before falling back to the existing interactive passphrase prompt. + +If Clevis is not available in the image, or if Clevis-based unlock fails, the +existing password prompt logic is preserved. + +## Requirements + +This feature is intended to be used together with the `luks` feature. + +A Clevis-enabled LUKS device must be provisioned in advance on the installed +system, for example with TPM2 binding. + +For more information about Clevis see: + + +## Configuration + +Enable the feature by adding it to `FEATURES`: + +```make +FEATURES += clevis +``` diff --git a/features/clevis/config.mk b/features/clevis/config.mk new file mode 100644 index 00000000..46175f72 --- /dev/null +++ b/features/clevis/config.mk @@ -0,0 +1 @@ +$(call feature-requires, luks) diff --git a/features/clevis/guess/device b/features/clevis/guess/device new file mode 100755 index 00000000..b80ee15e --- /dev/null +++ b/features/clevis/guess/device @@ -0,0 +1,30 @@ +#!/bin/bash -efu +# SPDX-License-Identifier: GPL-3.0-or-later + +[ -d "$SYSFS_PATH$1"/dm ] || exit 0 +command -v clevis >/dev/null 2>&1 || exit 0 + +. guess-functions + +uuid= +readline uuid "$SYSFS_PATH$1"/dm/uuid + +[ -n "$uuid" ] || exit 0 + +# CRYPT-LUKS1-00000000000000000000000000000000-name +# CRYPT-LUKS2-00000000000000000000000000000000-name +if [[ "$uuid" =~ CRYPT-[^-]+-([0-9A-Fa-f]{32})-.* ]]; then + raw_uuid="${BASH_REMATCH[1]}" +else + exit 0 +fi + +dashed_uuid="${raw_uuid:0:8}-${raw_uuid:8:4}-${raw_uuid:12:4}-${raw_uuid:16:4}-${raw_uuid:20:12}" +dev="/dev/disk/by-uuid/$dashed_uuid" +dev="$(readlink -ef "$dev" 2>/dev/null || true)" + +[ -b "$dev" ] || exit 0 + +clevis luks list -d "$dev" >/dev/null 2>&1 || exit 0 + +guess_feature clevis diff --git a/features/clevis/rules.mk b/features/clevis/rules.mk new file mode 100644 index 00000000..1bb0e1a5 --- /dev/null +++ b/features/clevis/rules.mk @@ -0,0 +1,15 @@ +PUT_FEATURE_PROGS += \ + clevis \ + clevis-decrypt \ + clevis-decrypt-tpm2 \ + clevis-luks-unlock \ + clevis-pin-tpm2 \ + cryptsetup \ + jq \ + jose \ + tpm2_pcrread \ + tpm2_getcap + +PUT_FEATURE_FILES += /usr/bin/clevis-luks-common-functions + +PUT_FEATURE_LIBS += libtss2-tcti-device.so.0 diff --git a/features/luks/data/lib/uevent/handlers/085-luks b/features/luks/data/lib/uevent/handlers/085-luks index 32ec2eb9..88b3f915 100755 --- a/features/luks/data/lib/uevent/handlers/085-luks +++ b/features/luks/data/lib/uevent/handlers/085-luks @@ -349,6 +349,17 @@ handler() { message "The keyfile was not found for partition: $LUKS_ROOT" rc=1 fi + if command -v clevis >/dev/null 2>&1; then + message "Сlevis detected." + message "Attempting to decrypt the partition using clevis luks..." + if [ "$rc" -ne 0 ] && shell_var_is_no "$luks_headless"; then + clevis luks unlock -d "$LUKS_ROOT" -n "$luks_volume" + rc="$?" + fi + if [ "$rc" -ne 0 ]; then + message "clevis could not decrypt!" + fi + fi if [ "$rc" -ne 0 ] && shell_var_is_no "$luks_headless"; then if shell_var_is_yes "$luks_empty_password"; then