summaryrefslogtreecommitdiffstats
path: root/fuzz/pcsc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fuzz/pcsc.c')
-rw-r--r--fuzz/pcsc.c153
1 files changed, 153 insertions, 0 deletions
diff --git a/fuzz/pcsc.c b/fuzz/pcsc.c
new file mode 100644
index 0000000..f6a3e9b
--- /dev/null
+++ b/fuzz/pcsc.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2022 Yubico AB. All rights reserved.
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file.
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <winscard.h>
+
+#include "mutator_aux.h"
+
+static const struct blob *reader_list;
+static int (*xread)(void *, u_char *, size_t, int);
+static int (*xwrite)(void *, const u_char *, size_t);
+static void (*xconsume)(const void *, size_t);
+
+LONG __wrap_SCardEstablishContext(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT);
+LONG __wrap_SCardListReaders(SCARDCONTEXT, LPCSTR, LPSTR, LPDWORD);
+LONG __wrap_SCardReleaseContext(SCARDCONTEXT);
+LONG __wrap_SCardConnect(SCARDCONTEXT, LPCSTR, DWORD, DWORD, LPSCARDHANDLE,
+ LPDWORD);
+LONG __wrap_SCardDisconnect(SCARDHANDLE, DWORD);
+LONG __wrap_SCardTransmit(SCARDHANDLE, const SCARD_IO_REQUEST *, LPCBYTE,
+ DWORD, SCARD_IO_REQUEST *, LPBYTE, LPDWORD);
+
+LONG
+__wrap_SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
+ LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
+{
+ assert(dwScope == SCARD_SCOPE_SYSTEM);
+ assert(pvReserved1 == NULL);
+ assert(pvReserved2 == NULL);
+
+ *phContext = 1;
+
+ if (uniform_random(400) < 1)
+ return SCARD_E_NO_SERVICE;
+ if (uniform_random(400) < 1)
+ return SCARD_E_NO_SMARTCARD;
+ if (uniform_random(400) < 1)
+ return SCARD_E_NO_MEMORY;
+ if (uniform_random(400) < 1)
+ *phContext = 0;
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG
+__wrap_SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups,
+ LPSTR mszReaders, LPDWORD pcchReaders)
+{
+ assert(hContext == 1);
+ assert(mszGroups == NULL);
+ assert(mszReaders != NULL);
+ assert(pcchReaders != 0);
+
+ if (reader_list == NULL || uniform_random(400) < 1)
+ return SCARD_E_NO_READERS_AVAILABLE;
+ if (uniform_random(400) < 1)
+ return SCARD_E_NO_MEMORY;
+
+ memcpy(mszReaders, reader_list->body, reader_list->len > *pcchReaders ?
+ *pcchReaders : reader_list->len);
+ *pcchReaders = (DWORD)reader_list->len; /* on purpose */
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG
+__wrap_SCardReleaseContext(SCARDCONTEXT hContext)
+{
+ assert(hContext == 1);
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG
+__wrap_SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
+ DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
+{
+ uint32_t r;
+
+ assert(hContext == 1);
+ xconsume(szReader, strlen(szReader) + 1);
+ assert(dwShareMode == SCARD_SHARE_SHARED);
+ assert(dwPreferredProtocols == SCARD_PROTOCOL_ANY);
+ assert(phCard != NULL);
+ assert(pdwActiveProtocol != NULL);
+
+ if ((r = uniform_random(400)) < 1)
+ return SCARD_E_UNEXPECTED;
+
+ *phCard = 1;
+ *pdwActiveProtocol = (r & 1) ? SCARD_PROTOCOL_T0 : SCARD_PROTOCOL_T1;
+
+ if (uniform_random(400) < 1)
+ *pdwActiveProtocol = SCARD_PROTOCOL_RAW;
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG
+__wrap_SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
+{
+ assert(hCard == 1);
+ assert(dwDisposition == SCARD_LEAVE_CARD);
+
+ return SCARD_S_SUCCESS;
+}
+
+extern void consume(const void *body, size_t len);
+
+LONG
+__wrap_SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
+ LPCBYTE pbSendBuffer, DWORD cbSendLength, SCARD_IO_REQUEST *pioRecvPci,
+ LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
+{
+ void *ioh = (void *)NFC_DEV_HANDLE;
+ int n;
+
+ assert(hCard == 1);
+ xconsume(pioSendPci, sizeof(*pioSendPci));
+ xwrite(ioh, pbSendBuffer, cbSendLength);
+ assert(pioRecvPci == NULL);
+
+ if (uniform_random(400) < 1 ||
+ (n = xread(ioh, pbRecvBuffer, *pcbRecvLength, -1)) == -1)
+ return SCARD_E_UNEXPECTED;
+ *pcbRecvLength = (DWORD)n;
+
+ return SCARD_S_SUCCESS;
+}
+
+void
+set_pcsc_parameters(const struct blob *reader_list_ptr)
+{
+ reader_list = reader_list_ptr;
+}
+
+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))
+{
+ xread = read_f;
+ xwrite = write_f;
+ xconsume = consume_f;
+}