I'm trying to understand the way T0
protocol works in smart cards. Based on the corresponding standard (ISO/IEC 7816/3), the communication in this protocol initiates by sending a 5-byte command header (CLA-INS-P1-P2-P3) from the reader to the card; and after this header, the reader shall wait for a procedure byte from the card. The prodecure byte can be one of the following values:
60
=> It is NULL(!), the reader shall wait for anotherprocedure byte
6X
(!60) or9X
=> The value is SW1, and the reader shall wait for the SW2INS
orINS^FF
=> It is an ACK. The reader shall send the remaining bytes
Let's assume that the reader send AA BB CC DD EE
to the card. The question is that How does the card can find out if the EE value in the received header is for a case 2 (Le), 3(Lc) or 4 (Lc) APDU command?
And also I can't understand why it is invalid to use 6X
and 9X
for INS values. Actually it makes sense to prevent developer to use 60
for SW1 (Because then the reader can not distinguish SW1 from NULL procedure byte), but it does not make sense to prevent him from using 6X
and 9X
for INS values. Any clue?
I've checked whole the document to find out any information regarding this question, but the more I read the more I get confused. The relation between APDU and TPDU is not distinguishable also.
As you've already indicated yourself, the T=0 protocol does a terrible job when it comes to separating layers. And the question you've asked shows that this is not just the case between the data link & transport layer, but also between the transport layer and the application layer.
The simple truth is that the card knows which command is being send when looking at the 4 bytes of the header. It simply knows how to interpret P3 by looking at the other values. That's also why you won't find any commands that switch case based on information within P3 or any C_DATA (command data).
In Java Card you can see the following remark for
setIncomingAndReceive
:so the transport buffer simply contains the 5 byte header initially and then you should only retrieve data after you've inspected the header. Of course, the card may have already received other data because of some buffering taking place - especially for T=1 and T=CL, but you should definitely not assume such a thing in advance.
Note that secure messaging (commonly case 4, as you also want to protect the header & status words) is detected using the first CLA byte, so just looking at the INS may not be enough. Similarly the SELECT command has different "ISO cases" that depend on the values of P1/P2. If you define your own APDU's then it is up to you of course.