diff --git a/applications/debug/ccid_test/ccid_test_app.c b/applications/debug/ccid_test/ccid_test_app.c index abb8ad3dd..4158c1a60 100644 --- a/applications/debug/ccid_test/ccid_test_app.c +++ b/applications/debug/ccid_test/ccid_test_app.c @@ -105,7 +105,7 @@ void ccid_test_app_free(CcidTestApp* app) { furi_record_close(RECORD_GUI); app->gui = NULL; - free(app->iso7816_handler); + iso7816_handler_free(app->iso7816_handler); // Free rest free(app); @@ -121,8 +121,7 @@ int32_t ccid_test_app(void* p) { furi_hal_usb_unlock(); furi_check(furi_hal_usb_set_config(&usb_ccid, &app->ccid_cfg) == true); - furi_hal_usb_ccid_set_callbacks( - (CcidCallbacks*)&app->iso7816_handler->ccid_callbacks, app->iso7816_handler); + iso7816_handler_set_usb_ccid_callbacks(); furi_hal_usb_ccid_insert_smartcard(); //handle button events @@ -142,7 +141,7 @@ int32_t ccid_test_app(void* p) { } //tear down USB - furi_hal_usb_ccid_set_callbacks(NULL, NULL); + iso7816_handler_reset_usb_ccid_callbacks(); furi_hal_usb_set_config(usb_mode_prev, NULL); //teardown view diff --git a/applications/debug/ccid_test/iso7816/iso7816_handler.c b/applications/debug/ccid_test/iso7816/iso7816_handler.c index 97214d1b2..8f0f758b2 100644 --- a/applications/debug/ccid_test/iso7816/iso7816_handler.c +++ b/applications/debug/ccid_test/iso7816/iso7816_handler.c @@ -6,11 +6,17 @@ #include #include +#include "iso7816_handler.h" + #include "iso7816_t0_apdu.h" #include "iso7816_atr.h" -#include "iso7816_handler.h" #include "iso7816_response.h" +static Iso7816Handler* iso7816_handler; +static CcidCallbacks* ccid_callbacks; +static uint8_t* command_apdu_buffer; +static uint8_t* response_apdu_buffer; + void iso7816_icc_power_on_callback(uint8_t* atr_data, uint32_t* atr_data_len, void* context) { furi_check(context); @@ -40,12 +46,11 @@ void iso7816_xfr_datablock_callback( Iso7816Handler* handler = (Iso7816Handler*)context; - ISO7816_Response_APDU* response_apdu = (ISO7816_Response_APDU*)&handler->response_apdu_buffer; - - ISO7816_Command_APDU* command_apdu = (ISO7816_Command_APDU*)&handler->command_apdu_buffer; + ISO7816_Response_APDU* response_apdu = (ISO7816_Response_APDU*)response_apdu_buffer; + ISO7816_Command_APDU* command_apdu = (ISO7816_Command_APDU*)command_apdu_buffer; uint8_t result = iso7816_read_command_apdu( - command_apdu, pc_to_reader_datablock, pc_to_reader_datablock_len); + command_apdu, pc_to_reader_datablock, pc_to_reader_datablock_len, CCID_SHORT_APDU_SIZE); if(result == ISO7816_READ_COMMAND_APDU_OK) { handler->iso7816_process_command(command_apdu, response_apdu); @@ -61,8 +66,31 @@ void iso7816_xfr_datablock_callback( } Iso7816Handler* iso7816_handler_alloc() { - Iso7816Handler* handler = malloc(sizeof(Iso7816Handler)); - handler->ccid_callbacks.icc_power_on_callback = iso7816_icc_power_on_callback; - handler->ccid_callbacks.xfr_datablock_callback = iso7816_xfr_datablock_callback; - return handler; + iso7816_handler = malloc(sizeof(Iso7816Handler)); + + command_apdu_buffer = malloc(sizeof(ISO7816_Command_APDU) + CCID_SHORT_APDU_SIZE); + response_apdu_buffer = malloc(sizeof(ISO7816_Response_APDU) + CCID_SHORT_APDU_SIZE); + + ccid_callbacks = malloc(sizeof(CcidCallbacks)); + ccid_callbacks->icc_power_on_callback = iso7816_icc_power_on_callback; + ccid_callbacks->xfr_datablock_callback = iso7816_xfr_datablock_callback; + + return iso7816_handler; +} + +void iso7816_handler_set_usb_ccid_callbacks() { + furi_hal_usb_ccid_set_callbacks(ccid_callbacks, iso7816_handler); +} + +void iso7816_handler_reset_usb_ccid_callbacks() { + furi_hal_usb_ccid_set_callbacks(NULL, NULL); +} + +void iso7816_handler_free(Iso7816Handler* handler) { + free(ccid_callbacks); + + free(command_apdu_buffer); + free(response_apdu_buffer); + + free(handler); } diff --git a/applications/debug/ccid_test/iso7816/iso7816_handler.h b/applications/debug/ccid_test/iso7816/iso7816_handler.h index d67118ce6..4f9703e46 100644 --- a/applications/debug/ccid_test/iso7816/iso7816_handler.h +++ b/applications/debug/ccid_test/iso7816/iso7816_handler.h @@ -5,14 +5,14 @@ #include "iso7816_t0_apdu.h" typedef struct { - CcidCallbacks ccid_callbacks; void (*iso7816_answer_to_reset)(Iso7816Atr* atr); void (*iso7816_process_command)( const ISO7816_Command_APDU* command, ISO7816_Response_APDU* response); - - uint8_t command_apdu_buffer[sizeof(ISO7816_Command_APDU) + CCID_SHORT_APDU_SIZE]; - uint8_t response_apdu_buffer[sizeof(ISO7816_Response_APDU) + CCID_SHORT_APDU_SIZE]; } Iso7816Handler; Iso7816Handler* iso7816_handler_alloc(); + +void iso7816_handler_free(Iso7816Handler* handler); +void iso7816_handler_set_usb_ccid_callbacks(); +void iso7816_handler_reset_usb_ccid_callbacks(); diff --git a/applications/debug/ccid_test/iso7816/iso7816_t0_apdu.c b/applications/debug/ccid_test/iso7816/iso7816_t0_apdu.c index 216f2582f..023daebe2 100644 --- a/applications/debug/ccid_test/iso7816/iso7816_t0_apdu.c +++ b/applications/debug/ccid_test/iso7816/iso7816_t0_apdu.c @@ -1,49 +1,48 @@ /* Implements rudimentary iso7816-3 support for APDU (T=0) */ #include #include -#include -#include #include "iso7816_t0_apdu.h" -//reads dataBuffer with dataLen size, translate it into a ISO7816_Command_APDU type +//reads pc_to_reader_datablock_len with pc_to_reader_datablock_len size, translate it into a ISO7816_Command_APDU type //extra data will be pointed to commandDataBuffer uint8_t iso7816_read_command_apdu( ISO7816_Command_APDU* command, - const uint8_t* dataBuffer, - uint32_t dataLen) { - command->CLA = dataBuffer[0]; - command->INS = dataBuffer[1]; - command->P1 = dataBuffer[2]; - command->P2 = dataBuffer[3]; + const uint8_t* pc_to_reader_datablock, + uint32_t pc_to_reader_datablock_len, + uint32_t max_apdu_size) { + command->CLA = pc_to_reader_datablock[0]; + command->INS = pc_to_reader_datablock[1]; + command->P1 = pc_to_reader_datablock[2]; + command->P2 = pc_to_reader_datablock[3]; - if(dataLen == 4) { + if(pc_to_reader_datablock_len == 4) { command->Lc = 0; command->Le = 0; command->LePresent = false; return ISO7816_READ_COMMAND_APDU_OK; - } else if(dataLen == 5) { + } else if(pc_to_reader_datablock_len == 5) { //short le command->Lc = 0; - command->Le = dataBuffer[4]; + command->Le = pc_to_reader_datablock[4]; command->LePresent = true; return ISO7816_READ_COMMAND_APDU_OK; - } else if(dataLen > 5 && dataBuffer[4] != 0x00) { + } else if(pc_to_reader_datablock_len > 5 && pc_to_reader_datablock[4] != 0x00) { //short lc - command->Lc = dataBuffer[4]; - if(command->Lc > 0 && command->Lc < CCID_SHORT_APDU_SIZE) { //-V560 - memcpy(command->Data, &dataBuffer[5], command->Lc); + command->Lc = pc_to_reader_datablock[4]; + if(command->Lc > 0 && command->Lc < max_apdu_size) { //-V560 + memcpy(command->Data, &pc_to_reader_datablock[5], command->Lc); //does it have a short le too? - if(dataLen == (uint32_t)(command->Lc + 5)) { + if(pc_to_reader_datablock_len == (uint32_t)(command->Lc + 5)) { command->Le = 0; command->LePresent = false; return ISO7816_READ_COMMAND_APDU_OK; - } else if(dataLen == (uint32_t)(command->Lc + 6)) { - command->Le = dataBuffer[dataLen - 1]; + } else if(pc_to_reader_datablock_len == (uint32_t)(command->Lc + 6)) { + command->Le = pc_to_reader_datablock[pc_to_reader_datablock_len - 1]; command->LePresent = true; return ISO7816_READ_COMMAND_APDU_OK; diff --git a/applications/debug/ccid_test/iso7816/iso7816_t0_apdu.h b/applications/debug/ccid_test/iso7816/iso7816_t0_apdu.h index a21dfbafc..bbd2a1b23 100644 --- a/applications/debug/ccid_test/iso7816/iso7816_t0_apdu.h +++ b/applications/debug/ccid_test/iso7816/iso7816_t0_apdu.h @@ -34,7 +34,8 @@ typedef struct { uint8_t iso7816_read_command_apdu( ISO7816_Command_APDU* command, const uint8_t* pc_to_reader_datablock, - uint32_t pc_to_reader_datablock_len); + uint32_t pc_to_reader_datablock_len, + uint32_t max_apdu_size); void iso7816_write_response_apdu( const ISO7816_Response_APDU* response, uint8_t* reader_to_pc_datablock,