Coverage Report

Created: 2022-04-27 14:33

/libfido2/fuzz/pcsc.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2022 Yubico AB. All rights reserved.
3
 * Use of this source code is governed by a BSD-style
4
 * license that can be found in the LICENSE file.
5
 */
6
7
#include <assert.h>
8
#include <stdint.h>
9
#include <stdlib.h>
10
#include <string.h>
11
#include <stdio.h>
12
#include <winscard.h>
13
14
#include "mutator_aux.h"
15
16
static const struct blob *reader_list;
17
static int (*xread)(void *, u_char *, size_t, int);
18
static int (*xwrite)(void *, const u_char *, size_t);
19
static void (*xconsume)(const void *, size_t);
20
21
LONG __wrap_SCardEstablishContext(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT);
22
LONG __wrap_SCardListReaders(SCARDCONTEXT, LPCSTR, LPSTR, LPDWORD);
23
LONG __wrap_SCardReleaseContext(SCARDCONTEXT);
24
LONG __wrap_SCardConnect(SCARDCONTEXT, LPCSTR, DWORD, DWORD, LPSCARDHANDLE,
25
    LPDWORD);
26
LONG __wrap_SCardDisconnect(SCARDHANDLE, DWORD);
27
LONG __wrap_SCardTransmit(SCARDHANDLE, const SCARD_IO_REQUEST *, LPCBYTE,
28
    DWORD, SCARD_IO_REQUEST *, LPBYTE, LPDWORD);
29
30
LONG
31
__wrap_SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
32
    LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
33
6.98k
{
34
6.98k
        assert(dwScope == SCARD_SCOPE_SYSTEM);
35
0
        assert(pvReserved1 == NULL);
36
0
        assert(pvReserved2 == NULL);
37
38
0
        *phContext = 1;
39
40
6.98k
        if (uniform_random(400) < 1)
41
45
                return SCARD_E_NO_SERVICE;
42
6.93k
        if (uniform_random(400) < 1)
43
43
                return SCARD_E_NO_SMARTCARD;
44
6.89k
        if (uniform_random(400) < 1)
45
48
                return SCARD_E_NO_MEMORY;
46
6.84k
        if (uniform_random(400) < 1)
47
48
                *phContext = 0;
48
49
6.84k
        return SCARD_S_SUCCESS;
50
6.89k
}
51
52
LONG
53
__wrap_SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups,
54
    LPSTR mszReaders, LPDWORD pcchReaders)
55
3.89k
{
56
3.89k
        assert(hContext == 1);
57
0
        assert(mszGroups == NULL);
58
0
        assert(mszReaders != NULL);
59
0
        assert(pcchReaders != 0);
60
61
3.89k
        if (reader_list == NULL || uniform_random(400) < 1)
62
1.18k
                return SCARD_E_NO_READERS_AVAILABLE;
63
2.71k
        if (uniform_random(400) < 1)
64
12
                return SCARD_E_NO_MEMORY;
65
66
2.69k
        memcpy(mszReaders, reader_list->body, reader_list->len > *pcchReaders ?
67
2.66k
            *pcchReaders : reader_list->len);
68
2.69k
        *pcchReaders = (DWORD)reader_list->len; /* on purpose */
69
70
2.69k
        return SCARD_S_SUCCESS;
71
2.71k
}
72
73
LONG
74
__wrap_SCardReleaseContext(SCARDCONTEXT hContext)
75
6.93k
{
76
6.93k
        assert(hContext == 1);
77
78
6.93k
        return SCARD_S_SUCCESS;
79
6.93k
}
80
81
LONG
82
__wrap_SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
83
    DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
84
2.40k
{
85
2.40k
        uint32_t r;
86
87
2.40k
        assert(hContext == 1);
88
0
        xconsume(szReader, strlen(szReader) + 1);
89
2.40k
        assert(dwShareMode == SCARD_SHARE_SHARED);
90
0
        assert(dwPreferredProtocols == SCARD_PROTOCOL_ANY);
91
0
        assert(phCard != NULL);
92
0
        assert(pdwActiveProtocol != NULL);
93
94
2.40k
        if ((r = uniform_random(400)) < 1)
95
19
                return SCARD_E_UNEXPECTED;
96
97
2.38k
        *phCard = 1;
98
2.38k
        *pdwActiveProtocol = (r & 1) ? SCARD_PROTOCOL_T0 : SCARD_PROTOCOL_T1;
99
100
2.38k
        if (uniform_random(400) < 1)
101
21
                *pdwActiveProtocol = SCARD_PROTOCOL_RAW;
102
103
2.38k
        return SCARD_S_SUCCESS;
104
2.40k
}
105
106
LONG
107
__wrap_SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
108
2.38k
{
109
2.38k
        assert(hCard == 1);
110
0
        assert(dwDisposition == SCARD_LEAVE_CARD);
111
112
2.38k
        return SCARD_S_SUCCESS;
113
2.38k
}
114
115
extern void consume(const void *body, size_t len);
116
117
LONG
118
__wrap_SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
119
    LPCBYTE pbSendBuffer, DWORD cbSendLength, SCARD_IO_REQUEST *pioRecvPci,
120
    LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
121
1.03k
{
122
1.03k
        void *ioh = (void *)NFC_DEV_HANDLE;
123
1.03k
        int n;
124
125
1.03k
        assert(hCard == 1);
126
0
        xconsume(pioSendPci, sizeof(*pioSendPci));
127
1.03k
        xwrite(ioh, pbSendBuffer, cbSendLength);
128
1.03k
        assert(pioRecvPci == NULL);
129
130
1.03k
        if (uniform_random(400) < 1 ||
131
1.03k
            (n = xread(ioh, pbRecvBuffer, *pcbRecvLength, -1)) == -1)
132
15
                return SCARD_E_UNEXPECTED;
133
1.02k
        *pcbRecvLength = (DWORD)n;
134
135
1.02k
        return SCARD_S_SUCCESS;
136
1.03k
}
137
138
void
139
set_pcsc_parameters(const struct blob *reader_list_ptr)
140
970
{
141
970
        reader_list = reader_list_ptr;
142
970
}
143
144
void
145
set_pcsc_io_functions(int (*read_f)(void *, u_char *, size_t, int),
146
    int (*write_f)(void *, const u_char *, size_t),
147
    void (*consume_f)(const void *, size_t))
148
970
{
149
970
        xread = read_f;
150
970
        xwrite = write_f;
151
970
        xconsume = consume_f;
152
970
}