aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nbproject/reader/manifest.mf2
-rw-r--r--src/cz/crcs/ectester/applet/AppletBase.java8
-rw-r--r--src/cz/crcs/ectester/common/output/BaseTextTestWriter.java3
-rw-r--r--src/cz/crcs/ectester/reader/ECTesterReader.java30
-rw-r--r--src/cz/crcs/ectester/reader/output/TextTestWriter.java1
-rw-r--r--src/cz/crcs/ectester/reader/output/XMLTestWriter.java18
-rw-r--r--src/cz/crcs/ectester/reader/output/YAMLTestWriter.java6
-rw-r--r--src/cz/crcs/ectester/reader/response/Response.java28
-rw-r--r--src/cz/crcs/ectester/reader/test/CardCofactorSuite.java2
-rw-r--r--src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java103
10 files changed, 187 insertions, 14 deletions
diff --git a/nbproject/reader/manifest.mf b/nbproject/reader/manifest.mf
index c2a00ee..4bb6334 100644
--- a/nbproject/reader/manifest.mf
+++ b/nbproject/reader/manifest.mf
@@ -1,4 +1,4 @@
Manifest-Version: 1.0
-Class-Path: lib/jcardsim-3.0.4-SNAPSHOT.jar lib/commons-cli-1.4.jar lib/snakeyaml-1.19.jar
+Class-Path: lib/bcprov-jdk15on-1.58.jar lib/jcardsim-3.0.4-SNAPSHOT.jar lib/commons-cli-1.4.jar lib/snakeyaml-1.19.jar
Main-Class: cz.crcs.ectester.reader.ECTesterReader
diff --git a/src/cz/crcs/ectester/applet/AppletBase.java b/src/cz/crcs/ectester/applet/AppletBase.java
index 24272c5..4e488b5 100644
--- a/src/cz/crcs/ectester/applet/AppletBase.java
+++ b/src/cz/crcs/ectester/applet/AppletBase.java
@@ -873,6 +873,14 @@ public abstract class AppletBase extends Applet {
length += 2;
Util.setShort(buffer, (short) (offset + length), (short) (JCSystem.isObjectDeletionSupported() ? 1 : 0));
length += 2;
+ Util.setShort(buffer, (short) (offset + length), (short) buffer.length);
+ length += 2;
+ Util.setShort(buffer, (short) (offset + length), (short) ramArray.length);
+ length += 2;
+ Util.setShort(buffer, (short) (offset + length), (short) ramArray2.length);
+ length += 2;
+ Util.setShort(buffer, (short) (offset + length), (short) apduArray.length);
+ length += 2;
return length;
}
}
diff --git a/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java b/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java
index f60f8bb..85b32a4 100644
--- a/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java
+++ b/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java
@@ -106,6 +106,9 @@ public abstract class BaseTextTestWriter implements TestWriter {
} else {
SimpleTest<? extends BaseTestable> test = (SimpleTest<? extends BaseTestable>) t;
out.append(testableString(test.getTestable()));
+ if (t.getResult().getCause() != null) {
+ out.append(" ┃ ").append(t.getResult().getCause().toString());
+ }
}
return line + out.toString();
}
diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java
index 2a74ea7..377e2ff 100644
--- a/src/cz/crcs/ectester/reader/ECTesterReader.java
+++ b/src/cz/crcs/ectester/reader/ECTesterReader.java
@@ -40,6 +40,7 @@ import cz.crcs.ectester.reader.test.*;
import javacard.framework.ISO7816;
import javacard.security.KeyPair;
import org.apache.commons.cli.*;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.smartcardio.CardException;
import javax.smartcardio.ResponseAPDU;
@@ -48,6 +49,7 @@ import java.io.*;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
+import java.security.Security;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
@@ -145,9 +147,9 @@ public class ECTesterReader {
}
ResponseAPDU selectResp = cardManager.send(SELECT_ECTESTERAPPLET);
if ((short) selectResp.getSW() != ISO7816.SW_NO_ERROR) {
- System.err.println(Colors.error("Failed to select ECTester applet, is it installed?"));
- cardManager.disconnectFromCard();
- System.exit(1);
+ System.err.println(Colors.error("Failed to select ECTester applet, is it installed?"));
+ cardManager.disconnectFromCard();
+ System.exit(1);
}
}
@@ -155,6 +157,12 @@ public class ECTesterReader {
logger = new OutputLogger(true, cfg.log);
respWriter = new ResponseWriter(logger.getPrintStream());
+ // Try adding the BouncyCastleProvider, which might be used in some parts of ECTester.
+ try {
+ Security.addProvider(new BouncyCastleProvider());
+ } catch (SecurityException | NoClassDefFoundError ignored) {
+ }
+
//do action
if (cli.hasOption("export")) {
export();
@@ -167,7 +175,7 @@ public class ECTesterReader {
} else if (cli.hasOption("ecdsa")) {
ecdsa();
} else if (cli.hasOption("info")) {
- info();
+ info();
}
//disconnect
@@ -282,7 +290,7 @@ public class ECTesterReader {
actions.addOption(Option.builder("V").longOpt("version").desc("Print version info.").build());
actions.addOption(Option.builder("h").longOpt("help").desc("Print help.").build());
actions.addOption(Option.builder("ln").longOpt("list-named").desc("Print the list of supported named curves and keys.").hasArg().argName("what").optionalArg(true).build());
- actions.addOption(Option.builder("ls").longOpt("list-suites").desc("List supported test suites.").build());
+ actions.addOption(Option.builder("ls").longOpt("list-suites").desc("List supported test suites.").build());
actions.addOption(Option.builder("e").longOpt("export").desc("Export the defaut curve parameters of the card(if any).").build());
actions.addOption(Option.builder("g").longOpt("generate").desc("Generate <amount> of EC keys.").hasArg().argName("amount").optionalArg(true).build());
actions.addOption(Option.builder("t").longOpt("test").desc("Test ECC support. Optionally specify a test number to run only a part of a test suite. <test_suite>:\n- default:\n- compression:\n- invalid:\n- twist:\n- degenerate:\n- cofactor:\n- wrong:\n- signature:\n- composite:\n- test-vectors:\n- edge-cases:\n- miscellaneous:").hasArg().argName("test_suite[:from[:to]]").optionalArg(true).build());
@@ -359,11 +367,12 @@ public class ECTesterReader {
}
private void info() throws CardException {
- Response.GetInfo info = new Command.GetInfo(cardManager).send();
- System.out.println(String.format("ECTester applet version: %s", info.getVersion()));
- System.out.println(String.format("ECTester applet APDU support: %s", (info.getBase() == ECTesterApplet.BASE_221) ? "basic" : "extended length"));
- System.out.println(String.format("JavaCard API version: %.1f", info.getJavaCardVersion()));
- System.out.println(String.format("JavaCard supports system cleanup: %s", info.getCleanupSupport()));
+ Response.GetInfo info = new Command.GetInfo(cardManager).send();
+ System.out.println(String.format("ECTester applet version: %s", info.getVersion()));
+ System.out.println(String.format("ECTester applet APDU support: %s", (info.getBase() == ECTesterApplet.BASE_221) ? "basic" : "extended length"));
+ System.out.println(String.format("JavaCard API version: %.1f", info.getJavaCardVersion()));
+ System.out.println(String.format("JavaCard supports system cleanup: %s", info.getCleanupSupport()));
+ System.out.println(String.format("Array sizes (apduBuf, ram, ram2, apduArr): %d %d %d %d", info.getApduBufferLength(), info.getRamArrayLength(), info.getRamArray2Length(), info.getApduArrayLength()));
}
/**
@@ -446,6 +455,7 @@ public class ECTesterReader {
respWriter.outputResponse(response);
Response.Export export = new Command.Export(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.KEY_BOTH, EC_Consts.PARAMETERS_KEYPAIR).send();
+ respWriter.outputResponse(export);
if (!response.successful() || !export.successful()) {
if (retry < 10) {
diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java
index a755857..e89d403 100644
--- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java
+++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java
@@ -51,6 +51,7 @@ public class TextTestWriter extends BaseTextTestWriter {
sb.append("═══ ").append(Colors.underline("ECTester applet version:")).append(" ").append(info.getVersion()).append(info.getBase() == ECTesterApplet.BASE_221 ? "" : " (extended length)").append(System.lineSeparator());
sb.append("═══ ").append(Colors.underline("Card ATR:")).append(" ").append(ByteUtil.bytesToHex(cardSuite.getCard().getATR().getBytes(), false)).append(System.lineSeparator());
sb.append("═══ ").append(Colors.underline("JavaCard version:")).append(" ").append(info.getJavaCardVersion()).append(System.lineSeparator());
+ sb.append("═══ ").append(Colors.underline("Array sizes (apduBuf, ram, ram2, apduArr):")).append(" ").append(String.format("%d %d %d %d", info.getApduBufferLength(), info.getRamArrayLength(), info.getRamArray2Length(), info.getApduArrayLength())).append(System.lineSeparator());
CardMngr.CPLC cplc = cardSuite.getCard().getCPLC();
if (!cplc.values().isEmpty()) {
sb.append("═══ ").append(Colors.underline("Card CPLC data:")).append(System.lineSeparator());
diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java
index 8abdea5..9add072 100644
--- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java
+++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java
@@ -116,6 +116,24 @@ public class XMLTestWriter extends BaseXMLTestWriter {
result.setAttribute("javacard", String.format("%.1f", info.getJavaCardVersion()));
result.setAttribute("base", String.format("%#x",info.getBase()));
result.setAttribute("cleanup", String.valueOf(info.getCleanupSupport()));
+ Element arrays = doc.createElement("arrays");
+ Element apduBuf = doc.createElement("length");
+ apduBuf.setAttribute("name", "apduBuf");
+ apduBuf.setTextContent(String.valueOf(info.getApduBufferLength()));
+ Element ramArray = doc.createElement("length");
+ ramArray.setAttribute("name", "ramArray");
+ ramArray.setTextContent(String.valueOf(info.getRamArrayLength()));
+ Element ramArray2 = doc.createElement("length");
+ ramArray2.setAttribute("name", "ramArray2");
+ ramArray2.setTextContent(String.valueOf(info.getRamArray2Length()));
+ Element apduArray = doc.createElement("length");
+ apduArray.setAttribute("name", "apduArray");
+ apduArray.setTextContent(String.valueOf(info.getApduArrayLength()));
+ arrays.appendChild(apduBuf);
+ arrays.appendChild(ramArray);
+ arrays.appendChild(ramArray2);
+ arrays.appendChild(apduArray);
+ result.appendChild(arrays);
} catch (CardException ignored) {
}
return result;
diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java
index 92de6c6..56ecb71 100644
--- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java
+++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java
@@ -91,6 +91,12 @@ public class YAMLTestWriter extends BaseYAMLTestWriter {
result.put("javacard", info.getJavaCardVersion());
result.put("base", info.getBase());
result.put("cleanup", info.getCleanupSupport());
+ Map<String, Integer> arrays = new LinkedHashMap<>();
+ arrays.put("apduBuf", Short.toUnsignedInt(info.getApduBufferLength()));
+ arrays.put("ramArray", Short.toUnsignedInt(info.getRamArrayLength()));
+ arrays.put("ramArray2", Short.toUnsignedInt(info.getRamArray2Length()));
+ arrays.put("apduArray", Short.toUnsignedInt(info.getApduArrayLength()));
+ result.put("arrays", arrays);
} catch (CardException ignored) {
}
return result;
diff --git a/src/cz/crcs/ectester/reader/response/Response.java b/src/cz/crcs/ectester/reader/response/Response.java
index 6f42ba1..235564e 100644
--- a/src/cz/crcs/ectester/reader/response/Response.java
+++ b/src/cz/crcs/ectester/reader/response/Response.java
@@ -436,6 +436,10 @@ public abstract class Response {
private short base;
private short jcVersion;
private short cleanupSupport;
+ private short apduBufferLength;
+ private short ramArrayLength;
+ private short ramArray2Length;
+ private short apduArrayLength;
public GetInfo(ResponseAPDU response, String description, long time) {
super(response, description, time);
@@ -448,6 +452,14 @@ public abstract class Response {
jcVersion = ByteUtil.getShort(data, offset);
offset += 2;
cleanupSupport = ByteUtil.getShort(data, offset);
+ offset += 2;
+ apduBufferLength = ByteUtil.getShort(data, offset);
+ offset += 2;
+ ramArrayLength = ByteUtil.getShort(data, offset);
+ offset += 2;
+ ramArray2Length = ByteUtil.getShort(data, offset);
+ offset += 2;
+ apduArrayLength = ByteUtil.getShort(data, offset);
}
public String getVersion() {
@@ -473,5 +485,21 @@ public abstract class Response {
public boolean getCleanupSupport() {
return cleanupSupport == 1;
}
+
+ public short getApduBufferLength() {
+ return apduBufferLength;
+ }
+
+ public short getRamArrayLength() {
+ return ramArrayLength;
+ }
+
+ public short getRamArray2Length() {
+ return ramArray2Length;
+ }
+
+ public short getApduArrayLength() {
+ return apduArrayLength;
+ }
}
}
diff --git a/src/cz/crcs/ectester/reader/test/CardCofactorSuite.java b/src/cz/crcs/ectester/reader/test/CardCofactorSuite.java
index c8caa8b..172c8af 100644
--- a/src/cz/crcs/ectester/reader/test/CardCofactorSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardCofactorSuite.java
@@ -46,7 +46,7 @@ public class CardCofactorSuite extends CardTestSuite {
for (EC_Key.Public pub : keys) {
Test setPub = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Result.ExpectedValue.FAILURE);
Test ecdh = CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.FAILURE);
- Test objectEcdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, CardUtil.getKATypeString(EC_Consts.KeyAgreement_ALG_EC_SVDP_DH) + " test with degenerate pubkey.", setPub, ecdh);
+ Test objectEcdh = CompoundTest.any(Result.ExpectedValue.SUCCESS, CardUtil.getKATypeString(EC_Consts.KeyAgreement_ALG_EC_SVDP_DH) + " test with degenerate pubkey.", setPub, ecdh);
Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten());
Test rawEcdh = CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on non-generator subgroup.", "Card incorrectly accepted point on non-generator subgroup.");
ecdhTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " cofactor key test.", objectEcdh, rawEcdh));
diff --git a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java
index fbdf103..3abcebb 100644
--- a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java
@@ -9,16 +9,28 @@ import cz.crcs.ectester.common.test.Result;
import cz.crcs.ectester.common.test.Test;
import cz.crcs.ectester.common.test.TestCallback;
import cz.crcs.ectester.common.util.ByteUtil;
+import cz.crcs.ectester.common.util.CardUtil;
+import cz.crcs.ectester.common.util.ECUtil;
import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.reader.CardMngr;
import cz.crcs.ectester.reader.ECTesterReader;
import cz.crcs.ectester.reader.command.Command;
import cz.crcs.ectester.reader.response.Response;
+import javacard.security.KeyPair;
+import javax.crypto.KeyAgreement;
import java.io.IOException;
+import java.math.BigInteger;
+import java.security.*;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPrivateKeySpec;
+import java.security.spec.ECPublicKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
import static cz.crcs.ectester.common.test.Result.ExpectedValue;
import static cz.crcs.ectester.common.test.Result.Value;
@@ -52,8 +64,13 @@ public class CardTestVectorSuite extends CardTestSuite {
throw new IOException("Test vector keys couldn't be located.");
}
List<Test> testVector = new LinkedList<>();
+ Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS));
+ if (!allocate.ok()) {
+ doTest(CompoundTest.all(ExpectedValue.SUCCESS, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()) + ".", allocate));
+ continue;
+ }
- testVector.add(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS));
+ testVector.add(allocate);
testVector.add(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS));
testVector.add(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), ExpectedValue.SUCCESS));
testVector.add(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), ExpectedValue.SUCCESS));
@@ -75,7 +92,89 @@ public class CardTestVectorSuite extends CardTestSuite {
if (cfg.cleanup) {
testVector.add(CommandTest.expect(new Command.Cleanup(this.card), ExpectedValue.ANY));
}
- doTest(CompoundTest.greedyAll(ExpectedValue.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0])));
+ doTest(CompoundTest.greedyAll(ExpectedValue.SUCCESS, "Test vector " + result.getId() + ".", testVector.toArray(new Test[0])));
+ }
+
+ KeyAgreement ka;
+ KeyFactory kf;
+ MessageDigest md;
+ try {
+ ka = KeyAgreement.getInstance("ECDH", "BC");
+ kf = KeyFactory.getInstance("ECDH", "BC");
+ md = MessageDigest.getInstance("SHA1", "BC");
+ } catch (NoSuchAlgorithmException | NoSuchProviderException ex) {
+ return;
+ }
+
+ List<EC_Curve> testCurves = new ArrayList<>();
+ testCurves.addAll(EC_Store.getInstance().getObjects(EC_Curve.class, "secg").values().stream().filter((curve) -> curve.getField() == KeyPair.ALG_EC_FP).collect(Collectors.toList()));
+ testCurves.addAll(EC_Store.getInstance().getObjects(EC_Curve.class, "brainpool").values().stream().filter((curve) -> curve.getField() == KeyPair.ALG_EC_FP).collect(Collectors.toList()));
+ for (EC_Curve curve : testCurves) {
+ List<Test> testVector = new LinkedList<>();
+ Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS));
+ if (!allocate.ok()) {
+ doTest(CompoundTest.all(ExpectedValue.SUCCESS, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()) + ".", allocate));
+ continue;
+ }
+ testVector.add(allocate);
+ testVector.add(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS));
+ testVector.add(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.SUCCESS));
+ CommandTest export = CommandTest.expect(new Command.Export(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETERS_KEYPAIR), ExpectedValue.ANY);
+ testVector.add(export);
+ TestCallback<CommandTestable> kaCallback = new TestCallback<CommandTestable>() {
+ @Override
+ public Result apply(CommandTestable testable) {
+ Response.ECDH ecdhData = (Response.ECDH) testable.getResponse();
+ if (!ecdhData.successful())
+ return new Result(Value.FAILURE, "ECDH was unsuccessful.");
+ if (!ecdhData.hasSecret()) {
+ return new Result(Value.FAILURE, "ECDH response did not contain the derived secret.");
+ }
+ byte[] secret = ecdhData.getSecret();
+ Response.Export keyData = (Response.Export) export.getResponse();
+ byte[] pkey = keyData.getParameter(ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.PARAMETER_W);
+ byte[] skey = keyData.getParameter(ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.PARAMETER_S);
+ ECParameterSpec spec = curve.toSpec();
+ ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec(new BigInteger(1, skey), spec);
+ ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(ECUtil.fromX962(pkey, curve.toCurve()), spec);
+ PrivateKey privKey;
+ PublicKey pubkey;
+ try {
+ privKey = kf.generatePrivate(privKeySpec);
+ pubkey = kf.generatePublic(pubKeySpec);
+ ka.init(privKey);
+ ka.doPhase(pubkey, true);
+ byte[] rawDerived = ka.generateSecret();
+ int fieldSize = (curve.getBits() + 7) / 8;
+ if (rawDerived.length < fieldSize) {
+ byte[] padded = new byte[fieldSize];
+ System.arraycopy(rawDerived, 0, padded, fieldSize - rawDerived.length, rawDerived.length);
+ rawDerived = padded;
+ }
+ byte[] derived = md.digest(rawDerived);
+ if (secret.length != derived.length) {
+ if (secret.length < derived.length) {
+ return new Result(Value.FAILURE, String.format("Derived secret was shorter than expected: %d vs %d (expected).", secret.length, derived.length));
+ } else {
+ return new Result(Value.FAILURE, String.format("Derived secret was longer than expected: %d vs %d (expected).", secret.length, derived.length));
+ }
+ }
+ int diff = ByteUtil.diffBytes(derived, 0, secret, 0, secret.length);
+ if (diff == secret.length) {
+ return new Result(Value.SUCCESS, "Derived secret matched expected value.");
+ } else {
+ return new Result(Value.FAILURE, "Derived secret does not match expected value, first difference was at byte " + String.valueOf(diff) + ".");
+ }
+ } catch (InvalidKeySpecException | InvalidKeyException ex) {
+ return new Result(Value.SUCCESS, "Result could not be verified. " + ex.getMessage());
+ }
+ }
+ };
+ testVector.add(CommandTest.function(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), kaCallback));
+ if (cfg.cleanup) {
+ testVector.add(CommandTest.expect(new Command.Cleanup(this.card), ExpectedValue.ANY));
+ }
+ doTest(CompoundTest.greedyAll(ExpectedValue.SUCCESS, "Validation test on " + curve.getId() + ".", testVector.toArray(new Test[0])));
}
}
}