Coverage Report

Created: 2026-01-09 07:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tpm2-tss/test/integration/test-common.c
Line
Count
Source
1
/* SPDX-License-Identifier: BSD-2-Clause */
2
/***********************************************************************
3
 * Copyright (c) 2017-2018, Intel Corporation
4
 *
5
 * All rights reserved.
6
 ***********************************************************************/
7
#include "tss2_sys.h"
8
9
#ifdef HAVE_CONFIG_H
10
#include "config.h" // IWYU pragma: keep
11
#endif
12
13
#include <inttypes.h> // for PRIx32, uint8_t, int32_t, uint32_t, uin...
14
#include <stdbool.h>  // for bool
15
#include <stdio.h>    // for NULL, size_t
16
#include <stdlib.h>   // for free, malloc, EXIT_SUCCESS, getenv
17
#include <string.h>   // for memset, memcmp, memcpy
18
19
#include "tss2_common.h"     // for TSS2_RC_SUCCESS, TSS2_RC, UINT32, TSS2_...
20
#include "tss2_mu.h"         // for Tss2_MU_TPMS_CAPABILITY_DATA_Marshal
21
#include "tss2_tctildr.h"    // for Tss2_TctiLdr_Finalize, Tss2_TctiLdr_Ini...
22
#include "tss2_tpm2_types.h" // for TPMS_CAPABILITY_DATA, TPM2_CAP_HANDLES
23
#ifdef TEST_ESYS
24
#include "tss2_esys.h" // for Esys_Finalize, Esys_GetSysContext, Esys...
25
#endif
26
#define LOGMODULE test
27
#include "test-common.h"
28
#include "util/log.h" // for LOG_ERROR, LOG_DEBUG, LOGBLOB_ERROR
29
30
0
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
31
32
struct {
33
    TPM2_CAP cap;
34
    UINT32   prop;
35
    UINT32   count;
36
} capabilities_to_dump[] = {
37
    { TPM2_CAP_PCRS, 0, 10 },
38
    { TPM2_CAP_HANDLES, TPM2_HR_PCR, TPM2_MAX_CAP_HANDLES },
39
    { TPM2_CAP_HANDLES, TPM2_HR_HMAC_SESSION, TPM2_MAX_CAP_HANDLES },
40
    { TPM2_CAP_HANDLES, TPM2_HR_POLICY_SESSION, TPM2_MAX_CAP_HANDLES },
41
    { TPM2_CAP_HANDLES, TPM2_HR_TRANSIENT, TPM2_MAX_CAP_HANDLES },
42
    { TPM2_CAP_HANDLES, TPM2_HR_PERSISTENT, TPM2_MAX_CAP_HANDLES },
43
    { TPM2_CAP_HANDLES, TPM2_HR_NV_INDEX, TPM2_MAX_CAP_HANDLES },
44
};
45
46
struct tpm_state {
47
    TPMS_CAPABILITY_DATA
48
    capabilities[sizeof(capabilities_to_dump) / sizeof(capabilities_to_dump[0])];
49
};
50
51
/** Define a proxy tcti that returns yielded on every second invocation
52
 * thus the corresponding handling code in ESYS can be tested.
53
 * The first invocation will be Tss2_Sys_StartUp.
54
 */
