From 1bdd75945ab24af7b40d8d90bedd02931e3879cd Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Thu, 4 Jan 2024 09:25:19 +0100 Subject: [PATCH] Update SC_Secure to fit with CCID spec; remove useless parameters --- .../Class/CCID/inc/sc_itf.h | 5 +- .../Class/CCID/inc/usbd_ccid_if.h | 8 +++ .../Class/CCID/src/usbd_ccid_cmd.c | 12 +--- .../Class/CCID/src/usbd_ccid_if.c | 56 ++++++++++--------- 4 files changed, 44 insertions(+), 37 deletions(-) diff --git a/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/sc_itf.h b/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/sc_itf.h index dfac8d607..8babdec31 100644 --- a/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/sc_itf.h +++ b/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/sc_itf.h @@ -64,7 +64,7 @@ uint8_t SC_ExecuteEscape (uint8_t* escapePtr, uint32_t escapeLen, uint8_t* responseBuff, uint16_t* responseLen); uint8_t SC_SetClock (uint8_t bClockCommand); -uint8_t SC_XferBlock (uint8_t* ptrBlock, uint32_t blockLen, uint16_t* expectedLen); +uint8_t SC_XferBlock (uint8_t* ptrBlock, uint32_t blockLen); uint8_t SC_Request_GetClockFrequencies(uint8_t* pbuf, uint16_t* len); uint8_t SC_Request_GetDataRates(uint8_t* pbuf, uint16_t* len); uint8_t SC_T0Apdu(uint8_t bmChanges, uint8_t bClassGetResponse, @@ -72,8 +72,7 @@ uint8_t SC_T0Apdu(uint8_t bmChanges, uint8_t bClassGetResponse, uint8_t SC_Mechanical(uint8_t bFunction); uint8_t SC_SetDataRateAndClockFrequency(uint32_t dwClockFrequency, uint32_t dwDataRate); -uint8_t SC_Secure(uint32_t dwLength, uint8_t bBWI, uint16_t wLevelParameter, - uint8_t* pbuf, uint32_t* returnLen ); +uint8_t SC_Secure(uint8_t* pbuf, uint32_t* returnLen); #endif // HAVE_USB_CLASS_CCID diff --git a/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/usbd_ccid_if.h b/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/usbd_ccid_if.h index 7cd8ecd39..1e077a7c8 100644 --- a/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/usbd_ccid_if.h +++ b/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/usbd_ccid_if.h @@ -58,6 +58,14 @@ #define VOLTAGE_SELECTION_5V 0x01 #define VOLTAGE_SELECTION_1V8 0x03 +/* PC_to_RDR_Secure PIN operations */ +#define PIN_OPR_VERIFICATION 0x00 +#define PIN_OPR_MODIFICATION 0x01 +#define PIN_OPR_TRANSFER 0x02 +#define PIN_OPR_WAIT_ICC_RESP 0x03 +#define PIN_OPR_CANCEL 0x04 +#define PIN_OPR_APDU_CLA 0xEF + #define PC_TO_RDR_ICCPOWERON 0x62 #define PC_TO_RDR_ICCPOWEROFF 0x63 #define PC_TO_RDR_GETSLOTSTATUS 0x65 diff --git a/lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_cmd.c b/lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_cmd.c index 0682de887..e75501c60 100644 --- a/lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_cmd.c +++ b/lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_cmd.c @@ -247,10 +247,7 @@ uint8_t PC_to_RDR_XfrBlock(void) G_io_ccid.bulk_header.bulkin.dwLength = (uint16_t)expectedLength; - - error = SC_XferBlock(&G_io_ccid_data_buffer[0], - reqlen, - &expectedLength); + error = SC_XferBlock(&G_io_ccid_data_buffer[0], reqlen); if (error != SLOT_NO_ERROR) { @@ -693,7 +690,6 @@ uint8_t PC_TO_RDR_SetDataRateAndClockFrequency(void) uint8_t PC_TO_RDR_Secure(void) { uint8_t error; - uint8_t bBWI; uint16_t wLevelParameter; uint32_t responseLen; @@ -707,14 +703,13 @@ uint8_t PC_TO_RDR_Secure(void) return error; } - bBWI = G_io_ccid.bulk_header.bulkout.bSpecific_0; wLevelParameter = (G_io_ccid.bulk_header.bulkout.bSpecific_1 + ((uint16_t)G_io_ccid.bulk_header.bulkout.bSpecific_2<<8)); if ((EXCHANGE_LEVEL_FEATURE == TPDU_EXCHANGE) || (EXCHANGE_LEVEL_FEATURE == SHORT_APDU_EXCHANGE)) { /* TPDU level & short APDU level, wLevelParameter is RFU, = 0000h */ - if (wLevelParameter != 0 ) + if (wLevelParameter != 0) { G_io_ccid.bulk_header.bulkin.dwLength = 0; CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); @@ -723,8 +718,7 @@ uint8_t PC_TO_RDR_Secure(void) } } - error = SC_Secure(G_io_ccid.bulk_header.bulkout.dwLength - CCID_HEADER_SIZE, bBWI, wLevelParameter, - &G_io_ccid_data_buffer[0], &responseLen); + error = SC_Secure(&G_io_ccid_data_buffer[0], &responseLen); G_io_ccid.bulk_header.bulkin.dwLength = responseLen; diff --git a/lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_if.c b/lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_if.c index eaa83b816..fc05b9466 100644 --- a/lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_if.c +++ b/lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_if.c @@ -526,35 +526,39 @@ uint8_t SC_SetDataRateAndClockFrequency(uint32_t dwClockFrequency, UNUSED(dwDataRate); return SLOT_NO_ERROR; } -uint8_t SC_Secure(uint32_t dwLength, uint8_t bBWI, uint16_t wLevelParameter, - uint8_t* pbuf, uint32_t* returnLen ) { - UNUSED(bBWI); - UNUSED(wLevelParameter); - UNUSED(returnLen); - // return SLOTERROR_CMD_NOT_SUPPORTED; - uint16_t ret_len,off; +uint8_t SC_Secure(uint8_t* pbuf, uint32_t* returnLen) { + // Extract the APDU to send to the App switch(pbuf[0]) { - case 0: // verify pin - ret_len = dwLength - 15; - memmove(G_io_apdu_buffer, pbuf+15, dwLength-15); + case PIN_OPR_VERIFICATION: + // CCID Spec: APDU starts at offset 25, after the 10-Byte header + pbuf += 15; break; - case 1: // modify pin + case PIN_OPR_MODIFICATION: + // CCID Spec: APDU starts at offset 28, 29 or 30 + // depending on the nb of messages to display switch(pbuf[11]) { - case 3: - off = 20; + case 0: + // CCID Spec: No message to display + // APDU starts at offset 28, after the 10-Byte header + pbuf += 18; break; - case 2: case 1: - off = 19; + case 2: + // CCID Spec: 1 or 2 message(s) to display + // APDU starts at offset 29, after the 10-Byte header + pbuf += 19; break; - // 0 and 4-0xFF - default: - off = 18; + case 3: + // CCID Spec: 3 messages to display + // APDU starts at offset 30, after the 10-Byte header + pbuf += 20; break; + default: // unsupported + G_io_ccid.bulk_header.bulkin.dwLength = 0; + RDR_to_PC_DataBlock(SLOTERROR_CMD_NOT_SUPPORTED); + CCID_Send_Reply(&USBD_Device); + return SLOTERROR_CMD_NOT_SUPPORTED; } - ret_len = dwLength-off; - // provide with the complete apdu - memmove(G_io_apdu_buffer, pbuf+off, dwLength-off); break; default: // unsupported G_io_ccid.bulk_header.bulkin.dwLength = 0; @@ -562,13 +566,15 @@ uint8_t SC_Secure(uint32_t dwLength, uint8_t bBWI, uint16_t wLevelParameter, CCID_Send_Reply(&USBD_Device); return SLOTERROR_CMD_NOT_SUPPORTED; } - return SC_XferBlock(G_io_apdu_buffer, ret_len, &ret_len); + // Change APDU CLA to be interpreted by the CCID compatible App (like OpenPGP) + pbuf[0] = PIN_OPR_APDU_CLA; + // The APDU has no data, only the header (size 5) + *returnLen = 5; + return SC_XferBlock(pbuf, *returnLen); } // prepare the apdu to be processed by the application -uint8_t SC_XferBlock (uint8_t* ptrBlock, uint32_t blockLen, uint16_t* expectedLen) { - UNUSED(expectedLen); - +uint8_t SC_XferBlock (uint8_t* ptrBlock, uint32_t blockLen) { // check for overflow if (blockLen > IO_APDU_BUFFER_SIZE) { return SLOTERROR_BAD_LENTGH;