How much memory does this java card really have? (EEPROM and ObjectDeletion game!)
Posted: Thu Jun 11, 2015 11:09 pm
I wrote a simple program to check requestObjectDeletion() method functionality and my card's available memory.
My applet respond to five different kind of APDU commands as follow :
To return the available memory I wrote a method that use an infinite while loop to create a lot of byte arrays with 100 elements and increase a counter simultaneously. On catching the Not enough memory exception, the method returns counter *100 (i.e. the free memory before calling this method)
OK, this is the program :
Now, there is a problem. This is the output of OpenSC-Tool when I send some APDU commands to the card:
Command 0 returns 0xE358 (=58200). So the memory before calling this method was 58200 bytes.
Command 1 returns 0x0000, and this mean that the free memory is less than 100 byte now.
Command 2 returns 0x9000, so requestObjectDeletion called successfully.
Command 3 returns 0xE358 again, and this mean that requestObjectDeletion run successfully.
Command 4 returns 0x9000, so requestObjectDeletion called successfully.
Command 5 returns 0x9000, so a byte array with 2000 element is created now.
Now I expect the card to have free memory equal with 0xE358 - 2000 = 0xDB88
But in the next command :
Command 6 returns 0xDD18! i.e we have 0xDD18 + 2000 = 0xE4E8 bytes memory space in our card!
Who is this possible? Why the card can't see this 400 bytes (0xE4E8 - 0xE358) in the first command?
My applet respond to five different kind of APDU commands as follow :
- SELECT APDU command : Response : 0X9000
- Command : XX 00 XX XX XX [...] Response : Return available memory in byte.
- Command : XX 01 XX XX XX [...] Response : Create a local byte array of 2000 elements (i.e. 2000 byte.)
- Command : XX 02 XX XX XX [...] Response : request for Object Deletion method
- Other commands : Response : 0x9000
To return the available memory I wrote a method that use an infinite while loop to create a lot of byte arrays with 100 elements and increase a counter simultaneously. On catching the Not enough memory exception, the method returns counter *100 (i.e. the free memory before calling this method)
OK, this is the program :
Code: Select all
public class ObjDeletion extends Applet {
public static short counter = 0x0000;
private ObjDeletion() {
}
public static void install(byte bArray[], short bOffset, byte bLength)
throws ISOException {
new ObjDeletion().register();
}
public void process(APDU arg0) throws ISOException {
if (selectingApplet()) {
return;
}
byte[] buffer = arg0.getBuffer();
switch (buffer[ISO7816.OFFSET_INS]) {
case 0x00:
counter=0;
ReturnAvailableMem();
break;
case 0x01:
genLocalArray();
break;
case 0x02:
JCSystem.requestObjectDeletion();
break;
default:
return;
}
}
public void genLocalArray() {
byte[] LocalArray = new byte[2000];
}
public void ReturnAvailableMem() {
try {
while (true) {
byte[] dump = new byte[100];
counter += 1;
}
} catch (Exception e) {
ISOException.throwIt((short) (counter * 100));
}
}
}
Now, there is a problem. This is the output of OpenSC-Tool when I send some APDU commands to the card:
Code: Select all
OSC: opensc-tool.exe -s 00a404000b0102030405060708090000 -s 00000000 -s 00020000
-s 00000000 -s 00020000 -s 00010000 -s 00000000 -s 00020000 -s 00000000 -s 0002
0000 -s 00010000 -s 00020000 -s 00000000
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 0B 01 02 03 04 05 06 07 08 09 00 00
Received (SW1=0x90, SW2=0x00)
//0::returnAvailableMem()
Sending: 00 00 00 00
Received (SW1=0xE3, SW2=0x58)
//1::returnAvailableMem()
Sending: 00 00 00 00
Received (SW1=0x00, SW2=0x00)
//2::requestObjectDeletion()
Sending: 00 02 00 00
Received (SW1=0x90, SW2=0x00)
//3::returnAvailableMem()
Sending: 00 00 00 00
Received (SW1=0xE3, SW2=0x58)
//4::requestObjectDeletion()
Sending: 00 02 00 00
Received (SW1=0x90, SW2=0x00)
//5::genLocalArray()
Sending: 00 01 00 00
Received (SW1=0x90, SW2=0x00)
//6::returnAvailableMem()
Sending: 00 00 00 00
Received (SW1=0xDD, SW2=0x18)
//7::requestObjectDeletion()
Sending: 00 02 00 00
Received (SW1=0x90, SW2=0x00)
//8::returnAvailableMem()
Sending: 00 00 00 00
Received (SW1=0xE3, SW2=0x58)
//9::requestObjectDeletion()
Sending: 00 02 00 00
Received (SW1=0x90, SW2=0x00)
//10::genLocalArray()
Sending: 00 01 00 00
Received (SW1=0x90, SW2=0x00)
//11::requestObjectDeletion()
Sending: 00 02 00 00
Received (SW1=0x90, SW2=0x00)
//12::returnAvailableMem()
Sending: 00 00 00 00
Received (SW1=0xE3, SW2=0x58)
Command 0 returns 0xE358 (=58200). So the memory before calling this method was 58200 bytes.
Command 1 returns 0x0000, and this mean that the free memory is less than 100 byte now.
Command 2 returns 0x9000, so requestObjectDeletion called successfully.
Command 3 returns 0xE358 again, and this mean that requestObjectDeletion run successfully.
Command 4 returns 0x9000, so requestObjectDeletion called successfully.
Command 5 returns 0x9000, so a byte array with 2000 element is created now.
Now I expect the card to have free memory equal with 0xE358 - 2000 = 0xDB88
But in the next command :
Command 6 returns 0xDD18! i.e we have 0xDD18 + 2000 = 0xE4E8 bytes memory space in our card!
Who is this possible? Why the card can't see this 400 bytes (0xE4E8 - 0xE358) in the first command?