Javacard and session variables

Hello,

I'm trying to find a reasonable Javacard technique to handle "session variables" that must be kept between successive APDUs, but must be re-initialized on each card reset (and/or each time the application is selected); e.g. currently selected file, currently selected record, current session key, has the user PIN been verified...

Such variables are best held in RAM, since changing permanent (EEPROM or Flash) variables is so slow (and in the long run limiting the operational life of the card).

Examples in the Java Card Kit 2.2.2 (e.g. JavaPurseCrypto.java) manipulate session variables in the following way:

1) The programmers group session variables of basic type (Short, Byte, Boolean) according to type, and map each such variable at an explicit index of a vector (one per basic type used as session variable).

2) At install() time, each such vector, and each vector session variable, is explicitly allocated as a transient object, and this object is stored in a field of the application (in permanent memory), where it remains across resets.

3) Each use of a session variable of basic type is explicitly translated by the programmer into using the appropriately numbered element of the appropriate vector.

4) Vector session variables require no further syntactic juggling, but eat up an object descriptor worth of permanent data memory (EEPROM or Flash), and a function call + object affectation worth of applet-storage memory (EEPROM, Flash or ROM).

The preparatory phase goes:

publicclass MyAppextends Applet{

// transientShorts array indices

finalstaticbyte TN_IX = 0;

finalstaticbyte NEW_BALANCE_IX=(byte)TN_IX+1;

finalstaticbyte CURRENT_BALANCE_IX=(byte)NEW_BALANCE_IX+1;

finalstaticbyte AMOUNT_IX=(byte)CURRENT_BALANCE_IX+1;

finalstaticbyteTRANSACTION_TYPE_IX=(byte)AMOUNT_IX+1;

finalstaticbyteSELECTED_FILE_IX=(byte)TRANSACTION_TYPE_IX+1;

finalstaticbyteNUM_TRANSIENT_SHORTS=(byte)SELECTED_FILE_IX+1;

// transientBools array indices

finalstaticbyte TRANSACTION_INITIALIZED=0;

finalstaticbyte UPDATE_INITIALIZED=(byte)TRANSACTION_INITIALIZED+1;

finalstaticbyteNUM_TRANSIENT_BOOLS=(byte)UPDATE_INITIALIZED+1;

(..)

// remanent variables holding reference for transient variables

privateshort[]transientShorts;

privateboolean[]transientBools;

privatebyte[]CAD_ID_array;

privatebyte[]byteArray8;// Signature work array

(..)

// install method

publicstaticvoid install(byte[] bArray,short bOffset,byte bLength ){

//Create transient objects.

transientShorts = JCSystem.makeTransientShortArray( NUM_TRANSIENT_SHORTS,

JCSystem.CLEAR_ON_DESELECT);

transientBools = JCSystem.makeTransientBooleanArray( NUM_TRANSIENT_BOOLS,

JCSystem.CLEAR_ON_DESELECT);

CAD_ID_array = JCSystem.makeTransientByteArray( (short)4,

JCSystem.CLEAR_ON_DESELECT);

byteArray8 = JCSystem.makeTransientByteArray( (short)8,

JCSystem.CLEAR_ON_DESELECT);

(..)

and when it's time for usage, things go:

if (transientShorts[SELECTED_FILE_IX] == (short)0)

transientShorts[SELECTED_FILE_IX] == fid;

transientBools[UPDATE_INITIALIZED] =

sig.verify(MAC_buffer, (short)0, (short)10,

byteArray8, START, SIGNATURE_LENGTH);

I find this

a) Verbose and complex.

b) Error-prone: there is nothing to prevent the accidental use of transientShorts[UPDATE_INITIALIZED].

c) Wastefull of memory: each use of a basic-type state variable wastes some code; each vector state variable wastes an object-descriptor worth of permanent data memory, and code for its allocation.

d) Slow at runtime: each use of a "session variable", especially of a basic type, goes thru method invocation(s) which end up painfully slow (at least on some cards), to the point that for repeated uses, one often attain a nice speedup by caching a session variable, and/or transientShorts and the like, into local variables.

As an aside, I don't get if the true allocation of RAM occurs at install time (implying non-selected applications eat up RAM), or at application selection (implying hidden extra overhead).

I dream of an equivalent for the C idiom "struct of state variables". Are these issues discussed, in a Sun manual, or elsewhere? Is there a better way?

Other desperate questions: does a C compiler that output Javacard bytecode make sense/exists? Or a usable Javacard bytecode assembler?

Francois Grieu

[6873 byte] By [fgrieua] at [2007-11-26 21:41:31]
# 1

Interesting post.

I don't have a solution to your problem, but caching the session variables arrays in local variable arrays is a good start. This should be only done when the applet is in context, e.g. selected or accessed through the shareable interface. This values should be written back to EEPROM at e.g. deselect or some other important point of time. Do you run into problems if a tear happens? I don't think so since the session variables should be transactional, and a defined point will commit a transaction.

Analyzing the bytecode is a good idea. I know of a view in JCOP Tools (Eclipse plugin) where you can analyze the bytecode and optimize it to your needs.

lexdabeara at 2007-7-10 3:27:03 > top of Java-index,Java Mobility Forums,Consumer and Commerce...
# 2

Thanks for the comments.

> Do you run into problems if a tear happens?

No. My "session variables" are expected to be lost on tear/reset. I want them this way, and in RAM rather than permanent (EEPROM/Flash) memory.

The Sun-blessed technique in my post does just this, and works fine, so that, at least, writing session variables does not write into EEPROM, which would be an immense disaster from a speed and functionality standpoint.

I'm "only" after something better from a syntatic, code size, and efficiency standpoint.

Francois Grieu

fgrieua at 2007-7-10 3:27:03 > top of Java-index,Java Mobility Forums,Consumer and Commerce...