From 27f6d0b788dd29dfbed8d2b5a9acc8d5bbb04b0e Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Thu, 8 Jun 2023 06:55:45 -0400 Subject: [PATCH] tpm2: remove tpm2_make_primary() Replace use of tpm2_make_primary() with tpm2_create_loaded() (cherry picked from commit 20988602ff203f6645762ceb8cda70b5f26b0e1d) Related: RHEL-16182 --- src/shared/tpm2-util.c | 188 ++++++----------------------------------- 1 file changed, 25 insertions(+), 163 deletions(-) diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 92f1fdd962..320261afb6 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -1200,156 +1200,6 @@ static int tpm2_get_or_create_srk( return 0; } -static int tpm2_make_primary( - Tpm2Context *c, - TPMI_ALG_PUBLIC alg, - bool use_srk_model, - TPMI_ALG_PUBLIC *ret_alg, - Tpm2Handle **ret_primary) { - - static const TPM2B_SENSITIVE_CREATE primary_sensitive = {}; - static const TPML_PCR_SELECTION creation_pcr = {}; - TPM2B_PUBLIC primary_template = { .size = sizeof(TPMT_PUBLIC), }; - _cleanup_(release_lock_file) LockFile srk_lock = LOCK_FILE_INIT; - TSS2_RC rc; - usec_t ts; - int r; - - log_debug("Creating %s on TPM.", use_srk_model ? "SRK" : "Transient Primary Key"); - - /* So apparently not all TPM2 devices support ECC. ECC is generally preferably, because it's so much - * faster, noticeably so (~10s vs. ~240ms on my system). Hence, unless explicitly configured let's - * try to use ECC first, and if that does not work, let's fall back to RSA. */ - - ts = now(CLOCK_MONOTONIC); - - _cleanup_(tpm2_handle_freep) Tpm2Handle *primary = NULL; - - /* we only need the SRK lock when making the SRK since its not atomic, transient - * primary creations don't even matter if they stomp on each other, the TPM will - * keep kicking back the same key. - */ - if (use_srk_model) { - r = make_lock_file("/run/systemd/tpm2-srk-init", LOCK_EX, &srk_lock); - if (r < 0) - return log_error_errno(r, "Failed to take TPM SRK lock: %m"); - } - - /* Find existing SRK and use it if present */ - if (use_srk_model) { - _cleanup_(Esys_Freep) TPM2B_PUBLIC *primary_public = NULL; - r = tpm2_get_srk(c, NULL, &primary_public, NULL, NULL, &primary); - if (r < 0) - return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), - "Failed to establish if SRK is present"); - if (r == 1) { - log_debug("Discovered existing SRK"); - - TPMI_ALG_PUBLIC got_alg = primary_public->publicArea.type; - if (alg != 0 && alg != got_alg) - log_warning("Caller asked for specific algorithm %u, but existing SRK is %u, ignoring", - alg, got_alg); - - if (ret_alg) - *ret_alg = alg; - if (ret_primary) - *ret_primary = TAKE_PTR(primary); - return 0; - } - log_debug("Did not find SRK, generating..."); - } - - r = tpm2_handle_new(c, &primary); - if (r < 0) - return r; - - if (IN_SET(alg, 0, TPM2_ALG_ECC)) { - if (use_srk_model) - r = tpm2_get_srk_template(c, TPM2_ALG_ECC, &primary_template.publicArea); - else - r = tpm2_get_legacy_template(TPM2_ALG_ECC, &primary_template.publicArea); - if (r < 0) - return r; - - rc = sym_Esys_CreatePrimary( - c->esys_context, - ESYS_TR_RH_OWNER, - ESYS_TR_PASSWORD, - ESYS_TR_NONE, - ESYS_TR_NONE, - &primary_sensitive, - &primary_template, - NULL, - &creation_pcr, - &primary->esys_handle, - NULL, - NULL, - NULL, - NULL); - - if (rc != TSS2_RC_SUCCESS) { - if (alg != 0) - return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), - "Failed to generate ECC primary key in TPM: %s", sym_Tss2_RC_Decode(rc)); - - log_debug("Failed to generate ECC primary key in TPM, trying RSA: %s", sym_Tss2_RC_Decode(rc)); - } else { - log_debug("Successfully created ECC primary key on TPM."); - alg = TPM2_ALG_ECC; - } - } - - if (IN_SET(alg, 0, TPM2_ALG_RSA)) { - if (use_srk_model) - r = tpm2_get_srk_template(c, TPM2_ALG_RSA, &primary_template.publicArea); - else - r = tpm2_get_legacy_template(TPM2_ALG_RSA, &primary_template.publicArea); - if (r < 0) - return r; - - rc = sym_Esys_CreatePrimary( - c->esys_context, - ESYS_TR_RH_OWNER, - ESYS_TR_PASSWORD, - ESYS_TR_NONE, - ESYS_TR_NONE, - &primary_sensitive, - &primary_template, - NULL, - &creation_pcr, - &primary->esys_handle, - NULL, - NULL, - NULL, - NULL); - if (rc != TSS2_RC_SUCCESS) - return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), - "Failed to generate RSA primary key in TPM: %s", sym_Tss2_RC_Decode(rc)); - else if (alg == 0) { - log_notice("TPM2 chip apparently does not support ECC primary keys, falling back to RSA. " - "This likely means TPM2 operations will be relatively slow, please be patient."); - alg = TPM2_ALG_RSA; - } - - log_debug("Successfully created RSA primary key on TPM."); - } - - log_debug("Generating %s on the TPM2 took %s.", use_srk_model ? "SRK" : "Transient Primary Key", - FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - ts, USEC_PER_MSEC)); - - if (use_srk_model) { - r = tpm2_persist_handle(c, primary, /* session= */ NULL, TPM2_SRK_HANDLE, ret_primary); - if (r < 0) - return r; - } else if (ret_primary) - *ret_primary = TAKE_PTR(primary); - - if (ret_alg) - *ret_alg = alg; - - return 0; -} - /* Utility functions for TPMS_PCR_SELECTION. */ /* Convert a TPMS_PCR_SELECTION object to a mask. */ @@ -3572,31 +3422,43 @@ int tpm2_unseal(const char *device, if (r < 0) return r; - /* If their is a primary key we trust, like an SRK, use it */ - _cleanup_(tpm2_handle_freep) Tpm2Handle *primary = NULL; + _cleanup_(tpm2_handle_freep) Tpm2Handle *primary_handle = NULL; if (srk_buf) { - - r = tpm2_handle_new(c, &primary); + r = tpm2_handle_new(c, &primary_handle); if (r < 0) return r; - primary->flush = false; + primary_handle->flush = false; log_debug("Found existing SRK key to use, deserializing ESYS_TR"); rc = sym_Esys_TR_Deserialize( c->esys_context, srk_buf, srk_buf_size, - &primary->esys_handle); + &primary_handle->esys_handle); if (rc != TSS2_RC_SUCCESS) return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to deserialize primary key: %s", sym_Tss2_RC_Decode(rc)); - /* old callers without an SRK still need to create a key */ - } else { - r = tpm2_make_primary(c, primary_alg, false, NULL, &primary); + } else if (primary_alg != 0) { + TPMT_PUBLIC template; + r = tpm2_get_legacy_template(primary_alg, &template); + if (r < 0) + return log_error_errno(r, "Could not get legacy template: %m"); + + r = tpm2_create_loaded( + c, + /* parent= */ NULL, + /* session= */ NULL, + &template, + /* sensitive= */ NULL, + /* ret_public= */ NULL, + /* ret_private= */ NULL, + &primary_handle); if (r < 0) return r; - } + } else + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "No SRK or primary alg provided."); log_debug("Loading HMAC key into TPM."); @@ -3607,7 +3469,7 @@ int tpm2_unseal(const char *device, * provides protections. */ _cleanup_(tpm2_handle_freep) Tpm2Handle *hmac_key = NULL; - r = tpm2_load(c, primary, NULL, &public, &private, &hmac_key); + r = tpm2_load(c, primary_handle, NULL, &public, &private, &hmac_key); if (r < 0) return r; @@ -3633,7 +3495,7 @@ int tpm2_unseal(const char *device, return r; _cleanup_(tpm2_handle_freep) Tpm2Handle *encryption_session = NULL; - r = tpm2_make_encryption_session(c, primary, hmac_key, &encryption_session); + r = tpm2_make_encryption_session(c, primary_handle, hmac_key, &encryption_session); if (r < 0) return r; @@ -3643,7 +3505,7 @@ int tpm2_unseal(const char *device, _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL; r = tpm2_make_policy_session( c, - primary, + primary_handle, encryption_session, /* trial= */ false, &policy_session);