Skip to content

Memory leak #29

@bitlogik

Description

@bitlogik

We identified a memory leak in this applet. Memory management on Javacard is very hard, especially because the limited RAM resource of the card chip which is approximately 2-3kB free maximum.

We believe this issue affects all cards on all JCOP versions. This is just a matter of how many operations are required to fill up the memory. This is a very annoying bug, as the card for example can't no more sign after a given number of signatures. Our tests show that even a power cycle of the card doesn't free the memory. This is a "feature" of JCOP, hence requiring some special techniques about memory management. Also, a applet reset (Terminate+Activate) doesn't clear the transient memory. This issue can lead to disastrous consequences as this can prevent any new signatures or others cryptographic operations with keys which only exists in the secure applet. Only an applet re-installation put the applet on the right track.

We have even decreased some RAM constants parameters, and the issue is nearly the same. The signature crashes forever after around 20 signatures.

For now, our team doesn't have some much time to fix this issue. But here are some recommendations to fix this :

  • The main goal is to reduce the heap "dynamic" size to nearly zero.
  • Avoid all dynamic memory allocation, only let "small and simple" variables space as byte or short. All classes should be instantiated once at card installation. That means the new Signature performs at each signature, should be instantiated as a PGPKey "static" property, which is then instantiated in Persistent with new PGPKey, instantiated with the SmartPGPApplet install. As the Persistent class name suggest, there were some efforts into this direction of creating objects once, this just need to be pushed further, also in the Transient class. The first points is to remove from dynamic heap the Signature.getInstance and some KeyPairs.
  • Performs some memory reuse. When some variables are used in some line,s and then not after, but a similar variable type is then used, this can be grouped as a single variable. This goes dramatically against code source reading comprehension by humans, but this is required in order to minimize dynamic object allocation, so reducing the heap size and tackle this issue.
  • On some left dynamic creation, the pointer should be put to null at the end of its uses, even at the end of its scope, in order to help the poor virtually non existent garbage collector.
  • Remove all final keyword in the remaining (only byte and short) dynamic memory allocation.
  • Try to avoid all new XX() in the code, except the instance variables in class, which are mostly instantiated at applet installation for the master classes.
  • Since all this involves memory reuse, and the applet code should not rely on the heap manager garbage collector, that means that some data put in temporary variable must be erased or zero fill. This is important for secret data. For example a signature output doesn't require erasing, but an AES MAC encrypted channel key does.
  • Test whether this is fixed, with some infinite loop script software, testing a lot of card functions in a loop over and over. It should not crash the app after hours of run. The script we provide as a PoC to trigger this issue loop 200 times to be sure to trigger it. Actually on our test cards, it happens around 20 signatures.

Note that the instantiation of nearly everything at the applet installation can lead to an other similar issue. The install function process is always performed in a transactional reversible process, which means every steps are saved in RAM. So the processing can't take too much memory. Most of the time this is OK. Still, if this happens, one should defer the instantiation at a later stage, like splitting the instantiation in 2 parts. For example at the very first select or at the first. The difficult part then in this case is to locate when this second instantiation part should happen.

Log details about the issue :
Performs with https://gist.github.com/bitlogik/44a7502f0b303ec10a3f45a810ac82fa using OpenPGPpy on a J3R110.

$>python3 demo/signSmartPGP.py
Trying to reach OpenPGP app
Available readers :
 - Identiv uTrust 3700 F CL Reader 0
Trying with reader : Identiv uTrust 3700 F CL Reader 0
 Sending 0xA4 command with 6 bytes data
-> 00 A4 04 00 06 D2 76 00 01 24 01
 Received 0 bytes data : SW 0x9000 - duration: 11.5 ms
A device detected, using Identiv uTrust 3700 F CL Reader 0
Read Data  in 0x006E
 Sending 0xCA command with 0 bytes data
-> 00 CA 00 6E 00
 Received 220 bytes data : SW 0x9000 - duration: 20.0 ms
