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