USB CCID issue

Jan Suhr jan at nitrokey.com
Tue Jan 26 22:51:14 CET 2016


Hi!

An error happens when using:
- Linux,
- GPG2.0,
- Nitrokey Storage (beta)
- connected via USB3.0
- to perform a signature with SHA224 or SHA256.

It works well when using USB1.1, USB2.0, SHA1, a non-Linux operating
system, or any Nitrokey model other than Storage.

The issue ticket is here:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=775559

We analyzed the issue by starting with the Nitrokey. We figured that the
issue is caused by an oversized USB packet send from the computer (GPG2)
to the Nitrokey. The failed APDU send by GPG2 has a length of 60 byte.
The length of the resulting CCID packet is 74 byte:

CCID packet = CCID header (10 Byte) + T1 header (3 Byte) + APDU (60
Byte) + T1 CRC (1 Byte) = 74 Byte

This CCID packet is send in a single USB packet. Because the receive
buffer of the Nitrokey is 64 byte large the last 10 bytes of the payload
are lost and replaced by random bytes. This causes a parity error when
the data was send to Nitrokey's OpenPGP Card. The 64 byte buffer is
declared in Nitrokey's USB descriptor. It seems that this declaration is
ignored by the computer. I'm not sure whether this is Linux kernel,
SCDaemon or GPG2 responsibility. Could someone with better knowledge of
the GPG stack help to localize the root cause?

Best regards,
Jan


Logs of the failed APDU (with different payloads because I couldn't log
all traces at the same time)


Failed APDU - Length 60 byte
2016-01-25 11:49:23 scdaemon[9614] DBG: send apdu: c=00 i=2A p1=9E p2=9A
lc=51 le=2048 em=1
2016-01-25 11:49:23 scdaemon[9614] DBG:  raw apdu: 00 2A 9E 9A 00 00 33 30
31 30 0D 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20 DD 34 2C 81 12 C7 49
DF 74 65 A1 2D A0 25 0A E9 62 CE 6C F8 66 A8 B7 55 94 04 DA 7C 55 AD D5 3F
08 00
2016-01-25 11:49:46 scdaemon[9614] ccid_transceive failed: (0x1000a)
2016-01-25 11:49:46 scdaemon[9614] apdu_send_simple(0) failed: card I/O
error
2016-01-25 11:49:46 scdaemon[9614] operation sign result: Input/output error
2016-01-25 11:49:46 scdaemon[9614] app_sign failed: Input/output error


USB CCID packet - payload length 74 Byte

No.     Time           Source                Destination           Protocol
Length Info
   3511 38.413647000   host                  8.4                   USB
138    URB_BULK out

Frame 3511: 138 bytes on wire (1104 bits), 138 bytes captured (1104 bits) on
interface 0
    Interface id: 0
    Encapsulation type: USB packets with Linux header and padding (115)
    Arrival Time: Jan 25, 2016 09:16:34.839335000 CET
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1453709794.839335000 seconds
    [Time delta from previous captured frame: 0.000037000 seconds]
    [Time delta from previous displayed frame: 0.000037000 seconds]
    [Time since reference or first frame: 38.413647000 seconds]
    Frame Number: 3511
    Frame Length: 138 bytes (1104 bits)
    Capture Length: 138 bytes (1104 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: usb]
USB URB
    URB id: 0xffff8803d34c9780
    URB type: URB_SUBMIT ('S')
    URB transfer type: URB_BULK (0x03)
    Endpoint: 0x04, Direction: OUT
        0... .... = Direction: OUT (0)
        .000 0100 = Endpoint value: 4
    Device: 8
    URB bus id: 3
    Device setup request: not relevant ('-')
    Data: present (0)
    URB sec: 1453709794
    URB usec: 839335
    URB status: Operation now in progress (-EINPROGRESS) (-115)
    URB length [bytes]: 74
    Data length [bytes]: 74
    [Response in: 3512]
    [bInterfaceClass: Unknown (0xffff)]
Leftover Capture Data: 6f40000000003d04000000403c002a9e9a0000333031300d...