<- 6E 81 D9 4F 10 D2 76 00 01 24 01 03 04 AF AF 00 00 00 00 00 00 5F 52 0A 00 C1 C5 73 C0 01 80 05 90 00 73 81 B7 C0 0A FF 03 00 20 04 80 00 FF 00 00 C1 06 01 08 00 00 11 03 C2 06 01 08 00 00 11 03 C3 06 01 08 00 00 11 03 C4 07 00 7F 7F 7F 03 00 03 C5 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C6 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CD 0C 00 00 00 00 00 00 00 00 00 00 00 00
Read Data  in 0x004F
 Sending 0xCA command with 0 bytes data
-> 00 CA 00 4F 00
 Received 16 bytes data : SW 0x9000 - duration: 8.7 ms
<- D2 76 00 01 24 01 03 04 AF AF 00 00 00 00 00 00
PGP version : 3.4
Manufacturer : ANSSI (0xAFAF)
Serial : 0
Read Data  in 0x7F66
 Sending 0xCA command with 0 bytes data
-> 00 CA 7F 66 00
 Received 11 bytes data : SW 0x9000 - duration: 9.0 ms
<- 7F 66 08 02 02 01 00 02 02 01 00
Read Data  in 0x7F74
 Sending 0xCA command with 0 bytes data
-> 00 CA 7F 74 00
 Received 0 bytes data : SW 0x6A88 - duration: 8.0 ms
Button ? No
OpenPGP device detected
 Sending 0x47 command with 2 bytes data
-> 00 47 81 00 02 B6 00
 Received 0 bytes data : SW 0x6A88 - duration: 8.1 ms
Setup the new device
Enter PIN3 (PUK) :
 Sending 0x20 command with 8 bytes data
-> 00 20 00 83 08 31 32 33 34 35 36 37 38
 Received 0 bytes data : SW 0x9000 - duration: 16.2 ms
Put data 132A8648CE3D030107 in 0x00C1
 Sending 0xDA command with 9 bytes data
-> 00 DA 00 C1 09 13 2A 86 48 CE 3D 03 01 07
 Received 0 bytes data : SW 0x9000 - duration: 25.7 ms
 Sending 0x47 command with 2 bytes data
-> 00 47 80 00 02 B6 00
 Received 70 bytes data : SW 0x9000 - duration: 256.8 ms
<- 7F 49 43 86 41 04 CD 39 E0 C9 A1 D0 FB 64 BC 4D 78 3C 92 D4 F6 91 B9 61 22 E2 7B C2 0B A1 1A 5F 80 C5 8F 76 8D 63 A0 6E 45 B7 AE 9B 96 1F 7E 82 32 21 D5 53 A7 92 F9 E2 E4 CB 0F 79 E4 C9 58 50 A1 5B 0A F6 58 97
Device "SIG" public key read
Enter PIN1 :

PublicKey for signature : 0x04cd39e0c9a1d0fb64bc4d783c92d4f691b96122e27bc20ba11a5f80c58f768d63a06e45b7ae9b961f7e823221d553a792f9e2e4cb0f79e4c95850a15b0af65897
 Sending 0x20 command with 6 bytes data
-> 00 20 00 81 06 31 32 33 34 35 36
 Received 0 bytes data : SW 0x9000 - duration: 16.7 ms
 Sending 0x2A command with 32 bytes data
-> 00 2A 9E 9A 20 F1 10 4E AD 6B 42 85 42 7C 67 8C C0 FC 85 D1 2C F6 7B 3F 20 78 B6 E3 4A 44 2F C5 F6 4E 01 30 EB
 Received 66 bytes data : SW 0x9000 - duration: 92.8 ms
<- 00 62 DE CC FA 8D E1 36 72 C0 5E 25 15 C8 5A 4A 22 FD E4 21 B9 5D 3B 81 51 1B 92 BB FD DE F5 78 13 00 D1 33 48 EC F1 DB 6E E9 A7 F3 C9 27 FF 3B 5E AC 55 88 52 2A 02 29 0D 09 3B 28 2F 74 E8 21 E1 36
Signature : 0x3045022062deccfa8de13672c05e2515c85a4a22fde421b95d3b81511b92bbfddef57813022100d13348ecf1db6ee9a7f3c927ff3b5eac5588522a02290d093b282f74e821e136
OK
 Sending 0x20 command with 6 bytes data
