Skip to content

Commit 63646bf

Browse files
SYS/ESYS/FAPI: wipe sensitive data using secure_mem_zero
Update functions handling sensitive data to use secure_mem_zero instead of regular memory clearing. This ensures that buffers containing secrets are reliably overwritten and not subject to compiler optimizations. Addresses: #2994 Signed-off-by: Juergen Repp <juergen_repp@web.de>
1 parent a54a27d commit 63646bf

12 files changed

Lines changed: 108 additions & 28 deletions

File tree

src/tss2-esys/api/Esys_Create.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -202,22 +202,22 @@ Esys_Create_Async(ESYS_CONTEXT *esysContext,
202202
r = iesys_adapt_auth_value(&esysContext->crypto_backend,
203203
&esysContext->in.Create.inSensitive->sensitive.userAuth,
204204
inPublic->publicArea.nameAlg);
205-
return_state_if_error(r, ESYS_STATE_INIT, "Adapt auth value.");
205+
goto_state_if_error(r, ESYS_STATE_INIT, "Adapt auth value.", error_cleanup);
206206
}
207207

208208
/* Retrieve the metadata objects for provided handles */
209209
r = esys_GetResourceObject(esysContext, parentHandle, &parentHandleNode);
210-
return_state_if_error(r, ESYS_STATE_INIT, "parentHandle unknown.");
210+
goto_state_if_error(r, ESYS_STATE_INIT, "parentHandle unknown.", error_cleanup);
211211

212212
/* Initial invocation of SAPI to prepare the command buffer with parameters */
213213
r = Tss2_Sys_Create_Prepare(
214214
esysContext->sys, (parentHandleNode == NULL) ? TPM2_RH_NULL : parentHandleNode->rsrc.handle,
215215
esysContext->in.Create.inSensitive, inPublic, outsideInfo, creationPCR);
216-
return_state_if_error(r, ESYS_STATE_INIT, "SAPI Prepare returned error.");
216+
goto_state_if_error(r, ESYS_STATE_INIT, "SAPI Prepare returned error.", error_cleanup);
217217

218218
/* Calculate the cpHash Values */
219219
r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
220-
return_state_if_error(r, ESYS_STATE_INIT, "Initialize session resources");
220+
goto_state_if_error(r, ESYS_STATE_INIT, "Initialize session resources", error_cleanup);
221221

