Safe Max Java Card APDU Data Command and Respond Size
Asked Answered
D

3

6

What is the recommended data field size in a Java Card APDU ? From Zhiqun Chen's Java Card Technology for Smart Cards: Architecture and Programmer's Guide book, it mentions that Le field allows a max of 255.

Are we to interpret it as follow for the APDU Command:

|<----------------------- 255 Bytes total ------------------------>|
|<- CLA -><- INS -><- P1 -><- P2 -><- Lc -><---- DATA ----><- Le ->|

Thus, if CLA, INS, P1, P2, Lc, Le are all 1 bytes each, we should assume that the we can safely only set 249 bytes into the DATA region ?

For the APDU Response are we to interpret:

|<----------------------- 258 Bytes total ------------------------>|
|<-------------------------- DATA ------------------------><- SW ->|

The response data can safely be set to 256 bytes with 2 bytes of SW and total of a response consisting of data response and SW is 258 bytes ?

What other considerations to safely send and receive data in chunks considering we have to face situations where chaining might not be possible and we have to manually handle data flow ourselves ?

Dade answered 7/10, 2015 at 14:27 Comment(0)
F
2

Lc and Le byte can signalize to hold/request upto 0xFF bytes. So for a Case 4 command APDU you have 6(header+lc+le) + 0xFF = 261 bytes. For a maxiumum response you have 256 bytes + 2(Statusword) = 258 bytes. This is what the standard would suggest. However, diffrent hardware tokens might have different implementations so this might not be 100% accurate. If you need more data you need to implement ExtendedLength.

Ferocious answered 8/10, 2015 at 0:13 Comment(8)
Are there anyway to accurately gauge the size of the APDU from the Java Card API besides asking the card vendor ?Dade
Test your card. What's your specific goal?Ferocious
I want to create a generic protocol between host and card that can be used on as many card platforms and usable on cards that don't support chaining.Dade
Well the numbers above are from the standards and the minimum every card should supportFerocious
To get the size of APDU buffer the APDU.getCurrentAPDUBuffer().length should work.Grantor
unfortunately this does not work. If you have a Javacard that supports extended length, but runs without the Extended Length interface, it does return the whole ext-length buffer size although you can only use the basic apdu sizeFerocious
You are right -- in this case it is not possible to use the whole APDU buffer size for communication.Grantor
The first sentence is certainly wrong. Lc and Le bytes are encodings of Nc and Ne respectively. Neither can signal zero bytes as absence of data is signalled by the field not being present (or you could say it is encoded in zero bytes, but I digress). Lc = 00h is invalid (it would indicate extended length instead) and Le = 00 indicates an Ne - the maximum response size - of 256 bytes. So Lc is indeed limited to 255 but Le can indicate 256 (0x100) bytes as max. response.Apollo
G
7

AFAIK the Le field allows 1-256 bytes (the 255 limit is for Lc) citing ISO 7816-3:

Case 2S ⎯ The short Le field consists of C(5) encoding Ne from 1 to 256 ('00' means the maximum, 256)....
....
Case 4S ⎯ ...The short Le field consists of C(6+Nc) encoding Ne from 1 to 256 ('00' means the maximum, 256)....

(And it is in line with your "Response APDU" length of 256+2, maybe it is just a typo)

The 255-byte limit is for the DATA part of "Command APDU". So for the whole non-extended length "Command APDU" the limit should be 5+255+1.

All those limits are precisely defined in ISO 7816-3 -- have a look here.


Beware, that the javacard's APDU buffer might be smaller. From the javadoc of the APDU class:

The buffer length (meaning APDU buffer) must be at least 133 bytes ( 5 bytes of header and 128 bytes of data)

Thus to read incoming data longer than 128 bytes you might need to call APDU.receiveBytes() to fetch the rest of bytes that didn't fit.

The same might apply for sending data (i.e. APDU.sendBytes() might be needed to send longer data).


For application level framing, I am aware of these methods (might be inspirational):

  • ISO 7816-4 (using bit 5 in CLA)

  • Global platform (using the most significant bit of P1 to indicate more blocks/last block for some commands)

  • EMV CPS (STORE DATA command using explicit lengths inside data)