-> 00 20 00 81 06 31 32 33 34 35 36
 Received 0 bytes data : SW 0x9000 - duration: 17.7 ms
 Sending 0x2A command with 32 bytes data
-> 00 2A 9E 9A 20 F1 10 4E AD 6B 42 85 42 7C 67 8C C0 FC 85 D1 2C F6 7B 3F 20 78 B6 E3 4A 44 2F C5 F6 4E 01 30 EB
 Received 66 bytes data : SW 0x9000 - duration: 93.4 ms
<- 00 4C 47 9C 22 2E 24 C0 D0 89 9C 46 16 7A 19 02 72 98 0E 4B CF 1E 5B 3C 04 79 60 DA 1D 6C F5 B8 F1 00 E4 81 90 6C 65 AE D2 0E 3B 25 AB 5F 39 44 D8 BE 4D 4D FC 58 F8 A4 D6 86 6F 37 8C 82 35 B8 1E 76
Signature : 0x304502204c479c222e24c0d0899c46167a190272980e4bcf1e5b3c047960da1d6cf5b8f1022100e481906c65aed20e3b25ab5f3944d8be4d4dfc58f8a4d6866f378c8235b81e76
OK
 Sending 0x20 command with 6 bytes data
-> 00 20 00 81 06 31 32 33 34 35 36
 Received 0 bytes data : SW 0x9000 - duration: 17.0 ms
 Sending 0x2A command with 32 bytes data
-> 00 2A 9E 9A 20 F1 10 4E AD 6B 42 85 42 7C 67 8C C0 FC 85 D1 2C F6 7B 3F 20 78 B6 E3 4A 44 2F C5 F6 4E 01 30 EB
 Received 66 bytes data : SW 0x9000 - duration: 92.9 ms
<- 00 C6 06 ED 2E 42 CF 1C 75 74 57 57 BF 8A FD 49 7C 70 ED E8 A8 6F C2 1A 79 21 C8 A7 99 7B EC 62 79 00 02 52 39 49 49 E7 E1 BF D6 6E F3 DA EC 41 A5 84 72 E1 A1 73 20 19 7A 0A F0 B8 A1 47 4E 9D 8D 48
Signature : 0x3045022100c606ed2e42cf1c75745757bf8afd497c70ede8a86fc21a7921c8a7997bec627902200252394949e7e1bfd66ef3daec41a58472e1a17320197a0af0b8a1474e9d8d48
OK
 Sending 0x20 command with 6 bytes data
-> 00 20 00 81 06 31 32 33 34 35 36
 Received 0 bytes data : SW 0x9000 - duration: 17.4 ms
 Sending 0x2A command with 32 bytes data
-> 00 2A 9E 9A 20 F1 10 4E AD 6B 42 85 42 7C 67 8C C0 FC 85 D1 2C F6 7B 3F 20 78 B6 E3 4A 44 2F C5 F6 4E 01 30 EB
 Received 66 bytes data : SW 0x9000 - duration: 93.0 ms
<- 00 F8 46 17 AA A2 16 75 A0 AE 18 88 34 46 54 6A E3 01 77 EC CB B3 23 21 4A 33 54 AF CC EA 0E 05 5B 00 8D 20 4C BE E1 07 93 4C 30 FF 99 FD 47 20 64 C0 72 15 A5 3E 1F 45 1F 8F 9F FC 97 C4 DE C2 D6 D9
Signature : 0x3046022100f84617aaa21675a0ae18883446546ae30177eccbb323214a3354afccea0e055b0221008d204cbee107934c30ff99fd472064c07215a53e1f451f8f9ffc97c4dec2d6d9
OK
 Sending 0x20 command with 6 bytes data
-> 00 20 00 81 06 31 32 33 34 35 36
 Received 0 bytes data : SW 0x9000 - duration: 16.4 ms
 Sending 0x2A command with 32 bytes data
-> 00 2A 9E 9A 20 F1 10 4E AD 6B 42 85 42 7C 67 8C C0 FC 85 D1 2C F6 7B 3F 20 78 B6 E3 4A 44 2F C5 F6 4E 01 30 EB
 Received 66 bytes data : SW 0x9000 - duration: 92.8 ms
