• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2018 Intel Corporation
4  * All rights reserved.
5  */
6 
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10 
11 #include <limits.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <stdarg.h>
15 #include <sys/time.h>
16 #include <inttypes.h>
17 #include <unistd.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 
22 #include "tss2_mu.h"
23 #include "tss2_tcti_fuzzing.h"
24 
25 #include "tcti-fuzzing.h"
26 #include "tss2-tcti/tcti-common.h"
27 #include "util/key-value-parse.h"
28 #define LOGMODULE tcti
29 #include "util/log.h"
30 
31 /*
32  * Using the data and size fields of the fuzzing TCTI memcpy the data into the
33  * structures given via va_list. Caller will pass the sysContext and number of
34  * arguments that follow. Following the count of arguments caller should pass
35  * the sizeof the next argument, which shall be a pointer to the structure to be
36  * filled.
37  *
38  * Example:
39  *
40  *     TPMI_DH_OBJECT keyA = {0};
41  *     TPM2B_ECC_POINT inQsB = {0};
42  *     TPM2B_ECC_POINT inQeB = {0};
43  *     TPMI_ECC_KEY_EXCHANGE inScheme = {0};
44  *     UINT16 counter = {0};
45  *
46  *     ret = fuzz_fill (
47  *         sysContext,
48  *         10,
49  *         sizeof (keyA), &keyA,
50  *         sizeof (inQsB), &inQsB,
51  *         sizeof (inQeB), &inQeB,
52  *         sizeof (inScheme), &inScheme,
53  *         sizeof (counter), &counter
54  *     );
55  *     if (ret) {
56  *         ... handle failure
57  *     }
58  */
59 int
fuzz_fill(TSS2_SYS_CONTEXT * sysContext,size_t count,...)60 fuzz_fill (
61         TSS2_SYS_CONTEXT *sysContext,
62         size_t count,
63         ...)
64 {
65     va_list ap;
66     const uint8_t *data = NULL;
67     const uint8_t *pointer_into_data = NULL;
68     size_t size = 0U;
69     size_t i = 0U;
70     void *copy_into_type;
71     size_t copy_into_length = 0U;
72     size_t data_used = 0U;
73     _TSS2_SYS_CONTEXT_BLOB *ctx = NULL;
74     TSS2_TCTI_FUZZING_CONTEXT *tcti_fuzzing = NULL;
75 
76     ctx = syscontext_cast (sysContext);
77     tcti_fuzzing = tcti_fuzzing_context_cast (ctx->tctiContext);
78     data = tcti_fuzzing->data;
79     size = tcti_fuzzing->size;
80 
81     va_start (ap, count);
82 
83     for (i = 0U; i < (count / 2); ++i) {
84         copy_into_length = va_arg (ap, size_t);
85         copy_into_type = va_arg (ap, void *);
86         if (size > (data_used + copy_into_length)) {
87             pointer_into_data = &data[data_used];
88             data_used += copy_into_length;
89             memcpy (copy_into_type, pointer_into_data, copy_into_length);
90         }
91     }
92 
93     va_end (ap);
94 
95     return EXIT_SUCCESS;
96 }
97 
98 /*
99  * This function wraps the "up-cast" of the opaque TCTI context type to the
100  * type for the fuzzing TCTI context. The only safeguard we have to ensure this
101  * operation is possible is the magic number in the fuzzing TCTI context.
102  * If passed a NULL context, or the magic number check fails, this function
103  * will return NULL.
104  */
105 TSS2_TCTI_FUZZING_CONTEXT*
tcti_fuzzing_context_cast(TSS2_TCTI_CONTEXT * tcti_ctx)106 tcti_fuzzing_context_cast (TSS2_TCTI_CONTEXT *tcti_ctx)
107 {
108     if (tcti_ctx != NULL && TSS2_TCTI_MAGIC (tcti_ctx) == TCTI_FUZZING_MAGIC) {
109         return (TSS2_TCTI_FUZZING_CONTEXT*)tcti_ctx;
110     }
111     return NULL;
112 }
113 
114 /*
115  * This function down-casts the fuzzing TCTI context to the common context
116  * defined in the tcti-common module.
117  */
118 TSS2_TCTI_COMMON_CONTEXT*
tcti_fuzzing_down_cast(TSS2_TCTI_FUZZING_CONTEXT * tcti_fuzzing)119 tcti_fuzzing_down_cast (TSS2_TCTI_FUZZING_CONTEXT *tcti_fuzzing)
120 {
121     if (tcti_fuzzing == NULL) {
122         return NULL;
123     }
124     return &tcti_fuzzing->common;
125 }
126 
127 TSS2_RC
tcti_fuzzing_transmit(TSS2_TCTI_CONTEXT * tcti_ctx,size_t size,const uint8_t * cmd_buf)128 tcti_fuzzing_transmit (
129     TSS2_TCTI_CONTEXT *tcti_ctx,
130     size_t size,
131     const uint8_t *cmd_buf)
132 {
133     (void) tcti_ctx;
134     (void) size;
135     (void) cmd_buf;
136     ((TSS2_TCTI_FUZZING_CONTEXT*) tcti_ctx)->common.state = TCTI_STATE_RECEIVE;
137     return TSS2_RC_SUCCESS;
138 }
139 
140 TSS2_RC
tcti_fuzzing_cancel(TSS2_TCTI_CONTEXT * tcti_ctx)141 tcti_fuzzing_cancel (
142     TSS2_TCTI_CONTEXT *tcti_ctx)
143 {
144     (void) tcti_ctx;
145     return TSS2_RC_SUCCESS;
146 }
147 
148 TSS2_RC
tcti_fuzzing_set_locality(TSS2_TCTI_CONTEXT * tcti_ctx,uint8_t locality)149 tcti_fuzzing_set_locality (
150     TSS2_TCTI_CONTEXT *tcti_ctx,
151     uint8_t locality)
152 {
153     (void) tcti_ctx;
154     (void) locality;
155     return TSS2_RC_SUCCESS;
156 }
157 
158 TSS2_RC
tcti_fuzzing_get_poll_handles(TSS2_TCTI_CONTEXT * tcti_ctx,TSS2_TCTI_POLL_HANDLE * handles,size_t * num_handles)159 tcti_fuzzing_get_poll_handles (
160     TSS2_TCTI_CONTEXT *tcti_ctx,
161     TSS2_TCTI_POLL_HANDLE *handles,
162     size_t *num_handles)
163 {
164     (void)(tcti_ctx);
165     (void)(handles);
166     (void)(num_handles);
167     return TSS2_TCTI_RC_NOT_IMPLEMENTED;
168 }
169 
170 void
tcti_fuzzing_finalize(TSS2_TCTI_CONTEXT * tcti_ctx)171 tcti_fuzzing_finalize(
172     TSS2_TCTI_CONTEXT *tcti_ctx)
173 {
174     (void)(tcti_ctx);
175 }
176 
177 TSS2_RC
tcti_fuzzing_receive(TSS2_TCTI_CONTEXT * tcti_ctx,size_t * response_size,unsigned char * response_buffer,int32_t timeout)178 tcti_fuzzing_receive (
179     TSS2_TCTI_CONTEXT *tcti_ctx,
180     size_t *response_size,
181     unsigned char *response_buffer,
182     int32_t timeout)
183 {
184     TSS2_TCTI_FUZZING_CONTEXT *tcti_fuzzing = tcti_fuzzing_context_cast (tcti_ctx);
185     TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_fuzzing_down_cast (tcti_fuzzing);
186     TSS2_RC rc;
187 
188     rc = tcti_common_receive_checks (tcti_common, response_size);
189     if (rc != TSS2_RC_SUCCESS) {
190         return rc;
191     }
192     if (timeout != TSS2_TCTI_TIMEOUT_BLOCK) {
193         LOG_WARNING ("The underlying IPC mechanism does not support "
194                      "asynchronous I/O. The 'timeout' parameter must be "
195                      "TSS2_TCTI_TIMEOUT_BLOCK");
196         return TSS2_TCTI_RC_BAD_VALUE;
197     }
198     if (response_buffer == NULL) {
199         LOG_DEBUG ("Caller queried for size but linux kernel doesn't allow this. "
200                    "Returning 4k which is the max size for a response buffer.");
201         *response_size = tcti_fuzzing->size;
202         return TSS2_RC_SUCCESS;
203     }
204     if (*response_size < tcti_fuzzing->size) {
205         LOG_INFO ("Caller provided buffer that *may* not be large enough to "
206                   "hold the response buffer.");
207     }
208 
209     /* Receive the TPM response. */
210     *response_size = tcti_fuzzing->size;
211     tcti_common->header.size = 0;
212     tcti_common->state = TCTI_STATE_TRANSMIT;
213     memcpy(response_buffer, tcti_fuzzing->data, *response_size);
214 
215     return rc;
216 }
217 
218 void
tcti_fuzzing_init_context_data(TSS2_TCTI_COMMON_CONTEXT * tcti_common)219 tcti_fuzzing_init_context_data (
220     TSS2_TCTI_COMMON_CONTEXT *tcti_common)
221 {
222     TSS2_TCTI_MAGIC (tcti_common) = TCTI_FUZZING_MAGIC;
223     TSS2_TCTI_VERSION (tcti_common) = TCTI_VERSION;
224     TSS2_TCTI_TRANSMIT (tcti_common) = tcti_fuzzing_transmit;
225     TSS2_TCTI_RECEIVE (tcti_common) = tcti_fuzzing_receive;
226     TSS2_TCTI_FINALIZE (tcti_common) = tcti_fuzzing_finalize;
227     TSS2_TCTI_CANCEL (tcti_common) = tcti_fuzzing_cancel;
228     TSS2_TCTI_GET_POLL_HANDLES (tcti_common) = tcti_fuzzing_get_poll_handles;
229     TSS2_TCTI_SET_LOCALITY (tcti_common) = tcti_fuzzing_set_locality;
230     TSS2_TCTI_MAKE_STICKY (tcti_common) = tcti_make_sticky_not_implemented;
231     tcti_common->state = TCTI_STATE_TRANSMIT;
232     tcti_common->locality = 3;
233     memset (&tcti_common->header, 0, sizeof (tcti_common->header));
234 }
235 
236 /*
237  * This is an implementation of the standard TCTI initialization function for
238  * this module.
239  */
240 TSS2_RC
Tss2_Tcti_Fuzzing_Init(TSS2_TCTI_CONTEXT * tcti_ctx,size_t * size,const char * conf)241 Tss2_Tcti_Fuzzing_Init (
242     TSS2_TCTI_CONTEXT *tcti_ctx,
243     size_t *size,
244     const char *conf)
245 {
246     (void) conf;
247 
248     if (size == NULL) {
249         return TSS2_TCTI_RC_BAD_VALUE;
250     }
251     if (tcti_ctx == NULL) {
252         *size = sizeof (TSS2_TCTI_FUZZING_CONTEXT);
253         return TSS2_RC_SUCCESS;
254     }
255     if (*size != sizeof (TSS2_TCTI_FUZZING_CONTEXT)) {
256         return TSS2_TCTI_RC_BAD_VALUE;
257     }
258 
259     tcti_fuzzing_init_context_data (
260             &(((TSS2_TCTI_FUZZING_CONTEXT*) tcti_ctx)->common));
261 
262     return TSS2_RC_SUCCESS;
263 }
264 
265 /* public info structure */
266 const TSS2_TCTI_INFO tss2_tcti_info = {
267     .version = TCTI_VERSION,
268     .name = "tcti-fuzzing",
269     .description = "TCTI module for fuzzing the System API.",
270     .config_help = "Takes no configuration.",
271     .init = Tss2_Tcti_Fuzzing_Init,
272 };
273 
274 const TSS2_TCTI_INFO*
Tss2_Tcti_Info(void)275 Tss2_Tcti_Info (void)
276 {
277     return &tss2_tcti_info;
278 }
279