From 571d829ee49147c588e53a1f107c29fd23968581 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 Apr 2022 15:37:54 +0200 Subject: [PATCH] creds-util: add an explicit 128bit ID for identifying "automatic" key determination Previously, when encrypting creds you could pick which key to use for this via a 128bit ID identifying the key type, and use an all zero ID for rquesting automatic mode. Let's change this to use an explicitly picked 128bit ID for automatic mode, i.e. something other than all zeros. This is in preparation for adding one further automatic mode with slightly different semantics. no change in behaviour. Note that the new 128bit id is never written to disk but only used internally to indicate a specific case. --- src/creds/creds.c | 4 ++-- src/shared/creds-util.c | 29 ++++++++++++++--------------- src/shared/creds-util.h | 5 +++++ 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/creds/creds.c b/src/creds/creds.c index 6e3441e5a0..501eb2deb8 100644 --- a/src/creds/creds.c +++ b/src/creds/creds.c @@ -40,7 +40,7 @@ static bool arg_legend = true; static bool arg_system = false; static TranscodeMode arg_transcode = TRANSCODE_OFF; static int arg_newline = -1; -static sd_id128_t arg_with_key = SD_ID128_NULL; +static sd_id128_t arg_with_key = _CRED_AUTO; static const char *arg_tpm2_device = NULL; static uint32_t arg_tpm2_pcr_mask = UINT32_MAX; static const char *arg_name = NULL; @@ -684,7 +684,7 @@ static int parse_argv(int argc, char *argv[]) { case ARG_WITH_KEY: if (isempty(optarg) || streq(optarg, "auto")) - arg_with_key = SD_ID128_NULL; + arg_with_key = _CRED_AUTO; else if (streq(optarg, "host")) arg_with_key = CRED_AES256_GCM_BY_HOST; else if (streq(optarg, "tpm2")) diff --git a/src/shared/creds-util.c b/src/shared/creds-util.c index 93c8b93fa9..d8f1a597a8 100644 --- a/src/shared/creds-util.c +++ b/src/shared/creds-util.c @@ -474,9 +474,6 @@ int encrypt_credential_and_warn( int ksz, bsz, ivsz, tsz, added, r; uint8_t md[SHA256_DIGEST_LENGTH]; const EVP_CIPHER *cc; -#if HAVE_TPM2 - bool try_tpm2 = false; -#endif sd_id128_t id; assert(input || input_size == 0); @@ -484,7 +481,7 @@ int encrypt_credential_and_warn( assert(ret_size); if (!sd_id128_in_set(with_key, - SD_ID128_NULL, + _CRED_AUTO, CRED_AES256_GCM_BY_HOST, CRED_AES256_GCM_BY_TPM2_HMAC, CRED_AES256_GCM_BY_HOST_AND_TPM2_HMAC)) @@ -507,23 +504,26 @@ int encrypt_credential_and_warn( log_debug("Including not-after timestamp '%s' in encrypted credential.", format_timestamp(buf, sizeof(buf), not_after)); } - if (sd_id128_is_null(with_key) || - sd_id128_in_set(with_key, CRED_AES256_GCM_BY_HOST, CRED_AES256_GCM_BY_HOST_AND_TPM2_HMAC)) { + if (sd_id128_in_set(with_key, + _CRED_AUTO, + CRED_AES256_GCM_BY_HOST, + CRED_AES256_GCM_BY_HOST_AND_TPM2_HMAC)) { r = get_credential_host_secret( CREDENTIAL_SECRET_GENERATE| CREDENTIAL_SECRET_WARN_NOT_ENCRYPTED| - (sd_id128_is_null(with_key) ? CREDENTIAL_SECRET_FAIL_ON_TEMPORARY_FS : 0), + (sd_id128_equal(with_key, _CRED_AUTO) ? CREDENTIAL_SECRET_FAIL_ON_TEMPORARY_FS : 0), &host_key, &host_key_size); - if (r == -ENOMEDIUM && sd_id128_is_null(with_key)) + if (r == -ENOMEDIUM && sd_id128_equal(with_key, _CRED_AUTO)) log_debug_errno(r, "Credential host secret location on temporary file system, not using."); else if (r < 0) return log_error_errno(r, "Failed to determine local credential host secret: %m"); } #if HAVE_TPM2 - if (sd_id128_is_null(with_key)) { + bool try_tpm2; + if (sd_id128_equal(with_key, _CRED_AUTO)) { /* If automatic mode is selected and we are running in a container, let's not try TPM2. OTOH * if user picks TPM2 explicitly, let's always honour the request and try. */ @@ -534,11 +534,10 @@ int encrypt_credential_and_warn( log_debug("Running in container, not attempting to use TPM2."); try_tpm2 = r <= 0; - } - - if (try_tpm2 || - sd_id128_in_set(with_key, CRED_AES256_GCM_BY_TPM2_HMAC, CRED_AES256_GCM_BY_HOST_AND_TPM2_HMAC)) { + } else + try_tpm2 = sd_id128_in_set(with_key, CRED_AES256_GCM_BY_TPM2_HMAC, CRED_AES256_GCM_BY_HOST_AND_TPM2_HMAC); + if (try_tpm2) { r = tpm2_seal(tpm2_device, tpm2_pcr_mask, NULL, @@ -551,7 +550,7 @@ int encrypt_credential_and_warn( &tpm2_pcr_bank, &tpm2_primary_alg); if (r < 0) { - if (!sd_id128_is_null(with_key)) + if (!sd_id128_equal(with_key, _CRED_AUTO)) return r; log_debug_errno(r, "TPM2 sealing didn't work, not using: %m"); @@ -562,7 +561,7 @@ int encrypt_credential_and_warn( } #endif - if (sd_id128_is_null(with_key)) { + if (sd_id128_equal(with_key, _CRED_AUTO)) { /* Let's settle the key type in auto mode now. */ if (host_key && tpm2_key) diff --git a/src/shared/creds-util.h b/src/shared/creds-util.h index caf632de6e..7f0ce421ad 100644 --- a/src/shared/creds-util.h +++ b/src/shared/creds-util.h @@ -43,5 +43,10 @@ int get_credential_host_secret(CredentialSecretFlags flags, void **ret, size_t * #define CRED_AES256_GCM_BY_TPM2_HMAC SD_ID128_MAKE(0c,7c,c0,7b,11,76,45,91,9c,4b,0b,ea,08,bc,20,fe) #define CRED_AES256_GCM_BY_HOST_AND_TPM2_HMAC SD_ID128_MAKE(93,a8,94,09,48,74,44,90,90,ca,f2,fc,93,ca,b5,53) +/* Special ID to pick automatic mode (i.e. tpm2+host if TPM2 exists, only host otherwise). This ID will never + * be stored on disk, but is useful only internally while figuring out what precisely to write to disk. To + * mark that this isn't a "real" type, we'll prefix it with an underscore. */ +#define _CRED_AUTO SD_ID128_MAKE(a2,19,cb,07,85,b2,4c,04,b1,6d,18,ca,b9,d2,ee,01) + int encrypt_credential_and_warn(sd_id128_t with_key, const char *name, usec_t timestamp, usec_t not_after, const char *tpm2_device, uint32_t tpm2_pcr_mask, const void *input, size_t input_size, void **ret, size_t *ret_size); int decrypt_credential_and_warn(const char *validate_name, usec_t validate_timestamp, const char *tpm2_device, const void *input, size_t input_size, void **ret, size_t *ret_size);