tpm2: support "+" as separator for TPM PCR lists

Previously, we supported only "," as separator. This adds support for
"+" and makes it the documented choice.

This is to make specifying PCRs in crypttab easier, since commas are
already used there for separating volume options, and needless escaping
sucks.

"," continues to be supported, but in order to keep things minimal not
documented.

Fixe: #19205
This commit is contained in:
Lennart Poettering 2021-05-25 23:26:31 +02:00
parent c473437862
commit a1788a69b2
5 changed files with 15 additions and 12 deletions

View file

@ -659,9 +659,9 @@
<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
<listitem><para>Takes a <literal>+</literal> 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

View file

@ -176,11 +176,11 @@
<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>
requested via <option>--tpm2-device=</option> to. Takes a <literal>+</literal> 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>

View file

@ -97,7 +97,7 @@ static int help(void) {
" Whether to require user verification to unlock the volume\n"
" --tpm2-device=PATH\n"
" Enroll a TPM2 device\n"
" --tpm2-pcrs=PCR1,PCR2,PCR3,…\n"
" --tpm2-pcrs=PCR1+PCR2+PCR3,…\n"
" Specify TPM2 PCRs to seal against\n"
" --wipe-slot=SLOT1,SLOT2,…\n"
" Wipe specified slots\n"

View file

@ -4070,7 +4070,7 @@ static int help(void) {
" --definitions=DIR Find partition definitions in specified directory\n"
" --key-file=PATH Key to use when encrypting partitions\n"
" --tpm2-device=PATH Path to TPM2 device node to use\n"
" --tpm2-pcrs=PCR1,PCR2,\n"
" --tpm2-pcrs=PCR1+PCR2+PCR3+\n"
" TPM2 PCR indexes to use for TPM2 enrollment\n"
" --seed=UUID 128bit seed UUID to derive all UUIDs from\n"
" --size=BYTES Grow loopback file to specified size\n"

View file

@ -920,13 +920,16 @@ int tpm2_parse_pcrs(const char *s, uint32_t *ret) {
uint32_t mask = 0;
int r;
/* Parses a comma-separated list of PCR indexes */
/* Parses a "," or "+" separated list of PCR indexes. We support "," since this is a list after all,
* and most other tools expect comma separated PCR specifications. We also support "+" since in
* /etc/crypttab the "," is already used to separate options, hence a different separator is nice to
* avoid escaping. */
for (;;) {
_cleanup_free_ char *pcr = NULL;
unsigned n;
r = extract_first_word(&p, &pcr, ",", EXTRACT_DONT_COALESCE_SEPARATORS);
r = extract_first_word(&p, &pcr, ",+", EXTRACT_DONT_COALESCE_SEPARATORS);
if (r == 0)
break;
if (r < 0)