Merge pull request #29296 from keszybz/make-cryptsetup-offical-and-add-docs

Make cryptsetup offical and add docs
This commit is contained in:
Luca Boccassi 2023-09-27 13:31:11 +01:00 committed by GitHub
commit 578840bdf9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 232 additions and 114 deletions

4
TODO
View file

@ -390,6 +390,10 @@ Features:
* udevd: extend memory pressure logic: also kill any idle worker processes
* udevadm: to make symlink querying with udevadm nicer:
- do not enable the pager for queries like 'udevadm info -q -r symlink'
- add mode with newlines instead of spaces (for grep)?
* SIGRTMIN+18 and memory pressure handling should still be added to: hostnamed,
localed, oomd, timedated.

View file

@ -957,7 +957,7 @@ external /dev/sda3 keyfile:LABEL=keydev keyfile-timeout=10s,cipher=xchac
<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>
<programlisting><xi:include href="yubikey-crypttab.sh" parse="text" /></programlisting>
<para>A few notes on the above:</para>
@ -977,7 +977,7 @@ external /dev/sda3 keyfile:LABEL=keydev keyfile-timeout=10s,cipher=xchac
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>
<programlisting><xi:include href="fido2-crypttab.sh" parse="text" /></programlisting>
</example>
<example>
@ -988,7 +988,7 @@ external /dev/sda3 keyfile:LABEL=keydev keyfile-timeout=10s,cipher=xchac
using
<citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>:</para>
<programlisting><xi:include href="tpm2-crypttab.sh" parse="text" /></programlisting>
<programlisting><xi:include href="tpm2-crypttab.sh" parse="text" /></programlisting>
</example>
</refsect1>

View file

@ -5,16 +5,20 @@
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
sudo 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'
# for the future. We don't want to use the (unstable) /dev/sdX name, so let's
# figure out a stable link:
udevadm info -q -r symlink /dev/sdXn
# Depending on your distribution and encryption setup, you may need
# to manually regenerate your initramfs to be able to use
# a FIDO2-Device to unlock the partition during early boot.
# More information at https://unix.stackexchange.com/a/705809
# Now add the line using the by-uuid symlink to /etc/crypttab:
sudo bash -c 'echo "mytest /dev/disk/by-uuid/... - fido2-device=auto" >>/etc/crypttab'
# Depending on your distribution and encryption setup, you may need to manually
# regenerate your initramfs to be able to use a FIDO2 device to unlock the
# partition during early boot.
# More information at https://unix.stackexchange.com/a/705809.
# On Fedora based systems:
sudo dracut --force
# On Debian based systems:

View file

