Skip to content

Commit

Permalink
Avoid wearing out flash storage (if possible)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
darconeous committed Mar 10, 2020
1 parent 14970ef commit f70ec53
Showing 1 changed file with 27 additions and 3 deletions.
30 changes: 27 additions & 3 deletions src/io/github/darconeous/gausskeycard/GaussKeyCard.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.security.AESKey;
import javacard.security.CryptoException;
import javacard.security.ECPrivateKey;
import javacard.security.ECPublicKey;
import javacard.security.KeyAgreement;
Expand All @@ -22,6 +23,11 @@ public class GaussKeyCard extends Applet

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

// Constants from JavaCard 3.x. This way we can still install on
// JC 2.2.2 cards and fall back to the traditional behavior.
private static final byte TYPE_AES_TRANSIENT_DESELECT = 14;
private static final byte TYPE_AES_TRANSIENT_RESET = 13;

private final KeyPair key1;
private final KeyAgreement ecdh;
private final Cipher aes_ecb;
Expand All @@ -44,8 +50,28 @@ public class GaussKeyCard extends Applet

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

ecdh.init(key1.getPrivate());

aes_ecb = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_ECB_NOPAD, false);
aes_key = (AESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_128, false);

AESKey key = null;

try {
// Put the AES key in RAM if we can.
key = (AESKey)KeyBuilder.buildKey(TYPE_AES_TRANSIENT_DESELECT, KeyBuilder.LENGTH_AES_128, false);
} catch (CryptoException e) {
try {
// This will use a bit more RAM, but
// at least it isn't using flash.
key = (AESKey)KeyBuilder.buildKey(TYPE_AES_TRANSIENT_RESET, KeyBuilder.LENGTH_AES_128, false);
} catch (CryptoException x) {
// Uggh. This will wear out the flash
// eventually, but we don't have a better option.
key = (AESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_128, false);
}
}

aes_key = key;

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

ecdh.init(key1.getPrivate());

ecdh.generateSecret(buffer, ISO7816.OFFSET_CDATA, (short)65, buffer, (short)16);

aes_key.setKey(buffer, (short)16);
Expand Down

0 comments on commit f70ec53

Please sign in to comment.