Skip to content

Commit

Permalink
ESYS: Support of Cp and RpHashes from Esys Layer
Browse files Browse the repository at this point in the history
The ESYS API is extended with the functions:
Esys_GetCpHash, Esys_GetRpHash, and Esys_Abort.
The cp hash can computed after the async call of a function.
The rp hash after the finish call. If only the async call is
executed to to compute the cp hash Esys_Abort has to be called
to enable the execution of further ESYS commands.
Addresses: #2930.

Signed-off-by: Juergen Repp <[email protected]>
  • Loading branch information
JuergenReppSIT committed Jan 16, 2025
1 parent e25ab67 commit bd830f7
Show file tree
Hide file tree
Showing 12 changed files with 355 additions and 16 deletions.
10 changes: 9 additions & 1 deletion Makefile-test.am
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ ESYS_TESTS_INTEGRATION_MANDATORY = \
test/integration/esys-clockset.int \
test/integration/esys-clockset-audit.int \
test/integration/esys-commit.int \
test/integration/esys-cp-hash.int \
test/integration/esys-create-fail.int \
test/integration/esys-create-password-auth.int \
test/integration/esys-create-policy-auth.int \
Expand Down Expand Up @@ -1136,7 +1137,7 @@ if POLICY
TESTS_UNIT += test/unit/tss2_policy

test_unit_tss2_policy_CFLAGS = $(CMOCKA_CFLAGS) $(TESTS_CFLAGS)
test_unit_tss2_policy_LDADD = $(CMOCKA_LIBS) $(libtss2_policy) $(libtss2_esys)
test_unit_tss2_policy_LDADD = $(CMOCKA_LIBS) $(libtss2_policy) $(libtss2_esys) $(libtss2_sys)
test_unit_tss2_policy_SOURCES = test/unit/tss2_policy.c src/util/log.c \
test/data/test-fapi-policies.h test/helper/cmocka_all.h
endif # POLICY
Expand Down Expand Up @@ -1593,6 +1594,13 @@ test_integration_esys_get_random_int_SOURCES = \
test/integration/esys-get-random.int.c \
test/integration/main-esys.c test/integration/test-esys.h

test_integration_esys_cp_hash_int_CFLAGS = $(TESTS_CFLAGS)
test_integration_esys_cp_hash_int_LDADD = $(TESTS_LDADD)
test_integration_esys_cp_hash_int_LDFLAGS = $(TESTS_LDFLAGS)
test_integration_esys_cp_hash_int_SOURCES = \
test/integration/esys-cp-hash.int.c \
test/integration/main-esys.c test/integration/test-esys.h

test_integration_esys_get_time_int_CFLAGS = $(TESTS_CFLAGS) $(TSS2_ESYS_CFLAGS_CRYPTO)
test_integration_esys_get_time_int_LDADD = $(TESTS_LDADD)
test_integration_esys_get_time_int_LDFLAGS = $(TESTS_LDFLAGS) $(TSS2_ESYS_LDFLAGS_CRYPTO)
Expand Down
18 changes: 18 additions & 0 deletions include/tss2/tss2_esys.h
Original file line number Diff line number Diff line change
Expand Up @@ -3808,6 +3808,24 @@ Esys_SetCryptoCallbacks(
ESYS_CONTEXT *esysContext,
ESYS_CRYPTO_CALLBACKS *callbacks);

TSS2_RC
Esys_GetCpHash(
ESYS_CONTEXT* esysContext,
TPMI_ALG_HASH hashAlg,
uint8_t **cpHash,
size_t *cpHash_size);

TSS2_RC
Esys_GetRpHash(
ESYS_CONTEXT* esysContext,
TPMI_ALG_HASH hashAlg,
uint8_t **cpHash,
size_t *cpHash_size);

TSS2_RC
Esys_Abort(
ESYS_CONTEXT* esysContext);