55
#ifdef TEST_ESYS
56
57
TSS2_RC (*transmit_hook)(const uint8_t *command_buffer, size_t command_size) = NULL;
58
59
0
#define TCTI_PROXY_MAGIC   0x5250584f0a000000ULL /* 'PROXY\0\0\0' */
60
0
#define TCTI_PROXY_VERSION 0x1
61
62
enum state { forwarding, intercepting };
63
64
typedef struct {
65
    uint64_t               magic;
66
    uint32_t               version;
67
    TSS2_TCTI_TRANSMIT_FCN transmit;
68
    TSS2_TCTI_RECEIVE_FCN  receive;
69
    TSS2_RC (*finalize)(TSS2_TCTI_CONTEXT *tctiContext);
70
    TSS2_RC (*cancel)(TSS2_TCTI_CONTEXT *tctiContext);
71
    TSS2_RC(*getPollHandles)
72
    (TSS2_TCTI_CONTEXT *tctiContext, TSS2_TCTI_POLL_HANDLE *handles, size_t *num_handles);
73
    TSS2_RC (*setLocality)(TSS2_TCTI_CONTEXT *tctiContext, uint8_t locality);
74
    TSS2_TCTI_CONTEXT *tctiInner;
75
    enum state         state;
76
} TSS2_TCTI_CONTEXT_PROXY;
77
78
static TSS2_TCTI_CONTEXT_PROXY *
79
0
tcti_proxy_cast(TSS2_TCTI_CONTEXT *ctx) {
80
0
    TSS2_TCTI_CONTEXT_PROXY *ctxi = (TSS2_TCTI_CONTEXT_PROXY *)ctx;
81
0
    if (ctxi == NULL || ctxi->magic != TCTI_PROXY_MAGIC) {
82
0
        LOG_ERROR("Bad tcti passed.");
83
0
        return NULL;
84
0
    }
85
0
    return ctxi;
86
0
}
87
88
static TSS2_RC
89
tcti_proxy_transmit(TSS2_TCTI_CONTEXT *tctiContext,
90
                    size_t             command_size,
91
0
                    const uint8_t     *command_buffer) {
92
0
    TSS2_RC                  rval;
93
0
    TSS2_TCTI_CONTEXT_PROXY *tcti_proxy = tcti_proxy_cast(tctiContext);
94
95
0
    if (tcti_proxy->state == intercepting) {
96
0
        return TSS2_RC_SUCCESS;
97
0
    }
98
99
0
    if (transmit_hook != NULL) {
100
0
        rval = transmit_hook(command_buffer, command_size);
101
0
        if (rval != TSS2_RC_SUCCESS) {
102
0
            LOG_ERROR("transmit hook requested error");
103
0
            return rval;
104
0
        }
105
0
    }
106
107
0
    rval = Tss2_Tcti_Transmit(tcti_proxy->tctiInner, command_size, command_buffer);
108
0
    if (rval != TSS2_RC_SUCCESS) {
109
0
        LOG_ERROR("Calling TCTI Transmit");
110
0
        return rval;
111
0
    }
112
113
0
    return rval;
114
0
}
115
116
uint8_t yielded_response[] = {
117
    0x80, 0x01,             /* TPM_ST_NO_SESSION */
118
    0x00, 0x00, 0x00, 0x0A, /* Response Size 10 */
119
    0x00, 0x00, 0x09, 0x08  /* TPM_RC_YIELDED */
120
};
121
122
static TSS2_RC
123
tcti_proxy_receive(TSS2_TCTI_CONTEXT *tctiContext,
124
                   size_t            *response_size,
125
                   uint8_t           *response_buffer,
126
0
                   int32_t            timeout) {
127
0
    TSS2_RC                  rval;
128
0
    TSS2_TCTI_CONTEXT_PROXY *tcti_proxy = tcti_proxy_cast(tctiContext);
129
130
0
    if (tcti_proxy->state == intercepting) {
131
0
        *response_size = sizeof(yielded_response);
132
133
0
        if (response_buffer != NULL) {
134
0
            memcpy(response_buffer, &yielded_response[0], sizeof(yielded_response));
135
0
            tcti_proxy->state = forwarding;
136
0
        }
137
0
        return TSS2_RC_SUCCESS;
138
0
    }
139
140
0
    rval = Tss2_Tcti_Receive(tcti_proxy->tctiInner, response_size, response_buffer, timeout);
141
0
    if (rval != TSS2_RC_SUCCESS) {
142
0
        LOG_ERROR("Calling TCTI Transmit");
143
0
        return rval;
144
0
    }
145
146
    /* First read with response buffer == NULL is to get the size of the
147
     * response. The subsequent read needs to be forwarded also */
148
0
    if (response_buffer != NULL)
149
0
        tcti_proxy->state = intercepting;
150
151
0
    return rval;
152
0
}
153
154
static void
155
0
tcti_proxy_finalize(TSS2_TCTI_CONTEXT *tctiContext) {
156
0
    memset(tctiContext, 0, sizeof(TSS2_TCTI_CONTEXT_PROXY));
157
0
}
158
159
static TSS2_RC
160
tcti_proxy_initialize(TSS2_TCTI_CONTEXT *tctiContext,
161
                      size_t            *contextSize,
162
0
                      TSS2_TCTI_CONTEXT *tctiInner) {
163
0
    TSS2_TCTI_CONTEXT_PROXY *tcti_proxy = (TSS2_TCTI_CONTEXT_PROXY *)tctiContext;
164
165
0
    if (tctiContext == NULL && contextSize == NULL) {
166
0
        return TSS2_TCTI_RC_BAD_VALUE;
167
0
    } else if (tctiContext == NULL) {
168
0
        *contextSize = sizeof(*tcti_proxy);
169
0
        return TSS2_RC_SUCCESS;
170
0
    }
171
172
    /* Init TCTI context */
173
0
    memset(tcti_proxy, 0, sizeof(*tcti_proxy));
174
0
    TSS2_TCTI_MAGIC(tctiContext) = TCTI_PROXY_MAGIC;
175
0
    TSS2_TCTI_VERSION(tctiContext) = TCTI_PROXY_VERSION;
176
0
    TSS2_TCTI_TRANSMIT(tctiContext) = tcti_proxy_transmit;
177
0
    TSS2_TCTI_RECEIVE(tctiContext) = tcti_proxy_receive;
178
0
    TSS2_TCTI_FINALIZE(tctiContext) = tcti_proxy_finalize;
179
0
    TSS2_TCTI_CANCEL(tctiContext) = NULL;
180
0
    TSS2_TCTI_GET_POLL_HANDLES(tctiContext) = NULL;
181
0
    TSS2_TCTI_SET_LOCALITY(tctiContext) = NULL;
182
0
    tcti_proxy->tctiInner = tctiInner;
183
0
    tcti_proxy->state = forwarding;
184
185
0
    return TSS2_RC_SUCCESS;
186
0
}
187
#endif /* TEST_ESYS */
188
189
int
190
0
transient_empty(TSS2_SYS_CONTEXT *sys_ctx) {
191
0
    TSS2_RC              rc;
192
0
    TPMS_CAPABILITY_DATA caps;
193
194
0
    do {
195
0
        rc = Tss2_Sys_GetCapability(sys_ctx, NULL, TPM2_CAP_HANDLES, TPM2_HR_TRANSIENT,
196
0
                                    ARRAY_SIZE(caps.data.handles.handle), NULL, &caps, NULL);
197
0
    } while (rc == TPM2_RC_YIELDED); // TODO also for other cmds?
198
0
    if (rc != TSS2_RC_SUCCESS) {
199
0
        LOG_ERROR("TPM2_GetCapabilities failed: 0x%" PRIx32, rc);
200
0
        return EXIT_ERROR;
201
0
    }
202
203
0
    if (caps.data.handles.count) {
204
0
        LOG_ERROR("TPM holds transient objects");
205
0
        for (UINT32 i = 0; i < caps.data.handles.count; i++) {
206
0
            LOG_ERROR("Handle 0x%" PRIx32, caps.data.handles.handle[i]);
207
0
        }
208
0
        return EXIT_ERROR;
209
0
    }
210
211
0
    return EXIT_SUCCESS;
212
0
}
213
214
int
215
0
pcr16_empty(TSS2_SYS_CONTEXT *sys_ctx) {
216
0
    TSS2_RC            rc;
217
0
    TPML_DIGEST        pcr_values = { 0 };
218
0
    TPML_PCR_SELECTION pcr_selection
219
0
        = { .count = 1,
220
0
            .pcrSelections
221
0
            = { { .hash = TPM2_ALG_SHA256, .sizeofSelect = 3, .pcrSelect = { 0 } } } };
222
0
    pcr_selection.pcrSelections[0].pcrSelect[(16 / 8)] = 1 << (16 % 8);
223
224
0
    do {
225
0
        rc = Tss2_Sys_PCR_Read(sys_ctx, NULL, &pcr_selection, NULL, NULL, &pcr_values, NULL);
226
0
    } while (rc == TPM2_RC_YIELDED); // TODO also for other cmds?
227
0
    if (rc != TSS2_RC_SUCCESS) {
228
0
        LOG_ERROR("TPM2_PCR_Read failed: 0x%" PRIx32, rc);
229
0
        return EXIT_ERROR;
230
0
    }
231
232
0
    if (pcr_values.count != 1) {
233
0
        LOG_ERROR("TPM2_PCR_Read for PCR 16 in SHA256 did not return a value");
234
0
        return EXIT_ERROR;
235
0
    }
236
237
0
    for (UINT16 i = 0; i < pcr_values.digests[0].size; i++) {
238
0
        if (pcr_values.digests[0].buffer[i] != 0x00) {
239
0
            LOGBLOB_ERROR(&pcr_values.digests[0].buffer[0], pcr_values.digests[0].size,
240
0
                          "PCR 16 in SHA256 is not 0x000..000");
241
0
            return EXIT_ERROR;
242
0
        }
243
0
    }
244
245
0
    return EXIT_SUCCESS;
246
0
}
247
248
int
249
0
dumpstate(TSS2_SYS_CONTEXT *sys_ctx, tpm_state *state_first, bool compare) {
250
0
    TSS2_RC               rc;
251
0
    tpm_state             state_second;
252
0
    tpm_state            *states[] = { state_first, &state_second };
253
0
    TPMS_CAPABILITY_DATA *capabilities;
254
0
    uint8_t               buffer[2][sizeof(TPMS_CAPABILITY_DATA)];
255
0
    size_t                off[2] = { 0, 0 };
256
257
0
    if (!compare) {
258
        /* capture and return first state */
259
0
        capabilities = state_first->capabilities;
260
0
    } else {
261
        /* capture second state and compare */
262
0
        capabilities = state_second.capabilities;
263
0
    }
264
0
    for (size_t i = 0; i < ARRAY_SIZE(capabilities_to_dump); i++) {
265
0
        do {
266
0
            rc = Tss2_Sys_GetCapability(sys_ctx, NULL, capabilities_to_dump[i].cap,
267
0
                                        capabilities_to_dump[i].prop, capabilities_to_dump[i].count,
268
0
                                        NULL, &capabilities[i], NULL);
269
0
        } while (rc == TPM2_RC_YIELDED); // TODO also for other cmds?
270
0
        if (rc != TSS2_RC_SUCCESS) {
271
0
            LOG_ERROR("TPM2_GetCapabilities failed: 0x%" PRIx32, rc);
272
0
            return EXIT_ERROR;
273
0
        }
274
0
    }
275
276
0
    if (!compare) {
277
0
        return TPM2_RC_SUCCESS;
278
0
    }
279
280
0
    for (int i = 0; i < (int)ARRAY_SIZE(capabilities_to_dump); i++) {
281
        /* marshal both first and second for easy comparison */
282
0
        for (int j = 0; j < 2; j++) {
283
0
            rc = Tss2_MU_TPMS_CAPABILITY_DATA_Marshal(&states[j]->capabilities[i], buffer[j],
284
0
                                                      ARRAY_SIZE(buffer[j]), &off[j]);
285
0
            if (rc != TSS2_RC_SUCCESS) {
286
0
                LOG_ERROR("Marshaling failed: 0x%" PRIx32, rc);
287
0
                return EXIT_ERROR;
288
0
            }
289
0
        }
290
291
0
        if (off[0] != off[1] || memcmp(buffer[0], buffer[1], off[0]) != 0) {
292
0
            LOG_ERROR("TPM states are not equal for capability 0x%08x, property 0x%08x",
293
0
                      capabilities_to_dump[i].cap, capabilities_to_dump[i].prop);
294
0
            LOGBLOB_ERROR(buffer[0], off[0], "Before");
295
0
            LOGBLOB_ERROR(buffer[1], off[1], "After");
296
297
0
            return EXIT_ERROR;
298
0
        }
299
0
    }
300
301
0
    return EXIT_SUCCESS;
302
0
}
303
304
int
305
438
test_sys_setup(TSS2_TEST_SYS_CONTEXT **test_ctx) {
306
438
    TSS2_RC          rc;
307
438
    TSS2_ABI_VERSION abi_version = TEST_ABI_VERSION;
308
438
    size_t           size;
309
438
    char            *name_conf;
310
311
438
    size = sizeof(TSS2_TEST_SYS_CONTEXT);
312
438
    *test_ctx = malloc(size);
313
438
    if (test_ctx == NULL) {
314
0
        LOG_ERROR("Failed to allocate 0x%zx bytes for the test context", size);
315
0
        goto fail;
316
0
    }
317
318
438
    name_conf = getenv(ENV_TCTI); // TODO arg, then env?
319
438
    if (!name_conf) {
320
438
        LOG_ERROR("TCTI module not specified. Use environment variable: " ENV_TCTI);
321
438
        goto cleanup_test_ctx;
322
438
    }
323
324
0
    rc = Tss2_TctiLdr_Initialize(name_conf, &(*test_ctx)->tcti_ctx);
325
0
    if (rc != TSS2_RC_SUCCESS) {
326
0
        LOG_ERROR("Error loading TCTI: %s", name_conf);
327
0
        goto cleanup_test_ctx;
328
0
    }
329
330
0
    size = Tss2_Sys_GetContextSize(0);
331
0
    (*test_ctx)->sys_ctx = malloc(size);
332
0
    if ((*test_ctx)->sys_ctx == NULL) {
333
0
        LOG_ERROR("Failed to allocate 0x%zx bytes for the System API context", size);
334
0
        goto cleanup_tcti_ctx;
335
0
    }
336
0
    rc = Tss2_Sys_Initialize((*test_ctx)->sys_ctx, size, (*test_ctx)->tcti_ctx, &abi_version);
337
0
    if (rc != TSS2_RC_SUCCESS) {
338
0
        LOG_ERROR("Failed to initialize System API context: 0x%x", rc);
339
0
        goto cleanup_sys_mem;
340
0
    }
341
342
0
    rc = Tss2_Sys_Startup((*test_ctx)->sys_ctx, TPM2_SU_CLEAR);
343
0
    if (rc != TSS2_RC_SUCCESS && rc != TPM2_RC_INITIALIZE) {
344
0
        LOG_ERROR("TPM2_Startup failed: 0x%" PRIx32, rc);
345
0
        goto cleanup_sys_ctx;
346
0
    }
347
348
0
    (*test_ctx)->tpm_state = malloc(sizeof(tpm_state));
349
0
    if (test_ctx == NULL) {
350
0
        LOG_ERROR("Failed to allocate 0x%zx bytes for tpm_state.", size);
351
0
        goto cleanup_sys_ctx;
352
0
    }
353
354
0
    return TPM2_RC_SUCCESS;
355
356
0
    free((*test_ctx)->tpm_state);
357
358
0
cleanup_sys_ctx:
359
0
    Tss2_Sys_Finalize((*test_ctx)->sys_ctx);
360
361
0
cleanup_sys_mem:
362
0
    free((*test_ctx)->sys_ctx);
363
364
0
cleanup_tcti_ctx:
365
0
    Tss2_TctiLdr_Finalize(&(*test_ctx)->tcti_ctx);
366
367
438
cleanup_test_ctx:
368
438
    free(*test_ctx);
369
370
438
fail:
371
438
    return EXIT_ERROR;
372
438
}
373
374
int
375
0
test_sys_checks_pre(TSS2_TEST_SYS_CONTEXT *test_ctx) {
376
0
    int ret;
377
378
0
    LOG_DEBUG("Running System API pre-test checks: transient handles empty");
379
0
    ret = transient_empty(test_ctx->sys_ctx);
380
0
    if (ret != EXIT_SUCCESS) {
381
0
        LOG_ERROR("TPM contains transient objects.");
382
0
        return ret;
383
0
    }
384
385
0
    LOG_DEBUG("Running System API pre-test checks: dump capabilities");
386
0
    ret = dumpstate(test_ctx->sys_ctx, test_ctx->tpm_state, 0);
387
0
    if (ret != EXIT_SUCCESS) {
388
0
        LOG_ERROR("Error while dumping TPM state.");
389
0
        return ret;
390
0
    }
391
392
0
    LOG_DEBUG("Running System API pre-test checks: pcr16 empty");
393
0
    ret = pcr16_empty(test_ctx->sys_ctx);
394
0
    if (ret != EXIT_SUCCESS) {
395
0
        LOG_ERROR("PCR16 is not empty");
396
0
        return ret;
397
0
    }
398
399
0
    return EXIT_SUCCESS;
400
0
}
401
402
int
403
0
test_sys_checks_post(TSS2_TEST_SYS_CONTEXT *test_ctx) {
404
0
    int ret;
405
406
0
    LOG_DEBUG("Running System API pre-test checks: transient handles empty");
407
0
    ret = transient_empty(test_ctx->sys_ctx);
408
0
    if (ret != EXIT_SUCCESS) {
409
0
        LOG_ERROR("TPM contains transient objects.");
410
0
        return ret;
411
0
    }
412
413
0
    LOG_DEBUG("Running System API post-test checks: dump capabilities");
414
0
    ret = dumpstate(test_ctx->sys_ctx, test_ctx->tpm_state, 1);
415
0
    if (ret != EXIT_SUCCESS) {
416
0
        LOG_ERROR("Error while performing TPM state checks.");
417
0
        return ret;
418
0
    }
419
420
0
    LOG_DEBUG("Running System API post-test checks: pcr16 empty");
421
0
    ret = pcr16_empty(test_ctx->sys_ctx);
422
0
    if (ret != EXIT_SUCCESS) {
423
0
        LOG_ERROR("PCR16 is not empty");
424
0
        return ret;
425
0
    }
426
427
0
    return EXIT_SUCCESS;
428
0
}
429
430
void
431
0
test_sys_teardown(TSS2_TEST_SYS_CONTEXT *test_ctx) {
432
0
    if (test_ctx) {
433
0
        free(test_ctx->tpm_state);
434
0
        Tss2_Sys_Finalize(test_ctx->sys_ctx);
435
0
        free(test_ctx->sys_ctx);
436
0
        Tss2_TctiLdr_Finalize(&test_ctx->tcti_ctx);
437
0
        free(test_ctx);
438
0
    }
439
0
}
440
441
#ifdef TEST_ESYS
442
int
443
0
test_esys_setup(TSS2_TEST_ESYS_CONTEXT **test_ctx) {
444
0
    TSS2_RC          rc;
445
0
    TSS2_ABI_VERSION abi_version = TEST_ABI_VERSION;
446
0
    size_t           size;
447
0
    char            *name_conf;
448
449
0
    size = sizeof(TSS2_TEST_ESYS_CONTEXT);
450
0
    *test_ctx = malloc(size);
451
0
    if (test_ctx == NULL) {
452
0
        LOG_ERROR("Failed to allocate 0x%zx bytes for the test context", size);
453
0
        goto fail;
454
0
    }
455
456
0
    name_conf = getenv(ENV_TCTI); // TODO arg, then env?
457
0
    if (!name_conf) {
458
0
        LOG_ERROR("TCTI module not specified. Use environment variable: " ENV_TCTI);
459
0
        goto cleanup_test_ctx;
460
0
    }
461
462
0
    rc = Tss2_TctiLdr_Initialize(name_conf, &(*test_ctx)->tcti_ctx);
463
0
    if (rc != TSS2_RC_SUCCESS) {
464
0
        LOG_ERROR("Error loading TCTI: %s", name_conf);
465
0
        goto cleanup_test_ctx;
466
0
    }
467
468
0
    rc = tcti_proxy_initialize(NULL, &size, NULL);
469
0
    if (rc != TSS2_RC_SUCCESS) {
470
0
        LOG_ERROR("Proxy TCTI initialization failed (while getting context size): 0x%" PRIx32, rc);
471
0
        goto cleanup_tcti_ctx;
472
0
    }
473
0
    (*test_ctx)->tcti_proxy_ctx = malloc(size);
474
0
    if ((*test_ctx)->tcti_proxy_ctx == NULL) {
475
0
        LOG_ERROR("Failed to allocate 0x%zx bytes for the proxy TCTI context", size);
476
0
        goto cleanup_tcti_ctx;
477
0
    }
478
0
    rc = tcti_proxy_initialize((*test_ctx)->tcti_proxy_ctx, &size, (*test_ctx)->tcti_ctx);
479
0
    if (rc != TSS2_RC_SUCCESS) {
480
0
        LOG_ERROR("Proxy TCTI initialization failed: 0x%" PRIx32, rc);
481
0
        goto cleanup_tcti_proxy_mem;
482
0
    }
483
0
    ((TSS2_TCTI_CONTEXT_PROXY *)(*test_ctx)->tcti_proxy_ctx)->state = forwarding;
484
485
0
    rc = Esys_Initialize(&(*test_ctx)->esys_ctx, (*test_ctx)->tcti_proxy_ctx, &abi_version);
486
0
    if (rc != TSS2_RC_SUCCESS) {
487
0
        LOG_ERROR("Esys_Initialize failed: 0x%" PRIx32, rc);
488
0
        goto cleanup_tcti_proxy_ctx;
489
0
    }
490
491
0
    rc = Esys_Startup((*test_ctx)->esys_ctx, TPM2_SU_CLEAR);
492
0
    if (rc != TSS2_RC_SUCCESS && rc != TPM2_RC_INITIALIZE) {
493
0
        LOG_ERROR("Esys_Startup failed: 0x%" PRIx32, rc);
494
0
        goto cleanup_esys_ctx;
495
0
    }
496
497
0
    (*test_ctx)->tpm_state = malloc(sizeof(tpm_state));
498
0
    if (test_ctx == NULL) {
499
0
        LOG_ERROR("Failed to allocate 0x%zx bytes for tpm_state.", size);
500
0
        goto cleanup_esys_ctx;
501
0
    }
502
503
0
    return TPM2_RC_SUCCESS;
504
505
0
    free((*test_ctx)->tpm_state);
506
507
0
cleanup_esys_ctx:
508
0
    Esys_Finalize(&(*test_ctx)->esys_ctx);
509
510
0
cleanup_tcti_proxy_ctx:
511
0
    Tss2_Tcti_Finalize((*test_ctx)->tcti_proxy_ctx);
512
513
0
cleanup_tcti_proxy_mem:
514
0
    free((*test_ctx)->tcti_proxy_ctx);
515
516
0
cleanup_tcti_ctx:
517
0
    Tss2_TctiLdr_Finalize(&(*test_ctx)->tcti_ctx);
518
519
0
cleanup_test_ctx:
520
0
    free(*test_ctx);
521
522
0
fail:
523
0
    return EXIT_ERROR;
524
0
}
525
526
int
527
0
test_esys_checks_pre(TSS2_TEST_ESYS_CONTEXT *test_ctx) {
528
0
    int               ret;
529
0
    TSS2_RC           rc;
530
0
    TSS2_SYS_CONTEXT *sys_context;
531
532
0
    rc = Esys_GetSysContext(test_ctx->esys_ctx, &sys_context);
533
0
    if (rc != TPM2_RC_SUCCESS) {
534
0
        LOG_ERROR("Error while getting System API context from Enhanced System API context.");
535
0
        return EXIT_ERROR;
536
0
    }
537
538
0
    LOG_DEBUG("Running System API pre-test checks: transient handles empty");
539
0
    ret = transient_empty(sys_context);
540
0
    if (ret != EXIT_SUCCESS) {
541
0
        LOG_ERROR("TPM contains transient objects.");
542
0
        return ret;
543
0
    }
544
545
0
    LOG_DEBUG("Running System API pre-test checks: dump handle capabilities");
546
0
    ret = dumpstate(sys_context, test_ctx->tpm_state, 0);
547
0
    if (ret != EXIT_SUCCESS) {
548
0
        LOG_ERROR("Error while dumping TPM state.");
549
0
        return ret;
550
0
    }
551
552
0
    LOG_DEBUG("Running System API pre-test checks: pcr16 empty");
553
0
    ret = pcr16_empty(sys_context);
554
0
    if (ret != EXIT_SUCCESS) {
555
0
        LOG_ERROR("PCR16 is not empty");
556
0
        return ret;
557
0
    }
558
559
0
    return EXIT_SUCCESS;
560
0
}
561
562
int
563
0
test_esys_checks_post(TSS2_TEST_ESYS_CONTEXT *test_ctx) {
564
0
    int               ret;
565
0
    TSS2_RC           rc;
566
0
    TSS2_SYS_CONTEXT *sys_context;
567
568
0
    rc = Esys_GetSysContext(test_ctx->esys_ctx, &sys_context);
569
0
    if (rc != TPM2_RC_SUCCESS) {
570
0
        LOG_ERROR("Error while getting System API context from Enhanced System API context.");
571
0
        return EXIT_ERROR;
572
0
    }
573
574
0
    LOG_DEBUG("Running System API pre-test checks: transient handles empty");
575
0
    ret = transient_empty(sys_context);
576
0
    if (ret != EXIT_SUCCESS) {
577
0
        LOG_ERROR("TPM contains transient objects.");
578
0
        return ret;
579
0
    }
580
581
0
    LOG_DEBUG("Running System API post-test checks: dump capabilities");
582
0
    ret = dumpstate(sys_context, test_ctx->tpm_state, 1);
583
0
    if (ret != EXIT_SUCCESS) {
584
0
        LOG_ERROR("Error while performing TPM state checks.");
585
0
        return ret;
586
0
    }
587
588
0
    LOG_DEBUG("Running System API pre-test checks: pcr16 empty");
589
0
    ret = pcr16_empty(sys_context);
590
0
    if (ret != EXIT_SUCCESS) {
591
0
        LOG_ERROR("PCR16 is not empty");
592
0
        return ret;
593
0
    }
594
595
0
    return EXIT_SUCCESS;
596
0
}
597
598
void
599
0
test_esys_teardown(TSS2_TEST_ESYS_CONTEXT *test_ctx) {
600
0
    if (test_ctx) {
601
0
        free(test_ctx->tpm_state);
602
0
        Esys_Finalize(&test_ctx->esys_ctx);
603
        Tss2_Tcti_Finalize(test_ctx->tcti_proxy_ctx);
604
0
        free(test_ctx->tcti_proxy_ctx);
605
0
        Tss2_TctiLdr_Finalize(&test_ctx->tcti_ctx);
606
0
        free(test_ctx);
607
0
    }
608
0
}
609
610
#endif /* TEST_ESYS */
611
612
#ifdef TEST_FAPI
613
int
614
test_fapi_checks_pre(TSS2_TEST_FAPI_CONTEXT *test_ctx) {
615
    return test_esys_checks_pre(&test_ctx->test_esys_ctx);
616
}
617
618
int
619
test_fapi_checks_post(TSS2_TEST_FAPI_CONTEXT *test_ctx) {
620
    return test_esys_checks_post(&test_ctx->test_esys_ctx);
621
}
622
#endif /* TEST_FAPI */