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