#ifdef __cplusplus
}
#endif
Expand Down
3 changes: 3 additions & 0 deletions lib/tss2-esys.def
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
LIBRARY tss2-esys
EXPORTS
Esys_Abort
Esys_AC_GetCapability
Esys_AC_GetCapability_Async
Esys_AC_GetCapability_Finish
Expand Down Expand Up @@ -110,10 +111,12 @@ EXPORTS
Esys_GetCommandAuditDigest
Esys_GetCommandAuditDigest_Async
Esys_GetCommandAuditDigest_Finish
Esys_GetCpHash
Esys_GetPollHandles
Esys_GetRandom
Esys_GetRandom_Async
Esys_GetRandom_Finish
Esys_GetRpHash
Esys_GetSessionAuditDigest
Esys_GetSessionAuditDigest_Async
Esys_GetSessionAuditDigest_Finish
Expand Down
3 changes: 3 additions & 0 deletions lib/tss2-esys.map
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
global:
Esys_Abort;
Esys_AC_GetCapability;
Esys_AC_GetCapability_Async;
Esys_AC_GetCapability_Finish;
Expand Down Expand Up @@ -109,9 +110,11 @@
Esys_GetCommandAuditDigest;
Esys_GetCommandAuditDigest_Async;
Esys_GetCommandAuditDigest_Finish;
Esys_GetCpHash;
Esys_GetRandom;
Esys_GetRandom_Async;
Esys_GetRandom_Finish;
Esys_GetRpHash;
Esys_GetSessionAuditDigest;
Esys_GetSessionAuditDigest_Async;
Esys_GetSessionAuditDigest_Finish;
Expand Down
115 changes: 115 additions & 0 deletions src/tss2-esys/esys_cp_rp_hash.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*******************************************************************************
* Copyright 2025, Juergen Repp
* All rights reserved.
******************************************************************************/

#ifdef HAVE_CONFIG_H
#include "config.h" // IWYU pragma: keep
#endif

#include <inttypes.h> // for PRIx32, uint8_t, SIZE_MAX, int32_t
#include <stdbool.h> // for bool, false, true
#include <stdlib.h> // for NULL, malloc, size_t, calloc
#include <string.h> // for memcmp

#include "esys_int.h" // for RSRC_NODE_T, ESYS_CONTEXT, _ESYS_ASSERT...
#include "esys_mu.h" // for iesys_MU_IESYS_RESOURCE_Marshal, iesys_...
#include "esys_types.h" // for IESYS_RESOURCE, IESYS_RSRC_UNION, IESYS...
#include "tss2_common.h" // for TSS2_RC, TSS2_RC_SUCCESS, TSS2_ESYS_RC_...
#include "tss2_esys.h" // for ESYS_CONTEXT, ESYS_TR, ESYS_TR_NONE
#include "tss2_tpm2_types.h" // for TPM2B_NAME, TPM2_HANDLE, TPM2_HR_SHIFT

#define LOGMODULE esys
#include "util/log.h" // for return_if_error, SAFE_FREE, goto_if_error


static TSS2_RC get_hash(HASH_TAB_ITEM hash_tab[3],
TPMI_ALG_HASH hashAlg, uint8_t **hash, size_t *hash_size) {
int i;

for (i = 0; i < 3; i++) {
if (hash_tab[i].alg == hashAlg) {
*hash_size = hash_tab[i].size;
*hash = malloc(*hash_size);
return_if_null(*hash, "Buffer could not be allocated",
TSS2_ESYS_RC_MEMORY);
memcpy(*hash, &hash_tab[i].digest[0], *hash_size);
return TSS2_RC_SUCCESS;
}
}
return TSS2_ESYS_RC_BAD_SEQUENCE;
}

/** Get the cpHash buffer computed by an ESYS async call.
*
* The buffer will be returned if the buffer is found for the passed hashAlg.
* @param esys_ctxt [in,out] The ESYS_CONTEXT.
* @param hashAlg [in] The hash alg used to compute the cp hash.
* @param cpHash [out] The buffer containing the cp hash.
* (caller-callocated)
* @param cpHash_size [out] The size of the cpHash buffer.
* @retval TSS2_RC_SUCCESS on Success.
* @retval TSS2_ESYS_RC_BAD_SEQUENCE: if no cpHash has been computed.
* @retval TSS2_ESYS_RC_BAD_VALUE if hashAlg is not found.
* @retval TSS2_ESYS_RC_BAD_REFERENCE if esys_ctx is NULL.
* @retval TSS2_ESYS_RC_MEMORY if the buffer for the cpHash can't
* be allocated.
*/
TSS2_RC Esys_GetCpHash(ESYS_CONTEXT* esys_ctx,
TPMI_ALG_HASH hashAlg, uint8_t **cpHash, size_t *cpHash_size) {
return_if_null(esys_ctx, "ESYS context is NULL",
TSS2_ESYS_RC_BAD_REFERENCE);
if (esys_ctx->cmd_hash != CP_HASH) {
return_error(TSS2_ESYS_RC_BAD_SEQUENCE, "No cp hash is available.");
}
return get_hash(&esys_ctx->hash_tab[0], hashAlg, cpHash, cpHash_size);
}

