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