aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpetrs2017-06-16 17:24:48 +0200
committerpetrs2017-06-16 17:24:48 +0200
commit7ab02af142427a996cedf7540ffa3345612fe1bc (patch)
tree058f525742c9af67506bee5a4108c06369c1f3ea /src
parent359b4bb5be1a822e389e54b9697504f4f0b43d34 (diff)
downloadECTester-7ab02af142427a996cedf7540ffa3345612fe1bc.tar.gz
ECTester-7ab02af142427a996cedf7540ffa3345612fe1bc.tar.zst
ECTester-7ab02af142427a996cedf7540ffa3345612fe1bc.zip
Diffstat (limited to 'src')
-rw-r--r--src/cz/crcs/ectester/applet/ECKeyTester.java15
-rw-r--r--src/cz/crcs/ectester/applet/ECTesterApplet.java66
-rw-r--r--src/cz/crcs/ectester/reader/Command.java27
-rw-r--r--src/cz/crcs/ectester/reader/ECTester.java7
-rw-r--r--src/cz/crcs/ectester/reader/Response.java17
-rw-r--r--src/cz/crcs/ectester/reader/Util.java33
6 files changed, 155 insertions, 10 deletions
diff --git a/src/cz/crcs/ectester/applet/ECKeyTester.java b/src/cz/crcs/ectester/applet/ECKeyTester.java
index b18073f..0b3c1e0 100644
--- a/src/cz/crcs/ectester/applet/ECKeyTester.java
+++ b/src/cz/crcs/ectester/applet/ECKeyTester.java
@@ -3,6 +3,7 @@ package cz.crcs.ectester.applet;
import javacard.framework.CardRuntimeException;
import javacard.framework.ISO7816;
+import javacard.framework.ISOException;
import javacard.security.*;
/**
@@ -19,20 +20,20 @@ public class ECKeyTester {
private short sw = ISO7816.SW_NO_ERROR;
- public short allocateECDH() {
+ public short allocateECDH(byte algorithm) {
sw = ISO7816.SW_NO_ERROR;
try {
- ecdhKeyAgreement = KeyAgreement.getInstance(KeyAgreement.ALG_EC_SVDP_DH, false);
+ ecdhKeyAgreement = KeyAgreement.getInstance(algorithm, false);
} catch (CardRuntimeException ce) {
sw = ce.getReason();
}
return sw;
}
- public short allocateECDHC() {
+ public short allocateECDHC(byte algorithm) {
sw = ISO7816.SW_NO_ERROR;
try {
- ecdhcKeyAgreement = KeyAgreement.getInstance(KeyAgreement.ALG_EC_SVDP_DHC, false);
+ ecdhcKeyAgreement = KeyAgreement.getInstance(algorithm, false);
} catch (CardRuntimeException ce) {
sw = ce.getReason();
}
@@ -55,9 +56,11 @@ public class ECKeyTester {
sw = AppletUtil.kaCheck(ka);
sw = AppletUtil.keypairCheck(privatePair);
sw = AppletUtil.keypairCheck(publicPair);
-
- ka.init(privatePair.getPrivate());
short pubkeyLength = ((ECPublicKey) publicPair.getPublic()).getW(pubkeyBuffer, pubkeyOffset);
+ // reached ok
+ ka.init(privatePair.getPrivate()); // throws UNITIALIZED KEY when ALG_EC_SVDP_DHC_PLAIN is used
+ //ISOException.throwIt((short) 0x666);
+
pubkeyLength = EC_Consts.corruptParameter(corruption, pubkeyBuffer, pubkeyOffset, pubkeyLength);
length = ka.generateSecret(pubkeyBuffer, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset);
} catch (CardRuntimeException ce) {
diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java
index c2e2c63..447d9af 100644
--- a/src/cz/crcs/ectester/applet/ECTesterApplet.java
+++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java
@@ -28,6 +28,7 @@ package cz.crcs.ectester.applet;
import javacard.framework.*;
import javacard.security.ECPrivateKey;
import javacard.security.ECPublicKey;
+import javacard.security.KeyAgreement;
import javacard.security.KeyPair;
import javacard.security.RandomData;
import javacardx.apdu.ExtendedLength;
@@ -69,7 +70,21 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
public static final short SW_KEYPAIR_NULL = (short) 0x0ee3;
public static final short SW_KA_NULL = (short) 0x0ee4;
public static final short SW_SIGNATURE_NULL = (short) 0x0ee5;
- public static final short SW_OBJECT_NULL = (short) 0x0ee6;
+ public static final short SW_OBJECT_NULL = (short) 0x0ee6;
+ public static final short SW_KA_UNSUPPORTED = (short) 0x0ee7;
+
+
+ // Class javacard.security.KeyAgreement
+ // javacard.security.KeyAgreement Fields:
+ public static final byte KeyAgreement_ALG_EC_SVDP_DH = 1;
+ public static final byte KeyAgreement_ALG_EC_SVDP_DH_KDF = 1;
+ public static final byte KeyAgreement_ALG_EC_SVDP_DHC = 2;
+ public static final byte KeyAgreement_ALG_EC_SVDP_DHC_KDF = 2;
+ public static final byte KeyAgreement_ALG_EC_SVDP_DH_PLAIN = 3;
+ public static final byte KeyAgreement_ALG_EC_SVDP_DHC_PLAIN = 4;
+ public static final byte KeyAgreement_ALG_EC_PACE_GM = 5;
+ public static final byte KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY = 6;
+ public static final byte KeyAgreement_ALG_DH_PLAIN = 7;
private static final short ARRAY_LENGTH = (short) 0xff;
@@ -116,8 +131,10 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
keyGenerator = new ECKeyGenerator();
keyTester = new ECKeyTester();
- ecdhSW = keyTester.allocateECDH();
- ecdhcSW = keyTester.allocateECDHC();
+ ecdhSW = keyTester.allocateECDH(KeyAgreement.ALG_EC_SVDP_DH);
+ ecdhcSW = keyTester.allocateECDHC(KeyAgreement.ALG_EC_SVDP_DHC);
+ //ecdhSW = keyTester.allocateECDH((byte) 3);
+ //ecdhcSW = keyTester.allocateECDHC((byte) 4);
ecdsaSW = keyTester.allocateECDSA();
}
register();
@@ -144,6 +161,9 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
short length = 0;
switch (ins) {
+ case INS_ALLOCATE_KA:
+ length = insAllocateKA(apdu);
+ break;
case INS_ALLOCATE:
length = insAllocate(apdu);
break;
@@ -186,7 +206,45 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
apdu.setOutgoingAndSend((short) 0, length);
} else ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
-
+
+ /**
+ * Allocates KeyAgreement object. returns allocate SW
+ *
+ * @param apdu DATA = byte KeyAgreementType
+ * @return length of response
+ */
+ private short insAllocateKA(APDU apdu) {
+ short cdata = apdu.getOffsetCdata();
+ byte kaType = apduArray[cdata];
+/*
+ short sw = SW_KA_UNSUPPORTED;
+ switch (kaType) {
+ case KeyAgreement_ALG_EC_SVDP_DH: // no break
+ case KeyAgreement_ALG_EC_SVDP_DH_PLAIN:
+ case KeyAgreement_ALG_EC_PACE_GM:
+ case KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY:
+ sw = keyTester.allocateECDH(kaType);
+ break;
+ case KeyAgreement_ALG_EC_SVDP_DHC:
+ case KeyAgreement_ALG_EC_SVDP_DHC_PLAIN:
+ sw = keyTester.allocateECDHC(kaType);
+ break;
+ default:
+ sw = SW_KA_UNSUPPORTED;
+ break;
+ }
+*/
+ // Allocate given type into both DH and DHC objects
+ short sw = keyTester.allocateECDH(kaType);
+ short offset = 0;
+ Util.setShort(apdu.getBuffer(), offset, sw);
+ offset += 2;
+
+ //sw = keyTester.allocateECDHC(kaType);
+ Util.setShort(apdu.getBuffer(), offset, sw);
+ offset += 2;
+ return offset;
+ }
/**
* Allocates local and remote keyPairs.
* returns allocate SWs
diff --git a/src/cz/crcs/ectester/reader/Command.java b/src/cz/crcs/ectester/reader/Command.java
index 5b7be01..8cb3a30 100644
--- a/src/cz/crcs/ectester/reader/Command.java
+++ b/src/cz/crcs/ectester/reader/Command.java
@@ -211,6 +211,33 @@ public abstract class Command {
return new Response.Allocate(response, elapsed, keyPair, keyLength, keyClass);
}
}
+
+ public static class AllocateKeyAgreement extends Command {
+
+ private byte kaType;
+
+
+ /**
+ * Creates the INS_ALLOCATE_KA instruction.
+ *
+ * @param cardManager cardManager to send APDU through
+ * @param kaType which type of KeyAgreement to use
+ */
+ protected AllocateKeyAgreement(CardMngr cardManager, byte kaType) {
+ super(cardManager);
+ this.kaType = kaType;
+ byte[] data = new byte[]{kaType};
+ this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE_KA, 0x00, 0x00, data);
+ }
+
+ @Override
+ public Response.AllocateKeyAgreement send() throws CardException {
+ long elapsed = -System.nanoTime();
+ ResponseAPDU response = cardManager.send(cmd);
+ elapsed += System.nanoTime();
+ return new Response.AllocateKeyAgreement(response, elapsed, kaType);
+ }
+ }
/**
*
diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java
index 3b5b84f..bb555f9 100644
--- a/src/cz/crcs/ectester/reader/ECTester.java
+++ b/src/cz/crcs/ectester/reader/ECTester.java
@@ -22,6 +22,7 @@
package cz.crcs.ectester.reader;
import cz.crcs.ectester.applet.ECTesterApplet;
+import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH;
import cz.crcs.ectester.applet.EC_Consts;
import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.reader.ec.EC_Category;
@@ -219,6 +220,7 @@ public class ECTester {
actions.addOption(Option.builder("dh").longOpt("ecdh").desc("Do ECDH, [count] times.").hasArg().argName("count").optionalArg(true).build());
actions.addOption(Option.builder("dhc").longOpt("ecdhc").desc("Do ECDHC, [count] times.").hasArg().argName("count").optionalArg(true).build());
actions.addOption(Option.builder("dsa").longOpt("ecdsa").desc("Sign data with ECDSA, [count] times.").hasArg().argName("count").optionalArg(true).build());
+
opts.addOptionGroup(actions);
OptionGroup size = new OptionGroup();
@@ -259,6 +261,8 @@ public class ECTester {
opts.addOption(Option.builder("s").longOpt("simulate").desc("Simulate a card with jcardsim instead of using a terminal.").build());
opts.addOption(Option.builder("y").longOpt("yes").desc("Accept all warnings and prompts.").build());
+ opts.addOption(Option.builder("ka").longOpt("ka-type").desc("Set KeyAgreement object [type], corresponds to JC.KeyAgreement constants.").hasArg().argName("type").optionalArg(true).build());
+
CommandLineParser parser = new DefaultParser();
return parser.parse(opts, args);
}
@@ -442,6 +446,7 @@ public class ECTester {
private void ecdh() throws IOException, CardException {
byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M;
List<Response> prepare = new LinkedList<>();
+ prepare.add(new Command.AllocateKeyAgreement(cardManager, cfg.kaType).send()); // Prepare KeyAgreement or required type
prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass).send());
Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass);
if (curve != null)
@@ -581,6 +586,7 @@ public class ECTester {
public boolean all;
public boolean primeField = false;
public boolean binaryField = false;
+ public byte kaType = KeyAgreement_ALG_EC_SVDP_DH;
public String namedCurve;
public String curveFile;
@@ -628,6 +634,7 @@ public class ECTester {
all = cli.hasOption("all");
primeField = cli.hasOption("fp");
binaryField = cli.hasOption("f2m");
+ kaType = Byte.parseByte(cli.getOptionValue("ka-type", "1"));
namedCurve = cli.getOptionValue("named-curve");
customCurve = cli.hasOption("custom");
diff --git a/src/cz/crcs/ectester/reader/Response.java b/src/cz/crcs/ectester/reader/Response.java
index d74724c..3df956e 100644
--- a/src/cz/crcs/ectester/reader/Response.java
+++ b/src/cz/crcs/ectester/reader/Response.java
@@ -154,9 +154,26 @@ public abstract class Response {
return out.toString();
}
+
/**
*
*/
+ public static class AllocateKeyAgreement extends Response {
+ byte kaType;
+ protected AllocateKeyAgreement(ResponseAPDU response, long time, byte kaType) {
+ super(response, time);
+ this.kaType = kaType;
+
+ parse(2, 0);
+ }
+
+ @Override
+ public String toString() {
+ return super.toString(String.format("Allocate KeyAgreement(%s) object", Util.getKATypeString(this.kaType)));
+ }
+
+ }
+
public static class Allocate extends Response {
private byte keyPair;
diff --git a/src/cz/crcs/ectester/reader/Util.java b/src/cz/crcs/ectester/reader/Util.java
index e7b7338..754cda3 100644
--- a/src/cz/crcs/ectester/reader/Util.java
+++ b/src/cz/crcs/ectester/reader/Util.java
@@ -1,6 +1,12 @@
package cz.crcs.ectester.reader;
import cz.crcs.ectester.applet.ECTesterApplet;
+import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_PACE_GM;
+import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH;
+import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC;
+import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC_PLAIN;
+import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_PLAIN;
+import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY;
import cz.crcs.ectester.applet.EC_Consts;
import javacard.framework.ISO7816;
import javacard.security.CryptoException;
@@ -339,4 +345,31 @@ public class Util {
}
return algo;
}
+
+ public static String getKATypeString(byte kaType) {
+ String kaTypeString = "unknown";
+ switch (kaType) {
+ case KeyAgreement_ALG_EC_SVDP_DH:
+ kaTypeString = "ALG_EC_SVDP_DH";
+ break;
+ case KeyAgreement_ALG_EC_SVDP_DH_PLAIN:
+ kaTypeString = "ALG_EC_SVDP_DH_PLAIN";
+ break;
+ case KeyAgreement_ALG_EC_PACE_GM:
+ kaTypeString = "ALG_EC_PACE_GM";
+ break;
+ case KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY:
+ kaTypeString = "ALG_EC_SVDP_DH_PLAIN_XY";
+ break;
+ case KeyAgreement_ALG_EC_SVDP_DHC:
+ kaTypeString = "ALG_EC_SVDP_DHC";
+ break;
+ case KeyAgreement_ALG_EC_SVDP_DHC_PLAIN:
+ kaTypeString = "ALG_EC_SVDP_DHC_PLAIN";
+ break;
+ default:
+ kaTypeString = "unknown";
+ }
+ return kaTypeString;
+ }
}