diff --git a/Makefile-test.am b/Makefile-test.am index bbaad2cad6..3f42f43821 100644 --- a/Makefile-test.am +++ b/Makefile-test.am @@ -194,6 +194,7 @@ ESYS_TESTS_INTEGRATION_MANDATORY = \ test/integration/esys-create-session-auth-bound.int \ test/integration/esys-create-session-auth-ecc.int \ test/integration/esys-create-session-auth.int \ + test/integration/esys-create-session-auth-long.int \ test/integration/esys-create-session-auth-xor.int \ test/integration/esys-ecc-parameters.int \ test/integration/esys-ecdh-zgen.int \ @@ -213,6 +214,7 @@ ESYS_TESTS_INTEGRATION_MANDATORY = \ test/integration/esys-make-credential-session.int \ test/integration/esys-nv-ram-counter.int \ test/integration/esys-nv-ram-counter-session.int \ + test/integration/esys-nv-ram-counter-session-long-auth.int \ test/integration/esys-nv-ram-extend-index.int \ test/integration/esys-nv-ram-extend-index-session.int \ test/integration/esys-nv-ram-ordinary-index-rlock.int \ @@ -881,6 +883,15 @@ test_integration_esys_create_session_auth_int_SOURCES = \ test/integration/esys-create-session-auth.int.c \ test/integration/main-esys.c test/integration/test-esys.h +test_integration_esys_create_session_auth_long_int_CFLAGS = $(TESTS_CFLAGS) \ + -DTEST_AES_ENCRYPTION -DTEST_LARGE_AUTH $(TSS2_ESYS_CFLAGS_CRYPTO) +test_integration_esys_create_session_auth_long_int_LDADD = $(TESTS_LDADD) +test_integration_esys_create_session_auth_long_int_LDFLAGS = $(TESTS_LDFLAGS) $(TSS2_ESYS_LDFLAGS_CRYPTO) +test_integration_esys_create_session_auth_long_int_SOURCES = \ + $(ESYS_SRC_UTIL_CRYPTO_SRC) \ + test/integration/esys-create-session-auth.int.c \ + test/integration/main-esys.c test/integration/test-esys.h + test_integration_esys_create_session_auth_bound_int_CFLAGS = $(TESTS_CFLAGS) \ -DTEST_AES_ENCRYPTION -DTEST_BOUND_SESSION $(TSS2_ESYS_CFLAGS_CRYPTO) test_integration_esys_create_session_auth_bound_int_LDADD = $(TESTS_LDADD) @@ -1109,6 +1120,15 @@ test_integration_esys_nv_ram_counter_session_int_SOURCES = \ test/integration/esys-nv-ram-counter.int.c \ test/integration/main-esys.c test/integration/test-esys.h +test_integration_esys_nv_ram_counter_session_long_auth_int_CFLAGS = $(TESTS_CFLAGS) \ + -DTEST_LONG_AUTH -DTEST_SESSION $(TSS2_ESYS_CFLAGS_CRYPTO) +test_integration_esys_nv_ram_counter_session_long_auth_int_LDADD = $(TESTS_LDADD) +test_integration_esys_nv_ram_counter_session_long_auth_int_LDFLAGS = $(TESTS_LDFLAGS) $(TSS2_ESYS_LDFLAGS_CRYPTO) +test_integration_esys_nv_ram_counter_session_long_auth_int_SOURCES = \ + $(ESYS_SRC_UTIL_CRYPTO_SRC) \ + test/integration/esys-nv-ram-counter.int.c \ + test/integration/main-esys.c test/integration/test-esys.h + test_integration_esys_nv_ram_extend_index_int_CFLAGS = $(TESTS_CFLAGS) $(TSS2_ESYS_CFLAGS_CRYPTO) test_integration_esys_nv_ram_extend_index_int_LDADD = $(TESTS_LDADD) test_integration_esys_nv_ram_extend_index_int_LDFLAGS = $(TESTS_LDFLAGS) $(TSS2_ESYS_LDFLAGS_CRYPTO) diff --git a/src/tss2-esys/api/Esys_Create.c b/src/tss2-esys/api/Esys_Create.c index 0e0ebdf483..4c7bb6b107 100644 --- a/src/tss2-esys/api/Esys_Create.c +++ b/src/tss2-esys/api/Esys_Create.c @@ -19,6 +19,20 @@ #include "util/log.h" #include "util/aux_util.h" +/** Store sensitive data inside the ESYS_CONTEXT */ +static void store_input_parameters ( + ESYS_CONTEXT *esysContext, + const TPM2B_SENSITIVE_CREATE *inSensitive) +{ + if (inSensitive == NULL) { + esysContext->in.Create.inSensitive = NULL; + } else { + esysContext->in.Create.inSensitiveData = *inSensitive; + esysContext->in.Create.inSensitive = + &esysContext->in.Create.inSensitiveData; + } +} + /** One-Call function for TPM2_Create * * This function invokes the TPM2_Create command in a one-call @@ -190,6 +204,13 @@ Esys_Create_Async( r = check_session_feasibility(shandle1, shandle2, shandle3, 1); return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage"); + store_input_parameters (esysContext, inSensitive); + if (inPublic) { + r = iesys_adapt_sensitive_to_long_auth_values(esysContext->in.Create.inSensitive, + inPublic->publicArea.nameAlg); + return_state_if_error(r, _ESYS_STATE_INIT, "Adapt auth value."); + } + /* Retrieve the metadata objects for provided handles */ r = esys_GetResourceObject(esysContext, parentHandle, &parentHandleNode); return_state_if_error(r, _ESYS_STATE_INIT, "parentHandle unknown."); @@ -197,7 +218,8 @@ Esys_Create_Async( /* Initial invocation of SAPI to prepare the command buffer with parameters */ r = Tss2_Sys_Create_Prepare(esysContext->sys, (parentHandleNode == NULL) ? TPM2_RH_NULL - : parentHandleNode->rsrc.handle, inSensitive, + : parentHandleNode->rsrc.handle, + esysContext->in.Create.inSensitive, inPublic, outsideInfo, creationPCR); return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error."); diff --git a/src/tss2-esys/api/Esys_CreateLoaded.c b/src/tss2-esys/api/Esys_CreateLoaded.c index 48d5093c43..c886851441 100644 --- a/src/tss2-esys/api/Esys_CreateLoaded.c +++ b/src/tss2-esys/api/Esys_CreateLoaded.c @@ -180,6 +180,8 @@ Esys_CreateLoaded_Async( esysContext, parentHandle, inSensitive, inPublic); TSS2L_SYS_AUTH_COMMAND auths; RSRC_NODE_T *parentHandleNode; + size_t offset = 0; + TPMT_PUBLIC publicArea; /* Check context, sequence correctness and set state to error for now */ if (esysContext == NULL) { @@ -196,6 +198,16 @@ Esys_CreateLoaded_Async( return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage"); store_input_parameters(esysContext, inSensitive, inPublic); + if (inPublic) { + r = Tss2_MU_TPMT_PUBLIC_Unmarshal(&inPublic->buffer[0], inPublic->size, &offset, + &publicArea); + return_if_error(r, "Unmarshalling inPublic failed"); + + r = iesys_adapt_sensitive_to_long_auth_values(esysContext->in.CreateLoaded.inSensitive, + publicArea.nameAlg); + return_state_if_error(r, _ESYS_STATE_INIT, "Adapt auth value."); + } + /* Retrieve the metadata objects for provided handles */ r = esys_GetResourceObject(esysContext, parentHandle, &parentHandleNode); return_state_if_error(r, _ESYS_STATE_INIT, "parentHandle unknown."); @@ -204,7 +216,7 @@ Esys_CreateLoaded_Async( r = Tss2_Sys_CreateLoaded_Prepare(esysContext->sys, (parentHandleNode == NULL) ? TPM2_RH_NULL : parentHandleNode->rsrc.handle, - inSensitive, inPublic); + esysContext->in.CreateLoaded.inSensitive, inPublic); return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error."); /* Calculate the cpHash Values */ diff --git a/src/tss2-esys/api/Esys_CreatePrimary.c b/src/tss2-esys/api/Esys_CreatePrimary.c index 2f325d1c97..f87c68a848 100644 --- a/src/tss2-esys/api/Esys_CreatePrimary.c +++ b/src/tss2-esys/api/Esys_CreatePrimary.c @@ -207,6 +207,11 @@ Esys_CreatePrimary_Async( r = check_session_feasibility(shandle1, shandle2, shandle3, 1); return_state_if_error(r, _ESYS_STATE_INIT, "Check session usage"); store_input_parameters (esysContext, inSensitive); + if (inPublic) { + r = iesys_adapt_sensitive_to_long_auth_values(esysContext->in.CreatePrimary.inSensitive, + inPublic->publicArea.nameAlg); + return_state_if_error(r, _ESYS_STATE_INIT, "Adapt auth value."); + } /* Retrieve the metadata objects for provided handles */ r = esys_GetResourceObject(esysContext, primaryHandle, &primaryHandleNode); @@ -216,7 +221,8 @@ Esys_CreatePrimary_Async( r = Tss2_Sys_CreatePrimary_Prepare(esysContext->sys, (primaryHandleNode == NULL) ? TPM2_RH_NULL : primaryHandleNode->rsrc.handle, - inSensitive, inPublic, outsideInfo, + esysContext->in.CreatePrimary.inSensitive, + inPublic, outsideInfo, creationPCR); return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error."); diff --git a/src/tss2-esys/api/Esys_NV_DefineSpace.c b/src/tss2-esys/api/Esys_NV_DefineSpace.c index 8e5c34178b..7e9487cc09 100644 --- a/src/tss2-esys/api/Esys_NV_DefineSpace.c +++ b/src/tss2-esys/api/Esys_NV_DefineSpace.c @@ -197,8 +197,15 @@ Esys_NV_DefineSpace_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, auth, publicInfo); + if (publicInfo) { + r = iesys_hash_long_auth_values(esysContext->in.NV.auth, + publicInfo->nvPublic.nameAlg); + return_state_if_error(r, _ESYS_STATE_INIT, "Adapt auth value."); + } + /* Retrieve the metadata objects for provided handles */ r = esys_GetResourceObject(esysContext, authHandle, &authHandleNode); return_state_if_error(r, _ESYS_STATE_INIT, "authHandle unknown."); @@ -206,8 +213,8 @@ Esys_NV_DefineSpace_Async( /* Initial invocation of SAPI to prepare the command buffer with parameters */ r = Tss2_Sys_NV_DefineSpace_Prepare(esysContext->sys, (authHandleNode == NULL) ? TPM2_RH_NULL - : authHandleNode->rsrc.handle, auth, - publicInfo); + : authHandleNode->rsrc.handle, + esysContext->in.NV.auth, publicInfo); return_state_if_error(r, _ESYS_STATE_INIT, "SAPI Prepare returned error."); /* Calculate the cpHash Values */ diff --git a/src/tss2-esys/esys_int.h b/src/tss2-esys/esys_int.h index d470bced07..7067f42d66 100644 --- a/src/tss2-esys/esys_int.h +++ b/src/tss2-esys/esys_int.h @@ -42,6 +42,11 @@ typedef struct { TPM2B_SENSITIVE_CREATE inSensitiveData; } CreatePrimary_IN; +typedef struct { + TPM2B_SENSITIVE_CREATE *inSensitive; + TPM2B_SENSITIVE_CREATE inSensitiveData; +} Create_IN; + typedef struct { ESYS_TR saveHandle; } ContextSave_IN; @@ -112,6 +117,7 @@ typedef struct { typedef union { StartAuthSession_IN StartAuthSession; CreatePrimary_IN CreatePrimary; + Create_IN Create; ContextSave_IN ContextSave; ContextLoad_IN ContextLoad; Load_IN Load; diff --git a/src/tss2-esys/esys_iutil.c b/src/tss2-esys/esys_iutil.c index 047a47d620..c4806cad35 100644 --- a/src/tss2-esys/esys_iutil.c +++ b/src/tss2-esys/esys_iutil.c @@ -1554,3 +1554,91 @@ iesys_tpm_error(TSS2_RC r) (r & TSS2_RC_LAYER_MASK) == TSS2_RESMGR_TPM_RC_LAYER || (r & TSS2_RC_LAYER_MASK) == TSS2_RESMGR_RC_LAYER)); } + + +/** Replace auth value with Hash for long auth values. + * + * if the size of auth value exceeds hash_size the auth value + * will be replaced with the hash of the auth value. + * + * @param[in,out] auth_value The auth value to be adapted. + * @param[in] hash_alg The hash alg used for adaption. + * @retval TSS2_RC_SUCCESS if the function call was a success. + * @retval TSS2_ESYS_RC_BAD_VALUE if an invalid hash is passed. + * @retval TSS2_ESYS_RC_MEMORY if the ESAPI cannot allocate enough memory. + * @retval TSS2_ESYS_RC_GENERAL_FAILURE for a failure during digest + * computation. + */ +TSS2_RC +iesys_hash_long_auth_values( + TPM2B_AUTH *auth_value, + TPMI_ALG_HASH hash_alg) +{ + TSS2_RC r; + IESYS_CRYPTO_CONTEXT_BLOB *cryptoContext; + TPM2B_AUTH hash2b; + size_t hash_size; + + r = iesys_crypto_hash_get_digest_size(hash_alg, &hash_size); + return_if_error(r, "Get digest size."); + + if (auth_value && auth_value->size > hash_size) { + /* The auth value has to be adapted. */ + r = iesys_crypto_hash_start(&cryptoContext, hash_alg); + return_if_error(r, "crypto hash start"); + + r = iesys_crypto_hash_update(cryptoContext, &auth_value->buffer[0], + auth_value->size); + goto_if_error(r, "crypto hash update", error_cleanup); + + r = iesys_crypto_hash_finish(&cryptoContext, &hash2b.buffer[0], + &hash_size); + goto_if_error(r, "crypto hash finish", error_cleanup); + + memcpy(&auth_value->buffer[0], &hash2b.buffer[0], hash_size); + auth_value->size = hash_size; + } + return r; + + error_cleanup: + if (cryptoContext) { + iesys_crypto_hash_abort(&cryptoContext); + } + return r; +} + +/** Adapt sensitive data for long auth values. + * + * If the size of the auth value exceeds the the size of the + * name alg hash a hash of this auth value will be stored + * in the sensitive data which is used for object creation. + * + * @param[in,out] in_sensitive The sensitive data with the auth value + * to be adapted. + * @param[in] name_hash_alg The name alg of the object whose sensitive + * data will be adapted. + * @retval TSS2_RC_SUCCESS if the function call was a success. + * @retval TSS2_ESYS_RC_MEMORY if the ESAPI cannot allocate enough memory. + * @retval TSS2_ESYS_RC_BAD_VALUE if an invalid hash is passed. + * @retval TSS2_ESYS_RC_GENERAL_FAILURE for a failure during digest + * computation. + */ +TSS2_RC +iesys_adapt_sensitive_to_long_auth_values( + TPM2B_SENSITIVE_CREATE *in_sensitive, + TPMI_ALG_HASH name_hash_alg) +{ + TSS2_RC r; + size_t hash_size; + + r = iesys_crypto_hash_get_digest_size(name_hash_alg, &hash_size); + return_if_error(r, "Get digest size."); + + if (in_sensitive->sensitive.userAuth.size > hash_size) { + /* The auth value has to be adapted. */ + r = iesys_hash_long_auth_values(&in_sensitive->sensitive.userAuth, + name_hash_alg); + return_if_error(r, "Adapt long auth values"); + } + return r; +} diff --git a/src/tss2-esys/esys_iutil.h b/src/tss2-esys/esys_iutil.h index 88519889b7..5e4e059896 100644 --- a/src/tss2-esys/esys_iutil.h +++ b/src/tss2-esys/esys_iutil.h @@ -167,6 +167,14 @@ TSS2_RC iesys_get_name( bool iesys_tpm_error( TSS2_RC r); +TSS2_RC iesys_hash_long_auth_values( + TPM2B_AUTH *auth_value, + TPMI_ALG_HASH hash_alg); + +TSS2_RC iesys_adapt_sensitive_to_long_auth_values( + TPM2B_SENSITIVE_CREATE *in_sensitive, + TPMI_ALG_HASH name_hash_alg); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/tss2-esys/esys_tr.c b/src/tss2-esys/esys_tr.c index f0127d0228..33d75fd10a 100644 --- a/src/tss2-esys/esys_tr.c +++ b/src/tss2-esys/esys_tr.c @@ -381,6 +381,8 @@ Esys_TR_SetAuth(ESYS_CONTEXT * esys_context, ESYS_TR esys_handle, { RSRC_NODE_T *esys_object; TSS2_RC r; + TPMI_ALG_HASH name_alg; + _ESYS_ASSERT_NON_NULL(esys_context); r = esys_GetResourceObject(esys_context, esys_handle, &esys_object); if (r != TPM2_RC_SUCCESS) @@ -392,7 +394,20 @@ Esys_TR_SetAuth(ESYS_CONTEXT * esys_context, ESYS_TR esys_handle, if (authValue->size > sizeof(TPMU_HA)) { return_error(TSS2_ESYS_RC_BAD_SIZE, "Bad size for auth value."); } + /* Determine name alg of resource */ + if (esys_object->rsrc.rsrcType == IESYSC_KEY_RSRC) { + name_alg = esys_object->rsrc.misc.rsrc_key_pub.publicArea.nameAlg; + } else if (esys_object->rsrc.rsrcType == IESYSC_NV_RSRC) { + name_alg = esys_object->rsrc.misc.rsrc_nv_pub.nvPublic.nameAlg; + } else { + name_alg = TPM2_ALG_NULL; + } esys_object->auth = *authValue; + /* Adapt auth value to hash for large auth values. */ + if (name_alg != TPM2_ALG_NULL) { + r = iesys_hash_long_auth_values(&esys_object->auth, name_alg); + return_if_error(r, "Adaption of out value failed."); + } } return TSS2_RC_SUCCESS; } diff --git a/test/integration/esys-create-session-auth.int.c b/test/integration/esys-create-session-auth.int.c index 736672de88..d537aaf345 100644 --- a/test/integration/esys-create-session-auth.int.c +++ b/test/integration/esys-create-session-auth.int.c @@ -80,6 +80,12 @@ test_esys_create_session_auth(ESYS_CONTEXT * esys_context) .buffer = {1, 2, 3, 4, 5} }; +#ifdef TEST_LARGE_AUTH + for (int i = 0; i < 33; i++) + authValuePrimary.buffer[i] = i; + authValuePrimary.size = 33; +#endif + TPM2B_SENSITIVE_CREATE inSensitivePrimary = { .size = 0, .sensitive = { @@ -305,6 +311,12 @@ test_esys_create_session_auth(ESYS_CONTEXT * esys_context) .buffer = {6, 7, 8, 9, 10, 11} }; +#ifdef TEST_LARGE_AUTH + for (int i = 0; i < 33; i++) + authKey2.buffer[i] = i; + authKey2.size = 33; +#endif + TPM2B_SENSITIVE_CREATE inSensitive2 = { .size = 0, .sensitive = { diff --git a/test/integration/esys-nv-ram-counter.int.c b/test/integration/esys-nv-ram-counter.int.c index eb48c18da5..1fcdb9ae83 100644 --- a/test/integration/esys-nv-ram-counter.int.c +++ b/test/integration/esys-nv-ram-counter.int.c @@ -73,6 +73,11 @@ test_esys_nv_ram_counter(ESYS_CONTEXT * esys_context) TPM2B_AUTH auth = {.size = 20, .buffer={10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}}; +#ifdef TEST_LARGE_AUTH + for (int i = 0; i < 33; i++) + auth.buffer[i] = i; + auth.size = 33; +#endif TPM2B_NV_PUBLIC publicInfo = { .size = 0,