JavaCard Memory

I made a simple applet to test the speed of adding arrays, depending whether they are saved in EEPROM or RAM. Since working with variables stored in RAM should be faster, I was really surprised when I noticed no difference between them. I would really like to know where I went wrong, but simply can-t figure it out, so any help would be really appreciated. I used Eclipse 3.2 with JCOP Tools 3.1.1b and JCOP31 v2.2 JavaCard. The code I produced is:
package test;
import javacard.framework.APDU;
import javacard.framework.ISO7816;
import javacard.framework.Applet;
import javacard.framework.ISOException;
import javacard.framework.JCSystem;
public class SimpleMemoryTest extends Applet {
     private static final short ARRAY_SIZE = 32;
     byte[] eeprom_a,  eeprom_b, eeprom_c;
     byte[] ram_a, ram_b, ram_c;
     short[] mem;
     private SimpleMemoryTest() {
          this.mem = new short[2];
     public static void install(byte[] bArray, short bOffset, byte bLength) {
          new SimpleMemoryTest().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
     public void process(APDU apdu) {
          if (selectingApplet()) return;
          byte[] buf = apdu.getBuffer();
          switch (buf[ISO7816.OFFSET_INS]) {
          case (byte) 0x00: { // Print memory info to verify where arrays are stored
               mem[0] = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
               mem[1] = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);
               buf[0] = (byte)(mem[0] / 256);
               buf[1] = (byte)(mem[0] % 256);
               buf[2] = (byte)(mem[1] / 256);
               buf[3] = (byte)(mem[1] % 256);
               apdu.setOutgoingAndSend((short)0, (short)4);
               break;
          case (byte) 0x01: { // Put arrays in EEPROM.
               this.eeprom_a = new byte[ARRAY_SIZE];
               this.eeprom_b = new byte[ARRAY_SIZE];
               this.eeprom_c = new byte[ARRAY_SIZE];
               break;
          case (byte) 0x02: { // Put arrays in RAM.
               this.ram_a = JCSystem.makeTransientByteArray(ARRAY_SIZE, JCSystem.CLEAR_ON_DESELECT);
               this.ram_b = JCSystem.makeTransientByteArray(ARRAY_SIZE, JCSystem.CLEAR_ON_DESELECT);
               this.ram_c = JCSystem.makeTransientByteArray(ARRAY_SIZE, JCSystem.CLEAR_ON_DESELECT);
               break;
          case (byte) 0x03: { // Add arrays in EEPROM 100 times
               short i, j;
               for (i = (short) 0; i < (short) 100; i++) {
                    for (j = (short) 0; j < (short) ARRAY_SIZE; j++) {
                         eeprom_c[j] = (byte)(eeprom_a[j] + eeprom_b[j]);
               break;
          case (byte) 0x04: { // Add arrays in RAM 100 times
               short i, j;
               for (i = (short) 0; i < (short) 100; i++) {
                    for (j = (short) 0; j < (short) ARRAY_SIZE; j++) {
                         ram_c[j] = (byte)(ram_a[j] + ram_b[j]);
               break;
          default:
               ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}

When you create a byte array, all values are initialized to 0. Looking at your loops, it seems you're adding 0's only. Smart card operating systems normally do a read before write, to make sure not the same value is written. It saves time, and in case of EEPROM also to prolong the lifetime. I think this is the reason why you see no difference .. because there is no writing. Do something like
eeprom_c[j] = (byte)(i + j);
Matjaz wrote:          case (byte) 0x03: { // Add arrays in EEPROM 100 times
               short i, j;
               for (i = (short) 0; i < (short) 100; i++) {
                    for (j = (short) 0; j < (short) ARRAY_SIZE; j++) {
                         eeprom_c[j] = (byte)(eeprom_a[j] + eeprom_b[j]);
               break;
          case (byte) 0x04: { // Add arrays in RAM 100 times
               short i, j;
               for (i = (short) 0; i < (short) 100; i++) {
                    for (j = (short) 0; j < (short) ARRAY_SIZE; j++) {
                         ram_c[j] = (byte)(ram_a[j] + ram_b[j]);
               break;

Similar Messages

  • Channel 0 deselection and JCSystem.makeTransientByteArray memory issues

    Hi,
    I am writing an applet that should among other things generate HMAC-SHA1 value. However, JCDK 3.02 Classic edition RI does not support Signature.ALG_HMAC_SHA1. That is why I had to make my own HMAC-SHA1 based on MessageDigest.getInstance(MessageDigest.ALG_SHA,false)The problem is that when I transfer data to my HMAC-SHA1 function I create byte [] workbuffer = JCSystem.makeTransientByteArray((short)(blockLength + datalength), JCSystem.CLEAR_ON_DESELECT); inside of my HMAC-SHA1 function. I cannot do memory allocation in constructor since I don't know the data length in advance. This function works fine only the first time, on the second run the apllet runs out of memory.
    From my MIDlet I call myConnection.close() to close the connection and deselect the applet before passing new data to applet for HMAC generation. But according to Security and Trust Services APIs for Java 2 Platform "the application selected on channel 0 is not deselected at the time the connection is closed but remains selected until a new connection is established on channel 0". So, the next time I open connection to my applet and pass data to HMAC-SHA1 I get throw_error(SYSTEMEXCEPT_NO_TRANSIENT_SPACE) from cref in the console window.
    Is there anything I can do with this memory problem? How can I eventually deselect the applet to free the memory?
    //Aleksandr

    Argh! Poor card :-)
    NEVER allocate memory outside of the constructor or initialization methods (called once then disabled)! Forget JavaCard 3, use 2.2 and remember you have 2KB RAM in all cards of these world. The 2MB-RAM/16MB-Flash cards simulated in the javacard SDK for netbeans exists only in the imagination of this spec creators.
    Allocate a fixed size buffer and process data in blocks. The update() method is here for this purpose.
    This is not java desktop, memory is more than scarce!
    transient memory allocated with the TRANSIENT_DESELECT flag is allocated for every logical channels to allow implementing multi selectable applets with independent contexts.
    transient memory allocated with the TRANSIENT_RESET flag is allocated once for every channels.

  • 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:
    public class MyApp extends Applet  {
    // transientShorts array indices
        final static byte       TN_IX = 0;
        final static byte       NEW_BALANCE_IX=(byte)TN_IX+1;
        final static byte      CURRENT_BALANCE_IX=(byte)NEW_BALANCE_IX+1;
        final static byte      AMOUNT_IX=(byte)CURRENT_BALANCE_IX+1;
        final static byte   TRANSACTION_TYPE_IX=(byte)AMOUNT_IX+1;
        final static byte     SELECTED_FILE_IX=(byte)TRANSACTION_TYPE_IX+1;
        final static byte   NUM_TRANSIENT_SHORTS=(byte)SELECTED_FILE_IX+1;
    // transientBools array indices
        final static byte       TRANSACTION_INITIALIZED=0;
        final static byte       UPDATE_INITIALIZED=(byte)TRANSACTION_INITIALIZED+1;
        final static byte   NUM_TRANSIENT_BOOLS=(byte)UPDATE_INITIALIZED+1;
    // remanent variables holding reference for transient variables
        private short[]     transientShorts;
        private boolean[]   transientBools;
        private byte[]      CAD_ID_array;
        private byte[]      byteArray8;  // Signature work array
    // install method
        public static void 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

    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.

  • How to store data,key,cert,... in javacard

    I'm newbie in javacard
    I develop it by use RMI model
    I develop to similar EMV specification but don't exactly
    EMV spec told me that data element such as KEY, CERT,COUNTER,ExpirationDate,...anything. will be keep in file , with tree structure.
    above is not importance
    I try to understand: How to save file into javacard?
    I read a lot of help and manual from sdk , this website ,forum
    and I feel it's impossible to save file (such as text file *.txt, photo file *.jpeg,*.gif) into javacard directly,
    Is my understand correct?
    I try to understand PhotoCardApplet Demo that come with sdk
    run it , have fun with it, try to understand code
    I saw the demo bring the pictures file from reader-side save into card to the "Object" of byte[]
    Is there just only one way to keep KEY,CERT,..DATA in Object in the applet?
    Can it possible to seperate these data away from applet and keep it individual? ( seperate applet , text file ,photo file ,... keep in javacard)
    And if it possible plz tell me how to do it with detailed.
    thx for every answer.

    EMV spec told me that data element such as KEY,
    CERT,COUNTER,ExpirationDate,...anything. will be
    keep in file , with tree structure.That is the file-system part of an EMV smart card. That has nothing (directly) to do with java cards. Most java cards has a file system part, too but that isn't accessible from within the java card applet.
    I try to understand PhotoCardApplet Demo that come
    with sdk
    run it , have fun with it, try to understand code
    I saw the demo bring the pictures file from
    reader-side save into card to the "Object" of
    byte[]
    Is there just only one way to keep KEY,CERT,..DATA
    in Object in the applet?
    Can it possible to seperate these data away from
    applet and keep it individual? ( seperate applet ,
    text file ,photo file ,... keep in javacard)
    No, loading data into the memory which belongs to your java card applet instance makes the data become a part of the applet. If you delete the applet all stored data will be deleted, too.
    You can only separate different objects within your applet by using separate byte-arrays or other java card objects.
    Jan

  • Maximum array length in javacard

    hi all
    i have a java class with 20 member variables.
    member variables are array of bytes. i doesn't allocate
    memory for this variables in class constructor,
    memory for this variables is dynamically allocated
    in my javacard applet (*runtime*).
    i defined an array of this class in my applet( in applet constructor):
    myclassArray = new myclass[MAX]
    for ( short i =0; i < MAX; i++ )
        myclassArray[i] = new myclass();myclass.java:
           class myclass {
                 byte[] membervariable1;
                  setVar1( byte[] input) {
                   membervariable1 = input;
            }if MAX >= 100 , i can't load applet on the card.
    (error :conditions of use not satisfied)
    why this problem occurs? my card is 32k and i doesn't allocate memory for myclass member variables in applet constructor;
    maybe an array of class in javacard has a maximum value in its length. am i right?
    thanks,
    siavash

    s.fallahdoost wrote:
    hi all
    i have a java class with 20 member variables.
    member variables are array of bytes. i doesn't allocate
    memory for this variables in class constructor,It doesn't look like it. If you look at the code snippet below, which is located in the constructor, you are allocating memory in the loop.
    memory for this variables is dynamically allocated
    in my javacard applet (*runtime*).Does not like it neither. If you look at your second code snippet, you're jusr re-referencing the pointer to another instance.
    i defined an array of this class in my applet( in applet constructor):
    myclassArray = new myclass[MAX]
    for ( short i =0; i < MAX; i++ )
    myclassArray[i] = new myclass();myclass.java:
    class myclass {
    byte[] membervariable1;
    setVar1( byte[] input) {
    membervariable1 = input;
    }if MAX >= 100 , i can't load applet on the card.
    (error :conditions of use not satisfied)Could be, since you're allocating memory in the constructor.
    why this problem occurs? my card is 32k and i doesn't allocate memory for myclass member variables in applet constructor;
    maybe an array of class in javacard has a maximum value in its length. am i right?The maximum array length is 32k.

  • Has any one used RSA on Gemplus Xpresso Javacards? (JC 2.1.1)

    Hello,
    i ve been trying to generate an RSA keypair on my Xpresso card, but the applet fails to load... what i try is...
    package packJCardDemo1;
    import javacard.framework.*;
    import javacard.security.*;
    public class CardRWV extends Applet {
    private static KeyPair keypair;
    public static void install(byte[] buffer, short offset, byte length) {
    memory = new byte[SIZE_MEMORY];
    pin = new OwnerPIN(DEFAULT_PIN_MAX, PIN_SIZE);
    pin.update(DEFAULT_PIN, (short)(0), PIN_SIZE);
    try {
    keypair = new KeyPair( KeyPair.ALG_RSA, KeyBuilder.LENGTH_RSA_512 );
    } catch (CryptoException ce) {
    if (ce.getReason() == CryptoException.UNINITIALIZED_KEY)
    ISOException.throwIt(ISO7816.SW_FILE_FULL);
    else if (ce.getReason() == CryptoException.INVALID_INIT)
    ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);
    else if (ce.getReason() == CryptoException.ILLEGAL_USE)
    ISOException.throwIt(ISO7816.SW_FILE_INVALID);
    else if (ce.getReason() == CryptoException.NO_SUCH_ALGORITHM)
    ISOException.throwIt(ISO7816.SW_WRONG_ALG);
    else
    ISOException.throwIt(ISO7816.SW_RECORD_NOT_FOUND);
    new CardRWV().register();
    The compile runs ok, but when i try to load the applet into the card it fails (the install method generates an exception). If i put the try-catch in comments my applet loads normally...
    Also when is use debug i get these messages indicating that RSA is (should be) implemented...
    Checking crypto providers...
    "DESede/ECB/NoPadding" feature found in provider: "SunJCE"
    DES/3DES feature is ok...
    "RSA/ECB/NoPadding" feature found in provider: "GemplusCrypto"
    RSA feature is ok...
    Any help would be appreciated!
    Best Regards
    John

    I found the problem, when i removed the key building from the install method and placed it in a separate block the applet installed correctly, but when i request the building of a pair of keys, a Crypto exception NO_SUCH_ALGORITHM is thrown. I have used RSA, RSA_CRT, DSA (every possible length combination) but i get the same exception. If anyone has implemented RSA on a Gemplus (Gemxplore Xpresso Range) card please give me your lights.
    Thanks in advance!
    John

  • Can I create DESKey in transient memory?

    I'm newbie to JavaCard and my questrions are:
    1. Can I create DESKey in transient memory?
    I'm migrating my PKI applet from MULTOS to JavaCard version. When the RSA key pair is loaded into card, I hope the key pair is protected by session key. The session key will be derived from the secret shared by card and terminal, say, user PIN, The best place to hold the session key is in transient memory. I think all the key objects are created in non-volatile ram.Is that right?
    2. Will the key object(DESKey and RSAKey) keep the key data permanently?Or just keep reference to the data?
    3. Are the cipher classes singleton classes?
    Thanks in advance.
    Regards,
    ZJ Yang

    Samples come with the kit. They all are downloadable from Sun. Read a article on the Sun wireless site. There are tons of sources here and with the kit that shows you how to write an applet. Just looking at the Applet class in the API docs will give you a quick sample. The APDU class in the API docs give you a snippet as well.

  • Javacard apdu

    Hi you all,
    I'm trying to run the apdutool.
    I first had the
    "Exception in thread 'main' java.lang.NoClassDefFoundError: javax/comm/PortInUseException" message and I tried then to install the comm api to fix this.
    But since I've added comm.jar to my classpath, I get an application error message from java.exe saying:
    "The memory could not be 'read' " when running apdutool.
    Worst, it seems like converter is crashing for the same reason as well since then.
    I suspect that while I'm running it with JDK 1.4, some troubles might appear.
    Is there anybody to confirm it or help me to work that out ??
    Thanks in advance

    Yes it is.
    I've found a work around to that.
    What I do is compiling everything without adding comm.jar to the environment and from another command prompt then run the apdutool.
    It seems ok this way. Everything is still not clear to what happens but at least I managed to simulate my javacard applet.

  • SimAlliance Loader for JavaCards - Question

    Hello everybody
    I have a question about the SimAlliance Loader for Javacards. I found this tool at www.simalliance.org.
    My question is about the "Memory Configuration", there are three fields to fill out.
    1. Package Non Volatile Memory Size (in bytes)
    2. Installation Non Volatile Memory Size (in bytes)
    3. Installation Volatile Memory Size (in bytes)
    as default is the value 00 00 what I have to put in there?
    In the Help File I could find following description:
    Memory configuration
    Enter the memory space required by the applet to be loaded and installed.
    Note:The default values proposed in the project settings are appropriate for most applets. It is therefore strongly recommended to leave these parameters unchanged.
    Package Non Volatile Memory Size
    If necessary, specify the size of the executable load file (package) generated by the selected Converter tool.
    Installation Non Volatile Memory Size
    If necessary, specify the number of bytes of EEPROM memory required to store the applet�s objects and data arrays.
    Installation Volatile Memory Size
    If necessary, specify the number of bytes of RAM memory required for the applet�s transient data.
    Thanks in advance. Please post me a sample description.
    Regards
    Linga

    Hello everybody
    I have a question about the SimAlliance Loader for Javacards. I found this tool at www.simalliance.org.
    My question is about the "Memory Configuration", there are three fields to fill out.
    1. Package Non Volatile Memory Size (in bytes)
    2. Installation Non Volatile Memory Size (in bytes)
    3. Installation Volatile Memory Size (in bytes)
    as default is the value 00 00 what I have to put in there?
    In the Help File I could find following description:
    Memory configuration
    Enter the memory space required by the applet to be loaded and installed.
    Note:The default values proposed in the project settings are appropriate for most applets. It is therefore strongly recommended to leave these parameters unchanged.
    Package Non Volatile Memory Size
    If necessary, specify the size of the executable load file (package) generated by the selected Converter tool.
    Installation Non Volatile Memory Size
    If necessary, specify the number of bytes of EEPROM memory required to store the applet�s objects and data arrays.
    Installation Volatile Memory Size
    If necessary, specify the number of bytes of RAM memory required for the applet�s transient data.
    Thanks in advance. Please post me a sample description.
    Regards
    Linga

  • X509 parsing in JavaCard

    Hello,
    Anyone knows about open source code that deals with (basic) x509 certificate parsing in JavaCard compatible Java?
    A related paper: http://www.waset.org/journals/waset/v22/v22-5.pdf

    Hi,
    1- the GC in modern cards have to be called explicitly, or nothing will happen. This is to avoid nasty effects from point 2 below.
    2 - a GC is a bad excuse. the "new" keyword allocates objects in eeprom/flash and there's no wear levelling so the memory deteriorates with time. Even if you calculate that based on manufacturer datasheet, you have 1 million writes per cell, and you will write once a day for 2 years blahblah so that's enough with 720 actual writes blahblah. That's true but avoidable. (you can fit a square stick in a round hole by cutting the edges, but you'd better use the square hole)
    3 - nv memory is far slower than ram. That's just finding a pointer and memcpy()ing.
    To avoid tearing problems, every byte stored in nv memory is actually written twice: once in the transaction buffer, once in the final memory cell, then the transaction buffer is erased. If the card is torn in the middle of the operation, either the operation can be resumed from the transaction buffer's data, or the final memory cell is not altered at all. That's why everything is double written.
    Using the provided code, expect tens of milliseconds wasted per apdu exchange.
    It's far better to include the destination array (and offset if required) in the method params. This way, you can even pass a pointer to a transient object or the apdu buffer when required, and you can also pass a nv object if you wish.
    Just have a look at how the Signature class works.
    sign(byte[] indata, short inoffset, short inlength, byte[] signbuffer, short signoffset)
    just use the same style of api to avoid allocating new objects at runtime, I assure you that this is quite bad for the card lifetime and long-term stability.
    Nevertheless, it is bad if x509 parsing happens often, tolerable, if not. the provided code uses "new" in a getter! so that's not only related to parsing...
    that code really hurts my eyes :-)
    public byte[] getFingerprint() {
             byte[] res = new byte[16];
             if (fp != null)
                 Util.arrayCopy(fp, (short)0, res, (short)0, (short)res.length);
             return res;
         }final word:
    reading the commented:
    //import java.io.UnsupportedEncodingException;
    and the use of java.util.Date at line :
    private static Date getUTCTime(byte[] buf, short off)
    tells me that http://vskristofsam.googlecode.com/svn/trunk/VeiligeSoftware_Card/src/be/msec/jorn/X509Certificate.java is not a valid javacard code.
    even javacard 3 classic does not have he "Date" class.
    that code may be jse, jee, or cdc code, but not javacard (nor cldc) code.

  • AES Cipher on Javacard 2.1.1

    Hy,
    i've implemented the AES Cipher on Javacard 2.1.1.
    If you are interested, you can download the code
    from: http://java.ittoolbox.com/code/d.asp?d=2728&a=s
    have fun
    snoopy

    Great start!
    However your code require lot of improvements before it can be used for anything real. The fact that JavaCard does not have GC results in memory leak in your code for each process() method call. So, you should use "new" only in the constructor/init of the applet. Moreover, for such temporary bufers you should use transient arrays but still create them only once in init method. Keep in mind that javacard code no need to be thread safe, so it will not be called concurrently.

  • Memory allocation when using multiple instances of a static array.

    Hi,
    I have question regarding the amount of memory allocated using multiple instances of a class that has declared a static array, e.g.:
    package staticTest;
    import javacard.framework.*;
    public class StaticClass
         static byte[] staticArray;
         public StaticClass()
              staticArray = new byte[100];
    /* Another class */
    package statictest;
    import javacard.framework.*;
    public class MyApplet extends javacard.framework.Applet
         StaticClass staticLibA, staticLibB;
         public MyApplet()
              /* Here we use two instances */
              staticLibA = new StaticClass();          
              staticLibB = new StaticClass();
         public static void install(byte[] bArray, short bOffset, byte bLength)
              (new MyApplet()).register(bArray, (short)(bOffset + 1), bArray[bOffset]);
         public void process(APDU apdu)
              byte[] buf = apdu.getBuffer();
              switch(buf[ISO7816.OFFSET_INS])
    }When downloading and installing this applet on a gemXpresso 211 PKis (that has a ' Get free EEPROM memory' function) the card reports that the amount of memory is increased by a approx 100 bytes every time a new staticLibX is added in the MyApplet constructor. Is this correct? If yes, can someone explain to me how to declare a static array that only allocates memory once and are being shared by the instances.
    Best regards,
    Jonas N

    Hi!
    I have another issue about static variable. The following is my sample code:
    ========================================
    package com.Test01;
    import javacard.framework.*;
    import javacard.security.*;
    import javacardx.crypto.Cipher;
    public class Test01 extends Applet {
         OwnerPIN Pin;
         static DESKey[] keys;
    protected Test01(byte[] buffer, short offset, byte length) {     
    keys = new DESKey[4];
    length = 0;
    while (length < 4) {
         keys[length] = (DESKey)KeyBuilder.buildKey((byte)3, (short)0x80, false);
         length = (byte)(length + 1);
    public static void install(byte buffer[], short offset, byte length) {     
    new Test01(buffer, offset, length);
    ===========================================================
    If there are two instances, A and B, created in the package.
    My issue:
    1. Are keys[0]~ keys [3] kept while B is deleted?
    2. Does each instance have itsown object while "keys[length] = (DESKey)KeyBuilder.buildKey((byte)3, (short)0x80, false);"?
    3. follow item 2, if A and B share the same object, is the object kept while B is deleted?
    Thank you
    Best regards,
    kantie

  • Java Card Memory Managament: How do you free-up allocated memory?

    I have a problem with java card memory management, that causes the applet to hang. I think the java card runs out of RAM when my applet runs for several iterations or process() calls. My program requires significant size of bytes for each APDU command to be sent. (around 100-250 bytes, for each apdu.sendBytes() call).
    I use a temporary byte array buffer that will contain the APDU command to be sent, declared as:
    private byte [] tmpBuff;Before each process() call, the tmBuff is initialized and contains a new byte array containing the APDU command to be sent. (array size around 100-250 bytes).
    tmpBuff = new byte[] {0x00, ... } On the process() call, the tmpBuff is copied to APDU and sendBytes() function is called. The tmpBuff byte array is reinitialized after every process() call to contain the next command. After about 20 successful commands by the process() call, the applet seems to ran out of RAM and hangs.
    I suspect, that when tmpBuff is reinitialized before each process() call, the Java Card garbage collector does now free-up the memory that was used for the previous tmpBuff byte array initialization.
    Is there a way to reclaim the memory allocated for tmpBuff after it has been initialized?
    Or maybe call the Java card garbage collector?

    Cenon,
    Generally speaking, the new keywork is a bad idea outside the install method or constructors as the JCRE is not guarenteed to have a garbage collector (and if it does, has to be called explicitly by JCSystem.requestObjectDeletion(); This however is slow.
    A better option may be to use memory more efficiently than to rely on garbage collection. A way of doing this would be to have an instance variable that is initialised once and reused. This allows you to use either a transient or persistent array.
    public class TestApplet extends Applet {
        private final static short BUFFER_SIZE = (short) 300;
        private final byte[] buffer;
        private TestApplet() {
            // only have one of the following not commented out
            /* persistent buffer */
            // buffer = new byte[BUFFER_SIZE];
            /* transient buffer (much faster) */
            buffer = JCSystem.makeTransientByteArray(BUFFER_SIZE, JCSystem.CLEAR_ON_DESELECT);
        public static void install(byte[] bArray, short bOffset, byte bLength) {
            // GP-compliant JavaCard applet registration
            new TestApplet().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
        public void process(APDU apdu) {
            // Good practice: Return 9000 on SELECT
            if (selectingApplet()) {
                return;
            // do some work here with buffer
    }In the above code you would be able to use the buffer to build the command and you will not have a memory leak.
    Cheers,
    Shane
    Edited by: safarmer on Jul 8, 2008 12:25 PM

  • Java Card Data Memory - how can a 16k array fit on my 8k card?

    Hi all,
    I tried to guess the memory size I can use in my applets by allocating arrays of bytes.
    I noticed that I am allowed to allocate a lot more memory than my physical RAM. For instance my card is 8KB ram but in my install method I create an array of 16384 bytes. How can it be possible ? Is there a swap mechanism or a virtual memory mechanism like classic computers ? I am working with a Javacard 3.0 Classic.
    Thanks a lot for your explanation.

    lexdabear wrote:
    >
    If you want to create a buffer in RAM you need to use: byte[] buffer = JCSystem.createTransientByteArray(16384);
    Oh, I didn't see this method before :).Thanks for picking that up. That is what I get for typing code into a text box when tired :(
    Correction:
    JCSystem.makeTransientByteArray(length, event)Shane

  • Allocate memory problem

    Hello. I have created an applet and i put it to my java card .
    Iso, can write to an array but when I repeat the procedure for 15 times(after 16 ) I get an error and the status word that it returns is "6F00",
    . I read somewhere that i have to allocate the memory in constructor because if i dont the memory is never free.
    can you please tell me what i have to do?
    my code is:
    package com.acme.options;
    import javacard.framework.*;
    public class optionsApplet extends Applet {
         final static byte Helloword_CLA = (byte) 0xB0;
         final static byte WR_HELLO = (byte) 0x57;
         private short i = 0;
         private short a = 0;
         private short x = 0;
    byte[] hello=new byte[0];     
         byte[] hello2;
         byte[] hello3;
         public static void install(byte[] bArray, short bOffset, byte bLength) {
              // GP-compliant JavaCard applet registration
              new optionsApplet().register(bArray, (short) (bOffset + 1),
                        bArray[bOffset]);
         public void process(APDU apdu) {
              // Good practice: Return 9000 on SELECT
              if (selectingApplet()) {
                   return;
    byte[] buffer = apdu.getBuffer();
              if (buffer[ISO7816.OFFSET_CLA] != Helloword_CLA)
                   ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
              switch (buffer[ISO7816.OFFSET_INS]) {
              case WR_HELLO:
                   wr_hello(apdu);
                   return;
                        case RESET:
              default:
         private void wr_hello(APDU apdu) throws APDUException {
              byte[] temp = apdu.getBuffer();
              short data_length = (short) (temp[ISO7816.OFFSET_LC] & 0xFF);
              hello2 = new byte[data_length];
              short read_count = apdu.setIncomingAndReceive();
              Util.arrayCopy(temp, ISO7816.OFFSET_CDATA, hello2, (short) 0,
                        (short) data_length);
              hello3 = hello;
              hello = new byte[hello3.length + hello2.length];
              for (i = 0; i < hello3.length; ++i) {
                   hello[i] = hello3;
              for (i = (short) hello3.length; i < hello.length; ++i) {
                   hello[i] = hello2[x];
                   x++;
    i = 0;
              a = 0;
              x = 0;

    Just to make it readable to the human eye:
    package com.acme.options;
    import javacard.framework.*;
    public class optionsApplet extends Applet {
    final static byte Helloword_CLA = (byte) 0xB0;
    final static byte WR_HELLO = (byte) 0x57;
    private short i = 0;
    private short a = 0;
    private short x = 0;
    byte[] hello=new byte[0];
    byte[] hello2;
    byte[] hello3;
    public static void install(byte[] bArray, short bOffset, byte bLength) {
    // GP-compliant JavaCard applet registration
    new optionsApplet().register(bArray, (short) (bOffset + 1),
    bArray[bOffset]);
    public void process(APDU apdu) {
    // Good practice: Return 9000 on SELECT
    if (selectingApplet()) {
    return;
    byte[] buffer = apdu.getBuffer();
    if (buffer[ISO7816.OFFSET_CLA] != Helloword_CLA)
    ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
    switch (buffer[ISO7816.OFFSET_INS]) {
    case WR_HELLO:
    wr_hello(apdu);
    return;
    case RESET:
    default:
    private void wr_hello(APDU apdu) throws APDUException {
    byte[] temp = apdu.getBuffer();
    short data_length = (short) (temp[ISO7816.OFFSET_LC] & 0xFF);
    hello2 = new byte[data_length];
    short read_count = apdu.setIncomingAndReceive();
    Util.arrayCopy(temp, ISO7816.OFFSET_CDATA, hello2, (short) 0,
    (short) data_length);
    hello3 = hello;
    hello = new byte[hello3.length + hello2.length];
    for (i = 0; i < hello3.length; ++i) {
    hello = hello3;
    for (i = (short) hello3.length; i < hello.length; ++i) {
    hello = hello2[x];
    x++;
    i = 0;
    a = 0;
    x = 0;
    }

Maybe you are looking for