1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*******************************************************************************
3 * Copyright 2019, Intel Corporation
4 *
5 * All rights reserved.
6 ******************************************************************************/
7
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include <stdarg.h>
13 #include <inttypes.h>
14 #include <string.h>
15 #include <stdlib.h>
16 #include <setjmp.h>
17 #include <cmocka.h>
18
19 #include "tss2_sys.h"
20 #include "sysapi_util.h"
21 #include "tss2-tcti/tcti-common.h"
22
23
24 #define LOGMODULE test
25 #include "util/log.h"
26
27 /**
28 * Test calls Tss2_Sys_Execute() many times after receiving TPM2_RC_RETRY
29 */
30
31 const uint8_t ok_response[] = {
32 0x80, 0x01, /* TPM_ST_NO_SESSION */
33 0x00, 0x00, 0x00, 0x2C, /* Response Size 10 + 2 + 32 */
34 0x00, 0x00, 0x00, 0x00, /* TPM_RC_SUCCESS */
35 0x00, 0x20, /* size of buffer */
36 0xde, 0xad, 0xbe, 0xef,
37 0xde, 0xad, 0xbe, 0xef,
38 0xde, 0xad, 0xbe, 0xef,
39 0xde, 0xad, 0xbe, 0xef,
40 0xde, 0xad, 0xbe, 0xef,
41 0xde, 0xad, 0xbe, 0xef,
42 0xde, 0xad, 0xbe, 0xef,
43 0xde, 0xad, 0xbe, 0xef,
44 };
45
46 const uint8_t retry_response[] = {
47 0x80, 0x01, /* TPM_ST_NO_SESSION */
48 0x00, 0x00, 0x00, 0x0A, /* Response Size 10 */
49 0x00, 0x00, 0x09, 0x22 /* TPM2_RC_RETRY */
50 };
51
52 static TSS2_RC
tcti_transmit(TSS2_TCTI_CONTEXT * tctiContext,size_t size,uint8_t const * command)53 tcti_transmit(
54 TSS2_TCTI_CONTEXT *tctiContext,
55 size_t size,
56 uint8_t const *command)
57 {
58 TSS2_RC r = 0;
59 tpm_header_t hdr;
60
61 LOG_DEBUG ("%s: transmiting %zu bytes", __func__, size);
62 r = header_unmarshal (command, &hdr);
63 if (r)
64 return r;
65
66 LOG_DEBUG ("%s request_hdr.tag = %x", __func__, hdr.tag);
67 LOG_DEBUG ("%s request_hdr.size = %x", __func__, hdr.size);
68 LOG_DEBUG ("%s request_hdr.code = %x", __func__, hdr.code);
69
70 if (hdr.tag != TPM2_ST_NO_SESSIONS || hdr.size != 0xC || hdr.code != 0x17B)
71 return TSS2_TCTI_RC_BAD_VALUE;
72
73 return r;
74 }
75
76 #define NUM_OF_RETRIES 4
77
78 static TSS2_RC
tcti_receive(TSS2_TCTI_CONTEXT * tctiContext,size_t * size,uint8_t * response,int32_t timeout)79 tcti_receive(
80 TSS2_TCTI_CONTEXT *tctiContext,
81 size_t *size,
82 uint8_t *response,
83 int32_t timeout)
84 {
85 static int i;
86
87 LOG_DEBUG ("%s: receiving response, size %zu, buff %p",
88 __func__, sizeof(ok_response), response);
89
90 if (response == NULL) {
91 *size = sizeof(ok_response);
92 return TPM2_RC_SUCCESS;
93 }
94
95 if (i++ < NUM_OF_RETRIES) {
96 LOG_DEBUG ("%s: return RC_RETRY", __func__);
97 memcpy(response, retry_response, sizeof(retry_response));
98 *size = sizeof(retry_response);
99 return TPM2_RC_SUCCESS;
100 }
101 memcpy(response, ok_response, sizeof(ok_response));
102 *size = sizeof(ok_response);
103 return TPM2_RC_SUCCESS;
104 }
105
106 static TSS2_ABI_VERSION ver = TSS2_ABI_VERSION_CURRENT;
107 static TSS2_TCTI_CONTEXT_COMMON_V1 _tcti_v1_ctx;
108
109 static int
setup(void ** state)110 setup(void **state)
111 {
112 TSS2_SYS_CONTEXT *sys_ctx;
113 TSS2_TCTI_CONTEXT *tcti_ctx = (TSS2_TCTI_CONTEXT *) &_tcti_v1_ctx;
114 UINT32 size_ctx;
115 TSS2_RC r;
116
117 size_ctx = Tss2_Sys_GetContextSize(0);
118 sys_ctx = calloc (1, size_ctx);
119 assert_non_null (sys_ctx);
120 _tcti_v1_ctx.version = 1;
121 _tcti_v1_ctx.transmit = tcti_transmit;
122 _tcti_v1_ctx.receive = tcti_receive;
123
124 r = Tss2_Sys_Initialize(sys_ctx, size_ctx, tcti_ctx, &ver);
125 assert_int_equal (r, TSS2_RC_SUCCESS);
126
127 *state = sys_ctx;
128
129 return 0;
130 }
131
132 static int
teardown(void ** state)133 teardown(void **state)
134 {
135 TSS2_SYS_CONTEXT *sys_ctx = (TSS2_SYS_CONTEXT *)*state;
136
137 if (sys_ctx)
138 free (sys_ctx);
139
140 return 0;
141 }
142
143 static void
test_resubmit(void ** state)144 test_resubmit(void **state)
145 {
146 TSS2_RC r = 0;
147 TSS2_SYS_CONTEXT *sys_ctx = (TSS2_SYS_CONTEXT *)*state;
148 int ctr = 0;
149
150 r = Tss2_Sys_GetRandom_Prepare(sys_ctx, 32);
151 assert_int_equal(r, TSS2_RC_SUCCESS);
152 do {
153 r = Tss2_Sys_Execute(sys_ctx);
154 } while (r == TPM2_RC_RETRY && ctr++ < 10);
155
156 assert_int_equal(r, TSS2_RC_SUCCESS);
157 assert_int_equal(ctr, NUM_OF_RETRIES);
158 return;
159 }
160
161 int
main(int argc,char * argv[])162 main(int argc, char *argv[])
163 {
164 const struct CMUnitTest tests[] = {
165 cmocka_unit_test_setup_teardown(test_resubmit, setup, teardown),
166 };
167 return cmocka_run_group_tests(tests, NULL, NULL);
168 }
169