Commit Graph
93 Commits
Author SHA1 Message Date
Lennart Poettering a4e9f3d3e8 cryptenroll: slightly reorder things
The tpm2_tpm2b_public_from_pem() invocation only makes sense when we
succeed to load the file from disk, hence we might do this together and
safe a conditionalization.
2023-11-09 12:27:43 +01:00
Lennart Poettering a8d8d34bfc tpm2-util: move loading of TPM2B_PUBLIC from disk into tpm2-util.c
No change in behaviour, let's just move this over so that we can reuse
this in repart later (and don't have to export the ugly `sym_` function
pointer for it)
2023-11-09 12:27:43 +01:00
Lennart Poettering 7911b6ca12 repart,cryptenroll: bring tpm2 switches/--help/handling in a single, canonical order
Let's define the same switches and their backing variables in the same
order, and let's make sure the enums and switches are named the same.

No actual code changes.
2023-11-09 12:27:43 +01:00
Dan Streetman c3a2a681be cryptenroll: add support for calculated TPM2 enrollment
Instead of enrolling the local TPM to a luks volume, use the public key from a
TPM to enroll it into the luks volume. This is useful when enrolling a TPM that
is not currently accessible, for example if the TPM is located on a different
system.
2023-11-07 12:20:54 -05:00
Lennart Poettering 404aea7815 tree-wide: hook everything up with pcrlock policy
Make sure cryptenroll and repart can enroll TPM2 policies with pcrlock
logic.

Make sure cryptsetup can unlock TPM2 policies with pcrlock in effect.
2023-11-03 11:24:24 +01:00
Lennart Poettering a434270139 pcrlock: add new pcrlock tool 2023-11-03 11:23:54 +01:00
Lennart Poettering 707de94cbf tree-wide: never link directly against p11kit
We go via dlopen() at most places, but forgot some. Cover the missing
cases too.
2023-11-02 17:26:46 +00:00
Lennart Poettering a3b46c6bf6 cryptenroll: use erase_and_free() at two more places 2023-11-01 15:19:10 +01:00
Antonio Alvarez Feijoo cb7aabf180 cryptenroll: fix bind default TPM2 signed policy to PCR 11
If `--tpm2-public-key=` is not specified, but `tpm2-pcr-public-key.pem` exists
in /{etc,run,usr/lib}/systemd/, the default PCR 11 is not being set.

Fixes 9e437994
2023-10-26 15:14:52 +02:00
Lennart Poettering 51abb74eab cryptenroll: validate positional arguments before looking at detail parameters
Let's switch the order in which we process positional arguments and
analyze/tweak detail parameters. Let's look at the positional arguments
first (i.e. the "big picture") and then look at the switches (i.e.
"little details").

THis doesn't matter much, but makes for better error messages I think.
At least I was very confused that a completely borked cmdline I passed
to cryptenrolled complained about some detail and let the major fuckup
pass...
2023-10-25 09:29:34 +02:00
Lennart Poettering 996d22e50a cryptenroll: add section headers to --help text 2023-10-25 09:29:34 +02:00
Lennart Poettering d66ff6fe77 cryptenroll: add addition asserts 2023-10-25 09:29:34 +02:00
Lennart Poettering 475c473d32 cryptenroll: merge two if checks with same condition
This removes a duplicate condition check by adding a common surrounding
if block.

This also change a confusing if check: "(X && Y) && Z" to simply "X && Y && Z"
2023-10-23 22:19:40 +02:00
Lennart Poettering 91a1632a4c cryptenroll: reduce scope of two global variables
No change in behaviour
2023-10-23 22:19:29 +02:00
Dan Streetman 382bfd90c3 cryptenroll: allow specifying handle index of key to use for sealing
This defaults to the SRK index.
2023-10-10 05:40:27 -04:00
Dan Streetman db7fdf152b tpm2: change tpm2_unseal() to accept Tpm2Context instead of device string
This matches the change to tpm2_seal(), which now accepts a Tpm2Context instead
of a device string.

This also allows using the same TPM context for sealing and unsealing, which
will be required by (future) test code when sealing/unsealing using a transient
key.
2023-10-03 12:56:55 -04:00
Dan Streetman f9a0ee7554 tpm2: downgrade most log functions from error to debug
Because most TPM2 functions here are 'library-like' functions, they should be
at debug level, not error level.