/** Get the rpHash buffer computed by an ESYS finalize call.
*
* The buffer will be returned if the buffer is found for the passed hashAlg.
* @param esys_ctx [in,out] The ESYS_CONTEXT.
* @param hashAlg [in] The hash alg used to compute the rp hash.
* @param cpHash [out] The buffer containing the rp hash.
* (caller-callocated)
* @param cpHash_size [out] The size of the cpHash buffer.
* @retval TSS2_RC_SUCCESS on Success.
* @retval TSS2_ESYS_RC_BAD_SEQUENCE: if no cpHash has been computed.
* @retval TSS2_ESYS_RC_BAD_VALUE if hashAlg is not found.
* @retval TSS2_ESYS_RC_BAD_REFERENCE if esys_ctx is NULL.
* @retval TSS2_ESYS_RC_MEMORY if the buffer for the cpHash can't
* be allocated.
*/
TSS2_RC Esys_GetRpHash(ESYS_CONTEXT* esys_ctx,
TPMI_ALG_HASH hashAlg, uint8_t **cpHash, size_t *cpHash_size) {
return_if_null(esys_ctx, "ESYS context is NULL",
TSS2_ESYS_RC_BAD_REFERENCE);
if (esys_ctx->cmd_hash != RP_HASH) {
return_error(TSS2_ESYS_RC_BAD_SEQUENCE, "No cp hash is available.");
}
return get_hash(&esys_ctx->hash_tab[0], hashAlg, cpHash, cpHash_size);
}

/** Reset the ESYS state.
*
* If only the cp hash will be computed and there will no finish call
* after the async call the ESYS sate has to be reset to allow further ESYS calls.
* @param esys_ctx [in,out] The ESYS_CONTEXT.
* @param cpHash_size [out] The size of the cpHash buffer.
* @retval TSS2_RC_SUCCESS on Success.
* @retval TSS2_ESYS_RC_BAD_REFERENCE if esys_ctx is NULL.
*/
TSS2_RC Esys_Abort(ESYS_CONTEXT* esys_ctx) {
TSS2_SYS_CONTEXT *sys_ctx;
TSS2_RC r;

return_if_null(esys_ctx, "ESYS context is NULL",
TSS2_ESYS_RC_BAD_REFERENCE);
esys_ctx->state = ESYS_STATE_INIT;

r = Esys_GetSysContext(esys_ctx, &sys_ctx);
return_if_error(r, "Could not get Sys context");

return Tss2_Sys_Abort(sys_ctx);
}
16 changes: 16 additions & 0 deletions src/tss2-esys/esys_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ typedef struct RSRC_NODE_T {
struct RSRC_NODE_T * next; /**< The next object in the linked list. */
} RSRC_NODE_T;

/** An entry in a cpHash or rpHash table. */
typedef struct {
TPM2_ALG_ID alg; /**< The hash algorithm. */
size_t size; /**< The digest size. */
uint8_t digest[sizeof(TPMU_HA)]; /**< The digest. */
} HASH_TAB_ITEM;

typedef struct {
ESYS_TR tpmKey;
ESYS_TR bind;
Expand Down Expand Up @@ -159,6 +166,13 @@ enum ESYS_STATE {
ESAPI code. */
};

/** The last computed cp or rp hash */
enum ESYS_CMD_HASH {
NONE = 0, /**< No hash was computed */
CP_HASH, /**< The CP hash is computed. */
RP_HASH /**< The RP hash is computed. */
};

/** The data structure holding internal state information.
*
* Each ESYS_CONTEXT respresents a logically independent connection to the TPM.
Expand Down Expand Up @@ -204,6 +218,8 @@ struct ESYS_CONTEXT {

ESYS_CRYPTO_CALLBACKS crypto_backend; /**< The backend function pointers to use
for crypto operations */
enum ESYS_CMD_HASH cmd_hash; /**< Switch what hash (cp, rp or none) is computed. */
HASH_TAB_ITEM hash_tab[3]; /**< Buffer for cp/rp hash values */
};