Grantor answered 8/10, 2015 at 23:49 Comment(5)
you are absolutely right about Le is 1-256 bytes. great answer!Ferocious
Hi vlp, is it correct that with "ISO 7816-4 (using bit 5 in CLA)" you are mentioning command chaining?Apollo
Beware that this answer is written with T=0 in mind. With T=CL and T=1 extended length may be supported. If so it should be indicated in the ATS or ATR respectively (usually just "ATR" in programming APIs).Apollo
@MaartenBodewes Yes I mean command chaining. Answer is written with short lengts in mind (actually I am not a big fan of extended-length APDUs because /unfortunately/ many times there is no support on card or reader side). And note that even T=0 cards can support extended-length APDUs (see section Command-response pair transmission by T=0 in ISO 7816-3).Grantor
There was a time that readers finally all supported extended length without buffering issues etc. However, then came the time of cheap NFC chips in mobile phones and even laptops etc., and we are back at square one. To be honest, the whole smart card communication needs an overhaul, but with mobile payment etc. getting more and more attention, I don't think that anybody is that interested.Apollo
F
2

Lc and Le byte can signalize to hold/request upto 0xFF bytes. So for a Case 4 command APDU you have 6(header+lc+le) + 0xFF = 261 bytes. For a maxiumum response you have 256 bytes + 2(Statusword) = 258 bytes. This is what the standard would suggest. However, diffrent hardware tokens might have different implementations so this might not be 100% accurate. If you need more data you need to implement ExtendedLength.

Ferocious answered 8/10, 2015 at 0:13 Comment(8)
Are there anyway to accurately gauge the size of the APDU from the Java Card API besides asking the card vendor ?Dade
Test your card. What's your specific goal?Ferocious
I want to create a generic protocol between host and card that can be used on as many card platforms and usable on cards that don't support chaining.Dade
Well the numbers above are from the standards and the minimum every card should supportFerocious
To get the size of APDU buffer the APDU.getCurrentAPDUBuffer().length should work.Grantor
unfortunately this does not work. If you have a Javacard that supports extended length, but runs without the Extended Length interface, it does return the whole ext-length buffer size although you can only use the basic apdu sizeFerocious
You are right -- in this case it is not possible to use the whole APDU buffer size for communication.Grantor
The first sentence is certainly wrong. Lc and Le bytes are encodings of Nc and Ne respectively. Neither can signal zero bytes as absence of data is signalled by the field not being present (or you could say it is encoded in zero bytes, but I digress). Lc = 00h is invalid (it would indicate extended length instead) and Le = 00 indicates an Ne - the maximum response size - of 256 bytes. So Lc is indeed limited to 255 but Le can indicate 256 (0x100) bytes as max. response.Apollo
A
0

The Lc and Le fields encode the maximum data size, Nc and Ne. Nc maxes out on 256 (Lc = 00h, a special case) and Ne maxes at 255 (Le = FFh) for normal length APDU's where the Lc & Le fields are 1 byte each. The Nc does not include the 4 byte header, the Lc encoding or Le encoding. The size specified by Ne doesn't include the 2 byte (16 bit) status word.


It is of course possible to send more data for a particular command. You can use extended length if the card supports it. See ISO/IEC 7816-4 for details.

Extended length uses 16 bit effective Lc and Le sizes. It can support up to 64KiB for Nc (effective part is 0000h) and 64KiB - 1 for Ne (effective part of Le = FFFFh). However, due to the use of signed short, Java Card is limited to Nc = 32KiB - 1 and Ne = 32KiB - 1 when using extended length. Generally you'd run out of buffer space long before that, it depends on the card implementation how this is handled. Extended length also grows the header, Lc and Le overhead.

Command chaining is trickier because you'd have to implement it yourself. It basically sends the same command multiple times, using the chaining bit in the CLA byte to indicate that more commands will follow, until the bit is reset to zero.


Of course you can do anything with the commands yourself. So you can e.g. define a file and write to that using multiple WRITE BINARY commands. How you define these commands is all up to you.


I'll not go into maximum sizes when secure messaging is used. It makes for some very interesting calculations, especially if BER encoding is used to implement secure messaging.

Apollo answered 4/7, 2021 at 17:19 Comment(1)
Beware that extended length must be supported by the complete card-reader-driver chain. If any of them does not support extended-length APDUs then you are stuck with normal (short) lengths. See here for some background info about extended-length support by CCID readers.Grantor

© 2022 - 2024 — McMap. All rights reserved.