[PATCH 22/27] hw/usb/dev-smartcard-reader: stop advertising PIN support

Marc-AndrĂ© Lureau <[email protected]> Wed, 05 Aug 2026 15:51:12 +0400
Newsgroups gmane.comp.emulators.qemu
Message-ID <[email protected]>
The CCID descriptor claims bPINSupport=1 (PIN Verification) but the
device does not implement it, returning CMD_NOT_SUPPORTED for Secure
commands. Stop advertising the capability by default, gated behind
an x-pin-support property for backward compatibility.

Fixes: 367071447ec5 ("usb-ccid: add CCID bus")
Signed-off-by: Marc-AndrĂ© Lureau <[email protected]>
---
 hw/core/machine.c             |  1 +
 hw/usb/dev-smartcard-reader.c | 12 +++++++++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 28842f53ae4f..790d947e28d1 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -52,6 +52,7 @@ GlobalProperty hw_compat_11_0[] = {
     { TYPE_ARM_SMMUV3, "oas", "44" },
     { "migration", "switchover-ack-legacy", "on" },
     { "usb-ccid", "x-accurate-message-length", "off" },
+    { "usb-ccid", "x-pin-support", "on" },
     { "usb-ccid", "x-migrate-pending-answers", "off" },
 };
 const size_t hw_compat_11_0_len = G_N_ELEMENTS(hw_compat_11_0);
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index 65ceed57541a..a973a0396bb3 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -328,6 +328,7 @@ struct USBCCIDState {
     bool accurate_message_length;
     bool migrate_pending_answers;
     bool pending_answers_loaded;
+    bool pin_support;
 };
 
 static uint32_t ccid_bulk_in_pending_num(USBCCIDState *s)
@@ -436,10 +437,14 @@ static uint8_t qemu_ccid_descriptor[] = {
                      * u16 wLcdLayout; XXYY Number of lines (XX) and chars per
                      * line for LCD display used for PIN entry. 0000 - no LCD
                      */
-        0x01,       /*
+                    /*
                      * u8  bPINSupport; 01h PIN Verification,
                      *                  02h PIN Modification
+                     *
+                     * Corrected to 0 when !x-pin-support
                      */
+#define CCID_DESC_OFFSET_B_PIN_SUPPORT 52
+        0x01,
         0x01,       /* u8  bMaxCCIDBusySlots; */
 };
 
@@ -1498,6 +1503,9 @@ static void ccid_realize(USBDevice *dev, Error **errp)
         stl_le_p(&qemu_ccid_descriptor[CCID_DESC_OFFSET_DW_MAX_MSG_LEN],
                  BULK_IN_BUF_SIZE);
     }
+    if (!s->pin_support) {
+        qemu_ccid_descriptor[CCID_DESC_OFFSET_B_PIN_SUPPORT] = 0;
+    }
     usb_desc_create_serial(dev);
     usb_desc_init(dev);
     qbus_init(&s->bus, sizeof(s->bus), TYPE_CCID_BUS, DEVICE(dev), NULL);
@@ -1692,6 +1700,8 @@ static const Property ccid_properties[] = {
     DEFINE_PROP_UINT8("debug", USBCCIDState, debug, 0),
     DEFINE_PROP_BOOL("x-accurate-message-length", USBCCIDState,
                      accurate_message_length, true),
+    DEFINE_PROP_BOOL("x-pin-support", USBCCIDState,
+                     pin_support, false),
     DEFINE_PROP_BOOL("x-migrate-pending-answers", USBCCIDState,
                      migrate_pending_answers, true),
 };

-- 
2.55.0