Coverage Report

Created: 2025-10-04 18:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/libfido2/fuzz/pcsc.c
Line
Count
Source
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
 * SPDX-License-Identifier: BSD-2-Clause
6
 */
7
8
#undef NDEBUG
9
10
#include <assert.h>
11
#include <stdint.h>
12
#include <stdlib.h>
13
#include <string.h>
14
#include <stdio.h>
15
#include <winscard.h>
16
17
#include "mutator_aux.h"
18
19
static const struct blob *reader_list;
20
static int (*xread)(void *, u_char *, size_t, int);
21
static int (*xwrite)(void *, const u_char *, size_t);
22
static void (*xconsume)(const void *, size_t);
23
24
LONG __wrap_SCardEstablishContext(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT);
25
LONG __wrap_SCardListReaders(SCARDCONTEXT, LPCSTR, LPSTR, LPDWORD);
26
LONG __wrap_SCardReleaseContext(SCARDCONTEXT);
27
LONG __wrap_SCardConnect(SCARDCONTEXT, LPCSTR, DWORD, DWORD, LPSCARDHANDLE,
28
    LPDWORD);
29
LONG __wrap_SCardDisconnect(SCARDHANDLE, DWORD);
30
LONG __wrap_SCardTransmit(SCARDHANDLE, const SCARD_IO_REQUEST *, LPCBYTE,
31
    DWORD, SCARD_IO_REQUEST *, LPBYTE, LPDWORD);
32
33
LONG
34
__wrap_SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
35
    LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
36
64.9k
{
37
64.9k
        assert(dwScope == SCARD_SCOPE_SYSTEM);
38
64.9k
        assert(pvReserved1 == NULL);
39
64.9k
        assert(pvReserved2 == NULL);
40
41
64.9k
        *phContext = 1;
42
43
64.9k
        if (uniform_random(400) < 1)
44
342
                return SCARD_E_NO_SERVICE;
45
64.5k
        if (uniform_random(400) < 1)
46
302
                return SCARD_E_NO_SMARTCARD;
47
64.2k
        if (uniform_random(400) < 1)
48
461
                return SCARD_E_NO_MEMORY;
49
63.8k
        if (uniform_random(400) < 1)
50
208
                *phContext = 0;
51
52
63.8k
        return SCARD_S_SUCCESS;
53
64.2k
}
54
55
LONG
56
__wrap_SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups,
57
    LPSTR mszReaders, LPDWORD pcchReaders)
58
30.7k
{
59
30.7k
        assert(hContext == 1);
60
30.7k
        assert(mszGroups == NULL);
61
30.7k
        assert(mszReaders != NULL);
62
30.7k
        assert(pcchReaders != 0);
63
64
30.7k
        if (reader_list == NULL || uniform_random(400) < 1)
65
6.90k
                return SCARD_E_NO_READERS_AVAILABLE;
66
23.8k
        if (uniform_random(400) < 1)
67
263
                return SCARD_E_NO_MEMORY;
68
69
23.5k
        memcpy(mszReaders, reader_list->body, reader_list->len > *pcchReaders ?
70
23.4k
            *pcchReaders : reader_list->len);
71
23.5k
        *pcchReaders = (DWORD)reader_list->len; /* on purpose */
72
73
23.5k
        return SCARD_S_SUCCESS;
74
23.8k
}
75
76
LONG
77
__wrap_SCardReleaseContext(SCARDCONTEXT hContext)
78
64.7k
{
79
64.7k
        assert(hContext == 1);
80
81
64.7k
        return SCARD_S_SUCCESS;
82
64.7k
}
83
84
LONG
85
__wrap_SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
86
    DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
87
29.0k
{
88
29.0k
        uint32_t r;
89
90
29.0k
        assert(hContext == 1);
91
29.0k
        xconsume(szReader, strlen(szReader) + 1);
92
29.0k
        assert(dwShareMode == SCARD_SHARE_SHARED);
93
29.0k
        assert(dwPreferredProtocols == SCARD_PROTOCOL_ANY);
94
29.0k
        assert(phCard != NULL);
95
29.0k
        assert(pdwActiveProtocol != NULL);
96
97
29.0k
        if ((r = uniform_random(400)) < 1)
98
177
                return SCARD_E_UNEXPECTED;
99
100
28.8k
        *phCard = 1;
101
28.8k
        *pdwActiveProtocol = (r & 1) ? SCARD_PROTOCOL_T0 : SCARD_PROTOCOL_T1;
102
103
28.8k
        if (uniform_random(400) < 1)
104
464
                *pdwActiveProtocol = SCARD_PROTOCOL_RAW;
105
106
28.8k
        return SCARD_S_SUCCESS;
107
29.0k
}
108
109
LONG
110
__wrap_SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
111
28.8k
{
112
28.8k
        assert(hCard == 1);
113
28.8k
        assert(dwDisposition == SCARD_LEAVE_CARD);
114
115
28.8k
        return SCARD_S_SUCCESS;
116
28.8k
}
117
118
extern void consume(const void *body, size_t len);
119
120
LONG
121
__wrap_SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
122
    LPCBYTE pbSendBuffer, DWORD cbSendLength, SCARD_IO_REQUEST *pioRecvPci,
123
    LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
124
14.3k
{
125
14.3k
        void *ioh = (void *)NFC_DEV_HANDLE;
126
14.3k
        int n;
127
128
14.3k
        assert(hCard == 1);
129
14.3k
        xconsume(pioSendPci, sizeof(*pioSendPci));
130
14.3k
        xwrite(ioh, pbSendBuffer, cbSendLength);
131
14.3k
        assert(pioRecvPci == NULL);
132
133
14.3k
        if (uniform_random(400) < 1 ||
134
14.3k
            (n = xread(ioh, pbRecvBuffer, *pcbRecvLength, -1)) == -1)
135
637
                return SCARD_E_UNEXPECTED;
136
13.6k
        *pcbRecvLength = (DWORD)n;
137
138
13.6k
        return SCARD_S_SUCCESS;
139
14.3k
}
140
141
void
142
set_pcsc_parameters(const struct blob *reader_list_ptr)
143
7.59k
{
144
7.59k
        reader_list = reader_list_ptr;
145
7.59k
}
146
147
void
148
set_pcsc_io_functions(int (*read_f)(void *, u_char *, size_t, int),
149
    int (*write_f)(void *, const u_char *, size_t),
150
    void (*consume_f)(const void *, size_t))
151
7.59k
{
152
7.59k
        xread = read_f;
153
7.59k
        xwrite = write_f;
154
7.59k
        xconsume = consume_f;
155
7.59k
}