popovec/oseid

translate the file "card_io.S" into a human readable file "card_io.c"

edbek opened this issue · 6 comments

edbek commented

Is it possible to translate the file "card_io.S" into a human readable file "card_io.c" in C code?

Which version of card_io.s are you interested in? We have a version for MCU atmega128 and for AVR128DA32 .. (the code strongly depends on the hardware of the mentioned processor, especially in the part that initializes and tests the timer/counter). The communication of the card that uses the code written in C will be significantly slower .. (approximately 10x).

edbek commented

I'm interested in the card_io.s version for the AVR128DA32 processor.

Also, I have another question:
now the card_io.s module is written in such a way that it blocks the execution of the rest of the code (it's just linear code), if it were. Have you thought about making this code non-blocking? For example, one could use the example "AVR274: Single-wire Software UART" as a basis.
Thanks in advance.

Non blocking code makes no sense here. Communication between (any) card reader and (any, not only OsEID) card is always blocking. Card is waiting for command (APDU/TPDU) and generates response (APDU/TPDU) to command. Card reader is always waiting for response.

But OK, there is still a need to carry out actions that are not "blocked", for example, by a longer calculation in the card.

If there is no way to generate response from the card in predefined interval, card is able to request "more working time" from the card reader. If the card does not request "more working time", and is unable to generate requested response in predefined interval, the card reader mark the card as non responsive. Please read ISO7816-3 about card/card-reader communication, there is lot information about ATR, where the predefined response time is signalized from card to card reader.

In OsEID project (atmega128, AVR128DA), hardware interrupt (from timer) is used to generate "request for more working time" (the card_io_start_null() function). NULL byte (0x60 - "request for more working time") is periodically sent to the card reader even card is working in long loop - for example - key generation function. T1 protocol does not send byte 0x60 (as request for more working time) instead, a special frame is sent to the card reader (more in ISO7816-3).

In xmega code (where xmega is used as card reader and card in one MCU), interrupt system from USB hardware is used as task switcher between the card reader task and the card task. Even complete card (task) reset is possible, USB subsystem is not affected here. The card task does not block the USB card reader function - in real action, USB subsystem generates responses for interrupt/bulk transfer even there is long task (key generation) running in card application.

Also note, none of the available hardware resources in the AVR128DA32 can fully replace the transmission defined in ISO7816-3. For this reason that (communication) code is written in ASM, using the method of bitbanging (for sending) and repeated sampling for receiving - including requesting corrections (repeat byte) for the T0 protocol (when detecting a parity error). Even code written using interrupts (from a timer) is slower (due to latencies caused by calls to the interrupt handler).

If I managed to find enough free time, I will prepare the C version of card_io.c for the AVR128DA32 processor. Maybe part of C code in https://github.com/popovec/tpdu-logger/blob/main/tpdu_logger.c may help you to understand card receive code (similar to card_io.s).

edbek commented

Thanks, we are waiting for the implementation on the processor AVR128DA.
I do not think that there will be such a delay (approximately 10x) in the work of the processor when converting its asm-code to C-code.

C code is available:

https://github.com/popovec/oseid/blob/test/src/targets/AVR128DA/card_io.c

The C code uses a different sampling method, so it is possible to achieve 300kbit/s. However, the size of the code is slightly larger.

Solved by commit 37aa69b