aboutsummaryrefslogtreecommitdiff
path: root/src/cz/crcs/ectester/applet/ECTesterApplet.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/cz/crcs/ectester/applet/ECTesterApplet.java')
-rw-r--r--src/cz/crcs/ectester/applet/ECTesterApplet.java182
1 files changed, 112 insertions, 70 deletions
diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java
index cb2c43f..ae19e28 100644
--- a/src/cz/crcs/ectester/applet/ECTesterApplet.java
+++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java
@@ -20,8 +20,8 @@
* SOFTWARE.
*/
/*
- * PACKAGEID: 4C6162616B417070
- * APPLETID: 4C6162616B4170706C6574
+ * PACKAGEID: 4543546573746572
+ * APPLETID: 45435465737465723031
*/
package cz.crcs.ectester.applet;
@@ -32,7 +32,7 @@ import javacard.security.KeyPair;
import javacard.security.RandomData;
/**
- * Reader part of ECTester, a tool for testing Elliptic curve support on javacards.
+ * Applet part of ECTester, a tool for testing Elliptic curve support on javacards.
*
* @author Petr Svenda petr@svenda.com
* @author Jan Jancar johny@neuromancer.sk
@@ -42,35 +42,32 @@ public class ECTesterApplet extends Applet {
// MAIN INSTRUCTION CLASS
public static final byte CLA_ECTESTERAPPLET = (byte) 0xB0;
- //INSTRUCTIONS
+ // INSTRUCTIONS
public static final byte INS_ALLOCATE = (byte) 0x5a;
public static final byte INS_CLEAR = (byte) 0x5b;
public static final byte INS_SET = (byte) 0x5c;
public static final byte INS_GENERATE = (byte) 0x5d;
- public static final byte INS_ECDH = (byte) 0x5e;
- public static final byte INS_ECDSA = (byte) 0x5f;
+ public static final byte INS_EXPORT = (byte) 0x5e;
+ public static final byte INS_ECDH = (byte) 0x5f;
+ public static final byte INS_ECDSA = (byte) 0x60;
- //PARAMETERS for P1 and P2
+ // PARAMETERS for P1 and P2
public static final byte KEYPAIR_LOCAL = (byte) 0x01;
public static final byte KEYPAIR_REMOTE = (byte) 0x02;
public static final byte KEYPAIR_BOTH = KEYPAIR_LOCAL | KEYPAIR_REMOTE;
- public static final byte EXPORT_NONE = (byte) 0x00;
- public static final byte EXPORT_PUBLIC = (byte) 0x04;
- public static final byte EXPORT_PRIVATE = (byte) 0x08;
- public static final byte EXPORT_BOTH = EXPORT_PUBLIC | EXPORT_PRIVATE;
- public static final byte EXPORT_ECDH = (byte) 0x10;
- public static final byte EXPORT_SIG = (byte) 0x20;
+ public static final byte EXPORT_TRUE = (byte) 0xff;
+ public static final byte EXPORT_FALSE = (byte) 0x00;
- //STATUS WORDS
+ // STATUS WORDS
public static final short SW_SIG_VERIFY_FAIL = (short) 0x0ee1;
private static final short ARRAY_LENGTH = (short) 0xff;
// TEMPORARRY ARRAY IN RAM
- private byte ramArray[] = null;
- private byte ramArray2[] = null;
+ private byte[] ramArray = null;
+ private byte[] ramArray2 = null;
// PERSISTENT ARRAY IN EEPROM
- private byte dataArray[] = null; // unused
+ private byte[] dataArray = null; // unused
private RandomData randomData = null;
@@ -120,8 +117,9 @@ public class ECTesterApplet extends Applet {
byte[] apduBuffer = apdu.getBuffer();
// ignore the applet select command dispached to the process
- if (selectingApplet())
+ if (selectingApplet()) {
return;
+ }
if (apduBuffer[ISO7816.OFFSET_CLA] == CLA_ECTESTERAPPLET) {
switch (apduBuffer[ISO7816.OFFSET_INS]) {
@@ -137,6 +135,9 @@ public class ECTesterApplet extends Applet {
case INS_GENERATE:
insGenerate(apdu);
break;
+ case INS_EXPORT:
+ insExport(apdu);
+ break;
case INS_ECDH:
insECDH(apdu);
break;
@@ -174,6 +175,8 @@ public class ECTesterApplet extends Applet {
}
/**
+ * Clears local and remote keyPair's keys {@code .clearKey()}.
+ * returns clearKey SWs
*
* @param apdu P1 = byte keyPair (KEYPAIR_* | ...)
* P2 =
@@ -184,10 +187,12 @@ public class ECTesterApplet extends Applet {
byte keyPair = apdubuf[ISO7816.OFFSET_P1];
short len = 0;
- if ((keyPair & KEYPAIR_LOCAL) != 0)
+ if ((keyPair & KEYPAIR_LOCAL) != 0) {
len += clear(localKeypair, apdubuf, (short) 0);
- if ((keyPair & KEYPAIR_REMOTE) != 0)
+ }
+ if ((keyPair & KEYPAIR_REMOTE) != 0) {
len += clear(remoteKeypair, apdubuf, len);
+ }
apdu.setOutgoingAndSend((short) 0, len);
}
@@ -197,9 +202,8 @@ public class ECTesterApplet extends Applet {
* returns setCurve SWs, set params if export
*
* @param apdu P1 = byte keyPair (KEYPAIR_* | ...)
- * P2 = byte export (EXPORT_* | KEYPAIR_*)
- * DATA = byte curve (EC_Consts.CURVE_*)
- * short params (EC_Consts.PARAMETER_* | ...)
+ * P2 = byte curve (EC_Consts.CURVE_*)
+ * DATA = short params (EC_Consts.PARAMETER_* | ...)
* short corruptedParams (EC_Consts.PARAMETER_* | ...)
* byte corruptionType (EC_Consts.CORRUPTION_*)
* <p>
@@ -213,22 +217,19 @@ public class ECTesterApplet extends Applet {
byte[] apdubuf = apdu.getBuffer();
byte keyPair = apdubuf[ISO7816.OFFSET_P1];
- byte export = apdubuf[ISO7816.OFFSET_P2];
- byte curve = apdubuf[ISO7816.OFFSET_CDATA];
- short params = Util.getShort(apdubuf, (short) (ISO7816.OFFSET_CDATA + 1));
- short corruptedParams = Util.getShort(apdubuf, (short) (ISO7816.OFFSET_CDATA + 3));
- byte corruptionType = apdubuf[(short) (ISO7816.OFFSET_CDATA + 5)];
+ byte curve = apdubuf[ISO7816.OFFSET_P2];
+ short params = Util.getShort(apdubuf, ISO7816.OFFSET_CDATA);
+ short corruptedParams = Util.getShort(apdubuf, (short) (ISO7816.OFFSET_CDATA + 2));
+ byte corruptionType = apdubuf[(short) (ISO7816.OFFSET_CDATA + 4)];
short len = 0;
- if ((keyPair & KEYPAIR_LOCAL) != 0)
+ if ((keyPair & KEYPAIR_LOCAL) != 0) {
len += set(localKeypair, curve, params, corruptedParams, corruptionType, apdubuf, (short) (ISO7816.OFFSET_CDATA + 6), (short) 0);
- if ((keyPair & KEYPAIR_REMOTE) != 0)
+ }
+ if ((keyPair & KEYPAIR_REMOTE) != 0) {
len += set(remoteKeypair, curve, params, corruptedParams, corruptionType, apdubuf, (short) (ISO7816.OFFSET_CDATA + 6), len);
- if ((export & KEYPAIR_LOCAL) != 0)
- len += export(localKeypair, export, params, apdubuf, len);
- if ((export & KEYPAIR_REMOTE) != 0)
- len += export(remoteKeypair, export, params, apdubuf, len);
+ }
apdu.setOutgoingAndSend((short) 0, len);
}
@@ -238,35 +239,61 @@ public class ECTesterApplet extends Applet {
* returns generate SWs, pubkey and privkey if export
*
* @param apdu P1 = byte keyPair (KEYPAIR_* | ...)
- * P2 = byte export (EXPORT_* | KEYPAIR_*)
+ * P2 =
*/
private void insGenerate(APDU apdu) {
apdu.setIncomingAndReceive();
byte[] apdubuf = apdu.getBuffer();
byte keyPair = apdubuf[ISO7816.OFFSET_P1];
- byte export = apdubuf[ISO7816.OFFSET_P2];
short len = 0;
- if ((keyPair & KEYPAIR_LOCAL) != 0)
+ if ((keyPair & KEYPAIR_LOCAL) != 0) {
len += generate(localKeypair, apdubuf, (short) 0);
- if ((keyPair & KEYPAIR_REMOTE) != 0)
+ }
+ if ((keyPair & KEYPAIR_REMOTE) != 0) {
len += generate(remoteKeypair, apdubuf, len);
- if ((export & KEYPAIR_LOCAL) != 0)
- len += export(localKeypair, export, (short) (EC_Consts.PARAMETER_W | EC_Consts.PARAMETER_S), apdubuf, len);
- if ((export & KEYPAIR_REMOTE) != 0)
- len += export(remoteKeypair, export, (short) (EC_Consts.PARAMETER_W | EC_Consts.PARAMETER_S), apdubuf, len);
+ }
+
+ apdu.setOutgoingAndSend((short) 0, len);
+ }
+
+ /**
+ * Exports selected key and domain parameters from the selected keyPair and key.
+ *
+ * @param apdu P1 = byte keyPair (KEYPAIR_* | ...)
+ * P2 = byte key (EC_Consts.KEY_* | ...)
+ * DATA = short params
+ */
+ private void insExport(APDU apdu) {
+ apdu.setIncomingAndReceive();
+ byte[] apdubuf = apdu.getBuffer();
+
+ byte keyPair = apdubuf[ISO7816.OFFSET_P1];
+ byte key = apdubuf[ISO7816.OFFSET_P2];
+ short params = Util.getShort(apdubuf, ISO7816.OFFSET_CDATA);
+
+ short swOffset = 0;
+ short len = (short) (keyPair == KEYPAIR_BOTH ? 4 : 2);
+
+ if ((keyPair & KEYPAIR_LOCAL) != 0) {
+ len += export(localKeypair, key, params, apdubuf, swOffset, len);
+ swOffset += 2;
+ }
+ if ((keyPair & KEYPAIR_REMOTE) != 0) {
+ len += export(remoteKeypair, key, params, apdubuf, swOffset, len);
+ }
apdu.setOutgoingAndSend((short) 0, len);
}
/**
* Performs ECDH, between the pubkey specified in P1(local/remote) and the privkey specified in P2(local/remote).
- * returns deriveSecret SW, if export != 0 => short secretlen, byte[] secret
+ * returns deriveSecret SW, {@code if(export == EXPORT_TRUE)} => short secretlen, byte[] secret
*
* @param apdu P1 = byte pubkey (KEYPAIR_*)
* P2 = byte privkey (KEYPAIR_*)
- * DATA = byte export (EXPORT_ECDH || 0)
+ * DATA = byte export (EXPORT_TRUE || EXPORT_FALSE)
* byte invalid (00 = valid, !00 = invalid)
*/
private void insECDH(APDU apdu) {
@@ -285,10 +312,10 @@ public class ECTesterApplet extends Applet {
/**
* Performs ECDSA signature and verification on data provided or random, using the keyPair in P1(local/remote).
- * returns ecdsa SW, if export != 0 => short signature_length, byte[] signature
+ * returns ecdsa SW, {@code if(export == EXPORT_TRUE)} => short signature_length, byte[] signature
*
* @param apdu P1 = byte keyPair (KEYPAIR_*)
- * P2 = byte export (EXPORT_SIG || 0)
+ * P2 = byte export (EXPORT_TRUE || EXPORT_FALSE)
* DATA = short dataLength (00 = random data generated, !00 = data length)
* byte[] data
*/
@@ -299,7 +326,13 @@ public class ECTesterApplet extends Applet {
byte keyPair = apdubuf[ISO7816.OFFSET_P1];
byte export = apdubuf[ISO7816.OFFSET_P2];
- short len = ecdsa(keyPair, export, apdubuf, ISO7816.OFFSET_CDATA, (short) 0);
+ short len = 0;
+ if ((keyPair & KEYPAIR_LOCAL) != 0) {
+ len += ecdsa(localKeypair, export, apdubuf, ISO7816.OFFSET_CDATA, (short) 0);
+ }
+ if ((keyPair & KEYPAIR_REMOTE) != 0) {
+ len += ecdsa(remoteKeypair, export, apdubuf, ISO7816.OFFSET_CDATA, len);
+ }
apdu.setOutgoingAndSend((short) 0, len);
}
@@ -308,8 +341,8 @@ public class ECTesterApplet extends Applet {
* @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...)
* @param keyLength key length to set
* @param keyClass key class to allocate
- * @param buffer apdu buffer
- * @param offset offset into apdu buffer
+ * @param buffer buffer to write sw to
+ * @param offset offset into buffer
* @return length of data written to the buffer
*/
private short allocate(byte keyPair, short keyLength, byte keyClass, byte[] buffer, short offset) {
@@ -329,8 +362,14 @@ public class ECTesterApplet extends Applet {
return length;
}
+ /**
+ * @param keyPair KeyPair to clear
+ * @param buffer buffer to write sw to
+ * @param offset offset into buffer
+ * @return length of data written to the buffer
+ */
private short clear(KeyPair keyPair, byte[] buffer, short offset) {
- short sw = keyGenerator.clearPair(keyPair, ECKeyGenerator.KEY_BOTH);
+ short sw = keyGenerator.clearPair(keyPair, EC_Consts.KEY_BOTH);
Util.setShort(buffer, offset, sw);
return 2;
@@ -384,26 +423,31 @@ public class ECTesterApplet extends Applet {
}
/**
- * @param keyPair KeyPair to export from
- * @param export which key to export from (EXPORT_PUBLIC | EXPORT_PRIVATE)
- * @param params which params to export (EC_Consts.PARAMETER_* | ...)
- * @param buffer buffer to export params to
- * @param offset output offset in buffer
+ * @param keyPair KeyPair to export from
+ * @param key which key to export from (EC_Consts.KEY_PUBLIC | EC_Consts.KEY_PRIVATE)
+ * @param params which params to export (EC_Consts.PARAMETER_* | ...)
+ * @param buffer buffer to export params to
+ * @param swOffset offset to output sw to buffer
+ * @param offset output offset in buffer
* @return length of data written to the buffer
*/
- private short export(KeyPair keyPair, byte export, short params, byte[] buffer, short offset) {
+ private short export(KeyPair keyPair, byte key, short params, byte[] buffer, short swOffset, short offset) {
short length = 0;
- if ((export & EXPORT_PUBLIC) != 0) {
+ short sw = ISO7816.SW_NO_ERROR;
+ if ((key & EC_Consts.KEY_PUBLIC) != 0) {
//export params from public
- length += keyGenerator.exportParameters(keyPair, ECKeyGenerator.KEY_PUBLIC, params, buffer, offset);
+ length += keyGenerator.exportParameters(keyPair, EC_Consts.KEY_PUBLIC, params, buffer, offset);
+ sw = keyGenerator.getSW();
}
-
- if ((export & EXPORT_PRIVATE) != 0) {
+ //TODO unify this, now that param key == the passed on param.
+ if ((key & EC_Consts.KEY_PRIVATE) != 0 && sw == ISO7816.SW_NO_ERROR) {
//export params from private
- length += keyGenerator.exportParameters(keyPair, ECKeyGenerator.KEY_PRIVATE, params, buffer, (short) (offset + length));
-
+ length += keyGenerator.exportParameters(keyPair, EC_Consts.KEY_PRIVATE, params, buffer, (short) (offset + length));
+ sw = keyGenerator.getSW();
}
+ Util.setShort(buffer, swOffset, sw);
+
return length;
}
@@ -412,7 +456,7 @@ public class ECTesterApplet extends Applet {
* @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE)
* @param export whether to export ECDH secret
* @param invalid whether to invalidate the pubkey before ECDH
- * @param buffer buffer to write sw to, and export ECDH secret if (export & EXPORT_ECDH) != 0
+ * @param buffer buffer to write sw to, and export ECDH secret {@code if(export == EXPORT_TRUE)}
* @param offset output offset in buffer
* @return length of data written to the buffer
*/
@@ -432,7 +476,7 @@ public class ECTesterApplet extends Applet {
Util.setShort(buffer, offset, keyTester.getSW());
length += 2;
- if ((export & EXPORT_ECDH) != 0) {
+ if ((export == EXPORT_TRUE)) {
Util.setShort(buffer, (short) (offset + length), secretLength);
length += 2;
Util.arrayCopyNonAtomic(ramArray2, (short) 0, buffer, (short) (offset + length), secretLength);
@@ -443,14 +487,14 @@ public class ECTesterApplet extends Applet {
}
/**
- * @param keyPair keyPair to use for signing and verification (KEYPAIR_LOCAL || KEYPAIR_REMOTE)
+ * @param sign keyPair to use for signing and verification
* @param export whether to export ECDSA signature
- * @param buffer buffer to write sw to, and export ECDSA signature if (export & EXPORT_SIG) != 0
+ * @param buffer buffer to write sw to, and export ECDSA signature {@code if(export == EXPORT_TRUE)}
* @param inOffset input offset in buffer
* @param outOffset output offset in buffer
* @return length of data written to the buffer
*/
- private short ecdsa(byte keyPair, byte export, byte[] buffer, short inOffset, short outOffset) {
+ private short ecdsa(KeyPair sign, byte export, byte[] buffer, short inOffset, short outOffset) {
short length = 0;
short dataLength = Util.getShort(buffer, inOffset);
@@ -462,13 +506,11 @@ public class ECTesterApplet extends Applet {
Util.arrayCopyNonAtomic(buffer, (short) (inOffset + 2), ramArray, (short) 0, dataLength);
}
- KeyPair sign = ((keyPair & KEYPAIR_LOCAL) != 0) ? localKeypair : remoteKeypair;
-
short signatureLength = keyTester.testECDSA((ECPrivateKey) sign.getPrivate(), (ECPublicKey) sign.getPublic(), ramArray, (short) 0, dataLength, ramArray2, (short) 0);
Util.setShort(buffer, outOffset, keyTester.getSW());
length += 2;
- if ((export & EXPORT_SIG) != 0) {
+ if (export == EXPORT_TRUE) {
Util.setShort(buffer, (short) (outOffset + length), signatureLength);
length += 2;