Nitrokey / nitrokey-pro-firmware

Firmware for the Nitrokey Pro device
GNU General Public License v3.0
117 stars 21 forks source link

Fix USB buffer description table corruption #72

Open cyril-L opened 4 years ago

cyril-L commented 4 years ago

CCID_ENDP0_RXADDR was set to 0x18, so 64 bytes incoming buffers were written from 0x18 to 0x57 in the packet memory area (PMA).

// CCIDHID_usb_conf.h
#define BTABLE_ADDRESS      (0x00)
#define CCID_ENDP0_RXADDR        (0x18)

// CCIDHID_usb_props.c
SetEPRxAddr (ENDP0, CCID_ENDP0_RXADDR);

This area contained the USB buffer description table (BTABLE) entry for endpoint 4 (0x20 to 0x5F), defining its buffer address to 0x19C.

// CCIDHID_usb_conf.h
#define ENDP4_TXADDR        (0x19C);

// CCIDHID_usb_props.c
SetEPTxAddr (ENDP4, ENDP4_TXADDR);

Data sent to the host with endpoint 4 was not the buffer located at the defined address (0x19C) but some other data from the PMA, depending on how the BTABLE was corrupted.

// keyboard.c
// Copies data to 0x19C
UserToPMABufferCopy (buffer, ENDP4_TXADDR, 8);
// Sends something else
SetEPTxCount (ENDP4, 8);
SetEPTxStatus (ENDP4, EP_TX_VALID);

It can be reproduced in the main loop like so:

int main(void) {
    // …
    int i = 0;
    while (1) {
        if ((i++ % 100000) == 0) {
            sendKeys((uint8_t *) "01234567");
        }
    }
    // …
}

When looking at usb traffic with Wireshark, the received data on endpoint 4 receives some data other than 01234567.