aboutsummaryrefslogtreecommitdiff
path: root/src/cz/crcs/ectester/reader/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/cz/crcs/ectester/reader/test')
-rw-r--r--src/cz/crcs/ectester/reader/test/CardCofactorSuite.java5
-rw-r--r--src/cz/crcs/ectester/reader/test/CardCompositeSuite.java14
-rw-r--r--src/cz/crcs/ectester/reader/test/CardCompressionSuite.java4
-rw-r--r--src/cz/crcs/ectester/reader/test/CardDefaultSuite.java9
-rw-r--r--src/cz/crcs/ectester/reader/test/CardDegenerateSuite.java19
-rw-r--r--src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java67
-rw-r--r--src/cz/crcs/ectester/reader/test/CardInvalidSuite.java14
-rw-r--r--src/cz/crcs/ectester/reader/test/CardMiscSuite.java2
-rw-r--r--src/cz/crcs/ectester/reader/test/CardSignatureSuite.java2
-rw-r--r--src/cz/crcs/ectester/reader/test/CardTestSuite.java22
-rw-r--r--src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java86
-rw-r--r--src/cz/crcs/ectester/reader/test/CardTwistSuite.java16
-rw-r--r--src/cz/crcs/ectester/reader/test/CommandTest.java2
-rw-r--r--src/cz/crcs/ectester/reader/test/PerformanceTest.java42
14 files changed, 237 insertions, 67 deletions
diff --git a/src/cz/crcs/ectester/reader/test/CardCofactorSuite.java b/src/cz/crcs/ectester/reader/test/CardCofactorSuite.java
index 172c8af..982e07a 100644
--- a/src/cz/crcs/ectester/reader/test/CardCofactorSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardCofactorSuite.java
@@ -25,7 +25,8 @@ import static cz.crcs.ectester.common.test.Result.ExpectedValue;
*/
public class CardCofactorSuite extends CardTestSuite {
public CardCofactorSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) {
- super(writer, cfg, cardManager, "cofactor", "The cofactor test suite tests whether the card correctly rejects points on the curve but not in the subgroup generated by the generator during ECDH.");
+ super(writer, cfg, cardManager, "cofactor", "The cofactor test suite tests whether the card correctly rejects points on the curve",
+ "but not in the subgroup generated by the generator(so of small order, dividing the cofactor) during ECDH.");
}
@Override
@@ -38,7 +39,7 @@ public class CardCofactorSuite extends CardTestSuite {
Test allocate = CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS);
Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS);
- Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS);
+ Test generate = genOrPreset(curve, ExpectedValue.SUCCESS);
Test prepare = CompoundTest.all(ExpectedValue.SUCCESS, "Prepare and generate keypair on " + curve.getId() + ".", allocate, set, generate);
diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java
index 4bf9290..93d50e8 100644
--- a/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java
@@ -25,7 +25,8 @@ import static cz.crcs.ectester.common.test.Result.ExpectedValue;
public class CardCompositeSuite extends CardTestSuite {
public CardCompositeSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) {
- super(writer, cfg, cardManager, "composite", "The composite suite runs ECDH over curves with composite order. This should generally fail, as using such a curve is unsafe.");
+ super(writer, cfg, cardManager, "composite", "The composite suite runs ECDH over curves with composite order.",
+ "Various types of compositeness is tested: smooth numbers, Carmichael pseudoprime, prime square, product of two large primes.");
}
@Override
@@ -48,11 +49,18 @@ public class CardCompositeSuite extends CardTestSuite {
}
tests.add(allocate);
tests.add(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY));
- tests.add(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY));
+
+ String name;
+ if (cfg.testOptions.contains("preset")) {
+ name = "preset semi-random key";
+ } else {
+ name = "generated key";
+ }
+ tests.add(genOrPreset(curve, ExpectedValue.ANY));
for (EC_Key key : curveKeys.getValue()) {
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, key.flatten());
Test ecdh = CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key.");
- tests.add(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", " + key.getDesc(), ecdh));
+ tests.add(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", with " + name + ", " + key.getDesc(), ecdh));
}
doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ".", tests.toArray(new Test[0])));
}
diff --git a/src/cz/crcs/ectester/reader/test/CardCompressionSuite.java b/src/cz/crcs/ectester/reader/test/CardCompressionSuite.java
index 291cc04..c86c0b1 100644
--- a/src/cz/crcs/ectester/reader/test/CardCompressionSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardCompressionSuite.java
@@ -29,7 +29,9 @@ import java.util.Map;
public class CardCompressionSuite extends CardTestSuite {
public CardCompressionSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) {
super(writer, cfg, cardManager, "compression", "The compression test suite tests cards support for compressed points in ECDH (as per ANSI X9.62).",
- "It also tests for handling of bogus input by using the point at infinity and a hybrid point with the y coordinate corrupted.");
+ "It also tests for handling of bogus input in ECDH by using the point at infinity and a hybrid point with the y coordinate corrupted.",
+ "It also tests handling of compressed point in ECDH, where the x coordinate is invalid and therefore",
+ "a quadratic non-residue will be computed and (square root-ed) during decompression.");
}
@Override
diff --git a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java
index 91f9ef6..ebece61 100644
--- a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java
@@ -10,7 +10,6 @@ import cz.crcs.ectester.common.util.CardUtil;
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 java.util.LinkedList;
@@ -29,7 +28,7 @@ import static cz.crcs.ectester.common.test.Result.Value;
public class CardDefaultSuite extends CardTestSuite {
public CardDefaultSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) {
- super(writer, cfg, cardManager, "default", "The default test suite tests basic support of ECDH and ECDSA.");
+ super(writer, cfg, cardManager, "default", "The default test suite tests basic support and performance of ECDH and ECDSA.");
}
@Override
@@ -83,7 +82,7 @@ public class CardDefaultSuite extends CardTestSuite {
Test compound;
if (ka.ok()) {
- Test perfTest = runTest(PerformanceTest.repeat(ecdh, 10));
+ Test perfTest = runTest(PerformanceTest.repeat(this.card, ecdh, 10));
compound = runTest(CompoundTest.function(kaCallback, kaDesc, allocate, ka, kaCompressed, perfTest));
} else {
compound = runTest(CompoundTest.function(kaCallback, kaDesc, allocate, ka, kaCompressed));
@@ -114,10 +113,10 @@ public class CardDefaultSuite extends CardTestSuite {
Test compound;
if (expect.ok()) {
Command ecdsaSign = new Command.ECDSA_sign(this.card, ECTesterApplet.KEYPAIR_LOCAL, sigType, ECTesterApplet.EXPORT_TRUE, sigData);
- PerformanceTest signTest = runTest(PerformanceTest.repeat("Sign", ecdsaSign, 10));
+ PerformanceTest signTest = runTest(PerformanceTest.repeat(this.card, "Sign", ecdsaSign, 10));
byte[] signature = signTest.getResponses()[0].getParam(0);
Command ecdsaVerify = new Command.ECDSA_verify(this.card, ECTesterApplet.KEYPAIR_LOCAL, sigType, sigData, signature);
- PerformanceTest verifyTest = runTest(PerformanceTest.repeat("Verify", ecdsaVerify, 10));
+ PerformanceTest verifyTest = runTest(PerformanceTest.repeat(this.card, "Verify", ecdsaVerify, 10));
compound = runTest(CompoundTest.all(ExpectedValue.SUCCESS, signDesc, allocate, expect, signTest, verifyTest));
} else {
compound = runTest(CompoundTest.all(ExpectedValue.SUCCESS, signDesc, allocate, expect));
diff --git a/src/cz/crcs/ectester/reader/test/CardDegenerateSuite.java b/src/cz/crcs/ectester/reader/test/CardDegenerateSuite.java
index f434d4d..730c70b 100644
--- a/src/cz/crcs/ectester/reader/test/CardDegenerateSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardDegenerateSuite.java
@@ -25,7 +25,7 @@ public class CardDegenerateSuite extends CardTestSuite {
public CardDegenerateSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) {
super(writer, cfg, cardManager, "degenerate", "The degenerate suite tests whether the card rejects points outside of the curve during ECDH.",
- "The tested points lie on a part of the plane for which some Edwards, Hessian and Huff form addition formulas work.");
+ "The tested points lie on a part of the plane for which some Edwards, Hessian and Huff form addition formulas degenerate into exponentiation in the base finite field.");
}
@Override
@@ -36,27 +36,32 @@ public class CardDegenerateSuite extends CardTestSuite {
EC_Curve curve = e.getKey();
List<EC_Key.Public> keys = e.getValue();
- Test allocate = CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS);
+ Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS));
+ if (!allocate.ok()) {
+ doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for " + curve.getId() + ".", allocate));
+ continue;
+ }
Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS);
Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS);
- Test prepare = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Prepare and generate keypair on " + curve.getId(), allocate, set, generate);
+ Test prepare = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Prepare and generate keypair on " + curve.getId() + ".", allocate, set, generate);
List<Test> ecdhTests = new LinkedList<>();
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 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, "Card correctly rejected point on degenerate curve.", "Card incorrectly accepted point on degenerate curve.");
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, Result.ExpectedValue.FAILURE, "Card correctly rejected point on degenerate curve.", "Card incorrectly accepted point on degenerate curve.");
ecdhTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " degenerate key test.", objectEcdh, rawEcdh));
+ //TODO: actually get the result of ECDH here, as well as export privkey and compare to exponentiation in Fp^*.
}
- Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with degenerate public points", ecdhTests.toArray(new Test[0]));
+ Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with degenerate public points.", ecdhTests.toArray(new Test[0]));
if (cfg.cleanup) {
Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.ANY);
- doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Degenerate curve test of " + curve.getId(), prepare, ecdh, cleanup));
+ doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Degenerate curve test of " + curve.getId() + ".", prepare, ecdh, cleanup));
} else {
- doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Degenerate curve test of " + curve.getId(), prepare, ecdh));
+ doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Degenerate curve test of " + curve.getId() + ".", prepare, ecdh));
}
}
diff --git a/src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java b/src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java
index ccec401..53f3b6b 100644
--- a/src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java
@@ -33,6 +33,7 @@ public class CardEdgeCasesSuite extends CardTestSuite {
public CardEdgeCasesSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) {
super(writer, cfg, cardManager, "edge-cases", "The edge-cases test suite tests various inputs to ECDH which may cause an implementation to achieve a certain edge-case state during it.",
"Some of the data is from the google/Wycheproof project. Tests include CVE-2017-10176 and CVE-2017-8932.",
+ "Also tests values of the private key and public key that would trigger the OpenSSL modualr multiplication bug on the P-256 curve.",
"Various edge private key values are also tested.");
}
@@ -91,7 +92,7 @@ public class CardEdgeCasesSuite extends CardTestSuite {
int firstDiff = ByteUtil.diffBytes(dh.getSecret(), 0, value.getData(0), 0, dh.secretLength());
System.err.println(ByteUtil.bytesToHex(dh.getSecret()));
System.err.println(ByteUtil.bytesToHex(value.getData(0)));
- return new Result(Result.Value.FAILURE, "ECDH derived secret does not match the test-vector, first difference was at byte " + String.valueOf(firstDiff) + ".");
+ return new Result(Result.Value.FAILURE, "ECDH derived secret does not match the test-vector, first difference was at byte " + firstDiff + ".");
}
return new Result(Result.Value.SUCCESS);
}
@@ -104,6 +105,10 @@ public class CardEdgeCasesSuite extends CardTestSuite {
curveTests.add(one);
}
+ if (cfg.cleanup) {
+ curveTests.add(CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.ANY));
+ }
+
Test curveTest = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests", curveTests.toArray(new Test[0]));
groupTests.add(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Tests on " + curve.getId() + ".", prepareCurve, curveTest));
}
@@ -149,8 +154,22 @@ public class CardEdgeCasesSuite extends CardTestSuite {
continue;
}
Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS);
- Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS);
- Test setup = CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPair setup.", key, set, generate);
+ Test generate = genOrPreset(curve, Result.ExpectedValue.SUCCESS);
+ CommandTest export = CommandTest.expect(new Command.Export(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.KEY_PUBLIC, EC_Consts.PARAMETER_W), Result.ExpectedValue.SUCCESS);
+ Test setup = runTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPair setup.", key, set, generate, export));
+
+ byte[] pParam = curve.getParam(EC_Consts.PARAMETER_FP)[0];
+ BigInteger p = new BigInteger(1, pParam);
+ byte[] wParam = ((Response.Export) export.getResponse()).getParameter(ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.PARAMETER_W);
+ byte[] yValue = new byte[(wParam.length - 1) / 2];
+ System.arraycopy(wParam, (wParam.length / 2) + 1, yValue, 0, yValue.length);
+ BigInteger y = new BigInteger(1, yValue);
+ BigInteger negY = p.subtract(y);
+ byte[] newY = ECUtil.toByteArray(negY, curve.getBits());
+ System.arraycopy(newY, 0, wParam, (wParam.length / 2) + 1, newY.length);
+
+ EC_Params negYParams = makeParams(newY);
+ Test negYTest = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, negYParams.getParams(), negYParams.flatten()), "ECDH with pubkey negated.", Result.ExpectedValue.FAILURE, Result.ExpectedValue.FAILURE);
Test zeroS = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, EC_Consts.TRANSFORMATION_ZERO), "ECDH with S = 0.", Result.ExpectedValue.FAILURE, Result.ExpectedValue.FAILURE);
Test oneS = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, EC_Consts.TRANSFORMATION_ONE), "ECDH with S = 1.", Result.ExpectedValue.FAILURE, Result.ExpectedValue.FAILURE);
@@ -164,8 +183,21 @@ public class CardEdgeCasesSuite extends CardTestSuite {
BigInteger full = BigInteger.valueOf(1).shiftLeft(R.bitLength() - 1).subtract(BigInteger.ONE);
+ BigInteger alternate = full;
+ for (int i = 0; i < R.bitLength(); i += 2) {
+ alternate = alternate.clearBit(i);
+ }
+
+ BigInteger alternateOther = alternate.xor(full);
+
+ EC_Params alternateParams = makeParams(alternate);
+ Test alternateS = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, alternateParams.getParams(), alternateParams.flatten()), "ECDH with S = 101010101...01010.", Result.ExpectedValue.SUCCESS, Result.ExpectedValue.SUCCESS);
+
+ EC_Params alternateOtherParams = makeParams(alternateOther);
+ Test alternateOtherS = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, alternateOtherParams.getParams(), alternateOtherParams.flatten()), "ECDH with S = 010101010...10101.", Result.ExpectedValue.SUCCESS, Result.ExpectedValue.SUCCESS);
+
EC_Params fullParams = makeParams(full);
- Test fullS = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, fullParams.getParams(), fullParams.flatten()), "ECDH with S = 2^((log2 r) - 1) - 1.", Result.ExpectedValue.SUCCESS, Result.ExpectedValue.SUCCESS);
+ Test fullS = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, fullParams.getParams(), fullParams.flatten()), "ECDH with S = 111111111...11111 (but < r).", Result.ExpectedValue.SUCCESS, Result.ExpectedValue.SUCCESS);
EC_Params smallerParams = makeParams(smaller);
Test smallerS = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, smallerParams.getParams(), smallerParams.flatten()), "ECDH with S < r.", Result.ExpectedValue.SUCCESS, Result.ExpectedValue.SUCCESS);
@@ -191,20 +223,22 @@ public class CardEdgeCasesSuite extends CardTestSuite {
BigInteger krm1 = kr.subtract(BigInteger.ONE);
BigInteger krp1 = kr.add(BigInteger.ONE);
+ Result.ExpectedValue kExpected = K.equals(BigInteger.ONE) ? Result.ExpectedValue.SUCCESS : Result.ExpectedValue.FAILURE;
+
EC_Params krParams = makeParams(kr);
Test krS /*ONE!*/ = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, krParams.getParams(), krParams.flatten()), "ECDH with S = k * r.", Result.ExpectedValue.FAILURE, Result.ExpectedValue.FAILURE);
EC_Params krm1Params = makeParams(krm1);
- Test krm1S = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, krm1Params.getParams(), krm1Params.flatten()), "ECDH with S = (k * r) - 1.", Result.ExpectedValue.FAILURE, Result.ExpectedValue.FAILURE);
+ Test krm1S = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, krm1Params.getParams(), krm1Params.flatten()), "ECDH with S = (k * r) - 1.", kExpected, kExpected);
EC_Params krp1Params = makeParams(krp1);
- Test krp1S = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, krp1Params.getParams(), krp1Params.flatten()), "ECDH with S = (k * r) + 1.", Result.ExpectedValue.FAILURE, Result.ExpectedValue.FAILURE);
+ Test krp1S = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, krp1Params.getParams(), krp1Params.flatten()), "ECDH with S = (k * r) + 1.", Result.ExpectedValue.ANY, Result.ExpectedValue.ANY);
if (cfg.cleanup) {
Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.ANY);
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with edge-case private key values over " + curve.getId() + ".", setup, zeroS, oneS, fullS, smallerS, exactS, largerS, rm1S, rp1S, krS, krm1S, krp1S, cleanup));
+ doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with edge-case private key values over " + curve.getId() + ".", setup, negYTest, zeroS, oneS, alternateS, alternateOtherS, fullS, smallerS, exactS, largerS, rm1S, rp1S, krS, krm1S, krp1S, cleanup));
} else {
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with edge-case private key values over " + curve.getId() + ".", setup, zeroS, oneS, fullS, smallerS, exactS, largerS, rm1S, rp1S, krS, krm1S, krp1S));
+ doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with edge-case private key values over " + curve.getId() + ".", setup, negYTest, zeroS, oneS, alternateS, alternateOtherS, fullS, smallerS, exactS, largerS, rm1S, rp1S, krS, krm1S, krp1S));
}
}
@@ -249,7 +283,7 @@ public class CardEdgeCasesSuite extends CardTestSuite {
int i = 0;
for (BigInteger nearZero : zeros) {
EC_Params params = makeParams(nearZero);
- zeroTests[i++] = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, params.getParams(), params.flatten()), nearZero.toString(16), Result.ExpectedValue.ANY, Result.ExpectedValue.ANY);
+ zeroTests[i++] = ecdhTestBoth(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, params.getParams(), params.flatten()), nearZero.toString(16), Result.ExpectedValue.SUCCESS, Result.ExpectedValue.SUCCESS);
}
Test zeroTest = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Near zero.", zeroTests);
@@ -257,7 +291,7 @@ public class CardEdgeCasesSuite extends CardTestSuite {
i = 0;
for (BigInteger nearP : ps) {
EC_Params params = makeParams(nearP);
- pTests[i++] = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, params.getParams(), params.flatten()), nearP.toString(16) + (nearP.compareTo(p) > 0 ? " (>p)" : " (<=p)"), Result.ExpectedValue.ANY, Result.ExpectedValue.ANY);
+ pTests[i++] = ecdhTestBoth(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, params.getParams(), params.flatten()), nearP.toString(16) + (nearP.compareTo(p) > 0 ? " (>p)" : " (<=p)"), Result.ExpectedValue.SUCCESS, Result.ExpectedValue.SUCCESS);
}
Test pTest = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Near p.", pTests);
@@ -265,12 +299,23 @@ public class CardEdgeCasesSuite extends CardTestSuite {
i = 0;
for (BigInteger nearR : rs) {
EC_Params params = makeParams(nearR);
- rTests[i++] = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, params.getParams(), params.flatten()), nearR.toString(16) + (nearR.compareTo(r) > 0 ? " (>r)" : " (<=r)"), Result.ExpectedValue.ANY, Result.ExpectedValue.ANY);
+ if (nearR.compareTo(r) >= 0) {
+ rTests[i++] = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, params.getParams(), params.flatten()), nearR.toString(16) + " (>=r)", Result.ExpectedValue.FAILURE, Result.ExpectedValue.FAILURE);
+ } else {
+ rTests[i++] = ecdhTestBoth(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, params.getParams(), params.flatten()), nearR.toString(16) + " (<r)", Result.ExpectedValue.SUCCESS, Result.ExpectedValue.SUCCESS);
+ }
}
Test rTest = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Near r.", rTests);
doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Test private key values near zero, near p and near/larger than the order.", setup, zeroTest, pTest, rTest));
}
+ private Test ecdhTestBoth(Command setPriv, String desc, Result.ExpectedValue setExpect, Result.ExpectedValue ecdhExpect) {
+ Test set = CommandTest.expect(setPriv, setExpect);
+ Test ecdh = CommandTest.expect(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), ecdhExpect);
+
+ return CompoundTest.all(Result.ExpectedValue.SUCCESS, desc, set, ecdh);
+ }
+
private Test ecdhTest(Command setPriv, String desc, Result.ExpectedValue setExpect, Result.ExpectedValue ecdhExpect) {
Test set = CommandTest.expect(setPriv, setExpect);
Test ecdh = CommandTest.expect(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), ecdhExpect);
diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidSuite.java
index 3b9e0e5..9c4b54c 100644
--- a/src/cz/crcs/ectester/reader/test/CardInvalidSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardInvalidSuite.java
@@ -40,11 +40,15 @@ public class CardInvalidSuite extends CardTestSuite {
EC_Curve curve = e.getKey();
List<EC_Key.Public> keys = e.getValue();
- Test allocate = CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS);
+ 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(Result.ExpectedValue.SUCCESS, "No support for " + curve.getId() + ".", allocate));
+ continue;
+ }
Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS);
Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS);
- Test prepare = CompoundTest.all(ExpectedValue.SUCCESS, "Prepare and generate keypair on " + curve.getId(), allocate, set, generate);
+ Test prepare = CompoundTest.all(ExpectedValue.SUCCESS, "Prepare and generate keypair on " + curve.getId() + ".", allocate, set, generate);
List<Test> ecdhTests = new LinkedList<>();
for (EC_Key.Public pub : keys) {
@@ -55,13 +59,13 @@ public class CardInvalidSuite extends CardTestSuite {
Test rawEcdh = CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve.", "Card incorrectly accepted point on invalid curve.");
ecdhTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " invalid key test.", objectEcdh, rawEcdh));
}
- Test ecdh = CompoundTest.all(ExpectedValue.SUCCESS, "Perform ECDH with invalid public points", ecdhTests.toArray(new Test[0]));
+ Test ecdh = CompoundTest.all(ExpectedValue.SUCCESS, "Perform ECDH with invalid public points.", ecdhTests.toArray(new Test[0]));
if (cfg.cleanup) {
Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), ExpectedValue.ANY);
- doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), prepare, ecdh, cleanup));
+ doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId() + ".", prepare, ecdh, cleanup));
} else {
- doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), prepare, ecdh));
+ doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId() + ".", prepare, ecdh));
}
}
}
diff --git a/src/cz/crcs/ectester/reader/test/CardMiscSuite.java b/src/cz/crcs/ectester/reader/test/CardMiscSuite.java
index a2ce2ce..b1163c3 100644
--- a/src/cz/crcs/ectester/reader/test/CardMiscSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardMiscSuite.java
@@ -56,7 +56,7 @@ public class CardMiscSuite extends CardTestSuite {
}
Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS);
- Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), Result.ExpectedValue.ANY);
+ Test generate = genOrPreset(curve, Result.ExpectedValue.ANY);
Test ka = CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), expected);
Test sig = CommandTest.expect(new Command.ECDSA(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.Signature_ALG_ECDSA_SHA, ECTesterApplet.EXPORT_FALSE, null), expected);
Test perform = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH and ECDSA.", ka, sig);
diff --git a/src/cz/crcs/ectester/reader/test/CardSignatureSuite.java b/src/cz/crcs/ectester/reader/test/CardSignatureSuite.java
index 20546c8..0fa58d3 100644
--- a/src/cz/crcs/ectester/reader/test/CardSignatureSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardSignatureSuite.java
@@ -22,7 +22,7 @@ import java.util.Map;
*/
public class CardSignatureSuite extends CardTestSuite {
public CardSignatureSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) {
- super(writer, cfg, cardManager, "signature", "Test verifying various wrong ECDSA values.");
+ super(writer, cfg, cardManager, "signature", "The signature test suite tests verifying various malformed and well-formed but invalid ECDSA signatures.");
}
@Override
diff --git a/src/cz/crcs/ectester/reader/test/CardTestSuite.java b/src/cz/crcs/ectester/reader/test/CardTestSuite.java
index 3578f9c..73acbe7 100644
--- a/src/cz/crcs/ectester/reader/test/CardTestSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardTestSuite.java
@@ -1,9 +1,17 @@
package cz.crcs.ectester.reader.test;
+import cz.crcs.ectester.applet.ECTesterApplet;
+import cz.crcs.ectester.applet.EC_Consts;
+import cz.crcs.ectester.common.ec.EC_Curve;
+import cz.crcs.ectester.common.ec.EC_Params;
import cz.crcs.ectester.common.output.TestWriter;
+import cz.crcs.ectester.common.test.Result;
+import cz.crcs.ectester.common.test.Test;
import cz.crcs.ectester.common.test.TestSuite;
+import cz.crcs.ectester.common.util.ECUtil;
import cz.crcs.ectester.reader.CardMngr;
import cz.crcs.ectester.reader.ECTesterReader;
+import cz.crcs.ectester.reader.command.Command;
/**
* @author Jan Jancar johny@neuromancer.sk
@@ -21,4 +29,18 @@ public abstract class CardTestSuite extends TestSuite {
public CardMngr getCard() {
return card;
}
+
+ public ECTesterReader.Config getCfg() {
+ return cfg;
+ }
+
+ public Test genOrPreset(EC_Curve curve, Result.ExpectedValue expected) {
+ if (cfg.testOptions.contains("preset")) {
+ byte[] presetPriv = ECUtil.semiRandomKey(curve);
+ EC_Params privParms = new EC_Params(EC_Consts.PARAMETER_S, new byte[][]{presetPriv});
+ return CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, privParms.getParams(), privParms.flatten()), expected);
+ } else {
+ return CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), expected);
+ }
+ }
}
diff --git a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java
index 3abcebb..b6dc904 100644
--- a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java
@@ -30,6 +30,7 @@ import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.function.BiFunction;
import java.util.stream.Collectors;
import static cz.crcs.ectester.common.test.Result.ExpectedValue;
@@ -84,7 +85,7 @@ public class CardTestVectorSuite extends CardTestSuite {
return new Result(Value.FAILURE, "ECDH response did not contain the derived secret.");
if (!ByteUtil.compareBytes(dh.getSecret(), 0, result.getData(0), 0, dh.secretLength())) {
int firstDiff = ByteUtil.diffBytes(dh.getSecret(), 0, result.getData(0), 0, dh.secretLength());
- return new Result(Value.FAILURE, "ECDH derived secret does not match the test-vector, first difference was at byte " + String.valueOf(firstDiff) + ".");
+ return new Result(Value.FAILURE, "ECDH derived secret does not match the test-vector, first difference was at byte " + firstDiff + ".");
}
return new Result(Value.SUCCESS);
}
@@ -96,10 +97,12 @@ public class CardTestVectorSuite extends CardTestSuite {
}
KeyAgreement ka;
+ Signature sig;
KeyFactory kf;
MessageDigest md;
try {
ka = KeyAgreement.getInstance("ECDH", "BC");
+ sig = Signature.getInstance("ECDSAwithSHA1", "BC");
kf = KeyFactory.getInstance("ECDH", "BC");
md = MessageDigest.getInstance("SHA1", "BC");
} catch (NoSuchAlgorithmException | NoSuchProviderException ex) {
@@ -119,8 +122,26 @@ public class CardTestVectorSuite extends CardTestSuite {
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);
+ CommandTest exportLocal = CommandTest.expect(new Command.Export(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.KEY_PUBLIC, EC_Consts.PARAMETER_W), ExpectedValue.ANY);
+ CommandTest exportRemote = CommandTest.expect(new Command.Export(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.KEY_PRIVATE, EC_Consts.PARAMETER_S), ExpectedValue.ANY);
+ testVector.add(exportLocal);
+ testVector.add(exportRemote);
+ BiFunction<Response.Export, Response.Export, Key[]> getKeys = (localData, remoteData) -> {
+ byte[] pkey = localData.getParameter(ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.PARAMETER_W);
+ byte[] skey = remoteData.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);
+ } catch (InvalidKeySpecException ex) {
+ return null;
+ }
+ return new Key[]{privKey, pubKey};
+ };
TestCallback<CommandTestable> kaCallback = new TestCallback<CommandTestable>() {
@Override
public Result apply(CommandTestable testable) {
@@ -131,19 +152,17 @@ public class CardTestVectorSuite extends CardTestSuite {
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;
+ Response.Export localData = (Response.Export) exportLocal.getResponse();
+ Response.Export remoteData = (Response.Export) exportRemote.getResponse();
+ Key[] keys = getKeys.apply(localData, remoteData);
+ if (keys == null) {
+ return new Result(Value.SUCCESS, "Result could not be verified. keyData unavailable.");
+ }
+ PrivateKey privKey = (PrivateKey) keys[0];
+ PublicKey pubKey = (PublicKey) keys[1];
try {
- privKey = kf.generatePrivate(privKeySpec);
- pubkey = kf.generatePublic(pubKeySpec);
ka.init(privKey);
- ka.doPhase(pubkey, true);
+ ka.doPhase(pubKey, true);
byte[] rawDerived = ka.generateSecret();
int fieldSize = (curve.getBits() + 7) / 8;
if (rawDerived.length < fieldSize) {
@@ -163,14 +182,47 @@ public class CardTestVectorSuite extends CardTestSuite {
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) + ".");
+ return new Result(Value.FAILURE, "Derived secret does not match expected value, first difference was at byte " + diff + ".");
+ }
+ } catch (InvalidKeyException ex) {
+ return new Result(Value.SUCCESS, "Result could not be verified. " + ex.getMessage());
+ }
+ }
+ };
+ Test ecdhTest = 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);
+ byte[] data = new byte[32];
+ TestCallback<CommandTestable> sigCallback = new TestCallback<CommandTestable>() {
+ @Override
+ public Result apply(CommandTestable testable) {
+ Response.ECDSA ecdsaData = (Response.ECDSA) testable.getResponse();
+ if (!ecdsaData.successful())
+ return new Result(Value.FAILURE, "ECDSA was unsuccessful.");
+ if (!ecdsaData.hasSignature()) {
+ return new Result(Value.FAILURE, "ECDSA response did not contain the signature.");
+ }
+ byte[] signature = ecdsaData.getSignature();
+ Response.Export localData = (Response.Export) exportLocal.getResponse();
+ Response.Export remoteData = (Response.Export) exportRemote.getResponse();
+ Key[] keys = getKeys.apply(localData, remoteData);
+ if (keys == null) {
+ return new Result(Value.SUCCESS, "Result could not be verified. keyData unavailable.");
+ }
+ PublicKey pubKey = (PublicKey) keys[1];
+ try {
+ sig.initVerify(pubKey);
+ sig.update(data);
+ if (sig.verify(signature)) {
+ return new Result(Value.SUCCESS, "Signature verified.");
+ } else {
+ return new Result(Value.FAILURE, "Signature failed to verify.");
}
- } catch (InvalidKeySpecException | InvalidKeyException ex) {
+ } catch (InvalidKeyException | SignatureException 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));
+ Test ecdsaTest = CommandTest.function(new Command.ECDSA_sign(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.Signature_ALG_ECDSA_SHA, ECTesterApplet.EXPORT_TRUE, data), sigCallback);
+ testVector.add(CompoundTest.all(ExpectedValue.SUCCESS, "", ecdhTest, ecdsaTest));
if (cfg.cleanup) {
testVector.add(CommandTest.expect(new Command.Cleanup(this.card), ExpectedValue.ANY));
}
diff --git a/src/cz/crcs/ectester/reader/test/CardTwistSuite.java b/src/cz/crcs/ectester/reader/test/CardTwistSuite.java
index 3df4c65..4929d52 100644
--- a/src/cz/crcs/ectester/reader/test/CardTwistSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardTwistSuite.java
@@ -34,29 +34,33 @@ public class CardTwistSuite extends CardTestSuite {
EC_Curve curve = e.getKey();
List<EC_Key.Public> keys = e.getValue();
- Test allocate = CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS);
+ Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS));
+ if (!allocate.ok()) {
+ doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for " + curve.getId() + ".", allocate));
+ continue;
+ }
Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS);
Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS);
- Test prepare = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Prepare and generate keypair on " + curve.getId(), allocate, set, generate);
+ Test prepare = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Prepare and generate keypair on " + curve.getId() + ".", allocate, set, generate);
List<Test> ecdhTests = new LinkedList<>();
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 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, "Card correctly rejected point on twist.", "Card incorrectly accepted point on twist.");
Test objectEcdh = CompoundTest.any(Result.ExpectedValue.SUCCESS, CardUtil.getKATypeString(EC_Consts.KeyAgreement_ALG_EC_SVDP_DH) + " test with twist 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, Result.ExpectedValue.FAILURE, "Card correctly rejected point on twist.", "Card incorrectly accepted point on twist.");
ecdhTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " twist key test.", objectEcdh, rawEcdh));
}
- Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with public points on twist", ecdhTests.toArray(new Test[0]));
+ Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with public points on twist.", ecdhTests.toArray(new Test[0]));
Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", ecdh);
if (cfg.cleanup) {
Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.ANY);
- doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId(), prepare, tests, cleanup));
+ doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId() + ".", prepare, tests, cleanup));
} else {
- doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId(), prepare, tests));
+ doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId() + ".", prepare, tests));
}
}
}
diff --git a/src/cz/crcs/ectester/reader/test/CommandTest.java b/src/cz/crcs/ectester/reader/test/CommandTest.java
index adad191..b05d3e4 100644
--- a/src/cz/crcs/ectester/reader/test/CommandTest.java
+++ b/src/cz/crcs/ectester/reader/test/CommandTest.java
@@ -32,7 +32,7 @@ public class CommandTest extends SimpleTest<CommandTestable> {
@Override
public Result apply(CommandTestable commandTestable) {
Result.Value resultValue = Result.Value.fromExpected(expected, commandTestable.ok(), commandTestable.error());
- return new Result(resultValue, resultValue.ok() ? ok : nok);
+ return new Result(resultValue, commandTestable.error() ? commandTestable.errorCause() : (resultValue.ok() ? ok : nok));
}
});
}
diff --git a/src/cz/crcs/ectester/reader/test/PerformanceTest.java b/src/cz/crcs/ectester/reader/test/PerformanceTest.java
index f9a4472..f9cba46 100644
--- a/src/cz/crcs/ectester/reader/test/PerformanceTest.java
+++ b/src/cz/crcs/ectester/reader/test/PerformanceTest.java
@@ -1,18 +1,24 @@
package cz.crcs.ectester.reader.test;
+import cz.crcs.ectester.applet.ECTesterApplet;
import cz.crcs.ectester.common.test.Result;
import cz.crcs.ectester.common.test.SimpleTest;
import cz.crcs.ectester.common.test.TestCallback;
+import cz.crcs.ectester.common.test.TestException;
+import cz.crcs.ectester.reader.CardMngr;
import cz.crcs.ectester.reader.command.Command;
import cz.crcs.ectester.reader.response.Response;
+import javax.smartcardio.CardException;
import java.util.Arrays;
/**
* @author Jan Jancar johny@neuromancer.sk
*/
public class PerformanceTest extends SimpleTest<CommandTestable> {
+ private CardMngr cardManager;
private long[] times;
+ private long[] reducedTimes;
private Response[] responses;
private long mean;
private long median;
@@ -20,23 +26,24 @@ public class PerformanceTest extends SimpleTest<CommandTestable> {
private int count;
private String desc;
- private PerformanceTest(CommandTestable testable, int count, String desc) {
+ private PerformanceTest(CardMngr cardManager, CommandTestable testable, int count, String desc) {
super(testable, new TestCallback<CommandTestable>() {
@Override
public Result apply(CommandTestable testable) {
return new Result(Result.Value.SUCCESS);
}
});
+ this.cardManager = cardManager;
this.count = count;
this.desc = desc;
}
- public static PerformanceTest repeat(Command cmd, int count) {
- return new PerformanceTest(new CommandTestable(cmd), count, null);
+ public static PerformanceTest repeat(CardMngr cardManager, Command cmd, int count) {
+ return new PerformanceTest(cardManager, new CommandTestable(cmd), count, null);
}
- public static PerformanceTest repeat(String desc, Command cmd, int count) {
- return new PerformanceTest(new CommandTestable(cmd), count, desc);
+ public static PerformanceTest repeat(CardMngr cardManager, String desc, Command cmd, int count) {
+ return new PerformanceTest(cardManager, new CommandTestable(cmd), count, desc);
}
@Override
@@ -47,18 +54,35 @@ public class PerformanceTest extends SimpleTest<CommandTestable> {
@Override
protected void runSelf() {
+ long baseTime;
+ try {
+ new Command.SetDryRunMode(cardManager, ECTesterApplet.MODE_DRY_RUN).send();
+ testable.run();
+ baseTime = testable.getResponse().getDuration();
+ testable.reset();
+ testable.run();
+ baseTime += testable.getResponse().getDuration();
+ testable.reset();
+ baseTime /= 2;
+ new Command.SetDryRunMode(cardManager, ECTesterApplet.MODE_NORMAL).send();
+ } catch (CardException ce) {
+ throw new TestException(ce);
+ }
+
times = new long[count];
+ reducedTimes = new long[count];
responses = new Response[count];
for (int i = 0; i < count; ++i) {
testable.run();
responses[i] = testable.getResponse();
times[i] = responses[i].getDuration();
+ reducedTimes[i] = times[i] - baseTime;
testable.reset();
}
- mean = Arrays.stream(times).sum() / count;
+ mean = Arrays.stream(reducedTimes).sum() / count;
- long[] sorted = times.clone();
+ long[] sorted = reducedTimes.clone();
Arrays.sort(sorted);
if (count % 2 == 0) {
median = (sorted[(count / 2) - 1] + sorted[count / 2]) / 2;
@@ -99,6 +123,10 @@ public class PerformanceTest extends SimpleTest<CommandTestable> {
return times;
}
+ public long[] getReducedTimes() {
+ return reducedTimes;
+ }
+
public long getMean() {
return mean;
}