Skip to content

Commit f70ec53

Browse files
committed
Avoid wearing out flash storage (if possible)
This change is an attempt to avoid unnecessary writes to flash memory during the normal course of using the applet— by preferring `TYPE_AES_TRANSIENT_DESELECT` and `TYPE_AES_TRANSIENT_RESET` over the plain `TYPE_AES`. If neither of the two "transient" types are supported then we will fall back to using `TYPE_AES`. We are also now only initializing the `KeyAgreement` instance once, which should also avoid writing to flash. Both of these changes should improve the longevity of the key card when run on supported hardware.
1 parent 14970ef commit f70ec53

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

src/io/github/darconeous/gausskeycard/GaussKeyCard.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import javacard.framework.ISO7816;
66
import javacard.framework.ISOException;
77
import javacard.security.AESKey;
8+
import javacard.security.CryptoException;
89
import javacard.security.ECPrivateKey;
910
import javacard.security.ECPublicKey;
1011
import javacard.security.KeyAgreement;
@@ -22,6 +23,11 @@ public class GaussKeyCard extends Applet
2223

2324
private static final short OFFSET_CHALLENGE = (short)(ISO7816.OFFSET_CDATA + 65);
2425

26+
// Constants from JavaCard 3.x. This way we can still install on
27+
// JC 2.2.2 cards and fall back to the traditional behavior.
28+
private static final byte TYPE_AES_TRANSIENT_DESELECT = 14;
29+
private static final byte TYPE_AES_TRANSIENT_RESET = 13;
30+
2531
private final KeyPair key1;
2632
private final KeyAgreement ecdh;
2733
private final Cipher aes_ecb;
@@ -44,8 +50,28 @@ public class GaussKeyCard extends Applet
4450

4551
ecdh = KeyAgreement.getInstance(KeyAgreement.ALG_EC_SVDP_DH, false);
4652

53+
ecdh.init(key1.getPrivate());
54+
4755
aes_ecb = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_ECB_NOPAD, false);
48-
aes_key = (AESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_128, false);
56+
57+
AESKey key = null;
58+
59+
try {
60+
// Put the AES key in RAM if we can.
61+
key = (AESKey)KeyBuilder.buildKey(TYPE_AES_TRANSIENT_DESELECT, KeyBuilder.LENGTH_AES_128, false);
62+
} catch (CryptoException e) {
63+
try {
64+
// This will use a bit more RAM, but
65+
// at least it isn't using flash.
66+
key = (AESKey)KeyBuilder.buildKey(TYPE_AES_TRANSIENT_RESET, KeyBuilder.LENGTH_AES_128, false);
67+
} catch (CryptoException x) {
68+
// Uggh. This will wear out the flash
69+
// eventually, but we don't have a better option.
70+
key = (AESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_128, false);
71+
}
72+
}
73+
74+
aes_key = key;
4975

5076
// We shouldn't require high-strength random numbers
5177
// for calculating the challenge salt.
@@ -126,8 +152,6 @@ public class GaussKeyCard extends Applet
126152
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
127153
}
128154

129-
ecdh.init(key1.getPrivate());
130-
131155
ecdh.generateSecret(buffer, ISO7816.OFFSET_CDATA, (short)65, buffer, (short)16);
132156

133157
aes_key.setKey(buffer, (short)16);

0 commit comments

Comments
 (0)