cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cyberjack.c (11755B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 *  REINER SCT cyberJack pinpad/e-com USB Chipcard Reader Driver
      4 *
      5 *  Copyright (C) 2001  REINER SCT
      6 *  Author: Matthias Bruestle
      7 *
      8 *  Contact: support@reiner-sct.com (see MAINTAINERS)
      9 *
     10 *  This program is largely derived from work by the linux-usb group
     11 *  and associated source files.  Please see the usb/serial files for
     12 *  individual credits and copyrights.
     13 *
     14 *  Thanks to Greg Kroah-Hartman (greg@kroah.com) for his help and
     15 *  patience.
     16 *
     17 *  In case of problems, please write to the contact e-mail address
     18 *  mentioned above.
     19 *
     20 *  Please note that later models of the cyberjack reader family are
     21 *  supported by a libusb-based userspace device driver.
     22 *
     23 *  Homepage: http://www.reiner-sct.de/support/treiber_cyberjack.php#linux
     24 */
     25
     26
     27#include <linux/kernel.h>
     28#include <linux/errno.h>
     29#include <linux/slab.h>
     30#include <linux/tty.h>
     31#include <linux/tty_driver.h>
     32#include <linux/tty_flip.h>
     33#include <linux/module.h>
     34#include <linux/spinlock.h>
     35#include <linux/uaccess.h>
     36#include <linux/usb.h>
     37#include <linux/usb/serial.h>
     38
     39#define CYBERJACK_LOCAL_BUF_SIZE 32
     40
     41#define DRIVER_AUTHOR "Matthias Bruestle"
     42#define DRIVER_DESC "REINER SCT cyberJack pinpad/e-com USB Chipcard Reader Driver"
     43
     44
     45#define CYBERJACK_VENDOR_ID	0x0C4B
     46#define CYBERJACK_PRODUCT_ID	0x0100
     47
     48/* Function prototypes */
     49static int cyberjack_port_probe(struct usb_serial_port *port);
     50static void cyberjack_port_remove(struct usb_serial_port *port);
     51static int  cyberjack_open(struct tty_struct *tty,
     52	struct usb_serial_port *port);
     53static void cyberjack_close(struct usb_serial_port *port);
     54static int cyberjack_write(struct tty_struct *tty,
     55	struct usb_serial_port *port, const unsigned char *buf, int count);
     56static unsigned int cyberjack_write_room(struct tty_struct *tty);
     57static void cyberjack_read_int_callback(struct urb *urb);
     58static void cyberjack_read_bulk_callback(struct urb *urb);
     59static void cyberjack_write_bulk_callback(struct urb *urb);
     60
     61static const struct usb_device_id id_table[] = {
     62	{ USB_DEVICE(CYBERJACK_VENDOR_ID, CYBERJACK_PRODUCT_ID) },
     63	{ }			/* Terminating entry */
     64};
     65
     66MODULE_DEVICE_TABLE(usb, id_table);
     67
     68static struct usb_serial_driver cyberjack_device = {
     69	.driver = {
     70		.owner =	THIS_MODULE,
     71		.name =		"cyberjack",
     72	},
     73	.description =		"Reiner SCT Cyberjack USB card reader",
     74	.id_table =		id_table,
     75	.num_ports =		1,
     76	.num_bulk_out =		1,
     77	.port_probe =		cyberjack_port_probe,
     78	.port_remove =		cyberjack_port_remove,
     79	.open =			cyberjack_open,
     80	.close =		cyberjack_close,
     81	.write =		cyberjack_write,
     82	.write_room =		cyberjack_write_room,
     83	.read_int_callback =	cyberjack_read_int_callback,
     84	.read_bulk_callback =	cyberjack_read_bulk_callback,
     85	.write_bulk_callback =	cyberjack_write_bulk_callback,
     86};
     87
     88static struct usb_serial_driver * const serial_drivers[] = {
     89	&cyberjack_device, NULL
     90};
     91
     92struct cyberjack_private {
     93	spinlock_t	lock;		/* Lock for SMP */
     94	short		rdtodo;		/* Bytes still to read */
     95	unsigned char	wrbuf[5*64];	/* Buffer for collecting data to write */
     96	short		wrfilled;	/* Overall data size we already got */
     97	short		wrsent;		/* Data already sent */
     98};
     99
    100static int cyberjack_port_probe(struct usb_serial_port *port)
    101{
    102	struct cyberjack_private *priv;
    103	int result;
    104
    105	priv = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL);
    106	if (!priv)
    107		return -ENOMEM;
    108
    109	spin_lock_init(&priv->lock);
    110	priv->rdtodo = 0;
    111	priv->wrfilled = 0;
    112	priv->wrsent = 0;
    113
    114	usb_set_serial_port_data(port, priv);
    115
    116	result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
    117	if (result)
    118		dev_err(&port->dev, "usb_submit_urb(read int) failed\n");
    119
    120	return 0;
    121}
    122
    123static void cyberjack_port_remove(struct usb_serial_port *port)
    124{
    125	struct cyberjack_private *priv;
    126
    127	usb_kill_urb(port->interrupt_in_urb);
    128
    129	priv = usb_get_serial_port_data(port);
    130	kfree(priv);
    131}
    132
    133static int  cyberjack_open(struct tty_struct *tty,
    134					struct usb_serial_port *port)
    135{
    136	struct cyberjack_private *priv;
    137	unsigned long flags;
    138
    139	dev_dbg(&port->dev, "%s - usb_clear_halt\n", __func__);
    140	usb_clear_halt(port->serial->dev, port->write_urb->pipe);
    141
    142	priv = usb_get_serial_port_data(port);
    143	spin_lock_irqsave(&priv->lock, flags);
    144	priv->rdtodo = 0;
    145	priv->wrfilled = 0;
    146	priv->wrsent = 0;
    147	spin_unlock_irqrestore(&priv->lock, flags);
    148
    149	return 0;
    150}
    151
    152static void cyberjack_close(struct usb_serial_port *port)
    153{
    154	usb_kill_urb(port->write_urb);
    155	usb_kill_urb(port->read_urb);
    156}
    157
    158static int cyberjack_write(struct tty_struct *tty,
    159	struct usb_serial_port *port, const unsigned char *buf, int count)
    160{
    161	struct device *dev = &port->dev;
    162	struct cyberjack_private *priv = usb_get_serial_port_data(port);
    163	unsigned long flags;
    164	int result;
    165	int wrexpected;
    166
    167	if (count == 0) {
    168		dev_dbg(dev, "%s - write request of 0 bytes\n", __func__);
    169		return 0;
    170	}
    171
    172	if (!test_and_clear_bit(0, &port->write_urbs_free)) {
    173		dev_dbg(dev, "%s - already writing\n", __func__);
    174		return 0;
    175	}
    176
    177	spin_lock_irqsave(&priv->lock, flags);
    178
    179	if (count+priv->wrfilled > sizeof(priv->wrbuf)) {
    180		/* To much data for buffer. Reset buffer. */
    181		priv->wrfilled = 0;
    182		spin_unlock_irqrestore(&priv->lock, flags);
    183		set_bit(0, &port->write_urbs_free);
    184		return 0;
    185	}
    186
    187	/* Copy data */
    188	memcpy(priv->wrbuf + priv->wrfilled, buf, count);
    189
    190	usb_serial_debug_data(dev, __func__, count, priv->wrbuf + priv->wrfilled);
    191	priv->wrfilled += count;
    192
    193	if (priv->wrfilled >= 3) {
    194		wrexpected = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
    195		dev_dbg(dev, "%s - expected data: %d\n", __func__, wrexpected);
    196	} else
    197		wrexpected = sizeof(priv->wrbuf);
    198
    199	if (priv->wrfilled >= wrexpected) {
    200		/* We have enough data to begin transmission */
    201		int length;
    202
    203		dev_dbg(dev, "%s - transmitting data (frame 1)\n", __func__);
    204		length = (wrexpected > port->bulk_out_size) ?
    205					port->bulk_out_size : wrexpected;
    206
    207		memcpy(port->write_urb->transfer_buffer, priv->wrbuf, length);
    208		priv->wrsent = length;
    209
    210		/* set up our urb */
    211		port->write_urb->transfer_buffer_length = length;
    212
    213		/* send the data out the bulk port */
    214		result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
    215		if (result) {
    216			dev_err(&port->dev,
    217				"%s - failed submitting write urb, error %d\n",
    218				__func__, result);
    219			/* Throw away data. No better idea what to do with it. */
    220			priv->wrfilled = 0;
    221			priv->wrsent = 0;
    222			spin_unlock_irqrestore(&priv->lock, flags);
    223			set_bit(0, &port->write_urbs_free);
    224			return 0;
    225		}
    226
    227		dev_dbg(dev, "%s - priv->wrsent=%d\n", __func__, priv->wrsent);
    228		dev_dbg(dev, "%s - priv->wrfilled=%d\n", __func__, priv->wrfilled);
    229
    230		if (priv->wrsent >= priv->wrfilled) {
    231			dev_dbg(dev, "%s - buffer cleaned\n", __func__);
    232			memset(priv->wrbuf, 0, sizeof(priv->wrbuf));
    233			priv->wrfilled = 0;
    234			priv->wrsent = 0;
    235		}
    236	}
    237
    238	spin_unlock_irqrestore(&priv->lock, flags);
    239
    240	return count;
    241}
    242
    243static unsigned int cyberjack_write_room(struct tty_struct *tty)
    244{
    245	/* FIXME: .... */
    246	return CYBERJACK_LOCAL_BUF_SIZE;
    247}
    248
    249static void cyberjack_read_int_callback(struct urb *urb)
    250{
    251	struct usb_serial_port *port = urb->context;
    252	struct cyberjack_private *priv = usb_get_serial_port_data(port);
    253	struct device *dev = &port->dev;
    254	unsigned char *data = urb->transfer_buffer;
    255	int status = urb->status;
    256	unsigned long flags;
    257	int result;
    258
    259	/* the urb might have been killed. */
    260	if (status)
    261		return;
    262
    263	usb_serial_debug_data(dev, __func__, urb->actual_length, data);
    264
    265	/* React only to interrupts signaling a bulk_in transfer */
    266	if (urb->actual_length == 4 && data[0] == 0x01) {
    267		short old_rdtodo;
    268
    269		/* This is a announcement of coming bulk_ins. */
    270		unsigned short size = ((unsigned short)data[3]<<8)+data[2]+3;
    271
    272		spin_lock_irqsave(&priv->lock, flags);
    273
    274		old_rdtodo = priv->rdtodo;
    275
    276		if (old_rdtodo > SHRT_MAX - size) {
    277			dev_dbg(dev, "Too many bulk_in urbs to do.\n");
    278			spin_unlock_irqrestore(&priv->lock, flags);
    279			goto resubmit;
    280		}
    281
    282		/* "+=" is probably more fault tolerant than "=" */
    283		priv->rdtodo += size;
    284
    285		dev_dbg(dev, "%s - rdtodo: %d\n", __func__, priv->rdtodo);
    286
    287		spin_unlock_irqrestore(&priv->lock, flags);
    288
    289		if (!old_rdtodo) {
    290			result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
    291			if (result)
    292				dev_err(dev, "%s - failed resubmitting read urb, error %d\n",
    293					__func__, result);
    294			dev_dbg(dev, "%s - usb_submit_urb(read urb)\n", __func__);
    295		}
    296	}
    297
    298resubmit:
    299	result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
    300	if (result)
    301		dev_err(&port->dev, "usb_submit_urb(read int) failed\n");
    302	dev_dbg(dev, "%s - usb_submit_urb(int urb)\n", __func__);
    303}
    304
    305static void cyberjack_read_bulk_callback(struct urb *urb)
    306{
    307	struct usb_serial_port *port = urb->context;
    308	struct cyberjack_private *priv = usb_get_serial_port_data(port);
    309	struct device *dev = &port->dev;
    310	unsigned char *data = urb->transfer_buffer;
    311	unsigned long flags;
    312	short todo;
    313	int result;
    314	int status = urb->status;
    315
    316	usb_serial_debug_data(dev, __func__, urb->actual_length, data);
    317	if (status) {
    318		dev_dbg(dev, "%s - nonzero read bulk status received: %d\n",
    319			__func__, status);
    320		return;
    321	}
    322
    323	if (urb->actual_length) {
    324		tty_insert_flip_string(&port->port, data, urb->actual_length);
    325		tty_flip_buffer_push(&port->port);
    326	}
    327
    328	spin_lock_irqsave(&priv->lock, flags);
    329
    330	/* Reduce urbs to do by one. */
    331	priv->rdtodo -= urb->actual_length;
    332	/* Just to be sure */
    333	if (priv->rdtodo < 0)
    334		priv->rdtodo = 0;
    335	todo = priv->rdtodo;
    336
    337	spin_unlock_irqrestore(&priv->lock, flags);
    338
    339	dev_dbg(dev, "%s - rdtodo: %d\n", __func__, todo);
    340
    341	/* Continue to read if we have still urbs to do. */
    342	if (todo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/) {
    343		result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
    344		if (result)
    345			dev_err(dev, "%s - failed resubmitting read urb, error %d\n",
    346				__func__, result);
    347		dev_dbg(dev, "%s - usb_submit_urb(read urb)\n", __func__);
    348	}
    349}
    350
    351static void cyberjack_write_bulk_callback(struct urb *urb)
    352{
    353	struct usb_serial_port *port = urb->context;
    354	struct cyberjack_private *priv = usb_get_serial_port_data(port);
    355	struct device *dev = &port->dev;
    356	int status = urb->status;
    357	unsigned long flags;
    358	bool resubmitted = false;
    359
    360	if (status) {
    361		dev_dbg(dev, "%s - nonzero write bulk status received: %d\n",
    362			__func__, status);
    363		set_bit(0, &port->write_urbs_free);
    364		return;
    365	}
    366
    367	spin_lock_irqsave(&priv->lock, flags);
    368
    369	/* only do something if we have more data to send */
    370	if (priv->wrfilled) {
    371		int length, blksize, result;
    372
    373		dev_dbg(dev, "%s - transmitting data (frame n)\n", __func__);
    374
    375		length = ((priv->wrfilled - priv->wrsent) > port->bulk_out_size) ?
    376			port->bulk_out_size : (priv->wrfilled - priv->wrsent);
    377
    378		memcpy(port->write_urb->transfer_buffer,
    379					priv->wrbuf + priv->wrsent, length);
    380		priv->wrsent += length;
    381
    382		/* set up our urb */
    383		port->write_urb->transfer_buffer_length = length;
    384
    385		/* send the data out the bulk port */
    386		result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
    387		if (result) {
    388			dev_err(dev, "%s - failed submitting write urb, error %d\n",
    389				__func__, result);
    390			/* Throw away data. No better idea what to do with it. */
    391			priv->wrfilled = 0;
    392			priv->wrsent = 0;
    393			goto exit;
    394		}
    395
    396		resubmitted = true;
    397
    398		dev_dbg(dev, "%s - priv->wrsent=%d\n", __func__, priv->wrsent);
    399		dev_dbg(dev, "%s - priv->wrfilled=%d\n", __func__, priv->wrfilled);
    400
    401		blksize = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
    402
    403		if (priv->wrsent >= priv->wrfilled ||
    404					priv->wrsent >= blksize) {
    405			dev_dbg(dev, "%s - buffer cleaned\n", __func__);
    406			memset(priv->wrbuf, 0, sizeof(priv->wrbuf));
    407			priv->wrfilled = 0;
    408			priv->wrsent = 0;
    409		}
    410	}
    411
    412exit:
    413	spin_unlock_irqrestore(&priv->lock, flags);
    414	if (!resubmitted)
    415		set_bit(0, &port->write_urbs_free);
    416	usb_serial_port_softint(port);
    417}
    418
    419module_usb_serial_driver(serial_drivers, id_table);
    420
    421MODULE_AUTHOR(DRIVER_AUTHOR);
    422MODULE_DESCRIPTION(DRIVER_DESC);
    423MODULE_LICENSE("GPL");