<- 00 3D 4A 9D E1 39 8E 5A B1 64 45 3A E3 E1 B7 6D FD CE B5 76 0C 30 07 A8 F0 88 5E 96 CC E6 8D 3B 1E 00 94 17 FE EB 0B 90 8D 77 8C BE 91 9A 96 5F 20 BD 98 84 20 59 03 58 97 DB E0 B5 87 6F 6E 88 D3 58
Signature : 0x304502203d4a9de1398e5ab164453ae3e1b76dfdceb5760c3007a8f0885e96cce68d3b1e0221009417feeb0b908d778cbe919a965f20bd98842059035897dbe0b5876f6e88d358
OK
 Sending 0x20 command with 6 bytes data
-> 00 20 00 81 06 31 32 33 34 35 36
 Received 0 bytes data : SW 0x9000 - duration: 17.0 ms
 Sending 0x2A command with 32 bytes data
-> 00 2A 9E 9A 20 F1 10 4E AD 6B 42 85 42 7C 67 8C C0 FC 85 D1 2C F6 7B 3F 20 78 B6 E3 4A 44 2F C5 F6 4E 01 30 EB
 Received 64 bytes data : SW 0x9000 - duration: 93.2 ms
<- 15 7D 16 F6 AC 89 A2 B6 C7 24 5C 0D F5 91 7A E6 CD 61 31 62 08 2A 9E 3D B6 DE 40 2F A2 00 21 3D 5D BE 71 23 2D ED 47 FC AA 0F AC AD 2B 93 7F B3 67 81 F8 B9 09 CA 32 83 0E 52 CF D4 5D B7 B6 E6
Signature : 0x30440220157d16f6ac89a2b6c7245c0df5917ae6cd613162082a9e3db6de402fa200213d02205dbe71232ded47fcaa0facad2b937fb36781f8b909ca32830e52cfd45db7b6e6
OK
 Sending 0x20 command with 6 bytes data
-> 00 20 00 81 06 31 32 33 34 35 36
 Received 0 bytes data : SW 0x9000 - duration: 17.1 ms
 Sending 0x2A command with 32 bytes data
-> 00 2A 9E 9A 20 F1 10 4E AD 6B 42 85 42 7C 67 8C C0 FC 85 D1 2C F6 7B 3F 20 78 B6 E3 4A 44 2F C5 F6 4E 01 30 EB
 Received 66 bytes data : SW 0x9000 - duration: 93.3 ms
<- 00 22 9E 13 E2 8B 0F F3 FE 5C C4 70 81 C8 33 11 D7 D6 FB 84 7C A9 11 F2 DF F1 65 7E 31 87 48 76 4A 00 88 7D 5A 45 C9 4B 97 3E DA 48 3D 98 E0 BD 2C 74 C7 CE C2 BE FA 9E AC A1 1C 51 26 8B AD 4E 87 F1
Signature : 0x30450220229e13e28b0ff3fe5cc47081c83311d7d6fb847ca911f2dff1657e318748764a022100887d5a45c94b973eda483d98e0bd2c74c7cec2befa9eaca11c51268bad4e87f1
OK
 Sending 0x20 command with 6 bytes data
-> 00 20 00 81 06 31 32 33 34 35 36
 Received 0 bytes data : SW 0x9000 - duration: 17.5 ms
 Sending 0x2A command with 32 bytes data
-> 00 2A 9E 9A 20 F1 10 4E AD 6B 42 85 42 7C 67 8C C0 FC 85 D1 2C F6 7B 3F 20 78 B6 E3 4A 44 2F C5 F6 4E 01 30 EB
 Received 64 bytes data : SW 0x9000 - duration: 93.3 ms
