Skip to content

Add TPM 1.2 support#462

Open
oldium wants to merge 28 commits intolatchset:masterfrom
oldium:feature/tpm1
Open

Add TPM 1.2 support#462
oldium wants to merge 28 commits intolatchset:masterfrom
oldium:feature/tpm1

Conversation

@oldium
Copy link
Copy Markdown
Contributor

@oldium oldium commented May 5, 2024

This patch series adds TPM 1.2 support and fixes few other things (I can split this into multiple Pull Requests if you wish):

  • Added missing shutdown SystemD dependencies when using DefaultDependencies=no.
  • When Dracut without SystemD is used, benefit cryptsetup unlocking workflow to let it handle the crypttab and other options. This uses pipe to unlock with password similarly like the initramfs-tools image does. See commit message for more details.
  • Added full support for TPM 1.2.

Status:

  • [✅ Done] Clevis encrypt, decrypt, bind support
  • [✅ Done] initramfs-tools support
  • [✅ Done] Systemd support
  • [✅ Done] Manual page for clevis-encrypt-tpm1
  • [✅ Done] Tests for tpm1 pin
  • [✅ Done] Dracut support

Example usage:

  • Boot and unlock with TPM1.2:
    clevis luks bind -d /dev/<device> tpm1 '{"pcr_ids":"0,4,7"}'
  • Encrypt and decrypt:
    echo test | clevis encrypt tpm1 '{"pcr_ids":"0,4,7"}' | clevis decrypt

Tested:

  • Tested with initramfs-tools, used both TPM 1.2 and null pins with "fail":true to test success and failed unlocking
  • Tested with Dracut with SystemD. Tested both success and failed cases
  • Tested with Dracut without SystemD (module was disabled). Tested both success and failed cases
  • Tested with Dracut without SystemD (module was disabled), with programmatically changed detection that null pin is a network pin. Tested that with rd.neednet the unlocking happens after network gets online.

Fixes: #84, #456

Comment thread src/initramfs-tools/hooks/clevis.in Fixed
@oldium oldium force-pushed the feature/tpm1 branch 2 times, most recently from 556332d to 04d5e9f Compare May 5, 2024 22:09
Comment thread src/pins/tang/tests/tang-common-test-functions.in Fixed
@oldium oldium force-pushed the feature/tpm1 branch 4 times, most recently from 2c32eb7 to a7de265 Compare May 8, 2024 14:26
Comment thread src/luks/clevis-luks-tpm1-functions Fixed
Comment thread src/luks/clevis-luks-tpm1-functions Fixed
Comment thread src/luks/clevis-luks-tpm1-functions Fixed
Comment thread src/luks/clevis-luks-tpm1-functions Fixed
Comment thread src/luks/clevis-luks-tpm1-functions Fixed
Comment thread src/luks/dracut/clevis-pin-tpm1/module-setup.sh.in Fixed
Comment thread src/luks/dracut/clevis-pin-tpm1/module-setup.sh.in Fixed
Comment thread src/luks/dracut/clevis/clevis-luks-unlocker.in Fixed
Comment thread src/luks/dracut/clevis/clevis-luks-unlocker.in Fixed
Comment thread src/luks/dracut/clevis/clevis-luks-unlocker.in Fixed
Comment thread src/luks/dracut/clevis/clevis-luks-unlocker.in Fixed
@oldium oldium force-pushed the feature/tpm1 branch 2 times, most recently from b4cc648 to e83e669 Compare June 23, 2024 12:20
Comment thread src/initramfs-tools/scripts/local-top/clevis.in Fixed
Comment thread src/initramfs-tools/scripts/local-top/clevis.in Fixed
Comment thread src/initramfs-tools/scripts/local-top/clevis.in Fixed
Comment thread src/luks/clevis-luks-common-functions.in Fixed
Comment thread src/luks/clevis-luks-common-functions.in Fixed
Comment thread src/luks/dracut/clevis/clevis-password-unlocker.in Fixed
Comment thread src/luks/dracut/clevis/clevis-password-unlocker.in Fixed
Comment thread src/luks/dracut/clevis/clevis-password-unlocker.in Fixed
Comment thread src/luks/dracut/clevis/clevis-password-unlocker.in Fixed
Comment thread src/luks/dracut/clevis/clevis-password-unlocker.in Fixed
@oldium oldium force-pushed the feature/tpm1 branch 3 times, most recently from dc1c5c3 to 40bfdf4 Compare June 23, 2024 13:46
@oldium oldium marked this pull request as ready for review June 23, 2024 14:08
@oldium oldium changed the title [WIP] Add TPM 1.2 support Add TPM 1.2 support Jun 23, 2024
@oldium
Copy link
Copy Markdown
Contributor Author

