Coverage Report

Created: 2025-12-03 06:13

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