Adding support for chained apdu in emulation mode.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2023-01-17 00:06:17 +01:00
parent 00f9e9c408
commit a9eee861fe
2 changed files with 19 additions and 5 deletions

View File

@@ -84,7 +84,7 @@ size_t apdu_process(uint8_t itf, const uint8_t *buffer, size_t buffer_size) {
} }
//printf("apdu.nc %ld, apdu.ne %ld\r\n",apdu.nc,apdu.ne); //printf("apdu.nc %ld, apdu.ne %ld\r\n",apdu.nc,apdu.ne);
if (apdu.header[1] == 0xc0) { if (apdu.header[1] == 0xc0) {
//printf("apdu.ne %ld, apdu.rlen %d, bk %x\r\n",apdu.ne,apdu.rlen,rdata_bk); printf("apdu.ne %u, apdu.rlen %d, bk %x\r\n",apdu.ne,apdu.rlen,rdata_bk);
timeout_stop(); timeout_stop();
*(uint16_t *)rdata_gr = rdata_bk; *(uint16_t *)rdata_gr = rdata_bk;
if (apdu.rlen <= apdu.ne) { if (apdu.rlen <= apdu.ne) {
@@ -95,6 +95,10 @@ size_t apdu_process(uint8_t itf, const uint8_t *buffer, size_t buffer_size) {
#ifdef USB_ITF_CCID #ifdef USB_ITF_CCID
if (itf == ITF_CCID) if (itf == ITF_CCID)
driver_exec_finished_cont_ccid(apdu.rlen+2, rdata_gr-usb_get_tx(itf)); driver_exec_finished_cont_ccid(apdu.rlen+2, rdata_gr-usb_get_tx(itf));
#endif
#ifdef ENABLE_EMULATION
if (itf == ITF_EMUL)
driver_exec_finished_cont_emul(apdu.rlen+2, rdata_gr-usb_get_tx(itf));
#endif #endif
//Prepare next RAPDU //Prepare next RAPDU
apdu.sw = 0; apdu.sw = 0;
@@ -119,6 +123,10 @@ size_t apdu_process(uint8_t itf, const uint8_t *buffer, size_t buffer_size) {
#ifdef USB_ITF_CCID #ifdef USB_ITF_CCID
if (itf == ITF_CCID) if (itf == ITF_CCID)
driver_exec_finished_cont_ccid(apdu.ne+2, rdata_gr-apdu.ne-usb_get_tx(card_locked_itf)); driver_exec_finished_cont_ccid(apdu.ne+2, rdata_gr-apdu.ne-usb_get_tx(card_locked_itf));
#endif
#ifdef ENABLE_EMULATION
if (itf == ITF_EMUL)
driver_exec_finished_cont_emul(apdu.ne+2, rdata_gr-apdu.ne-usb_get_tx(card_locked_itf));
#endif #endif
} }
apdu.rlen -= apdu.ne; apdu.rlen -= apdu.ne;
@@ -178,10 +186,12 @@ void apdu_finish() {
apdu.rdata[apdu.rlen] = apdu.sw >> 8; apdu.rdata[apdu.rlen] = apdu.sw >> 8;
apdu.rdata[apdu.rlen+1] = apdu.sw & 0xff; apdu.rdata[apdu.rlen+1] = apdu.sw & 0xff;
timeout_stop(); timeout_stop();
#ifndef ENABLE_EMULATION
if ((apdu.rlen + 2 + 10) % 64 == 0) if ((apdu.rlen + 2 + 10) % 64 == 0)
{ // FIX for strange behaviour with PSCS and multiple of 64 { // FIX for strange behaviour with PSCS and multiple of 64
apdu.ne = apdu.rlen - 2; apdu.ne = apdu.rlen - 2;
} }
#endif
} }
size_t apdu_next() { size_t apdu_next() {

View File

@@ -103,15 +103,19 @@ int driver_write_emul(const uint8_t *buffer, size_t buffer_size) {
} }
uint32_t emul_write_offset(uint16_t size, uint16_t offset) { uint32_t emul_write_offset(uint16_t size, uint16_t offset) {
if (size > 0) {
//DEBUG_PAYLOAD(usb_get_tx(ITF_EMUL)+offset, size); //DEBUG_PAYLOAD(usb_get_tx(ITF_EMUL)+offset, size);
return usb_write_offset(ITF_EMUL, size, offset); return usb_write_offset(ITF_EMUL, size, offset);
} }
return 0;
}
uint32_t emul_write(uint16_t size) { uint32_t emul_write(uint16_t size) {
return emul_write_offset(size, 0); return emul_write_offset(size, 0);
} }
void driver_exec_finished_cont_emul(size_t size_next, size_t offset) { void driver_exec_finished_cont_emul(size_t size_next, size_t offset) {
emul_write_offset(size_next, offset);
} }
int driver_process_usb_packet_emul(uint16_t len) { int driver_process_usb_packet_emul(uint16_t len) {
@@ -127,7 +131,7 @@ int driver_process_usb_packet_emul(uint16_t len) {
} }
else { else {
DEBUG_PAYLOAD(data, len); DEBUG_PAYLOAD(data, len);
apdu_process(ITF_EMUL, data, len); if (apdu_process(ITF_EMUL, data, len) > 0)
process_apdu(); process_apdu();
apdu_finish(); apdu_finish();
size_t ret = apdu_next(); size_t ret = apdu_next();