@ -914,9 +914,9 @@ manpages = [
['systemd-creds', '1', [], ''],
['systemd-cryptenroll', '1', [], 'HAVE_LIBCRYPTSETUP'],
['systemd-cryptsetup-generator', '8', [], 'HAVE_LIBCRYPTSETUP'],
['systemd-cryptsetup@.service',
['systemd-cryptsetup',
'8',
['systemd-cryptsetup'],
['systemd-cryptsetup@.service'],
'HAVE_LIBCRYPTSETUP'],
['systemd-debug-generator', '8', [], ''],
['systemd-delta', '1', [], ''],

View file

@ -22,7 +22,9 @@
<refsynopsisdiv>
<cmdsynopsis>
<command>systemd-cryptenroll <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt">DEVICE</arg></command>
<command>systemd-cryptenroll</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="opt">DEVICE</arg>
</cmdsynopsis>
</refsynopsisdiv>
@ -545,6 +547,14 @@
<para>On success, 0 is returned, a non-zero failure code otherwise.</para>
</refsect1>
<refsect1>
<title>Examples</title>
<para><citerefentry><refentrytitle>crypttab</refentrytitle><manvolnum>5</manvolnum></citerefentry> and
<citerefentry><refentrytitle>systemd-measure</refentrytitle><manvolnum>1</manvolnum></citerefentry>
contain various examples employing <command>systemd-cryptenroll</command>.</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>

View file

@ -3,38 +3,62 @@
<!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-cryptsetup@.service" conditional='HAVE_LIBCRYPTSETUP'>
<refentry id="systemd-cryptsetup" conditional='HAVE_LIBCRYPTSETUP'>
<refentryinfo>
<title>systemd-cryptsetup@.service</title>
<title>systemd-cryptsetup</title>
<productname>systemd</productname>
</refentryinfo>
<refmeta>
<refentrytitle>systemd-cryptsetup@.service</refentrytitle>
<refentrytitle>systemd-cryptsetup</refentrytitle>
<manvolnum>8</manvolnum>
</refmeta>
<refnamediv>
<refname>systemd-cryptsetup</refname>
<refname>systemd-cryptsetup@.service</refname>
<!-- <refname>system-systemd\x2dcryptsetup.slice</refname> — this causes meson to go haywire because it
thinks this is a (windows) path. Let's just not create the alias for this name, and only include it
in the synopsis. -->
<refname>systemd-cryptsetup</refname>
<refpurpose>Full disk decryption logic</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>systemd-cryptsetup</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="plain">attach</arg>
<arg choice="plain">VOLUME</arg>
<arg choice="plain">SOURCE-DEVICE</arg>
<arg choice="opt">KEY-FILE</arg>
<arg choice="opt">CONFIG</arg>
</cmdsynopsis>
<cmdsynopsis>
<command>systemd-cryptsetup</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="plain">detach</arg>
<arg choice="plain">VOLUME</arg>
</cmdsynopsis>
<para><filename>systemd-cryptsetup@.service</filename></para>
<para><filename>system-systemd\x2dcryptsetup.slice</filename></para>
<para><filename>/usr/lib/systemd/systemd-cryptsetup</filename></para>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para><filename>systemd-cryptsetup@.service</filename> is a service responsible for setting up encrypted
block devices. It is instantiated for each device that requires decryption for access.</para>
<para><filename>systemd-cryptsetup</filename> is used to set up (with <command>attach</command>) and tear
down (with <command>detach</command>) access to an encrypted block device. It is primarily used via
<filename>systemd-cryptsetup@.service</filename> during early boot, but may also be be called manually.
The positional arguments <parameter>VOLUME</parameter>, <parameter>SOURCEDEVICE</parameter>,
<parameter>KEY-FILE</parameter>, and <parameter>CRYPTTAB-OPTIONS</parameter> have the same meaning as the
fields in <citerefentry><refentrytitle>crypttab</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
</para>
<para><filename>systemd-cryptsetup@.service</filename> is a service responsible for providing access to
encrypted block devices. It is instantiated for each device that requires decryption.</para>
<para><filename>systemd-cryptsetup@.service</filename> instances are part of the
<filename>system-systemd\x2dcryptsetup.slice</filename> slice, which is destroyed only very late in the
@ -51,9 +75,9 @@
translated into <filename>systemd-cryptsetup@.service</filename> units by
<citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
<para>In order to unlock a volume a password or binary key is
required. <filename>systemd-cryptsetup@.service</filename> tries to acquire a suitable password or binary
key via the following mechanisms, tried in order:</para>
<para>In order to unlock a volume a password or binary key is required.
<filename>systemd-cryptsetup@.service</filename> tries to acquire a suitable password or binary key via
the following mechanisms, tried in order:</para>
<orderedlist>
<listitem><para>If a key file is explicitly configured (via the third column in
@ -67,8 +91,8 @@
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
to unlock the volume with an empty password.</para></listitem>
<listitem><para>If the <varname>try-empty-password</varname> option is specified then unlocking the
volume with an empty password is attempted.</para></listitem>
<listitem><para>The kernel keyring is then checked for a suitable cached password from previous
attempts.</para></listitem>

View file

@ -295,7 +295,7 @@ $ openssl rsa -pubout -in tpm2-pcr-private.pem -out tpm2-pcr-public.pem
<para>And then unlock the device with the signature:</para>
<programlisting># /usr/lib/systemd/systemd-cryptsetup attach \
<programlisting># systemd-cryptsetup attach \
volume5 /dev/sda5 - \
tpm2-device=auto,tpm2-signature=/path/to/tpm2-pcr-signature.json</programlisting>

View file

@ -5,16 +5,36 @@
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
sudo 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'
# for the future. We don't want to use the (unstable) /dev/sdX name, so let's
# figure out a stable link:
udevadm info -q -r symlink /dev/sdXn
# Depending on your distribution and encryption setup, you may need
# to manually regenerate your initramfs to be able to use
# a TPM2 security chip to unlock the partition during early boot.
# More information at https://unix.stackexchange.com/a/705809
# Now add the line using the by-uuid symlink to /etc/crypttab:
sudo bash -c 'echo "mytest /dev/disk/by-uuid/... - tpm2-device=auto" >>/etc/crypttab'
# And now let's check that automatic unlocking works:
sudo systemd-cryptsetup detach mytest
sudo systemctl daemon-reload
sudo systemctl start cryptsetup.target
systemctl is-active systemd-cryptsetup@mytest.service
# Once we have the device which will be unlocked automatically, we can use it.
# Usually we would create a file system and add it to /etc/fstab:
sudo mkfs.ext4 /dev/mapper/mytest
# This prints a 'Filesystem UUID', which we can use as a stable name:
sudo bash -c 'echo "/dev/disk/by-uuid/... /var/mytest ext4 defaults,x-systemd.mkdir 0 2" >>/etc/fstab'
# And now let's check that the mounting works:
sudo systemctl daemon-reload
sudo systemctl start /var/mytest
systemctl status /var/mytest
# Depending on your distribution and encryption setup, you may need to manually
# regenerate your initramfs to be able to use a TPM2 security chip to unlock
# the partition during early boot.
# More information at https://unix.stackexchange.com/a/705809.
# On Fedora based systems:
sudo dracut --force
# On Debian based systems:

View file

@ -21,16 +21,20 @@ rm pubkey.pem
sudo systemd-cryptenroll --pkcs11-token-uri=auto /dev/sdXn
# 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
sudo 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'
# for the future. We don't want to use the (unstable) /dev/sdX name, so let's
# figure out a stable link:
udevadm info -q -r symlink /dev/sdXn
# Depending on your distribution and encryption setup, you may need
# to manually regenerate your initramfs to be able to use a
# Yubikey / PKCS#11 Token to unlock the partition during early boot.
# More information at https://unix.stackexchange.com/a/705809
# Now add the line using the by-uuid symlink to /etc/crypttab:
sudo bash -c 'echo "mytest /dev/disk/by-uuid/... - pkcs11-uri=auto" >>/etc/crypttab'
# Depending on your distribution and encryption setup, you may need to manually
# regenerate your initramfs to be able to use a Yubikey / PKCS#11 token to
# unlock the partition during early boot.
# More information at https://unix.stackexchange.com/a/705809.
# On Fedora based systems:
sudo dracut --force
# On Debian based systems:

View file

@ -226,7 +226,7 @@ conf.set_quoted('SYSTEMCTL_BINARY_PATH', bindir / 'systemct
conf.set_quoted('SYSTEMD_BINARY_PATH', libexecdir / 'systemd')
conf.set_quoted('SYSTEMD_CATALOG_DIR', catalogdir)
conf.set_quoted('SYSTEMD_CGROUPS_AGENT_PATH', libexecdir / 'systemd-cgroups-agent')
conf.set_quoted('SYSTEMD_CRYPTSETUP_PATH', libexecdir / 'systemd-cryptsetup')
conf.set_quoted('SYSTEMD_CRYPTSETUP_PATH', bindir / 'systemd-cryptsetup')
conf.set_quoted('SYSTEMD_EXPORT_PATH', libexecdir / 'systemd-export')
conf.set_quoted('SYSTEMD_FSCK_PATH', libexecdir / 'systemd-fsck')
conf.set_quoted('SYSTEMD_GROWFS_PATH', libexecdir / 'systemd-growfs')
@ -2420,6 +2420,7 @@ ukify = custom_target(
if want_ukify
public_programs += ukify
# symlink for backwards compatibility after rename
meson.add_install_script(sh, '-c',
ln_s.format(bindir / 'ukify',
libexecdir / 'ukify'))

View file

@ -78,9 +78,9 @@ static bool wipe_requested(void) {
static const char* const enroll_type_table[_ENROLL_TYPE_MAX] = {
[ENROLL_PASSWORD] = "password",
[ENROLL_RECOVERY] = "recovery",
[ENROLL_PKCS11] = "pkcs11",
[ENROLL_FIDO2] = "fido2",
[ENROLL_TPM2] = "tpm2",
[ENROLL_PKCS11] = "pkcs11",
[ENROLL_FIDO2] = "fido2",
[ENROLL_TPM2] = "tpm2",
};
DEFINE_STRING_TABLE_LOOKUP(enroll_type, EnrollType);
@ -88,9 +88,9 @@ DEFINE_STRING_TABLE_LOOKUP(enroll_type, EnrollType);
static const char *const luks2_token_type_table[_ENROLL_TYPE_MAX] = {
/* ENROLL_PASSWORD has no entry here, as slots of this type do not have a token in the LUKS2 header */
[ENROLL_RECOVERY] = "systemd-recovery",
[ENROLL_PKCS11] = "systemd-pkcs11",
[ENROLL_FIDO2] = "systemd-fido2",
[ENROLL_TPM2] = "systemd-tpm2",
[ENROLL_PKCS11] = "systemd-pkcs11",
[ENROLL_FIDO2] = "systemd-fido2",
[ENROLL_TPM2] = "systemd-tpm2",
};
DEFINE_STRING_TABLE_LOOKUP(luks2_token_type, EnrollType);
@ -150,7 +150,6 @@ static int help(void) {
}
static int parse_argv(int argc, char *argv[]) {
enum {
ARG_VERSION = 0x100,
ARG_PASSWORD,

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <getopt.h>
#include <mntent.h>
#include <sys/mman.h>
#include <sys/stat.h>
@ -12,6 +13,7 @@
#include "alloc-util.h"
#include "ask-password-api.h"
#include "build.h"
#include "cryptsetup-fido2.h"
#include "cryptsetup-keyfile.h"
#include "cryptsetup-pkcs11.h"
@ -127,7 +129,6 @@ PassphraseType passphrase_type_from_string(const char *s);
DEFINE_STRING_TABLE_LOOKUP(passphrase_type, PassphraseType);
/* Options Debian's crypttab knows we don't:
check=
checkargs=
noearly
@ -501,7 +502,7 @@ static int parse_one_option(const char *option) {
return 0;
}
static int parse_options(const char *options) {
static int parse_crypt_config(const char *options) {
assert(options);
for (;;) {
@ -2025,21 +2026,62 @@ static int help(void) {
_cleanup_free_ char *link = NULL;
int r;
r = terminal_urlify_man("systemd-cryptsetup@.service", "8", &link);
r = terminal_urlify_man("systemd-cryptsetup", "8", &link);
if (r < 0)
return log_oom();
printf("%s attach VOLUME SOURCEDEVICE [KEY-FILE] [OPTIONS]\n"
"%s detach VOLUME\n\n"
"Attaches or detaches an encrypted block device.\n"
"\nSee the %s for details.\n",
program_invocation_short_name,
printf("%1$s attach VOLUME SOURCE-DEVICE [KEY-FILE] [CONFIG]\n"
"%1$s detach VOLUME\n\n"
"%2$sAttach or detach an encrypted block device.%3$s\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
"\nSee the %4$s for details.\n",
program_invocation_short_name,
ansi_highlight(),
ansi_normal(),
link);
return 0;
}
static int parse_argv(int argc, char *argv[]) {
enum {
ARG_VERSION = 0x100,
};
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, ARG_VERSION },
{}
};
int c;
assert(argc >= 0);
assert(argv);
if (argv_looks_like_help(argc, argv))
return help();
while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
switch (c) {
case 'h':
return help();
case ARG_VERSION:
return version();
case '?':
return -EINVAL;
default:
assert_not_reached();
}
return 1;
}
static uint32_t determine_flags(void) {
uint32_t flags = 0;
@ -2086,25 +2128,24 @@ static int run(int argc, char *argv[]) {
const char *verb;
int r;
if (argv_looks_like_help(argc, argv))
return help();
if (argc < 3)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"This program requires at least two arguments.");
log_setup();
cryptsetup_enable_logging(NULL);
umask(0022);
verb = argv[1];
r = parse_argv(argc, argv);
if (r <= 0)
return r;
cryptsetup_enable_logging(NULL);
if (argc - optind < 2)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"This program requires at least two arguments.");
verb = ASSERT_PTR(argv[optind]);
if (streq(verb, "attach")) {
_unused_ _cleanup_(remove_and_erasep) const char *destroy_key_file = NULL;
_cleanup_(erase_and_freep) void *key_data = NULL;
const char *volume, *source, *key_file, *options;
crypt_status_info status;
size_t key_data_size = 0;
uint32_t flags = 0;
@ -2112,15 +2153,17 @@ static int run(int argc, char *argv[]) {
usec_t until;
PassphraseType passphrase_type = PASSPHRASE_NONE;
/* Arguments: systemd-cryptsetup attach VOLUME SOURCE-DEVICE [KEY-FILE] [OPTIONS] */
/* Arguments: systemd-cryptsetup attach VOLUME SOURCE-DEVICE [KEY-FILE] [CONFIG] */
if (argc < 4)
if (argc - optind < 3)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "attach requires at least two arguments.");
if (argc - optind >= 6)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "attach does not accept more than four arguments.");
volume = argv[2];
source = argv[3];
key_file = mangle_none(argc >= 5 ? argv[4] : NULL);
options = mangle_none(argc >= 6 ? argv[5] : NULL);
const char *volume = ASSERT_PTR(argv[optind + 1]),
*source = ASSERT_PTR(argv[optind + 2]),
*key_file = argc - optind >= 4 ? mangle_none(argv[optind + 3]) : NULL,
*config = argc - optind >= 5 ? mangle_none(argv[optind + 4]) : NULL;
if (!filename_is_valid(volume))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);
@ -2130,8 +2173,8 @@ static int run(int argc, char *argv[]) {
key_file = NULL;
}
if (options) {
r = parse_options(options);
if (config) {
r = parse_crypt_config(config);
if (r < 0)
return r;
}
@ -2313,9 +2356,10 @@ static int run(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Too many attempts to activate; giving up.");
} else if (streq(verb, "detach")) {
const char *volume;
const char *volume = ASSERT_PTR(argv[optind + 1]);
volume = argv[2];
if (argc - optind >= 3)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "attach does not accept more than one argument.");
if (!filename_is_valid(volume))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);

View file

@ -16,8 +16,9 @@ if conf.get('HAVE_TPM2') == 1
endif
executables += [
libexec_template + {
executable_template + {
'name' : 'systemd-cryptsetup',
'public' : true,
'conditions' : ['HAVE_LIBCRYPTSETUP'],
'sources' : systemd_cryptsetup_sources,
'dependencies' : [
@ -32,3 +33,10 @@ executables += [
'sources' : files('cryptsetup-generator.c'),
},
]
if conf.get('HAVE_LIBCRYPTSETUP') == 1
# symlink for backwards compatibility after rename
meson.add_install_script(sh, '-c',
ln_s.format(bindir / 'systemd-cryptsetup',
libexecdir / 'systemd-cryptsetup'))
endif

View file

@ -225,6 +225,7 @@ if conf.get('ENABLE_RESOLVE') == 1
ln_s.format(bindir / 'resolvectl',
sbindir / 'resolvconf'))
# symlink for backwards compatibility after rename
meson.add_install_script(sh, '-c',
ln_s.format(bindir / 'resolvectl',
bindir / 'systemd-resolve'))

View file

@ -3,7 +3,6 @@
set -ex
set -o pipefail
SD_CRYPTSETUP="/usr/lib/systemd/systemd-cryptsetup"
SD_MEASURE="/usr/lib/systemd/systemd-measure"
SD_PCREXTEND="/usr/lib/systemd/systemd-pcrextend"
export SYSTEMD_LOG_LEVEL=debug
@ -29,10 +28,10 @@ tpm_check_failure_with_wrong_pin() {
# We need to be careful not to trigger DA lockout; allow 2 failures
tpm2_dictionarylockout -s -n 2
(! PIN=$badpin "$SD_CRYPTSETUP" attach test-volume "$testimg" - tpm2-device=auto,headless=1)
(! PIN=$badpin systemd-cryptsetup attach test-volume "$testimg" - tpm2-device=auto,headless=1)
# Verify the correct PIN works, to be sure the failure wasn't a DA lockout
PIN=$goodpin "$SD_CRYPTSETUP" attach test-volume "$testimg" - tpm2-device=auto,headless=1
"$SD_CRYPTSETUP" detach test-volume
PIN=$goodpin systemd-cryptsetup attach test-volume "$testimg" - tpm2-device=auto,headless=1
systemd-cryptsetup detach test-volume
# Clear/reset the DA lockout counter
tpm2_dictionarylockout -c
}
@ -50,18 +49,18 @@ systemd-cryptenroll --unlock-key-file=/tmp/passphrase --tpm2-device=auto "$img"
# Enroll unlock with default PCR policy
PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto "$img"
"$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1
"$SD_CRYPTSETUP" detach test-volume
systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1
systemd-cryptsetup detach test-volume
# Check with wrong PCR
tpm2_pcrextend 7:sha256=0000000000000000000000000000000000000000000000000000000000000000
(! "$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1)
(! systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1)
# Enroll unlock with PCR+PIN policy
systemd-cryptenroll --wipe-slot=tpm2 "$img"
PASSWORD=passphrase NEWPIN=123456 systemd-cryptenroll --tpm2-device=auto --tpm2-with-pin=true "$img"
PIN=123456 "$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1
"$SD_CRYPTSETUP" detach test-volume
PIN=123456 systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1
systemd-cryptsetup detach test-volume
# Check failure with wrong PIN; try a few times to make sure we avoid DA lockout
for _ in {0..3}; do
@ -70,8 +69,8 @@ done
# Check LUKS2 token plugin unlock (i.e. without specifying tpm2-device=auto)
if cryptsetup_has_token_plugin_support; then
PIN=123456 "$SD_CRYPTSETUP" attach test-volume "$img" - headless=1
"$SD_CRYPTSETUP" detach test-volume
PIN=123456 systemd-cryptsetup attach test-volume "$img" - headless=1
systemd-cryptsetup detach test-volume
# Check failure with wrong PIN
for _ in {0..3}; do
@ -83,39 +82,39 @@ fi
# Check failure with wrong PCR (and correct PIN)
tpm2_pcrextend 7:sha256=0000000000000000000000000000000000000000000000000000000000000000
(! PIN=123456 "$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1)
(! PIN=123456 systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1)
# Enroll unlock with PCR 0+7
systemd-cryptenroll --wipe-slot=tpm2 "$img"
PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 "$img"
"$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1
"$SD_CRYPTSETUP" detach test-volume
systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1
systemd-cryptsetup detach test-volume
# Check with wrong PCR 0
tpm2_pcrextend 0:sha256=0000000000000000000000000000000000000000000000000000000000000000
(! "$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1)
(! systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1)
if tpm_has_pcr sha256 12; then
# Enroll using an explict PCR value (that does match current PCR value)
systemd-cryptenroll --wipe-slot=tpm2 "$img"
EXPECTED_PCR_VALUE=$(cat /sys/class/tpm/tpm0/pcr-sha256/12)
PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="12:sha256=$EXPECTED_PCR_VALUE" "$img"
"$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1
"$SD_CRYPTSETUP" detach test-volume
systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1
systemd-cryptsetup detach test-volume
# Same as above plus more PCRs without the value or alg specified
systemd-cryptenroll --wipe-slot=tpm2 "$img"
EXPECTED_PCR_VALUE=$(cat /sys/class/tpm/tpm0/pcr-sha256/12)
PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="1,12:sha256=$EXPECTED_PCR_VALUE,3" "$img"
"$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1
"$SD_CRYPTSETUP" detach test-volume
systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1
systemd-cryptsetup detach test-volume
# Same as above plus more PCRs with hash alg specified but hash value not specified
systemd-cryptenroll --wipe-slot=tpm2 "$img"
EXPECTED_PCR_VALUE=$(cat /sys/class/tpm/tpm0/pcr-sha256/12)
PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="1:sha256,12:sha256=$EXPECTED_PCR_VALUE,3" "$img"
"$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1
"$SD_CRYPTSETUP" detach test-volume
systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1
systemd-cryptsetup detach test-volume
# Now the interesting part, enrolling using a hash value that doesn't match the current PCR value
systemd-cryptenroll --wipe-slot=tpm2 "$img"
@ -123,10 +122,10 @@ if tpm_has_pcr sha256 12; then
CURRENT_PCR_VALUE=$(cat /sys/class/tpm/tpm0/pcr-sha256/12)
EXPECTED_PCR_VALUE=$(cat /tmp/pcr.dat /tmp/pcr.dat | openssl dgst -sha256 -r | cut -d ' ' -f 1)
PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="12:sha256=$EXPECTED_PCR_VALUE" "$img"
(! "$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1)
(! systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1)
tpm2_pcrextend "12:sha256=$CURRENT_PCR_VALUE"
"$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1
"$SD_CRYPTSETUP" detach test-volume
systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1
systemd-cryptsetup detach test-volume
rm -f /tmp/pcr.dat
fi
@ -208,24 +207,24 @@ if [[ -x "$SD_MEASURE" ]] && tpm_has_pcr sha1 11 && tpm_has_pcr sha256 11; then
systemd-cryptenroll --unlock-key-file=/tmp/passphrase --tpm2-device=auto --tpm2-public-key="/tmp/pcrsign-public.pem" --tpm2-signature="/tmp/pcrsign.sig2" "$img"
# Check if we can activate that (without the token module stuff)
SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 "$SD_CRYPTSETUP" attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1
SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 "$SD_CRYPTSETUP" detach test-volume2
SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1
SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup detach test-volume2
# Check if we can activate that (and a second time with the token module stuff enabled)
SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 "$SD_CRYPTSETUP" attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1
SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 "$SD_CRYPTSETUP" detach test-volume2
SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1
SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 systemd-cryptsetup detach test-volume2
# After extending the PCR things should fail
tpm2_pcrextend 11:sha256=0000000000000000000000000000000000000000000000000000000000000000
(! SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 "$SD_CRYPTSETUP" attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1)
(! SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 "$SD_CRYPTSETUP" attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1)
(! SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1)
(! SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1)
# But once we sign the current PCRs, we should be able to unlock again
"$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=: >"/tmp/pcrsign.sig3"
SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 "$SD_CRYPTSETUP" attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig3",headless=1
"$SD_CRYPTSETUP" detach test-volume2
SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 "$SD_CRYPTSETUP" attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig3",headless=1
"$SD_CRYPTSETUP" detach test-volume2
SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig3",headless=1
systemd-cryptsetup detach test-volume2
SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig3",headless=1
systemd-cryptsetup detach test-volume2
# Test --append mode and de-duplication. With the same parameters signing should not add a new entry
"$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=: --append="/tmp/pcrsign.sig3" >"/tmp/pcrsign.sig4"
@ -236,8 +235,8 @@ if [[ -x "$SD_MEASURE" ]] && tpm_has_pcr sha1 11 && tpm_has_pcr sha256 11; then
(! cmp "/tmp/pcrsign.sig4" "/tmp/pcrsign.sig5")
# Should still be good to unlock, given the old entry still exists
SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 "$SD_CRYPTSETUP" attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig5",headless=1
"$SD_CRYPTSETUP" detach test-volume2
SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig5",headless=1
systemd-cryptsetup detach test-volume2
# Adding both signatures once more should not change anything, due to the deduplication
"$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=: --append="/tmp/pcrsign.sig5" >"/tmp/pcrsign.sig6"