From: "Golz, Wilhelm" <Wilhelm.Golz@secunet.com>
To: "qemu-devel@nongnu.org" <qemu-devel@nongnu.org>
Subject: [PATCH] add option for a multislot usb ccid device
Date: Thu, 31 Aug 2023 15:10:25 +0000 [thread overview]
Message-ID: <2685e8e4bc6f41bf80010c33cdb5c7bc@secunet.com> (raw)
Signed-off-by: Wilhelm Golz <wilhelm.golz@secunet.com>
hw/usb/dev-smartcard-reader.c:
add option for a multislot usb ccid device, similar to audio multi.
---
hw/usb/dev-smartcard-reader.c | 106 +++++++++++++++++++++++++++++++++-
1 file changed, 103 insertions(+), 3 deletions(-)
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-
reader.c
index be0a4fc3bc..30d8892b4e 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -90,10 +90,13 @@ OBJECT_DECLARE_SIMPLE_TYPE(USBCCIDState,
USB_CCID_DEV)
* usbccid.sys (winxp, others untested) is a class driver so it
doesn't care.
* linux has a number of class drivers, but openct filters based on
* vendor/product (/etc/openct.conf under fedora), hence Gemplus.
+ * Use a Omnikey/HID 3121 with multislot for distinction.
*/
#define CCID_VENDOR_ID 0x08e6
#define CCID_PRODUCT_ID 0x4433
#define CCID_DEVICE_VERSION 0x0000
+#define CCID_VENDOR_ID_MULTI 0x076b
+#define CCID_PRODUCT_ID_MULTI 0x3021
/*
* BULK_OUT messages from PC to Reader
@@ -312,7 +315,9 @@ struct USBCCIDState {
uint8_t bmSlotICCState;
uint8_t powered;
uint8_t notify_slot_change;
+ /* properties */
uint8_t debug;
+ bool multi;
};
/*
@@ -411,6 +416,34 @@ static const uint8_t qemu_ccid_descriptor[] = {
0x01, /* u8 bMaxCCIDBusySlots; */
};
+static const uint8_t qemu_ccid_descriptor_multi[] = {
+ /* Smart Card Device Class Descriptor */
+ 0x36, /* u8 bLength; */
+ 0x21, /* u8 bDescriptorType; Functional */
+ 0x10, 0x01, /* u16 bcdCCID; CCID Specification Release Number.
*/
+ 0x0e, /* u8 bMaxSlotIndex; 14, as 16 slots can cause
trouble. */
+ 0x07, /* u8 bVoltageSupport; 01h - 5.0v, 02h - 3.0, 03
- 1.8 */
+
+ 0x01, 0x00, /* u32 dwProtocols; RRRR PPPP. RRRR = 0000h.*/
+ 0x00, 0x00, /* PPPP: see above */
+ 0xa0, 0x0f, 0x00, 0x00, /* u32 dwMaximumClock; */
+ 0x00, 0x00, 0x01, 0x00,
+ 0x00, /* u8 bNumClockSupported; see above */
+ 0x80, 0x25, 0x00, 0x00, /* u32 dwMaxDataRate ; see above */
+ 0x00, 0xC2, 0x01, 0x00,
+ 0x00, /* u8 bNumDataRatesSupported; see above */
+ 0xfe, 0x00, 0x00, 0x00, /* u32 dwMaxIFSD; see above */
+ 0x00, 0x00, 0x00, 0x00, /* u32 dwSyncProtocols; see above */
+ 0x00, 0x00, 0x00, 0x00, /* u32 dwMechanical; see above */
+ 0xfe, 0x04, 0x04, 0x00, /* u32 dwFeatures; 400 for better
compat. */
+ 0x12, 0x00, 0x01, 0x00, /* u32 dwMaxCCIDMessageLength; see
above */
+ 0xFF, /* u8 bClassGetResponse; see above */
+ 0xFF, /* u8 bClassEnvelope; see above */
+ 0x00, 0x00, /* u16 wLcdLayout; see above */
+ 0x01, /* u8 bPINSupport; see above */
+ 0x0f, /* u8 bMaxCCIDBusySlots; modified from 1 */
+};
+
enum {
STR_MANUFACTURER = 1,
STR_PRODUCT,
@@ -457,6 +490,38 @@ static const USBDescIface desc_iface0 = {
}
};
+static const USBDescIface desc_iface0_multi = {
+ .bInterfaceNumber = 0,
+ .bNumEndpoints = 3,
+ .bInterfaceClass = USB_CLASS_CSCID,
+ .bInterfaceSubClass = USB_SUBCLASS_UNDEFINED,
+ .bInterfaceProtocol = 0x00,
+ .iInterface = STR_INTERFACE,
+ .ndesc = 1,
+ .descs = (USBDescOther[]) {
+ {
+ /* smartcard descriptor */
+ .data = qemu_ccid_descriptor_multi,
+ },
+ },
+ .eps = (USBDescEndpoint[]) {
+ {
+ .bEndpointAddress = USB_DIR_IN | CCID_INT_IN_EP,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .bInterval = 255,
+ .wMaxPacketSize = 64,
+ },{
+ .bEndpointAddress = USB_DIR_IN | CCID_BULK_IN_EP,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = 64,
+ },{
+ .bEndpointAddress = USB_DIR_OUT | CCID_BULK_OUT_EP,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = 64,
+ },
+ }
+};
+
static const USBDescDevice desc_device = {
.bcdUSB = 0x0110,
.bMaxPacketSize0 = 64,
@@ -474,6 +539,23 @@ static const USBDescDevice desc_device = {
},
};
+static const USBDescDevice desc_device_multi = {
+ .bcdUSB = 0x0110,
+ .bMaxPacketSize0 = 64,
+ .bNumConfigurations = 1,
+ .confs = (USBDescConfig[]) {
+ {
+ .bNumInterfaces = 1,
+ .bConfigurationValue = 1,
+ .bmAttributes = USB_CFG_ATT_ONE |
USB_CFG_ATT_SELFPOWER |
+ USB_CFG_ATT_WAKEUP,
+ .bMaxPower = 50,
+ .nif = 1,
+ .ifs = &desc_iface0_multi,
+ },
+ },
+};
+
static const USBDesc desc_ccid = {
.id = {
.idVendor = CCID_VENDOR_ID,
@@ -487,6 +569,19 @@ static const USBDesc desc_ccid = {
.str = desc_strings,
};
+static const USBDesc desc_ccid_multi = {
+ .id = {
+ .idVendor = CCID_VENDOR_ID_MULTI,
+ .idProduct = CCID_PRODUCT_ID_MULTI,
+ .bcdDevice = CCID_DEVICE_VERSION,
+ .iManufacturer = STR_MANUFACTURER,
+ .iProduct = STR_PRODUCT,
+ .iSerialNumber = STR_SERIALNUMBER,
+ },
+ .full = &desc_device_multi,
+ .str = desc_strings,
+};
+
static const uint8_t *ccid_card_get_atr(CCIDCardState *card, uint32_t
*len)
{
CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
@@ -1293,10 +1388,12 @@ static void ccid_card_realize(DeviceState
*qdev, Error **errp)
USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
USBCCIDState *s = USB_CCID_DEV(dev);
Error *local_err = NULL;
+ const USBDesc *desc = usb_device_get_usb_desc(dev);
+ uint8_t bMaxSlotIndex = desc->full->confs[0].ifs-
>descs[0].data[4];
- if (card->slot != 0) {
- error_setg(errp, "usb-ccid supports one slot, can't add %d",
- card->slot);
+ if (card->slot > bMaxSlotIndex) {
+ error_setg(errp, "usb-ccid supports %d slots, can't add %d",
+ bMaxSlotIndex + 1, card->slot);
return;
}
if (s->card != NULL) {
@@ -1317,6 +1414,8 @@ static void ccid_realize(USBDevice *dev, Error
**errp)
{
USBCCIDState *s = USB_CCID_DEV(dev);
+ dev->usb_desc = s->multi ? &desc_ccid_multi : &desc_ccid;
+
usb_desc_create_serial(dev);
usb_desc_init(dev);
qbus_init(&s->bus, sizeof(s->bus), TYPE_CCID_BUS, DEVICE(dev),
NULL);
@@ -1433,6 +1532,7 @@ static const VMStateDescription ccid_vmstate = {
static Property ccid_properties[] = {
DEFINE_PROP_UINT8("debug", USBCCIDState, debug, 0),
+ DEFINE_PROP_BOOL("multi", USBCCIDState, multi, false),
DEFINE_PROP_END_OF_LIST(),
};
--
2.34.1
--
Wilhelm Golz
Lead Expert Smartcard
Public Authorities Division
secunet Security Networks AG
Fon +49 201 5454-3513
Fax +49 201 5454-1321
Mobil +49 160 90164415
E-Mail: wilhelm.golz@secunet.com
next reply other threads:[~2023-08-31 21:51 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-31 15:10 Golz, Wilhelm [this message]
-- strict thread matches above, loose matches on Subject: below --
2023-03-14 0:59 [PATCH] add option for a multislot usb ccid device Ripke, Klaus
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2685e8e4bc6f41bf80010c33cdb5c7bc@secunet.com \
--to=wilhelm.golz@secunet.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).