oldium commented Jun 30, 2024

Work is done, pre-built packages for Debian 12 and amd64 arch are available here https://github.com/oldium/clevis/releases/tag/v20_tpm1

@oldium
Copy link
Copy Markdown
Contributor Author

oldium commented Jul 3, 2024

The CentOS test build image needs some love, the mirrorlist.centos.org site does not exist any more it seems.
image

@oldium
Copy link
Copy Markdown
Contributor Author

oldium commented Jul 3, 2024

Rebased to latest master to fix the build.

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
The command fails in Docker or otherwise limited environments, so skip the
test when it is not usable.

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
…oot)

[code-review] Unnecessary keyword.

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
…oot)

[code-review] Check return value.

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
[code-review] Check return value.

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
[code-review] Update wording.

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
[code-review] Unify the function signatures.

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
Add forgotten copyright header.

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
Fix PCR bank and sealing fail logic.

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
Add missing local variable declaration.

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
Fix PCR bank and sealing fail logic in test.

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
Fix usage of uninitialized ${orig} value. Also test exactly the string
without having newlines added by echo.

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
Fix usage of uninitialized ${orig} value. Also test exactly the string
without having newlines added by echo.

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
@aadnehovda
Copy link
Copy Markdown

Would this play nicely together with #467? Anything missing? Great for proxmox ZFS root on older TPM 1.2 only hardware.

@oldium
Copy link
Copy Markdown
Contributor Author

oldium commented Sep 14, 2025

Would this play nicely together with #467? Anything missing? Great for proxmox ZFS root on older TPM 1.2 only hardware.

Hard to say without looking more into the ZFS support. I see some code duplication in the ZFS initramfs hook, it installs basically the same binaries as the regular clevis hook. It misses TPM1.2 completely (for obvious reasons).

From the brief look I was not able to tell how exactly the ZFS unlocking works, but if it uses the same clevis functionality to decrypt the password, it should (in theory) work.

Side note: I have rebased my patches and changed them according to code-review input plus few fixes more (also for easier packaging of the new file pin in Debian). I will send an update within a week or two after testing it.

@oldium
Copy link
Copy Markdown
Contributor Author

oldium commented Sep 14, 2025

Possibly there will be some startup changes necessary to line-up with the ZFS support, because the clevis initramfs local-top script just starts the tcsd (TPM1.2 daemon) only in case the tpm1 pin is detected by get_pid_device_pins function (again, I do not know how the ZFS integration works). For dracut startup I can imagine missing optional startup dependency on tcsd.

Anyway, nothing impossible to do.

@almereyda almereyda mentioned this pull request Sep 14, 2025
5 tasks
Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
@oldium
Copy link
Copy Markdown
Contributor Author

oldium commented Nov 16, 2025

Added several fixup! commits ready to be rebased after code review (with git rebase --autosquash). It is ready to be read one-by-one, the commits are small and self-explanatory.

On top of the code-review fixes, I added the following:

  • Few additional safety checks and local variable declarations.
  • Fixed usage of uninitialized variable in tpm2/tpm1 test code (the test did not test what it should test for a looooooong time...).
  • Fixed new template and file pins to allow installation under Debian. Debian installs all Dracut scripts and uses check() function to determine if the pin is actually installed on the system.

On top of that, I created a new tpm1u8 version and published GPG signed packages in the public repository – see the Release Notes.

Copy link
Copy Markdown
Collaborator

@sarroutbi sarroutbi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks for your PR. @sergio-correia : A double opinion is welcome here

@oldium
Copy link
Copy Markdown
Contributor Author

oldium commented Dec 12, 2025

Just a kind reminder: Please do not merge without auto-squashing first (git rebase --autosquash), I would be sad to have the commit history in this state 😁. I would like to do it when the reviews are finished.

@akostadinov
Copy link
Copy Markdown

Who needs to approve this PR for merge?

@sarroutbi
Copy link
Copy Markdown
Collaborator

