aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/ec/EC_Params.java24
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java7
-rw-r--r--reader/src/main/java/cz/crcs/ectester/reader/ECTesterReader.java59
3 files changed, 78 insertions, 12 deletions
diff --git a/common/src/main/java/cz/crcs/ectester/common/ec/EC_Params.java b/common/src/main/java/cz/crcs/ectester/common/ec/EC_Params.java
index 8d15437..24e9d56 100644
--- a/common/src/main/java/cz/crcs/ectester/common/ec/EC_Params.java
+++ b/common/src/main/java/cz/crcs/ectester/common/ec/EC_Params.java
@@ -5,6 +5,7 @@ import cz.crcs.ectester.common.util.CardUtil;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
/**
@@ -265,6 +266,29 @@ public class EC_Params extends EC_Data {
return p;
}
+ public static EC_Params merge(EC_Params p1, EC_Params p2) {
+ if ((p1.params & p2.params) != 0) {
+ throw new IllegalArgumentException("Cannot merge EC_Params with overlapping parameters.");
+ }
+ short params = (short) (p1.params | p2.params);
+ List<byte[]> dataList = new ArrayList<>();
+ short paramMask = EC_Consts.PARAMETER_FP;
+ while (paramMask <= EC_Consts.PARAMETER_S) {
+ byte[][] paramData;
+ if ((p1.params & paramMask) != 0) {
+ paramData = p1.getParam(paramMask);
+ } else if ((p2.params & paramMask) != 0) {
+ paramData = p2.getParam(paramMask);
+ } else {
+ throw new IllegalArgumentException("Cannot merge EC_Params with overlapping parameters.");
+ }
+ dataList.addAll(Arrays.asList(paramData));
+ paramMask = (short) (paramMask << 1);
+ }
+
+ return new EC_Params(params, dataList.toArray(new byte[dataList.size()][]));
+ }
+
@Override
public String[] expand() {
List<String> out = new ArrayList<>();
diff --git a/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java b/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java
index 6eb0b1a..677075b 100644
--- a/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java
+++ b/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java
@@ -71,6 +71,13 @@ public class ECUtil {
return toX962Compressed(point, spec.getCurve().getField().getFieldSize());
}
+ public static byte[] toX962Uncompressed(byte[][] point) {
+ if (point.length != 2) {
+ return null;
+ }
+ return ByteUtil.concatenate(new byte[]{(byte) (0x04)}, point[0], point[1]);
+ }
+
public static byte[] toX962Uncompressed(ECPoint point, int bits) {
if (point.equals(ECPoint.POINT_INFINITY)) {
return new byte[]{0};
diff --git a/reader/src/main/java/cz/crcs/ectester/reader/ECTesterReader.java b/reader/src/main/java/cz/crcs/ectester/reader/ECTesterReader.java
index 1fa937e..bb11484 100644
--- a/reader/src/main/java/cz/crcs/ectester/reader/ECTesterReader.java
+++ b/reader/src/main/java/cz/crcs/ectester/reader/ECTesterReader.java
@@ -28,6 +28,7 @@ import cz.crcs.ectester.common.cli.CLITools;
import cz.crcs.ectester.common.cli.Colors;
import cz.crcs.ectester.common.ec.EC_Curve;
import cz.crcs.ectester.common.ec.EC_Consts;
+import cz.crcs.ectester.common.ec.EC_Params;
import cz.crcs.ectester.common.output.OutputLogger;
import cz.crcs.ectester.common.output.TestWriter;
import cz.crcs.ectester.common.util.*;
@@ -333,6 +334,7 @@ public class ECTesterReader {
opts.addOption(Option.builder("v").longOpt("verbose").desc("Turn on verbose logging.").build());
opts.addOption(Option.builder().longOpt("format").desc("Output format to use. One of: text,yml,xml.").hasArg().argName("format").build());
+ opts.addOption(Option.builder().longOpt("external").desc("Use external key in ECDH.").build());
opts.addOption(Option.builder().longOpt("alloc-keypair").desc("Use KeyPair allocation method, one of: keypair, keybuilder, any.").hasArg().argName("method").build());
opts.addOption(Option.builder().longOpt("fixed").desc("Generate key(s) only once, keep them for later operations.").build());
opts.addOption(Option.builder().longOpt("fixed-private").desc("Generate private key only once, keep it for later ECDH.").build());
@@ -600,10 +602,23 @@ public class ECTesterReader {
Response gen = new Command.Generate(cardManager, CardConsts.KEYPAIR_BOTH).send();
respWriter.outputResponse(gen);
- if (cfg.anyPublicKey || cfg.anyKey) {
- Response prep = Command.prepareKey(cardManager, EC_Store.getInstance(), cfg, CardConsts.KEYPAIR_REMOTE, EC_Consts.PARAMETER_W).send();
- respWriter.outputResponse(prep);
+ EC_Params keypair = null;
+ if (!cfg.external) {
+ if (cfg.anyPublicKey || cfg.anyKey) {
+ Response prep = Command.prepareKey(cardManager, EC_Store.getInstance(), cfg, CardConsts.KEYPAIR_REMOTE, EC_Consts.PARAMETER_W).send();
+ respWriter.outputResponse(prep);
+ }
+ } else {
+ if (cfg.key != null || cfg.namedKey != null) {
+ keypair = ECUtil.loadParams(EC_Consts.PARAMETERS_KEYPAIR, cfg.namedKey, cfg.key);
+ } else if (cfg.publicKey != null || cfg.namedPublicKey != null) {
+ keypair = ECUtil.loadParams(EC_Consts.PARAMETER_W, cfg.namedPublicKey, cfg.publicKey);
+ } else {
+ System.err.println(Colors.error("No key provided for external ECDH."));
+ return;
+ }
}
+
if (cfg.anyPrivateKey || cfg.anyKey) {
Response prep = Command.prepareKey(cardManager, EC_Store.getInstance(), cfg, CardConsts.KEYPAIR_LOCAL, EC_Consts.PARAMETER_S).send();
respWriter.outputResponse(prep);
@@ -633,21 +648,34 @@ public class ECTesterReader {
respWriter.outputResponse(regen);
}
- Response.Export exportRemote = new Command.Export(cardManager, CardConsts.KEYPAIR_REMOTE, EC_Consts.KEY_PUBLIC, EC_Consts.PARAMETER_W).send();
- respWriter.outputResponse(exportRemote);
- Response.Export exportLocal = new Command.Export(cardManager, CardConsts.KEYPAIR_LOCAL, EC_Consts.KEY_PRIVATE, EC_Consts.PARAMETER_S).send();
- respWriter.outputResponse(exportLocal);
- byte[] pubkey_bytes = exportRemote.getParameter(CardConsts.KEYPAIR_REMOTE, EC_Consts.PARAMETER_W);
- byte[] privkey_bytes = exportLocal.getParameter(CardConsts.KEYPAIR_LOCAL, EC_Consts.PARAMETER_S);
+ byte[] privkey_bytes;
+ byte[] pubkey_bytes;
+ Command perform;
+ if (cfg.external) {
+ Response.Export exportLocal = new Command.Export(cardManager, CardConsts.KEYPAIR_LOCAL, EC_Consts.KEY_PRIVATE, EC_Consts.PARAMETER_S).send();
+ respWriter.outputResponse(exportLocal);
+ privkey_bytes = exportLocal.getParameter(CardConsts.KEYPAIR_LOCAL, EC_Consts.PARAMETER_S);
+ pubkey_bytes = ECUtil.toX962Uncompressed(keypair.getParam(EC_Consts.PARAMETER_W));
+
+ perform = new Command.ECDH_direct(cardManager, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, cfg.ECKAType, pubkey_bytes);
+ } else {
+ Response.Export exportRemote = new Command.Export(cardManager, CardConsts.KEYPAIR_REMOTE, EC_Consts.KEY_PUBLIC, EC_Consts.PARAMETER_W).send();
+ respWriter.outputResponse(exportRemote);
+ Response.Export exportLocal = new Command.Export(cardManager, CardConsts.KEYPAIR_LOCAL, EC_Consts.KEY_PRIVATE, EC_Consts.PARAMETER_S).send();
+ respWriter.outputResponse(exportLocal);
+ pubkey_bytes = exportRemote.getParameter(CardConsts.KEYPAIR_REMOTE, EC_Consts.PARAMETER_W);
+ privkey_bytes = exportLocal.getParameter(CardConsts.KEYPAIR_LOCAL, EC_Consts.PARAMETER_S);
+
+ perform = new Command.ECDH(cardManager, CardConsts.KEYPAIR_REMOTE, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, cfg.ECKAType);
+ }
- Command.ECDH perform = new Command.ECDH(cardManager, CardConsts.KEYPAIR_REMOTE, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, cfg.ECKAType);
long time = 0;
if (cfg.time) {
time = -Command.dryRunTime(cardManager, perform, 2, respWriter);
}
- Response.ECDH result = perform.send();
+ Response.ECDH result = (Response.ECDH) perform.send();
respWriter.outputResponse(result);
if (!result.successful() || !result.hasSecret()) {
@@ -842,7 +870,7 @@ public class ECTesterReader {
public boolean fixedKey = false;
public boolean fixedPrivate = false;
public boolean fixedPublic = false;
- public byte keyBuilder;
+ public byte keyBuilder = CardConsts.BUILD_KEYBUILDER | CardConsts.BUILD_KEYPAIR;
public String log;
@@ -859,6 +887,7 @@ public class ECTesterReader {
public boolean color;
//Action-related options
+ public boolean external;
public String listNamed;
public String testSuite;
public int testFrom;
@@ -1080,6 +1109,12 @@ public class ECTesterReader {
}
} else if (cli.hasOption("ecdh")) {
+ external = cli.hasOption("external");
+ if (external && !(anyPublicKey || anyKey)) {
+ System.err.print(Colors.error("Need to specify public key with -pub or -named-public (or key with -key or -named-key) when specifying --external."));
+ return false;
+ }
+
if (primeField == binaryField) {
System.err.print(Colors.error("Need to specify field with -fp or -f2m. (not both)"));
return false;