Skip to content

Commit

Permalink
ESYS: Enable large auth value for keys and NV objects (Addresses tpm2…
Browse files Browse the repository at this point in the history
…-software#1008).

* The size of the auth value for keys and NV objects is restricted to the size
  of the name hash algorithm of these objects.  Esapi will use the
  hash of the user auth values as auth value for these object.
  The maximal size will be sizeof(TPMU_HA).
* Test cases for keys and NV objects with large auth values were added.

Signed-off-by: Juergen Repp <juergen.repp@sit.fraunhofer.de>
  • Loading branch information
JuergenReppSIT committed Nov 27, 2020
1 parent 198201e commit 3a4b30c
Show file tree
Hide file tree
Showing 11 changed files with 206 additions and 5 deletions.
20 changes: 20 additions & 0 deletions Makefile-test.am
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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 \
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
24 changes: 23 additions & 1 deletion src/tss2-esys/api/Esys_Create.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -190,14 +204,22 @@ 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.");

/* 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.");

Expand Down
14 changes: 13 additions & 1 deletion src/tss2-esys/api/Esys_CreateLoaded.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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.");
Expand All @@ -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 */
Expand Down
8 changes: 7 additions & 1 deletion src/tss2-esys/api/Esys_CreatePrimary.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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.");

Expand Down
11 changes: 9 additions & 2 deletions src/tss2-esys/api/Esys_NV_DefineSpace.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,17 +197,24 @@ 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.");

/* 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 */
Expand Down
6 changes: 6 additions & 0 deletions src/tss2-esys/esys_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
88 changes: 88 additions & 0 deletions src/tss2-esys/esys_iutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
8 changes: 8 additions & 0 deletions src/tss2-esys/esys_iutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 15 additions & 0 deletions src/tss2-esys/esys_tr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
}
Expand Down
12 changes: 12 additions & 0 deletions test/integration/esys-create-session-auth.int.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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 = {
Expand Down
5 changes: 5 additions & 0 deletions test/integration/esys-nv-ram-counter.int.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 3a4b30c

Please sign in to comment.