The only functions not reduced to logging at debug are tpm2_list_devices(),
since it is expected to print output, and the tpm2_parse_pcr_argument_*()
functions, since the system-wide parse_*_argument() functions generally log at
error level.
2023-10-03 17:13:50 +01:00
Zbigniew Jędrzejewski-Szmek 4cc8e81db5 cryptenroll: align tables 2023-09-26 15:35:06 +02:00
Luca Boccassi cd4ed8579b Merge pull request #28948 from poettering/tpm2-duplicate-pcr-names
tpm2: unify tpm2 PCR symbolic identifiers
2023-08-28 17:43:10 +01:00
Dan Streetman 26d8d71fa5 tpm2: add tpm2_pcr_values_has_(any|all)_values() functions 2023-08-24 12:35:58 -04:00
Dan Streetman cc1a78d5c4 tpm2: lowercase TPM2_PCR_VALUE[S]_VALID functions
As these are not macros, they should be lowercase.
2023-08-24 12:31:00 -04:00
Lennart Poettering e0e1f4f7a2 fundamental: rename tpm-pcr.h → tpm2-pcr.h
I always found it confusing that most of our TPM related definitions are
in tpm2-util.h, but the PCR names in tpm-pcr.h, without the "2". Let's
fix that and make this systematic, in particular as the definitions in
the file all start with TPM2_ already.

No code flow changes, just some renaming.
2023-08-24 13:40:37 +02:00
Lennart Poettering 2099cd6289 tpm2: unify symbolic name infra for PCRs
We so far maintained two places for symboic names for PCRs. One in
tpm2-util.h and one in tpm-pcr.h.

Let's unify this into one, i.e. move the full list from tpm2-util.h into
tpm-pcr.h, replacing the short list placed so far there.

Systematically prefix the definitions with TPM2_ or tpm2_, to follow how
we do this for all other defines in this context.

No change in behaviour, just unification of tables.
2023-08-24 13:40:37 +02:00
Zbigniew Jędrzejewski-Szmek bb44fd0734 various: use _NEG_ macros to reduce indentation
No functional change intended.
2023-08-16 12:52:56 +02:00
Dan Streetman 9e4379945b tpm2: move policy calculation out of tpm2_seal()
Move the calculation of the sealed object policy hash out of the tpm2_seal()
function. Instead, callers of tpm2_seal() can directly call
tpm2_calculate_sealing_policy() and then provide the policy hash to
tpm2_seal().
2023-08-04 11:20:22 -04:00
Dan Streetman 07c0406117 tpm2: change tpm2_parse_pcr_argument() parameters to parse to Tpm2PCRValue array
In order to allow users to specify expected PCR values, change the
tpm2_parse_pcr_argument() to parse the text argument into an array of
Tpm2PCRValue objects, which provide not only the selected PCR indexes, but also
(optionally) the hash algorithm and hash value for each PCR index.
2023-08-04 10:57:07 -04:00
Yu Watanabe 81fe141ba3 meson: move declarations of cryptsetup and friends 2023-08-01 05:52:50 +09:00
Dan Streetman adb7fe82c7 Revert "cryptenroll: drop unmet condition"
This reverts commit cefa4a02ab.

Because the first 'break' is inside a nested for loop, this second 'break' is
needed to exit the outer for loop.

Fixes: #28451
2023-07-21 18:59:26 +01:00
Egor IgnatovandDmitry V. Levin d34b1823ca shared: add password quality check abstraction layer to support both pwquality and passwdqc
Co-authored-by: Dmitry V. Levin <ldv@altlinux.org>
2023-07-06 10:59:41 +00:00
Dmitry V. Levin bc0ef0e2c0 pwquality: add old password argument to quality_check_password
This would allow to use quality_check_password() in
user_record_quality_check_password() which still uses
sym_pwquality_check() directly.
2023-07-06 10:59:41 +00:00
Dmitry V. Levin 7fc3f9c032 pwquality: fix quality_check_password return value
quality_check_password() used to return the same value 0 in two
different cases: when pwq_allocate_context() failed with a
ERRNO_IS_NOT_SUPPORTED() code, and when pwquality_check() rejected the
password.  As result, users of quality_check_password() used to report
password weakness also in case when the underlying library was not
available.

Fix this by changing quality_check_password() to forward the
ERRNO_IS_NOT_SUPPORTED() code to its callers, and change the callers
to handle this case gracefully.
2023-07-06 10:59:41 +00:00
Yu Watanabe 5d2a48da12 tree-wide: use _cleanup_set_free_ and friends
Instead of _cleanup_(set_freep) or so.
2023-06-01 06:47:48 +09:00
Yu Watanabe 70b53893f1 cryptenroll: update log messages 2023-05-20 14:21:10 +09:00
Yu Watanabe cefa4a02ab cryptenroll: drop unmet condition 2023-05-20 14:21:10 +09:00
Frantisek Sumsal b0582f6b63 cryptenroll: actually allow using multiple "special" strings when wiping
The systemd-cryptenroll man page states:

    Takes a comma separated list of numeric slot indexes, or the special
    strings ..., or any combination of these strings or numeric
    indexes, in which case all slots matching either are wiped.

