From 7c38eced518a638e29a3cb0ef014ed842e8e0a3c Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 12 Jul 2026 22:00:55 +0200 Subject: [PATCH] CCID now bounds initial XfrBlock APDU responses to the advertised payload budget and converts oversized responses into 61xx chaining instead of cutting off the status word. Signed-off-by: Pol Henarejos --- src/usb/ccid/ccid.c | 7 +++++++ src/usb/usb.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/usb/ccid/ccid.c b/src/usb/ccid/ccid.c index b92707b..e9a5d3a 100644 --- a/src/usb/ccid/ccid.c +++ b/src/usb/ccid/ccid.c @@ -57,6 +57,7 @@ #define CCID_MSG_CHAIN_OFFSET 9 #define CCID_MSG_DATA_OFFSET 10 /* == CCID_MSG_HEADER_SIZE */ #define CCID_MAX_MSG_DATA_SIZE USB_BUF_SIZE +#define CCID_MAX_XFR_BLOCK_DATA_SIZE (USB_BUFFER_SIZE - CCID_MSG_DATA_OFFSET) #define CCID_STATUS_RUN 0x00 #define CCID_STATUS_PRESENT 0x01 @@ -336,6 +337,12 @@ void driver_exec_finished_ccid(uint8_t itf, uint16_t size_next) { } void driver_exec_finished_cont_ccid(uint8_t itf, uint16_t size_next, uint16_t offset) { + if (offset == 0) { + size_next = apdu_limit_response(size_next, CCID_MAX_XFR_BLOCK_DATA_SIZE); + } + else if (size_next > CCID_MAX_XFR_BLOCK_DATA_SIZE) { + size_next = CCID_MAX_XFR_BLOCK_DATA_SIZE; + } ccid_response[itf] = (ccid_header_t *) (ccid_tx[itf].buffer + ccid_tx[itf].w_ptr + offset); ccid_response[itf]->bMessageType = CCID_DATA_BLOCK_RET; ccid_response[itf]->dwLength = size_next; diff --git a/src/usb/usb.h b/src/usb/usb.h index f2b9ed4..2eb2c33 100644 --- a/src/usb/usb.h +++ b/src/usb/usb.h @@ -118,7 +118,7 @@ extern void driver_exec_finished_cont_emul(uint8_t itf, uint16_t size_next, uint #endif #ifndef USB_BUFFER_SIZE -#define USB_BUFFER_SIZE 2048 +#define USB_BUFFER_SIZE 2048u #endif PACK(