Sometimes ago I've written the post about JavaCard applets debugging techniques. In the current post I'd like to narrate story from real life. Actually this post is translation of post in my Russian blog.
Well, the problem which I've encountered was the SIM Toolkit (STK) applet with a couple of menu entries. On the real card when you select one of menu entry applet silently exits instead of sending SMS. Checking source code of the applet was not helped. So the only way to debug was loading applet to Software Simulator.
Ok, if no other way, I've compiled the most similar configuration of simulator to real card, created file system, loaded applet. I’ve connected Mobile Phone Simulator to OS Simulator and start browsing menu. When I’ve selected menu item which doesn’t work JCRE log has the following:
// Byte code dump, some part has skipped
CAP[1] - 0x4aac11: SAND
CAP[1] - 0x4aac12: SADD
CAP[1] - 0x4aac13: S2B
CAP[1] - 0x4aac14: BASTORE
CAP[1] - 0x4aac15: ALOAD_0
CAP[1] - 0x4aac16: SCONST_5
CAP[1] - 0x4aac17: SCONST_0
CAP[1] - 0x4aac18: INVOKESTATIC [0x1c 0x24]
LIB[7] - 0x4987eb: SCONST_5
LIB[7] - 0x4987ec: SLOAD_0
LIB[7] - 0x4987ed: INVOKESTATIC [0x1c 0x17]
Calling nativeMethod[51] - javacard/security/CryptoException/algorithmCheck(BS)V
0x498802: RETURN - returns: V0x0
LIB[7] - 0x4987f0: NEW [0x1c 0x18]
total number of effective EEPROM writing = 0xbc
total number of requested atomic update = 0x1e6
number EEPROM writing saved thanks NVL = 0x4f6
Exception: VM; SystemException; reason: 5
< INVALID exceptions java.lang for >INTP Exception jump to dispatch loop
total number of effective EEPROM writing = 0xbc
total number of requested atomic update = 0x1e6
number EEPROM writing saved thanks NVL = 0x4f6
By checking the source code of JCRE of the OS I’ve found that “reason 5” is No Resources. Checking available volatile and non volatile memory, it seems there is enough memory. From the dump I couldn’t figure out what was wrong. So no clue!
Next step to analyze applet bytecode. Fortunately Gemalto Developer Suite has utility called “Cap File Utility”. I dumped applet and searched the exact consequence of commands from dump of JCRE. After a while I found in the applet dump the following:
method_info[8] // @04b4= {
// Some part skipped
/*0f31*/ sand
/*0f32*/ sadd
/*0f33*/ s2b
/*0f34*/ bastore
/*0f35*/ L124: aload_0
/*0f36*/ sconst_5
/*0f37*/ sconst_0
/*0f38*/ invokestatic 57
/*0f3b*/ putfield_a 26
/*0f3d*/ getfield_a_this 26
/*0f3f*/ getfield_a_this 23
/*0f41*/ sload 10
}
Pay attention to /*0f38*/ invokestatic 57. It is last call from the applet before switching to system libraries. So, it has to be something wrong with this call. But how to find what exactly it is calling. Here we have to check Component_Pool from the dump:
.Constant_Pool {
// some part skipped
/* 00e4, 57 */CONSTANT_StaticMethodRef : external: 0x84,0x1,0x0
// some part skipped
}
So here it is – static method 57. It is referencing to external package. By checking ImportComponent I’ve found the right one. Here I have to mention that 0x84,0x1,0x00 means:
- 0x84 – is 5th package in ImportComponent section due to numbering starts from 0x80
- 0x1 – is the class number
- 0x0 is method number
Here extract from applet dump:
.ImportComponent = {
// some part skipped, it is 5th package due to 1st one has reference 0x80
package_info = {
minor_version : 2
major_version : 1
AID_length : 7
AID : a0.00.00.00.62.02.01
}
// some part skipped }
Now we know what is AID of the imported package: a0.00.00.00.62.02.01. It is standard package javacardx.security. To figure out what is class 1 and method 0 we have to dump javacrdx.security.exp file. Below is extract from dump:
class_info { // javacardx/crypto/Cipher
u1 token : 1 <== Class identification number
u2 access_flags : 10000000001b
u2 name_index : 57
u2 export_supers_count : 1
// some parts skipped
export_methods {
method_info { // getInstance
u1 token : 0 <== Method identification number
u2 access_flags : 11001b
u2 name_index : 42
u2 descriptor_index : 43
}
// some parts skipped
}
So now we know which method raises exception. It is getInstance() method of Cipher class. In the source code of the applet getInstance() method has called as follows:
myCipher = Cipher.getInstance( Cipher.ALG_DES_ECB_NOPAD, false );
According to specification JavaCard API:
getInstance
public static final Cipher getInstance(byte algorithm,
boolean externalAccess)
throws CryptoException
- Creates a
Cipher
object instance of the selected algorithm. -
- Parameters:
algorithm
- the desired Cipher algorithm. Valid codes listed in ALG_ .. constants above, for example, ALG_DES_CBC_NOPAD
. externalAccess
- true
indicates that the instance will be shared among multiple applet instances and that the Cipher
instance will also be accessed (via a Shareable
interface) when the owner of the Cipher
instance is not the currently selected applet. If true
the implementation must not allocate CLEAR_ON_DESELECT transient space for internal data.
- Returns:
- the
Cipher
object instance of the requested algorithm
- Throws:
CryptoException
- with the following reason codes:
CryptoException.NO_SUCH_ALGORITHM
if the requested algorithm is not supported or shared access mode is not supported.
Et Voila! Issue is in externalAccess. We have to set it true, as STK applets are not explicitly selected applets by SELECT APPLICATION. They are triggered by SIM Toolkit Events.
So, changing to true externalAccess parameter has solved issue.