but we'd allow only one special string at any given time as the value
was not ORed when assigning. So, for example, --wipe=recovery,password
would actually become --wipe=password, etc.
2023-05-11 13:12:08 +01:00
Frantisek Sumsal 0e43ab6d24 cryptenroll: fix an assertion with weak passwords
Passing 0 to log_xxx_errno() leads to an assertion, so let's not do that:

$ NEWPASSWORD="" build-san/systemd-cryptenroll --unlock-key-file=/tmp/password --password "$img"
/tmp/password has 0644 mode that is too permissive, please adjust the ownership and access mode.
Assertion '(_error) != 0' failed at src/cryptenroll/cryptenroll-password.c:164, function enroll_password(). Aborting.
Aborted (core dumped)
2023-05-09 22:17:15 +02:00
Zbigniew Jędrzejewski-Szmek 51214cf491 various: simplify calls to parse_boolean_argument()
parse_boolean_argument() returns the same information via both the output
argument and normal return.
2023-04-05 13:06:26 +08:00
William Roberts 96181b7a89 tpm2: fix nits from PR #26185
Fixes:
  - Comment style
  - Alignment style
  - cleanup macro usage
  - incorrect error message[1]

1. Thanks to tempusfugit991@gmail.com for pointing out the error
message mistake.

Signed-off-by: William Roberts <william.c.roberts@intel.com>
2023-04-04 20:41:11 +01:00
William Roberts acbb504eaf tpm2: add support for a trusted SRK
Prevent attackers from spoofing the tpmKey portion of the AuthSession by
adding a trusted key to the LUKS header metadata. Also, use a persistent
object rather than a transient object.

This provides the following benifits:
1. No way to MITM the tpmKey portion of the session, see [1] for
details.

2. Strengthens the encrypted sessions, note that the bindKey could be
   dropped now.

3. Speed, once it's created we just use it.

4. Owner Auth is needed to call create primary, so using the SRK
   creates a scratch space for normal users.

This is a "first to set" model, in where the first person to set the key
in the LUKS header wins. Thus, setup should be done in a known good
state. If an SRK, which is a primary key at a special persistent
address, is found, it will use whatever is there. If not, it creates an
SRK. The SRK follows the convetions used through the tpm2-software
organization code on GitHub [2], however, a split has occured between
Windows and Linux with respect to SRK templates. The Linux SRK is
generated with the unique field size set to 0, in Windows, it properly
sets the size to key size in bytes and the unique data to all 0's of that
size. Note the proper templates for SRKs is covered in spec [3].
However, the most important thing, is that both SRKs are passwordless,
and thus they should be interchangable. If Windows is the first to make
the SRK, systemd will gladly accept it and vice-versa.

1. Without the bindKey being utilized, an attacker was able to intercept
this and fake a key, thus being able to decrypt and encrypt traffic as
needed. Introduction of the bindKey strengthened this, but allows for
the attacker to brute force AES128CFB using pin guesses. Introduction of
the salt increases the difficulty of this attack as well as DA attacks
on the TPM objects itself.

2. https://github.com/tpm2-software

3. https://trustedcomputinggroup.org/wp-content/uploads/TCG-TPM-v2.0-Provisioning-Guidance-Published-v1r1.pdf

Fixes: #20668
Fixes: #22637

Signed-off-by: William Roberts <william.c.roberts@intel.com>
2023-04-03 13:10:49 +02:00
Frantisek Sumsal 30dbadf65e cryptenroll: fix a memory leak
$ dd if=/dev/zero of=luks.img bs=1M count=64
$ echo 1231dfsd234d | cryptsetup luksFormat luks.img
$ build-san/systemd-cryptenroll luks.img
SLOT TYPE
   0 password

=================================================================
==640364==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 64 byte(s) in 1 object(s) allocated from:
    #0 0x7f43ffeb95b5 in __interceptor_realloc.part.0 (/lib64/libasan.so.8+0xb95b5)
    #1 0x7f43ff0a4f2f in greedy_realloc ../src/basic/alloc-util.c:70
    #2 0x404d9f in list_enrolled ../src/cryptenroll/cryptenroll-list.c:30
    #3 0x40f149 in run ../src/cryptenroll/cryptenroll.c:673
    #4 0x40f149 in main ../src/cryptenroll/cryptenroll.c:692
    #5 0x7f43fd64a50f in __libc_start_call_main (/lib64/libc.so.6+0x2750f)

