man: document new features

This commit is contained in:
Lennart Poettering 2020-12-07 17:18:52 +01:00
parent 1abaa19781
commit cf1e172d58
10 changed files with 603 additions and 94 deletions

View File

@ -45,13 +45,12 @@
The first two fields are mandatory, the remaining two are
optional.</para>
<para>Setting up encrypted block devices using this file supports
three encryption modes: LUKS, TrueCrypt and plain. See
<citerefentry project='die-net'><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
for more information about each mode. When no mode is specified in
the options field and the block device contains a LUKS signature,
it is opened as a LUKS device; otherwise, it is assumed to be in
raw dm-crypt (plain mode) format.</para>
<para>Setting up encrypted block devices using this file supports four encryption modes: LUKS, TrueCrypt,
BitLocker and plain. See <citerefentry
project='die-net'><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry> for
more information about each mode. When no mode is specified in the options field and the block device
contains a LUKS signature, it is opened as a LUKS device; otherwise, it is assumed to be in raw dm-crypt
(plain mode) format.</para>
<para>The four fields of <filename>/etc/crypttab</filename> are defined as follows:</para>
@ -65,9 +64,10 @@
<literal>UUID=</literal> followed by the UUID.</para></listitem>
<listitem><para>The third field specifies an absolute path to a file with the encryption
key. Optionally, the path may be followed by <literal>:</literal> and an fstab device specification
(e.g. starting with <literal>LABEL=</literal> or similar); in which case the path is taken relative to
the device file system root. If the field is not present or is <literal>none</literal> or
key. Optionally, the path may be followed by <literal>:</literal> and an
<filename>/etc/fstab</filename> style device specification (e.g. starting with
<literal>LABEL=</literal> or similar); in which case the path is taken relative to the specified
device's file system root. If the field is not present or is <literal>none</literal> or
<literal>-</literal>, a key file named after the volume to unlock (i.e. the first column of the line),
suffixed with <filename>.key</filename> is automatically loaded from the
<filename>/etc/cryptsetup-keys.d/</filename> and <filename>/run/cryptsetup-keys.d/</filename>
@ -83,6 +83,60 @@
<listitem><para>The fourth field, if present, is a comma-delimited list of options. The supported
options are listed below.</para></listitem>
</orderedlist>
</refsect1>
<refsect1>
<title>Key Acquisition</title>
<para>Six different mechanisms for acquiring the decryption key or passphrase unlocking the encrypted
volume are supported. Specifically:</para>
<orderedlist>
<listitem><para>Most prominently, the user may be queried interactively during volume activation
(i.e. typically at boot), asking them to type in the necessary passphrase(s).</para></listitem>
<listitem><para>The (unencrypted) key may be read from a file on disk, possibly on removable media. The third field
of each line encodes the location, for details see above.</para></listitem>
<listitem><para>The (unencrypted) key may be requested from another service, by specifying an
<constant>AF_UNIX</constant> file system socket in place of a key file in the third field. For details
see above and below.</para></listitem>
<listitem><para>The key may be acquired via a PKCS#11 compatible hardware security token or
smartcard. In this case an encrypted key is stored on disk/removable media, acquired via
<constant>AF_UNIX</constant>, or stored in the LUKS2 JSON token metadata header. The encrypted key is
then decrypted by the PKCS#11 token with an RSA key stored on it, and then used to unlock the encrypted
volume. Use the <option>pkcs11-uri=</option> option described below to use this mechanism.</para></listitem>
<listitem><para>Similar, the key may be acquired via a FIDO2 compatible hardware security token (which
must implement the "hmac-secret" extension). In this case a (during enrollment) randomly generated key
is stored on disk/removable media, acquired via <constant>AF_UNIX</constant>, or stored in the LUKS2
JSON token metadata header. The random key is hashed via a keyed hash function (HMAC) on the FIDO2
token, using a secret key stored on the token that never leaves it. The resulting hash value is then
used as key to unlock the encrypted volume. Use the <option>fido2-device=</option> option described
below to use this mechanism.</para></listitem>
<listitem><para>Similar, the key may be acquired via a TPM2 security chip. In this case a (during
enrollment) randomly generated key — encrypted by an asymmetric key derived from the TPM2 chip's seed
key — is stored on disk/removable media, acquired via <constant>AF_UNIX</constant>, or stored in the
LUKS2 JSON token metadata header. Use the <option>tpm2-device=</option> option described below to use
this mechanism.</para></listitem>
</orderedlist>
<para>For the latter five mechanisms the source for the key material used for unlocking the volume is
primarily configured in the third field of each <filename>/etc/crypttab</filename> line, but may also
configured in <filename>/etc/cryptsetup-keys.d/</filename> and
<filename>/run/cryptsetup-keys.d/</filename> (see above) or in the LUKS2 JSON token header (in case of
the latter three). Use the
<citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>
tool to enroll PKCS#11, FIDO2 and TPM2 devices in LUKS2 volumes.</para>
</refsect1>
<refsect1>
<title>Supported Options</title>
<para>The following options may be used in the fourth field of each line:</para>
<variablelist class='fstab-options'>
@ -125,10 +179,10 @@
for possible values and the default value of this
option.</para>
<para>Optionally, the path may be followed by <literal>:</literal> and an fstab device specification
(e.g. starting with <literal>UUID=</literal> or similar); in which case, the path is relative to the
device file system root. The device gets mounted automatically for LUKS device activation duration only.
</para></listitem>
<para>Optionally, the path may be followed by <literal>:</literal> and an
<filename>/etc/fstab</filename> device specification (e.g. starting with <literal>UUID=</literal> or
similar); in which case, the path is relative to the device file system root. The device gets mounted
automatically for LUKS device activation duration only.</para></listitem>
</varlistentry>
<varlistentry>
@ -198,8 +252,8 @@
<varlistentry>
<term><option>bitlk</option></term>
<listitem><para>Decrypt Bitlocker drive. Encryption parameters
are deduced by cryptsetup from Bitlocker header.</para></listitem>
<listitem><para>Decrypt BitLocker drive. Encryption parameters
are deduced by cryptsetup from BitLocker header.</para></listitem>
</varlistentry>
<varlistentry>
@ -269,7 +323,7 @@
<varlistentry>
<term><option>same-cpu-crypt</option></term>
<listitem><para>Perform encryption using the same cpu that IO was submitted on. The default is to use
<listitem><para>Perform encryption using the same CPU that IO was submitted on. The default is to use
an unbound workqueue so that encryption work is automatically balanced between available CPUs.</para>
<para>This requires kernel 4.0 or newer.</para>
@ -451,15 +505,134 @@
<varlistentry>
<term><option>pkcs11-uri=</option></term>
<listitem><para>Takes a <ulink url="https://tools.ietf.org/html/rfc7512">RFC7512 PKCS#11 URI</ulink>
pointing to a private RSA key which is used to decrypt the key specified in the third column of the
line. This is useful for unlocking encrypted volumes through security tokens or smartcards. See below
for an example how to set up this mechanism for unlocking a LUKS volume with a YubiKey security
token. The specified URI can refer directly to a private RSA key stored on a token or alternatively
<listitem><para>Takes either the special value <literal>auto</literal> or an <ulink
url="https://tools.ietf.org/html/rfc7512">RFC7512 PKCS#11 URI</ulink> pointing to a private RSA key
which is used to decrypt the encrypted key specified in the third column of the line. This is useful
for unlocking encrypted volumes through PKCS#11 compatible security tokens or smartcards. See below
for an example how to set up this mechanism for unlocking a LUKS2 volume with a YubiKey security
token.</para>
<para>If specified as <literal>auto</literal> the volume must be of type LUKS2 and must carry PKCS#11
security token metadata in its LUKS2 JSON token section. In this mode the URI and the encrypted key
are automatically read from the LUKS2 JSON token header. Use
<citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>
as simple tool for enrolling PKCS#11 security tokens or smartcards in a way compatible with
<literal>auto</literal>. In this mode the third column of the line should remain empty (that is,
specified as <literal>-</literal>).</para>
<para>The specified URI can refer directly to a private RSA key stored on a token or alternatively
just to a slot or token, in which case a search for a suitable private RSA key will be performed. In
this case if multiple suitable objects are found the token is refused. The key configured in the
third column is passed as is to RSA decryption. The resulting decrypted key is then base64 encoded
before it is used to unlock the LUKS volume.</para></listitem>
this case if multiple suitable objects are found the token is refused. The encrypted key configured
in the third column of the line is passed as is (i.e. in binary form, unprocessed) to RSA
decryption. The resulting decrypted key is then Base64 encoded before it is used to unlock the LUKS
volume.</para>
<para>Use <command>systemd-cryptenroll --pkcs11-token-uri=list</command> to list all suitable PKCS#11
security tokens currently plugged in, along with their URIs.</para>
<para>Note that many newer security tokens that may be used as PKCS#11 security token typically also
implement the newer and simpler FIDO2 standard. Consider using <option>fido2-device=</option>
(described below) to enroll it via FIDO2 instead. Note that a security token enrolled via PKCS#11
cannot be used to unlock the volume via FIDO2, unless also enrolled via FIDO2, and vice
versa.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>fido2-device=</option></term>
<listitem><para>Takes either the special value <literal>auto</literal> or the path to a
<literal>hidraw</literal> device node (e.g. <filename>/dev/hidraw1</filename>) referring to a FIDO2
security token that implements the <literal>hmac-secret</literal> extension (most current hardware
security tokens do). See below for an example how to set up this mechanism for unlocking an encrypted
volume with a FIDO2 security token.</para>
<para>If specified as <literal>auto</literal> the FIDO2 token device is automatically discovered, as
it is plugged in.</para>
<para>FIDO2 volume unlocking requires a client ID hash (CID) to be configured via
<option>fido2-cid=</option> (see below) and a key to pass to the security token's HMAC functionality
(configured in the line's third column) to operate. If not configured and the volume is of type
LUKS2, the CID and the key are read from LUKS2 JSON token metadata instead. Use
<citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>
as simple tool for enrolling FIDO2 security tokens, compatible with this automatic mode, which is
only available for LUKS2 volumes.</para>
<para>Use <command>systemd-cryptenroll --fido2-device=list</command> to list all suitable FIDO2
security tokens currently plugged in, along with their device nodes.</para>
<para>This option implements the following mechanism: the configured key is hashed via they HMAC
keyed hash function the FIDO2 device implements, keyed by a secret key embedded on the device. The
resulting hash value is Base64 encoded and used to unlock the LUKS2 volume. As it should not be
possible to extract the secret from the hardware token, it should not be possible to retrieve the
hashed key given the configured key — without possessing the hardware token.</para>
<para>Note that many security tokens that implement FIDO2 also implement PKCS#11, suitable for
unlocking volumes via the <option>pkcs11-uri=</option> option described above. Typically the newer,
simpler FIDO2 standard is preferable.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>fido2-cid=</option></term>
<listitem><para>Takes a Base64 encoded FIDO2 client ID to use for the FIDO2 unlock operation. If
specified, but <option>fido2-device=</option> is not, <option>fido2-device=auto</option> is
implied. If <option>fido2-device=</option> is used but <option>fido2-cid=</option> is not, the volume
must be of LUKS2 type, and the CID is read from the LUKS2 JSON token header. Use
<citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>
for enrolling a FIDO2 token in the LUKS2 header compatible with this automatic
mode.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>fido2-rp=</option></term>
<listitem><para>Takes a string, configuring the FIDO2 Relying Party (rp) for the FIDO2 unlock
operation. If not specified <literal>io.systemd.cryptsetup</literal> is used, except if the the LUKS2
JSON token header contains a different value. It should normally not be necessary to override
this.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>tpm2-device=</option></term>
<listitem><para>Takes either the special value <literal>auto</literal> or the path to a device node
(e.g. <filename>/dev/tpmrm0</filename>) referring to a TPM2 security chip. See below for an example
how to set up this mechanism for unlocking an encrypted volume with a TPM2 chip.</para>
<para>Use <option>tpm2-pcrs=</option> (see below) to configure the set of TPM2 PCRs to bind the
volume unlocking to. Use
<citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>
as simple tool for enrolling TPM2 security chips in LUKS2 volumes.</para>
<para>If specified as <literal>auto</literal> the TPM2 device is automatically discovered. Use
<command>systemd-cryptenroll --tpm2-device=list</command> to list all suitable TPM2 devices currently
available, along with their device nodes.</para>
<para>This option implements the following mechanism: when enrolling a TPM2 device via
<command>systemd-cryptenroll</command> on a LUKS2 volume, a randomized key unlocking the volume is
generated on the host and loaded into the TPM2 chip where it is encrypted with an asymmetric
"primary" key pair derived from the TPM2's internal "seed" key. Neither the seed key nor the primary
key are permitted to ever leave the TPM2 chip — however, the now encrypted randomized key may. It is
saved in the LUKS2 volume JSON token header. When unlocking the encrypted volume, the primary key
pair is generated on the TPM2 chip again (which works as long as the chip's seed key is correctly
maintained by the TPM2 chip), which is then used to decrypt (on the TPM2 chip) the encrypted key from
the LUKS2 volume JSON token header saved there during enrollment. The resulting decrypted key is then
used to unlock the volume. When the randomized key is encrypted the current values of the selected
PCRs (see below) are included in the operation, so that different PCR state results in different
encrypted keys and the decrypted key can only be recovered if the same PCR state is
reproduced.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>tpm2-pcrs=</option></term>
<listitem><para>Takes a comma separated list of numeric TPM2 PCR (i.e. "Platform Configuration
Register") indexes to bind the TPM2 volume unlocking to. This option is only useful when TPM2
enrollment metadata is not available in the LUKS2 JSON token header already, the way
<command>systemd-cryptenroll</command> writes it there. If not used (and no metadata in the LUKS2
JSON token header defines it), defaults to a list of a single entry: PCR 7. Assign an empty string to
encode a policy that binds the key to no PCRs, making the key accessible to local programs regardless
of the current PCR state.</para></listitem>
</varlistentry>
<varlistentry>
@ -523,7 +696,7 @@
<programlisting><constant>NUL</constant> <replaceable>RANDOM</replaceable> <literal>/cryptsetup/</literal> <replaceable>VOLUME</replaceable></programlisting>
<para>In other words: a <constant>NUL</constant> byte (as required for abstract namespace sockets),
followed by a random string (consisting of alphabenumeric characters only), followed by the literal
followed by a random string (consisting of alphanumeric characters only), followed by the literal
string <literal>/cryptsetup/</literal>, followed by the name of the volume to acquire they key
for. Example (for a volume <literal>myvol</literal>):</para>
@ -533,11 +706,13 @@
name with <citerefentry
project='man-pages'><refentrytitle>getpeername</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
and use it to determine which key to send, allowing a single listening socket to serve keys for a
multitude of volumes. If the PKCS#11 logic is used (see below) the socket source name is picked in
identical fashion, except that the literal string <literal>/cryptsetup-pkcs11/</literal> is used. This is
multitude of volumes. If the PKCS#11 logic is used (see above) the socket source name is picked in
identical fashion, except that the literal string <literal>/cryptsetup-pkcs11/</literal> is used (similar
for FIDO2: <literal>/cryptsetup-fido2/</literal> and TPM2: <literal>/cryptsetup-tpm2/</literal>). This is
done so that services providing key material know that not a secret key is requested but an encrypted key
that will be decrypted via the PKCS#11 logic to acquire the final secret key.</para>
that will be decrypted via the PKCS#11/FIDO2/TPM2 logic to acquire the final secret key.</para>
</refsect1>
<refsect1>
<title>Examples</title>
<example>
@ -556,25 +731,48 @@ external /dev/sda3 keyfile:LABEL=keydev keyfile-timeout=10s,cipher=xchac
</example>
<example>
<title>Yubikey-based Volume Unlocking Example</title>
<title>Yubikey-based PKCS#11 Volume Unlocking Example</title>
<para>The PKCS#11 logic allows hooking up any compatible security token that is capable of storing RSA
decryption keys. Here's an example how to set up a Yubikey security token for this purpose, using
<citerefentry project='debian'><refentrytitle>ykmap</refentrytitle><manvolnum>1</manvolnum></citerefentry>
from the yubikey-manager project:</para>
decryption keys for unlocking an encrypted volume. Here's an example how to set up a Yubikey security
token for this purpose on a LUKS2 volume, using <citerefentry
project='debian'><refentrytitle>ykmap</refentrytitle><manvolnum>1</manvolnum></citerefentry> from the
yubikey-manager project to initialize the token and
<citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>
to add it in the LUKS2 volume:</para>
<programlisting><xi:include href="yubikey-crypttab.sh" parse="text" /></programlisting>
<para>A few notes on the above:</para>
<para>A few notes on the above:</para>
<itemizedlist>
<listitem><para>We use RSA2048, which is the longest key size current Yubikeys support</para></listitem>
<listitem><para>LUKS key size must be shorter than 2048bit due to RSA padding, hence we use 128 bytes</para></listitem>
<listitem><para>We use Yubikey key slot 9d, since that's apparently the keyslot to use for decryption purposes,
<ulink url="https://developers.yubico.com/PIV/Introduction/Certificate_slots.html">see
documentation</ulink>.</para></listitem>
</itemizedlist>
<itemizedlist>
<listitem><para>We use RSA2048, which is the longest key size current Yubikeys support</para></listitem>
<listitem><para>We use Yubikey key slot 9d, since that's apparently the keyslot to use for decryption purposes,
<ulink url="https://developers.yubico.com/PIV/Introduction/Certificate_slots.html">see
documentation</ulink>.</para></listitem>
</itemizedlist>
</example>
<example>
<title>FIDO2 Volume Unlocking Example</title>
<para>The FIDO2 logic allows using any compatible FIDO2 security token that implements the
<literal>hmac-secret</literal> extension for unlocking an encrypted volume. Here's an example how to
set up a FIDO2 security token for this purpose for a LUKS2 volume, using
<citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>:</para>
<programlisting><xi:include href="fido2-crypttab.sh" parse="text" /></programlisting>
</example>
<example>
<title>TPM2 Volume Unlocking Example</title>
<para>The TPM2 logic allows using any TPM2 chip supported by the Linux kernel for unlocking an
encrypted volume. Here's an example how to set up a TPM2 chip for this purpose for a LUKS2 volume,
using
<citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>:</para>
<programlisting><xi:include href="tpm2-crypttab.sh" parse="text" /></programlisting>
</example>
</refsect1>
@ -584,6 +782,7 @@ external /dev/sda3 keyfile:LABEL=keydev keyfile-timeout=10s,cipher=xchac
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-cryptsetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry project='die-net'><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>mkswap</refentrytitle><manvolnum>8</manvolnum></citerefentry>,

10
man/fido2-crypttab.sh Normal file
View File

@ -0,0 +1,10 @@
# Enroll the security token in the LUKS2 volume. Replace /dev/sdXn by the
# partition to use (e.g. /dev/sda1).
sudo systemd-cryptenroll --fido2-device=auto /dev/sdXn
# Test: Let's run systemd-cryptsetup to test if this worked.
sudo /usr/lib/systemd/systemd-cryptsetup attach mytest /dev/sdXn - fido2-device=auto
# If that worked, let's now add the same line persistently to /etc/crypttab,
# for the future.
sudo bash -c 'echo "mytest /dev/sdXn - fido2-device=auto" >> /etc/crypttab'

View File

@ -492,12 +492,19 @@
<varlistentry>
<term><varname>Encrypt=</varname></term>
<listitem><para>Takes a boolean parameter, defaulting to false. If true the partition will be
<listitem><para>Takes one of <literal>off</literal>, <literal>key-file</literal>,
<literal>tpm2</literal> and <literal>key-file+tpm2</literal> (alternatively, also accepts a boolean
value, which is mapped to <literal>off</literal> when false, and <literal>key-file</literal> when
true). Defaults to <literal>off</literal>. If not <literal>off</literal> the partition will be
formatted with a LUKS2 superblock, before the blocks configured with <varname>CopyBlocks=</varname>
are copied in or the file system configured with <varname>Format=</varname> is created.</para>
<para>The LUKS2 UUID is automatically derived from the partition UUID in a stable fashion. A single
key is added to the LUKS2 superblock, configurable with the <option>--key-file=</option> switch to
<para>The LUKS2 UUID is automatically derived from the partition UUID in a stable fashion. If
<literal>key-file</literal> or <literal>key-file+tpm2</literal> is used a key is added to the LUKS2
superblock, configurable with the <option>--key-file=</option> switch to
<command>systemd-repart</command>. If <literal>tpm2</literal> or <literal>key-file+tpm2</literal> is
used a key is added to the LUKS2 superblock that is enrolled to the local TPM2 chip, as configured
with the <option>--tpm2-device=</option> and <option>--tpm2-pcrs=</option> options to
<command>systemd-repart</command>.</para>
<para>When used this slightly alters the size allocation logic as the implicit, minimal size limits
@ -627,7 +634,8 @@ SizeMaxBytes=64M
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-repart</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>sfdisk</refentrytitle><manvolnum>8</manvolnum></citerefentry>
<citerefentry project='man-pages'><refentrytitle>sfdisk</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>
</para>
</refsect1>

View File

@ -825,6 +825,7 @@ manpages = [
'8',
['systemd-coredump.socket', 'systemd-coredump@.service'],
'ENABLE_COREDUMP'],
['systemd-cryptenroll', '1', [], 'HAVE_LIBCRYPTSETUP'],
['systemd-cryptsetup-generator', '8', [], 'HAVE_LIBCRYPTSETUP'],
['systemd-cryptsetup@.service',
'8',

284
man/systemd-cryptenroll.xml Normal file
View File

@ -0,0 +1,284 @@
<?xml version="1.0"?>
<!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
<refentry id="systemd-cryptenroll" xmlns:xi="http://www.w3.org/2001/XInclude" conditional='HAVE_LIBCRYPTSETUP'>
<refentryinfo>
<title>systemd-cryptenroll</title>
<productname>systemd</productname>
</refentryinfo>
<refmeta>
<refentrytitle>systemd-cryptenroll</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>systemd-cryptenroll</refname>
<refpurpose>Enroll PKCS#11, FIDO2, TPM2 token/devices to LUKS2 encrypted volumes</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>systemd-cryptenroll <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt">DEVICE</arg></command>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para><command>systemd-cryptenroll</command> 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. Specifically, it supports
tokens and credentials of the following kind to be enrolled:</para>
<orderedlist>
<listitem><para>PKCS#11 security tokens and smartcards that may carry an RSA key pair (e.g. various YubiKeys)</para></listitem>
<listitem><para>FIDO2 security tokens that implement the <literal>hmac-secret</literal> extension (most FIDO2 keys, including YubiKeys)</para></listitem>
<listitem><para>TPM2 security devices</para></listitem>
<listitem><para>Recovery keys. These are similar to regular passphrases, however are randomly generated
on the computer and thus generally have higher entropy than user chosen passphrases. Their character
set has been designed to ensure they are easy to type in, while having high entropy. They may also be
scanned off screen using QR codes. Recovery keys may be used for unlocking LUKS2 volumes wherever
passphrases are accepted. They are intended to be used in combination with an enrolled hardware
security token, as a recovery option when the token is lost.</para></listitem>
<listitem><para>Regular passphrases</para></listitem>
</orderedlist>
<para>In addition, the tool may be used to enumerate currently enrolled security tokens and wipe a subset
of them. The latter may be combined with the enrollment operation of a new security token, in order to
update or replace enrollments.</para>
<para>The tool supports only LUKS2 volumes, as it stores token meta-information in the LUKS2 JSON token
area, which is not available in other encryption formats.</para>
</refsect1>
<refsect1>
<title>Options</title>
<para>The following options are understood:</para>
<variablelist>
<varlistentry>
<term><option>--password</option></term>
<listitem><para>Enroll a regular password/passphrase. This command is mostly equivalent to
<command>cryptsetup luksAddKey</command>, however may be combined with
<option>--wipe-slot=</option> in one call, see below.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--recovery-key</option></term>
<listitem><para>Enroll a recovery key. Recovery keys are most identical to passphrases, but are
computer generated instead of human chosen, 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.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--pkcs11-token-uri=</option><replaceable>URI</replaceable></term>
<listitem><para>Enroll a PKCS#11 security token or smartcard (e.g. a YubiKey). Expects a PKCS#11
smart card URI referring to the token. Alternatively the special value <literal>auto</literal> may
be specified, in order to automatically determine the URI of a currently plugged in security token
(of which there must be exactly one). The special value <literal>list</literal> may be used to
enumerate all suitable PKCS#11 tokens currently plugged in. The security token must contain an RSA
key pair which is used to encrypt the randomly generated key that is used to unlock the LUKS2
volume. The encrypted key is then stored in the LUKS2 JSON token header area.</para>
<para>In order to unlock a LUKS2 volume with an enrolled PKCS#11 security token, specify the
<option>pkcs11-uri=</option> option in the respective <filename>/etc/crypttab</filename> line:</para>
<programlisting>myvolume /dev/sda1 - pkcs11-uri=auto</programlisting>
<para>See
<citerefentry><refentrytitle>crypttab</refentrytitle><manvolnum>5</manvolnum></citerefentry> for a
more comprehensive example of a <command>systemd-cryptenroll</command> invocation and its matching
<filename>/etc/crypttab</filename> line.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--fido2-device=</option><replaceable>PATH</replaceable></term>
<listitem><para>Enroll a FIDO2 security token that implements the <literal>hmac-secret</literal>
extension (e.g. a YubiKey). Expects a <filename>hidraw</filename> device referring to the FIDO2
device (e.g. <filename>/dev/hidraw1</filename>). Alternatively the special value
<literal>auto</literal> may be specified, in order to automatically determine the device node of a
currently plugged in security token (of which there must be exactly one). The special value
<literal>list</literal> may be used to enumerate all suitable FIDO2 tokens currently plugged in. Note
that many hardware security tokens that implement FIDO2 also implement the older PKCS#11
standard. Typically FIDO2 is preferable, given it's simpler to use and more modern.</para>
<para>In order to unlock a LUKS2 volume with an enrolled FIDO2 security token, specify the
<option>fido2-device=</option> option in the respective <filename>/etc/crypttab</filename> line:</para>
<programlisting>myvolume /dev/sda1 - fido2-device=auto</programlisting>
<para>See
<citerefentry><refentrytitle>crypttab</refentrytitle><manvolnum>5</manvolnum></citerefentry> for a
more comprehensive example of a <command>systemd-cryptenroll</command> invocation and its matching
<filename>/etc/crypttab</filename> line.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--tpm2-device=</option><replaceable>PATH</replaceable></term>
<listitem><para>Enroll a TPM2 security chip. Expects a device node path referring to the TPM2 chip
(e.g. <filename>/dev/tpmrm0</filename>). Alternatively the special value <literal>auto</literal> may
be specified, in order to automatically determine the device node of a currently discovered TPM2
device (of which there must be exactly one). The special value <literal>list</literal> may be used to
enumerate all suitable TPM2 devices currently discovered.</para>
<para>In order to unlock a LUKS2 volume with an enrolled TPM2 security chip, specify the
<option>tpm2-device=</option> option in the respective <filename>/etc/crypttab</filename> line:</para>
<programlisting>myvolume /dev/sda1 - tpm2-device=auto</programlisting>
<para>See
<citerefentry><refentrytitle>crypttab</refentrytitle><manvolnum>5</manvolnum></citerefentry> for a
more comprehensive example of a <command>systemd-cryptenroll</command> invocation and its matching
<filename>/etc/crypttab</filename> line.</para>
<para>Use <option>--tpm2-pcrs=</option> (see below) to configure which TPM2 PCR indexes to bind the
enrollment to.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--tpm2-pcrs=</option><arg rep="repeat">PCR</arg></term>
<listitem><para>Configures the TPM2 PCRs (Platform Configuration Registers) to bind the enrollment
requested via <option>--tpm2-device=</option> to. Takes a comma separated list of numeric PCR indexes
in the range 0…23. If not used, defaults to PCR 7 only. If an empty string is specified, binds the
enrollment to no PCRs at all. PCRs allow binding the enrollment to specific software versions and
system state, so that the enrolled unlocking key is only accessible (may be "unsealed") if specific
trusted software and/or configuration is used.</para></listitem>
<table>
<title>Well-known PCR Definitions</title>
<tgroup cols='2' align='left' colsep='1' rowsep='1'>
<colspec colname="pcr" />
<colspec colname="definition" />
<thead>
<row>
<entry>PCR</entry>
<entry>Explanation</entry>
</row>
</thead>
<tbody>
<row>
<entry>0</entry>
<entry>Core system firmware executable code; changes on firmware updates</entry>
</row>
<row>
<entry>1</entry>
<entry>Core system firmware data/host platform configuration; typically contains serial and model numbers, changes on basic hardware/CPU/RAM replacements</entry>
</row>
<row>
<entry>2</entry>
<entry>Extended or pluggable executable code; includes option ROMs on pluggable hardware</entry>
</row>
<row>
<entry>3</entry>
<entry>Extended or pluggable firmware data; includes information about pluggable hardware</entry>
</row>
<row>
<entry>4</entry>
<entry>Boot loader; changes on boot loader updates</entry>
</row>
<row>
<entry>5</entry>
<entry>GPT/Partition table; changes when the partitions are added, modified or removed</entry>
</row>
<row>
<entry>6</entry>
<entry>Power state events; changes on system suspend/sleep</entry>
</row>
<row>
<entry>7</entry>
<entry>Secure boot state; changes when UEFI SecureBoot mode is enabled/disabled</entry>
</row>
<row>
<entry>8</entry>
<entry><citerefentry><refentrytitle>sd-boot</refentrytitle><manvolnum>8</manvolnum></citerefentry> measures the kernel command line in this PCR.</entry>
</row>
</tbody>
</tgroup>
</table>
</varlistentry>
<varlistentry>
<term><option>--wipe-slot=</option><arg rep="repeat">SLOT</arg></term>
<listitem><para>Wipes one or more LUKS2 key slots. Takes a comma separated list of numeric slot
indexes, or the special strings <literal>all</literal> (for wiping all key slots),
<literal>empty</literal> (for wiping all key slots that are unlocked by an empty passphrase),
<literal>password</literal> (for wiping all key slots that are unlocked by a traditional passphrase),
<literal>recovery</literal> (for wiping all key slots that are unlocked by a recovery key),
<literal>pkcs11</literal> (for wiping all key slots that are unlocked by a PKCS#11 token),
<literal>fido2</literal> (for wiping all key slots that are unlocked by a FIDO2 token),
<literal>tpm2</literal> (for wiping all key slots that are unlocked by a TPM2 chip), or any
combination of these strings or numeric indexes, in which case all slots matching either are
wiped. As safety precaution an operation that wipes all slots without exception (so that the volume
cannot be unlocked at all anymore, unless the volume key is known) is refused.</para>
<para>This switch may be used alone, in which case only the requested wipe operation is executed. It
may also be used in combination with any of the enrollment options listed above, in which case the
enrollment is completed first, and only when successful the wipe operation executed — and the newly
added slot is always excluded from the wiping. Combining enrollment and slot wiping may thus be used to
update existing enrollments:</para>
<programlisting>systemd-cryptenroll /dev/sda1 --wipe-slot=tpm2 --tpm2-device=auto</programlisting>
<para>The above command will enroll the TPM2 chip, and then wipe all previously crated TPM2
enrollments on the LUKS2 volume, leaving only the newly created one. Combining wiping and enrollment
may also be used to replace enrollments of different types, for example for changing from a PKCS#11
enrollment to a FIDO2 one:</para>
<programlisting>systemd-cryptenroll /dev/sda1 --wipe-slot=pkcs11 --fido2-device=auto</programlisting>
<para>Or for replacing an enrolled empty password by TPM2:</para>
<programlisting>systemd-cryptenroll /dev/sda1 --wipe-slot=empty --tpm2-device=auto</programlisting>
</listitem>
</varlistentry>
<xi:include href="standard-options.xml" xpointer="help" />
<xi:include href="standard-options.xml" xpointer="version" />
</variablelist>
</refsect1>
<refsect1>
<title>Exit status</title>
<para>On success, 0 is returned, a non-zero failure code otherwise.</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-cryptsetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>crypttab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry project='die-net'><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>

View File

@ -228,6 +228,7 @@
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>crypttab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-cryptsetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry project='die-net'><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
</para>

View File

@ -50,13 +50,14 @@
<orderedlist>
<listitem><para>If a key file is explicitly configured (via the third column in
<filename>/etc/crypttab</filename>), a key read from it is used. If a PKCS#11 token is configured
(using the <varname>pkcs11-uri=</varname> option) the key is decrypted before use.</para></listitem>
<filename>/etc/crypttab</filename>), a key read from it is used. If a PKCS#11 token, FIDO2 token or
TPM2 device is configured (using the <varname>pkcs11-uri=</varname>, <varname>fido2-device=</varname>,
<varname>tpm2-device=</varname> options) the key is decrypted before use.</para></listitem>
<listitem><para>If no key file is configured explicitly this way, a key file is automatically loaded
from <filename>/etc/cryptsetup-keys.d/<replaceable>volume</replaceable>.key</filename> and
<filename>/run/cryptsetup-keys.d/<replaceable>volume</replaceable>.key</filename>, if present. Here
too, if a PKCS#11 token is configured, any key found this way is decrypted before
too, if a PKCS#11/FIDO2/TPM2 token/device is configured, any key found this way is decrypted before
use.</para></listitem>
<listitem><para>If the <varname>try-empty-password</varname> option is specified it is then attempted
@ -77,6 +78,7 @@
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>crypttab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry project='die-net'><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
</para>
</refsect1>

View File

@ -300,12 +300,23 @@
<term><option>--key-file=</option></term>
<listitem><para>Takes a file system path. Configures the encryption key to use when setting up LUKS2
volumes configured with the <varname>Encrypt=</varname> setting in partition files. Should refer to a
regular file containing the key, or an <constant>AF_UNIX</constant> stream socket in the file
system. In the latter case a connection is made to it and the key read from it. If this switch is not
specified the empty key (i.e. zero length key) is used. This behaviour is useful for setting up encrypted
partitions during early first boot that receive their user-supplied password only in a later setup
step.</para></listitem>
volumes configured with the <varname>Encrypt=key-file</varname> setting in partition files. Should
refer to a regular file containing the key, or an <constant>AF_UNIX</constant> stream socket in the
file system. In the latter case a connection is made to it and the key read from it. If this switch
is not specified the empty key (i.e. zero length key) is used. This behaviour is useful for setting
up encrypted partitions during early first boot that receive their user-supplied password only in a
later setup step.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--tpm2-device=</option></term>
<term><option>--tpm2-pcrs=</option></term>
<listitem><para>Configures the TPM2 device and list of PCRs to use for LUKS2 volumes configured with
the <varname>Encrypt=tpm2</varname> option. These options take the same parameters as the identically
named options to
<citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>
and have the same effect on partitions where TPM2 enrollment is requested.</para></listitem>
</varlistentry>
<xi:include href="standard-options.xml" xpointer="help" />
@ -313,12 +324,19 @@
</variablelist>
</refsect1>
<refsect1>
<title>Exit status</title>
<para>On success, 0 is returned, a non-zero failure code otherwise.</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>repart.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>
</para>
</refsect1>

10
man/tpm2-crypttab.sh Normal file
View File

@ -0,0 +1,10 @@
# Enroll the TPM2 security chip in the LUKS2 volume, and bind it to PCR 7
# only. Replace /dev/sdXn by the partition to use (e.g. /dev/sda1).
sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 /dev/sdXn
# Test: Let's run systemd-cryptsetup to test if this worked.
sudo /usr/lib/systemd/systemd-cryptsetup attach mytest /dev/sdXn - tpm2-device=auto
# If that worked, let's now add the same line persistently to /etc/crypttab,
# for the future.
sudo bash -c 'echo "mytest /dev/sdXn - tpm2-device=auto" >> /etc/crypttab'

View File

@ -1,50 +1,26 @@
# Make sure no one can read the files we generate but us
umask 077
# Destroy any old key on the Yubikey (careful!)
ykman piv reset
# Generate a new private/public key pair on the device, store the public key in 'pubkey.pem'.
# Generate a new private/public key pair on the device, store the public key in
# 'pubkey.pem'.
ykman piv generate-key -a RSA2048 9d pubkey.pem
# Create a self-signed certificate from this public key, and store it on the
# device. The "subject" should be an arbitrary string to identify the token in
# the p11tool output below.
# device. The "subject" should be an arbitrary user-chosen string to identify
# the token with.
ykman piv generate-certificate --subject "Knobelei" 9d pubkey.pem
# Check if the newly create key on the Yubikey shows up as token in PKCS#11. Have a look at the output, and
# copy the resulting token URI to the clipboard.
p11tool --list-tokens
# Generate a (secret) random key to use as LUKS decryption key.
dd if=/dev/urandom of=plaintext.bin bs=128 count=1
# Encode the secret key also as base64 text (with all whitespace removed)
base64 < plaintext.bin | tr -d '\n\r\t ' > plaintext.base64
# Encrypt this newly generated (binary) LUKS decryption key using the public key whose private key is on the
# Yubikey, store the result in /etc/cryptsetup-keys.d/mytest.key, where we'll look for it during boot.
mkdir -p /etc/cryptsetup-keys.d
sudo openssl rsautl -encrypt -pubin -inkey pubkey.pem -in plaintext.bin -out /etc/cryptsetup-keys.d/mytest.key
# Configure the LUKS decryption key on the LUKS device. We use very low pbkdf settings since the key already
# has quite a high quality (it comes directly from /dev/urandom after all), and thus we don't need to do much
# key derivation. Replace /dev/sdXn by the partition to use (e.g. sda1)
sudo cryptsetup luksAddKey /dev/sdXn plaintext.base64 --pbkdf=pbkdf2 --pbkdf-force-iterations=1000
# Now securely delete the plain text LUKS key, we don't need it anymore, and since it contains secret key
# material it should be removed from disk thoroughly.
shred -u plaintext.bin plaintext.base64
# We don't need the public key anymore either, let's remove it too. Since this one is not security
# sensitive we just do a regular "rm" here.
# We don't need the public key anymore, let's remove it. Since it is not
# security sensitive we just do a regular "rm" here.
rm pubkey.pem
# Test: Let's run systemd-cryptsetup to test if this all worked. The option string should contain the full
# PKCS#11 URI we have in the clipboard; it tells the tool how to decipher the encrypted LUKS key. Note that
# systemd-cryptsetup automatically searches for the encrypted key in /etc/cryptsetup-keys.d/, hence we do
# not need to specify the key file path explicitly here.
sudo systemd-cryptsetup attach mytest /dev/sdXn - 'pkcs11-uri=pkcs11:…'
# Enroll the freshly initialized security token in the LUKS2 volume. Replace
# /dev/sdXn by the partition to use (e.g. /dev/sda1).
sudo systemd-cryptenroll --pkcs11-token-uri=auto /dev/sdXn
# If that worked, let's now add the same line persistently to /etc/crypttab, for the future.
sudo bash -c 'echo "mytest /dev/sdXn - \'pkcs11-uri=pkcs11:…\'" >> /etc/crypttab'
# Test: Let's run systemd-cryptsetup to test if this all worked.
sudo /usr/lib/systemd/systemd-cryptsetup attach mytest /dev/sdXn - pkcs11-uri=auto
# If that worked, let's now add the same line persistently to /etc/crypttab,
# for the future.
sudo bash -c 'echo "mytest /dev/sdXn - pkcs11-uri=auto" >> /etc/crypttab'