[Pcsclite-muscle] What's responsible to filter out Le in Case 4 C-APDUs under T=0?

Francois Grieu fgrieu at gmail.com
Wed Feb 9 12:30:20 PST 2022

On 2022-02-09 at 20:03, Michael StJohns wrote :
> On 2/9/2022 1:02 PM, Francois Grieu wrote:
> > On 2022-02-08 at 23:53, s.ferey  wrote :
> > > When T=0 protocol is used a case-4 can NOT contain a Le.
> >
> > The definition of Case 4 is given by ISO/IEC 7816-3:2006 section 12:
> > ] In case 4, Nc ≠ 0 and Nr ≠ 0. The command APDU consists of the 
> > header, the Lc field, the command data field and the Le field. The 
> > response APDU consists of the response data field and the trailer.
> >
> > Therefore, independently of the protocol, Le is present in a case 4 
> > APDU, and in the corresponding Command APDU. Under T=0, Le must not be 
> > present in the first C-TPDU, nor physically sent to the card as part 
> > of that (only later on, conditionally). That does not tell if Le 
> > can/should be passed to ScardTransmit; or in other words if 
> > ScardTransmit is passed a C-APDU or a C-TPDU.
> >
> > Under T=0 case 1, the specification of ScardTransmit REQUIRES passing 
> > to ScardTransmit the 4-byte C-APDU, not the 5-byte C-TPDU. Quoting 
> > https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardtransmit
> > } For T=0, in the special case where no data is sent to the card and 
> > no data expected in return, this length [of the data passed to 
> > ScardTransmit] must reflect that the bP3 member is not being sent; the 
> > length should be sizeof(CmdBytes) - sizeof(BYTE) [that is 4]
> This is strange, but probably correct. From PCSC 3 -
> > T=0 Protocol Support
> > From the ICC Service Provider perspective, an IFD Subsystem shall 
> > accept Case 1, 2 or 3 short APDUs, as defined in ISO 7816-4 and 
> > asynchronously return the response from the ICC. Direct Case 4 APDU 
> > support is not required. The IFD Subsystem shall change this APDU to 
> > TPDU for T=0 command. Especially it is mandatory to change APDU case1 
> > format (CLA INS P1 P2) to TPDU with P3='00' (CLA INS P1 P2 '00').
> So that may explain why this only applies to Case 1.    I think for case
> 2, you pass in Le as the P3 TPDU parameter and the IFD figures out that
> this is case 2 due to the lack of any follow on data bytes.  Strangely,
> that means the card can't actually tell the difference between a Case 1
> APDU and a Case 2 APDU with Le=0 except by how the card defines the INS.
Yes. The card is supposed to determine the transfer direction from CLA INS P1 P2 
P3, and the reader is supposed to reach the same conclusion from the structure 
of the C-APDU. More often than not that fails, e.g. in Select where data 
transfer direction in the first T=0 TPDU is variable. That mess boils down to 
decisions made in the early 1980's at Bull CP8, like inverse convention and the 
error signal. But at least, that got clearly documented.
> > I'm ready to admit ScardTransmit is supposed to be passed a C-TPDU 
> > except as stated by the above quote. I just wish some reference 
> > stating that (..)
> I'm pretty sure that SCardTransmit should get passed a TPDU and not an
> APDU.  I was looking for a definitive answer in the PCSC specifications,
> specifically PCSC 3, and the closest I come is to section which
> says that a Case 4 APDU can't be used - instead use GET RESPONSE (and I
> guess  use a Case 3 APDU).
> > • A case 4 APDU cannot be used. It is the responsibility of the 
> > application or the service provider to generate a « get response » if 
> > they need it.
> This is not exactly what ISO7816-3 says, but it's sort of a reasonable
> interpretation of how to map APDUs to TPDUs for T=0. Case 3 and Case 4
> APDUs have the same format for the first command TPDU.
Does PCSC specify the interface between the application and ScardTransmit ? I 
though it was one layer closer to the reader. In which case "A case 4 APDU 
cannot be used" would not necessarily apply to the input of ScardTransmit.
> > Perhaps useful to settle that debate: under T=1, even in short cases, 
> > it can be necessary to break the C-APDU into several C-TPDUs. Is that 
> > the job of ScardTransmit+driver, or is that the job of the application ?
> I think you're confusing Blocks and TPDUs.   The TPDU for T=1 is the
> same as the APDU.  But the underlying driver has to deal with the block
> by block T=1 transmission.

Quoting ISO/IEC 7616-3:2006, 12.3.1 and 12.3.5

] This clause defines the mapping of application protocol data units (APDU) into 
information fields of transmission protocol data units (TPDU) by T=1. (..)
] Cases 4S and 4E: The command APDU is mapped without any change onto either
] — the information field of one I-block, or
] — the concatenation of the information fields of successive I-blocks. These 
blocks shall be chained.

My reading is that under T=1, a TPDU is the information field of an individual 
I-block; and in case 4, when there is sizable data, there can be multiple 
I-blocks/C-TPDUs for a single C-APDU.

Thus I stand by the idea that it's useful to examine if the splitting of C-APDU 
into small blocks is the responsibility of ScardTransmit or of the application 
using it. I don't know that, having experience of T=1 only at the card and 
reader level, not at the (win)scard level.
If ScardTransmit was to receive C-TPDUs under T=1, I'd wholeheartedly admit it's 
to receive C-TPDUs under T=0 too (with a minor deviation in case 1).
But if ScardTransmit was to receive C-APDUs under T=1, and under T=0 cases 1, 
2S, 3S, I'd stick to believe that it/it's driver should at least be ready to 
also accept full C-APDUs under case 4S.

> (..) I'd just check for the protocol and assume for T=0 that you have to
> special case Case 4 APDUs.

This has one big advantage: it's sure to work around the issue I have with this 
driver. Thanks for your input.

   François Grieu

More information about the pcsclite-muscle mailing list