<- 7D CB 49 88 F2 99 F5 45 17 F3 87 58 F2 E1 35 4E A7 D1 D3 C1 8A 25 3C 14 89 3F 0E 0F FC 76 D1 CA 79 07 5E 2F 1D A6 69 26 A7 EE D9 65 33 98 07 5C 3F DA D4 EE ED 5D FE 82 09 78 70 10 CD 5E 2F CE
Signature : 0x304402207dcb4988f299f54517f38758f2e1354ea7d1d3c18a253c14893f0e0ffc76d1ca022079075e2f1da66926a7eed9653398075c3fdad4eeed5dfe8209787010cd5e2fce
OK
 Sending 0x20 command with 6 bytes data
-> 00 20 00 81 06 31 32 33 34 35 36
 Received 0 bytes data : SW 0x9000 - duration: 16.8 ms
 Sending 0x2A command with 32 bytes data
-> 00 2A 9E 9A 20 F1 10 4E AD 6B 42 85 42 7C 67 8C C0 FC 85 D1 2C F6 7B 3F 20 78 B6 E3 4A 44 2F C5 F6 4E 01 30 EB
 Received 64 bytes data : SW 0x9000 - duration: 92.5 ms
<- 5D A3 18 51 A1 4D B8 4D E3 7A 33 87 96 F8 E5 FE 2A 47 5C C9 35 F6 A3 EB 9F CC 75 5F 72 B7 27 E4 0E 69 D1 98 AB 72 3C 5B F2 94 F7 7F E2 B5 F2 7C 1C 96 A3 0F 9B 51 08 8A B8 0C D3 3D 33 AB 04 C2
Signature : 0x304402205da31851a14db84de37a338796f8e5fe2a475cc935f6a3eb9fcc755f72b727e402200e69d198ab723c5bf294f77fe2b5f27c1c96a30f9b51088ab80cd33d33ab04c2
OK
 Sending 0x20 command with 6 bytes data
-> 00 20 00 81 06 31 32 33 34 35 36
 Received 0 bytes data : SW 0x9000 - duration: 17.0 ms
 Sending 0x2A command with 32 bytes data
-> 00 2A 9E 9A 20 F1 10 4E AD 6B 42 85 42 7C 67 8C C0 FC 85 D1 2C F6 7B 3F 20 78 B6 E3 4A 44 2F C5 F6 4E 01 30 EB
 Received 66 bytes data : SW 0x9000 - duration: 93.4 ms
<- 00 E0 79 F5 1D 19 71 F1 DD 64 3C 66 6B 62 DF 20 F9 3D 24 45 C5 05 DE 67 EA 97 00 46 79 0C A7 06 17 00 9F C6 3D FC 82 72 DF 16 FF B1 72 4C 2E 23 49 AE FA C7 05 C6 A8 31 96 ED 6E 0D 94 63 3A D2 2F 6E
Signature : 0x3046022100e079f51d1971f1dd643c666b62df20f93d2445c505de67ea970046790ca706170221009fc63dfc8272df16ffb1724c2e2349aefac705c6a83196ed6e0d94633ad22f6e
OK
 Sending 0x20 command with 6 bytes data
-> 00 20 00 81 06 31 32 33 34 35 36
 Received 0 bytes data : SW 0x9000 - duration: 16.9 ms
 Sending 0x2A command with 32 bytes data
-> 00 2A 9E 9A 20 F1 10 4E AD 6B 42 85 42 7C 67 8C C0 FC 85 D1 2C F6 7B 3F 20 78 B6 E3 4A 44 2F C5 F6 4E 01 30 EB
 Received 66 bytes data : SW 0x9000 - duration: 93.4 ms
<- 00 FB 45 6E 04 FA E0 3D 00 43 36 94 BD 3F E1 E2 64 86 41 06 9B 48 3A 57 49 21 FD 20 86 9E F5 B5 EC 00 AF 14 D6 DE 59 7E 47 10 88 3B 7B 93 FC E9 86 DD 4B A8 B6 28 E9 52 9F 87 73 4C 15 7D 57 A9 B7 59
Signature : 0x3046022100fb456e04fae03d00433694bd3fe1e2648641069b483a574921fd20869ef5b5ec022100af14d6de597e4710883b7b93fce986dd4ba8b628e9529f87734c157d57a9b759
OK
 Sending 0x20 command with 6 bytes data