SUMMARY: AddressSanitizer: 64 byte(s) leaked in 1 allocation(s).
Aborted (core dumped)

Reported in https://github.com/systemd/systemd/pull/27007.
2023-03-28 13:41:55 +09:00
Yu Watanabe 0b75493da0 tree-wide: fix typo and comment style update 2023-02-15 10:08:16 +09:00
Yu Watanabe 645063d1bb cryptenroll: drop deadcode
Follow-up for b0fc23fae5.

After the commit, 'signature_path' is now always non-NULL, hence the
condition can be dropped.

Fixes CID#1504492.
2023-02-10 10:45:19 +00:00
Luca Boccassi b0fc23fae5 cryptenroll: do not implicitly verify with default tpm policy signature
If it was not requested to use a tpm2 signature file when enrolling, do
not fallback to the default /run/systemd/tpm2-pcr-signature.json as it
likely will be unrelated if it exists.

Fixes https://github.com/systemd/systemd/issues/25435
2023-02-08 10:58:57 +00:00
Jan Janssen 4a7ee0a521 meson: Do not include headers in source lists
Meson+ninja+compiler do this for us and are better at it.

https://mesonbuild.com/FAQ.html#do-i-need-to-add-my-headers-to-the-sources-list-like-in-autotools
2023-01-24 22:04:03 +01:00
William Roberts aae6eb9611 tpm2: add salt to pin
Add a salt to the pin and store it in the TPM2 LUKS header for future
this. This adds entropy to user supplied pins and helps brute forcing
the passphrase on the key residing in the TPM or brute forcing bind key
encrypted sessions with low entropy passphrases.

Signed-off-by: malikabhi05 <abhishek.malik@intel.com>
Signed-off-by: William Roberts <william.c.roberts@intel.com>
2023-01-18 21:58:33 +00:00
Lennart Poettering 5e476b8512 tree-wide: fix return value handling of base64mem()
This returns an ssize_t, not an int. On populare archs that's the
difference between 64bit and 32bit. hence, let's be more careful here,
and not silently drop half the bits on the ground by assigning the
return value to "int".

As noticed by @malikabhi05:

https://github.com/systemd/systemd/pull/24754#discussion_r1062903159
2023-01-11 10:46:08 +01:00
Peter Cai 48765191d2 cryptenroll: Implement support for unlocking via FIDO2 tokens
This allows FIDO2 users to wipe out password slots and still be able to
enroll new key slots via systemd-cryptenroll. Note that when the user
wants to both unlock with a FIDO2 token and enroll a new FIDO2 token,
they cannot be set to automatic discovery. This is to safeguard against
confusion, because there will be multiple tokens connected to the system
when doing so -- and we require users to explicitly confirm which one to
use for unlocking and which one to use for enrollment.

Addresses #20230 for the FIDO2 case.
2022-12-22 17:33:25 -05:00
Zbigniew Jędrzejewski-Szmek d6b4d1c7c4 basic: move version() to build.h+c 2022-11-08 13:41:14 +01:00
Lennart Poettering f0f4fcaeb7 cryptenroll: hook up new TPM2 signed policies with cryptenroll 2022-09-08 16:34:27 +02:00
Lennart Poettering d9b5841d40 tpm2-util: extend TPM2 policies to optionally check PCR values against signed values
Traditionally, TPM2 PCR policies are bound against literal PCR values,
which makes them hard to work with when updating software that is
measured into PCRs: each update will change the PCR values, and thus
break TPM2 policies of existing objects.

Let's improve the situation: let's allow signed PCR policies. Secrets
and other TPM2 objects can be associated with a public key that signs a
PCR policy. Thus, if the signed policy and the public key is presented,
access to the TPM2 object can be granted. This allows a less brittle
handling of updates: for example, whenever a kernel image is updated a
new signed PCR policy can be shipped along with it, signed by a private
key owned by the kernel vendor (ideally: same private key that is used
to sign the kernel image itself). TPM2 objects can then be bound to the
associated public key, thus allowing objects that can only be unlocked
by kernels of the same vendor. This makes it very easy to update kernels
without affecting locked secrets.

This does not hook up any of the consuming code (just passes NULL/0
everywhere). This is for later commits.
2022-09-08 16:34:27 +02:00