From 517e94ee72b286e9942a5a6ecbffd05fc0b0bcf5 Mon Sep 17 00:00:00 2001
From: Juergen Repp <juergen.repp@sit.fraunhofer.de>
Date: Fri, 5 Nov 2021 23:08:47 +0100
Subject: [PATCH 07/23] FAPI: Fix loading of primary keys.
Problems caused by primary keys created with Fapi_CreateKey are fixed:
* For primary keys not in all cases the unique field was cleared before calling create
primary.
* If the primary key was used for signing the object was cleared after loading. So
access e.g. to the certificate did not work.
* For primary keys created with Fapi_Create with an auth value the auth_value was
not used in inSensitive to recreate the primary key. Now the auth value callback
is used to initialize inSensitive.
Fixes #2189.
Signed-off-by: Juergen Repp <juergen.repp@sit.fraunhofer.de>
---
src/tss2-fapi/fapi_int.h | 1 +
src/tss2-fapi/fapi_util.c | 62 +++++++++++++++++++++++++++++++++++++--
2 files changed, 60 insertions(+), 3 deletions(-)
diff --git a/src/tss2-fapi/fapi_int.h b/src/tss2-fapi/fapi_int.h
index d13ec413..7bcf442c 100644
--- a/src/tss2-fapi/fapi_int.h
+++ b/src/tss2-fapi/fapi_int.h
@@ -768,6 +768,7 @@ enum _FAPI_STATE_PRIMARY {
PRIMARY_READ_HIERARCHY,
PRIMARY_READ_HIERARCHY_FINISH,
PRIMARY_AUTHORIZE_HIERARCHY,
+ PRIMARY_GET_AUTH_VALUE,
PRIMARY_WAIT_FOR_PRIMARY,
PRIMARY_HAUTH_SENT,
PRIMARY_CREATED,
diff --git a/src/tss2-fapi/fapi_util.c b/src/tss2-fapi/fapi_util.c
index a0fd714e..90f8b2aa 100644
--- a/src/tss2-fapi/fapi_util.c
+++ b/src/tss2-fapi/fapi_util.c
@@ -362,6 +362,52 @@ ifapi_get_object_path(IFAPI_OBJECT *object)
return NULL;
}
+/** Set authorization value for a primary key to be created.
+ *
+ * The callback which provides the auth value must be defined.
+ *
+ * @param[in,out] context The FAPI_CONTEXT.
+ * @param[in] object The auth value will be assigned to this object.
+ * @param[in,out] inSensitive The sensitive data to store the auth value.
+ *
+ * @retval TSS2_RC_SUCCESS on success.
+ * @retval TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN If the callback for getting
+ * the auth value is not defined.
+ */
+TSS2_RC
+ifapi_set_auth_primary(
+ FAPI_CONTEXT *context,
+ IFAPI_OBJECT *object,
+ TPMS_SENSITIVE_CREATE *inSensitive)
+{
+ TSS2_RC r;
+ const char *auth = NULL;
+ const char *obj_path;
+
+ memset(inSensitive, 0, sizeof(TPMS_SENSITIVE_CREATE));
+
+ if (!object->misc.key.with_auth) {
+ return TSS2_RC_SUCCESS;
+ }
+
+ obj_path = ifapi_get_object_path(object);
+
+ /* Check whether callback is defined. */
+ if (context->callbacks.auth) {
+ r = context->callbacks.auth(obj_path, object->misc.key.description,
+ &auth, context->callbacks.authData);
+ return_if_error(r, "AuthCallback");
+ if (auth != NULL) {
+ inSensitive->userAuth.size = strlen(auth);
+ memcpy(&inSensitive->userAuth.buffer[0], auth,
+ inSensitive->userAuth.size);
+ }
+ return TSS2_RC_SUCCESS;
+ }
+ SAFE_FREE(auth);
+ return_error( TSS2_FAPI_RC_AUTHORIZATION_UNKNOWN, "Authorization callback not defined.");
+}
+
/** Set authorization value for a FAPI object.
*
* The callback which provides the auth value must be defined.
@@ -848,7 +894,7 @@ ifapi_load_primary_finish(FAPI_CONTEXT *context, ESYS_TR *handle)
IFAPI_KEY *pkey = &context->createPrimary.pkey_object.misc.key;
TPMS_CAPABILITY_DATA **capabilityData = &context->createPrimary.capabilityData;
TPMI_YES_NO moreData;
- ESYS_TR auth_session;
+ ESYS_TR auth_session = ESYS_TR_NONE; /* Initialized due to scanbuild */
LOG_TRACE("call");
@@ -923,12 +969,23 @@ ifapi_load_primary_finish(FAPI_CONTEXT *context, ESYS_TR *handle)
memset(&context->createPrimary.inSensitive, 0, sizeof(TPM2B_SENSITIVE_CREATE));
memset(&context->createPrimary.outsideInfo, 0, sizeof(TPM2B_DATA));
memset(&context->createPrimary.creationPCR, 0, sizeof(TPML_PCR_SELECTION));
+ fallthrough;
+
+ statecase(context->primary_state, PRIMARY_GET_AUTH_VALUE);
+ /* Get the auth value to be stored in inSensitive */
+ r = ifapi_set_auth_primary(context, pkey_object,
+ &context->createPrimary.inSensitive.sensitive);
+ return_try_again(r);
+ goto_if_error_reset_state(r, "Get auth value for primary", error_cleanup);
/* Prepare primary creation. */
+ TPM2B_PUBLIC public = pkey->public;
+ memset(&public.publicArea.unique, 0, sizeof(TPMU_PUBLIC_ID));
+
r = Esys_CreatePrimary_Async(context->esys, hierarchy->handle,
auth_session, ESYS_TR_NONE, ESYS_TR_NONE,
&context->createPrimary.inSensitive,
- &pkey->public,
+ &public,
&context->createPrimary.outsideInfo,
&context->createPrimary.creationPCR);
return_if_error(r, "CreatePrimary");
@@ -1905,7 +1962,6 @@ ifapi_load_key_finish(FAPI_CONTEXT *context, bool flush_parent)
} else {
LOG_TRACE("success");
ifapi_cleanup_ifapi_object(context->loadKey.key_object);
- ifapi_cleanup_ifapi_object(&context->loadKey.auth_object);
return TSS2_RC_SUCCESS;
}
break;
--
2.34.3