Files
garden/KaraKeep/attachments/bc1e8b42-d238-4476-867c-052d1446edde-systemd-cryptenroll-ArchWiki.jpg
Lauren Kaviak 14da5ef936
Some checks failed
Deploy Quartz site to Pages / build (push) Successful in 2m43s
Deploy Quartz site to Pages / deploy (push) Failing after 9s
updated content
2026-04-23 20:31:22 -05:00

136 lines
16 KiB
Plaintext

<div id="readability-page-1" class="page"><div lang="en" dir="ltr" id="mw-content-text">
<p>From <span title="$ man 1 systemd-cryptenroll"><a rel="nofollow" href="https://man.archlinux.org/man/systemd-cryptenroll.1">systemd-cryptenroll(1)</a></span>:
</p>
<dl><dd>systemd-cryptenroll is a tool for enrolling hardware security tokens and devices into a LUKS2 encrypted volume, which may then be used to unlock the volume during boot.</dd></dl>
<p><i>systemd-cryptenroll</i> allows enrolling <a href="https://wiki.archlinux.org/title/Smartcards" title="Smartcards">smartcards</a>, <a href="https://wiki.archlinux.org/title/Universal_2nd_Factor" title="Universal 2nd Factor">FIDO2</a> tokens and <a href="https://wiki.archlinux.org/title/Trusted_Platform_Module" title="Trusted Platform Module">Trusted Platform Module</a> security chips into <a href="https://wiki.archlinux.org/title/LUKS" title="LUKS">LUKS</a> devices, as well as regular passphrases. These devices are later unlocked by <span title="$ man 8 systemd-cryptsetup@.service"><a rel="nofollow" href="https://man.archlinux.org/man/systemd-cryptsetup%40.service.8">systemd-cryptsetup@.service(8)</a></span>, using the enrolled tokens.
</p>
<p></p><h2 id="Installation">Installation</h2><p></p>
<p><i>systemd-cryptenroll</i> is part of and packaged with <span><a rel="nofollow" href="https://archlinux.org/packages/?name=systemd">systemd</a></span>. However, extra packages are required to use hardware devices as keys:
</p>
<ul><li>To use PKCS#11 tokens, <a href="https://wiki.archlinux.org/title/Install" title="Install">install</a> <span><a rel="nofollow" href="https://archlinux.org/packages/?name=libp11-kit">libp11-kit</a></span>, you may also need <span><a rel="nofollow" href="https://archlinux.org/packages/?name=opensc">opensc</a></span> and <span><a rel="nofollow" href="https://aur.archlinux.org/packages/opensc-p11-kit-module/">opensc-p11-kit-module</a></span><sup><small>AUR</small></sup><sup>[<a href="https://wiki.archlinux.org/title/Help:Procedures#Fix_broken_package_links" title="Help:Procedures">broken link</a>: package not found]</sup>.</li>
<li>To use FIDO2 tokens, install <span><a rel="nofollow" href="https://archlinux.org/packages/?name=libfido2">libfido2</a></span>.</li>
<li>To use TPM2 devices, install <span><a rel="nofollow" href="https://archlinux.org/packages/?name=tpm2-tss">tpm2-tss</a></span>.</li></ul>
<p></p><h2 id="List_keyslots">List keyslots</h2><p></p>
<p><i>systemd-cryptenroll</i> can list the keyslots in a LUKS device, similar to <code>cryptsetup</code> <a href="https://wiki.archlinux.org/title/Dm-crypt/Device_encryption#Key_management" title="Dm-crypt/Device encryption">luksDump</a>, but in a more user-friendly format.
</p>
<pre># systemd-cryptenroll /dev/<i>disk</i></pre>
<pre>SLOT TYPE
0 password
1 recovery
2 tpm2
</pre>
<p></p><h2 id="Erasing_keyslots">Erasing keyslots</h2><p></p>
<pre># systemd-cryptenroll /dev/<i>disk</i> --wipe-slot=<i>SLOT</i>
</pre>
<p>Where <i>SLOT</i> can be:
</p>
<ul><li>A single keyslot index, as represented in <a href="#List_keyslots">#List keyslots</a></li>
<li>A type of keyslot, which will erase all keyslots of that type. Valid types are <code>empty</code>, <code>password</code>, <code>recovery</code>, <code>pkcs11</code>, <code>fido2</code>, <code>tpm2</code></li>
<li>A combination of all of the above, separated by commas</li>
<li>The string <code>all</code>, which erases all keyslots on the device. This option can only be used when enrolling another device or passphrase at the same time.</li></ul>
<p>The <code>--wipe-slot</code> operation can be used in combination with all enrollment options, which is useful to update existing device enrollments:
</p>
<pre># systemd-cryptenroll /dev/<i>disk</i> --wipe-slot=fido2 --fido2-device=auto
</pre>
<p></p><h2 id="Enrolling_passphrases">Enrolling passphrases</h2><p></p>
<p></p><h3 id="Regular_password">Regular password</h3><p></p>
<p>This is equivalent to <code>cryptsetup luksAddKey</code>.
</p>
<pre># systemd-cryptenroll /dev/<i>disk</i> --password
</pre>
<p></p><h3 id="Recovery_key">Recovery key</h3><p></p>
<p>From <span title="$ man 1 systemd-cryptenroll"><a rel="nofollow" href="https://man.archlinux.org/man/systemd-cryptenroll.1">systemd-cryptenroll(1)</a></span>:
</p>
<dl><dd>Recovery keys are mostly identical to passphrases, but are computer-generated instead of being chosen by a human, and thus have a guaranteed high entropy. The key uses a character set that is easy to type in, and may be scanned off screen via a QR code.</dd></dl>
<p>A recovery key is designed to be used as a fallback if the hardware tokens are unavailable, and can be used in place of regular passphrases whenever they are required.
</p>
<pre># systemd-cryptenroll /dev/<i>disk</i> --recovery-key
</pre>
<p></p><h2 id="Enrolling_hardware_devices">Enrolling hardware devices</h2><p></p>
<p>The <code>--<i>type</i>-device</code> options must point to a valid device path of their respective type. A list of available devices can be obtained by passing the <code>list</code> argument to this option. Alternatively, if you only have a single device of the desired type connected, the <code>auto</code> option can be used to automatically select it.
</p>
<p></p><h3 id="PKCS#11_tokens_or_smartcards"><span id="PKCS.2311_tokens_or_smartcards"></span>PKCS#11 tokens or smartcards</h3><p></p>
<p>The token or smartcard must contain a RSA key pair, which will be used to encrypt the generated key that will be used to unlock the volume.
</p>
<pre># systemd-cryptenroll /dev/<i>disk</i> --pkcs11-token-uri=<i>device</i>
</pre>
<p></p><h3 id="FIDO2_tokens">FIDO2 tokens</h3><p></p>
<p>Any FIDO2 token that supports the "hmac-secret" extension can be used with <i>systemd-cryptenroll</i>. The following example would enroll a FIDO2 token to an encrypted LUKS2 block device, requiring only user presence as authentication.
</p>
<pre># systemd-cryptenroll /dev/<i>disk</i> --fido2-device=<i>device</i> --fido2-with-client-pin=no
</pre>
<p>In addition, <i>systemd-cryptenroll</i> supports using the token's built-in user verification methods:
</p>
<ul><li><code>--fido2-with-user-presence</code> defines whether to verify the user presence (i.e. by tapping the token) before unlocking, defaults to yes</li>
<li><code>--fido2-with-user-verification</code> defines whether to require user verification before unlocking, defaults to no</li></ul>
<div><p><strong>Note</strong></p><ul><li>These options will have no effect if the token does not support these features.</li>
<li>See <a rel="nofollow" href="https://developers.yubico.com/WebAuthn/WebAuthn_Developer_Guide/User_Presence_vs_User_Verification.html">User Presence vs User Verification</a> for more information on the difference between the two.</li></ul>
</div>
<p>By default, the cryptographic algorithm used when generating a FIDO2 credential is <i>es256</i> which denotes Elliptic Curve Digital Signature Algorithm (ECDSA) over NIST P-256 with SHA-256. If desired and provided by the FIDO2 token, a different cryptographic algorithm can be specified during enrollment.
</p>
<p><strong>Note</strong> This may also be desirable for those concerned with ECDSA. See <a href="https://wiki.archlinux.org/title/SSH_keys#ECDSA" title="SSH keys">SSH keys#ECDSA</a> for details.</p>
<p>Suppose that a previous FIDO2 token has already been enrolled and the user wishes to enroll another, the following generates an <i>eddsa</i> credential which denotes <a rel="nofollow" href="https://datatracker.ietf.org/doc/html/rfc8032">EdDSA</a> over Curve25519 with SHA-512 and authenticates the device with a previous enrolled token instead of a password.
</p>
<pre># systemd-cryptenroll /dev/<i>disk</i> --fido2-device=<i>device</i> --fido2-credential-algorithm=eddsa --unlock-fido2-device=auto
</pre>
<p><strong>Note</strong> Both tokens must be plugged in to the system for successful enrollment.</p>
<p></p><h3 id="Trusted_Platform_Module">Trusted Platform Module</h3><p></p>
<div>
<p><span><span><img src="https://wiki.archlinux.org/images/1/19/Tango-view-fullscreen.svg" decoding="async" width="48" height="48"></span></span><b>This article or section needs expansion.</b></p>
<p><b>Reason:</b> Document <code>--tpm2-seal-key-handle</code> <code>--tpm2-device-key</code> <code>--tpm2-pcrlock</code> (Discuss in <a rel="nofollow" href="https://wiki.archlinux.org/title/Talk:Systemd-cryptenroll">Talk:Systemd-cryptenroll</a>)</p>
</div>
<p><i>systemd-cryptenroll</i> has native support for enrolling LUKS keys in TPMs. It requires the following:
</p>
<ul><li><span><a rel="nofollow" href="https://archlinux.org/packages/?name=tpm2-tss">tpm2-tss</a></span> must be <a href="https://wiki.archlinux.org/title/Install" title="Install">installed</a>,</li>
<li>A LUKS2 device (currently the default type used by <a href="https://wiki.archlinux.org/title/Cryptsetup" title="Cryptsetup">cryptsetup</a>),</li>
<li>If you intend to use this method on your root partition, some tweaks need to be made to the <a href="https://wiki.archlinux.org/title/Initramfs" title="Initramfs">initramfs</a> (see <a href="https://wiki.archlinux.org/title/Dm-crypt/System_configuration#Using_systemd-cryptsetup-generator" title="Dm-crypt/System configuration">dm-crypt/System configuration#Using systemd-cryptsetup-generator</a> for advanced configuration)&nbsp;:
<ul><li><a href="https://wiki.archlinux.org/title/Mkinitcpio" title="Mkinitcpio">mkinitcpio</a> users: enable the <code>systemd</code> and <code>sd-encrypt</code> <a href="https://wiki.archlinux.org/title/Mkinitcpio#HOOKS" title="Mkinitcpio">hooks</a>. </li>
<li><a href="https://wiki.archlinux.org/title/Dracut" title="Dracut">dracut</a> users: enable the <code>tpm2-tss</code> <a href="https://wiki.archlinux.org/title/Dracut#dracut_modules" title="Dracut">module</a>.</li></ul></li></ul>
<p>To begin, run the following command to list your installed TPMs and the driver in use:
</p>
<pre>$ systemd-cryptenroll --tpm2-device=list
</pre>
<div><p><strong>Tip</strong></p><ul><li>If your computer has multiple TPMs installed, specify the one you wish to use with <code>--tpm2-device=<i>/path/to/tpm2_device</i></code> in the following steps.</li>
<li>Consider using <a href="https://wiki.archlinux.org/title/Trusted_Platform_Module#PCR_policies" title="Trusted Platform Module">PCR policies</a> instead of binding secrets to raw PCR values.</li></ul></div>
<p>A key may be enrolled in both the TPM and the LUKS volume using only one command. The following example generates a new random key, adds it to the volume so it can be used to unlock it in addition to the existing keys, and binds this new key to PCR 7 (<a href="https://wiki.archlinux.org/title/Secure_Boot" title="Secure Boot">Secure Boot</a> state):
</p>
<pre># systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 /dev/<i>sdX</i>
</pre>
<p>where <code>/dev/<i>sdX</i></code> is the full path to the encrypted LUKS volume. Use <code>--unlock-key-file=<i>/path/to/keyfile</i></code> if the LUKS volume is unlocked by a keyfile instead of a passphrase.
</p><p>Refer to <span title="$ man 1 systemd-cryptenroll"><a rel="nofollow" href="https://man.archlinux.org/man/systemd-cryptenroll.1">systemd-cryptenroll(1)</a></span> and <a href="https://wiki.archlinux.org/title/Trusted_Platform_Module#Accessing_PCR_registers" title="Trusted Platform Module">Trusted Platform Module#Accessing PCR registers</a> for common PCR measurements in Linux. Adjust <code>--tpm2-pcrs=7</code> as necessary (parameters are separated by the <code>+</code> symbol).
</p>
<div><p><strong>Warning</strong></p><ul><li>Make sure <a href="https://wiki.archlinux.org/title/Secure_Boot" title="Secure Boot">Secure Boot</a> is active and in user mode when binding to PCR 7, otherwise, unauthorized boot devices could unlock the encrypted volume.</li>
<li>The state of PCR 7 can change if firmware certificates change, which can risk locking the user out. This can be implicitly done by <a href="https://wiki.archlinux.org/title/Fwupd" title="Fwupd">fwupd</a><a rel="nofollow" href="https://github.com/systemd/systemd/blob/ed272a9ff59a26beedaab508dd3c9d631de67165/TODO#L664-L673">[1]</a> or explicitly by rotating Secure Boot keys.</li>
<li>Only binding to PCRs measured pre-boot (PCRs 0-7) opens a vulnerability from rogue operating systems. A rogue partition with metadata copied from the real root filesystem (such as partition UUID) can mimic the original partition. Then, initramfs will attempt to mount the rogue partition as the root filesystem (decryption failure will fall back to password entry), leaving pre-boot PCRs unchanged. The rogue root filesystem with files controlled by an attacker is still able to receive the decryption key for the real root partition. See <a rel="nofollow" href="https://0pointer.net/blog/brave-new-trusted-boot-world.html">Brave New Trusted Boot World</a> and <a rel="nofollow" href="https://learn.microsoft.com/en-us/windows/security/operating-system-security/data-protection/bitlocker/countermeasures">BitLocker documentation</a> for additional information.</li>
<li>A solution for the root volume is to bind to an empty PCR 15 using <code>--tpm2-pcrs=<i>other_pcrs</i>+15:sha256=0000000000000000000000000000000000000000000000000000000000000000</code>. If you set any <code>rd.luks</code> kernel parameters or use <code>/etc/crypttab.initramfs</code>, additionally add the <code>tpm2-measure-pcr=yes</code> option to <code>rd.luks.options=</code> or the fourth field in <code>/etc/crypttab.initramfs</code>; this is not required when relying on <a href="https://wiki.archlinux.org/title/Systemd#GPT_partition_automounting" title="Systemd">GPT partition automounting</a>. After the root volume is unlocked in early userspace, PCR 15 will change and the enrolled key will no longer be retrievable.</li>
<li>Another cleaner solution is described in the <a href="https://wiki.archlinux.org/title/Dm-crypt/System_configuration#Pinning_a_LUKS_Volume" title="Dm-crypt/System configuration">Pinning a LUKS volume</a> section.</li></ul>
</div>
<p>The combination of PCRs to bind to depends on the individual case to balance usability and lock-down. For example, you may require UEFI firmware updates without manual intervention to the <a href="https://wiki.archlinux.org/title/Secure_Boot" title="Secure Boot">Secure Boot</a> state, or different boot devices. As another example, Microsoft's <a rel="nofollow" href="https://learn.microsoft.com/en-us/windows-hardware/test/hlk/testref/954cf796-a640-4134-b742-eaf0ed2663ff#troubleshooting">Bitlocker</a> prefers PCR <code>7+11</code>, but may also use other PCR combinations.
</p>
<div><p><strong>Note</strong></p><ul><li>It is possible to require a PIN to be entered in addition to the TPM state being correct. Simply add the option <code>--tpm2-with-pin=yes</code> to the command above and enter the PIN when prompted.</li>
<li><i>systemd-cryptenroll</i> does not check the TPM measurement before asking for the PIN, therefore consider using a unique PIN since the environment may be untrustworthy.</li></ul>
</div>
<p>To check that the new key was enrolled, dump the LUKS configuration and look for a <code>systemd-tpm2</code> token entry, as well as an additional entry in the <i>Keyslots</i> section:
</p>
<pre># cryptsetup luksDump /dev/sdX
</pre>
<p>To test that the key works, run the following command while the LUKS volume is closed:
</p>
<pre># systemd-cryptsetup attach <i>mapping_name</i> /dev/<i>sdX</i> none tpm2-device=auto
</pre>
<p>where <code><i>mapping_name</i></code> is your chosen name for the volume once opened.
</p><p>See <a href="https://wiki.archlinux.org/title/Dm-crypt/System_configuration#crypttab" title="Dm-crypt/System configuration">dm-crypt/System configuration#crypttab</a> and <a href="https://wiki.archlinux.org/title/Dm-crypt/System_configuration#Trusted_Platform_Module_and_FIDO2_keys" title="Dm-crypt/System configuration">dm-crypt/System configuration#Trusted Platform Module and FIDO2 keys</a> in order to unlock the volume at boot time.
</p>
<p><strong>Note</strong> While you may specify the UUID of your LUKS volume in place of the pathname in <code>/etc/crypttab</code>, the <i>systemd-cryptenroll</i> command itself currently only supports path names.</p>
<p>See <span title="$ man 1 systemd-cryptenroll"><a rel="nofollow" href="https://man.archlinux.org/man/systemd-cryptenroll.1">systemd-cryptenroll(1)</a></span> and <span title="$ man 5 crypttab"><a rel="nofollow" href="https://man.archlinux.org/man/crypttab.5">crypttab(5)</a></span> for more information and examples.
</p>
<p></p><h2 id="See_also">See also</h2><p></p>
<ul><li><a rel="nofollow" href="https://0pointer.net/blog/unlocking-luks2-volumes-with-tpm2-fido2-pkcs11-security-hardware-on-systemd-248.html">Lennart's blog: Unlocking LUKS2 volumes with TPM2, FIDO2, PKCS#11 Security Hardware on systemd 248</a></li></ul>
</div></div>