Coverage Report

Created: 2025-03-01 02:43

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
#include <assert.h>
9
#include <stdint.h>
10
#include <stdlib.h>
11
#include <string.h>
12
#include <stdio.h>
13
#include <winscard.h>
14
15
#include "mutator_aux.h"
16
17
static const struct blob *reader_list;
18
static int (*xread)(void *, u_char *, size_t, int);
19
static int (*xwrite)(void *, const u_char *, size_t);
20
static void (*xconsume)(const void *, size_t);
21
22
LONG __wrap_SCardEstablishContext(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT);
23
LONG __wrap_SCardListReaders(SCARDCONTEXT, LPCSTR, LPSTR, LPDWORD);
24
LONG __wrap_SCardReleaseContext(SCARDCONTEXT);
25
LONG __wrap_SCardConnect(SCARDCONTEXT, LPCSTR, DWORD, DWORD, LPSCARDHANDLE,
26
    LPDWORD);
27
LONG __wrap_SCardDisconnect(SCARDHANDLE, DWORD);
28
LONG __wrap_SCardTransmit(SCARDHANDLE, const SCARD_IO_REQUEST *, LPCBYTE,
29
    DWORD, SCARD_IO_REQUEST *, LPBYTE, LPDWORD);
30
31
LONG
32
__wrap_SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
33
    LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
34
58.9k
{
35
58.9k
        assert(dwScope == SCARD_SCOPE_SYSTEM);
36
58.9k
        assert(pvReserved1 == NULL);
37
58.9k
        assert(pvReserved2 == NULL);
38
39
58.9k
        *phContext = 1;
40
41
58.9k
        if (uniform_random(400) < 1)
42
233
                return SCARD_E_NO_SERVICE;
43
58.6k
        if (uniform_random(400) < 1)
44
272
                return SCARD_E_NO_SMARTCARD;
45
58.4k
        if (uniform_random(400) < 1)
46
204
                return SCARD_E_NO_MEMORY;
47
58.2k
        if (uniform_random(400) < 1)
48
152
                *phContext = 0;
49
50
58.2k
        return SCARD_S_SUCCESS;
51
58.4k
}
52
53
LONG
54
__wrap_SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups,
55
    LPSTR mszReaders, LPDWORD pcchReaders)
56
35.4k
{
57
35.4k
        assert(hContext == 1);
58
35.4k
        assert(mszGroups == NULL);
59
35.4k
        assert(mszReaders != NULL);
60
35.4k
        assert(pcchReaders != 0);
61
62
35.4k
        if (reader_list == NULL || uniform_random(400) < 1)
63
5.96k
                return SCARD_E_NO_READERS_AVAILABLE;
64
29.4k
        if (uniform_random(400) < 1)
65
173
                return SCARD_E_NO_MEMORY;
66
67
29.2k
        memcpy(mszReaders, reader_list->body, reader_list->len > *pcchReaders ?
68
29.0k
            *pcchReaders : reader_list->len);
69
29.2k
        *pcchReaders = (DWORD)reader_list->len; /* on purpose */
70
71
29.2k
        return SCARD_S_SUCCESS;
72
29.4k
}
73
74
LONG
75
__wrap_SCardReleaseContext(SCARDCONTEXT hContext)
76
58.7k
{
77
58.7k
        assert(hContext == 1);
78
79
58.7k
        return SCARD_S_SUCCESS;
80
58.7k
}
81
82
LONG
83
__wrap_SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
84
    DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
85
40.7k
{
86
40.7k
        uint32_t r;
87
88
40.7k
        assert(hContext == 1);
89
40.7k
        xconsume(szReader, strlen(szReader) + 1);
90
40.7k
        assert(dwShareMode == SCARD_SHARE_SHARED);
91
40.7k
        assert(dwPreferredProtocols == SCARD_PROTOCOL_ANY);
92
40.7k
        assert(phCard != NULL);
93
40.7k
        assert(pdwActiveProtocol != NULL);
94
95
40.7k
        if ((r = uniform_random(400)) < 1)
96
146
                return SCARD_E_UNEXPECTED;
97
98
40.5k
        *phCard = 1;
99
40.5k
        *pdwActiveProtocol = (r & 1) ? SCARD_PROTOCOL_T0 : SCARD_PROTOCOL_T1;
100
101
40.5k
        if (uniform_random(400) < 1)
102
424
                *pdwActiveProtocol = SCARD_PROTOCOL_RAW;
103
104
40.5k
        return SCARD_S_SUCCESS;
105
40.7k
}
106
107
LONG
108
__wrap_SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
109
40.5k
{
110
40.5k
        assert(hCard == 1);
111
40.5k
        assert(dwDisposition == SCARD_LEAVE_CARD);
112
113
40.5k
        return SCARD_S_SUCCESS;
114
40.5k
}
115
116
extern void consume(const void *body, size_t len);
117
118
LONG
119
__wrap_SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
120
    LPCBYTE pbSendBuffer, DWORD cbSendLength, SCARD_IO_REQUEST *pioRecvPci,
121
    LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
122
21.1k
{
123
21.1k
        void *ioh = (void *)NFC_DEV_HANDLE;
124
21.1k
        int n;
125
126
21.1k
        assert(hCard == 1);
127
21.1k
        xconsume(pioSendPci, sizeof(*pioSendPci));
128
21.1k
        xwrite(ioh, pbSendBuffer, cbSendLength);
129
21.1k
        assert(pioRecvPci == NULL);
130
131
21.1k
        if (uniform_random(400) < 1 ||
132
21.1k
            (n = xread(ioh, pbRecvBuffer, *pcbRecvLength, -1)) == -1)
133
587
                return SCARD_E_UNEXPECTED;
134
20.5k
        *pcbRecvLength = (DWORD)n;
135
136
20.5k
        return SCARD_S_SUCCESS;
137
21.1k
}
138
139
void
140
set_pcsc_parameters(const struct blob *reader_list_ptr)
141
5.91k
{
142
5.91k
        reader_list = reader_list_ptr;
143
5.91k
}
144
145
void
146
set_pcsc_io_functions(int (*read_f)(void *, u_char *, size_t, int),
147
    int (*write_f)(void *, const u_char *, size_t),
148
    void (*consume_f)(const void *, size_t))
149
5.91k
{
150
5.91k
        xread = read_f;
151
5.91k
        xwrite = write_f;
152
5.91k
        xconsume = consume_f;
153
5.91k
}