222222
if (parentHandleNode != NULL)
223223
iesys_compute_session_value(esysContext->session_tab[0], &parentHandleNode->rsrc.name,
@@ -230,7 +230,7 @@ Esys_Create_Async(ESYS_CONTEXT *esysContext,
230230

231231
/* Generate the auth values and set them in the SAPI command buffer */
232232
r = iesys_gen_auths(esysContext, parentHandleNode, NULL, NULL, &auths);
233-
return_state_if_error(r, ESYS_STATE_INIT, "Error in computation of auth values");
233+
goto_state_if_error(r, ESYS_STATE_INIT, "Error in computation of auth values", error_cleanup);
234234

235235
esysContext->authsCount = auths.count;
236236
if (auths.count > 0) {
@@ -240,11 +240,16 @@ Esys_Create_Async(ESYS_CONTEXT *esysContext,
240240

241241
/* Trigger execution and finish the async invocation */
242242
r = Tss2_Sys_ExecuteAsync(esysContext->sys);
243-
return_state_if_error(r, ESYS_STATE_INTERNALERROR, "Finish (Execute Async)");
243+
goto_state_if_error(r, ESYS_STATE_INTERNALERROR, "Finish (Execute Async)", error_cleanup);
244244

245245
esysContext->state = ESYS_STATE_SENT;
246246

247247
return r;
248+
249+
error_cleanup:
250+
secure_mem_zero((void *)&esysContext->in.Create.inSensitiveData,
251+
sizeof(TPM2B_SENSITIVE_CREATE));
252+
return r;
248253
}
249254

250255
/** Asynchronous finish function for TPM2_Create
@@ -409,11 +414,16 @@ Esys_Create_Finish(ESYS_CONTEXT *esysContext,
409414
goto_state_if_error(r, ESYS_STATE_INTERNALERROR, "Received error from SAPI unmarshaling",
410415
error_cleanup);
411416

417+
secure_mem_zero((void *)&esysContext->in.Create.inSensitiveData,
418+
sizeof(TPM2B_SENSITIVE_CREATE));
419+
412420
esysContext->state = ESYS_STATE_INIT;
413421

414422
return TSS2_RC_SUCCESS;
415423

416424
error_cleanup:
425+
secure_mem_zero((void *)&esysContext->in.Create.inSensitiveData,
426+
sizeof(TPM2B_SENSITIVE_CREATE));
417427
if (outPrivate != NULL)
418428
SAFE_FREE(*outPrivate);
419429
if (outPublic != NULL)

src/tss2-esys/api/Esys_CreatePrimary.c

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -204,23 +204,23 @@ Esys_CreatePrimary_Async(ESYS_CONTEXT *esysContext,
204204
r = iesys_adapt_auth_value(&esysContext->crypto_backend,
205205
&esysContext->in.CreatePrimary.inSensitive->sensitive.userAuth,
206206
inPublic->publicArea.nameAlg);
207-
return_state_if_error(r, ESYS_STATE_INIT, "Adapt auth value.");
207+
goto_state_if_error(r, ESYS_STATE_INIT, "Adapt auth value.", error_cleanup);
208208
}
209209

210210
/* Retrieve the metadata objects for provided handles */
211211
r = esys_GetResourceObject(esysContext, primaryHandle, &primaryHandleNode);
212-
return_state_if_error(r, ESYS_STATE_INIT, "primaryHandle unknown.");
212+
goto_state_if_error(r, ESYS_STATE_INIT, "primaryHandle unknown.", error_cleanup);
213213

214214
/* Initial invocation of SAPI to prepare the command buffer with parameters */
215215
r = Tss2_Sys_CreatePrimary_Prepare(
216216
esysContext->sys,
217217
(primaryHandleNode == NULL) ? TPM2_RH_NULL : primaryHandleNode->rsrc.handle,
218218
esysContext->in.CreatePrimary.inSensitive, inPublic, outsideInfo, creationPCR);
219-
return_state_if_error(r, ESYS_STATE_INIT, "SAPI Prepare returned error.");
219+
goto_state_if_error(r, ESYS_STATE_INIT, "SAPI Prepare returned error.", error_cleanup);
220220

221221
/* Calculate the cpHash Values */
222222
r = init_session_tab(esysContext, shandle1, shandle2, shandle3);
223-
return_state_if_error(r, ESYS_STATE_INIT, "Initialize session resources");
223+
goto_state_if_error(r, ESYS_STATE_INIT, "Initialize session resources", error_cleanup);
224224
if (primaryHandleNode != NULL)
225225
iesys_compute_session_value(esysContext->session_tab[0], &primaryHandleNode->rsrc.name,
226226
&primaryHandleNode->auth);
@@ -232,12 +232,12 @@ Esys_CreatePrimary_Async(ESYS_CONTEXT *esysContext,
232232

233233
/* Generate the auth values and set them in the SAPI command buffer */
234234
r = iesys_gen_auths(esysContext, primaryHandleNode, NULL, NULL, &auths);
235-
return_state_if_error(r, ESYS_STATE_INIT, "Error in computation of auth values");
235+
goto_state_if_error(r, ESYS_STATE_INIT, "Error in computation of auth values", error_cleanup);
236236

237237
esysContext->authsCount = auths.count;
238238
if (auths.count > 0) {
239239
r = Tss2_Sys_SetCmdAuths(esysContext->sys, &auths);
240-
return_state_if_error(r, ESYS_STATE_INIT, "SAPI error on SetCmdAuths");
240+
goto_state_if_error(r, ESYS_STATE_INIT, "SAPI error on SetCmdAuths", error_cleanup);
241241
}
242242

243243
/* Trigger execution and finish the async invocation */
@@ -247,6 +247,12 @@ Esys_CreatePrimary_Async(ESYS_CONTEXT *esysContext,
247247
esysContext->state = ESYS_STATE_SENT;
248248

249249
return r;
250+
251+
error_cleanup:
252+
secure_mem_zero((void *)&esysContext->in.CreatePrimary.inSensitiveData,
253+
sizeof(TPM2B_SENSITIVE_CREATE));
254+
255+
return r;
250256
}
251257

252258
/** Asynchronous finish function for TPM2_CreatePrimary
@@ -368,19 +374,19 @@ Esys_CreatePrimary_Finish(ESYS_CONTEXT *esysContext,
368374
if (esysContext->submissionCount++ >= ESYS_MAX_SUBMISSIONS) {
369375
LOG_WARNING("Maximum number of (re)submissions has been reached.");
370376
esysContext->state = ESYS_STATE_INIT;
371-
goto error_cleanup;
377+
goto cleanup;
372378
}
373379
esysContext->state = ESYS_STATE_RESUBMISSION;
374380
r = Tss2_Sys_ExecuteAsync(esysContext->sys);
375381
if (r != TSS2_RC_SUCCESS) {
376382
LOG_WARNING("Error attempting to resubmit");
377383
/* We do not set esysContext->state here but inherit the most recent
378384
* state of the _async function. */
379-
goto error_cleanup;
385+
goto cleanup;
380386
}
381387
r = TSS2_ESYS_RC_TRY_AGAIN;
382388
LOG_DEBUG("Resubmission initiated and returning RC_TRY_AGAIN.");
383-
goto error_cleanup;
389+
goto cleanup;
384390
}
385391
/* The following is the "regular error" handling. */
386392
if (iesys_tpm_error(r)) {
@@ -426,11 +432,16 @@ Esys_CreatePrimary_Finish(ESYS_CONTEXT *esysContext,
426432
else
427433
SAFE_FREE(loutPublic);
428434

435+
secure_mem_zero((void *)&esysContext->in.CreatePrimary.inSensitiveData,
436+
sizeof(TPM2B_SENSITIVE_CREATE));
429437
esysContext->state = ESYS_STATE_INIT;
430438

431439
return TSS2_RC_SUCCESS;
432440

433441
error_cleanup:
442+
secure_mem_zero((void *)&esysContext->in.CreatePrimary.inSensitiveData,
443+
sizeof(TPM2B_SENSITIVE_CREATE));
444+
cleanup:
434445
Esys_TR_Close(esysContext, objectHandle);
435446
SAFE_FREE(loutPublic);
436447
if (creationData != NULL)

src/tss2-esys/api/Esys_StartAuthSession.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ Esys_StartAuthSession_Finish(ESYS_CONTEXT *esysContext, ESYS_TR *sessionHandle)
462462
secret_size, "ATH", &lnonceTPM, esysContext->in.StartAuthSession.nonceCaller,
463463
authHash_size * 8, NULL,
464464
&sessionHandleNode->rsrc.misc.rsrc_session.sessionKey.buffer[0], FALSE);
465+
secure_mem_zero(secret, secret_size);
465466
free(secret);
466467
return_if_error(r, "Error in KDFa computation.");
467468

src/tss2-esys/esys_iutil.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
44
* All rights reserved.
55
******************************************************************************/
6+
#include "util/aux_util.h"
67
#ifdef HAVE_CONFIG_H
78
#include "config.h" // IWYU pragma: keep
89
#endif
@@ -13,10 +14,11 @@
1314
#include "esys_crypto.h" // for iesys_crypto_hash_get_digest_size, iesys_cr...
1415
#include "esys_int.h" // for RSRC_NODE_T, ESYS_CONTEXT, _ESYS_STATE_INIT
1516
#include "esys_iutil.h"
16-
#include "esys_mu.h" // for FALSE
17-
#include "esys_types.h" // for IESYS_SESSION, IESYS_RESOURCE, IESYS_RSRC_U...
18-
#include "tss2_esys.h" // for ESYS_CONTEXT, ESYS_TR, ESYS_TR_NONE, ESYS_C...
19-
#include "tss2_mu.h" // for Tss2_MU_TPMI_ALG_HASH_Marshal, Tss2_MU_TPM2...
17+
#include "esys_mu.h" // for FALSE
18+
#include "esys_types.h" // for IESYS_SESSION, IESYS_RESOURCE, IESYS_RSRC_U...
19+
#include "tss2_esys.h" // for ESYS_CONTEXT, ESYS_TR, ESYS_TR_NONE, ESYS_C...
20+
#include "tss2_mu.h" // for Tss2_MU_TPMI_ALG_HASH_Marshal, Tss2_MU_TPM2...
21+
#include "util/aux_util.h" // for secure_mem_zero
2022

2123
#define LOGMODULE esys
2224
#include "util/log.h" // for return_if_error, LOG_ERROR, LOG_TRACE, goto...
@@ -135,6 +137,7 @@ iesys_DeleteAllResourceObjects(ESYS_CONTEXT *esys_context) {
135137
RSRC_NODE_T *next_node_rsrc;
136138
for (node_rsrc = esys_context->rsrc_list; node_rsrc != NULL; node_rsrc = next_node_rsrc) {
137139
next_node_rsrc = node_rsrc->next;
140+
secure_mem_zero(node_rsrc, sizeof(RSRC_NODE_T));
138141
free(node_rsrc);
139142
}
140143
esys_context->rsrc_list = NULL;

src/tss2-esys/esys_tr.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@ Esys_TR_Close(ESYS_CONTEXT *esys_context, ESYS_TR *object) {
427427
return TSS2_RC_SUCCESS;
428428
}
429429
*update_ptr = node->next;
430+
secure_mem_zero(node, sizeof(RSRC_NODE_T));
430431
free(node);
431432
*object = ESYS_TR_NONE;
432433
return TSS2_RC_SUCCESS;

src/tss2-fapi/api/Fapi_ChangeAuth.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* All rights reserved.
55
******************************************************************************/
66

7+
#include "util/aux_util.h"
78
#ifdef HAVE_CONFIG_H
89
#include "config.h" // IWYU pragma: keep
910
#endif
@@ -212,6 +213,7 @@ Fapi_ChangeAuth_Async(FAPI_CONTEXT *context, char const *entityPath, char const
212213
error_cleanup:
213214
/* Cleanup duplicated input parameters that were copied before. */
214215
SAFE_FREE(command->entityPath);
216+
secure_mem_zero((void *)command->authValue, strlen(command->authValue));
215217
SAFE_FREE(command->authValue);
216218
return r;
217219
}
@@ -580,13 +582,15 @@ Fapi_ChangeAuth_Finish(FAPI_CONTEXT *context) {
580582
ifapi_cleanup_ifapi_object(&context->createPrimary.pkey_object);
581583
ifapi_cleanup_ifapi_object(command->key_object);
582584
SAFE_FREE(command->entityPath);
585+
secure_mem_zero((void *)command->authValue, strlen(command->authValue));
583586
SAFE_FREE(command->authValue);
584587
if (command->pathlist) {
585588
for (size_t i = 0; i < command->numPathsCleanup; i++) {
586589
SAFE_FREE(command->pathlist[i]);
587590
}
588591
SAFE_FREE(command->pathlist);
589592
}
593+
secure_mem_zero((void *)&command->newAuthValue, sizeof(TPM2B_AUTH));
590594
LOG_TRACE("finished");
591595
context->state = FAPI_STATE_INIT;
592596
return r;

src/tss2-fapi/api/Fapi_Provision.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
#include "tss2_policy.h" // for TSS2_OBJECT
3333
#include "tss2_tcti.h" // for TSS2_TCTI_TIMEOUT_BLOCK
3434
#include "tss2_tpm2_types.h" // for TPMS_CAPABILITY_DATA, TPMU_CAPABILITIES
35-
35+
#include "util/aux_util.h" // for UNUSED, secure_mem_zero
3636
#define LOGMODULE fapi
3737
#include "util/log.h" // for goto_if_error, SAFE_FREE, goto_error
3838

@@ -1632,8 +1632,17 @@ Fapi_Provision_Finish(FAPI_CONTEXT *context) {
16321632
ifapi_primary_clean(context);
16331633
SAFE_FREE(command->root_crt);
16341634
SAFE_FREE(*capabilityData);
1635+
if (command->authValueLockout) {
1636+
secure_mem_zero(command->authValueLockout, strlen(command->authValueLockout));
1637+
}
16351638
SAFE_FREE(command->authValueLockout);
1639+
if (command->authValueEh) {
1640+
secure_mem_zero(command->authValueLockout, strlen(command->authValueEh));
1641+
}
16361642
SAFE_FREE(command->authValueEh);
1643+
if (command->authValueSh) {
1644+
secure_mem_zero(command->authValueLockout, strlen(command->authValueSh));
1645+
}
16371646
SAFE_FREE(command->authValueSh);
16381647
SAFE_FREE(command->pem_cert);
16391648
SAFE_FREE(certData);

src/tss2-fapi/fapi_int.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -580,10 +580,10 @@ typedef struct {
580580
TPM2B_DATA outsideInfo;
581581
TPML_PCR_SELECTION creationPCR;
582582
ESYS_TR handle;
583-
const char *authValueLockout;
584-
const char *authValueEh;
583+
char *authValueLockout;
584+
char *authValueEh;
585585
const char *policyPathEh;
586-
const char *authValueSh;
586+
char *authValueSh;
587587
const char *policyPathSh;
588588
size_t digest_idx;
589589
size_t hash_size;

src/tss2-sys/api/Tss2_Sys_Finalize.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,17 @@
88
#include "config.h" // IWYU pragma: keep
99
#endif
1010

11-
#include "tss2_sys.h" // for TSS2_SYS_CONTEXT, Tss2_Sys_Finalize
12-
#include "util/aux_util.h" // for UNUSED
11+
#include <string.h>
1312

13+
#include "sysapi_util.h" // for _TSS2_SYS_CONTEXT_BLOB, syscontext_cast
14+
#include "tss2_sys.h" // for TSS2_SYS_CONTEXT, Tss2_Sys_Finalize
15+
#include "util/aux_util.h" // for UNUSED, secure_mem_zero
1416
void
1517
Tss2_Sys_Finalize(TSS2_SYS_CONTEXT *sysContext) {
16-
UNUSED(sysContext);
18+
19+
TSS2_SYS_CONTEXT_BLOB *ctx = syscontext_cast(sysContext);
20+
21+
if (ctx && ctx->cmdBuffer) {
22+
secure_mem_zero(ctx->cmdBuffer, ctx->maxCmdSize);
23+
}
1724
}

src/util/aux_util.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,47 @@
1111
#include <config.h>
1212
#endif
1313
#include <inttypes.h> // for PRIx32
14+
#include <string.h> // for explicit_bzero
1415

1516
#include "tss2_common.h" // for TSS2_RC_SUCCESS, TSS2_RC_LAYER_MASK
1617
#include "tss2_tpm2_types.h" // for TPM2_RC_1, TPM2_RC_ASYMMETRIC, TPM2_RC_...
18+
#if defined(_WIN32)
19+
#include <windows.h> // for SecureZeroMemory
20+
#endif
1721
#ifdef __cplusplus
1822
extern "C" {
1923
#endif
2024

25+
/*
26+
* secure_mem_zero(buf, size)
27+
*
28+
* Securely zeroes a memory region that may contain sensitive data.
29+
*
30+
* This macro ensures that the memory is actually overwritten and not
31+
* optimized away by the compile.
32+
*/
33+
#if defined(__GLIBC__)
34+
#define secure_mem_zero(buf, size) \
35+
if ((buf) && (size)) \
36+
explicit_bzero((buf), (size))
37+
#elif defined(_WIN32)
38+
#define secure_mem_zero(buf, size) \
39+
if ((buf) && (size)) \
40+
SecureZeroMemory((buf), (size))
41+
#else
42+
#define secure_mem_zero(buf, size) \
43+
do { \
44+
void *mz_ptr = (buf); \
45+
size_t mz_len = (size); \
46+
if (mz_ptr && mz_len) { \
47+
volatile unsigned char *mz_p = (volatile unsigned char *)mz_ptr; \
48+
while (mz_len--) { \
49+
*mz_p++ = 0; \
50+
} \
51+
} \
52+
} while (0)
53+
#endif
54+
2155
#define SAFE_FREE(S) \
2256
if ((S) != NULL) { \
2357
free((void *)(S)); \

0 commit comments

Comments
 (0)