diff options
author | Lennart Poettering <lennart@poettering.net> | 2024-04-22 09:46:23 +0200 |
---|---|---|
committer | Luca Boccassi <luca.boccassi@gmail.com> | 2024-04-22 12:40:09 +0200 |
commit | 21a3bc6b9f01c3b0bf906c0b28f8827db086edf8 (patch) | |
tree | 09615be569defc4752fbc2439b01d4fe61d5c41c | |
parent | sd-event: fix fd leak when fd is owned by IO event source (diff) | |
download | systemd-21a3bc6b9f01c3b0bf906c0b28f8827db086edf8.tar.xz systemd-21a3bc6b9f01c3b0bf906c0b28f8827db086edf8.zip |
tpm2-util: add generic wrapper tpm2_context_new_or_warn() that wrpas tpm2_context_new and logs about errors
We so far just print a short log message that is not very useful, let's
add some recognizable error codes, and output better log messages if we
can't get TPM stuff to work.
Fixes: #31925
-rw-r--r-- | src/analyze/analyze-srk.c | 4 | ||||
-rw-r--r-- | src/cryptenroll/cryptenroll-tpm2.c | 4 | ||||
-rw-r--r-- | src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c | 4 | ||||
-rw-r--r-- | src/cryptsetup/cryptsetup.c | 4 | ||||
-rw-r--r-- | src/partition/repart.c | 4 | ||||
-rw-r--r-- | src/pcrextend/pcrextend.c | 2 | ||||
-rw-r--r-- | src/pcrlock/pcrlock.c | 8 | ||||
-rw-r--r-- | src/shared/creds-util.c | 4 | ||||
-rw-r--r-- | src/shared/cryptsetup-tpm2.c | 4 | ||||
-rw-r--r-- | src/shared/tpm2-util.c | 28 | ||||
-rw-r--r-- | src/shared/tpm2-util.h | 1 | ||||
-rw-r--r-- | src/tpm2-setup/tpm2-setup.c | 4 |
12 files changed, 45 insertions, 26 deletions
diff --git a/src/analyze/analyze-srk.c b/src/analyze/analyze-srk.c index 0e24b416bb..6faf2c29a3 100644 --- a/src/analyze/analyze-srk.c +++ b/src/analyze/analyze-srk.c @@ -11,9 +11,9 @@ int verb_srk(int argc, char *argv[], void *userdata) { _cleanup_(Esys_Freep) TPM2B_PUBLIC *public = NULL; int r; - r = tpm2_context_new(/* device= */ NULL, &c); + r = tpm2_context_new_or_warn(/* device= */ NULL, &c); if (r < 0) - return log_error_errno(r, "Failed to create TPM2 context: %m"); + return r; r = tpm2_get_srk( c, diff --git a/src/cryptenroll/cryptenroll-tpm2.c b/src/cryptenroll/cryptenroll-tpm2.c index 3ded815fb0..83a2f4420f 100644 --- a/src/cryptenroll/cryptenroll-tpm2.c +++ b/src/cryptenroll/cryptenroll-tpm2.c @@ -351,9 +351,9 @@ int enroll_tpm2(struct crypt_device *cd, return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Must provide all PCR values when using TPM2 device key."); } else { - r = tpm2_context_new(device, &tpm2_context); + r = tpm2_context_new_or_warn(device, &tpm2_context); if (r < 0) - return log_error_errno(r, "Failed to create TPM2 context: %m"); + return r; if (!tpm2_pcr_values_has_all_values(hash_pcr_values, n_hash_pcr_values)) { r = tpm2_pcr_read_missing_values(tpm2_context, hash_pcr_values, n_hash_pcr_values); diff --git a/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c b/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c index d902c591df..08f901c548 100644 --- a/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c +++ b/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c @@ -87,9 +87,9 @@ int acquire_luks2_key( } _cleanup_(tpm2_context_unrefp) Tpm2Context *tpm2_context = NULL; - r = tpm2_context_new(device, &tpm2_context); + r = tpm2_context_new_or_warn(device, &tpm2_context); if (r < 0) - return log_error_errno(r, "Failed to create TPM2 context: %m"); + return r; r = tpm2_unseal(tpm2_context, hash_pcr_mask, diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index 34ad9ebd14..89bea30d00 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -919,9 +919,9 @@ static int measure_volume_key( #if HAVE_TPM2 _cleanup_(tpm2_context_unrefp) Tpm2Context *c = NULL; - r = tpm2_context_new(arg_tpm2_device, &c); + r = tpm2_context_new_or_warn(arg_tpm2_device, &c); if (r < 0) - return log_error_errno(r, "Failed to create TPM2 context: %m"); + return r; _cleanup_strv_free_ char **l = NULL; if (strv_isempty(arg_tpm2_measure_banks)) { diff --git a/src/partition/repart.c b/src/partition/repart.c index fa556874df..51ae8592fd 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -4067,9 +4067,9 @@ static int partition_encrypt(Context *context, Partition *p, PartitionTarget *ta return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Must provide all PCR values when using TPM2 device key."); } else { - r = tpm2_context_new(arg_tpm2_device, &tpm2_context); + r = tpm2_context_new_or_warn(arg_tpm2_device, &tpm2_context); if (r < 0) - return log_error_errno(r, "Failed to create TPM2 context: %m"); + return r; if (!tpm2_pcr_values_has_all_values(arg_tpm2_hash_pcr_values, arg_tpm2_n_hash_pcr_values)) { r = tpm2_pcr_read_missing_values(tpm2_context, arg_tpm2_hash_pcr_values, arg_tpm2_n_hash_pcr_values); diff --git a/src/pcrextend/pcrextend.c b/src/pcrextend/pcrextend.c index ead353f5a6..ba2b171250 100644 --- a/src/pcrextend/pcrextend.c +++ b/src/pcrextend/pcrextend.c @@ -199,7 +199,7 @@ static int extend_now(unsigned pcr, const void *data, size_t size, Tpm2Userspace _cleanup_(tpm2_context_unrefp) Tpm2Context *c = NULL; int r; - r = tpm2_context_new(arg_tpm2_device, &c); + r = tpm2_context_new_or_warn(arg_tpm2_device, &c); if (r < 0) return r; diff --git a/src/pcrlock/pcrlock.c b/src/pcrlock/pcrlock.c index 5045ad93e8..4e86b527d3 100644 --- a/src/pcrlock/pcrlock.c +++ b/src/pcrlock/pcrlock.c @@ -1228,7 +1228,7 @@ static int event_log_read_pcrs(EventLog *el) { assert(el); - r = tpm2_context_new(NULL, &tc); + r = tpm2_context_new_or_warn(/* device= */ NULL, &tc); if (r < 0) return r; @@ -4490,9 +4490,9 @@ static int make_policy(bool force, RecoveryPinMode recovery_pin_mode) { } _cleanup_(tpm2_context_unrefp) Tpm2Context *tc = NULL; - r = tpm2_context_new(NULL, &tc); + r = tpm2_context_new_or_warn(/* device= */ NULL, &tc); if (r < 0) - return log_error_errno(r, "Failed to allocate TPM2 context: %m"); + return r; if (!tpm2_supports_command(tc, TPM2_CC_PolicyAuthorizeNV)) return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM2 does not support PolicyAuthorizeNV command, refusing."); @@ -4836,7 +4836,7 @@ static int undefine_policy_nv_index( assert(srk_blob); _cleanup_(tpm2_context_unrefp) Tpm2Context *tc = NULL; - r = tpm2_context_new(NULL, &tc); + r = tpm2_context_new_or_warn(/* device= */ NULL, &tc); if (r < 0) return r; diff --git a/src/shared/creds-util.c b/src/shared/creds-util.c index bd2af6d172..fd7388127b 100644 --- a/src/shared/creds-util.c +++ b/src/shared/creds-util.c @@ -919,9 +919,9 @@ int encrypt_credential_and_warn( tpm2_pubkey_pcr_mask = 0; _cleanup_(tpm2_context_unrefp) Tpm2Context *tpm2_context = NULL; - r = tpm2_context_new(tpm2_device, &tpm2_context); + r = tpm2_context_new_or_warn(tpm2_device, &tpm2_context); if (r < 0) - return log_error_errno(r, "Failed to create TPM2 context: %m"); + return r; r = tpm2_get_best_pcr_bank(tpm2_context, tpm2_hash_pcr_mask | tpm2_pubkey_pcr_mask, &tpm2_pcr_bank); if (r < 0) diff --git a/src/shared/cryptsetup-tpm2.c b/src/shared/cryptsetup-tpm2.c index ee664a95a1..335bb2eb89 100644 --- a/src/shared/cryptsetup-tpm2.c +++ b/src/shared/cryptsetup-tpm2.c @@ -143,9 +143,9 @@ int acquire_tpm2_key( } _cleanup_(tpm2_context_unrefp) Tpm2Context *tpm2_context = NULL; - r = tpm2_context_new(device, &tpm2_context); + r = tpm2_context_new_or_warn(device, &tpm2_context); if (r < 0) - return log_error_errno(r, "Failed to create TPM2 context: %m"); + return r; if (!(flags & TPM2_FLAGS_USE_PIN)) { r = tpm2_unseal(tpm2_context, diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 1e747a07e4..10a78adfaf 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -675,7 +675,7 @@ int tpm2_context_new(const char *device, Tpm2Context **ret_context) { context->tcti_dl = dlopen(fn, RTLD_NOW); if (!context->tcti_dl) - return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to load %s: %s", fn, dlerror()); + return log_debug_errno(SYNTHETIC_ERRNO(ENOPKG), "Failed to load %s: %s", fn, dlerror()); log_debug("Loaded '%s' via dlopen()", fn); @@ -691,7 +691,7 @@ int tpm2_context_new(const char *device, Tpm2Context **ret_context) { log_debug("Loaded TCTI module '%s' (%s) [Version %" PRIu32 "]", info->name, info->description, info->version); - rc = info->init(NULL, &sz, NULL); + rc = info->init(/* context= */ NULL, &sz, /* param= */ NULL); if (rc != TPM2_RC_SUCCESS) return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to initialize TCTI context: %s", sym_Tss2_RC_Decode(rc)); @@ -726,19 +726,37 @@ int tpm2_context_new(const char *device, Tpm2Context **ret_context) { /* We require AES and CFB support for session encryption. */ if (!tpm2_supports_alg(context, TPM2_ALG_AES)) - return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM does not support AES."); + return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM does not support AES."); if (!tpm2_supports_alg(context, TPM2_ALG_CFB)) - return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM does not support CFB."); + return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM does not support CFB."); if (!tpm2_supports_tpmt_sym_def(context, &SESSION_TEMPLATE_SYM_AES_128_CFB)) - return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM does not support AES-128-CFB."); + return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM does not support AES-128-CFB."); *ret_context = TAKE_PTR(context); return 0; } +int tpm2_context_new_or_warn(const char *device, Tpm2Context **ret_context) { + int r; + + assert(ret_context); + + r = tpm2_context_new(device, ret_context); + if (r == -EOPNOTSUPP) + return log_error_errno(r, "TPM device not usable as it does not support the required functionality (AES-128-CFB missing?)."); + if (r == -ENOPKG) + return log_error_errno(r, "TPM TCTI driver not available."); + if (r == -ENOENT) + return log_error_errno(r, "TPM device not found."); + if (r < 0) + return log_error_errno(r, "Failed to create TPM2 context: %m"); + + return 0; +} + static void tpm2_handle_cleanup(ESYS_CONTEXT *esys_context, ESYS_TR esys_handle, bool flush) { TSS2_RC rc; diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h index f09b71f84c..dc8aa88f09 100644 --- a/src/shared/tpm2-util.h +++ b/src/shared/tpm2-util.h @@ -72,6 +72,7 @@ typedef struct { } Tpm2Context; int tpm2_context_new(const char *device, Tpm2Context **ret_context); +int tpm2_context_new_or_warn(const char *device, Tpm2Context **ret_context); Tpm2Context *tpm2_context_ref(Tpm2Context *context); Tpm2Context *tpm2_context_unref(Tpm2Context *context); DEFINE_TRIVIAL_CLEANUP_FUNC(Tpm2Context*, tpm2_context_unref); diff --git a/src/tpm2-setup/tpm2-setup.c b/src/tpm2-setup/tpm2-setup.c index 846d5b8ac8..35628fc02a 100644 --- a/src/tpm2-setup/tpm2-setup.c +++ b/src/tpm2-setup/tpm2-setup.c @@ -212,9 +212,9 @@ static int load_public_key_tpm2(struct public_key_data *ret) { assert(ret); - r = tpm2_context_new(arg_tpm2_device, &c); + r = tpm2_context_new_or_warn(arg_tpm2_device, &c); if (r < 0) - return log_error_errno(r, "Failed to create TPM2 context: %m"); + return r; r = tpm2_get_or_create_srk( c, |