HID devices without numbered reports

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

HID devices without numbered reports

Damien Miller
Hi,

Some HID devices do not list any report IDs for communication, e.g. my
Yubikey5:

> uhidev0: iclass 3/0
> uhid0 at uhidev0: input=64, output=64, feature=0
> ugen0 at uhub0 port 2 configuration 1 "Yubico YubiKey FIDO+CCID" rev 2.00/5.12 addr 2

on Linux, these can be talked to by sending to report ID 0. This AFAIK
causes the write(2)'d data to be sent to the interrupt pipe.

Our uhid(4) devices already consider write(2) operations to be
equivalent to USB_SET_REPORT to the UHID_OUTPUT_REPORT, so we can't
use that. So this patch allows USB_SET_REPORT with ucr_report=0
to do something similar to what Linux does.

Caveat: this is literally my first attempt at writing USB code, and
I ended up futzing with the kernel.

Index: sys/dev/usb/uhidev.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uhidev.c,v
retrieving revision 1.76
diff -u -p -r1.76 uhidev.c
--- sys/dev/usb/uhidev.c 25 Aug 2018 18:32:05 -0000 1.76
+++ sys/dev/usb/uhidev.c 25 Oct 2019 03:17:19 -0000
@@ -903,6 +903,15 @@ uhidev_ioctl(struct uhidev *sc, u_long c
  case USB_SET_REPORT:
  re = (struct usb_ctl_report *)addr;
  switch (re->ucr_report) {
+ case 0:
+ /*
+ * unnumbered report; send to interrupt pipe using
+ * size from output report descriptor.
+ */
+ if (uhidev_write(sc->sc_parent,
+    re->ucr_data, sc->sc_osize) != 0)
+ return EIO;
+ break;
  case UHID_INPUT_REPORT:
  size = sc->sc_isize;
  break;

Is this a sensible approach? Is there something obvious that I missed?

-d

Reply | Threaded
Open this post in threaded view
|

Re: HID devices without numbered reports

Martin Pieuchot
On 25/10/19(Fri) 15:10, Damien Miller wrote:

> Some HID devices do not list any report IDs for communication, e.g. my
> Yubikey5:
>
> > uhidev0: iclass 3/0
> > uhid0 at uhidev0: input=64, output=64, feature=0
> > ugen0 at uhub0 port 2 configuration 1 "Yubico YubiKey FIDO+CCID" rev 2.00/5.12 addr 2
>
> on Linux, these can be talked to by sending to report ID 0. This AFAIK
> causes the write(2)'d data to be sent to the interrupt pipe.
>
> Our uhid(4) devices already consider write(2) operations to be
> equivalent to USB_SET_REPORT to the UHID_OUTPUT_REPORT, so we can't
> use that. So this patch allows USB_SET_REPORT with ucr_report=0
> to do something similar to what Linux does.

Submitting transfers from userland is currently only supported by the
ugen(4) driver on OpenBSD.  Because ugen(4) attaches itself to unclaimed
devices there is less possibility to crash the kernel by messing with
the state of the underlying USB device.

Did you consider using the ugen(4) driver to achieve what you want?

How are you trying to submit this transfer?  Are you using the libusb?

If we add write support for some devices, starting with uhid(4), could
we come up with a generic interface instead of hacking USB_SET_REPORT?
If you use the libusb it should be easy to issue an ioctl(2) on the
/dev/usb node corresponding to the root of the bus where your device is
connected.  So instead of opening /dev/ugenX we submit xfer to the bus
via /dev/usbX.

Adding some sort of write(2) support for uhid(4) should we easy.  Some
pipes opened in uhidev_open() are currently unused, some transfers are
also allocated for nothing.  I'd suggest that the process opening the
pipe should "claim" the interfaces that it opens.  That could be done
by storing a uid in usbd_iface_claimed() instead of a boolean.  Then
later when a write(2) or an ioctl(2) is issued for that particular
interface, we can check if the id matches the one of the interface.

> Caveat: this is literally my first attempt at writing USB code, and
> I ended up futzing with the kernel.

That's the way :o)

> Index: sys/dev/usb/uhidev.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/uhidev.c,v
> retrieving revision 1.76
> diff -u -p -r1.76 uhidev.c
> --- sys/dev/usb/uhidev.c 25 Aug 2018 18:32:05 -0000 1.76
> +++ sys/dev/usb/uhidev.c 25 Oct 2019 03:17:19 -0000
> @@ -903,6 +903,15 @@ uhidev_ioctl(struct uhidev *sc, u_long c
>   case USB_SET_REPORT:
>   re = (struct usb_ctl_report *)addr;
>   switch (re->ucr_report) {
> + case 0:
> + /*
> + * unnumbered report; send to interrupt pipe using
> + * size from output report descriptor.
> + */
> + if (uhidev_write(sc->sc_parent,
> +    re->ucr_data, sc->sc_osize) != 0)
> + return EIO;
> + break;
>   case UHID_INPUT_REPORT:
>   size = sc->sc_isize;
>   break;
>
> Is this a sensible approach? Is there something obvious that I missed?
>
> -d
>

Reply | Threaded
Open this post in threaded view
|

Re: HID devices without numbered reports

Patrick Wildt-3
In reply to this post by Damien Miller
On Fri, Oct 25, 2019 at 03:10:48PM +1100, Damien Miller wrote:

> Hi,
>
> Some HID devices do not list any report IDs for communication, e.g. my
> Yubikey5:
>
> > uhidev0: iclass 3/0
> > uhid0 at uhidev0: input=64, output=64, feature=0
> > ugen0 at uhub0 port 2 configuration 1 "Yubico YubiKey FIDO+CCID" rev 2.00/5.12 addr 2
>
> on Linux, these can be talked to by sending to report ID 0. This AFAIK
> causes the write(2)'d data to be sent to the interrupt pipe.
>
> Our uhid(4) devices already consider write(2) operations to be
> equivalent to USB_SET_REPORT to the UHID_OUTPUT_REPORT, so we can't
> use that. So this patch allows USB_SET_REPORT with ucr_report=0
> to do something similar to what Linux does.
>
> Caveat: this is literally my first attempt at writing USB code, and
> I ended up futzing with the kernel.

So from what I understood the Yubikey expects the transfer to happen
on the Interrupt OUT pipe instead of doing a control transfer.  Read-
ing some code and documentation, it looks like that we should by de-
fault send our reports on the interrupt pipe, and only if it does not
exist fall back to control transfers.  Linux seems to do exactly that.

I tried to come up with the following diff, which appeard to make a
test program work for me.  Though I'm not sure I got all the specifics
right.

Can you give this a go with your test progam?

Patrick

diff --git a/sys/dev/usb/uhidev.c b/sys/dev/usb/uhidev.c
index 7c02c82f7d5..6f30f11855c 100644
--- a/sys/dev/usb/uhidev.c
+++ b/sys/dev/usb/uhidev.c
@@ -97,6 +97,7 @@ int uhidev_detach(struct device *, int);
 int uhidev_activate(struct device *, int);
 
 void uhidev_get_report_async_cb(struct usbd_xfer *, void *, usbd_status);
+void uhidev_set_report_async_cb(struct usbd_xfer *, void *, usbd_status);
 
 struct cfdriver uhidev_cd = {
  NULL, "uhidev", DV_DULL
@@ -670,14 +671,23 @@ uhidev_set_report(struct uhidev_softc *sc, int type, int id, void *data,
  memcpy(buf + 1, data, len - 1);
  }
 
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_REPORT;
- USETW2(req.wValue, type, id);
- USETW(req.wIndex, sc->sc_ifaceno);
- USETW(req.wLength, len);
+ if (sc->sc_opipe != NULL) {
+ usbd_setup_xfer(sc->sc_owxfer, sc->sc_opipe, 0, buf, len,
+    USBD_SYNCHRONOUS | USBD_CATCH, 0, NULL);
+ if (usbd_transfer(sc->sc_owxfer)) {
+ usbd_clear_endpoint_stall(sc->sc_opipe);
+ actlen = -1;
+ }
+ } else {
+ req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
+ req.bRequest = UR_SET_REPORT;
+ USETW2(req.wValue, type, id);
+ USETW(req.wIndex, sc->sc_ifaceno);
+ USETW(req.wLength, len);
 
- if (usbd_do_request(sc->sc_udev, &req, buf))
- actlen = -1;
+ if (usbd_do_request(sc->sc_udev, &req, buf))
+ actlen = -1;
+ }
 
  if (id > 0)
  free(buf, M_TEMP, len);
@@ -685,6 +695,16 @@ uhidev_set_report(struct uhidev_softc *sc, int type, int id, void *data,
  return (actlen);
 }
 
+void
+uhidev_set_report_async_cb(struct usbd_xfer *xfer, void *priv, usbd_status err)
+{
+ struct uhidev_softc *sc = priv;
+
+ if (err == USBD_STALLED)
+ usbd_clear_endpoint_stall_async(sc->sc_opipe);
+ usbd_free_xfer(xfer);
+}
+
 int
 uhidev_set_report_async(struct uhidev_softc *sc, int type, int id, void *data,
     int len)
@@ -715,11 +735,21 @@ uhidev_set_report_async(struct uhidev_softc *sc, int type, int id, void *data,
  memcpy(buf, data, len);
  }
 
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_REPORT;
- USETW2(req.wValue, type, id);
- USETW(req.wIndex, sc->sc_ifaceno);
- USETW(req.wLength, len);
+ if (sc->sc_opipe != NULL) {
+ usbd_setup_xfer(xfer, sc->sc_opipe, sc, buf, len,
+    USBD_NO_COPY, USBD_DEFAULT_TIMEOUT,
+    uhidev_set_report_async_cb);
+ if (usbd_transfer(xfer)) {
+ usbd_clear_endpoint_stall(sc->sc_opipe);
+ actlen = -1;
+ }
+ } else {
+ req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
+ req.bRequest = UR_SET_REPORT;
+ USETW2(req.wValue, type, id);
+ USETW(req.wIndex, sc->sc_ifaceno);
+ USETW(req.wLength, len);
+ }
 
  if (usbd_request_async(xfer, &req, NULL, NULL))
  actlen = -1;

Reply | Threaded
Open this post in threaded view
|

Re: HID devices without numbered reports

Patrick Wildt-3
On Fri, Oct 25, 2019 at 03:59:25PM +0200, Patrick Wildt wrote:

> On Fri, Oct 25, 2019 at 03:10:48PM +1100, Damien Miller wrote:
> > Hi,
> >
> > Some HID devices do not list any report IDs for communication, e.g. my
> > Yubikey5:
> >
> > > uhidev0: iclass 3/0
> > > uhid0 at uhidev0: input=64, output=64, feature=0
> > > ugen0 at uhub0 port 2 configuration 1 "Yubico YubiKey FIDO+CCID" rev 2.00/5.12 addr 2
> >
> > on Linux, these can be talked to by sending to report ID 0. This AFAIK
> > causes the write(2)'d data to be sent to the interrupt pipe.
> >
> > Our uhid(4) devices already consider write(2) operations to be
> > equivalent to USB_SET_REPORT to the UHID_OUTPUT_REPORT, so we can't
> > use that. So this patch allows USB_SET_REPORT with ucr_report=0
> > to do something similar to what Linux does.
> >
> > Caveat: this is literally my first attempt at writing USB code, and
> > I ended up futzing with the kernel.
>
> So from what I understood the Yubikey expects the transfer to happen
> on the Interrupt OUT pipe instead of doing a control transfer.  Read-
> ing some code and documentation, it looks like that we should by de-
> fault send our reports on the interrupt pipe, and only if it does not
> exist fall back to control transfers.  Linux seems to do exactly that.
>
> I tried to come up with the following diff, which appeard to make a
> test program work for me.  Though I'm not sure I got all the specifics
> right.
>
> Can you give this a go with your test progam?
>
> Patrick

Oops, obvious error.  Though I still cannot write/read multiple times
in a row, so there is probably still something wrong (unless my test
is as well).

diff --git a/sys/dev/usb/uhidev.c b/sys/dev/usb/uhidev.c
index 7c02c82f7d5..73de7aeaf56 100644
--- a/sys/dev/usb/uhidev.c
+++ b/sys/dev/usb/uhidev.c
@@ -97,6 +97,7 @@ int uhidev_detach(struct device *, int);
 int uhidev_activate(struct device *, int);
 
 void uhidev_get_report_async_cb(struct usbd_xfer *, void *, usbd_status);
+void uhidev_set_report_async_cb(struct usbd_xfer *, void *, usbd_status);
 
 struct cfdriver uhidev_cd = {
  NULL, "uhidev", DV_DULL
@@ -670,14 +671,23 @@ uhidev_set_report(struct uhidev_softc *sc, int type, int id, void *data,
  memcpy(buf + 1, data, len - 1);
  }
 
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_REPORT;
- USETW2(req.wValue, type, id);
- USETW(req.wIndex, sc->sc_ifaceno);
- USETW(req.wLength, len);
+ if (sc->sc_opipe != NULL) {
+ usbd_setup_xfer(sc->sc_owxfer, sc->sc_opipe, 0, buf, len,
+    USBD_SYNCHRONOUS | USBD_CATCH, 0, NULL);
+ if (usbd_transfer(sc->sc_owxfer)) {
+ usbd_clear_endpoint_stall(sc->sc_opipe);
+ actlen = -1;
+ }
+ } else {
+ req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
+ req.bRequest = UR_SET_REPORT;
+ USETW2(req.wValue, type, id);
+ USETW(req.wIndex, sc->sc_ifaceno);
+ USETW(req.wLength, len);
 
- if (usbd_do_request(sc->sc_udev, &req, buf))
- actlen = -1;
+ if (usbd_do_request(sc->sc_udev, &req, buf))
+ actlen = -1;
+ }
 
  if (id > 0)
  free(buf, M_TEMP, len);
@@ -685,6 +695,16 @@ uhidev_set_report(struct uhidev_softc *sc, int type, int id, void *data,
  return (actlen);
 }
 
+void
+uhidev_set_report_async_cb(struct usbd_xfer *xfer, void *priv, usbd_status err)
+{
+ struct uhidev_softc *sc = priv;
+
+ if (err == USBD_STALLED)
+ usbd_clear_endpoint_stall_async(sc->sc_opipe);
+ usbd_free_xfer(xfer);
+}
+
 int
 uhidev_set_report_async(struct uhidev_softc *sc, int type, int id, void *data,
     int len)
@@ -715,14 +735,23 @@ uhidev_set_report_async(struct uhidev_softc *sc, int type, int id, void *data,
  memcpy(buf, data, len);
  }
 
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_REPORT;
- USETW2(req.wValue, type, id);
- USETW(req.wIndex, sc->sc_ifaceno);
- USETW(req.wLength, len);
-
- if (usbd_request_async(xfer, &req, NULL, NULL))
- actlen = -1;
+ if (sc->sc_opipe != NULL) {
+ usbd_setup_xfer(xfer, sc->sc_opipe, sc, buf, len,
+    USBD_NO_COPY, USBD_DEFAULT_TIMEOUT,
+    uhidev_set_report_async_cb);
+ if (usbd_transfer(xfer)) {
+ usbd_clear_endpoint_stall_async(sc->sc_opipe);
+ actlen = -1;
+ }
+ } else {
+ req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
+ req.bRequest = UR_SET_REPORT;
+ USETW2(req.wValue, type, id);
+ USETW(req.wIndex, sc->sc_ifaceno);
+ USETW(req.wLength, len);
+ if (usbd_request_async(xfer, &req, NULL, NULL))
+ actlen = -1;
+ }
 
  return (actlen);
 }

Reply | Threaded
Open this post in threaded view
|

Re: HID devices without numbered reports

Damien Miller
On Fri, 25 Oct 2019, Patrick Wildt wrote:

> > So from what I understood the Yubikey expects the transfer to happen
> > on the Interrupt OUT pipe instead of doing a control transfer.  Read-
> > ing some code and documentation, it looks like that we should by de-
> > fault send our reports on the interrupt pipe, and only if it does not
> > exist fall back to control transfers.  Linux seems to do exactly that.
> >
> > I tried to come up with the following diff, which appeard to make a
> > test program work for me.  Though I'm not sure I got all the specifics
> > right.
> >
> > Can you give this a go with your test progam?
> >
> > Patrick
>
> Oops, obvious error.  Though I still cannot write/read multiple times
> in a row, so there is probably still something wrong (unless my test
> is as well).

It didn't work for me - I think because uhidev_set_report() (and _async)
is still prepending a report ID. If I modify uhid.c to send writes
without a report ID, then it does work:

Index: uhid.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uhid.c,v
retrieving revision 1.71
diff -u -p -r1.71 uhid.c
--- uhid.c 1 May 2018 18:14:46 -0000 1.71
+++ uhid.c 27 Oct 2019 22:03:16 -0000
@@ -322,7 +322,7 @@ uhid_do_write(struct uhid_softc *sc, str
  error = uiomove(sc->sc_obuf, size, uio);
  if (!error) {
  if (uhidev_set_report(sc->sc_hdev.sc_parent,
-    UHID_OUTPUT_REPORT, sc->sc_hdev.sc_report_id, sc->sc_obuf,
+    0, sc->sc_hdev.sc_report_id, sc->sc_obuf,
     size) != size)
  error = EIO;
  }

I don't think this is optimal though - perhaps we should do something
like Linux: if the endpoint has an output report then use it, and fall
back to not prepending a report ID otherwise. This should be compatible
with current devices too (well, at least it shouldn't break any that
aren't already broken.)

(again, caveat - I don't know much about USB programming).

-d

Reply | Threaded
Open this post in threaded view
|

Re: HID devices without numbered reports

Damien Miller
On Mon, 28 Oct 2019, Damien Miller wrote:

> On Fri, 25 Oct 2019, Patrick Wildt wrote:
>
> > > So from what I understood the Yubikey expects the transfer to happen
> > > on the Interrupt OUT pipe instead of doing a control transfer.  Read-
> > > ing some code and documentation, it looks like that we should by de-
> > > fault send our reports on the interrupt pipe, and only if it does not
> > > exist fall back to control transfers.  Linux seems to do exactly that.
> > >
> > > I tried to come up with the following diff, which appeard to make a
> > > test program work for me.  Though I'm not sure I got all the specifics
> > > right.
> > >
> > > Can you give this a go with your test progam?
> > >
> > > Patrick
> >
> > Oops, obvious error.  Though I still cannot write/read multiple times
> > in a row, so there is probably still something wrong (unless my test
> > is as well).
>
> It didn't work for me - I think because uhidev_set_report() (and _async)
> is still prepending a report ID. If I modify uhid.c to send writes
> without a report ID, then it does work:

BTW, the token still becomes unresponsive after the first transaction,
but looking at a sniff (using an OpenViszla), it seems we're getting the
DATA0/DATA1 flipping incorrect on the wire.

On OpenBSD, this is the last rx of the transaction with the card:

[        ]  12.992349 d=  0.001951 [154.0 +  3.500] [  3] IN   : 8.4
[        ]  12.992352 d=  0.000003 [154.0 +  6.667] [ 67] DATA0: 00 10 00 01 0e 1b 4a 78 ec 87 06 bd 47 d4 a0 49 d9 c7 2d 89 d9 7e 2c c5 62 87 53 92 9b 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3a e8

and this is the first tx of the first packet of the subsequent transaction
that hangs:

[        ]  22.201067 d=  0.001998 [146.0 +  4.333] [  3] OUT  : 8.4
[        ]  22.201070 d=  0.000003 [146.0 +  7.583] [ 67] DATA0: ff ff ff ff 86 00 08 c0 65 eb 53 9a 48 04 7d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d6 1d

On Linux, the sequence bit does get flipped between the last rx:

[        ]  14.174783 d=  0.001951 [214.0 +  3.417] [  3] IN   : 24.4
[        ]  14.174786 d=  0.000003 [214.0 +  6.583] [ 67] DATA0: 00 12 00 01 0e 2e 25 14 32 f4 a4 68 d1 81 d1 29 e1 47 6f 4c 7d e2 69 dc b9 96 e5 f5 23 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 be 67

and the tx of the next attempt:

[        ]  20.057155 d=  0.001997 [208.0 +  3.417] [  3] OUT  : 24.4
[        ]  20.057158 d=  0.000003 [208.0 +  6.667] [ 67] DATA1: ff ff ff ff 86 00 08 82 40 e5 bf c6 94 7e e8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 8b

I think it's losing the sequence bit state across open/close of
/dev/uhidX - If I try to do two transactions without an intervening
close/open then it seems to work...

-d

Reply | Threaded
Open this post in threaded view
|

Re: HID devices without numbered reports

Damien Miller
On Mon, 28 Oct 2019, Damien Miller wrote:

> BTW, the token still becomes unresponsive after the first transaction,
> but looking at a sniff (using an OpenViszla), it seems we're getting the
> DATA0/DATA1 flipping incorrect on the wire.
>
> On OpenBSD, this is the last rx of the transaction with the card:
>
> [        ]  12.992349 d=  0.001951 [154.0 +  3.500] [  3] IN   : 8.4
> [        ]  12.992352 d=  0.000003 [154.0 +  6.667] [ 67] DATA0: 00 10 00 01 0e 1b 4a 78 ec 87 06 bd 47 d4 a0 49 d9 c7 2d 89 d9 7e 2c c5 62 87 53 92 9b 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3a e8
>
> and this is the first tx of the first packet of the subsequent transaction
> that hangs:
>
> [        ]  22.201067 d=  0.001998 [146.0 +  4.333] [  3] OUT  : 8.4
> [        ]  22.201070 d=  0.000003 [146.0 +  7.583] [ 67] DATA0: ff ff ff ff 86 00 08 c0 65 eb 53 9a 48 04 7d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d6 1d

Since I don't really understand how USB sequence numbers work, it just
occurred to me to check the sequence bit on the last sent packet.
It too is a DATA0, so the sequence is definitiely getting lost across
close+open.

Here's an annotated trace - starting with the last command sent to
a Yk5 token during key enrollment:

[        ]   9.212345 d=  0.001992 [  2   +  4.333] [  3] OUT  : 10.4
[        ]   9.212349 d=  0.000003 [  2   +  7.583] [ 67] DATA1: 00 13 00 01 83 00 47 00 01 00 00 00 00 40 a9 dc 95 51 0e ec 44 6d 7a b1 14 88 d1 84 93 b4 aa d2 e5 10 11 db 9c fa b4 b3 0b 89 2c ea 3f b9 e3 06 10 e8 a1 62 11 59 60 fe 1e c2 23 e6 52 9c 9f 4b 8a c8
[        ]   9.212395 d=  0.000046 [  2   + 53.750] [  1] ACK
[        ]   9.212397 d=  0.000002 [  2   + 55.667] [  3] IN   : 10.4
[        ]   9.212400 d=  0.000003 [  2   + 58.833] [  1] NAK
[        ]   9.214346 d=  0.001946 [  4   +  4.500] [  3] OUT  : 10.4
[        ]   9.214349 d=  0.000003 [  4   +  7.750] [ 67] DATA0: 00 13 00 01 00 6e 80 20 0d cb 5e 5c 32 1c 8a f1 e2 b1 bf 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11 7c
[        ]   9.214395 d=  0.000046 [  4   + 53.750] [  1] ACK
[        ]   9.214397 d=  0.000002 [  4   + 55.667] [  3] IN   : 10.4
[        ]   9.214400 d=  0.000003 [  4   + 58.833] [  1] NAK
[        ]   9.216345 d=  0.001945 [  6   +  4.000] [  3] IN   : 10.4
[        ]   9.216349 d=  0.000003 [  6   +  7.167] [  1] NAK

Note that the last OUT was a DATA0.

The token replies with a bunch of data:

[        ]   9.350355 d=  0.001997 [140   +  3.250] [  3] IN   : 10.4
[        ]   9.350358 d=  0.000003 [140   +  6.417] [ 67] DATA1: 00 13 00 01 83 03 8d 05 04 f6 80 b1 df 4d 8e fe 30 cd a0 2c 42 e1 a1 46 52 9f 8a 06 80 21 78 7a 73 71 e3 f3 0a e6 f6 e0 74 54 ef df 0c 74 ed be 3f 35 1d dd 35 cf 33 14 fc 33 6e b6 45 11 bd f5 79 99
[        ]   9.350404 d=  0.000046 [140   + 52.417] [  1] ACK
[        ]   9.352356 d=  0.001951 [142   +  3.750] [  3] IN   : 10.4
[        ]   9.352359 d=  0.000003 [142   +  6.917] [ 67] DATA0: 00 13 00 01 00 61 98 66 2c 14 5f 65 e5 4c 40 df 01 56 e8 d8 2b e8 f7 a8 ff 00 96 a6 f3 95 00 d9 93 87 cb c8 b1 02 23 ec 8f 38 37 b8 cf da 73 62 18 90 ff 8b 01 cf a1 78 61 3e cc 48 ac 7b 45 4f b0 6b
[        ]   9.352405 d=  0.000046 [142   + 53.167] [  1] ACK
[        ]   9.354356 d=  0.001950 [144   +  3.500] [  3] IN   : 10.4
[        ]   9.354359 d=  0.000003 [144   +  6.667] [ 67] DATA1: 00 13 00 01 01 4a 0d 3a 6d d7 ca fc 00 e1 ad 7e 78 b1 9d 88 30 82 02 bd 30 82 01 a5 a0 03 02 01 02 02 04 18 ac 46 c0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 2e 31 2c 30 2a 06 03 55 04 83 af
[        ]   9.354405 d=  0.000046 [144   + 52.833] [  1] ACK
[        ]   9.356356 d=  0.001951 [146   +  3.583] [  3] IN   : 10.4
[        ]   9.356359 d=  0.000003 [146   +  6.750] [ 67] DATA0: 00 13 00 01 02 03 13 23 59 75 62 69 63 6f 20 55 32 46 20 52 6f 6f 74 20 43 41 20 53 65 72 69 61 6c 20 34 35 37 32 30 30 36 33 31 30 20 17 0d 31 34 30 38 30 31 30 30 30 30 30 30 5a 18 0f 32 30 98 68
[        ]   9.356405 d=  0.000046 [146   + 52.667] [  1] ACK
[        ]   9.358356 d=  0.001951 [148   +  3.583] [  3] IN   : 10.4
[        ]   9.358359 d=  0.000003 [148   +  6.750] [ 67] DATA1: 00 13 00 01 03 35 30 30 39 30 34 30 30 30 30 30 30 5a 30 6e 31 0b 30 09 06 03 55 04 06 13 02 53 45 31 12 30 10 06 03 55 04 0a 0c 09 59 75 62 69 63 6f 20 41 42 31 22 30 20 06 03 55 04 0b 0c 19 69 76
[        ]   9.358405 d=  0.000046 [148   + 52.667] [  1] ACK
[        ]   9.360357 d=  0.001952 [150   +  4.833] [  3] IN   : 10.4
[        ]   9.360361 d=  0.000003 [150   +  8.000] [ 67] DATA0: 00 13 00 01 04 41 75 74 68 65 6e 74 69 63 61 74 6f 72 20 41 74 74 65 73 74 61 74 69 6f 6e 31 27 30 25 06 03 55 04 03 0c 1e 59 75 62 69 63 6f 20 55 32 46 20 45 45 20 53 65 72 69 61 6c 20 34 31 4c 3a
[        ]   9.360406 d=  0.000046 [150   + 53.917] [  1] ACK
[        ]   9.362356 d=  0.001950 [152   +  3.500] [  3] IN   : 10.4
[        ]   9.362359 d=  0.000003 [152   +  6.667] [ 67] DATA1: 00 13 00 01 05 33 39 34 33 34 38 38 30 59 30 13 06 07 2a 86 48 ce 3d 02 01 06 08 2a 86 48 ce 3d 03 01 07 03 42 00 04 79 ea 3b 2c 7c 49 70 10 62 23 0c d2 3f eb 60 e5 29 31 71 d4 83 f1 00 be 85 94 5e
[        ]   9.362405 d=  0.000046 [152   + 52.750] [  1] ACK
[        ]   9.364356 d=  0.001951 [154   +  3.500] [  3] IN   : 10.4
[        ]   9.364360 d=  0.000003 [154   +  6.667] [ 67] DATA0: 00 13 00 01 06 9d 6b 0f 83 97 03 01 b5 46 cd d4 6e cf ca e3 e3 f3 0f 81 e9 ed 62 bd 26 8d 4c 1e bd 37 b3 bc be 92 a8 c2 ae eb 4e 3a a3 6c 30 6a 30 22 06 09 2b 06 01 04 01 82 c4 0a 02 04 15 31 34 85
[        ]   9.364406 d=  0.000046 [154   + 52.750] [  1] ACK
[        ]   9.366356 d=  0.001951 [156   +  3.500] [  3] IN   : 10.4
[        ]   9.366360 d=  0.000003 [156   +  6.667] [ 67] DATA1: 00 13 00 01 07 2e 33 2e 36 2e 31 2e 34 2e 31 2e 34 31 34 38 32 2e 31 2e 37 30 13 06 0b 2b 06 01 04 01 82 e5 1c 02 01 01 04 04 03 02 05 20 30 21 06 0b 2b 06 01 04 01 82 e5 1c 01 01 04 04 12 04 f8 38
[        ]   9.366406 d=  0.000046 [156   + 52.667] [  1] ACK
[        ]   9.368357 d=  0.001951 [158   +  3.500] [  3] IN   : 10.4
[        ]   9.368360 d=  0.000003 [158   +  6.667] [ 67] DATA0: 00 13 00 01 08 10 cb 69 48 1e 8f f7 40 39 93 ec 0a 27 29 a1 54 a8 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 82 01 01 00 97 9d 03 97 d8 60 f8 2e d8 dc
[        ]   9.368406 d=  0.000046 [158   + 52.833] [  1] ACK
[        ]   9.370357 d=  0.001951 [160   +  3.917] [  3] IN   : 10.4
[        ]   9.370360 d=  0.000003 [160   +  7.083] [ 67] DATA1: 00 13 00 01 09 e1 5d 31 1c 79 6e ba fb 22 fa a7 e0 84 d9 ba b4 c6 1b bb 57 f3 e6 b4 c1 8a 48 37 b8 5c 3c 4e db e4 83 43 f4 d6 a5 d9 b1 ce da 8a e1 fe d4 91 29 21 73 05 8e 5e e1 cb dd 6b da c0 59 fc
[        ]   9.370406 d=  0.000046 [160   + 53.250] [  1] ACK
[        ]   9.370408 d=  0.000002 [160   + 55.167] [  3] IN   : 10.3
[        ]   9.370412 d=  0.000003 [160   + 58.333] [  1] NAK
[        ]   9.372357 d=  0.001945 [162   +  3.500] [  3] IN   : 10.4
[        ]   9.372360 d=  0.000003 [162   +  6.667] [ 67] DATA0: 00 13 00 01 0a 75 57 c6 a0 e8 d3 68 25 ba 15 9e 7f b5 ad 8c da f8 04 86 8c f9 0e 8f 1f 8a ea 17 c0 16 b5 5c 2a 7a d4 97 c8 94 fb 71 d7 53 d7 9b 9a 48 4b 6c 37 6d 72 3b 99 8d 2e 1d 43 06 bf 10 85 9c
[        ]   9.372407 d=  0.000046 [162   + 53.083] [  1] ACK
[        ]   9.374357 d=  0.001951 [164   +  3.750] [  3] IN   : 10.4
[        ]   9.374360 d=  0.000003 [164   +  6.917] [ 67] DATA1: 00 13 00 01 0b 33 b5 ae f8 cc a5 cb b2 56 8b 69 24 22 6d 22 a3 58 ab 7d 87 e4 ac 5f 2e 09 1a a7 15 79 f3 a5 69 09 49 7d 72 f5 4e 06 ba c1 c3 b4 41 3b ba 5e af 94 c3 b6 4f 34 f9 eb a4 1a cb 6a 76 f6
[        ]   9.374407 d=  0.000046 [164   + 53.167] [  1] ACK
[        ]   9.376357 d=  0.001950 [166   +  3.500] [  3] IN   : 10.4
[        ]   9.376360 d=  0.000003 [166   +  6.667] [ 67] DATA0: 00 13 00 01 0c e2 83 77 6d 36 46 53 78 48 fe e8 84 bd dd f5 b1 ba 57 98 54 cf fd ce ba c3 44 05 95 27 e5 6d d5 98 f8 f5 66 71 5a be 43 01 dd 19 11 30 e6 b9 f0 c6 40 39 12 53 e2 29 80 3f 3a ef e0 2e
[        ]   9.376407 d=  0.000046 [166   + 53.000] [  1] ACK
[        ]   9.378357 d=  0.001951 [168   +  3.583] [  3] IN   : 10.4
[        ]   9.378360 d=  0.000003 [168   +  6.667] [ 67] DATA1: 00 13 00 01 0d 27 4b ed bf de 3f cb bd 42 ea d6 79 30 45 02 21 00 b6 7c f3 1c 01 74 16 2d 5e 95 76 08 e1 5f 98 71 b0 09 4e 68 e6 16 cc b3 3e f6 92 08 da 8d ae f1 02 20 74 69 4a 1d 35 fd c5 dc 7f 84
[        ]   9.378407 d=  0.000046 [168   + 53.000] [  1] ACK
[        ]   9.380358 d=  0.001951 [170   +  3.500] [  3] IN   : 10.4
[        ]   9.380361 d=  0.000003 [170   +  6.667] [ 67] DATA0: 00 13 00 01 0e e7 4f c9 17 46 4e 5c 5b b1 3d 80 37 75 5f d2 cd 40 b3 6c ca df 26 39 1d 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 57 47
[        ]   9.380407 d=  0.000046 [170   + 52.750] [  1] ACK
[        ]   9.382358 d=  0.001951 [172   +  3.583] [  3] IN   : 10.4
[        ]   9.382361 d=  0.000003 [172   +  6.750] [  1] NAK

This successfully concludes the operation.

A few seconds later, I try again:

[        ]  14.170723 d=  0.031999 [ 96   +  3.250] [  3] IN   : 10.3
[        ]  14.170727 d=  0.000003 [ 96   +  6.417] [  1] NAK
[        ]  14.178725 d=  0.007999 [104   +  4.417] [  3] OUT  : 10.4
[        ]  14.178728 d=  0.000003 [104   +  7.667] [ 67] DATA0: ff ff ff ff 86 00 08 e0 94 54 03 2f d9 d6 77 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c5 f9
[        ]  14.178775 d=  0.000046 [104   + 54.000] [  1] ACK
[        ]  14.178777 d=  0.000002 [104   + 55.917] [  3] IN   : 10.4
[        ]  14.178780 d=  0.000003 [104   + 59.083] [  1] NAK
[        ]  14.180725 d=  0.001945 [106   +  4.000] [  3] IN   : 10.4
[        ]  14.180728 d=  0.000003 [106   +  7.167] [  1] NAK
[        ]  14.182724 d=  0.001996 [108   +  3.333] [  3] IN   : 10.4
[        ]  14.182728 d=  0.000003 [108   +  6.500] [  1] NAK
[        ]  14.184724 d=  0.001997 [110   +  3.250] [  3] IN   : 10.4
[        ]  14.184728 d=  0.000003 [110   +  6.417] [  1] NAK

Note that the initial request for this operation gets assigned the DATA0
sequence, just like the last outbound request of the previous transaction.
AFAIK the token will ACK+ignore this as a duplicate.

Any clues? I can't see where the sequence bit gets tracked - is it in the
controller driver?

-d

Reply | Threaded
Open this post in threaded view
|

Re: HID devices without numbered reports

Patrick Wildt-3
On Mon, Oct 28, 2019 at 03:14:22PM +1100, Damien Miller wrote:

> On Mon, 28 Oct 2019, Damien Miller wrote:
>
> > BTW, the token still becomes unresponsive after the first transaction,
> > but looking at a sniff (using an OpenViszla), it seems we're getting the
> > DATA0/DATA1 flipping incorrect on the wire.
> >
> > On OpenBSD, this is the last rx of the transaction with the card:
> >
> > [        ]  12.992349 d=  0.001951 [154.0 +  3.500] [  3] IN   : 8.4
> > [        ]  12.992352 d=  0.000003 [154.0 +  6.667] [ 67] DATA0: 00 10 00 01 0e 1b 4a 78 ec 87 06 bd 47 d4 a0 49 d9 c7 2d 89 d9 7e 2c c5 62 87 53 92 9b 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3a e8
> >
> > and this is the first tx of the first packet of the subsequent transaction
> > that hangs:
> >
> > [        ]  22.201067 d=  0.001998 [146.0 +  4.333] [  3] OUT  : 8.4
> > [        ]  22.201070 d=  0.000003 [146.0 +  7.583] [ 67] DATA0: ff ff ff ff 86 00 08 c0 65 eb 53 9a 48 04 7d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d6 1d
>
> Since I don't really understand how USB sequence numbers work, it just
> occurred to me to check the sequence bit on the last sent packet.
> It too is a DATA0, so the sequence is definitiely getting lost across
> close+open.
>
> Here's an annotated trace - starting with the last command sent to
> a Yk5 token during key enrollment:
>
> [        ]   9.212345 d=  0.001992 [  2   +  4.333] [  3] OUT  : 10.4
> [        ]   9.212349 d=  0.000003 [  2   +  7.583] [ 67] DATA1: 00 13 00 01 83 00 47 00 01 00 00 00 00 40 a9 dc 95 51 0e ec 44 6d 7a b1 14 88 d1 84 93 b4 aa d2 e5 10 11 db 9c fa b4 b3 0b 89 2c ea 3f b9 e3 06 10 e8 a1 62 11 59 60 fe 1e c2 23 e6 52 9c 9f 4b 8a c8
> [        ]   9.212395 d=  0.000046 [  2   + 53.750] [  1] ACK
> [        ]   9.212397 d=  0.000002 [  2   + 55.667] [  3] IN   : 10.4
> [        ]   9.212400 d=  0.000003 [  2   + 58.833] [  1] NAK
> [        ]   9.214346 d=  0.001946 [  4   +  4.500] [  3] OUT  : 10.4
> [        ]   9.214349 d=  0.000003 [  4   +  7.750] [ 67] DATA0: 00 13 00 01 00 6e 80 20 0d cb 5e 5c 32 1c 8a f1 e2 b1 bf 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11 7c
> [        ]   9.214395 d=  0.000046 [  4   + 53.750] [  1] ACK
> [        ]   9.214397 d=  0.000002 [  4   + 55.667] [  3] IN   : 10.4
> [        ]   9.214400 d=  0.000003 [  4   + 58.833] [  1] NAK
> [        ]   9.216345 d=  0.001945 [  6   +  4.000] [  3] IN   : 10.4
> [        ]   9.216349 d=  0.000003 [  6   +  7.167] [  1] NAK
>
> Note that the last OUT was a DATA0.
>
> The token replies with a bunch of data:
>
> [        ]   9.350355 d=  0.001997 [140   +  3.250] [  3] IN   : 10.4
> [        ]   9.350358 d=  0.000003 [140   +  6.417] [ 67] DATA1: 00 13 00 01 83 03 8d 05 04 f6 80 b1 df 4d 8e fe 30 cd a0 2c 42 e1 a1 46 52 9f 8a 06 80 21 78 7a 73 71 e3 f3 0a e6 f6 e0 74 54 ef df 0c 74 ed be 3f 35 1d dd 35 cf 33 14 fc 33 6e b6 45 11 bd f5 79 99
> [        ]   9.350404 d=  0.000046 [140   + 52.417] [  1] ACK
> [        ]   9.352356 d=  0.001951 [142   +  3.750] [  3] IN   : 10.4
> [        ]   9.352359 d=  0.000003 [142   +  6.917] [ 67] DATA0: 00 13 00 01 00 61 98 66 2c 14 5f 65 e5 4c 40 df 01 56 e8 d8 2b e8 f7 a8 ff 00 96 a6 f3 95 00 d9 93 87 cb c8 b1 02 23 ec 8f 38 37 b8 cf da 73 62 18 90 ff 8b 01 cf a1 78 61 3e cc 48 ac 7b 45 4f b0 6b
> [        ]   9.352405 d=  0.000046 [142   + 53.167] [  1] ACK
> [        ]   9.354356 d=  0.001950 [144   +  3.500] [  3] IN   : 10.4
> [        ]   9.354359 d=  0.000003 [144   +  6.667] [ 67] DATA1: 00 13 00 01 01 4a 0d 3a 6d d7 ca fc 00 e1 ad 7e 78 b1 9d 88 30 82 02 bd 30 82 01 a5 a0 03 02 01 02 02 04 18 ac 46 c0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 2e 31 2c 30 2a 06 03 55 04 83 af
> [        ]   9.354405 d=  0.000046 [144   + 52.833] [  1] ACK
> [        ]   9.356356 d=  0.001951 [146   +  3.583] [  3] IN   : 10.4
> [        ]   9.356359 d=  0.000003 [146   +  6.750] [ 67] DATA0: 00 13 00 01 02 03 13 23 59 75 62 69 63 6f 20 55 32 46 20 52 6f 6f 74 20 43 41 20 53 65 72 69 61 6c 20 34 35 37 32 30 30 36 33 31 30 20 17 0d 31 34 30 38 30 31 30 30 30 30 30 30 5a 18 0f 32 30 98 68
> [        ]   9.356405 d=  0.000046 [146   + 52.667] [  1] ACK
> [        ]   9.358356 d=  0.001951 [148   +  3.583] [  3] IN   : 10.4
> [        ]   9.358359 d=  0.000003 [148   +  6.750] [ 67] DATA1: 00 13 00 01 03 35 30 30 39 30 34 30 30 30 30 30 30 5a 30 6e 31 0b 30 09 06 03 55 04 06 13 02 53 45 31 12 30 10 06 03 55 04 0a 0c 09 59 75 62 69 63 6f 20 41 42 31 22 30 20 06 03 55 04 0b 0c 19 69 76
> [        ]   9.358405 d=  0.000046 [148   + 52.667] [  1] ACK
> [        ]   9.360357 d=  0.001952 [150   +  4.833] [  3] IN   : 10.4
> [        ]   9.360361 d=  0.000003 [150   +  8.000] [ 67] DATA0: 00 13 00 01 04 41 75 74 68 65 6e 74 69 63 61 74 6f 72 20 41 74 74 65 73 74 61 74 69 6f 6e 31 27 30 25 06 03 55 04 03 0c 1e 59 75 62 69 63 6f 20 55 32 46 20 45 45 20 53 65 72 69 61 6c 20 34 31 4c 3a
> [        ]   9.360406 d=  0.000046 [150   + 53.917] [  1] ACK
> [        ]   9.362356 d=  0.001950 [152   +  3.500] [  3] IN   : 10.4
> [        ]   9.362359 d=  0.000003 [152   +  6.667] [ 67] DATA1: 00 13 00 01 05 33 39 34 33 34 38 38 30 59 30 13 06 07 2a 86 48 ce 3d 02 01 06 08 2a 86 48 ce 3d 03 01 07 03 42 00 04 79 ea 3b 2c 7c 49 70 10 62 23 0c d2 3f eb 60 e5 29 31 71 d4 83 f1 00 be 85 94 5e
> [        ]   9.362405 d=  0.000046 [152   + 52.750] [  1] ACK
> [        ]   9.364356 d=  0.001951 [154   +  3.500] [  3] IN   : 10.4
> [        ]   9.364360 d=  0.000003 [154   +  6.667] [ 67] DATA0: 00 13 00 01 06 9d 6b 0f 83 97 03 01 b5 46 cd d4 6e cf ca e3 e3 f3 0f 81 e9 ed 62 bd 26 8d 4c 1e bd 37 b3 bc be 92 a8 c2 ae eb 4e 3a a3 6c 30 6a 30 22 06 09 2b 06 01 04 01 82 c4 0a 02 04 15 31 34 85
> [        ]   9.364406 d=  0.000046 [154   + 52.750] [  1] ACK
> [        ]   9.366356 d=  0.001951 [156   +  3.500] [  3] IN   : 10.4
> [        ]   9.366360 d=  0.000003 [156   +  6.667] [ 67] DATA1: 00 13 00 01 07 2e 33 2e 36 2e 31 2e 34 2e 31 2e 34 31 34 38 32 2e 31 2e 37 30 13 06 0b 2b 06 01 04 01 82 e5 1c 02 01 01 04 04 03 02 05 20 30 21 06 0b 2b 06 01 04 01 82 e5 1c 01 01 04 04 12 04 f8 38
> [        ]   9.366406 d=  0.000046 [156   + 52.667] [  1] ACK
> [        ]   9.368357 d=  0.001951 [158   +  3.500] [  3] IN   : 10.4
> [        ]   9.368360 d=  0.000003 [158   +  6.667] [ 67] DATA0: 00 13 00 01 08 10 cb 69 48 1e 8f f7 40 39 93 ec 0a 27 29 a1 54 a8 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 82 01 01 00 97 9d 03 97 d8 60 f8 2e d8 dc
> [        ]   9.368406 d=  0.000046 [158   + 52.833] [  1] ACK
> [        ]   9.370357 d=  0.001951 [160   +  3.917] [  3] IN   : 10.4
> [        ]   9.370360 d=  0.000003 [160   +  7.083] [ 67] DATA1: 00 13 00 01 09 e1 5d 31 1c 79 6e ba fb 22 fa a7 e0 84 d9 ba b4 c6 1b bb 57 f3 e6 b4 c1 8a 48 37 b8 5c 3c 4e db e4 83 43 f4 d6 a5 d9 b1 ce da 8a e1 fe d4 91 29 21 73 05 8e 5e e1 cb dd 6b da c0 59 fc
> [        ]   9.370406 d=  0.000046 [160   + 53.250] [  1] ACK
> [        ]   9.370408 d=  0.000002 [160   + 55.167] [  3] IN   : 10.3
> [        ]   9.370412 d=  0.000003 [160   + 58.333] [  1] NAK
> [        ]   9.372357 d=  0.001945 [162   +  3.500] [  3] IN   : 10.4
> [        ]   9.372360 d=  0.000003 [162   +  6.667] [ 67] DATA0: 00 13 00 01 0a 75 57 c6 a0 e8 d3 68 25 ba 15 9e 7f b5 ad 8c da f8 04 86 8c f9 0e 8f 1f 8a ea 17 c0 16 b5 5c 2a 7a d4 97 c8 94 fb 71 d7 53 d7 9b 9a 48 4b 6c 37 6d 72 3b 99 8d 2e 1d 43 06 bf 10 85 9c
> [        ]   9.372407 d=  0.000046 [162   + 53.083] [  1] ACK
> [        ]   9.374357 d=  0.001951 [164   +  3.750] [  3] IN   : 10.4
> [        ]   9.374360 d=  0.000003 [164   +  6.917] [ 67] DATA1: 00 13 00 01 0b 33 b5 ae f8 cc a5 cb b2 56 8b 69 24 22 6d 22 a3 58 ab 7d 87 e4 ac 5f 2e 09 1a a7 15 79 f3 a5 69 09 49 7d 72 f5 4e 06 ba c1 c3 b4 41 3b ba 5e af 94 c3 b6 4f 34 f9 eb a4 1a cb 6a 76 f6
> [        ]   9.374407 d=  0.000046 [164   + 53.167] [  1] ACK
> [        ]   9.376357 d=  0.001950 [166   +  3.500] [  3] IN   : 10.4
> [        ]   9.376360 d=  0.000003 [166   +  6.667] [ 67] DATA0: 00 13 00 01 0c e2 83 77 6d 36 46 53 78 48 fe e8 84 bd dd f5 b1 ba 57 98 54 cf fd ce ba c3 44 05 95 27 e5 6d d5 98 f8 f5 66 71 5a be 43 01 dd 19 11 30 e6 b9 f0 c6 40 39 12 53 e2 29 80 3f 3a ef e0 2e
> [        ]   9.376407 d=  0.000046 [166   + 53.000] [  1] ACK
> [        ]   9.378357 d=  0.001951 [168   +  3.583] [  3] IN   : 10.4
> [        ]   9.378360 d=  0.000003 [168   +  6.667] [ 67] DATA1: 00 13 00 01 0d 27 4b ed bf de 3f cb bd 42 ea d6 79 30 45 02 21 00 b6 7c f3 1c 01 74 16 2d 5e 95 76 08 e1 5f 98 71 b0 09 4e 68 e6 16 cc b3 3e f6 92 08 da 8d ae f1 02 20 74 69 4a 1d 35 fd c5 dc 7f 84
> [        ]   9.378407 d=  0.000046 [168   + 53.000] [  1] ACK
> [        ]   9.380358 d=  0.001951 [170   +  3.500] [  3] IN   : 10.4
> [        ]   9.380361 d=  0.000003 [170   +  6.667] [ 67] DATA0: 00 13 00 01 0e e7 4f c9 17 46 4e 5c 5b b1 3d 80 37 75 5f d2 cd 40 b3 6c ca df 26 39 1d 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 57 47
> [        ]   9.380407 d=  0.000046 [170   + 52.750] [  1] ACK
> [        ]   9.382358 d=  0.001951 [172   +  3.583] [  3] IN   : 10.4
> [        ]   9.382361 d=  0.000003 [172   +  6.750] [  1] NAK
>
> This successfully concludes the operation.
>
> A few seconds later, I try again:
>
> [        ]  14.170723 d=  0.031999 [ 96   +  3.250] [  3] IN   : 10.3
> [        ]  14.170727 d=  0.000003 [ 96   +  6.417] [  1] NAK
> [        ]  14.178725 d=  0.007999 [104   +  4.417] [  3] OUT  : 10.4
> [        ]  14.178728 d=  0.000003 [104   +  7.667] [ 67] DATA0: ff ff ff ff 86 00 08 e0 94 54 03 2f d9 d6 77 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c5 f9
> [        ]  14.178775 d=  0.000046 [104   + 54.000] [  1] ACK
> [        ]  14.178777 d=  0.000002 [104   + 55.917] [  3] IN   : 10.4
> [        ]  14.178780 d=  0.000003 [104   + 59.083] [  1] NAK
> [        ]  14.180725 d=  0.001945 [106   +  4.000] [  3] IN   : 10.4
> [        ]  14.180728 d=  0.000003 [106   +  7.167] [  1] NAK
> [        ]  14.182724 d=  0.001996 [108   +  3.333] [  3] IN   : 10.4
> [        ]  14.182728 d=  0.000003 [108   +  6.500] [  1] NAK
> [        ]  14.184724 d=  0.001997 [110   +  3.250] [  3] IN   : 10.4
> [        ]  14.184728 d=  0.000003 [110   +  6.417] [  1] NAK
>
> Note that the initial request for this operation gets assigned the DATA0
> sequence, just like the last outbound request of the previous transaction.
> AFAIK the token will ACK+ignore this as a duplicate.
>
> Any clues? I can't see where the sequence bit gets tracked - is it in the
> controller driver?
>
> -d
>

I don't know USB well enough, but to me it seems like that each transfer
starts with DATA0?  I need to cross-check this with a similar program on
Linux to be sure.

Patrick

Reply | Threaded
Open this post in threaded view
|

Re: HID devices without numbered reports

Gerhard Roth-2
On Mon, 28 Oct 2019 15:41:34 +0100 Patrick Wildt <[hidden email]> wrote:

> On Mon, Oct 28, 2019 at 03:14:22PM +1100, Damien Miller wrote:
> > On Mon, 28 Oct 2019, Damien Miller wrote:
> >  
> > > BTW, the token still becomes unresponsive after the first transaction,
> > > but looking at a sniff (using an OpenViszla), it seems we're getting the
> > > DATA0/DATA1 flipping incorrect on the wire.
> > >
> > > On OpenBSD, this is the last rx of the transaction with the card:
> > >
> > > [        ]  12.992349 d=  0.001951 [154.0 +  3.500] [  3] IN   : 8.4
> > > [        ]  12.992352 d=  0.000003 [154.0 +  6.667] [ 67] DATA0: 00 10 00 01 0e 1b 4a 78 ec 87 06 bd 47 d4 a0 49 d9 c7 2d 89 d9 7e 2c c5 62 87 53 92 9b 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3a e8
> > >
> > > and this is the first tx of the first packet of the subsequent transaction
> > > that hangs:
> > >
> > > [        ]  22.201067 d=  0.001998 [146.0 +  4.333] [  3] OUT  : 8.4
> > > [        ]  22.201070 d=  0.000003 [146.0 +  7.583] [ 67] DATA0: ff ff ff ff 86 00 08 c0 65 eb 53 9a 48 04 7d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d6 1d  
> >
> > Since I don't really understand how USB sequence numbers work, it just
> > occurred to me to check the sequence bit on the last sent packet.
> > It too is a DATA0, so the sequence is definitiely getting lost across
> > close+open.
> >
> > Here's an annotated trace - starting with the last command sent to
> > a Yk5 token during key enrollment:
> >
> > [        ]   9.212345 d=  0.001992 [  2   +  4.333] [  3] OUT  : 10.4
> > [        ]   9.212349 d=  0.000003 [  2   +  7.583] [ 67] DATA1: 00 13 00 01 83 00 47 00 01 00 00 00 00 40 a9 dc 95 51 0e ec 44 6d 7a b1 14 88 d1 84 93 b4 aa d2 e5 10 11 db 9c fa b4 b3 0b 89 2c ea 3f b9 e3 06 10 e8 a1 62 11 59 60 fe 1e c2 23 e6 52 9c 9f 4b 8a c8
> > [        ]   9.212395 d=  0.000046 [  2   + 53.750] [  1] ACK
> > [        ]   9.212397 d=  0.000002 [  2   + 55.667] [  3] IN   : 10.4
> > [        ]   9.212400 d=  0.000003 [  2   + 58.833] [  1] NAK
> > [        ]   9.214346 d=  0.001946 [  4   +  4.500] [  3] OUT  : 10.4
> > [        ]   9.214349 d=  0.000003 [  4   +  7.750] [ 67] DATA0: 00 13 00 01 00 6e 80 20 0d cb 5e 5c 32 1c 8a f1 e2 b1 bf 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11 7c
> > [        ]   9.214395 d=  0.000046 [  4   + 53.750] [  1] ACK
> > [        ]   9.214397 d=  0.000002 [  4   + 55.667] [  3] IN   : 10.4
> > [        ]   9.214400 d=  0.000003 [  4   + 58.833] [  1] NAK
> > [        ]   9.216345 d=  0.001945 [  6   +  4.000] [  3] IN   : 10.4
> > [        ]   9.216349 d=  0.000003 [  6   +  7.167] [  1] NAK
> >
> > Note that the last OUT was a DATA0.
> >
> > The token replies with a bunch of data:
> >
> > [        ]   9.350355 d=  0.001997 [140   +  3.250] [  3] IN   : 10.4
> > [        ]   9.350358 d=  0.000003 [140   +  6.417] [ 67] DATA1: 00 13 00 01 83 03 8d 05 04 f6 80 b1 df 4d 8e fe 30 cd a0 2c 42 e1 a1 46 52 9f 8a 06 80 21 78 7a 73 71 e3 f3 0a e6 f6 e0 74 54 ef df 0c 74 ed be 3f 35 1d dd 35 cf 33 14 fc 33 6e b6 45 11 bd f5 79 99
> > [        ]   9.350404 d=  0.000046 [140   + 52.417] [  1] ACK
> > [        ]   9.352356 d=  0.001951 [142   +  3.750] [  3] IN   : 10.4
> > [        ]   9.352359 d=  0.000003 [142   +  6.917] [ 67] DATA0: 00 13 00 01 00 61 98 66 2c 14 5f 65 e5 4c 40 df 01 56 e8 d8 2b e8 f7 a8 ff 00 96 a6 f3 95 00 d9 93 87 cb c8 b1 02 23 ec 8f 38 37 b8 cf da 73 62 18 90 ff 8b 01 cf a1 78 61 3e cc 48 ac 7b 45 4f b0 6b
> > [        ]   9.352405 d=  0.000046 [142   + 53.167] [  1] ACK
> > [        ]   9.354356 d=  0.001950 [144   +  3.500] [  3] IN   : 10.4
> > [        ]   9.354359 d=  0.000003 [144   +  6.667] [ 67] DATA1: 00 13 00 01 01 4a 0d 3a 6d d7 ca fc 00 e1 ad 7e 78 b1 9d 88 30 82 02 bd 30 82 01 a5 a0 03 02 01 02 02 04 18 ac 46 c0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 2e 31 2c 30 2a 06 03 55 04 83 af
> > [        ]   9.354405 d=  0.000046 [144   + 52.833] [  1] ACK
> > [        ]   9.356356 d=  0.001951 [146   +  3.583] [  3] IN   : 10.4
> > [        ]   9.356359 d=  0.000003 [146   +  6.750] [ 67] DATA0: 00 13 00 01 02 03 13 23 59 75 62 69 63 6f 20 55 32 46 20 52 6f 6f 74 20 43 41 20 53 65 72 69 61 6c 20 34 35 37 32 30 30 36 33 31 30 20 17 0d 31 34 30 38 30 31 30 30 30 30 30 30 5a 18 0f 32 30 98 68
> > [        ]   9.356405 d=  0.000046 [146   + 52.667] [  1] ACK
> > [        ]   9.358356 d=  0.001951 [148   +  3.583] [  3] IN   : 10.4
> > [        ]   9.358359 d=  0.000003 [148   +  6.750] [ 67] DATA1: 00 13 00 01 03 35 30 30 39 30 34 30 30 30 30 30 30 5a 30 6e 31 0b 30 09 06 03 55 04 06 13 02 53 45 31 12 30 10 06 03 55 04 0a 0c 09 59 75 62 69 63 6f 20 41 42 31 22 30 20 06 03 55 04 0b 0c 19 69 76
> > [        ]   9.358405 d=  0.000046 [148   + 52.667] [  1] ACK
> > [        ]   9.360357 d=  0.001952 [150   +  4.833] [  3] IN   : 10.4
> > [        ]   9.360361 d=  0.000003 [150   +  8.000] [ 67] DATA0: 00 13 00 01 04 41 75 74 68 65 6e 74 69 63 61 74 6f 72 20 41 74 74 65 73 74 61 74 69 6f 6e 31 27 30 25 06 03 55 04 03 0c 1e 59 75 62 69 63 6f 20 55 32 46 20 45 45 20 53 65 72 69 61 6c 20 34 31 4c 3a
> > [        ]   9.360406 d=  0.000046 [150   + 53.917] [  1] ACK
> > [        ]   9.362356 d=  0.001950 [152   +  3.500] [  3] IN   : 10.4
> > [        ]   9.362359 d=  0.000003 [152   +  6.667] [ 67] DATA1: 00 13 00 01 05 33 39 34 33 34 38 38 30 59 30 13 06 07 2a 86 48 ce 3d 02 01 06 08 2a 86 48 ce 3d 03 01 07 03 42 00 04 79 ea 3b 2c 7c 49 70 10 62 23 0c d2 3f eb 60 e5 29 31 71 d4 83 f1 00 be 85 94 5e
> > [        ]   9.362405 d=  0.000046 [152   + 52.750] [  1] ACK
> > [        ]   9.364356 d=  0.001951 [154   +  3.500] [  3] IN   : 10.4
> > [        ]   9.364360 d=  0.000003 [154   +  6.667] [ 67] DATA0: 00 13 00 01 06 9d 6b 0f 83 97 03 01 b5 46 cd d4 6e cf ca e3 e3 f3 0f 81 e9 ed 62 bd 26 8d 4c 1e bd 37 b3 bc be 92 a8 c2 ae eb 4e 3a a3 6c 30 6a 30 22 06 09 2b 06 01 04 01 82 c4 0a 02 04 15 31 34 85
> > [        ]   9.364406 d=  0.000046 [154   + 52.750] [  1] ACK
> > [        ]   9.366356 d=  0.001951 [156   +  3.500] [  3] IN   : 10.4
> > [        ]   9.366360 d=  0.000003 [156   +  6.667] [ 67] DATA1: 00 13 00 01 07 2e 33 2e 36 2e 31 2e 34 2e 31 2e 34 31 34 38 32 2e 31 2e 37 30 13 06 0b 2b 06 01 04 01 82 e5 1c 02 01 01 04 04 03 02 05 20 30 21 06 0b 2b 06 01 04 01 82 e5 1c 01 01 04 04 12 04 f8 38
> > [        ]   9.366406 d=  0.000046 [156   + 52.667] [  1] ACK
> > [        ]   9.368357 d=  0.001951 [158   +  3.500] [  3] IN   : 10.4
> > [        ]   9.368360 d=  0.000003 [158   +  6.667] [ 67] DATA0: 00 13 00 01 08 10 cb 69 48 1e 8f f7 40 39 93 ec 0a 27 29 a1 54 a8 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 82 01 01 00 97 9d 03 97 d8 60 f8 2e d8 dc
> > [        ]   9.368406 d=  0.000046 [158   + 52.833] [  1] ACK
> > [        ]   9.370357 d=  0.001951 [160   +  3.917] [  3] IN   : 10.4
> > [        ]   9.370360 d=  0.000003 [160   +  7.083] [ 67] DATA1: 00 13 00 01 09 e1 5d 31 1c 79 6e ba fb 22 fa a7 e0 84 d9 ba b4 c6 1b bb 57 f3 e6 b4 c1 8a 48 37 b8 5c 3c 4e db e4 83 43 f4 d6 a5 d9 b1 ce da 8a e1 fe d4 91 29 21 73 05 8e 5e e1 cb dd 6b da c0 59 fc
> > [        ]   9.370406 d=  0.000046 [160   + 53.250] [  1] ACK
> > [        ]   9.370408 d=  0.000002 [160   + 55.167] [  3] IN   : 10.3
> > [        ]   9.370412 d=  0.000003 [160   + 58.333] [  1] NAK
> > [        ]   9.372357 d=  0.001945 [162   +  3.500] [  3] IN   : 10.4
> > [        ]   9.372360 d=  0.000003 [162   +  6.667] [ 67] DATA0: 00 13 00 01 0a 75 57 c6 a0 e8 d3 68 25 ba 15 9e 7f b5 ad 8c da f8 04 86 8c f9 0e 8f 1f 8a ea 17 c0 16 b5 5c 2a 7a d4 97 c8 94 fb 71 d7 53 d7 9b 9a 48 4b 6c 37 6d 72 3b 99 8d 2e 1d 43 06 bf 10 85 9c
> > [        ]   9.372407 d=  0.000046 [162   + 53.083] [  1] ACK
> > [        ]   9.374357 d=  0.001951 [164   +  3.750] [  3] IN   : 10.4
> > [        ]   9.374360 d=  0.000003 [164   +  6.917] [ 67] DATA1: 00 13 00 01 0b 33 b5 ae f8 cc a5 cb b2 56 8b 69 24 22 6d 22 a3 58 ab 7d 87 e4 ac 5f 2e 09 1a a7 15 79 f3 a5 69 09 49 7d 72 f5 4e 06 ba c1 c3 b4 41 3b ba 5e af 94 c3 b6 4f 34 f9 eb a4 1a cb 6a 76 f6
> > [        ]   9.374407 d=  0.000046 [164   + 53.167] [  1] ACK
> > [        ]   9.376357 d=  0.001950 [166   +  3.500] [  3] IN   : 10.4
> > [        ]   9.376360 d=  0.000003 [166   +  6.667] [ 67] DATA0: 00 13 00 01 0c e2 83 77 6d 36 46 53 78 48 fe e8 84 bd dd f5 b1 ba 57 98 54 cf fd ce ba c3 44 05 95 27 e5 6d d5 98 f8 f5 66 71 5a be 43 01 dd 19 11 30 e6 b9 f0 c6 40 39 12 53 e2 29 80 3f 3a ef e0 2e
> > [        ]   9.376407 d=  0.000046 [166   + 53.000] [  1] ACK
> > [        ]   9.378357 d=  0.001951 [168   +  3.583] [  3] IN   : 10.4
> > [        ]   9.378360 d=  0.000003 [168   +  6.667] [ 67] DATA1: 00 13 00 01 0d 27 4b ed bf de 3f cb bd 42 ea d6 79 30 45 02 21 00 b6 7c f3 1c 01 74 16 2d 5e 95 76 08 e1 5f 98 71 b0 09 4e 68 e6 16 cc b3 3e f6 92 08 da 8d ae f1 02 20 74 69 4a 1d 35 fd c5 dc 7f 84
> > [        ]   9.378407 d=  0.000046 [168   + 53.000] [  1] ACK
> > [        ]   9.380358 d=  0.001951 [170   +  3.500] [  3] IN   : 10.4
> > [        ]   9.380361 d=  0.000003 [170   +  6.667] [ 67] DATA0: 00 13 00 01 0e e7 4f c9 17 46 4e 5c 5b b1 3d 80 37 75 5f d2 cd 40 b3 6c ca df 26 39 1d 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 57 47
> > [        ]   9.380407 d=  0.000046 [170   + 52.750] [  1] ACK
> > [        ]   9.382358 d=  0.001951 [172   +  3.583] [  3] IN   : 10.4
> > [        ]   9.382361 d=  0.000003 [172   +  6.750] [  1] NAK
> >
> > This successfully concludes the operation.
> >
> > A few seconds later, I try again:
> >
> > [        ]  14.170723 d=  0.031999 [ 96   +  3.250] [  3] IN   : 10.3
> > [        ]  14.170727 d=  0.000003 [ 96   +  6.417] [  1] NAK
> > [        ]  14.178725 d=  0.007999 [104   +  4.417] [  3] OUT  : 10.4
> > [        ]  14.178728 d=  0.000003 [104   +  7.667] [ 67] DATA0: ff ff ff ff 86 00 08 e0 94 54 03 2f d9 d6 77 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c5 f9
> > [        ]  14.178775 d=  0.000046 [104   + 54.000] [  1] ACK
> > [        ]  14.178777 d=  0.000002 [104   + 55.917] [  3] IN   : 10.4
> > [        ]  14.178780 d=  0.000003 [104   + 59.083] [  1] NAK
> > [        ]  14.180725 d=  0.001945 [106   +  4.000] [  3] IN   : 10.4
> > [        ]  14.180728 d=  0.000003 [106   +  7.167] [  1] NAK
> > [        ]  14.182724 d=  0.001996 [108   +  3.333] [  3] IN   : 10.4
> > [        ]  14.182728 d=  0.000003 [108   +  6.500] [  1] NAK
> > [        ]  14.184724 d=  0.001997 [110   +  3.250] [  3] IN   : 10.4
> > [        ]  14.184728 d=  0.000003 [110   +  6.417] [  1] NAK
> >
> > Note that the initial request for this operation gets assigned the DATA0
> > sequence, just like the last outbound request of the previous transaction.
> > AFAIK the token will ACK+ignore this as a duplicate.
> >
> > Any clues? I can't see where the sequence bit gets tracked - is it in the
> > controller driver?
> >
> > -d
> >  
>
> I don't know USB well enough, but to me it seems like that each transfer
> starts with DATA0?  I need to cross-check this with a similar program on
> Linux to be sure.
>
> Patrick


Not quite so. For each endpoint (in High-Speed mode) it should use DATA0 and
DATA1 alternating.

However, there is a protocol for synchronization, see
https://wiki.osdev.org/Universal_Serial_Bus#Data_Toggle_Synchronization


Gerhard

Reply | Threaded
Open this post in threaded view
|

Re: HID devices without numbered reports

Patrick Wildt-3
In reply to this post by Damien Miller
On Mon, Oct 28, 2019 at 12:07:20PM +1100, Damien Miller wrote:

> On Mon, 28 Oct 2019, Damien Miller wrote:
>
> > On Fri, 25 Oct 2019, Patrick Wildt wrote:
> >
> > > > So from what I understood the Yubikey expects the transfer to happen
> > > > on the Interrupt OUT pipe instead of doing a control transfer.  Read-
> > > > ing some code and documentation, it looks like that we should by de-
> > > > fault send our reports on the interrupt pipe, and only if it does not
> > > > exist fall back to control transfers.  Linux seems to do exactly that.
> > > >
> > > > I tried to come up with the following diff, which appeard to make a
> > > > test program work for me.  Though I'm not sure I got all the specifics
> > > > right.
> > > >
> > > > Can you give this a go with your test progam?
> > > >
> > > > Patrick
> > >
> > > Oops, obvious error.  Though I still cannot write/read multiple times
> > > in a row, so there is probably still something wrong (unless my test
> > > is as well).
> >
> > It didn't work for me - I think because uhidev_set_report() (and _async)
> > is still prepending a report ID. If I modify uhid.c to send writes
> > without a report ID, then it does work:
>
> BTW, the token still becomes unresponsive after the first transaction,
> but looking at a sniff (using an OpenViszla), it seems we're getting the
> DATA0/DATA1 flipping incorrect on the wire.
>
> On OpenBSD, this is the last rx of the transaction with the card:
>
> [        ]  12.992349 d=  0.001951 [154.0 +  3.500] [  3] IN   : 8.4
> [        ]  12.992352 d=  0.000003 [154.0 +  6.667] [ 67] DATA0: 00 10 00 01 0e 1b 4a 78 ec 87 06 bd 47 d4 a0 49 d9 c7 2d 89 d9 7e 2c c5 62 87 53 92 9b 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3a e8
>
> and this is the first tx of the first packet of the subsequent transaction
> that hangs:
>
> [        ]  22.201067 d=  0.001998 [146.0 +  4.333] [  3] OUT  : 8.4
> [        ]  22.201070 d=  0.000003 [146.0 +  7.583] [ 67] DATA0: ff ff ff ff 86 00 08 c0 65 eb 53 9a 48 04 7d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d6 1d
>
> On Linux, the sequence bit does get flipped between the last rx:
>
> [        ]  14.174783 d=  0.001951 [214.0 +  3.417] [  3] IN   : 24.4
> [        ]  14.174786 d=  0.000003 [214.0 +  6.583] [ 67] DATA0: 00 12 00 01 0e 2e 25 14 32 f4 a4 68 d1 81 d1 29 e1 47 6f 4c 7d e2 69 dc b9 96 e5 f5 23 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 be 67
>
> and the tx of the next attempt:
>
> [        ]  20.057155 d=  0.001997 [208.0 +  3.417] [  3] OUT  : 24.4
> [        ]  20.057158 d=  0.000003 [208.0 +  6.667] [ 67] DATA1: ff ff ff ff 86 00 08 82 40 e5 bf c6 94 7e e8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 8b
>
> I think it's losing the sequence bit state across open/close of
> /dev/uhidX - If I try to do two transactions without an intervening
> close/open then it seems to work...
>
> -d

I have also sniffed this on both OpenBSD with xhci(4) and some
Linux.  Turns out, yes, we're always doing DATA0 instead of
toggling to DATA1 and back.  But I'm not sure where exactly
this happens.  I'll investigate.

Patrick

Reply | Threaded
Open this post in threaded view
|

Re: HID devices without numbered reports

Patrick Wildt-3
On Tue, Oct 29, 2019 at 05:41:55PM +0100, Patrick Wildt wrote:

> On Mon, Oct 28, 2019 at 12:07:20PM +1100, Damien Miller wrote:
> > On Mon, 28 Oct 2019, Damien Miller wrote:
> >
> > > On Fri, 25 Oct 2019, Patrick Wildt wrote:
> > >
> > > > > So from what I understood the Yubikey expects the transfer to happen
> > > > > on the Interrupt OUT pipe instead of doing a control transfer.  Read-
> > > > > ing some code and documentation, it looks like that we should by de-
> > > > > fault send our reports on the interrupt pipe, and only if it does not
> > > > > exist fall back to control transfers.  Linux seems to do exactly that.
> > > > >
> > > > > I tried to come up with the following diff, which appeard to make a
> > > > > test program work for me.  Though I'm not sure I got all the specifics
> > > > > right.
> > > > >
> > > > > Can you give this a go with your test progam?
> > > > >
> > > > > Patrick
> > > >
> > > > Oops, obvious error.  Though I still cannot write/read multiple times
> > > > in a row, so there is probably still something wrong (unless my test
> > > > is as well).
> > >
> > > It didn't work for me - I think because uhidev_set_report() (and _async)
> > > is still prepending a report ID. If I modify uhid.c to send writes
> > > without a report ID, then it does work:
> >
> > BTW, the token still becomes unresponsive after the first transaction,
> > but looking at a sniff (using an OpenViszla), it seems we're getting the
> > DATA0/DATA1 flipping incorrect on the wire.
> >
> > On OpenBSD, this is the last rx of the transaction with the card:
> >
> > [        ]  12.992349 d=  0.001951 [154.0 +  3.500] [  3] IN   : 8.4
> > [        ]  12.992352 d=  0.000003 [154.0 +  6.667] [ 67] DATA0: 00 10 00 01 0e 1b 4a 78 ec 87 06 bd 47 d4 a0 49 d9 c7 2d 89 d9 7e 2c c5 62 87 53 92 9b 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3a e8
> >
> > and this is the first tx of the first packet of the subsequent transaction
> > that hangs:
> >
> > [        ]  22.201067 d=  0.001998 [146.0 +  4.333] [  3] OUT  : 8.4
> > [        ]  22.201070 d=  0.000003 [146.0 +  7.583] [ 67] DATA0: ff ff ff ff 86 00 08 c0 65 eb 53 9a 48 04 7d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d6 1d
> >
> > On Linux, the sequence bit does get flipped between the last rx:
> >
> > [        ]  14.174783 d=  0.001951 [214.0 +  3.417] [  3] IN   : 24.4
> > [        ]  14.174786 d=  0.000003 [214.0 +  6.583] [ 67] DATA0: 00 12 00 01 0e 2e 25 14 32 f4 a4 68 d1 81 d1 29 e1 47 6f 4c 7d e2 69 dc b9 96 e5 f5 23 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 be 67
> >
> > and the tx of the next attempt:
> >
> > [        ]  20.057155 d=  0.001997 [208.0 +  3.417] [  3] OUT  : 24.4
> > [        ]  20.057158 d=  0.000003 [208.0 +  6.667] [ 67] DATA1: ff ff ff ff 86 00 08 82 40 e5 bf c6 94 7e e8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 8b
> >
> > I think it's losing the sequence bit state across open/close of
> > /dev/uhidX - If I try to do two transactions without an intervening
> > close/open then it seems to work...
> >
> > -d
>
> I have also sniffed this on both OpenBSD with xhci(4) and some
> Linux.  Turns out, yes, we're always doing DATA0 instead of
> toggling to DATA1 and back.  But I'm not sure where exactly
> this happens.  I'll investigate.
>
> Patrick

Ok, so it turns out that this is related with opening/closing
the uhid(4) device.  Because every open(2) and close(2) also
opens and closes the pipe.  I think for ehci we somehow can
save the toggle and restore it on re-open, and for xhci we
somehow don't?

So I'm wondering if a) we should just keep the output pipe
open or b) there's some way to save/restore the... endpoint
context?  I'm looking into b) obviously.

Patrick

Reply | Threaded
Open this post in threaded view
|

Re: HID devices without numbered reports

Damien Miller
On Tue, 29 Oct 2019, Patrick Wildt wrote:

> Ok, so it turns out that this is related with opening/closing
> the uhid(4) device.  Because every open(2) and close(2) also
> opens and closes the pipe.  I think for ehci we somehow can
> save the toggle and restore it on re-open, and for xhci we
> somehow don't?

uhci isn't saving/restoring it either. Someone else reported no problems
using ohci.

> So I'm wondering if a) we should just keep the output pipe
> open or b) there's some way to save/restore the... endpoint
> context?  I'm looking into b) obviously.

Yeah, I spent some time reading xhci.c but couldn't figure out how
interrupt transfers actually get sent - I could see them get enqueud
but not where the got dequeued...

-d

Reply | Threaded
Open this post in threaded view
|

Re: HID devices without numbered reports

Patrick Wildt-3
On Wed, Oct 30, 2019 at 08:07:06AM +1100, Damien Miller wrote:

> On Tue, 29 Oct 2019, Patrick Wildt wrote:
>
> > Ok, so it turns out that this is related with opening/closing
> > the uhid(4) device.  Because every open(2) and close(2) also
> > opens and closes the pipe.  I think for ehci we somehow can
> > save the toggle and restore it on re-open, and for xhci we
> > somehow don't?
>
> uhci isn't saving/restoring it either. Someone else reported no problems
> using ohci.

Actually, I think it does.  Look for "nexttoggle".  And "savedtoggle" in
ohci.

> > So I'm wondering if a) we should just keep the output pipe
> > open or b) there's some way to save/restore the... endpoint
> > context?  I'm looking into b) obviously.
>
> Yeah, I spent some time reading xhci.c but couldn't figure out how
> interrupt transfers actually get sent - I could see them get enqueud
> but not where the got dequeued...

Interrupt transfers are just normal TRBs that are enqueued.  I think
that the state is saved by the controller in the endpoint context, and
then if you close the pipe you can "drop" the endpoint, while keeping
the state in the endpoint context, so an "add endpoint" restores that
context?  So I think the toggle is actually kept track of by the xHC
itself, in the endpoint context.  So maybe we clear to much of that
endpoint context when we re-open the pipe?

Patrick