const Tpm2Handle *session,
uint32_t hash_pcr_mask,
uint16_t pcr_bank,
- const void *pubkey,
- size_t pubkey_size,
+ const TPM2B_PUBLIC *public,
+ const void *fp,
+ size_t fp_size,
uint32_t pubkey_pcr_mask,
JsonVariant *signature_json,
bool use_pin,
TPM2B_DIGEST **ret_policy_digest) {
- TSS2_RC rc;
int r;
assert(c);
assert(session);
- assert(pubkey || pubkey_size == 0);
- assert(pubkey_pcr_mask == 0 || pubkey_size > 0);
+ assert(pubkey_pcr_mask == 0 || public);
log_debug("Building sealing policy.");
}
if (pubkey_pcr_mask != 0) {
- _cleanup_free_ void *fp = NULL;
- size_t fp_size = 0;
- TPM2B_PUBLIC pubkey_tpm2;
-
- log_debug("Configuring public key based PCR policy.");
-
- /* Convert the PEM key to TPM2 format */
- r = openssl_pubkey_to_tpm2_pubkey(pubkey, pubkey_size, &pubkey_tpm2, &fp, &fp_size);
- if (r < 0)
- return r;
-
- _cleanup_tpm2_handle_ Tpm2Handle *pubkey_handle = NULL;
- r = tpm2_handle_new(c, &pubkey_handle);
- if (r < 0)
- return r;
-
- rc = sym_Esys_LoadExternal(
- c->esys_context,
- ESYS_TR_NONE,
- ESYS_TR_NONE,
- ESYS_TR_NONE,
- NULL,
- &pubkey_tpm2,
-#if HAVE_TSS2_ESYS3
- /* tpm2-tss >= 3.0.0 requires a ESYS_TR_RH_* constant specifying the requested
- * hierarchy, older versions need TPM2_RH_* instead. */
- ESYS_TR_RH_OWNER,
-#else
- TPM2_RH_OWNER,
-#endif
- &pubkey_handle->esys_handle);
- if (rc != TSS2_RC_SUCCESS)
- return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
- "Failed to load public key into TPM: %s", sym_Tss2_RC_Decode(rc));
-
- /* Acquire the "name" of what we just loaded */
- _cleanup_(Esys_Freep) TPM2B_NAME *pubkey_name = NULL;
- r = tpm2_get_name(c, pubkey_handle, &pubkey_name);
- if (r < 0)
- return r;
-
- /* Put together the PCR policy we want to use */
TPML_PCR_SELECTION pcr_selection;
tpm2_tpml_pcr_selection_from_mask(pubkey_pcr_mask, (TPMI_ALG_HASH)pcr_bank, &pcr_selection);
- _cleanup_(Esys_Freep) TPM2B_DIGEST *approved_policy = NULL;
- r = tpm2_policy_pcr(c, session, &pcr_selection, &approved_policy);
+ r = tpm2_policy_authorize(c, session, &pcr_selection, public, fp, fp_size, signature_json, NULL);
if (r < 0)
return r;
-
- /* When we are unlocking and have a signature, let's pass it to the TPM */
- _cleanup_(Esys_Freep) TPMT_TK_VERIFIED *check_ticket_buffer = NULL;
- const TPMT_TK_VERIFIED *check_ticket;
- if (signature_json) {
- _cleanup_free_ void *signature_raw = NULL;
- size_t signature_size;
-
- r = find_signature(
- signature_json,
- &pcr_selection,
- fp, fp_size,
- approved_policy->buffer,
- approved_policy->size,
- &signature_raw,
- &signature_size);
- if (r < 0)
- return r;
-
- /* TPM2_VerifySignature() will only verify the RSA part of the RSA+SHA256 signature,
- * hence we need to do the SHA256 part ourselves, first */
- TPM2B_DIGEST signature_hash = *approved_policy;
- r = tpm2_digest_rehash(TPM2_ALG_SHA256, &signature_hash);
- if (r < 0)
- return r;
-
- TPMT_SIGNATURE policy_signature = {
- .sigAlg = TPM2_ALG_RSASSA,
- .signature.rsassa = {
- .hash = TPM2_ALG_SHA256,
- .sig.size = signature_size,
- },
- };
- if (signature_size > sizeof(policy_signature.signature.rsassa.sig.buffer))
- return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Signature larger than buffer.");
- memcpy(policy_signature.signature.rsassa.sig.buffer, signature_raw, signature_size);
-
- rc = sym_Esys_VerifySignature(
- c->esys_context,
- pubkey_handle->esys_handle,
- ESYS_TR_NONE,
- ESYS_TR_NONE,
- ESYS_TR_NONE,
- &signature_hash,
- &policy_signature,
- &check_ticket_buffer);
- if (rc != TSS2_RC_SUCCESS)
- return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
- "Failed to validate signature in TPM: %s", sym_Tss2_RC_Decode(rc));
-
- check_ticket = check_ticket_buffer;
- } else {
- /* When enrolling, we pass a NULL ticket */
- static const TPMT_TK_VERIFIED check_ticket_null = {
- .tag = TPM2_ST_VERIFIED,
- .hierarchy = TPM2_RH_OWNER,
- };
-
- check_ticket = &check_ticket_null;
- }
-
- rc = sym_Esys_PolicyAuthorize(
- c->esys_context,
- session->esys_handle,
- ESYS_TR_NONE,
- ESYS_TR_NONE,
- ESYS_TR_NONE,
- approved_policy,
- /* policyRef= */ &(const TPM2B_NONCE) {},
- pubkey_name,
- check_ticket);
- if (rc != TSS2_RC_SUCCESS)
- return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
- "Failed to push Authorize policy into TPM: %s", sym_Tss2_RC_Decode(rc));
}
if (hash_pcr_mask != 0) {
return r;
}
+ TPM2B_PUBLIC pubkey_tpm2, *authorize_key = NULL;
+ _cleanup_free_ void *fp = NULL;
+ size_t fp_size = 0;
+ if (pubkey) {
+ r = openssl_pubkey_to_tpm2_pubkey(pubkey, pubkey_size, &pubkey_tpm2, &fp, &fp_size);
+ if (r < 0)
+ return r;
+ authorize_key = &pubkey_tpm2;
+ }
+
_cleanup_tpm2_handle_ Tpm2Handle *primary = NULL;
r = tpm2_make_primary(c, /* alg = */0, !!ret_srk_buf, &primary_alg, &primary);
if (r < 0)
policy_session,
hash_pcr_mask,
pcr_bank,
- pubkey, pubkey_size,
+ authorize_key,
+ fp, fp_size,
pubkey_pcr_mask,
/* signature_json= */ NULL,
!!pin,
sym_Tss2_RC_Decode(rc));
}
+ TPM2B_PUBLIC pubkey_tpm2, *authorize_key = NULL;
+ _cleanup_free_ void *fp = NULL;
+ size_t fp_size = 0;
+ if (pubkey) {
+ r = openssl_pubkey_to_tpm2_pubkey(pubkey, pubkey_size, &pubkey_tpm2, &fp, &fp_size);
+ if (r < 0)
+ return r;
+ authorize_key = &pubkey_tpm2;
+ }
+
/*
* if a pin is set for the seal object, use it to bind the session
* key to that object. This prevents active bus interposers from
policy_session,
hash_pcr_mask,
pcr_bank,
- pubkey, pubkey_size,
+ authorize_key,
+ fp, fp_size,
pubkey_pcr_mask,
signature,
!!pin,