-> 00 20 00 81 06 31 32 33 34 35 36
 Received 0 bytes data : SW 0x9000 - duration: 18.0 ms
 Sending 0x2A command with 32 bytes data
-> 00 2A 9E 9A 20 F1 10 4E AD 6B 42 85 42 7C 67 8C C0 FC 85 D1 2C F6 7B 3F 20 78 B6 E3 4A 44 2F C5 F6 4E 01 30 EB
 Received 66 bytes data : SW 0x9000 - duration: 92.5 ms
<- 00 2F 12 A2 E0 2C E7 18 AF 31 AC 31 08 05 62 C7 83 02 BC 51 B9 DE B2 5D CD BA C0 3A 2F B1 D5 15 8A 00 E6 15 27 E5 86 49 25 97 E9 A7 AD C6 E3 E5 01 DB C9 96 67 20 5E 12 EB 74 6D 90 D7 38 64 C8 E8 E7
Signature : 0x304502202f12a2e02ce718af31ac31080562c78302bc51b9deb25dcdbac03a2fb1d5158a022100e61527e586492597e9a7adc6e3e501dbc99667205e12eb746d90d73864c8e8e7
OK
 Sending 0x20 command with 6 bytes data
-> 00 20 00 81 06 31 32 33 34 35 36
 Received 0 bytes data : SW 0x9000 - duration: 16.9 ms
 Sending 0x2A command with 32 bytes data
-> 00 2A 9E 9A 20 F1 10 4E AD 6B 42 85 42 7C 67 8C C0 FC 85 D1 2C F6 7B 3F 20 78 B6 E3 4A 44 2F C5 F6 4E 01 30 EB
 Received 66 bytes data : SW 0x9000 - duration: 92.5 ms
<- 00 DF 23 7D 89 A1 8D 34 1C BA C0 15 E7 C6 0F 28 74 2C FB 92 B8 A1 0A BA 35 02 CC AB 05 77 28 FA 71 00 20 99 9C 1E E7 22 CD 16 1D 7F F8 39 25 06 09 A1 4E E4 4A 34 90 13 8C FC 00 96 91 C3 27 8B 6F 85
Signature : 0x3045022100df237d89a18d341cbac015e7c60f28742cfb92b8a10aba3502ccab057728fa71022020999c1ee722cd161d7ff839250609a14ee44a3490138cfc009691c3278b6f85
OK
 Sending 0x20 command with 6 bytes data
-> 00 20 00 81 06 31 32 33 34 35 36
 Received 0 bytes data : SW 0x9000 - duration: 16.8 ms
 Sending 0x2A command with 32 bytes data
-> 00 2A 9E 9A 20 F1 10 4E AD 6B 42 85 42 7C 67 8C C0 FC 85 D1 2C F6 7B 3F 20 78 B6 E3 4A 44 2F C5 F6 4E 01 30 EB
 Received 66 bytes data : SW 0x9000 - duration: 92.7 ms
<- 00 53 1C 3D 04 0F 26 F3 74 7F FD C9 A7 36 E5 B7 1E 2B F4 F6 37 F2 30 69 CC 42 19 94 E3 E2 26 AF E7 00 97 42 77 3A C6 7E 27 1F 71 40 38 F4 4A F3 34 B3 5B 7E 7D B1 43 5B 88 13 E1 FA E6 17 56 B5 20 23
Signature : 0x30450220531c3d040f26f3747ffdc9a736e5b71e2bf4f637f23069cc421994e3e226afe70221009742773ac67e271f714038f44af334b35b7e7db1435b8813e1fae61756b52023
OK
 Sending 0x20 command with 6 bytes data
-> 00 20 00 81 06 31 32 33 34 35 36
 Received 0 bytes data : SW 0x9000 - duration: 17.0 ms
 Sending 0x2A command with 32 bytes data
-> 00 2A 9E 9A 20 F1 10 4E AD 6B 42 85 42 7C 67 8C C0 FC 85 D1 2C F6 7B 3F 20 78 B6 E3 4A 44 2F C5 F6 4E 01 30 EB
 Received 0 bytes data : SW 0x6F00 - duration: 36.7 ms
Crash, game over.
SFYL !
Error status : 0x6F00

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions