A P P E N D I X  C

Using the Large Address Space

Allowing your applications to take advantage of the large address capabilities of the Java Card platform reference implementation, version 2.2.2, requires careful planning and programming. Some size limitations still exist within the reference implementation. The way that you structure large applications, as well as applications that manage large amounts of data, determines how the large address space can be exploited.

The following sections describe two ways in which you can take advantage of large memory storage in smart cards.

Programming Large Applications and Libraries

The key to writing large applications for the Java Card platform is to divide the code into individual package units. The most important limitation on a package is the 64KB limitation on the maximum component size. This is especially true for the Method component: if the size of an application's Method component exceeds 64KB, then the Java Card converter will not process the package and will return an error.

You can overcome the component size limitation by dividing the application into separate application and library components. The Java Card platform has the ability to support library packages. Library packages contain code which can be linked and reused by several applications. By dividing the functionality of a given application into application and library packages, you can increase the size of the components. Keep in mind that there are important differences between library packages and applet packages:

Therefore, you should not place sensitive or exclusive-use code in a library package. It should be placed in an applet package, instead.

Handling a Package as a Separate Code Space

Several applications and API functionality can be installed in the smart card simultaneously by handling each package as a separate code space. This technique will let you exceed the 64KB limit, and provide full Java Card API functionality and support for complex applications requiring larger amounts of code.

Storing Large Amounts of Data

The most efficient way to take advantage of the large memory space is to use it to store data. Today's applications are required to securely store ever-growing amounts of information about the cardholder or network identity. This information includes certificates, images, security keys, and biometric and biographic information.

This information sometimes requires large amounts of storage. Before version 2.2.2, versions of the Java Card platform reference implementation had to save downloaded applications or user data in valuable persistent memory space. Sometimes, the amount of memory space required was insufficient for some applications. However, the memory access schemes introduced with version 2.2.2 allow applications to store large amounts of information, while still conforming to the Java Card specification.

The Java Card specification does not impose any requirements on object location or total object heap space used on the card. It specifies only that each object must be accessible by using a 16-bit reference. It also imposes some limitations on the amount of information an individual object is capable of storing, by using the number of fields or the count of array elements. Because of this loose association, it is possible for any given implementation to control how an object's information is stored, and how much data these objects can collectively hold.

The Java Card platform reference implementation, version 2.2.2, allows you to use all of the available persistent memory space to store object information. By allowing you to separate data storage into distinct array and object types, this reference implementation allows you to store the large amounts of data demanded by today's applications.

Example: The photocard Demo Applet

The photocard demo applet (included with the Java Card platform reference implementation, version 2.2.2) is an example of an application that takes advantage of the large address space capabilities.

The photocard applet performs a very simple task: it stores pictures inside the smart card and retrieves them by using a Java Card RMI interface. For more information on the photocard demo applet and how to run it, see Photo Card Demo.

/**
  * PhotoCard interface
  * Defines methods to be used as interface between photo client
  * and storage smart card
  */
public interface PhotoCard extends Remote {
 
// User exception error codes
    /**
      * No space available for photo storage
      */
    public static final short NO_SPACE_AVAILABLE = (short)0x6000;
 
/**
      * No photo stored in selected location
      */
    public static final short NO_PHOTO_STORED  = (short)0x6001;
 
/**
      * Invalid photo ID
      */
    public static final short INVALID_PHOTO_ID = (short)0x6002;
 
/**
      * Invalid argument value
      */
    public static final short INVALID_ARGUMENT   = (short)0x6003;
 
/**
      * Maximum photo size
      */
    public static final short MAX_SIZE           = (short)0x7FFF;
 
/**
      * Maximum on-card photos
      */
    public static final short MAX_PHOTO_COUNT    = (short)4;
 
/**
      * Maximum bytes for transfer
      */
    public static final short MAX_BUFFER_BYTES   = (short)96;
    
/*
     * Offset into the Photo array is invalid
     */
    public static final short INVALID_OFFSET = (short)0x7000;
 
/**
      * SHA256 MessageDisgest implementation not provided
      */
    public static final short DOES_NOT_SUPPORT_PHOTO_VERIFICTAION
=(short) 0x7110;
 
      /*
     *  the signature didn't verify
     */
    public static final short FAIL1 = (short) 0x7111;
 
    /*
     * threw wrong reason code
     */
    public static final short FAIL2 = 0x7222;
 
