diff --git a/src/tss2-esys/api/Esys_HierarchyChangeAuth.c b/src/tss2-esys/api/Esys_HierarchyChangeAuth.c index 70f7210f0..873d27d9a 100644 --- a/src/tss2-esys/api/Esys_HierarchyChangeAuth.c +++ b/src/tss2-esys/api/Esys_HierarchyChangeAuth.c @@ -175,7 +175,9 @@ Esys_HierarchyChangeAuth_Async( /* Check input parameters */ r = check_session_feasibility(shandle1, shandle2, shandle3, 1); return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage"); + store_input_parameters(esysContext, authHandle, newAuth); + iesys_strip_trailing_zeros(&esysContext->in.HierarchyChangeAuth.newAuth); /* Retrieve the metadata objects for provided handles */ r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode); diff --git a/src/tss2-esys/api/Esys_NV_ChangeAuth.c b/src/tss2-esys/api/Esys_NV_ChangeAuth.c index d555adb1f..cbd9b6670 100644 --- a/src/tss2-esys/api/Esys_NV_ChangeAuth.c +++ b/src/tss2-esys/api/Esys_NV_ChangeAuth.c @@ -159,6 +159,8 @@ Esys_NV_ChangeAuth_Async( esysContext, nvIndex, newAuth); TSS2L_SYS_AUTH_COMMAND auths; RSRC_NODE_T *nvIndexNode; + TPM2B_AUTH *authCopy; + TPMI_ALG_HASH hashAlg; /* Check context, sequence correctness and set state to error for now */ if (esysContext == NULL) { @@ -174,10 +176,14 @@ Esys_NV_ChangeAuth_Async( r = check_session_feasibility(shandle1, shandle2, shandle3, 1); return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage"); store_input_parameters(esysContext, nvIndex, newAuth); + authCopy = &esysContext->in.HierarchyChangeAuth.newAuth; /* Retrieve the metadata objects for provided handles */ r = esys_GetResourceObject(esysContext, nvIndex, &nvIndexNode); return_state_if_error(r, _ESYS_STATE_INIT, "nvIndex unknown."); + hashAlg = nvIndexNode->rsrc.misc.rsrc_nv_pub.nvPublic.nameAlg; + r = iesys_adapt_auth_value(&esysContext->crypto_backend, authCopy, hashAlg); + return_state_if_error(r, _ESYS_STATE_INIT, "Adapt auth value"); /* Initial invocation of SAPI to prepare the command buffer with parameters */ r = Tss2_Sys_NV_ChangeAuth_Prepare(esysContext->sys, diff --git a/src/tss2-esys/api/Esys_ObjectChangeAuth.c b/src/tss2-esys/api/Esys_ObjectChangeAuth.c index c2b95d04a..eeee9d517 100644 --- a/src/tss2-esys/api/Esys_ObjectChangeAuth.c +++ b/src/tss2-esys/api/Esys_ObjectChangeAuth.c @@ -19,6 +19,20 @@ #include "util/log.h" #include "util/aux_util.h" +/** Store command parameters inside the ESYS_CONTEXT for use during _Finish */ +static void store_input_parameters ( + ESYS_CONTEXT *esysContext, + ESYS_TR authHandle, + const TPM2B_AUTH *newAuth) +{ + esysContext->in.ObjectChangeAuth.authHandle = authHandle; + if (newAuth == NULL) + memset(&esysContext->in.ObjectChangeAuth.newAuth, 0, + sizeof(esysContext->in.ObjectChangeAuth.newAuth)); + else + esysContext->in.ObjectChangeAuth.newAuth = *newAuth; +} + /** One-Call function for TPM2_ObjectChangeAuth * * This function invokes the TPM2_ObjectChangeAuth command in a one-call @@ -148,6 +162,8 @@ Esys_ObjectChangeAuth_Async( TSS2L_SYS_AUTH_COMMAND auths; RSRC_NODE_T *objectHandleNode; RSRC_NODE_T *parentHandleNode; + TPM2B_AUTH *authCopy; + TPMI_ALG_HASH hashAlg = 0; /* Check context, sequence correctness and set state to error for now */ if (esysContext == NULL) { @@ -163,12 +179,22 @@ Esys_ObjectChangeAuth_Async( r = check_session_feasibility(shandle1, shandle2, shandle3, 1); return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage"); + store_input_parameters(esysContext, objectHandle, newAuth); + /* Retrieve the metadata objects for provided handles */ r = esys_GetResourceObject(esysContext, objectHandle, &objectHandleNode); return_state_if_error(r, _ESYS_STATE_INIT, "objectHandle unknown."); r = esys_GetResourceObject(esysContext, parentHandle, &parentHandleNode); return_state_if_error(r, _ESYS_STATE_INIT, "parentHandle unknown."); + if (objectHandleNode->rsrc.rsrcType == IESYSC_KEY_RSRC) { + hashAlg = objectHandleNode->rsrc.misc.rsrc_key_pub.publicArea.nameAlg; + } + + authCopy = &esysContext->in.ObjectChangeAuth.newAuth; + r = iesys_adapt_auth_value(&esysContext->crypto_backend, authCopy, hashAlg); + return_state_if_error(r, _ESYS_STATE_INIT, "Adapt auth value"); + /* Initial invocation of SAPI to prepare the command buffer with parameters */ r = Tss2_Sys_ObjectChangeAuth_Prepare(esysContext->sys, (objectHandleNode == NULL) @@ -177,7 +203,7 @@ Esys_ObjectChangeAuth_Async( (parentHandleNode == NULL) ? TPM2_RH_NULL : parentHandleNode->rsrc.handle, - newAuth); + authCopy); return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error."); /* Calculate the cpHash Values */ @@ -247,6 +273,8 @@ Esys_ObjectChangeAuth_Finish( ESYS_CONTEXT *esysContext, TPM2B_PRIVATE **outPrivate) { + ESYS_TR authHandle; + RSRC_NODE_T *authHandleNode; TSS2_RC r; LOG_TRACE("context=%p, outPrivate=%p", esysContext, outPrivate); @@ -312,6 +340,14 @@ Esys_ObjectChangeAuth_Finish( goto error_cleanup; } + /* + * Store the new auth value in the object. + */ + authHandle = esysContext->in.ObjectChangeAuth.authHandle; + r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode); + return_if_error(r, "get resource"); + + authHandleNode->auth = esysContext->in.ObjectChangeAuth.newAuth; /* * Now the verification of the response (hmac check) and if necessary the * parameter decryption have to be done. diff --git a/src/tss2-esys/esys_int.h b/src/tss2-esys/esys_int.h index 49430a606..e6c669356 100644 --- a/src/tss2-esys/esys_int.h +++ b/src/tss2-esys/esys_int.h @@ -90,6 +90,12 @@ typedef struct { TPM2B_AUTH newAuth; } HierarchyChangeAuth_IN; +typedef struct { + ESYS_TR authHandle; + TPM2B_AUTH newAuth; +} ObjectChangeAuth_IN; + + typedef struct { ESYS_TR sequenceHandle; } SequenceComplete_IN; @@ -132,6 +138,7 @@ typedef union { HMAC_Start_IN HMAC_Start; MAC_Start_IN MAC_Start; HierarchyChangeAuth_IN HierarchyChangeAuth; + ObjectChangeAuth_IN ObjectChangeAuth; SequenceComplete_IN SequenceComplete; Policy_IN Policy; NV_IN NV; diff --git a/test/integration/esys-check-auth-with-trailing-zero.int.c b/test/integration/esys-check-auth-with-trailing-zero.int.c index 908b0b2dd..75e527bc2 100644 --- a/test/integration/esys-check-auth-with-trailing-zero.int.c +++ b/test/integration/esys-check-auth-with-trailing-zero.int.c @@ -41,6 +41,8 @@ test_esys_trailing_zeros_in_auth(ESYS_CONTEXT * esys_context) ESYS_TR session = ESYS_TR_NONE; ESYS_TR enc_session = ESYS_TR_NONE; ESYS_TR bind_key = ESYS_TR_NONE; + ESYS_TR key = ESYS_TR_NONE; + ESYS_TR key_sign = ESYS_TR_NONE; TPM2B_PUBLIC *outPublic = NULL; TPM2B_CREATION_DATA *creationData = NULL; @@ -216,6 +218,174 @@ test_esys_trailing_zeros_in_auth(ESYS_CONTEXT * esys_context) goto_if_error(r, "Error Esys_FlushContext", error); bind_key = ESYS_TR_NONE; + /* Test HierarchyChangeAuth */ + + TPM2B_AUTH authKey2 = { + .size = 6, + .buffer = { 6, 7, 8, 9, 10, 0 } + }; + + TPM2B_SENSITIVE_CREATE inSensitive2 = { + .size = 0, + .sensitive = { + .userAuth = { + .size = 0, + .buffer = {0} + }, + .data = { + .size = 0, + .buffer = {} + } + } + }; + + inSensitive2.sensitive.userAuth = authKey2; + + + TPM2B_AUTH newAuth = { + .size = 6, + .buffer = {6, 7, 8, 9, 10, 0 } + }; + + TPM2B_AUTH newAuth2 = { + .size = 6, + .buffer = {11, 12, 13, 14, 15, 0 } + }; + + TPM2B_PUBLIC template_parent = { + .size = 0, + .publicArea = { + .type = TPM2_ALG_RSA, + .nameAlg = TPM2_ALG_SHA256, + .objectAttributes = (TPMA_OBJECT_USERWITHAUTH | + TPMA_OBJECT_RESTRICTED | + TPMA_OBJECT_DECRYPT | + TPMA_OBJECT_FIXEDTPM | + TPMA_OBJECT_FIXEDPARENT | + TPMA_OBJECT_SENSITIVEDATAORIGIN), + + .authPolicy = { + .size = 0, + }, + .parameters.rsaDetail = { + .symmetric = { + .algorithm = TPM2_ALG_AES, + .keyBits.aes = 128, + .mode.aes = TPM2_ALG_CFB + }, + .scheme = { + .scheme = + TPM2_ALG_NULL, + }, + .keyBits = 2048, + .exponent = 0 + }, + .unique.rsa = { + .size = 0, + .buffer = {} + , + } + } + }; + + Esys_Free(outPublic3); + Esys_Free(outPrivate3); + + r = Esys_Create(esys_context, primaryHandle, ESYS_TR_PASSWORD, ESYS_TR_NONE, + ESYS_TR_NONE, &inSensitive2, &template_parent, NULL, &(TPML_PCR_SELECTION) {}, + &outPrivate3 , &outPublic3, NULL, NULL, NULL); + goto_if_error(r, "Error Esys_Create", error); + + r = Esys_HierarchyChangeAuth(esys_context, + ESYS_TR_RH_OWNER, + ESYS_TR_PASSWORD, + ESYS_TR_NONE, + ESYS_TR_NONE, + &newAuth); + + r = Esys_StartAuthSession(esys_context, primaryHandle, ESYS_TR_RH_OWNER, ESYS_TR_NONE, + ESYS_TR_NONE, ESYS_TR_NONE, NULL, TPM2_SE_HMAC, + &SESSION_TEMPLATE_SYM_AES_128_CFB, + TPM2_ALG_SHA256, &session); + goto_if_error(r, "Error Esys_StartAuthSession", error); + + r = Esys_TRSess_SetAttributes(esys_context, session, sessionAttributes, 0xff); + goto_if_error(r, "Error Esys_TRSess_SetAttributes", error); + + r = Esys_Load(esys_context, primaryHandle, session, ESYS_TR_NONE, ESYS_TR_NONE, + outPrivate3, outPublic3, &key); + goto_if_error(r, "Error Esys_Load", error); + + r = Esys_HierarchyChangeAuth(esys_context, + ESYS_TR_RH_OWNER, + ESYS_TR_PASSWORD, + ESYS_TR_NONE, + ESYS_TR_NONE, + &newAuth2); + goto_if_error(r, "Error: HierarchyChangeAuth", error); + + Esys_Free(outPublic3); + Esys_Free(outPrivate3); + + TPM2B_PUBLIC template_sign = { + .size = 0, + .publicArea = { + .type = TPM2_ALG_ECC, + .nameAlg = TPM2_ALG_SHA256, + .objectAttributes = (TPMA_OBJECT_USERWITHAUTH | + TPMA_OBJECT_RESTRICTED | + TPMA_OBJECT_DECRYPT | + TPMA_OBJECT_FIXEDTPM | + TPMA_OBJECT_FIXEDPARENT | + TPMA_OBJECT_SENSITIVEDATAORIGIN), + .authPolicy = { + .size = 0, + }, + .parameters.eccDetail = { + .symmetric ={ + .algorithm = TPM2_ALG_AES, + .keyBits.aes = 128, + .mode.aes = TPM2_ALG_CFB}, + .scheme = { + .scheme = TPM2_ALG_NULL + }, + .curveID = TPM2_ECC_NIST_P256, + .kdf = { + .scheme = TPM2_ALG_NULL, + .details = {}} + }, + .unique.ecc = { + .x = {.size = 0,.buffer = {}}, + .y = {.size = 0,.buffer = {}}, + }, + }, + }; + + Esys_FlushContext(esys_context, primaryHandle); + primaryHandle = ESYS_TR_NONE; + + r = Esys_TR_SetAuth(esys_context, key, &authKey2); + goto_if_error(r, "Error Esys_", error); + + r = Esys_Create(esys_context, key, ESYS_TR_PASSWORD, session, + ESYS_TR_NONE, &inSensitive2, &template_sign, NULL, &(TPML_PCR_SELECTION) {}, + &outPrivate3 , &outPublic3, NULL, NULL, NULL); + goto_if_error(r, "Error Esys_Create", error); + + r = Esys_Load(esys_context, key, session, ESYS_TR_NONE, ESYS_TR_NONE, + outPrivate3, outPublic3, &key_sign); + goto_if_error(r, "Error Esys_Load", error); + + /* Reset auth value for storage hierarchy */ + r = Esys_HierarchyChangeAuth(esys_context, + ESYS_TR_RH_OWNER, + ESYS_TR_PASSWORD, + ESYS_TR_NONE, + ESYS_TR_NONE, + NULL); + goto_if_error(r, "Error: HierarchyChangeAuth", error); + + error: if (session != ESYS_TR_NONE) { @@ -242,6 +412,18 @@ test_esys_trailing_zeros_in_auth(ESYS_CONTEXT * esys_context) } } + if (key != ESYS_TR_NONE) { + if (Esys_FlushContext(esys_context, key) != TSS2_RC_SUCCESS) { + LOG_ERROR("Cleanup key."); + } + } + + if (key_sign != ESYS_TR_NONE) { + if (Esys_FlushContext(esys_context, key_sign) != TSS2_RC_SUCCESS) { + LOG_ERROR("Cleanup key2 failed."); + } + } + Esys_Free(outPublic); Esys_Free(creationData); Esys_Free(creationHash);