sarroutbi commented Feb 18, 2026

Who needs to approve this PR for merge?

Changes LGTM. Waiting for @sergio-correia to check if anything else is required (it seems all suggested nits were resolved)

@oldium
Copy link
Copy Markdown
Contributor Author

oldium commented Apr 14, 2026

[Updated]

@sarroutbi I am testing the rebase and almost everything works. Unfortunately, the newest Ubuntu 26.04 is using Dracut 110, which renumbered the systemd-cryptsetup module from 11 to 71, so we cannot add “needs” for cryptsetup.target, which is installed after clevis (we were 60, currently 50). The Dracut change breaks actually all versions of clevis-dracut - I am talking about this line, we do not depend on systemd-cryptsetup intentionally to allow installation without systemd. So either we switch some code to 90-99 range (not recommended for general use, but for adding one “needs” it would suffice), or create a bug report in Dracut repo, or think about a different solution...

Hm, or maybe I am wrong. Dracut has 00systemd, which installs cryptsetup.target. Let me check more...

[Edit]
00systemd is not installed - it is in old dracut repo, not dracut-ng...

Copy link
Copy Markdown
Collaborator

@sergio-correia sergio-correia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oldium: Thanks, I finally had a chance to review this again. Looks very nice, but I pointed a few small issues to fix. Please, also rebase on top of the current master. Also, are you going to autosquash those fixup commits?


copy_exec "${tcsd_bin}" || die 1 "Unable to copy ${tcsd_bin}"
copy_exec "${libgcc_s}" || die 1 "Unable to copy ${libgcc_s}"
copy_file config /etc/tcsd.conf || dia 2 "Unable to copy /etc/tcsd.conf"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo here: should be die instead of dia

echo "root:x:0:0:root:/root:/bin/bash" >> "${DESTDIR}/etc/passwd"
echo "root:x:0:" >> "${DESTDIR}/etc/group"

group_id=`id -G tss` || die 2 "Unable to get tss group ID"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this supposed to be id -g (lowercase), to return all groups instead of primary GID?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The id -G is actually returning all groups, so this might form an invalid entry (not usually the case, tss is a system user created during package installation with single group tss). This usage is specifically about the group ID of the tss group, so getting it through the primary group of tss user is the way to go - id -g tss should be used.

[ -f "/sys/class/tpm/tpm0/pcr-${_pcr_bank}/${_pcr}" ] || return 1
done
else
local pcr_args="${pcr_ids:+-p}${pcr_ids//,/ -p}"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we should use $_pcrs (which we define in this validate_pcrs() function) here; we are using the "outer" $pcr_ids instead, whihc seems to work by coincidence.

if ! ps -A -o pid | awk -v pid="${pid}" '$1==pid {found=1} END {exit !found}'; then
error "Failed waiting, ${name:process} terminated"
elif [ "${elapsed}" -gt "${max_timeout_in_s}" ]; then
error "Timeout (${max_timeout_in_s}s) waiting for ${name:process}"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

${name:process} should be ${name:-process} (missing the dash for the default value), in those two instances here.

int
setgid(gid_t gid)
{
static int (*real_setgid)(uid_t) = NULL;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gid_t instead of uid_t here.

}
return real_setgid(gid);
}
return 0;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This return is unreachable, please just remove it.


local enc
if ! enc=$(echo -n "${orig}" | clevis encrypt tpm1 "${cfg}"); then
echo "${TEST}: encrypt failed for cfg: ${cfg}" >&1
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be >&2

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, a copy-paste from tpm2 pin test 🙈 Fixing it there too.

@oldium
Copy link
Copy Markdown
Contributor Author

oldium commented Apr 14, 2026

Thanks @sergio-correia for the review, I now feel like a kid. I saw the code so many times and have not noticed that 😅. I will fix all your findings and auto-squash it.

@oldium
Copy link
Copy Markdown
Contributor Author

oldium commented Apr 14, 2026

The issue with Dracut 110 is reported here #545

@guilherme-puida
Copy link
Copy Markdown

I commented this in #545 as well, but clevis 20-1ubuntu2 was uploaded with a patch that fixes the ordering issue.

@oldium
Copy link
Copy Markdown
Contributor Author

oldium commented Apr 16, 2026

I will rebase onto #549 to create a non-conflicting branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for TPM 1.x

10 participants