    /**
     *threw wrong exception
     */
    public static final short FAIL3 = 0x7333;
 
    /*
     *threw wrong exception
     */
    public static final short FAIL4 = 0x7444;
 
/**
      * This method requests the smart card to allocate space to store
      * a photo image of the specified size.
      * @param size - Image size to store in the smart card
      * @return photoID - ID slot in card where photo will be stored
      * @exception UserException - thrown if error condition occurs, or
      *  invalid parameters passed.
      */
    public short requestPhotoStorage(short size) 
        throws RemoteException, UserException;
 
/**
      * This method loads a series of bytes belonging to the photo
      * into the smart card at the position specified.
      * @param photoID - photo slot where to store data
      * @param data - byte array contaiing binary photo information
      * @param size - number of bytes being passed into the smart card
      * @param offset - position inside photo buffer where to store data.
      * @boolean more - <b>true</b> indicates more data coming;
<b>false</b>
      *  inidicates this is the last data chunk.
      * @exception UserException - thrown if error condition occurs, or
      *  invalid parameters passed.
      */
    public void loadPhoto(short photoID, byte[] data, 
        short size, short offset, boolean more) 
        throws RemoteException, UserException;
 
/**
      * This method deletes the photo whose ID is specified in the card.
      * @param photoID - ID slot of photo to delete
      * @exception UserException - thrown if error condition occurs, or
      *  invalid parameters passed.
      */
    public void deletePhoto(short photoID) 
        throws RemoteException, UserException;
 
/**
      * This method retrieves the photo size whose ID is specified.
      * @param photoID - ID slot of photo to access
      * @exception UserException - thrown if error condition occurs, or
      *  invalid parameters passed.
      */
    public short getPhotoSize(short photoID) 
        throws RemoteException, UserException;
        
/**
      * This method retrueves a series of bytes belonging to the photo
      * from the smart card at the position specified.
      * @param photoID - photo slot where to store data
      * @param size - number of bytes expected from the smart card
      * @param offset - position inside photo buffer where to access data.
      * @return byte array with binary data from photo stored inside the
      *  smart card
      * @exception UserException - thrown if error condition occurs, or
      *  invalid parameters passed.
      */
    public byte[] getPhoto(short photoID, short offset, short size) 
        throws RemoteException, UserException;
 
/**
      * This method verifies on card the photo
      * presented by the user.
      * @param photoID - photo slot where to store data
      * @param size - number of bytes expected from the smart card
      * @param offset - position inside photo buffer where to access
      * data.
      * @param photoDigest - msg digest of photo sent by user
      * @param photoOffset - position inside photoDigest where to
      * access data
      * @return void
      * @exception UserException - thrown if error condition occurs, or
      * invalid parameters passed.
      */
   public short verifyPhoto(short photoID, byte[] photoDigest, short
photoOffset)
        throws RemoteException, UserException ;
}

To store the images, an array of arrays has been defined:

// Array containing photo objects
    private Object[] photos;

Each image is stored inside an array, and each array can grow up to 32,767 elements in size.

for (short i = (short)0; i < (short)MAX_PHOTO_COUNT;i++) {
    byte[] thePhoto = (byte[])photos[i];
 
    if (photos[i] == null) {
        photos[i] = new byte[size];
        return (short)(i + 1);
    }
}
UserException.throwIt(NO_SPACE_AVAILABLE);

The array can be randomly accessed, as needed. In this implementation, the arrays are defined as byte arrays, however, they could also have been defined as integer arrays.

byte[] selPhoto = (byte[])photos[(short)(photoID - (short)1)];
... 
Util.arrayCopy(selPhoto, offset, buffer, (short)0, size);
return buffer;

The collection of arrays (more than two arrays would be required in this case) can easily hold far more than 64KB of data. Storing this amount of information should not be a problem, provided that enough mutable persistent memory is configured in the C-language Java Card RE.

Notes on the photocard Applet

The photocard applet employs a collection of arrays to store large amounts of data. The arrays allow the applet to take advantage of the platform's capabilities by transparently storing data.

The coding and design of applications that use the large address space to access memory must adhere to the target platform's requirements.

As smart cards have limited resources, code cannot be guaranteed to behave identically on different cards. For example, if you run the photocard applet on a card with less mutable persistent memory available for storage, it might run out of memory space when it attempts to store the images. A given set of inputs might not produce the same set of outputs in a C-language Java Card RE with different characteristics. The applet code must account for any different implementation-specific behavior.