USB block:
0000  80 97 4c d3 03 88 ff ff 53 03 04 08 03 00 2d 00   ..L.....S.....-.
0010  e2 d9 a5 56 00 00 00 00 a7 ce 0c 00 8d ff ff ff   ...V............
0020  4a 00 00 00 4a 00 00 00 00 00 00 00 00 00 00 00   J...J...........
0030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
Payload: CCID block = CCID header (10 Byte) + T1 header (3 Byte) + APDU (60
Byte) + T1 CRC (1 Byte) = 74 Byte
0040  6f 40 00 00 00 00 3d 04 00 00 00 40 3c 00 2a 9e   o at ....=....@<.*.
0050  9a 00 00 33 30 31 30 0d 06 09 60 86 48 01 65 03   ...3010...`.H.e.
0060  04 02 01 05 00 04 20 da e5 62 1a cf f5 4a e8 b4   ...... ..b...J..
0070  a8 2e 69 5b ea 88 f1 eb c5 04 3e 08 5a 51 b8 d8   ..i[......>.ZQ..
0080  11 24 cf c4 b5 bd a7 08 00 1f                     .$........


Nitrokey log:
  25176 CCID USB EP_CCID_OUT buffer overflow
  25176 Get CCID USB block  74 byte

Received T1 block = T1 header (3 Byte) + APDU (60 Byte) + T1 CRC (1 Byte) =
64 Byte - the last 10 bytes from the USB packet are lost and filled by
random bytes
  50355 : Send T1 block - Comand len  64 -  Answer len  4  -   140 ms
Command - 00 40 3c 00 2a 9e 9a 00 00 33 30 31 30 0d 06 09 60 86 48 01 65 03
04 02 01 05 00 04 20 dd 34 2c 81 12 c7 49 df 74 65 a1 2d a0 25 0a e9 62 ce
6c f8 66 a8 b7 55 94 80 04 00 00 00 00 3d 00 00 00
          I-Block
          PERFORM SECURITY OPERATION
Answer  - 00 91 00 91
          R-Block
          00 91 00 91 = EDC- / parity error


Nitrokey USB descriptor - USB CCID buffer size = 64 byte

Bus 003 Device 032: ID 20a0:4109 Clay Logic
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x20a0 Clay Logic
  idProduct          0x4109
  bcdDevice            1.00
  iManufacturer           1 Nitrokey
  iProduct                2 Nitrokey Storage
  iSerial                 3 0000000000000
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength          141
    bNumInterfaces          3
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         8 Mass Storage
      bInterfaceSubClass      6 SCSI
      bInterfaceProtocol     80 Bulk-Only
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           3
      bInterfaceClass        11 Chip/SmartCard
      bInterfaceSubClass      0
      bInterfaceProtocol      0
      iInterface              0
      ChipCard Interface Descriptor:
        bLength                54
        bDescriptorType        33
        bcdCCID              1.10  (Warning: Only accurate for version 1.0)
        nMaxSlotIndex           0
        bVoltageSupport         2  3.0V
        dwProtocols             2  T=1
        dwDefaultClock       3600
        dwMaxiumumClock      3600
        bNumClockSupported      0
        dwDataRate           9677 bps
        dwMaxDataRate      116129 bps
        bNumDataRatesSupp.      0
        dwMaxIFSD              48
        dwSyncProtocols  00000000
        dwMechanical     00000000
        dwFeatures       000104BA
          Auto configuration based on ATR
          Auto voltage selection
          Auto clock change
          Auto baud rate change
          Auto PPS made by CCID
          Auto IFSD exchange
          TPDU level exchange
        dwMaxCCIDMsgLen        48
        bClassGetResponse      00
        bClassEnvelope         00
        wlcdLayout           none
        bPINSupport             0
        bMaxCCIDBusySlots       1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0010  1x 16 bytes
        bInterval              16
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x04  EP 4 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x85  EP 5 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      1 Keyboard
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      71
         Report Descriptors:
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x86  EP 6 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               5
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  bNumConfigurations      1
Device Status:     0x0000
  (Bus Powered)






Am 25.01.2016 12:59, schrieb rudbo:
> Hi Jan,
> 
> the problem from the ticket
> https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=775559 is in my 
> opinion an
> oversized USB packet.
> The failed APDU send by gpg2 has a length of 60 byte. The length of the 
> CCID
> packet is then 74 byte:
> 
> CCID packet = CCID header (10 Byte) + T1 header (3 Byte) + APDU (60 
> Byte) +
> T1 CRC (1 Byte) = 74 Byte
> 
> this CCID packet is send via 1 USB packet. Because the receive buffer 
> our
> USB device is only 64 byte large (send by the Nitrokey USB descriptor 
> to the
> system)
> the last 10 bytes of the payload are lost and replaced by random bytes. 
> This
> causes a  parity error when the data was send to the smartcard.
> 
> Greetings
> Rudolf
> 
> 
> Logs of the failed APDU (with different payloads because I couldn't log 
> all
> traces at the same time)
> 
> 
> Failed APDU - Length 60 byte
> 2016-01-25 11:49:23 scdaemon[9614] DBG: send apdu: c=00 i=2A p1=9E 
> p2=9A
> lc=51 le=2048 em=1
> 2016-01-25 11:49:23 scdaemon[9614] DBG:  raw apdu: 00 2A 9E 9A 00 00 33 
> 30
> 31 30 0D 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20 DD 34 2C 81 12 C7 
> 49
> DF 74 65 A1 2D A0 25 0A E9 62 CE 6C F8 66 A8 B7 55 94 04 DA 7C 55 AD D5 
> 3F
> 08 00
> 2016-01-25 11:49:46 scdaemon[9614] ccid_transceive failed: (0x1000a)
> 2016-01-25 11:49:46 scdaemon[9614] apdu_send_simple(0) failed: card I/O
> error
> 2016-01-25 11:49:46 scdaemon[9614] operation sign result: Input/output 
> error
> 2016-01-25 11:49:46 scdaemon[9614] app_sign failed: Input/output error
> 
> 
> USB CCID packet - payload length 74 Byte
> 
> No.     Time           Source                Destination           
> Protocol
> Length Info
>    3511 38.413647000   host                  8.4                   USB
> 138    URB_BULK out
> 
> Frame 3511: 138 bytes on wire (1104 bits), 138 bytes captured (1104 
> bits) on
> interface 0
>     Interface id: 0
>     Encapsulation type: USB packets with Linux header and padding (115)
>     Arrival Time: Jan 25, 2016 09:16:34.839335000 CET
>     [Time shift for this packet: 0.000000000 seconds]
>     Epoch Time: 1453709794.839335000 seconds
>     [Time delta from previous captured frame: 0.000037000 seconds]
>     [Time delta from previous displayed frame: 0.000037000 seconds]
>     [Time since reference or first frame: 38.413647000 seconds]
>     Frame Number: 3511
>     Frame Length: 138 bytes (1104 bits)
>     Capture Length: 138 bytes (1104 bits)
>     [Frame is marked: False]
>     [Frame is ignored: False]
>     [Protocols in frame: usb]
> USB URB
>     URB id: 0xffff8803d34c9780
>     URB type: URB_SUBMIT ('S')
>     URB transfer type: URB_BULK (0x03)
>     Endpoint: 0x04, Direction: OUT
>         0... .... = Direction: OUT (0)
>         .000 0100 = Endpoint value: 4
>     Device: 8
>     URB bus id: 3
>     Device setup request: not relevant ('-')
>     Data: present (0)
>     URB sec: 1453709794
>     URB usec: 839335
>     URB status: Operation now in progress (-EINPROGRESS) (-115)
>     URB length [bytes]: 74
>     Data length [bytes]: 74
>     [Response in: 3512]
>     [bInterfaceClass: Unknown (0xffff)]
> Leftover Capture Data: 
> 6f40000000003d04000000403c002a9e9a0000333031300d...
> 
> USB block:
> 0000  80 97 4c d3 03 88 ff ff 53 03 04 08 03 00 2d 00   
> ..L.....S.....-.
> 0010  e2 d9 a5 56 00 00 00 00 a7 ce 0c 00 8d ff ff ff   
> ...V............
> 0020  4a 00 00 00 4a 00 00 00 00 00 00 00 00 00 00 00   
> J...J...........
> 0030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   
> ................
> Payload: CCID block = CCID header (10 Byte) + T1 header (3 Byte) + APDU 
> (60
> Byte) + T1 CRC (1 Byte) = 74 Byte
> 0040  6f 40 00 00 00 00 3d 04 00 00 00 40 3c 00 2a 9e   
> o at ....=....@<.*.
> 0050  9a 00 00 33 30 31 30 0d 06 09 60 86 48 01 65 03   
> ...3010...`.H.e.
> 0060  04 02 01 05 00 04 20 da e5 62 1a cf f5 4a e8 b4   ...... 
> ..b...J..
> 0070  a8 2e 69 5b ea 88 f1 eb c5 04 3e 08 5a 51 b8 d8   
> ..i[......>.ZQ..
> 0080  11 24 cf c4 b5 bd a7 08 00 1f                     .$........
> 
> 
> Nitrokey log:
>   25176 CCID USB EP_CCID_OUT buffer overflow
>   25176 Get CCID USB block  74 byte
> 
> Received T1 block = T1 header (3 Byte) + APDU (60 Byte) + T1 CRC (1 
> Byte) =
> 64 Byte - the last 10 bytes from the USB packet are lost and filled by
> random bytes
>   50355 : Send T1 block - Comand len  64 -  Answer len  4  -   140 ms
> Command - 00 40 3c 00 2a 9e 9a 00 00 33 30 31 30 0d 06 09 60 86 48 01 
> 65 03
> 04 02 01 05 00 04 20 dd 34 2c 81 12 c7 49 df 74 65 a1 2d a0 25 0a e9 62 
> ce
> 6c f8 66 a8 b7 55 94 80 04 00 00 00 00 3d 00 00 00
>           I-Block
>           PERFORM SECURITY OPERATION
> Answer  - 00 91 00 91
>           R-Block
>           00 91 00 91 = EDC- / parity error
> 
> 
> Nitrokey USB descriptor - USB CCID buffer size = 64 byte
> 
> Bus 003 Device 032: ID 20a0:4109 Clay Logic
> Device Descriptor:
>   bLength                18
>   bDescriptorType         1
>   bcdUSB               2.00
>   bDeviceClass            0 (Defined at Interface level)
>   bDeviceSubClass         0
>   bDeviceProtocol         0
>   bMaxPacketSize0        64
>   idVendor           0x20a0 Clay Logic
>   idProduct          0x4109
>   bcdDevice            1.00
>   iManufacturer           1 Nitrokey
>   iProduct                2 Nitrokey Storage
>   iSerial                 3 0000000000000
>   bNumConfigurations      1
>   Configuration Descriptor:
>     bLength                 9
>     bDescriptorType         2
>     wTotalLength          141
>     bNumInterfaces          3
>     bConfigurationValue     1
>     iConfiguration          0
>     bmAttributes         0x80
>       (Bus Powered)
>     MaxPower              100mA
>     Interface Descriptor:
>       bLength                 9
>       bDescriptorType         4
>       bInterfaceNumber        0
>       bAlternateSetting       0
>       bNumEndpoints           2
>       bInterfaceClass         8 Mass Storage
>       bInterfaceSubClass      6 SCSI
>       bInterfaceProtocol     80 Bulk-Only
>       iInterface              0
>       Endpoint Descriptor:
>         bLength                 7
>         bDescriptorType         5
>         bEndpointAddress     0x81  EP 1 IN
>         bmAttributes            2
>           Transfer Type            Bulk
>           Synch Type               None
>           Usage Type               Data
>         wMaxPacketSize     0x0200  1x 512 bytes
>         bInterval               0
>       Endpoint Descriptor:
>         bLength                 7
>         bDescriptorType         5
>         bEndpointAddress     0x02  EP 2 OUT
>         bmAttributes            2
>           Transfer Type            Bulk
>           Synch Type               None
>           Usage Type               Data
>         wMaxPacketSize     0x0200  1x 512 bytes
>         bInterval               0
>     Interface Descriptor:
>       bLength                 9
>       bDescriptorType         4
>       bInterfaceNumber        1
>       bAlternateSetting       0
>       bNumEndpoints           3
>       bInterfaceClass        11 Chip/SmartCard
>       bInterfaceSubClass      0
>       bInterfaceProtocol      0
>       iInterface              0
>       ChipCard Interface Descriptor:
>         bLength                54
>         bDescriptorType        33
>         bcdCCID              1.10  (Warning: Only accurate for version 
> 1.0)
>         nMaxSlotIndex           0
>         bVoltageSupport         2  3.0V
>         dwProtocols             2  T=1
>         dwDefaultClock       3600
>         dwMaxiumumClock      3600
>         bNumClockSupported      0
>         dwDataRate           9677 bps
>         dwMaxDataRate      116129 bps
>         bNumDataRatesSupp.      0
>         dwMaxIFSD              48
>         dwSyncProtocols  00000000
>         dwMechanical     00000000
>         dwFeatures       000104BA
>           Auto configuration based on ATR
>           Auto voltage selection
>           Auto clock change
>           Auto baud rate change
>           Auto PPS made by CCID
>           Auto IFSD exchange
>           TPDU level exchange
>         dwMaxCCIDMsgLen        48
>         bClassGetResponse      00
>         bClassEnvelope         00
>         wlcdLayout           none
>         bPINSupport             0
>         bMaxCCIDBusySlots       1
>       Endpoint Descriptor:
>         bLength                 7
>         bDescriptorType         5
>         bEndpointAddress     0x83  EP 3 IN
>         bmAttributes            3
>           Transfer Type            Interrupt
>           Synch Type               None
>           Usage Type               Data
>         wMaxPacketSize     0x0010  1x 16 bytes
>         bInterval              16
>       Endpoint Descriptor:
>         bLength                 7
>         bDescriptorType         5
>         bEndpointAddress     0x04  EP 4 OUT
>         bmAttributes            2
>           Transfer Type            Bulk
>           Synch Type               None
>           Usage Type               Data
>         wMaxPacketSize     0x0040  1x 64 bytes
>         bInterval               0
>       Endpoint Descriptor:
>         bLength                 7
>         bDescriptorType         5
>         bEndpointAddress     0x85  EP 5 IN
>         bmAttributes            2
>           Transfer Type            Bulk
>           Synch Type               None
>           Usage Type               Data
>         wMaxPacketSize     0x0040  1x 64 bytes
>         bInterval               0
>     Interface Descriptor:
>       bLength                 9
>       bDescriptorType         4
>       bInterfaceNumber        2
>       bAlternateSetting       0
>       bNumEndpoints           1
>       bInterfaceClass         3 Human Interface Device
>       bInterfaceSubClass      0 No Subclass
>       bInterfaceProtocol      1 Keyboard
>       iInterface              0
>         HID Device Descriptor:
>           bLength                 9
>           bDescriptorType        33
>           bcdHID               1.10
>           bCountryCode            0 Not supported
>           bNumDescriptors         1
>           bDescriptorType        34 Report
>           wDescriptorLength      71
>          Report Descriptors:
>            ** UNAVAILABLE **
>       Endpoint Descriptor:
>         bLength                 7
>         bDescriptorType         5
>         bEndpointAddress     0x86  EP 6 IN
>         bmAttributes            3
>           Transfer Type            Interrupt
>           Synch Type               None
>           Usage Type               Data
>         wMaxPacketSize     0x0040  1x 64 bytes
>         bInterval               5
> Device Qualifier (for other device speed):
>   bLength                10
>   bDescriptorType         6
>   bcdUSB               2.00
>   bDeviceClass            0 (Defined at Interface level)
>   bDeviceSubClass         0
>   bDeviceProtocol         0
>   bMaxPacketSize0        64
>   bNumConfigurations      1
> Device Status:     0x0000
>   (Bus Powered)

-- 
Jan Suhr

Nitrokey UG (haftungsbeschränkt)
Web: https://www.nitrokey.com

Email: jan at nitrokey.com
Phone: +49 163 7010 408

Berliner Str. 166, 10715 Berlin, Germany
CEO / Geschäftsführer: Jan Suhr
Register Record: AG Charlottenburg, HRB 164549 B
VAT ID / USt-IdNr.: DE300136599



More information about the Gnupg-devel mailing list