summaryrefslogtreecommitdiffstats
path: root/tests/fuzz.cc
blob: fe5b223fb13d127e2c7de97dc2148c2f0c2ff9df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>

#include <libtpms/tpm_types.h>
#include <libtpms/tpm_library.h>
#include <libtpms/tpm_error.h>
#include <libtpms/tpm_memory.h>
#include <libtpms/tpm_nvfilename.h>


static void die(const char *msg)
{
    fprintf(stderr, "%s", msg);
    assert(false);
}

static TPM_RESULT mytpm_io_init(void)
{
    return TPM_SUCCESS;
}

static TPM_RESULT mytpm_io_getlocality(TPM_MODIFIER_INDICATOR *locModif,
                                       uint32_t tpm_number)
{
    *locModif = 0;

    return TPM_SUCCESS;
}

static TPM_RESULT mytpm_io_getphysicalpresence(TPM_BOOL *phyPres,
                                               uint32_t tpm_number)
{
    *phyPres = FALSE;

    return TPM_SUCCESS;
}

static unsigned char *permall;
static uint32_t permall_length;

static TPM_RESULT mytpm_nvram_loaddata(unsigned char **data,
                                       uint32_t *length,
                                       uint32_t tpm_number,
                                       const char *name)
{
    if (!strcmp(name, TPM_PERMANENT_ALL_NAME)) {
        if (permall) {
            *data = NULL;
            assert(TPM_Malloc(data, permall_length) == TPM_SUCCESS);
            memcpy(*data, permall, permall_length);
            *length = permall_length;
            return TPM_SUCCESS;
        }
    }
    return TPM_RETRY;
}

static TPM_RESULT mytpm_nvram_storedata(const unsigned char *data,
                                        uint32_t length,
                                        uint32_t tpm_number,
                                        const char *name)
{
    if (!strcmp(name, TPM_PERMANENT_ALL_NAME)) {
        free(permall);
        permall = NULL;
        assert(TPM_Malloc(&permall, length) == TPM_SUCCESS);
        memcpy(permall, data, length);
        permall_length = length;
    }
    return TPM_SUCCESS;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
    unsigned char *rbuffer = NULL;
    uint32_t rlength;
    uint32_t rtotal = 0;
    TPM_RESULT res;
    unsigned char *vol_buffer = NULL;
    uint32_t vol_buffer_len;
    unsigned char *perm_buffer = NULL;
    uint32_t perm_buffer_len;
    unsigned char startup[] = {
        0x80, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x44, 0x00, 0x00
    };
    struct libtpms_callbacks cbs = {
        .sizeOfStruct               = sizeof(struct libtpms_callbacks),
        .tpm_nvram_init             = NULL,
        .tpm_nvram_loaddata         = mytpm_nvram_loaddata,
        .tpm_nvram_storedata        = mytpm_nvram_storedata,
        .tpm_nvram_deletename       = NULL,
        .tpm_io_init                = mytpm_io_init,
        .tpm_io_getlocality         = mytpm_io_getlocality,
        .tpm_io_getphysicalpresence = mytpm_io_getphysicalpresence,
    };
    res = TPMLIB_RegisterCallbacks(&cbs);
    if (res != TPM_SUCCESS)
        die("Could not register callbacks\n");

    res = TPMLIB_ChooseTPMVersion(TPMLIB_TPM_VERSION_2);
    if (res != TPM_SUCCESS)
        die("Could not choose the TPM version\n");

    res = TPMLIB_MainInit();
    if (res != TPM_SUCCESS)
        die("Error: TPMLIB_MainInit() failed\n");

    res = TPMLIB_Process(&rbuffer, &rlength, &rtotal, startup, sizeof(startup));
    if (res != TPM_SUCCESS)
        die("Error: TPMLIB_Process(Startup) failed\n");

    res = TPMLIB_Process(&rbuffer, &rlength, &rtotal, (unsigned char*)data, size);
    if (res != TPM_SUCCESS)
        die("Error: TPMLIB_Process(fuzz-command) failed\n");

    /* state suspend */
    res = TPMLIB_GetState(TPMLIB_STATE_VOLATILE, &vol_buffer, &vol_buffer_len);
    if (res != TPM_SUCCESS)
        die("Error: TPMLIB_GetState(TPMLIB_STATE_VOLATILE) failed\n");

    res = TPMLIB_GetState(TPMLIB_STATE_PERMANENT, &perm_buffer, &perm_buffer_len);
    if (res != TPM_SUCCESS)
        die("Error: TPMLIB_GetState(TPMLIB_STATE_PERMANENT) failed\n");

    TPMLIB_Terminate();

    /* state resume */
    res = TPMLIB_SetState(TPMLIB_STATE_PERMANENT, perm_buffer, perm_buffer_len);
    if (res != TPM_SUCCESS)
        die("Error: TPMLIB_SetState(TPMLIB_STATE_PERMANENT) failed\n");

    res = TPMLIB_SetState(TPMLIB_STATE_VOLATILE, vol_buffer, vol_buffer_len);
    if (res != TPM_SUCCESS)
        die("Error: TPMLIB_SetState(TPMLIB_STATE_VOLATILE) failed\n");

    res = TPMLIB_MainInit();
    if (res != TPM_SUCCESS)
        die("Error: TPMLIB_MainInit() to resume with the state failed\n");

    TPMLIB_Terminate();
    TPM_Free(rbuffer);
    TPM_Free(vol_buffer);
    TPM_Free(perm_buffer);
    TPM_Free(permall);
    permall = NULL;

    return 0;
}