Skip to content

Commit

Permalink
Update SC_Secure to fit with CCID spec; remove useless parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
cedelavergne-ledger committed Jan 4, 2024
1 parent 7fd1703 commit 9564251
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 37 deletions.
5 changes: 2 additions & 3 deletions lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/sc_itf.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,15 @@ 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,
uint8_t bClassEnvelope);
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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@
#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 PC_TO_RDR_ICCPOWERON 0x62
#define PC_TO_RDR_ICCPOWEROFF 0x63
#define PC_TO_RDR_GETSLOTSTATUS 0x65
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;

Expand All @@ -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);
Expand All @@ -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;

Expand Down
56 changes: 31 additions & 25 deletions lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,49 +526,55 @@ 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;
RDR_to_PC_DataBlock(SLOTERROR_CMD_NOT_SUPPORTED);
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 App (like OpenPGP)
pbuf[0] = 0xEF;
// 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;
Expand Down

0 comments on commit 9564251

Please sign in to comment.