Merge pull request #23122 from poettering/creds-has-tpm2

tpm2: beef up tpm2 support checks
This commit is contained in:
Lennart Poettering
2022-04-20 23:18:02 +02:00
committed by GitHub
6 changed files with 125 additions and 30 deletions
+7 -21
View File
@@ -50,6 +50,7 @@
#include "string-table.h"
#include "string-util.h"
#include "tomoyo-util.h"
#include "tpm2-util.h"
#include "udev-util.h"
#include "uid-alloc-range.h"
#include "user-util.h"
@@ -623,29 +624,14 @@ static int condition_test_ac_power(Condition *c, char **env) {
}
static int has_tpm2(void) {
int r;
/* Checks whether the system has at least one TPM2 resource manager device, i.e. at least one "tpmrm"
* class device */
* class device. Alternatively, we are also happy if the firmware reports support (this is to cover
* for cases where we simply haven't loaded the driver for it yet, i.e. during early boot where we
* very likely want to use this condition check).
*
* Note that we don't check if we ourselves are built with TPM2 support here! */
r = dir_is_empty("/sys/class/tpmrm");
if (r == 0)
return true; /* nice! we have a device */
/* Hmm, so Linux doesn't know of the TPM2 device (or we couldn't check for it), most likely because
* the driver wasn't loaded yet. Let's see if the firmware knows about a TPM2 device, in this
* case. This way we can answer the TPM2 question already during early boot (where we most likely
* need it) */
if (efi_has_tpm2())
return true;
/* OK, this didn't work either, in this case propagate the original errors */
if (r == -ENOENT)
return false;
if (r < 0)
return log_debug_errno(r, "Failed to determine whether system has TPM2 support: %m");
return !r;
return (tpm2_support() & (TPM2_SUPPORT_DRIVER|TPM2_SUPPORT_FIRMWARE)) != 0;
}
static int condition_test_security(Condition *c, char **env) {
+23
View File
@@ -1,7 +1,9 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "efi-api.h"
#include "extract-word.h"
#include "parse-util.h"
#include "stat-util.h"
#include "tpm2-util.h"
#if HAVE_TPM2
@@ -1453,3 +1455,24 @@ int tpm2_primary_alg_from_string(const char *alg) {
return TPM2_ALG_RSA;
return -EINVAL;
}
Tpm2Support tpm2_support(void) {
Tpm2Support support = TPM2_SUPPORT_NONE;
int r;
r = dir_is_empty("/sys/class/tpmrm");
if (r < 0) {
if (r != -ENOENT)
log_debug_errno(r, "Unable to test whether /sys/class/tpmrm/ exists and is populated, assuming it is not: %m");
} else if (r == 0) /* populated! */
support |= TPM2_SUPPORT_DRIVER;
if (efi_has_tpm2())
support |= TPM2_SUPPORT_FIRMWARE;
#if HAVE_TPM2
support |= TPM2_SUPPORT_SYSTEM;
#endif
return support;
}
+12
View File
@@ -89,3 +89,15 @@ typedef struct {
uint32_t search_pcr_mask;
const char *device;
} systemd_tpm2_plugin_params;
typedef enum Tpm2Support {
/* NOTE! The systemd-creds tool returns these flags 1:1 as exit status. Hence these flags are pretty
* much ABI! Hence, be extra careful when changing/extending these definitions. */
TPM2_SUPPORT_NONE = 0, /* no support */
TPM2_SUPPORT_FIRMWARE = 1 << 0, /* firmware reports TPM2 was used */
TPM2_SUPPORT_DRIVER = 1 << 1, /* the kernel has a driver loaded for it */
TPM2_SUPPORT_SYSTEM = 1 << 2, /* we support it ourselves */
TPM2_SUPPORT_FULL = TPM2_SUPPORT_FIRMWARE|TPM2_SUPPORT_DRIVER|TPM2_SUPPORT_SYSTEM,
} Tpm2Support;
Tpm2Support tpm2_support(void);