/** The number of authomatic resubmissions.
Expand Down
13 changes: 6 additions & 7 deletions src/tss2-esys/esys_iutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ iesys_compute_cp_hashtab(ESYS_CONTEXT * esys_context,
}
}
}
esys_context->cmd_hash = CP_HASH;
return r;
}

Expand Down Expand Up @@ -311,6 +312,7 @@ iesys_compute_rp_hashtab(ESYS_CONTEXT * esys_context,
*rpHashNum += 1;
}
}
esys_context->cmd_hash = RP_HASH;
return TPM2_RC_SUCCESS;
}
/** Create an esys resource object corresponding to a TPM object.
Expand Down Expand Up @@ -1389,7 +1391,6 @@ iesys_gen_auths(ESYS_CONTEXT * esys_context,

RSRC_NODE_T *objects[] = { h1, h2, h3 };

HASH_TAB_ITEM cp_hash_tab[3];
uint8_t cpHashNum = 0;

auths->count = 0;
Expand All @@ -1412,14 +1413,13 @@ iesys_gen_auths(ESYS_CONTEXT * esys_context,
decryptNonceIdx = 0;
}


/* Compute cp hash values for command buffer for all used algorithms */

r = iesys_compute_cp_hashtab(esys_context,
(h1 != NULL) ? &h1->rsrc.name : NULL,
(h2 != NULL) ? &h2->rsrc.name : NULL,
(h3 != NULL) ? &h3->rsrc.name : NULL,
&cp_hash_tab[0], &cpHashNum);
&esys_context->hash_tab[0], &cpHashNum);
return_if_error(r, "Error while computing cp hashes");

for (int session_idx = 0; session_idx < 3; session_idx++) {
Expand Down Expand Up @@ -1453,7 +1453,7 @@ iesys_gen_auths(ESYS_CONTEXT * esys_context,
}
}
r = iesys_compute_hmac(esys_context, esys_context->session_tab[session_idx],
&cp_hash_tab[0], cpHashNum,
&esys_context->hash_tab[0], cpHashNum,
(session_idx == 0
&& decryptNonceIdx > 0) ? decryptNonce : NULL,
(session_idx == 0
Expand Down Expand Up @@ -1494,7 +1494,6 @@ iesys_check_response(ESYS_CONTEXT * esys_context)
const uint8_t *rpBuffer;
size_t rpBuffer_size;
TSS2L_SYS_AUTH_RESPONSE rspAuths;
HASH_TAB_ITEM rp_hash_tab[3];
uint8_t rpHashNum = 0;

if (esys_context->authsCount == 0) {
Expand Down Expand Up @@ -1523,10 +1522,10 @@ iesys_check_response(ESYS_CONTEXT * esys_context)

r = iesys_compute_rp_hashtab(esys_context,
rpBuffer, rpBuffer_size,
&rp_hash_tab[0], &rpHashNum);
&esys_context->hash_tab[0], &rpHashNum);
return_if_error(r, "Error: while computing response hashes");

r = iesys_check_rp_hmacs(esys_context, &rspAuths, &rp_hash_tab[0],
r = iesys_check_rp_hmacs(esys_context, &rspAuths, &esys_context->hash_tab[0],
rpHashNum);
return_if_error(r, "Error: response hmac check");

Expand Down
7 changes: 0 additions & 7 deletions src/tss2-esys/esys_iutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,6 @@ extern "C" {
*/
#define ESYS_TR_MIN_OBJECT (TPM2_RH_LAST + 1 + 0x1000)

/** An entry in a cpHash or rpHash table. */
typedef struct {
TPM2_ALG_ID alg; /**< The hash algorithm. */
size_t size; /**< The digest size. */
uint8_t digest[sizeof(TPMU_HA)]; /**< The digest. */
} HASH_TAB_ITEM;

TSS2_RC init_session_tab(
ESYS_CONTEXT *esysContext,
ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3);
Expand Down
3 changes: 2 additions & 1 deletion src/tss2-esys/tss2-esys.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@
<ClCompile Include="api\Esys_VerifySignature.c" />
<ClCompile Include="api\Esys_ZGen_2Phase.c" />
<ClCompile Include="esys_context.c" />
<ClCompile Include="esys_cp_rp_hash.c" />
<ClCompile Include="esys_crypto.c" />
<ClCompile Include="esys_crypto_ossl.c" />
<ClCompile Include="esys_free.c" />
Expand All @@ -264,4 +265,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
Loading

0 comments on commit bd830f7

Please sign in to comment.