From 370f65c33992f71b7d21296f0fe44fa1380d4541 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sun, 4 Feb 2018 19:20:08 +0100 Subject: Update README, docs and test suites. --- .../ectester/reader/test/CardCompositeCurvesSuite.java | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java') diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java index a53806c..5bedce5 100644 --- a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java @@ -9,7 +9,6 @@ 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 javacard.security.KeyPair; import java.util.Map; @@ -35,17 +34,12 @@ public class CardCompositeCurvesSuite extends CardTestSuite { Map keys = EC_Store.getInstance().getObjects(EC_Key.class, "composite"); for (EC_Key key : keys.values()) { EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, key.getCurve()); - if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { - continue; - } - if ((curve.getBits() == cfg.bits || cfg.all)) { - doTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - doTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); - doTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY)); - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); - doTest(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.")); - new Command.Cleanup(this.card).send(); - } + doTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + doTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); + doTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY)); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); + doTest(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.")); + new Command.Cleanup(this.card).send(); } } } -- cgit v1.2.3-70-g09d2 From 603cc4692252d66a894e514ee474cb7acbcfd6a0 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 10 Feb 2018 20:23:12 +0100 Subject: Restructure the Composite test suite. --- .../ectester/reader/test/CardCompositeCurvesSuite.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java') diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java index 5bedce5..e866c25 100644 --- a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java @@ -5,6 +5,8 @@ import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.common.ec.EC_Curve; import cz.crcs.ectester.common.ec.EC_Key; import cz.crcs.ectester.common.output.TestWriter; +import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.Test; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; @@ -20,7 +22,7 @@ import static cz.crcs.ectester.common.test.Result.ExpectedValue; public class CardCompositeCurvesSuite extends CardTestSuite { public CardCompositeCurvesSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { - super(writer, cfg, cardManager, "composite", "The composite suite run 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. This should generally fail, as using such a curve is unsafe."); } @Override @@ -34,11 +36,13 @@ public class CardCompositeCurvesSuite extends CardTestSuite { Map keys = EC_Store.getInstance().getObjects(EC_Key.class, "composite"); for (EC_Key key : keys.values()) { EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, key.getCurve()); - doTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - doTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); - doTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY)); + 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.ANY); + Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY); Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); - doTest(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.")); + 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."); + + doTest(CompoundTest.greedyAll(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", " + key.getDesc(), allocate, set, generate, ecdh)); new Command.Cleanup(this.card).send(); } } -- cgit v1.2.3-70-g09d2 From db1f7faf4608d5552293e2ea7e49a6b2a069f7ea Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 6 Mar 2018 21:47:46 +0100 Subject: Better evaluate results of compound test in some test suites. --- src/cz/crcs/ectester/common/test/CompoundTest.java | 37 ++++++++++++++++++++++ .../reader/test/CardCofactorTestSuite.java | 2 +- .../reader/test/CardCompositeCurvesSuite.java | 2 +- .../reader/test/CardInvalidCurvesSuite.java | 2 +- .../ectester/reader/test/CardTwistTestSuite.java | 2 +- 5 files changed, 41 insertions(+), 4 deletions(-) (limited to 'src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java') diff --git a/src/cz/crcs/ectester/common/test/CompoundTest.java b/src/cz/crcs/ectester/common/test/CompoundTest.java index 4b1df16..d7a2d9c 100644 --- a/src/cz/crcs/ectester/common/test/CompoundTest.java +++ b/src/cz/crcs/ectester/common/test/CompoundTest.java @@ -82,6 +82,43 @@ public class CompoundTest extends Test { return result; } + public static CompoundTest greedyAllTry(Result.ExpectedValue what, Test... all) { + return new CompoundTest((tests) -> { + int run = 0; + int ok = 0; + for (Test test : tests) { + if (test.hasRun()) { + run++; + if (Result.Value.fromExpected(what, test.ok()).ok()) { + ok++; + } + } + } + if (run == tests.length) { + if (ok == run) { + return new Result(Result.Value.SUCCESS, "All sub-tests had the expected result."); + } else { + return new Result(Result.Value.FAILURE, "Some sub-tests did not have the expected result."); + } + } else { + return new Result(Result.Value.SUCCESS, "All considered sub-tests had the expected result."); + } + }, (tests) -> { + for (Test t : tests) { + t.run(); + if (!t.ok()) { + break; + } + } + }, all); + } + + public static CompoundTest greedyAllTry(Result.ExpectedValue what, String description, Test... all) { + CompoundTest result = CompoundTest.greedyAllTry(what, all); + result.setDescription(description); + return result; + } + public static CompoundTest greedyAny(Result.ExpectedValue what, Test... any) { return new CompoundTest((tests) -> { for (Test test : tests) { diff --git a/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java b/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java index c17a7d9..fd3f0ae 100644 --- a/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java @@ -53,7 +53,7 @@ public class CardCofactorTestSuite extends CardTestSuite { } Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with public points on non-generator subgroup", ecdhTests.toArray(new Test[0])); - doTest(CompoundTest.greedyAll(Result.ExpectedValue.SUCCESS, "Cofactor test of " + curve.getId(), prepare, ecdh)); + doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Cofactor test of " + curve.getId(), prepare, ecdh)); new Command.Cleanup(this.card).send(); } } diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java index e866c25..b931aad 100644 --- a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java @@ -42,7 +42,7 @@ public class CardCompositeCurvesSuite extends CardTestSuite { Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.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."); - doTest(CompoundTest.greedyAll(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", " + key.getDesc(), allocate, set, generate, ecdh)); + doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", " + key.getDesc(), allocate, set, generate, ecdh)); new Command.Cleanup(this.card).send(); } } diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java index 190a20c..0cf27ec 100644 --- a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java @@ -58,7 +58,7 @@ public class CardInvalidCurvesSuite extends CardTestSuite { } Test ecdh = CompoundTest.all(ExpectedValue.SUCCESS, "Perform ECDH with invalid public points", ecdhTests.toArray(new Test[0])); - doTest(CompoundTest.greedyAll(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), prepare, ecdh)); + doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), prepare, ecdh)); new Command.Cleanup(this.card).send(); } } diff --git a/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java b/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java index c301e1e..fad508f 100644 --- a/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java @@ -53,7 +53,7 @@ public class CardTwistTestSuite extends CardTestSuite { } Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with public points on twist", ecdhTests.toArray(new Test[0])); - doTest(CompoundTest.greedyAll(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId(), prepare, ecdh)); + doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId(), prepare, ecdh)); new Command.Cleanup(this.card).send(); } } -- cgit v1.2.3-70-g09d2 From ec84a28d3930140f908e18cd82562357abcf84a8 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 14 Mar 2018 21:23:45 +0100 Subject: Rename the CORRUPT command to TRANSFORM, as it does that now. --- src/cz/crcs/ectester/applet/ECKeyGenerator.java | 20 ++++---- src/cz/crcs/ectester/applet/ECKeyTester.java | 12 ++--- src/cz/crcs/ectester/applet/ECTesterApplet.java | 58 ++++++++++----------- src/cz/crcs/ectester/applet/EC_Consts.java | 54 +++++++++---------- src/cz/crcs/ectester/common/util/CardUtil.java | 24 ++++----- src/cz/crcs/ectester/reader/ECTesterReader.java | 2 +- src/cz/crcs/ectester/reader/command/Command.java | 60 +++++++++++----------- src/cz/crcs/ectester/reader/response/Response.java | 14 ++--- .../reader/test/CardCofactorTestSuite.java | 2 +- .../reader/test/CardCompositeCurvesSuite.java | 2 +- .../ectester/reader/test/CardDefaultSuite.java | 4 +- .../reader/test/CardInvalidCurvesSuite.java | 2 +- .../ectester/reader/test/CardTestVectorSuite.java | 3 +- .../ectester/reader/test/CardTwistTestSuite.java | 2 +- .../ectester/reader/test/CardWrongCurvesSuite.java | 10 ++-- 15 files changed, 134 insertions(+), 135 deletions(-) (limited to 'src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java') diff --git a/src/cz/crcs/ectester/applet/ECKeyGenerator.java b/src/cz/crcs/ectester/applet/ECKeyGenerator.java index 244bdba..9150248 100644 --- a/src/cz/crcs/ectester/applet/ECKeyGenerator.java +++ b/src/cz/crcs/ectester/applet/ECKeyGenerator.java @@ -139,38 +139,38 @@ public class ECKeyGenerator { /** * @param keypair - * @param corruptParams - * @param corruption + * @param params + * @param transformation * @param buffer * @param offset * @return */ - public short corruptCurve(KeyPair keypair, short corruptParams, short corruption, byte[] buffer, short offset) { - return corruptCurve(keypair, EC_Consts.KEY_BOTH, corruptParams, corruption, buffer, offset); + public short transformCurve(KeyPair keypair, short params, short transformation, byte[] buffer, short offset) { + return transformCurve(keypair, EC_Consts.KEY_BOTH, params, transformation, buffer, offset); } /** * @param keypair * @param key - * @param corruptParams - * @param corruption + * @param params + * @param transformation * @param buffer * @param offset * @return */ - public short corruptCurve(KeyPair keypair, byte key, short corruptParams, short corruption, byte[] buffer, short offset) { + public short transformCurve(KeyPair keypair, byte key, short params, short transformation, byte[] buffer, short offset) { sw = ISO7816.SW_NO_ERROR; - if (corruptParams == EC_Consts.PARAMETERS_NONE) { + if (params == EC_Consts.PARAMETERS_NONE) { return sw; } //go through param bit by bit, and invalidate all selected params short paramMask = EC_Consts.PARAMETER_FP; while (paramMask <= EC_Consts.PARAMETER_S) { - short masked = (short) (paramMask & corruptParams); + short masked = (short) (paramMask & params); if (masked != 0) { short length = exportParameter(keypair, key, masked, buffer, offset); - length = EC_Consts.corruptParameter(corruption, buffer, offset, length); + length = EC_Consts.transformParameter(transformation, buffer, offset, length); sw = setParameter(keypair, key, masked, buffer, offset, length); if (sw != ISO7816.SW_NO_ERROR) break; } diff --git a/src/cz/crcs/ectester/applet/ECKeyTester.java b/src/cz/crcs/ectester/applet/ECKeyTester.java index 36515ef..27bb9e1 100644 --- a/src/cz/crcs/ectester/applet/ECKeyTester.java +++ b/src/cz/crcs/ectester/applet/ECKeyTester.java @@ -52,10 +52,10 @@ public class ECKeyTester { * @param pubkeyOffset offset into pubkeyBuffer that can be used for the public key * @param outputBuffer buffer to be used for the secret output * @param outputOffset offset into the outputBuffer - * @param corruption (EC_Consts.CORRUPTION_* | ...) + * @param transformation (EC_Consts.TRANSFORMATION_* | ...) * @return derived secret length **/ - public short testKA(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, short corruption) { + public short testKA(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, short transformation) { short length = 0; try { sw = AppletUtil.kaCheck(ecKeyAgreement); @@ -64,7 +64,7 @@ public class ECKeyTester { short pubkeyLength = ((ECPublicKey) publicPair.getPublic()).getW(pubkeyBuffer, pubkeyOffset); ecKeyAgreement.init(privatePair.getPrivate()); - pubkeyLength = EC_Consts.corruptParameter(corruption, pubkeyBuffer, pubkeyOffset, pubkeyLength); + pubkeyLength = EC_Consts.transformParameter(transformation, pubkeyBuffer, pubkeyOffset, pubkeyLength); length = ecKeyAgreement.generateSecret(pubkeyBuffer, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset); } catch (CardRuntimeException ce) { sw = ce.getReason(); @@ -79,17 +79,17 @@ public class ECKeyTester { * @param pubkeyLength * @param outpuBuffer * @param outputOffset - * @param corruption + * @param transformation * @return */ - public short testKA_direct(KeyPair privatePair, byte[] pubkey, short pubkeyOffset, short pubkeyLength, byte[] outpuBuffer, short outputOffset, short corruption) { + public short testKA_direct(KeyPair privatePair, byte[] pubkey, short pubkeyOffset, short pubkeyLength, byte[] outpuBuffer, short outputOffset, short transformation) { short length = 0; try { sw = AppletUtil.kaCheck(ecKeyAgreement); sw = AppletUtil.keypairCheck(privatePair); ecKeyAgreement.init(privatePair.getPrivate()); - pubkeyLength = EC_Consts.corruptParameter(corruption, pubkey, pubkeyOffset, pubkeyLength); + pubkeyLength = EC_Consts.transformParameter(transformation, pubkey, pubkeyOffset, pubkeyLength); length = ecKeyAgreement.generateSecret(pubkey, pubkeyOffset, pubkeyLength, outpuBuffer, outputOffset); } catch (CardRuntimeException ce) { sw = ce.getReason(); diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index e34e52c..18c4d1f 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -45,7 +45,7 @@ public class ECTesterApplet extends Applet implements ExtendedLength { public static final byte INS_ALLOCATE = (byte) 0x5a; public static final byte INS_CLEAR = (byte) 0x5b; public static final byte INS_SET = (byte) 0x5c; - public static final byte INS_CORRUPT = (byte) 0x5d; + public static final byte INS_TRANSFORM = (byte) 0x5d; public static final byte INS_GENERATE = (byte) 0x5e; public static final byte INS_EXPORT = (byte) 0x5f; public static final byte INS_ECDH = (byte) 0x70; @@ -185,8 +185,8 @@ public class ECTesterApplet extends Applet implements ExtendedLength { case INS_SET: length = insSet(apdu); break; - case INS_CORRUPT: - length = insCorrupt(apdu); + case INS_TRANSFORM: + length = insTransform(apdu); break; case INS_GENERATE: length = insGenerate(apdu); @@ -344,29 +344,29 @@ public class ECTesterApplet extends Applet implements ExtendedLength { } /** - * Corrupts curve paramaters of local and remote keyPairs. - * returns corruptCurve SWs + * Transforms curve paramaters of local and remote keyPairs. + * returns transformCurve SWs * * @param apdu P1 = byte keyPair (KEYPAIR_* | ...) * P2 = byte key (EC_Consts.KEY_* | ...) * DATA = short params (EC_Consts.PARAMETER_* | ...) - * short corruption (EC_Consts.CORRUPTION_* || ...) + * short transformation (EC_Consts.TRANSFORMATION_* || ...) * @return length of response */ - private short insCorrupt(APDU apdu) { + private short insTransform(APDU apdu) { byte keyPair = apduArray[ISO7816.OFFSET_P1]; byte key = apduArray[ISO7816.OFFSET_P2]; short cdata = apdu.getOffsetCdata(); short params = Util.getShort(apduArray, cdata); - short corruption = Util.getShort(apduArray, (short) (cdata + 2)); + short transformation = Util.getShort(apduArray, (short) (cdata + 2)); short len = 0; if ((keyPair & KEYPAIR_LOCAL) != 0) { - len += corrupt(localKeypair, key, params, corruption, apdu.getBuffer(), (short) 0); + len += transform(localKeypair, key, params, transformation, apdu.getBuffer(), (short) 0); } if ((keyPair & KEYPAIR_REMOTE) != 0) { - len += corrupt(remoteKeypair, key, params, corruption, apdu.getBuffer(), len); + len += transform(remoteKeypair, key, params, transformation, apdu.getBuffer(), len); } return len; @@ -429,7 +429,7 @@ public class ECTesterApplet extends Applet implements ExtendedLength { * @param apdu P1 = byte pubkey (KEYPAIR_*) * P2 = byte privkey (KEYPAIR_*) * DATA = byte export (EXPORT_TRUE || EXPORT_FALSE) - * short corruption (EC_Consts.CORRUPTION_* | ...) + * short transformation (EC_Consts.TRANSFORMATION_* | ...) * byte type (EC_Consts.KA_* | ...) * @return length of response */ @@ -438,10 +438,10 @@ public class ECTesterApplet extends Applet implements ExtendedLength { byte privkey = apduArray[ISO7816.OFFSET_P2]; short cdata = apdu.getOffsetCdata(); byte export = apduArray[cdata]; - short corruption = Util.getShort(apduArray, (short) (cdata + 1)); + short transformation = Util.getShort(apduArray, (short) (cdata + 1)); byte type = apduArray[(short) (cdata + 3)]; - return ecdh(pubkey, privkey, export, corruption, type, apdu.getBuffer(), (short) 0); + return ecdh(pubkey, privkey, export, transformation, type, apdu.getBuffer(), (short) 0); } /** @@ -449,7 +449,7 @@ public class ECTesterApplet extends Applet implements ExtendedLength { * * @param apdu P1 = byte privkey (KEYPAIR_*) * P2 = byte export (EXPORT_TRUE || EXPORT_FALSE) - * DATA = short corruption (EC_Consts.CORRUPTION_* | ...) + * DATA = short transformation (EC_Consts.TRANSFORMATION_* | ...) * byte type (EC_Consts.KA_* | ...) * short length * byte[] pubkey @@ -459,11 +459,11 @@ public class ECTesterApplet extends Applet implements ExtendedLength { byte privkey = apduArray[ISO7816.OFFSET_P1]; byte export = apduArray[ISO7816.OFFSET_P2]; short cdata = apdu.getOffsetCdata(); - short corruption = Util.getShort(apduArray, cdata); + short transformation = Util.getShort(apduArray, cdata); byte type = apduArray[(short) (cdata + 2)]; short length = Util.getShort(apduArray, (short) (cdata + 3)); - return ecdh_direct(privkey, export, corruption, type, (short) (cdata + 5), length, apdu.getBuffer(), (short) 0); + return ecdh_direct(privkey, export, transformation, type, (short) (cdata + 5), length, apdu.getBuffer(), (short) 0); } /** @@ -576,16 +576,16 @@ public class ECTesterApplet extends Applet implements ExtendedLength { } /** - * @param keyPair KeyPair to corrupt - * @param key key to corrupt (EC_Consts.KEY_* | ...) - * @param params parameters to corrupt (EC_Consts.PARAMETER_* | ...) - * @param corruption corruption type (EC_Consts.CORRUPTION_*) + * @param keyPair KeyPair to transform + * @param key key to transform (EC_Consts.KEY_* | ...) + * @param params parameters to transform (EC_Consts.PARAMETER_* | ...) + * @param transformation transformation type (EC_Consts.TRANSFORMATION_*) * @param outBuffer buffer to output sw to * @param outOffset output offset in buffer * @return length of data written to the buffer */ - private short corrupt(KeyPair keyPair, byte key, short params, short corruption, byte[] outBuffer, short outOffset) { - short sw = keyGenerator.corruptCurve(keyPair, key, params, corruption, ramArray, (short) 0); + private short transform(KeyPair keyPair, byte key, short params, short transformation, byte[] outBuffer, short outOffset) { + short sw = keyGenerator.transformCurve(keyPair, key, params, transformation, ramArray, (short) 0); Util.setShort(outBuffer, outOffset, sw); return 2; } @@ -635,13 +635,13 @@ public class ECTesterApplet extends Applet implements ExtendedLength { * @param pubkey keyPair to use for public key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) * @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) * @param export whether to export ECDH secret - * @param corruption whether to invalidate the pubkey before ECDH + * @param transformation whether to transform the pubkey before ECDH * @param type KeyAgreement type to test * @param outBuffer buffer to write sw to, and export ECDH secret {@code if(export == EXPORT_TRUE)} * @param outOffset output offset in buffer * @return length of data written to the buffer */ - private short ecdh(byte pubkey, byte privkey, byte export, short corruption, byte type, byte[] outBuffer, short outOffset) { + private short ecdh(byte pubkey, byte privkey, byte export, short transformation, byte type, byte[] outBuffer, short outOffset) { short length = 0; KeyPair pub = ((pubkey & KEYPAIR_LOCAL) != 0) ? localKeypair : remoteKeypair; @@ -649,11 +649,11 @@ public class ECTesterApplet extends Applet implements ExtendedLength { short secretLength = 0; if (keyTester.getKaType() == type) { - secretLength = keyTester.testKA(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption); + secretLength = keyTester.testKA(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, transformation); } else { short allocateSW = keyTester.allocateKA(type); if (allocateSW == ISO7816.SW_NO_ERROR) { - secretLength = keyTester.testKA(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption); + secretLength = keyTester.testKA(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, transformation); } } Util.setShort(outBuffer, outOffset, keyTester.getSW()); @@ -669,18 +669,18 @@ public class ECTesterApplet extends Applet implements ExtendedLength { return length; } - private short ecdh_direct(byte privkey, byte export, short corruption, byte type, short keyOffset, short keyLength, byte[] outBuffer, short outOffset) { + private short ecdh_direct(byte privkey, byte export, short transformation, byte type, short keyOffset, short keyLength, byte[] outBuffer, short outOffset) { short length = 0; KeyPair priv = ((privkey & KEYPAIR_LOCAL) != 0) ? localKeypair : remoteKeypair; short secretLength = 0; if (keyTester.getKaType() == type) { - secretLength = keyTester.testKA_direct(priv, apduArray, keyOffset, keyLength, ramArray2, (short) 0, corruption); + secretLength = keyTester.testKA_direct(priv, apduArray, keyOffset, keyLength, ramArray2, (short) 0, transformation); } else { short allocateSW = keyTester.allocateKA(type); if (allocateSW == ISO7816.SW_NO_ERROR) { - secretLength = keyTester.testKA_direct(priv, apduArray, keyOffset, keyLength, ramArray2, (short) 0, corruption); + secretLength = keyTester.testKA_direct(priv, apduArray, keyOffset, keyLength, ramArray2, (short) 0, transformation); } } diff --git a/src/cz/crcs/ectester/applet/EC_Consts.java b/src/cz/crcs/ectester/applet/EC_Consts.java index 008269a..5b3c74c 100644 --- a/src/cz/crcs/ectester/applet/EC_Consts.java +++ b/src/cz/crcs/ectester/applet/EC_Consts.java @@ -981,17 +981,17 @@ public class EC_Consts { public static final short EC571_F2M_K = 2; - // getCorruptCurveParameter PARAMETER_CORRUPTION TYPES - public static final short CORRUPTION_NONE = (short) 0x00; - public static final short CORRUPTION_FIXED = (short) 0x01; - public static final short CORRUPTION_FULLRANDOM = (short) 0x02; - public static final short CORRUPTION_ONEBYTERANDOM = (short) 0x04; - public static final short CORRUPTION_ZERO = (short) 0x08; - public static final short CORRUPTION_ONE = (short) 0x10; - public static final short CORRUPTION_MAX = (short) 0x20; - public static final short CORRUPTION_INCREMENT = (short) 0x40; - public static final short CORRUPTION_INFINITY = (short) 0x80; - public static final short CORRUPTION_COMPRESS = (short) 0x0100; + // transformParameter TRANSFORMATION types + public static final short TRANSFORMATION_NONE = (short) 0x00; + public static final short TRANSFORMATION_FIXED = (short) 0x01; + public static final short TRANSFORMATION_FULLRANDOM = (short) 0x02; + public static final short TRANSFORMATION_ONEBYTERANDOM = (short) 0x04; + public static final short TRANSFORMATION_ZERO = (short) 0x08; + public static final short TRANSFORMATION_ONE = (short) 0x10; + public static final short TRANSFORMATION_MAX = (short) 0x20; + public static final short TRANSFORMATION_INCREMENT = (short) 0x40; + public static final short TRANSFORMATION_INFINITY = (short) 0x80; + public static final short TRANSFORMATION_COMPRESS = (short) 0x0100; // toX962 FORM types public static final byte X962_UNCOMPRESSED = (byte) 0x00; @@ -1307,27 +1307,27 @@ public class EC_Consts { return length; } - public static short corruptParameter(short corruption, byte[] buffer, short offset, short length) { - if (corruption == CORRUPTION_NONE) { + public static short transformParameter(short transformation, byte[] buffer, short offset, short length) { + if (transformation == TRANSFORMATION_NONE) { return length; } - short corruptionMask = CORRUPTION_FIXED; - while (corruptionMask <= CORRUPTION_COMPRESS) { - short corruptionPart = (short) (corruptionMask & corruption); - switch (corruptionPart) { + short transformationMask = TRANSFORMATION_FIXED; + while (transformationMask <= TRANSFORMATION_COMPRESS) { + short transformationPart = (short) (transformationMask & transformation); + switch (transformationPart) { case (short) 0: break; - case CORRUPTION_FIXED: + case TRANSFORMATION_FIXED: if (length >= 1) { buffer[offset] = (byte) 0xcc; buffer[(short) (offset + length - 1)] = (byte) 0xcc; } break; - case CORRUPTION_FULLRANDOM: + case TRANSFORMATION_FULLRANDOM: randomData.generateData(buffer, offset, length); break; - case CORRUPTION_ONEBYTERANDOM: + case TRANSFORMATION_ONEBYTERANDOM: short first = Util.getShort(buffer, (short) 0); // save first two bytes randomData.generateData(buffer, (short) 0, (short) 2); // generate position @@ -1345,17 +1345,17 @@ public class EC_Consts { randomData.generateData(buffer, rngPos, (short) 1); } while (original == buffer[rngPos]); break; - case CORRUPTION_ZERO: + case TRANSFORMATION_ZERO: Util.arrayFillNonAtomic(buffer, offset, length, (byte) 0); break; - case CORRUPTION_ONE: + case TRANSFORMATION_ONE: Util.arrayFillNonAtomic(buffer, offset, length, (byte) 0); buffer[(short) (offset + length)] = (byte) 1; break; - case CORRUPTION_MAX: + case TRANSFORMATION_MAX: Util.arrayFillNonAtomic(buffer, offset, length, (byte) 1); break; - case CORRUPTION_INCREMENT: + case TRANSFORMATION_INCREMENT: short index = (short) (offset + length - 1); byte value; do { @@ -1363,11 +1363,11 @@ public class EC_Consts { buffer[index--] = ++value; } while (value == (byte) 0 && index >= offset); break; - case CORRUPTION_INFINITY: + case TRANSFORMATION_INFINITY: Util.arrayFillNonAtomic(buffer, offset, length, (byte) 0); length = 1; break; - case CORRUPTION_COMPRESS: + case TRANSFORMATION_COMPRESS: if ((short) (length % 2) != 1) { // an uncompressed point should have odd length (since 1 byte type, + 2 * coords) ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); @@ -1387,7 +1387,7 @@ public class EC_Consts { default: ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); } - corruptionMask = (short) (corruptionMask << 1); + transformationMask = (short) (transformationMask << 1); } return length; } diff --git a/src/cz/crcs/ectester/common/util/CardUtil.java b/src/cz/crcs/ectester/common/util/CardUtil.java index 1349879..3df5829 100644 --- a/src/cz/crcs/ectester/common/util/CardUtil.java +++ b/src/cz/crcs/ectester/common/util/CardUtil.java @@ -179,27 +179,27 @@ public class CardUtil { } } - public static String getCorruption(short corruptionType) { - switch (corruptionType) { - case EC_Consts.CORRUPTION_NONE: + public static String getTransformation(short transformationType) { + switch (transformationType) { + case EC_Consts.TRANSFORMATION_NONE: return "NONE"; - case EC_Consts.CORRUPTION_FIXED: + case EC_Consts.TRANSFORMATION_FIXED: return "FIXED"; - case EC_Consts.CORRUPTION_ONE: + case EC_Consts.TRANSFORMATION_ONE: return "ONE"; - case EC_Consts.CORRUPTION_ZERO: + case EC_Consts.TRANSFORMATION_ZERO: return "ZERO"; - case EC_Consts.CORRUPTION_ONEBYTERANDOM: + case EC_Consts.TRANSFORMATION_ONEBYTERANDOM: return "ONE_BYTE_RANDOM"; - case EC_Consts.CORRUPTION_FULLRANDOM: + case EC_Consts.TRANSFORMATION_FULLRANDOM: return "FULL_RANDOM"; - case EC_Consts.CORRUPTION_INCREMENT: + case EC_Consts.TRANSFORMATION_INCREMENT: return "INCREMENT"; - case EC_Consts.CORRUPTION_INFINITY: + case EC_Consts.TRANSFORMATION_INFINITY: return "INFINITY"; - case EC_Consts.CORRUPTION_COMPRESS: + case EC_Consts.TRANSFORMATION_COMPRESS: return "COMPRESSED"; - case EC_Consts.CORRUPTION_MAX: + case EC_Consts.TRANSFORMATION_MAX: return "MAX"; default: return "unknown"; diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index 1e8b8a4..302df84 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -488,7 +488,7 @@ public class ECTesterReader { byte pubkey_bytes[] = export.getParameter(pubkey, EC_Consts.PARAMETER_W); byte privkey_bytes[] = export.getParameter(privkey, EC_Consts.PARAMETER_S); - Response.ECDH perform = new Command.ECDH(cardManager, pubkey, privkey, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, cfg.ECKAType).send(); + Response.ECDH perform = new Command.ECDH(cardManager, pubkey, privkey, ECTesterApplet.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, cfg.ECKAType).send(); ecdh.add(perform); for (Response r : ecdh) { respWriter.outputResponse(r); diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java index 5e025d8..25b41dd 100644 --- a/src/cz/crcs/ectester/reader/command/Command.java +++ b/src/cz/crcs/ectester/reader/command/Command.java @@ -405,44 +405,44 @@ public abstract class Command { /** * */ - public static class Corrupt extends Command { + public static class Transform extends Command { private byte keyPair; private byte key; private short params; - private short corruption; + private short transformation; /** * @param cardManager cardManager to send APDU through - * @param keyPair which keyPair to corrupt, local/remote (KEYPAIR_* || ...) - * @param key key to corrupt (EC_Consts.KEY_* | ...) - * @param params parameters to corrupt (EC_Consts.PARAMETER_* | ...) - * @param corruption corruption type (EC_Consts.CORRUPTION_*) + * @param keyPair which keyPair to transform, local/remote (KEYPAIR_* || ...) + * @param key key to transform (EC_Consts.KEY_* | ...) + * @param params parameters to transform (EC_Consts.PARAMETER_* | ...) + * @param transformation transformation type (EC_Consts.TRANSFORMATION_*) */ - public Corrupt(CardMngr cardManager, byte keyPair, byte key, short params, short corruption) { + public Transform(CardMngr cardManager, byte keyPair, byte key, short params, short transformation) { super(cardManager); this.keyPair = keyPair; this.key = key; this.params = params; - this.corruption = corruption; + this.transformation = transformation; byte[] data = new byte[4]; ByteUtil.setShort(data, 0, params); - ByteUtil.setShort(data, 2, corruption); + ByteUtil.setShort(data, 2, transformation); - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_CORRUPT, keyPair, key, data); + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_TRANSFORM, keyPair, key, data); } @Override - public Response.Corrupt send() throws CardException { + public Response.Transform send() throws CardException { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.Corrupt(response, getDescription(), elapsed, keyPair, key, params, corruption); + return new Response.Transform(response, getDescription(), elapsed, keyPair, key, params, transformation); } @Override public String getDescription() { - String corrupt = CardUtil.getCorruption(corruption); + String transform = CardUtil.getTransformation(transformation); String pair; if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { @@ -450,7 +450,7 @@ public abstract class Command { } else { pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return String.format("Corrupt params of %s, %s", pair, corrupt); + return String.format("Transform params of %s, %s", pair, transform); } } @@ -556,7 +556,7 @@ public abstract class Command { private byte pubkey; private byte privkey; private byte export; - private short corruption; + private short transformation; private byte type; /** @@ -566,19 +566,19 @@ public abstract class Command { * @param pubkey keyPair to use for public key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) * @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) * @param export whether to export ECDH secret - * @param corruption whether to invalidate the pubkey before ECDH (EC_Consts.CORRUPTION_* | ...) + * @param transformation whether to transform the pubkey before ECDH (EC_Consts.TRANSFORMATION_* | ...) * @param type ECDH algorithm type (EC_Consts.KA_* | ...) */ - public ECDH(CardMngr cardManager, byte pubkey, byte privkey, byte export, short corruption, byte type) { + public ECDH(CardMngr cardManager, byte pubkey, byte privkey, byte export, short transformation, byte type) { super(cardManager); this.pubkey = pubkey; this.privkey = privkey; this.export = export; - this.corruption = corruption; + this.transformation = transformation; this.type = type; byte[] data = new byte[]{export, 0, 0, type}; - ByteUtil.setShort(data, 1, corruption); + ByteUtil.setShort(data, 1, transformation); this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDH, pubkey, privkey, data); } @@ -588,7 +588,7 @@ public abstract class Command { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.ECDH(response, getDescription(), elapsed, pubkey, privkey, export, corruption, type); + return new Response.ECDH(response, getDescription(), elapsed, pubkey, privkey, export, transformation, type); } @Override @@ -599,10 +599,10 @@ public abstract class Command { String priv = privkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; String validity; - if (corruption == EC_Consts.CORRUPTION_NONE) { + if (transformation == EC_Consts.TRANSFORMATION_NONE) { validity = "unchanged"; } else { - validity = CardUtil.getCorruption(corruption); + validity = CardUtil.getTransformation(transformation); } return String.format("%s of %s pubkey and %s privkey(%s point)", algo, pub, priv, validity); } @@ -614,7 +614,7 @@ public abstract class Command { public static class ECDH_direct extends Command { private byte privkey; private byte export; - private short corruption; + private short transformation; private byte type; private byte[] pubkey; @@ -624,20 +624,20 @@ public abstract class Command { * @param cardManager cardManager to send APDU through * @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) * @param export whether to export ECDH secret - * @param corruption whether to invalidate the pubkey before ECDH (EC_Consts.CORRUPTION_* | ...) + * @param transformation whether to transform the pubkey before ECDH (EC_Consts.TRANSFORMATION_* | ...) * @param type EC KeyAgreement type * @param pubkey pubkey data to do ECDH with. */ - public ECDH_direct(CardMngr cardManager, byte privkey, byte export, short corruption, byte type, byte[] pubkey) { + public ECDH_direct(CardMngr cardManager, byte privkey, byte export, short transformation, byte type, byte[] pubkey) { super(cardManager); this.privkey = privkey; this.export = export; - this.corruption = corruption; + this.transformation = transformation; this.type = type; this.pubkey = pubkey; byte[] data = new byte[3 + pubkey.length]; - ByteUtil.setShort(data, 0, corruption); + ByteUtil.setShort(data, 0, transformation); data[2] = type; System.arraycopy(pubkey, 0, data, 3, pubkey.length); @@ -649,7 +649,7 @@ public abstract class Command { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.ECDH(response, getDescription(), elapsed, ECTesterApplet.KEYPAIR_REMOTE, privkey, export, corruption, type); + return new Response.ECDH(response, getDescription(), elapsed, ECTesterApplet.KEYPAIR_REMOTE, privkey, export, transformation, type); } @Override @@ -659,10 +659,10 @@ public abstract class Command { String priv = privkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; String validity; - if (corruption == EC_Consts.CORRUPTION_NONE) { + if (transformation == EC_Consts.TRANSFORMATION_NONE) { validity = "unchanged"; } else { - validity = CardUtil.getCorruption(corruption); + validity = CardUtil.getTransformation(transformation); } return String.format("%s of external pubkey and %s privkey(%s point)", algo, priv, validity); } diff --git a/src/cz/crcs/ectester/reader/response/Response.java b/src/cz/crcs/ectester/reader/response/Response.java index 5a9a458..4814e41 100644 --- a/src/cz/crcs/ectester/reader/response/Response.java +++ b/src/cz/crcs/ectester/reader/response/Response.java @@ -222,18 +222,18 @@ public abstract class Response { /** * */ - public static class Corrupt extends Response { + public static class Transform extends Response { private byte keyPair; private byte key; private short params; - private short corruption; + private short transformation; - public Corrupt(ResponseAPDU response, String description, long time, byte keyPair, byte key, short params, short corruption) { + public Transform(ResponseAPDU response, String description, long time, byte keyPair, byte key, short params, short transformation) { super(response, description, time); this.keyPair = keyPair; this.key = key; this.params = params; - this.corruption = corruption; + this.transformation = transformation; int pairs = 0; if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) pairs++; @@ -358,15 +358,15 @@ public abstract class Response { private byte pubkey; private byte privkey; private byte export; - private short corruption; + private short transformation; private byte type; - public ECDH(ResponseAPDU response, String description, long time, byte pubkey, byte privkey, byte export, short corruption, byte type) { + public ECDH(ResponseAPDU response, String description, long time, byte pubkey, byte privkey, byte export, short transformation, byte type) { super(response, description, time); this.pubkey = pubkey; this.privkey = privkey; this.export = export; - this.corruption = corruption; + this.transformation = transformation; this.type = type; parse(1, (export == ECTesterApplet.EXPORT_TRUE) ? 1 : 0); diff --git a/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java b/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java index fd3f0ae..a0b71a7 100644 --- a/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java @@ -48,7 +48,7 @@ public class CardCofactorTestSuite extends CardTestSuite { List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); ecdhTests.add(CommandTest.expect(ecdhCommand, Result.ExpectedValue.FAILURE, "Card correctly rejected point on non-generator subgroup.", "Card incorrectly accepted point on non-generator subgroup.")); } Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with public points on non-generator subgroup", ecdhTests.toArray(new Test[0])); diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java index b931aad..f0eaa87 100644 --- a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java @@ -39,7 +39,7 @@ public class CardCompositeCurvesSuite 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.ANY); Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY); - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.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."); doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", " + key.getDesc(), allocate, set, generate, ecdh)); diff --git a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java index cb5e0c9..dd9c8c8 100644 --- a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java @@ -59,9 +59,9 @@ public class CardDefaultSuite extends CardTestSuite { for (byte kaType : EC_Consts.KA_TYPES) { Test allocate = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), ExpectedValue.SUCCESS)); if (allocate.ok()) { - Command ecdh = new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, kaType); + Command ecdh = new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType); Test ka = runTest(CommandTest.expect(ecdh, ExpectedValue.SUCCESS)); - Test kaCompressed = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, kaType), ExpectedValue.SUCCESS)); + Test kaCompressed = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS, kaType), ExpectedValue.SUCCESS)); Test perfTest = null; if (ka.ok()) { perfTest = runTest(PerformanceTest.repeat(ecdh, 10)); diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java index 0cf27ec..fab7786 100644 --- a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java @@ -53,7 +53,7 @@ public class CardInvalidCurvesSuite extends CardTestSuite { List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); ecdhTests.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve.", "Card incorrectly accepted point on invalid curve.")); } Test ecdh = CompoundTest.all(ExpectedValue.SUCCESS, "Perform ECDH with invalid public points", ecdhTests.toArray(new Test[0])); diff --git a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java index de267c3..9d39525 100644 --- a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java @@ -11,7 +11,6 @@ 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.io.IOException; import java.util.LinkedList; @@ -55,7 +54,7 @@ public class CardTestVectorSuite extends CardTestSuite { 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)); - testVector.add(CommandTest.function(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getJavaCardKA()), new TestCallback() { + testVector.add(CommandTest.function(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, result.getJavaCardKA()), new TestCallback() { @Override public Result apply(CommandTestable testable) { Response.ECDH dh = (Response.ECDH) testable.getResponse(); diff --git a/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java b/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java index fad508f..4b90694 100644 --- a/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java @@ -48,7 +48,7 @@ public class CardTwistTestSuite extends CardTestSuite { List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); ecdhTests.add(CommandTest.expect(ecdhCommand, Result.ExpectedValue.FAILURE, "Card correctly rejected point on twist.", "Card incorrectly accepted point on twist.")); } Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with public points on twist", ecdhTests.toArray(new Test[0])); diff --git a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java index 4706bdd..5d58be1 100644 --- a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java @@ -55,7 +55,7 @@ public class CardWrongCurvesSuite extends CardTestSuite { for (byte kaType : EC_Consts.KA_TYPES) { Test allocate = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), Result.ExpectedValue.SUCCESS)); if (allocate.ok()) { - Test ka = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, kaType), Result.ExpectedValue.FAILURE)); + Test ka = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType), Result.ExpectedValue.FAILURE)); Test kaTest = runTest(CompoundTest.all(Result.ExpectedValue.FAILURE, "Allocate and perform KA, should fail.", allocate, ka)); tests.add(kaTest); } @@ -81,8 +81,8 @@ public class CardWrongCurvesSuite extends CardTestSuite { Test set = runTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, curve, EC_Consts.PARAMETERS_DOMAIN_FP, null), Result.ExpectedValue.SUCCESS)); Test setup = runTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPair setup.", key, set)); - Test prime0 = ecdhTest(new Command.Corrupt(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_FP, EC_Consts.CORRUPTION_ZERO), "Set p = 0.", "ECDH with p = 0."); - Test prime1 = ecdhTest(new Command.Corrupt(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_FP, EC_Consts.CORRUPTION_ONE), "Set p = 1.", "ECDH with p = 1."); + Test prime0 = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_FP, EC_Consts.TRANSFORMATION_ZERO), "Set p = 0.", "ECDH with p = 0."); + Test prime1 = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_FP, EC_Consts.TRANSFORMATION_ONE), "Set p = 1.", "ECDH with p = 1."); short keyHalf = (short) (keyLength / 2); BigInteger prime = new BigInteger(keyHalf, r); @@ -116,7 +116,7 @@ public class CardWrongCurvesSuite extends CardTestSuite { Test set = runTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, curve, EC_Consts.PARAMETERS_DOMAIN_F2M, null), Result.ExpectedValue.SUCCESS)); Test setup = runTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPair setup.", key, set)); - Test coeff0 = ecdhTest(new Command.Corrupt(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_F2M, EC_Consts.CORRUPTION_ZERO), "Set e1 = e2 = e3 = 0.", "ECDH with wrong field polynomial: x^" + keyLength); + Test coeff0 = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_F2M, EC_Consts.TRANSFORMATION_ZERO), "Set e1 = e2 = e3 = 0.", "ECDH with wrong field polynomial: x^" + keyLength); short e1 = (short) (2 * keyLength); short e2 = (short) (3 * keyLength); @@ -147,7 +147,7 @@ public class CardWrongCurvesSuite extends CardTestSuite { Test generate = runTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), Result.ExpectedValue.FAILURE)); Test preparePhase = runTest(CompoundTest.any(Result.ExpectedValue.SUCCESS, prepareDesc, setup, generate)); Test allocateECDH = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.SUCCESS)); - Test ecdh = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.FAILURE)); + Test ecdh = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.FAILURE)); return runTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, fullDesc, preparePhase, allocateECDH, ecdh)); } } -- cgit v1.2.3-70-g09d2 From efc1a237f83a6fe7bcfaced2aaebcfeae116a774 Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 5 Apr 2018 00:38:24 +0200 Subject: Add ECDSA_sign and ECDSA_verify commands, to allow separate testing. --- src/cz/crcs/ectester/applet/ECKeyTester.java | 50 +++++++ src/cz/crcs/ectester/applet/ECTesterApplet.java | 148 +++++++++++++++++---- src/cz/crcs/ectester/applet/EC_Consts.java | 45 +++++-- src/cz/crcs/ectester/common/util/CardUtil.java | 52 ++++---- src/cz/crcs/ectester/reader/ECTesterReader.java | 4 +- src/cz/crcs/ectester/reader/command/Command.java | 113 ++++++++++++++++ .../reader/test/CardCofactorTestSuite.java | 2 +- .../reader/test/CardCompositeCurvesSuite.java | 2 +- .../reader/test/CardInvalidCurvesSuite.java | 2 +- .../ectester/reader/test/CardTwistTestSuite.java | 2 +- .../ectester/reader/test/CardWrongCurvesSuite.java | 4 +- 11 files changed, 347 insertions(+), 77 deletions(-) (limited to 'src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java') diff --git a/src/cz/crcs/ectester/applet/ECKeyTester.java b/src/cz/crcs/ectester/applet/ECKeyTester.java index 27bb9e1..7c091e3 100644 --- a/src/cz/crcs/ectester/applet/ECKeyTester.java +++ b/src/cz/crcs/ectester/applet/ECKeyTester.java @@ -130,6 +130,56 @@ public class ECKeyTester { return length; } + /** + * + * @param signKey + * @param inputBuffer + * @param inputOffset + * @param inputLength + * @param sigBuffer + * @param sigOffset + * @return + */ + public short testECDSA_sign(ECPrivateKey signKey, byte[] inputBuffer, short inputOffset, short inputLength, byte[] sigBuffer, short sigOffset) { + short length = 0; + try { + sw = AppletUtil.signCheck(ecdsaSignature); + + ecdsaSignature.init(signKey, Signature.MODE_SIGN); + length = ecdsaSignature.sign(inputBuffer, inputOffset, inputLength, sigBuffer, sigOffset); + } catch (CardRuntimeException ce) { + sw = ce.getReason(); + } + return length; + } + + /** + * + * @param verifyKey + * @param inputBuffer + * @param inputOffset + * @param inputLength + * @param sigBuffer + * @param sigOffset + * @param sigLength + * @return + */ + public short testECDSA_verify(ECPublicKey verifyKey, byte[] inputBuffer, short inputOffset, short inputLength, byte[] sigBuffer, short sigOffset, short sigLength) { + short length = 0; + try { + sw = AppletUtil.signCheck(ecdsaSignature); + + ecdsaSignature.init(verifyKey, Signature.MODE_VERIFY); + boolean correct = ecdsaSignature.verify(inputBuffer, inputOffset, inputLength, sigBuffer, sigOffset, sigLength); + if (!correct) { + sw = ECTesterApplet.SW_SIG_VERIFY_FAIL; + } + } catch (CardRuntimeException ce) { + sw = ce.getReason(); + } + return length; + } + public KeyAgreement getKA() { return ecKeyAgreement; } diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index 18c4d1f..d0ca8f5 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -51,10 +51,11 @@ public class ECTesterApplet extends Applet implements ExtendedLength { public static final byte INS_ECDH = (byte) 0x70; public static final byte INS_ECDH_DIRECT = (byte) 0x71; public static final byte INS_ECDSA = (byte) 0x72; - public static final byte INS_CLEANUP = (byte) 0x73; - //public static final byte INS_SUPPORT = (byte) 0x74; - public static final byte INS_ALLOCATE_KA = (byte) 0x75; - public static final byte INS_ALLOCATE_SIG = (byte) 0x76; + public static final byte INS_ECDSA_SIGN = (byte) 0x73; + public static final byte INS_ECDSA_VERIFY = (byte) 0x74; + public static final byte INS_CLEANUP = (byte) 0x75; + public static final byte INS_ALLOCATE_KA = (byte) 0x76; + public static final byte INS_ALLOCATE_SIG = (byte) 0x77; // PARAMETERS for P1 and P2 @@ -83,34 +84,12 @@ public class ECTesterApplet extends Applet implements ExtendedLength { public static final short SW_TransactionException_prefix = (short) 0xf400; public static final short SW_CardRuntimeException_prefix = (short) 0xf500; - - // 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; - - // Class javacard.security.Signature - // javacard.security.Signature Fields: - public static final byte Signature_ALG_ECDSA_SHA = 17; - public static final byte Signature_ALG_ECDSA_SHA_256 = 33; - public static final byte Signature_ALG_ECDSA_SHA_384 = 34; - public static final byte Signature_ALG_ECDSA_SHA_224 = 37; - public static final byte Signature_ALG_ECDSA_SHA_512 = 38; - private static final short ARRAY_LENGTH = (short) 0xff; private static final short APDU_MAX_LENGTH = (short) 1024; // TEMPORARRY ARRAY IN RAM private byte[] ramArray = null; private byte[] ramArray2 = null; private byte[] apduArray = null; - // PERSISTENT ARRAY IN EEPROM - private byte[] dataArray = null; // unused private RandomData randomData = null; @@ -135,9 +114,6 @@ public class ECTesterApplet extends Applet implements ExtendedLength { ramArray2 = JCSystem.makeTransientByteArray(ARRAY_LENGTH, JCSystem.CLEAR_ON_RESET); apduArray = JCSystem.makeTransientByteArray(APDU_MAX_LENGTH, JCSystem.CLEAR_ON_RESET); - dataArray = new byte[ARRAY_LENGTH]; - Util.arrayFillNonAtomic(dataArray, (short) 0, ARRAY_LENGTH, (byte) 0); - randomData = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM); EC_Consts.randomData = randomData; @@ -203,6 +179,12 @@ public class ECTesterApplet extends Applet implements ExtendedLength { case INS_ECDSA: length = insECDSA(apdu); break; + case INS_ECDSA_SIGN: + length = insECDSA_sign(apdu); + break; + case INS_ECDSA_VERIFY: + length = insECDSA_verify(apdu); + break; case INS_CLEANUP: length = insCleanup(apdu); break; @@ -494,6 +476,57 @@ public class ECTesterApplet extends Applet implements ExtendedLength { return len; } + /** + * + * @param apdu P1 = byte keyPair (KEYPAIR_*) + * P2 = byte export (EXPORT_TRUE || EXPORT_FALSE) + * DATA = byte sigType + * short dataLength (00 = random data generated, !00 = data length) + * byte[] data + * @return length of response + */ + private short insECDSA_sign(APDU apdu) { + byte keyPair = apduArray[ISO7816.OFFSET_P1]; + byte export = apduArray[ISO7816.OFFSET_P2]; + short cdata = apdu.getOffsetCdata(); + byte sigType = apduArray[cdata]; + + short len = 0; + if ((keyPair & KEYPAIR_LOCAL) != 0) { + len += ecdsa_sign(localKeypair, sigType, export, apduArray, (short) (cdata + 1), apdu.getBuffer(), (short) 0); + } + if ((keyPair & KEYPAIR_REMOTE) != 0) { + len += ecdsa_sign(remoteKeypair, sigType, export, apduArray, (short) (cdata + 1), apdu.getBuffer(), len); + } + return len; + } + + /** + * + * @param apdu P1 = byte keyPair (KEYPAIR_*) + * P2 = byte sigType + * DATA = short dataLength (00 = random data generated, !00 = data length) + * byte[] data + * short sigLength + * byte[] signature + * @return length of response + */ + private short insECDSA_verify(APDU apdu) { + byte keyPair = apduArray[ISO7816.OFFSET_P1]; + byte sigType = apduArray[ISO7816.OFFSET_P2]; + short cdata = apdu.getOffsetCdata(); + + short len = 0; + if ((keyPair & KEYPAIR_LOCAL) != 0) { + len += ecdsa_verify(localKeypair, sigType, apduArray, cdata, apdu.getBuffer(), (short) 0); + } + if ((keyPair & KEYPAIR_REMOTE) != 0) { + len += ecdsa_verify(remoteKeypair, sigType, apduArray, cdata, apdu.getBuffer(), len); + } + return len; + } + + /** * Performs card memory cleanup via JCSystem.requestObjectDeletion() * @@ -741,6 +774,63 @@ public class ECTesterApplet extends Applet implements ExtendedLength { return length; } + private short ecdsa_sign(KeyPair sign, byte sigType, byte export, byte[] inBuffer, short inOffset, byte[] outBuffer, short outOffset) { + short length = 0; + + short dataLength = Util.getShort(inBuffer, inOffset); + if (dataLength == 0) { //no data to sign + //generate random + dataLength = 64; + randomData.generateData(ramArray, (short) 0, dataLength); + } else { + Util.arrayCopyNonAtomic(inBuffer, (short) (inOffset + 2), ramArray, (short) 0, dataLength); + } + + short signatureLength = 0; + if (keyTester.getSigType() == sigType) { + signatureLength = keyTester.testECDSA_sign((ECPrivateKey) sign.getPrivate(), ramArray, (short) 0, dataLength, ramArray2, (short) 0); + } else { + short allocateSW = keyTester.allocateSig(sigType); + if (allocateSW == ISO7816.SW_NO_ERROR) { + signatureLength = keyTester.testECDSA_sign((ECPrivateKey) sign.getPrivate(), ramArray, (short) 0, dataLength, ramArray2, (short) 0); + } + } + Util.setShort(outBuffer, outOffset, keyTester.getSW()); + length += 2; + + if (export == EXPORT_TRUE) { + Util.setShort(outBuffer, (short) (outOffset + length), signatureLength); + length += 2; + + Util.arrayCopyNonAtomic(ramArray2, (short) 0, outBuffer, (short) (outOffset + length), signatureLength); + length += signatureLength; + } + + return length; + } + + private short ecdsa_verify(KeyPair verify, byte sigType, byte[] inBuffer, short inOffset, byte[] outBuffer, short outOffset) { + short length = 0; + + short dataLength = Util.getShort(inBuffer, inOffset); + short dataOffset = (short)(inOffset + 2); + short sigLength = Util.getShort(inBuffer, (short)(dataOffset + dataLength)); + short sigOffset = (short)(dataOffset + dataLength + 2); + + if (keyTester.getSigType() == sigType) { + keyTester.testECDSA_verify((ECPublicKey) verify.getPublic(), inBuffer, dataOffset, dataLength, inBuffer, sigOffset, sigLength); + } else { + short allocateSW = keyTester.allocateSig(sigType); + if (allocateSW == ISO7816.SW_NO_ERROR) { + keyTester.testECDSA_verify((ECPublicKey) verify.getPublic(), inBuffer, dataOffset, dataLength, inBuffer, sigOffset, sigLength); + } + } + Util.setShort(outBuffer, outOffset, keyTester.getSW()); + length += 2; + + return length; + } + /** * @param buffer buffer to write sw to * @param offset output offset in buffer diff --git a/src/cz/crcs/ectester/applet/EC_Consts.java b/src/cz/crcs/ectester/applet/EC_Consts.java index 5b3c74c..88a8bd6 100644 --- a/src/cz/crcs/ectester/applet/EC_Consts.java +++ b/src/cz/crcs/ectester/applet/EC_Consts.java @@ -12,6 +12,8 @@ import javacard.security.RandomData; */ public class EC_Consts { + public static final byte KeyAgreement_ALG_EC_SVDP_DH_KDF = 1; + public static final byte KeyAgreement_ALG_EC_SVDP_DHC_KDF = 2; private static byte[] EC_FP_P = null; //p private static byte[] EC_A = null; //a private static byte[] EC_B = null; //b @@ -1026,23 +1028,40 @@ public class EC_Consts { public static final short[] FP_SIZES = new short[]{112, 128, 160, 192, 224, 256, 384, 521}; public static final short[] F2M_SIZES = new short[]{163, 233, 283, 409, 571}; + // 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_DHC = 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[] KA_TYPES = new byte[]{ - ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, - //ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_KDF, //duplicate - ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC, - //ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC_KDF, //duplicate - ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_PLAIN, - ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC_PLAIN, - ECTesterApplet.KeyAgreement_ALG_EC_PACE_GM, - ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY + KeyAgreement_ALG_EC_SVDP_DH, + //KeyAgreement_ALG_EC_SVDP_DH_KDF, //duplicate + KeyAgreement_ALG_EC_SVDP_DHC, + //KeyAgreement_ALG_EC_SVDP_DHC_KDF, //duplicate + KeyAgreement_ALG_EC_SVDP_DH_PLAIN, + KeyAgreement_ALG_EC_SVDP_DHC_PLAIN, + KeyAgreement_ALG_EC_PACE_GM, + KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY }; + // Class javacard.security.Signature + // javacard.security.Signature Fields: + public static final byte Signature_ALG_ECDSA_SHA = 17; + public static final byte Signature_ALG_ECDSA_SHA_224 = 37; + public static final byte Signature_ALG_ECDSA_SHA_256 = 33; + public static final byte Signature_ALG_ECDSA_SHA_384 = 34; + public static final byte Signature_ALG_ECDSA_SHA_512 = 38; + public static final byte[] SIG_TYPES = new byte[]{ - ECTesterApplet.Signature_ALG_ECDSA_SHA, - ECTesterApplet.Signature_ALG_ECDSA_SHA_224, - ECTesterApplet.Signature_ALG_ECDSA_SHA_256, - ECTesterApplet.Signature_ALG_ECDSA_SHA_384, - ECTesterApplet.Signature_ALG_ECDSA_SHA_512 + Signature_ALG_ECDSA_SHA, + Signature_ALG_ECDSA_SHA_224, + Signature_ALG_ECDSA_SHA_256, + Signature_ALG_ECDSA_SHA_384, + Signature_ALG_ECDSA_SHA_512 }; public static byte getCurve(short keyLength, byte keyClass) { diff --git a/src/cz/crcs/ectester/common/util/CardUtil.java b/src/cz/crcs/ectester/common/util/CardUtil.java index 3df5829..2501e47 100644 --- a/src/cz/crcs/ectester/common/util/CardUtil.java +++ b/src/cz/crcs/ectester/common/util/CardUtil.java @@ -6,8 +6,6 @@ import javacard.framework.ISO7816; import javacard.security.CryptoException; import javacard.security.KeyPair; -import static cz.crcs.ectester.applet.ECTesterApplet.*; - /** * @author Petr Svenda petr@svenda.com * @author Jan Jancar johny@neuromancer.sk @@ -17,12 +15,12 @@ public class CardUtil { switch (name) { case "DH": case "ECDH": - return ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DH; case "DHC": case "ECDHC": - return ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC; default: - return ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DH; } } @@ -208,17 +206,17 @@ public class CardUtil { public static String getKATypeString(byte kaType) { switch (kaType) { - case KeyAgreement_ALG_EC_SVDP_DH: + case EC_Consts.KeyAgreement_ALG_EC_SVDP_DH: return "ALG_EC_SVDP_DH"; - case KeyAgreement_ALG_EC_SVDP_DH_PLAIN: + case EC_Consts.KeyAgreement_ALG_EC_SVDP_DH_PLAIN: return "ALG_EC_SVDP_DH_PLAIN"; - case KeyAgreement_ALG_EC_PACE_GM: + case EC_Consts.KeyAgreement_ALG_EC_PACE_GM: return "ALG_EC_PACE_GM"; - case KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY: + case EC_Consts.KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY: return "ALG_EC_SVDP_DH_PLAIN_XY"; - case KeyAgreement_ALG_EC_SVDP_DHC: + case EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC: return "ALG_EC_SVDP_DHC"; - case KeyAgreement_ALG_EC_SVDP_DHC_PLAIN: + case EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC_PLAIN: return "ALG_EC_SVDP_DHC_PLAIN"; default: return "unknown"; @@ -228,17 +226,17 @@ public class CardUtil { public static byte getKAType(String kaTypeString) { switch (kaTypeString) { case "ALG_EC_SVDP_DH": - return KeyAgreement_ALG_EC_SVDP_DH; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DH; case "ALG_EC_SVDP_DH_PLAIN": - return KeyAgreement_ALG_EC_SVDP_DH_PLAIN; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DH_PLAIN; case "ALG_EC_PACE_GM": - return KeyAgreement_ALG_EC_PACE_GM; + return EC_Consts.KeyAgreement_ALG_EC_PACE_GM; case "ALG_EC_SVDP_DH_PLAIN_XY": - return KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY; case "ALG_EC_SVDP_DHC": - return KeyAgreement_ALG_EC_SVDP_DHC; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC; case "ALG_EC_SVDP_DHC_PLAIN": - return KeyAgreement_ALG_EC_SVDP_DHC_PLAIN; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC_PLAIN; default: return 0; } @@ -256,15 +254,15 @@ public class CardUtil { public static String getSigTypeString(byte sigType) { switch (sigType) { - case Signature_ALG_ECDSA_SHA: + case EC_Consts.Signature_ALG_ECDSA_SHA: return "ALG_ECDSA_SHA"; - case Signature_ALG_ECDSA_SHA_224: + case EC_Consts.Signature_ALG_ECDSA_SHA_224: return "ALG_ECDSA_SHA_224"; - case Signature_ALG_ECDSA_SHA_256: + case EC_Consts.Signature_ALG_ECDSA_SHA_256: return "ALG_ECDSA_SHA_256"; - case Signature_ALG_ECDSA_SHA_384: + case EC_Consts.Signature_ALG_ECDSA_SHA_384: return "ALG_ECDSA_SHA_384"; - case Signature_ALG_ECDSA_SHA_512: + case EC_Consts.Signature_ALG_ECDSA_SHA_512: return "ALG_ECDSA_SHA_512"; default: return "unknown"; @@ -274,15 +272,15 @@ public class CardUtil { public static byte getSigType(String sigTypeString) { switch (sigTypeString) { case "ALG_ECDSA_SHA": - return Signature_ALG_ECDSA_SHA; + return EC_Consts.Signature_ALG_ECDSA_SHA; case "ALG_ECDSA_SHA_224": - return Signature_ALG_ECDSA_SHA_224; + return EC_Consts.Signature_ALG_ECDSA_SHA_224; case "ALG_ECDSA_SHA_256": - return Signature_ALG_ECDSA_SHA_256; + return EC_Consts.Signature_ALG_ECDSA_SHA_256; case "ALG_ECDSA_SHA_384": - return Signature_ALG_ECDSA_SHA_384; + return EC_Consts.Signature_ALG_ECDSA_SHA_384; case "ALG_ECDSA_SHA_512": - return Signature_ALG_ECDSA_SHA_512; + return EC_Consts.Signature_ALG_ECDSA_SHA_512; default: return 0; } diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index dfd71db..84c0439 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -49,8 +49,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Scanner; -import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH; -import static cz.crcs.ectester.applet.ECTesterApplet.Signature_ALG_ECDSA_SHA; +import static cz.crcs.ectester.applet.EC_Consts.KeyAgreement_ALG_EC_SVDP_DH; +import static cz.crcs.ectester.applet.EC_Consts.Signature_ALG_ECDSA_SHA; /** * Reader part of ECTester, a tool for testing Elliptic curve support on javacards. diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java index 25b41dd..d0eaf45 100644 --- a/src/cz/crcs/ectester/reader/command/Command.java +++ b/src/cz/crcs/ectester/reader/command/Command.java @@ -685,6 +685,10 @@ public abstract class Command { */ public ECDSA(CardMngr cardManager, byte keyPair, byte sigType, byte export, byte[] raw) { super(cardManager); + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + throw new IllegalArgumentException(); + } + this.keyPair = keyPair; this.sigType = sigType; this.export = export; @@ -718,6 +722,115 @@ public abstract class Command { } } + public static class ECDSA_sign extends Command { + private byte keyPair; + private byte sigType; + private byte export; + private byte[] raw; + + /** + * Creates the INS_ECDSA_SIGN instruction. + * + * @param cardManager cardManager to send APDU through + * @param keyPair keyPair to use for signing and verification (KEYPAIR_LOCAL || KEYPAIR_REMOTE) + * @param sigType Signature type to use + * @param export whether to export ECDSA signature + * @param raw data to sign, can be null, in which case random data is signed. + */ + public ECDSA_sign(CardMngr cardManager, byte keyPair, byte sigType, byte export, byte[] raw) { + super(cardManager); + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + throw new IllegalArgumentException(); + } + + this.keyPair = keyPair; + this.sigType = sigType; + this.export = export; + this.raw = raw; + + int len = raw != null ? raw.length : 0; + byte[] data = new byte[3 + len]; + data[0] = sigType; + ByteUtil.setShort(data, 1, (short) len); + if (raw != null) { + System.arraycopy(raw, 0, data, 3, len); + } + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDSA_SIGN, keyPair, export, data); + } + + @Override + public Response.ECDSA send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.ECDSA(response, getDescription(), elapsed, keyPair, sigType, export, raw); + } + + @Override + public String getDescription() { + String algo = CardUtil.getSigTypeString(sigType); + String key = keyPair == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; + String data = raw == null ? "random" : "provided"; + return String.format("%s signature with %s keypair(%s data)", algo, key, data); + } + } + + public static class ECDSA_verify extends Command { + private byte keyPair; + private byte sigType; + private byte[] raw; + private byte[] signature; + + /** + * Creates the INS_ECDSA_VERIFY instruction. + * + * @param cardManager cardManager to send APDU through + * @param keyPair keyPair to use for signing and verification (KEYPAIR_LOCAL || KEYPAIR_REMOTE) + * @param sigType Signature type to use + * @param raw data to sign + * @param signature signature data + */ + public ECDSA_verify(CardMngr cardManager, byte keyPair, byte sigType, byte[] raw, byte[] signature) { + super(cardManager); + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + throw new IllegalArgumentException(); + } + if (raw == null || signature == null) { + throw new IllegalArgumentException(); + } + + this.keyPair = keyPair; + this.sigType = sigType; + this.raw = raw; + this.signature = signature; + + byte[] data = new byte[4 + raw.length + signature.length]; + ByteUtil.setShort(data, 0, (short) raw.length); + System.arraycopy(raw, 0, data, 2, raw.length); + ByteUtil.setShort(data, 2 + raw.length, (short) signature.length); + System.arraycopy(signature, 0, data, 2 + raw.length + 2, signature.length); + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDSA_SIGN, keyPair, sigType, data); + } + + @Override + public Response.ECDSA send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.ECDSA(response, getDescription(), elapsed, keyPair, sigType, ECTesterApplet.EXPORT_FALSE, raw); + } + + @Override + public String getDescription() { + String algo = CardUtil.getSigTypeString(sigType); + String key = keyPair == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; + String data = raw == null ? "random" : "provided"; + return String.format("%s verification with %s keypair(%s data)", algo, key, data); + } + } + /** * */ diff --git a/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java b/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java index a0b71a7..1ca05d4 100644 --- a/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java @@ -48,7 +48,7 @@ public class CardCofactorTestSuite extends CardTestSuite { List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + 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()); ecdhTests.add(CommandTest.expect(ecdhCommand, Result.ExpectedValue.FAILURE, "Card correctly rejected point on non-generator subgroup.", "Card incorrectly accepted point on non-generator subgroup.")); } Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with public points on non-generator subgroup", ecdhTests.toArray(new Test[0])); diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java index f0eaa87..95204dd 100644 --- a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java @@ -39,7 +39,7 @@ public class CardCompositeCurvesSuite 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.ANY); Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY); - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); + 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."); doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", " + key.getDesc(), allocate, set, generate, ecdh)); diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java index fab7786..d3c5f99 100644 --- a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java @@ -53,7 +53,7 @@ public class CardInvalidCurvesSuite extends CardTestSuite { List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + 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()); ecdhTests.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve.", "Card incorrectly accepted point on invalid curve.")); } Test ecdh = CompoundTest.all(ExpectedValue.SUCCESS, "Perform ECDH with invalid public points", ecdhTests.toArray(new Test[0])); diff --git a/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java b/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java index 4b90694..c80db0d 100644 --- a/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java @@ -48,7 +48,7 @@ public class CardTwistTestSuite extends CardTestSuite { List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + 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()); ecdhTests.add(CommandTest.expect(ecdhCommand, Result.ExpectedValue.FAILURE, "Card correctly rejected point on twist.", "Card incorrectly accepted point on twist.")); } Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with public points on twist", ecdhTests.toArray(new Test[0])); diff --git a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java index 5d58be1..429b047 100644 --- a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java @@ -146,8 +146,8 @@ public class CardWrongCurvesSuite extends CardTestSuite { Test setup = runTest(CommandTest.expect(setupCmd, Result.ExpectedValue.FAILURE)); Test generate = runTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), Result.ExpectedValue.FAILURE)); Test preparePhase = runTest(CompoundTest.any(Result.ExpectedValue.SUCCESS, prepareDesc, setup, generate)); - Test allocateECDH = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.SUCCESS)); - Test ecdh = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.FAILURE)); + Test allocateECDH = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.SUCCESS)); + Test ecdh = runTest(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), Result.ExpectedValue.FAILURE)); return runTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, fullDesc, preparePhase, allocateECDH, ecdh)); } } -- cgit v1.2.3-70-g09d2 From f00b363143885905bb4ab29642461d2b7e299d04 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 27 Jun 2018 23:59:36 +0200 Subject: Add tests for small R to composite test suite. --- .../reader/test/CardCompositeCurvesSuite.java | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java') diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java index 95204dd..d186b4a 100644 --- a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java @@ -3,6 +3,7 @@ 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_KAResult; import cz.crcs.ectester.common.ec.EC_Key; import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.CompoundTest; @@ -12,6 +13,7 @@ import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; import cz.crcs.ectester.reader.command.Command; +import java.util.List; import java.util.Map; import static cz.crcs.ectester.common.test.Result.ExpectedValue; @@ -36,8 +38,8 @@ public class CardCompositeCurvesSuite extends CardTestSuite { Map keys = EC_Store.getInstance().getObjects(EC_Key.class, "composite"); for (EC_Key key : keys.values()) { EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, key.getCurve()); - 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.ANY); + Test allocate = CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_LOCAL, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS); + Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY); Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY); 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."); @@ -45,5 +47,20 @@ public class CardCompositeCurvesSuite extends CardTestSuite { doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", " + key.getDesc(), allocate, set, generate, ecdh)); new Command.Cleanup(this.card).send(); } + + /* Also test having a G of small order, so small R. + */ + Map results = EC_Store.getInstance().getObjects(EC_Curve.class, "composite"); + List>> groupList = EC_Store.mapToPrefix(results.values()); + List smallRCurves = groupList.stream().filter((e) -> e.getKey().equals("small")).findFirst().get().getValue(); + for (EC_Curve curve : smallRCurves) { + 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.ANY); + Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.ANY); + Test ecdh = 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), ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a small order generator.", "Card incorrectly does ECDH over a small order generator."); + + doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Small generator order test of " + curve.getId() + ".", allocate, set, generate, ecdh)); + new Command.Cleanup(this.card).send(); + } } } -- cgit v1.2.3-70-g09d2 From 6c29f55b0e3c5a866c7589393db9259950db811b Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 30 Jun 2018 00:57:54 +0200 Subject: Add composite PQ tests. Better order tests by EC_Data id. --- src/cz/crcs/ectester/data/EC_Store.java | 6 ++ .../ectester/data/composite/composite128_pq.csv | 1 + .../ectester/data/composite/composite128_pq1.csv | 1 + .../ectester/data/composite/composite128_pq2.csv | 1 + .../ectester/data/composite/composite160_pq.csv | 1 + .../ectester/data/composite/composite160_pq1.csv | 1 + .../ectester/data/composite/composite160_pq2.csv | 1 + .../ectester/data/composite/composite192_pq.csv | 1 + .../ectester/data/composite/composite192_pq1.csv | 1 + .../ectester/data/composite/composite192_pq2.csv | 1 + .../ectester/data/composite/composite224_pq.csv | 1 + .../ectester/data/composite/composite224_pq1.csv | 1 + .../ectester/data/composite/composite224_pq2.csv | 1 + .../ectester/data/composite/composite256_pq.csv | 1 + .../ectester/data/composite/composite256_pq1.csv | 1 + .../ectester/data/composite/composite256_pq2.csv | 1 + src/cz/crcs/ectester/data/composite/curves.xml | 110 +++++++++++++++++++++ .../reader/test/CardCompositeCurvesSuite.java | 50 +++++++--- 18 files changed, 170 insertions(+), 11 deletions(-) create mode 100644 src/cz/crcs/ectester/data/composite/composite128_pq.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite128_pq1.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite128_pq2.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite160_pq.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite160_pq1.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite160_pq2.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite192_pq.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite192_pq1.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite192_pq2.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite224_pq.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite224_pq1.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite224_pq2.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite256_pq.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite256_pq1.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite256_pq2.csv (limited to 'src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java') diff --git a/src/cz/crcs/ectester/data/EC_Store.java b/src/cz/crcs/ectester/data/EC_Store.java index d2c8224..db8371c 100644 --- a/src/cz/crcs/ectester/data/EC_Store.java +++ b/src/cz/crcs/ectester/data/EC_Store.java @@ -327,6 +327,9 @@ public class EC_Store { curveKeys.add(item); curves.putIfAbsent(curve, curveKeys); } + for (List keyList : curves.values()) { + Collections.sort(keyList); + } List>> curveList = new LinkedList<>(); curveList.addAll(curves.entrySet()); Comparator>> c = Comparator.comparing(o -> o.getKey().getBits()); @@ -350,6 +353,9 @@ public class EC_Store { group.add(item); groups.putIfAbsent(prefix, group); } + for (List itemList : groups.values()) { + Collections.sort(itemList); + } List>> result = new LinkedList<>(); result.addAll(groups.entrySet()); result.sort(Comparator.comparing(Map.Entry::getKey)); diff --git a/src/cz/crcs/ectester/data/composite/composite128_pq.csv b/src/cz/crcs/ectester/data/composite/composite128_pq.csv new file mode 100644 index 0000000..8aea6b2 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite128_pq.csv @@ -0,0 +1 @@ +0xee6b3964632807cf11b8b9dba1b4f099,0x1fd6f78c0303652c5b7de184a4744f98,0x2da1b3253571565989f3b72b865a3e27,0x7c23e2a7e80b6586a1f9e1c9d4fbadc2,0xe987ee5eb715e2eb8cc8ad77311cfe0a,0xee6b3964632807cd9c885b5658f1a7c7,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite128_pq1.csv b/src/cz/crcs/ectester/data/composite/composite128_pq1.csv new file mode 100644 index 0000000..a551487 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite128_pq1.csv @@ -0,0 +1 @@ +0xee6b3964632807cf11b8b9dba1b4f099,0x1fd6f78c0303652c5b7de184a4744f98,0x2da1b3253571565989f3b72b865a3e27,0x6ef5b1d42abdbd6f44bcf4d64504927c,0x73e82c27b93032b7a7a15111d1569bb3,0x000000000000000000000003f76917eb,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite128_pq2.csv b/src/cz/crcs/ectester/data/composite/composite128_pq2.csv new file mode 100644 index 0000000..69181df --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite128_pq2.csv @@ -0,0 +1 @@ +0xee6b3964632807cf11b8b9dba1b4f099,0x1fd6f78c0303652c5b7de184a4744f98,0x2da1b3253571565989f3b72b865a3e27,0x73ca0050dff0de43cff4a026d8aa4baa,0xebd7490611fe3886fe5a8083d344edd0,0x000000003c1be1d1dd7edf84b8013495,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite160_pq.csv b/src/cz/crcs/ectester/data/composite/composite160_pq.csv new file mode 100644 index 0000000..3f43b50 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite160_pq.csv @@ -0,0 +1 @@ +0x919cf0a89ca7a8ea2f61156ea4b3100a2a357477,0x75cd1f1c32f1e5d2b2d54db103b22d296de34722,0x3177d3e2f79c884a0b1a6e74d9843c3a52e794de,0x46239bb42c524f45764e8edba8c958203d185886,0x6bce8ab48c9b4d0ab4083122ea9684173f9b07a9,0x919cf0a89ca7a8ea2f626ab2ab86ff4a074a5d51,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite160_pq1.csv b/src/cz/crcs/ectester/data/composite/composite160_pq1.csv new file mode 100644 index 0000000..debd466 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite160_pq1.csv @@ -0,0 +1 @@ +0x919cf0a89ca7a8ea2f61156ea4b3100a2a357477,0x75cd1f1c32f1e5d2b2d54db103b22d296de34722,0x3177d3e2f79c884a0b1a6e74d9843c3a52e794de,0x706deef87d4593bbeaa70bc2609e1d8c0e2e0c10,0x64df2537d395da2e0cb8c7e340426b64699cf325,0x00000000000000000000000af2407f270b81f45f,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite160_pq2.csv b/src/cz/crcs/ectester/data/composite/composite160_pq2.csv new file mode 100644 index 0000000..efd7475 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite160_pq2.csv @@ -0,0 +1 @@ +0x919cf0a89ca7a8ea2f61156ea4b3100a2a357477,0x75cd1f1c32f1e5d2b2d54db103b22d296de34722,0x3177d3e2f79c884a0b1a6e74d9843c3a52e794de,0x0818df9ccebf5b3fd422d00393d346b314e48f98,0x75bde540b81b5bf0ab45c86fbff7bb2e7ec833cb,0x00000000000000000d4d7041e1dbf10b42f48c4f,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite192_pq.csv b/src/cz/crcs/ectester/data/composite/composite192_pq.csv new file mode 100644 index 0000000..47b8a13 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite192_pq.csv @@ -0,0 +1 @@ +0xa261fff62647eebf810a404f0c80a971dd7c7838fdc52b5b,0x87502ebb62d26e1eca06c434f8ef069dfb2c287d6183750c,0x4ad6ce1f16e1bfc3d40f0027d787aeadb53846d69099a883,0x253e1db7210418abfe1de82c0053098e90bb15ad4f20096f,0x962c565cb0dd62b6a04be33ec7b20a1b3e7f23e24d48c6c2,0xa261fff62647eebf810a404f23ba4db93199e2e02ccffdfd,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite192_pq1.csv b/src/cz/crcs/ectester/data/composite/composite192_pq1.csv new file mode 100644 index 0000000..664d35e --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite192_pq1.csv @@ -0,0 +1 @@ +0xa261fff62647eebf810a404f0c80a971dd7c7838fdc52b5b,0x87502ebb62d26e1eca06c434f8ef069dfb2c287d6183750c,0x4ad6ce1f16e1bfc3d40f0027d787aeadb53846d69099a883,0x6366613b66339fa580f390d630ccf9b535437229aa8b61cd,0x2abab8c0e803a3612c7a7fbcb47e06fd8ef42a7a7d8c380f,0x00000000000000000000000000302b72431ff070e7e06799,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite192_pq2.csv b/src/cz/crcs/ectester/data/composite/composite192_pq2.csv new file mode 100644 index 0000000..41f4610 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite192_pq2.csv @@ -0,0 +1 @@ +0xa261fff62647eebf810a404f0c80a971dd7c7838fdc52b5b,0x87502ebb62d26e1eca06c434f8ef069dfb2c287d6183750c,0x4ad6ce1f16e1bfc3d40f0027d787aeadb53846d69099a883,0x6366613b66339fa580f390d630ccf9b535437229aa8b61cd,0x1b975fa3848bd68f34f6a08b7cf190bcaeaf9782270e2413,0x00000000000000000000035efd8bad55038e6bd22db8b805,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite224_pq.csv b/src/cz/crcs/ectester/data/composite/composite224_pq.csv new file mode 100644 index 0000000..ffa2cc1 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite224_pq.csv @@ -0,0 +1 @@ +0xa0dccd401872aa37c279e2469a08d97d559addb6fc870a1766f80e6f,0x393797f1d924dc63c761d4497086d09284a922a5517c07f93f3a075c,0x54f4673322854dafc1241b66192134ea9e18f8849c45660b793abb97,0x4f3b94b4e9234f3611bfe74d69ad06178e06c5f56fa100233f0d43e1,0x0eb042a295465c53ca6e01ff8c2cf4d029bf6d4a646fed830468d73a,0xa0dccd401872aa37c279e2469a0791ea2f15e32a10632ec07cf3ff97,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite224_pq1.csv b/src/cz/crcs/ectester/data/composite/composite224_pq1.csv new file mode 100644 index 0000000..6a01e2d --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite224_pq1.csv @@ -0,0 +1 @@ +0xa0dccd401872aa37c279e2469a08d97d559addb6fc870a1766f80e6f,0x393797f1d924dc63c761d4497086d09284a922a5517c07f93f3a075c,0x54f4673322854dafc1241b66192134ea9e18f8849c45660b793abb97,0x1b189f3372946c9cbb421a60bc3a0a06d16cf3ce043781ada561834c,0x57e00f270dbc56c6c86946dcb6c6ab12133d168609c588b6960c357f,0x00000000000000000000000000000000001824ec370e405bfb5024db,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite224_pq2.csv b/src/cz/crcs/ectester/data/composite/composite224_pq2.csv new file mode 100644 index 0000000..f8bc6df --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite224_pq2.csv @@ -0,0 +1 @@ +0xa0dccd401872aa37c279e2469a08d97d559addb6fc870a1766f80e6f,0x393797f1d924dc63c761d4497086d09284a922a5517c07f93f3a075c,0x54f4673322854dafc1241b66192134ea9e18f8849c45660b793abb97,0x97e540c8fc6f9603f25b1689895e5fe738565013675b1bd6c0e16a4b,0x66d0bbe7ee9b0e9e7e1d43b6a47e1d5550c696433c58ee06b94e8615,0x0000000000000000000006a99de2a928e8f227e7a2ed33a555f24ef5,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite256_pq.csv b/src/cz/crcs/ectester/data/composite/composite256_pq.csv new file mode 100644 index 0000000..8a59520 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite256_pq.csv @@ -0,0 +1 @@ +0xf75e78a6e2acb23d6317e57258287c00597e24881e0686039d0badb77b4e6b21,0x1aafadea1da31b45bbc02da735cc341f9cf9915884eb9cd31441520ead906b38,0x0f7f209988b0eada7190201ace3b3972d6ce3cbadac9933716d08645a7c31c63,0x4c4765a35cb2de9cc548d4dd47778b70395d023c4bf112f4bc820431502384e9,0x25bffa1f9ae1af10177f32abf13d3f607e78415c89676eeb13330098c9794503,0xf75e78a6e2acb23d6317e57258287c021fa26f10c359320ee8758b4e1f2c605d,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite256_pq1.csv b/src/cz/crcs/ectester/data/composite/composite256_pq1.csv new file mode 100644 index 0000000..8012893 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite256_pq1.csv @@ -0,0 +1 @@ +0xf75e78a6e2acb23d6317e57258287c00597e24881e0686039d0badb77b4e6b21,0x1aafadea1da31b45bbc02da735cc341f9cf9915884eb9cd31441520ead906b38,0x0f7f209988b0eada7190201ace3b3972d6ce3cbadac9933716d08645a7c31c63,0x93d1f4d02d6f0d2ea7b80f7095e70e731bcf66fb8118e7698a16eab45aadcaa4,0x51dccaa47e35062383e4878625bf2116be5413c34a1b964c7547f65297f0bc04,0x743bc7ea193d40db,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite256_pq2.csv b/src/cz/crcs/ectester/data/composite/composite256_pq2.csv new file mode 100644 index 0000000..25b57af --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite256_pq2.csv @@ -0,0 +1 @@ +0xf75e78a6e2acb23d6317e57258287c00597e24881e0686039d0badb77b4e6b21,0x1aafadea1da31b45bbc02da735cc341f9cf9915884eb9cd31441520ead906b38,0x0f7f209988b0eada7190201ace3b3972d6ce3cbadac9933716d08645a7c31c63,0x93d1f4d02d6f0d2ea7b80f7095e70e731bcf66fb8118e7698a16eab45aadcaa4,0x3db7c6ee2d24d142ee0ec56f3ba0a606d099debb66a765e3926a5aa19539a2c3,0x220d23234534b240aac0efa70a3bc44e046c2431ad5a32d27,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/curves.xml b/src/cz/crcs/ectester/data/composite/curves.xml index a1abe2e..1eddbea 100644 --- a/src/cz/crcs/ectester/data/composite/curves.xml +++ b/src/cz/crcs/ectester/data/composite/curves.xml @@ -100,4 +100,114 @@ composite521_small.csv r = 0x05 + + + pq/composite128 + 128 + prime + composite128_pq.csv + r = 0x03f76917eb * 0x3c1be1d1dd7edf84b8013495 + + + pq/composite128/1 + 128 + prime + composite128_pq1.csv + r = 0x03f76917eb + + + pq/composite128/2 + 128 + prime + composite128_pq2.csv + r = 0x3c1be1d1dd7edf84b8013495 + + + + pq/composite160 + 160 + prime + composite160_pq.csv + r = 0x0af2407f270b81f45f * 0x4d7041e1dbf10b42f48c4f + + + pq/composite160/1 + 160 + prime + composite160_pq1.csv + r = 0x0af2407f270b81f45f + + + pq/composite160/2 + 160 + prime + composite160_pq2.csv + r = 0x4d7041e1dbf10b42f48c4f + + + + pq/composite192 + 192 + prime + composite192_pq.csv + r = 0x302b72431ff070e7e06799 * 0x35efd8bad55038e6bd22db8b805 + + + pq/composite192/1 + 192 + prime + composite192_pq1.csv + r = 0x302b72431ff070e7e06799 + + + pq/composite192/2 + 192 + prime + composite192_pq2.csv + r = 0x35efd8bad55038e6bd22db8b805 + + + + pq/composite224 + 224 + prime + composite224_pq.csv + r = 0x1824ec370e405bfb5024db * 0x6a99de2a928e8f227e7a2ed33a555f24ef5 + + + pq/composite224/1 + 224 + prime + composite224_pq1.csv + r = 0x1824ec370e405bfb5024db + + + pq/composite224/2 + 224 + prime + composite224_pq2.csv + r = 0x6a99de2a928e8f227e7a2ed33a555f24ef5 + + + + pq/composite256 + 256 + prime + composite256_pq.csv + r = 0x743bc7ea193d40db * 0x220d23234534b240aac0efa70a3bc44e046c2431ad5a32d27 + + + pq/composite256/1 + 256 + prime + composite256_pq1.csv + r = 0x743bc7ea193d40db + + + pq/composite256/2 + 256 + prime + composite256_pq2.csv + r = 0x220d23234534b240aac0efa70a3bc44e046c2431ad5a32d27 + \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java index d186b4a..d474638 100644 --- a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java @@ -8,11 +8,13 @@ import cz.crcs.ectester.common.ec.EC_Key; import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.CompoundTest; import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.util.CardUtil; 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 java.util.LinkedList; import java.util.List; import java.util.Map; @@ -36,15 +38,25 @@ public class CardCompositeCurvesSuite extends CardTestSuite { * is revealed. */ Map keys = EC_Store.getInstance().getObjects(EC_Key.class, "composite"); - for (EC_Key key : keys.values()) { - EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, key.getCurve()); - Test allocate = CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_LOCAL, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS); - Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY); - Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY); - 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."); + List>> mappedKeys = EC_Store.mapKeyToCurve(keys.values()); + for (Map.Entry> curveKeys : mappedKeys) { + EC_Curve curve = curveKeys.getKey(); + List tests = new LinkedList<>(); + Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_LOCAL, 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; + } + tests.add(allocate); + for (EC_Key key : curveKeys.getValue()) { + Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY); + Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY); + 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."); - doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", " + key.getDesc(), allocate, set, generate, ecdh)); + tests.add(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", " + key.getDesc(), set, generate, ecdh)); + } + doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ".", tests.toArray(new Test[0]))); new Command.Cleanup(this.card).send(); } @@ -53,14 +65,30 @@ public class CardCompositeCurvesSuite extends CardTestSuite { Map results = EC_Store.getInstance().getObjects(EC_Curve.class, "composite"); List>> groupList = EC_Store.mapToPrefix(results.values()); List smallRCurves = groupList.stream().filter((e) -> e.getKey().equals("small")).findFirst().get().getValue(); - for (EC_Curve curve : smallRCurves) { + testGroup(smallRCurves, "Small generator order", ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a small order generator.", "Card incorrectly does ECDH over a small order generator."); + + /* Also test having a G of large but composite order, R = p * q, + */ + List pqCurves = groupList.stream().filter((e) -> e.getKey().equals("pq")).findFirst().get().getValue(); + testGroup(pqCurves, null, ExpectedValue.ANY, "", ""); + } + + private void testGroup(List curves, String testName, ExpectedValue dhValue, String ok, String nok) throws Exception { + for (EC_Curve curve : curves) { 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.ANY); Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.ANY); - Test ecdh = 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), ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a small order generator.", "Card incorrectly does ECDH over a small order generator."); + Test ecdh = 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), dhValue, ok, nok); - doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Small generator order test of " + curve.getId() + ".", allocate, set, generate, ecdh)); + String description; + if (testName == null) { + description = curve.getDesc() + " test of " + curve.getId() + "."; + } else { + description = testName + " test of " + curve.getId() + "."; + } + doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, description, allocate, set, generate, ecdh)); new Command.Cleanup(this.card).send(); } + } } -- cgit v1.2.3-70-g09d2 From 632ba7f154bd90b3528ed39b2bc01cb2cfa10dd0 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 30 Jun 2018 18:27:41 +0200 Subject: Add more composite tests. --- docs/TESTS.md | 5 ++- .../ectester/data/composite/composite128_rg0.csv | 1 + .../ectester/data/composite/composite160_rg0.csv | 1 + .../ectester/data/composite/composite192_rg0.csv | 1 + .../ectester/data/composite/composite224_rg0.csv | 1 + .../ectester/data/composite/composite256_pq.csv | 2 +- .../ectester/data/composite/composite256_pq1.csv | 2 +- .../ectester/data/composite/composite256_pq2.csv | 2 +- .../ectester/data/composite/composite256_rg0.csv | 1 + .../ectester/data/composite/composite256_small.csv | 2 +- .../crcs/ectester/data/composite/composite384.csv | 2 +- .../ectester/data/composite/composite384_small.csv | 2 +- .../crcs/ectester/data/composite/composite521.csv | 2 +- .../ectester/data/composite/composite521_small.csv | 2 +- src/cz/crcs/ectester/data/composite/curves.xml | 40 ++++++++++++++++++++++ .../reader/test/CardCompositeCurvesSuite.java | 6 +++- 16 files changed, 62 insertions(+), 10 deletions(-) create mode 100644 src/cz/crcs/ectester/data/composite/composite128_rg0.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite160_rg0.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite192_rg0.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite224_rg0.csv create mode 100644 src/cz/crcs/ectester/data/composite/composite256_rg0.csv (limited to 'src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java') diff --git a/docs/TESTS.md b/docs/TESTS.md index c62234b..59bd27b 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -59,7 +59,7 @@ Tests on a category of wrong curves. These curves are not really curves as they - non-prime field in the prime-field case - reducible polynomial as the field polynomial in the binary case -This test suite also does some additional tests with corrupting the field parameter: +This test suite also does some additional tests with corrupting the parameters: - Fp: - p = 0 - p = 1 @@ -87,6 +87,9 @@ Tests using curves that don't have a prime order/nearly prime order. These tests should generally fail, a success here implies the card will use a non-secure curve if such curve is set by the applet. Operations over such curves are susceptible to small-subgroup attacks. + - r = p * q + - \[r\]G = infinity but r != |G|, so |G| divides r + For example: ```bash java -jar ECTester.jar -t composite diff --git a/src/cz/crcs/ectester/data/composite/composite128_rg0.csv b/src/cz/crcs/ectester/data/composite/composite128_rg0.csv new file mode 100644 index 0000000..2e039f4 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite128_rg0.csv @@ -0,0 +1 @@ +0xee6b3964632807cf11b8b9dba1b4f099,0x1fd6f78c0303652c5b7de184a4744f98,0x2da1b3253571565989f3b72b865a3e27,0x6ef5b1d42abdbd6f44bcf4d64504927c,0x73e82c27b93032b7a7a15111d1569bb3,0xee6b3964632807cd9c885b5658f1a7c7,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite160_rg0.csv b/src/cz/crcs/ectester/data/composite/composite160_rg0.csv new file mode 100644 index 0000000..e6a1a95 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite160_rg0.csv @@ -0,0 +1 @@ +0x919cf0a89ca7a8ea2f61156ea4b3100a2a357477,0x75cd1f1c32f1e5d2b2d54db103b22d296de34722,0x3177d3e2f79c884a0b1a6e74d9843c3a52e794de,0x706deef87d4593bbeaa70bc2609e1d8c0e2e0c10,0x64df2537d395da2e0cb8c7e340426b64699cf325,0x919cf0a89ca7a8ea2f626ab2ab86ff4a074a5d51,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite192_rg0.csv b/src/cz/crcs/ectester/data/composite/composite192_rg0.csv new file mode 100644 index 0000000..a55a994 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite192_rg0.csv @@ -0,0 +1 @@ +0xa261fff62647eebf810a404f0c80a971dd7c7838fdc52b5b,0x87502ebb62d26e1eca06c434f8ef069dfb2c287d6183750c,0x4ad6ce1f16e1bfc3d40f0027d787aeadb53846d69099a883,0x6366613b66339fa580f390d630ccf9b535437229aa8b61cd,0x2abab8c0e803a3612c7a7fbcb47e06fd8ef42a7a7d8c380f,0xa261fff62647eebf810a404f23ba4db93199e2e02ccffdfd,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite224_rg0.csv b/src/cz/crcs/ectester/data/composite/composite224_rg0.csv new file mode 100644 index 0000000..835676d --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite224_rg0.csv @@ -0,0 +1 @@ +0xa0dccd401872aa37c279e2469a08d97d559addb6fc870a1766f80e6f,0x393797f1d924dc63c761d4497086d09284a922a5517c07f93f3a075c,0x54f4673322854dafc1241b66192134ea9e18f8849c45660b793abb97,0x1b189f3372946c9cbb421a60bc3a0a06d16cf3ce043781ada561834c,0x57e00f270dbc56c6c86946dcb6c6ab12133d168609c588b6960c357f,0xa0dccd401872aa37c279e2469a0791ea2f15e32a10632ec07cf3ff97,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite256_pq.csv b/src/cz/crcs/ectester/data/composite/composite256_pq.csv index 8a59520..380f756 100644 --- a/src/cz/crcs/ectester/data/composite/composite256_pq.csv +++ b/src/cz/crcs/ectester/data/composite/composite256_pq.csv @@ -1 +1 @@ -0xf75e78a6e2acb23d6317e57258287c00597e24881e0686039d0badb77b4e6b21,0x1aafadea1da31b45bbc02da735cc341f9cf9915884eb9cd31441520ead906b38,0x0f7f209988b0eada7190201ace3b3972d6ce3cbadac9933716d08645a7c31c63,0x4c4765a35cb2de9cc548d4dd47778b70395d023c4bf112f4bc820431502384e9,0x25bffa1f9ae1af10177f32abf13d3f607e78415c89676eeb13330098c9794503,0xf75e78a6e2acb23d6317e57258287c021fa26f10c359320ee8758b4e1f2c605d,0x1 \ No newline at end of file +0xf75e78a6e2acb23d6317e57258287c00597e24881e0686039d0badb77b4e6b21,0x1aafadea1da31b45bbc02da735cc341f9cf9915884eb9cd31441520ead906b38,0x0f7f209988b0eada7190201ace3b3972d6ce3cbadac9933716d08645a7c31c63,0x4c4765a35cb2de9cc548d4dd47778b70395d023c4bf112f4bc820431502384e9,0x25bffa1f9ae1af10177f32abf13d3f607e78415c89676eeb13330098c9794503,0xf75e78a6e2acb23d6317e57258287c021fa26f10c359320ee8758b4e1f2c605d,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite256_pq1.csv b/src/cz/crcs/ectester/data/composite/composite256_pq1.csv index 8012893..e3d5b42 100644 --- a/src/cz/crcs/ectester/data/composite/composite256_pq1.csv +++ b/src/cz/crcs/ectester/data/composite/composite256_pq1.csv @@ -1 +1 @@ -0xf75e78a6e2acb23d6317e57258287c00597e24881e0686039d0badb77b4e6b21,0x1aafadea1da31b45bbc02da735cc341f9cf9915884eb9cd31441520ead906b38,0x0f7f209988b0eada7190201ace3b3972d6ce3cbadac9933716d08645a7c31c63,0x93d1f4d02d6f0d2ea7b80f7095e70e731bcf66fb8118e7698a16eab45aadcaa4,0x51dccaa47e35062383e4878625bf2116be5413c34a1b964c7547f65297f0bc04,0x743bc7ea193d40db,0x1 \ No newline at end of file +0xf75e78a6e2acb23d6317e57258287c00597e24881e0686039d0badb77b4e6b21,0x1aafadea1da31b45bbc02da735cc341f9cf9915884eb9cd31441520ead906b38,0x0f7f209988b0eada7190201ace3b3972d6ce3cbadac9933716d08645a7c31c63,0x93d1f4d02d6f0d2ea7b80f7095e70e731bcf66fb8118e7698a16eab45aadcaa4,0x51dccaa47e35062383e4878625bf2116be5413c34a1b964c7547f65297f0bc04,0x000000000000000000000000000000000000000000000000743bc7ea193d40db,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite256_pq2.csv b/src/cz/crcs/ectester/data/composite/composite256_pq2.csv index 25b57af..c67eaa7 100644 --- a/src/cz/crcs/ectester/data/composite/composite256_pq2.csv +++ b/src/cz/crcs/ectester/data/composite/composite256_pq2.csv @@ -1 +1 @@ -0xf75e78a6e2acb23d6317e57258287c00597e24881e0686039d0badb77b4e6b21,0x1aafadea1da31b45bbc02da735cc341f9cf9915884eb9cd31441520ead906b38,0x0f7f209988b0eada7190201ace3b3972d6ce3cbadac9933716d08645a7c31c63,0x93d1f4d02d6f0d2ea7b80f7095e70e731bcf66fb8118e7698a16eab45aadcaa4,0x3db7c6ee2d24d142ee0ec56f3ba0a606d099debb66a765e3926a5aa19539a2c3,0x220d23234534b240aac0efa70a3bc44e046c2431ad5a32d27,0x1 \ No newline at end of file +0xf75e78a6e2acb23d6317e57258287c00597e24881e0686039d0badb77b4e6b21,0x1aafadea1da31b45bbc02da735cc341f9cf9915884eb9cd31441520ead906b38,0x0f7f209988b0eada7190201ace3b3972d6ce3cbadac9933716d08645a7c31c63,0x93d1f4d02d6f0d2ea7b80f7095e70e731bcf66fb8118e7698a16eab45aadcaa4,0x3db7c6ee2d24d142ee0ec56f3ba0a606d099debb66a765e3926a5aa19539a2c3,0x000000000000000220d23234534b240aac0efa70a3bc44e046c2431ad5a32d27,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite256_rg0.csv b/src/cz/crcs/ectester/data/composite/composite256_rg0.csv new file mode 100644 index 0000000..0c2d123 --- /dev/null +++ b/src/cz/crcs/ectester/data/composite/composite256_rg0.csv @@ -0,0 +1 @@ +0xf75e78a6e2acb23d6317e57258287c00597e24881e0686039d0badb77b4e6b21,0x1aafadea1da31b45bbc02da735cc341f9cf9915884eb9cd31441520ead906b38,0x0f7f209988b0eada7190201ace3b3972d6ce3cbadac9933716d08645a7c31c63,0x93d1f4d02d6f0d2ea7b80f7095e70e731bcf66fb8118e7698a16eab45aadcaa4,0x51dccaa47e35062383e4878625bf2116be5413c34a1b964c7547f65297f0bc04,0xf75e78a6e2acb23d6317e57258287c021fa26f10c359320ee8758b4e1f2c605d,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite256_small.csv b/src/cz/crcs/ectester/data/composite/composite256_small.csv index a28e62e..58c0a75 100644 --- a/src/cz/crcs/ectester/data/composite/composite256_small.csv +++ b/src/cz/crcs/ectester/data/composite/composite256_small.csv @@ -1 +1 @@ -0xdc42862158cdcfc8fbe8c4ec28b02e0e12624ebc15f6486163df218253e1b953,0x01f355375dac7e69cc12c22ce747782bf998252f1c9c9c983273bc2b7e721461,0x22098140e10d5d88bcc96a558500a022d0252bfbe438d3475ef2d90261fe3b1f,0x8ca20dd1fa045339a171513fb1daa25fa7439e4b97c129c6039e4b9abbac1532,0xb565bde8fe9831f0bce07d70784dc1b7064c443b54b5e96408c1942e30437cc3,0x0000000000000000000000000000000000000000000000000000000000000005,0x1 \ No newline at end of file +0xdc42862158cdcfc8fbe8c4ec28b02e0e12624ebc15f6486163df218253e1b953,0x01f355375dac7e69cc12c22ce747782bf998252f1c9c9c983273bc2b7e721461,0x22098140e10d5d88bcc96a558500a022d0252bfbe438d3475ef2d90261fe3b1f,0x8ca20dd1fa045339a171513fb1daa25fa7439e4b97c129c6039e4b9abbac1532,0xb565bde8fe9831f0bce07d70784dc1b7064c443b54b5e96408c1942e30437cc3,0x0000000000000000000000000000000000000000000000000000000000000005,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite384.csv b/src/cz/crcs/ectester/data/composite/composite384.csv index 7516301..4e9d058 100644 --- a/src/cz/crcs/ectester/data/composite/composite384.csv +++ b/src/cz/crcs/ectester/data/composite/composite384.csv @@ -1 +1 @@ -0x91520c5e44d7a5e9c673943d2fc502d2b35a1c9edc6189da10277423d7381fd4671fc706ff1dce6f8513317842fb655b,0x6c64adff869b4e0b9f0dd35945b24e3ab389232b1e506a71306e389dddbf43ec6c73d290fab04976da246fd77a7e28dd,0x4004c33e4f8b4de57064543802ca11810c79aa9990796d5750dba07f3e4e98f3dd18b3abe052208741149c3ad0fe6f56,0x39bf2e7d67ad506e074e04c1b73a4add511b0579cdae07bd6c025c703ee31ff33c0445c2cb10e465f0f453d996751e4e,0x667ec38866be3e87229e31e6dabc2444e2603e8118c0316e592571e9a904423e4792c18c0360ae57fcdaec87901d2e0b,0x91520c5e44d7a5e9c673943d2fc502d2b35a1c9edc6189db347c42a7d0924b7cd1414d57f582a4b96177c911e9bb3ddd,0x1 \ No newline at end of file +0x91520c5e44d7a5e9c673943d2fc502d2b35a1c9edc6189da10277423d7381fd4671fc706ff1dce6f8513317842fb655b,0x6c64adff869b4e0b9f0dd35945b24e3ab389232b1e506a71306e389dddbf43ec6c73d290fab04976da246fd77a7e28dd,0x4004c33e4f8b4de57064543802ca11810c79aa9990796d5750dba07f3e4e98f3dd18b3abe052208741149c3ad0fe6f56,0x39bf2e7d67ad506e074e04c1b73a4add511b0579cdae07bd6c025c703ee31ff33c0445c2cb10e465f0f453d996751e4e,0x667ec38866be3e87229e31e6dabc2444e2603e8118c0316e592571e9a904423e4792c18c0360ae57fcdaec87901d2e0b,0x91520c5e44d7a5e9c673943d2fc502d2b35a1c9edc6189db347c42a7d0924b7cd1414d57f582a4b96177c911e9bb3ddd,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite384_small.csv b/src/cz/crcs/ectester/data/composite/composite384_small.csv index 470704d..00b643b 100644 --- a/src/cz/crcs/ectester/data/composite/composite384_small.csv +++ b/src/cz/crcs/ectester/data/composite/composite384_small.csv @@ -1 +1 @@ -0x91520c5e44d7a5e9c673943d2fc502d2b35a1c9edc6189da10277423d7381fd4671fc706ff1dce6f8513317842fb655b,0x6c64adff869b4e0b9f0dd35945b24e3ab389232b1e506a71306e389dddbf43ec6c73d290fab04976da246fd77a7e28dd,0x4004c33e4f8b4de57064543802ca11810c79aa9990796d5750dba07f3e4e98f3dd18b3abe052208741149c3ad0fe6f56,0x5136c182f03241ec87e6eec1728c1fb2d6b2ddcd4d9abf2a110c337419c4ec7cc8386b7b9ea9f5cb18b0f3c2a78e6489,0x9130cb73f8064fddb24d8c6a216b57fe99df93bcc82c93343617a5246ca1643fe57a06d6112a1791d1bd3643fbd9c041,0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005,0x1 \ No newline at end of file +0x91520c5e44d7a5e9c673943d2fc502d2b35a1c9edc6189da10277423d7381fd4671fc706ff1dce6f8513317842fb655b,0x6c64adff869b4e0b9f0dd35945b24e3ab389232b1e506a71306e389dddbf43ec6c73d290fab04976da246fd77a7e28dd,0x4004c33e4f8b4de57064543802ca11810c79aa9990796d5750dba07f3e4e98f3dd18b3abe052208741149c3ad0fe6f56,0x5136c182f03241ec87e6eec1728c1fb2d6b2ddcd4d9abf2a110c337419c4ec7cc8386b7b9ea9f5cb18b0f3c2a78e6489,0x9130cb73f8064fddb24d8c6a216b57fe99df93bcc82c93343617a5246ca1643fe57a06d6112a1791d1bd3643fbd9c041,0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite521.csv b/src/cz/crcs/ectester/data/composite/composite521.csv index 0cf36e7..8681273 100644 --- a/src/cz/crcs/ectester/data/composite/composite521.csv +++ b/src/cz/crcs/ectester/data/composite/composite521.csv @@ -1 +1 @@ -0x01c230ff4a64e33ad6da8361c7e2bf2a85e4ad5e88f8e3e8e7e3c42a6b9c9883b3690e2f82b38a684e823a257b3d5c4c2d7c34bfcb937fe5658c77247b28bc90c6af,0x00852cf32173a9b3a8a2316bbe6ba0b98efcc41247a17a8aead02ccc7cb90870daccd10a44e9385abf0d0ae175fa03c0facab1d2069b79795f36d10ce25430676805,0x0174e20e49d5970117cdfc61c0a0ae062519c0c4d577f42e0d3f1cd443732b8e62deb34922a4a6d85b8b7f6df61dadffec95c17babbfaf5c57598033be0b1a44e32f,0x01b1dbc5bd175cbd8699895698b10d047853679f048261094854134de1d6a81ffdd1cc31ede64293c9bee543ad2113c164bd1da92f5c3aa7ba7f0378bdb58251d870,0x0188b8c020cc1504eedb4fb859e40b8031cb26d9273efa2578bf7da01db994cf2a5cf2780b9a7ff6d33210b962ae20c56f71b7fa2b36deef33d7d675c6136acd73c1,0x1c230ff4a64e33ad6da8361c7e2bf2a85e4ad5e88f8e3e8e7e3c42a6b9c9883b36ec447771e871c188d3f04a4e407f1d659335dd0e351bd7f3f76a639726d6dc0d2,0x1 \ No newline at end of file +0x01c230ff4a64e33ad6da8361c7e2bf2a85e4ad5e88f8e3e8e7e3c42a6b9c9883b3690e2f82b38a684e823a257b3d5c4c2d7c34bfcb937fe5658c77247b28bc90c6af,0x00852cf32173a9b3a8a2316bbe6ba0b98efcc41247a17a8aead02ccc7cb90870daccd10a44e9385abf0d0ae175fa03c0facab1d2069b79795f36d10ce25430676805,0x0174e20e49d5970117cdfc61c0a0ae062519c0c4d577f42e0d3f1cd443732b8e62deb34922a4a6d85b8b7f6df61dadffec95c17babbfaf5c57598033be0b1a44e32f,0x01b1dbc5bd175cbd8699895698b10d047853679f048261094854134de1d6a81ffdd1cc31ede64293c9bee543ad2113c164bd1da92f5c3aa7ba7f0378bdb58251d870,0x0188b8c020cc1504eedb4fb859e40b8031cb26d9273efa2578bf7da01db994cf2a5cf2780b9a7ff6d33210b962ae20c56f71b7fa2b36deef33d7d675c6136acd73c1,0x1c230ff4a64e33ad6da8361c7e2bf2a85e4ad5e88f8e3e8e7e3c42a6b9c9883b36ec447771e871c188d3f04a4e407f1d659335dd0e351bd7f3f76a639726d6dc0d2,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/composite521_small.csv b/src/cz/crcs/ectester/data/composite/composite521_small.csv index f065b9f..15df9c8 100644 --- a/src/cz/crcs/ectester/data/composite/composite521_small.csv +++ b/src/cz/crcs/ectester/data/composite/composite521_small.csv @@ -1 +1 @@ -0x01c230ff4a64e33ad6da8361c7e2bf2a85e4ad5e88f8e3e8e7e3c42a6b9c9883b3690e2f82b38a684e823a257b3d5c4c2d7c34bfcb937fe5658c77247b28bc90c6af,0x00852cf32173a9b3a8a2316bbe6ba0b98efcc41247a17a8aead02ccc7cb90870daccd10a44e9385abf0d0ae175fa03c0facab1d2069b79795f36d10ce25430676805,0x0174e20e49d5970117cdfc61c0a0ae062519c0c4d577f42e0d3f1cd443732b8e62deb34922a4a6d85b8b7f6df61dadffec95c17babbfaf5c57598033be0b1a44e32f,0x00a4b42ad90c0e3f7e342d8d661b4d5162ab7928b4938ab660b2e6fea3213c5d4b420123f65141a8eb7b4a46173bfce6ea1577df94f6f934f72d459c4dd3c0ef038e,0x003316c4b6c5c6b3ab3eee7f1ff365cce6045fdc43d4e6c64efa7789f2626676b47b488e6612d291d60d4a788ddd2e8b1aa8bfff02e105a285532a20ac08fa1088e7,0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005,0x1 \ No newline at end of file +0x01c230ff4a64e33ad6da8361c7e2bf2a85e4ad5e88f8e3e8e7e3c42a6b9c9883b3690e2f82b38a684e823a257b3d5c4c2d7c34bfcb937fe5658c77247b28bc90c6af,0x00852cf32173a9b3a8a2316bbe6ba0b98efcc41247a17a8aead02ccc7cb90870daccd10a44e9385abf0d0ae175fa03c0facab1d2069b79795f36d10ce25430676805,0x0174e20e49d5970117cdfc61c0a0ae062519c0c4d577f42e0d3f1cd443732b8e62deb34922a4a6d85b8b7f6df61dadffec95c17babbfaf5c57598033be0b1a44e32f,0x00a4b42ad90c0e3f7e342d8d661b4d5162ab7928b4938ab660b2e6fea3213c5d4b420123f65141a8eb7b4a46173bfce6ea1577df94f6f934f72d459c4dd3c0ef038e,0x003316c4b6c5c6b3ab3eee7f1ff365cce6045fdc43d4e6c64efa7789f2626676b47b488e6612d291d60d4a788ddd2e8b1aa8bfff02e105a285532a20ac08fa1088e7,0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005,0x01 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/composite/curves.xml b/src/cz/crcs/ectester/data/composite/curves.xml index 1eddbea..8cec330 100644 --- a/src/cz/crcs/ectester/data/composite/curves.xml +++ b/src/cz/crcs/ectester/data/composite/curves.xml @@ -123,6 +123,14 @@ r = 0x3c1be1d1dd7edf84b8013495 + + rg0/composite128 + 128 + prime + composite128_rg0.csv + |G| divides r(so [r]G = infinity), but r != |G| = 0x03f76917eb + + pq/composite160 160 @@ -145,6 +153,14 @@ r = 0x4d7041e1dbf10b42f48c4f + + rg0/composite160 + 160 + prime + composite160_rg0.csv + |G| divides r(so [r]G = infinity), but r != |G| = 0x0af2407f270b81f45f + + pq/composite192 192 @@ -166,6 +182,14 @@ composite192_pq2.csv r = 0x35efd8bad55038e6bd22db8b805 + + + rg0/composite192 + 192 + prime + composite192_rg0.csv + |G| divides r(so [r]G = infinity), but r != |G| = 0x302b72431ff070e7e06799 + pq/composite224 @@ -189,6 +213,14 @@ r = 0x6a99de2a928e8f227e7a2ed33a555f24ef5 + + rg0/composite224 + 224 + prime + composite224_rg0.csv + |G| divides r(so [r]G = infinity), but r != |G| = 0x1824ec370e405bfb5024db + + pq/composite256 256 @@ -210,4 +242,12 @@ composite256_pq2.csv r = 0x220d23234534b240aac0efa70a3bc44e046c2431ad5a32d27 + + + rg0/composite256 + 256 + prime + composite256_rg0.csv + |G| divides r(so [r]G = infinity), but r != |G| = 0x743bc7ea193d40db + \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java index d474638..2b3724c 100644 --- a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java @@ -3,7 +3,6 @@ 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_KAResult; import cz.crcs.ectester.common.ec.EC_Key; import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.CompoundTest; @@ -71,6 +70,11 @@ public class CardCompositeCurvesSuite extends CardTestSuite { */ List pqCurves = groupList.stream().filter((e) -> e.getKey().equals("pq")).findFirst().get().getValue(); testGroup(pqCurves, null, ExpectedValue.ANY, "", ""); + + /* Also test rg0 curves. + */ + List rg0Curves = groupList.stream().filter((e) -> e.getKey().equals("rg0")).findFirst().get().getValue(); + testGroup(rg0Curves, null, ExpectedValue.ANY, "", ""); } private void testGroup(List curves, String testName, ExpectedValue dhValue, String ok, String nok) throws Exception { -- cgit v1.2.3-70-g09d2 From 50244cd3ff01ad997b5900883ffbc95dbba1154f Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 4 Jul 2018 17:00:05 +0200 Subject: Add supersingular curves, do some tests over supersingular and Barreto-Naehrig curves. --- docs/CURVES.md | 6 + docs/TESTS.md | 9 + src/cz/crcs/ectester/data/categories.xml | 5 + src/cz/crcs/ectester/data/supersingular/curves.xml | 32 ++++ src/cz/crcs/ectester/data/supersingular/ss128.csv | 1 + src/cz/crcs/ectester/data/supersingular/ss192.csv | 1 + src/cz/crcs/ectester/data/supersingular/ss224.csv | 1 + src/cz/crcs/ectester/data/supersingular/ss256.csv | 1 + src/cz/crcs/ectester/reader/ECTesterReader.java | 28 +-- .../reader/test/CardCompositeCurvesSuite.java | 98 ---------- .../ectester/reader/test/CardCompositeSuite.java | 98 ++++++++++ .../reader/test/CardDegenerateCurvesSuite.java | 55 ------ .../ectester/reader/test/CardDegenerateSuite.java | 55 ++++++ .../reader/test/CardInvalidCurvesSuite.java | 75 -------- .../ectester/reader/test/CardInvalidSuite.java | 75 ++++++++ .../crcs/ectester/reader/test/CardMiscSuite.java | 54 ++++++ .../crcs/ectester/reader/test/CardTwistSuite.java | 69 +++++++ .../ectester/reader/test/CardTwistTestSuite.java | 69 ------- .../ectester/reader/test/CardWrongCurvesSuite.java | 203 --------------------- .../crcs/ectester/reader/test/CardWrongSuite.java | 203 +++++++++++++++++++++ 20 files changed, 626 insertions(+), 512 deletions(-) create mode 100644 src/cz/crcs/ectester/data/supersingular/curves.xml create mode 100644 src/cz/crcs/ectester/data/supersingular/ss128.csv create mode 100644 src/cz/crcs/ectester/data/supersingular/ss192.csv create mode 100644 src/cz/crcs/ectester/data/supersingular/ss224.csv create mode 100644 src/cz/crcs/ectester/data/supersingular/ss256.csv delete mode 100644 src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/CardCompositeSuite.java delete mode 100644 src/cz/crcs/ectester/reader/test/CardDegenerateCurvesSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/CardDegenerateSuite.java delete mode 100644 src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/CardInvalidSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/CardMiscSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/CardTwistSuite.java delete mode 100644 src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java delete mode 100644 src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/CardWrongSuite.java (limited to 'src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java') diff --git a/docs/CURVES.md b/docs/CURVES.md index a9b8b68..a417035 100644 --- a/docs/CURVES.md +++ b/docs/CURVES.md @@ -41,6 +41,7 @@ Barreto-Naehrig curves from: A Family of Implementation-Friendly BN Elliptic Cur ### Other An assortment of some other curves. Montgomery curves transformed into short Weierstrass form from + Curve25519 transformed into short Weierstrass form. @@ -83,6 +84,11 @@ Contains curves that are composite order, with points not on the subgroup genera Generated using [ecgen](https://github.com/J08nY/ecgen). +### supersingular +Contains supersingular curves, over F_p with order equal to p + 1. These have embedding degree equal to 2. + +Generated using [ecgen](https://github.com/J08nY/ecgen). + ## Other ### Wycheproof diff --git a/docs/TESTS.md b/docs/TESTS.md index 5ec3b63..4d71ea6 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -3,6 +3,7 @@ - `default` - `test-vectors` - `compression` + - `miscellaneous` - `wrong`* - `composite`* - `invalid`* @@ -155,4 +156,12 @@ P-256 curve which leaked information about the private key. For example: ```bash java -jar ECTester.jar -t edge-cases +``` + +## Miscellaneous +Some miscellaneous tests, tries ECDH and ECDSA over supersingular curves and Barreto-Naehrig curves with small embedding degree and CM discriminant. + +For example: +```bash +java -jar ECTester.jar -t miscellaneous ``` \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/categories.xml b/src/cz/crcs/ectester/data/categories.xml index e725db0..38ce683 100644 --- a/src/cz/crcs/ectester/data/categories.xml +++ b/src/cz/crcs/ectester/data/categories.xml @@ -89,4 +89,9 @@ wycheproof Test cases from google Wycheproof project: https://github.com/google/wycheproof + + supersingular + supersingular + Some supersingular curves, over F_p with order equal to p + 1. + \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/supersingular/curves.xml b/src/cz/crcs/ectester/data/supersingular/curves.xml new file mode 100644 index 0000000..186a8a7 --- /dev/null +++ b/src/cz/crcs/ectester/data/supersingular/curves.xml @@ -0,0 +1,32 @@ + + + + ss128 + 128 + prime + ss128.csv + Supersingular curve + + + ss192 + 192 + prime + ss192.csv + Supersingular curve + + + ss224 + 224 + prime + ss224.csv + Supersingular curve + + + ss256 + 256 + prime + ss256.csv + Supersingular curve + + \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/supersingular/ss128.csv b/src/cz/crcs/ectester/data/supersingular/ss128.csv new file mode 100644 index 0000000..9dd4f13 --- /dev/null +++ b/src/cz/crcs/ectester/data/supersingular/ss128.csv @@ -0,0 +1 @@ +0x9ad6ed2af5bd6f3a9ac1d052ea17b2a9,0x8a3fe60aedb247e20a2d0c4a07de4d37,0x10970720080b27589094c408e2396572,0x563804cbd66f054434143af1e3ec6eaf,0x42af7ba7a078ef8fa3c0f253d1ccc16a,0x4d6b76957adeb79d4d60e829750bd955,0x02 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/supersingular/ss192.csv b/src/cz/crcs/ectester/data/supersingular/ss192.csv new file mode 100644 index 0000000..0c8ae8b --- /dev/null +++ b/src/cz/crcs/ectester/data/supersingular/ss192.csv @@ -0,0 +1 @@ +0x8c4dbc0e122afdeb466c2b7c3321e72531ac1cd8435f5159,0x64ff701953d8a795e3d9fa41a85eb2bd355479744198ae6c,0x274e4bf4be5256556292313a8ac33467fc57a36401c6a2ed,0x6c39b62a8665aca35dc1669dd483a1e881c65557bbed7f8c,0x1f90241e9bdb361251343bf4cb1ff19545e1e0fff2c8f235,0x4626de0709157ef5a33615be1990f39298d60e6c21afa8ad,0x02 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/supersingular/ss224.csv b/src/cz/crcs/ectester/data/supersingular/ss224.csv new file mode 100644 index 0000000..01eaa35 --- /dev/null +++ b/src/cz/crcs/ectester/data/supersingular/ss224.csv @@ -0,0 +1 @@ +0xa52f9550f18b8475c5cddd1232428b0c6138aa8704759eab7916f839,0x35186ffe96c8460148b9070efdde881f68647ff48a93854966ebf457,0x701725525ac33e747d14d603346402ecf8d42a9279e21962122b03e2,0x726e4342d936e7c3f004d36b5a703ca35d000014e70bceb1e956f7cc,0x9b3785caa9b028340c564ec4e7450229b7a0b16bc7185c78d852e2a6,0x1084c221b1c126d893c7c94e9ea0411ad685aaa71a0bc31125b57f39,0x0a \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/supersingular/ss256.csv b/src/cz/crcs/ectester/data/supersingular/ss256.csv new file mode 100644 index 0000000..47a8174 --- /dev/null +++ b/src/cz/crcs/ectester/data/supersingular/ss256.csv @@ -0,0 +1 @@ +0xf9cde8953b26ab31fe1b135266d2f9187e3d9df982880f05cc80f1998b9b0c8d,0xdf0a21f2f4d03d6ca2e151406e17cc1f0300287a348bc4452d7320db6138269e,0x1ac3c6a246566dc55b39c211f8bb2cf97b3d757f4dfc4ac09f0dd0be2a62e5ef,0x3c52f9e66b5c180923ac7bfb7f88f0162ee1dca122aa8dda1e8de3e044cb55a6,0x89c2f4437118d2edb0021706feef5a4419150afd7d1c3b7401eee93c2e547264,0x7ce6f44a9d935598ff0d89a933697c8c3f1ecefcc1440782e64078ccc5cd8647,0x02 \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index ab022dd..89cfca1 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -273,7 +273,7 @@ public class ECTesterReader { 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("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. [test_suite]:\n- default:\n- compression:\n- invalid:\n- twist:\n- degenerate:\n- cofactor:\n- wrong:\n- composite:\n- test-vectors:\n- edge-cases:").hasArg().argName("test_suite").optionalArg(true).build()); + actions.addOption(Option.builder("t").longOpt("test").desc("Test ECC support. [test_suite]:\n- default:\n- compression:\n- invalid:\n- twist:\n- degenerate:\n- cofactor:\n- wrong:\n- composite:\n- test-vectors:\n- edge-cases:\n- miscellaneous:").hasArg().argName("test_suite").optionalArg(true).build()); actions.addOption(Option.builder("dh").longOpt("ecdh").desc("Do EC KeyAgreement (ECDH...), [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()); actions.addOption(Option.builder("ls").longOpt("list-suites").desc("List supported test suites.").build()); @@ -332,13 +332,14 @@ public class ECTesterReader { new CardDefaultSuite(null, null, null), new CardTestVectorSuite(null, null, null), new CardCompressionSuite(null, null, null), - new CardWrongCurvesSuite(null, null, null), - new CardDegenerateCurvesSuite(null, null, null), + new CardWrongSuite(null, null, null), + new CardDegenerateSuite(null, null, null), new CardCofactorSuite(null, null, null), - new CardCompositeCurvesSuite(null, null, null), - new CardInvalidCurvesSuite(null, null, null), + new CardCompositeSuite(null, null, null), + new CardInvalidSuite(null, null, null), new CardEdgeCasesSuite(null, null, null), - new CardTwistTestSuite(null, null, null)}; + new CardTwistSuite(null, null, null), + new CardMiscSuite(null, null, null)}; for (CardTestSuite suite : suites) { System.out.println(" - " + Colors.bold(suite.getName())); for (String line : suite.getDescription()) { @@ -457,6 +458,9 @@ public class ECTesterReader { case "compression": suite = new CardCompressionSuite(writer, cfg, cardManager); break; + case "miscellaneous": + suite = new CardMiscSuite(writer, cfg, cardManager); + break; default: // These run are dangerous, prompt before them. System.out.println("The test you selected (" + cfg.testSuite + ") is potentially dangerous."); @@ -472,19 +476,19 @@ public class ECTesterReader { } switch (cfg.testSuite) { case "wrong": - suite = new CardWrongCurvesSuite(writer, cfg, cardManager); + suite = new CardWrongSuite(writer, cfg, cardManager); break; case "composite": - suite = new CardCompositeCurvesSuite(writer, cfg, cardManager); + suite = new CardCompositeSuite(writer, cfg, cardManager); break; case "invalid": - suite = new CardInvalidCurvesSuite(writer, cfg, cardManager); + suite = new CardInvalidSuite(writer, cfg, cardManager); break; case "degenerate": - suite = new CardDegenerateCurvesSuite(writer, cfg, cardManager); + suite = new CardDegenerateSuite(writer, cfg, cardManager); break; case "twist": - suite = new CardTwistTestSuite(writer, cfg, cardManager); + suite = new CardTwistSuite(writer, cfg, cardManager); break; case "cofactor": suite = new CardCofactorSuite(writer, cfg, cardManager); @@ -824,7 +828,7 @@ public class ECTesterReader { } testSuite = cli.getOptionValue("test", "default").toLowerCase(); - String[] tests = new String[]{"default", "composite", "compression", "invalid", "degenerate", "test-vectors", "wrong", "twist", "cofactor", "edge-cases"}; + String[] tests = new String[]{"default", "composite", "compression", "invalid", "degenerate", "test-vectors", "wrong", "twist", "cofactor", "edge-cases", "miscellaneous"}; if (!Arrays.asList(tests).contains(testSuite)) { System.err.println(Colors.error("Unknown test suite " + testSuite + ". Should be one of: " + Arrays.toString(tests))); return false; diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java deleted file mode 100644 index 2b3724c..0000000 --- a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java +++ /dev/null @@ -1,98 +0,0 @@ -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_Key; -import cz.crcs.ectester.common.output.TestWriter; -import cz.crcs.ectester.common.test.CompoundTest; -import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.common.util.CardUtil; -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 java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import static cz.crcs.ectester.common.test.Result.ExpectedValue; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class CardCompositeCurvesSuite extends CardTestSuite { - - public CardCompositeCurvesSuite(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."); - } - - @Override - protected void runTests() throws Exception { - /* Do the default run with the public keys set to provided smallorder keys - * over composite order curves. Essentially small subgroup attacks. - * These should fail, the curves aren't safe so that if the computation with - * a small order public key succeeds the private key modulo the public key order - * is revealed. - */ - Map keys = EC_Store.getInstance().getObjects(EC_Key.class, "composite"); - List>> mappedKeys = EC_Store.mapKeyToCurve(keys.values()); - for (Map.Entry> curveKeys : mappedKeys) { - EC_Curve curve = curveKeys.getKey(); - List tests = new LinkedList<>(); - Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_LOCAL, 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; - } - tests.add(allocate); - for (EC_Key key : curveKeys.getValue()) { - Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY); - Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY); - 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(), set, generate, ecdh)); - } - doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ".", tests.toArray(new Test[0]))); - new Command.Cleanup(this.card).send(); - } - - /* Also test having a G of small order, so small R. - */ - Map results = EC_Store.getInstance().getObjects(EC_Curve.class, "composite"); - List>> groupList = EC_Store.mapToPrefix(results.values()); - List smallRCurves = groupList.stream().filter((e) -> e.getKey().equals("small")).findFirst().get().getValue(); - testGroup(smallRCurves, "Small generator order", ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a small order generator.", "Card incorrectly does ECDH over a small order generator."); - - /* Also test having a G of large but composite order, R = p * q, - */ - List pqCurves = groupList.stream().filter((e) -> e.getKey().equals("pq")).findFirst().get().getValue(); - testGroup(pqCurves, null, ExpectedValue.ANY, "", ""); - - /* Also test rg0 curves. - */ - List rg0Curves = groupList.stream().filter((e) -> e.getKey().equals("rg0")).findFirst().get().getValue(); - testGroup(rg0Curves, null, ExpectedValue.ANY, "", ""); - } - - private void testGroup(List curves, String testName, ExpectedValue dhValue, String ok, String nok) throws Exception { - for (EC_Curve curve : curves) { - 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.ANY); - Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.ANY); - Test ecdh = 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), dhValue, ok, nok); - - String description; - if (testName == null) { - description = curve.getDesc() + " test of " + curve.getId() + "."; - } else { - description = testName + " test of " + curve.getId() + "."; - } - doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, description, allocate, set, generate, ecdh)); - new Command.Cleanup(this.card).send(); - } - - } -} diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java new file mode 100644 index 0000000..0d4d2e0 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java @@ -0,0 +1,98 @@ +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_Key; +import cz.crcs.ectester.common.output.TestWriter; +import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.util.CardUtil; +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 java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import static cz.crcs.ectester.common.test.Result.ExpectedValue; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +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."); + } + + @Override + protected void runTests() throws Exception { + /* Do the default run with the public keys set to provided smallorder keys + * over composite order curves. Essentially small subgroup attacks. + * These should fail, the curves aren't safe so that if the computation with + * a small order public key succeeds the private key modulo the public key order + * is revealed. + */ + Map keys = EC_Store.getInstance().getObjects(EC_Key.class, "composite"); + List>> mappedKeys = EC_Store.mapKeyToCurve(keys.values()); + for (Map.Entry> curveKeys : mappedKeys) { + EC_Curve curve = curveKeys.getKey(); + List tests = new LinkedList<>(); + Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_LOCAL, 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; + } + tests.add(allocate); + for (EC_Key key : curveKeys.getValue()) { + Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY); + Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY); + 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(), set, generate, ecdh)); + } + doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ".", tests.toArray(new Test[0]))); + new Command.Cleanup(this.card).send(); + } + + /* Also test having a G of small order, so small R. + */ + Map results = EC_Store.getInstance().getObjects(EC_Curve.class, "composite"); + List>> groupList = EC_Store.mapToPrefix(results.values()); + List smallRCurves = groupList.stream().filter((e) -> e.getKey().equals("small")).findFirst().get().getValue(); + testGroup(smallRCurves, "Small generator order", ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a small order generator.", "Card incorrectly does ECDH over a small order generator."); + + /* Also test having a G of large but composite order, R = p * q, + */ + List pqCurves = groupList.stream().filter((e) -> e.getKey().equals("pq")).findFirst().get().getValue(); + testGroup(pqCurves, null, ExpectedValue.ANY, "", ""); + + /* Also test rg0 curves. + */ + List rg0Curves = groupList.stream().filter((e) -> e.getKey().equals("rg0")).findFirst().get().getValue(); + testGroup(rg0Curves, null, ExpectedValue.ANY, "", ""); + } + + private void testGroup(List curves, String testName, ExpectedValue dhValue, String ok, String nok) throws Exception { + for (EC_Curve curve : curves) { + 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.ANY); + Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.ANY); + Test ecdh = 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), dhValue, ok, nok); + + String description; + if (testName == null) { + description = curve.getDesc() + " test of " + curve.getId() + "."; + } else { + description = testName + " test of " + curve.getId() + "."; + } + doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, description, allocate, set, generate, ecdh)); + new Command.Cleanup(this.card).send(); + } + + } +} diff --git a/src/cz/crcs/ectester/reader/test/CardDegenerateCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardDegenerateCurvesSuite.java deleted file mode 100644 index 0cc9186..0000000 --- a/src/cz/crcs/ectester/reader/test/CardDegenerateCurvesSuite.java +++ /dev/null @@ -1,55 +0,0 @@ -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_Key; -import cz.crcs.ectester.common.output.TestWriter; -import cz.crcs.ectester.common.test.CompoundTest; -import cz.crcs.ectester.common.test.Result; -import cz.crcs.ectester.common.test.Test; -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 java.util.LinkedList; -import java.util.List; -import java.util.Map; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class CardDegenerateCurvesSuite extends CardTestSuite { - - public CardDegenerateCurvesSuite(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."); - } - - @Override - protected void runTests() throws Exception { - Map pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "degenerate"); - List>> curveList = EC_Store.mapKeyToCurve(pubkeys.values()); - for (Map.Entry> e : curveList) { - EC_Curve curve = e.getKey(); - List keys = e.getValue(); - - Test allocate = CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS); - 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); - - List ecdhTests = new LinkedList<>(); - for (EC_Key.Public pub : keys) { - 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()); - ecdhTests.add(CommandTest.expect(ecdhCommand, Result.ExpectedValue.FAILURE, "Card correctly rejected point on degenerate curve.", "Card incorrectly accepted point on degenerate curve.")); - } - Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with degenerate public points", ecdhTests.toArray(new Test[0])); - - doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Degenerate curve test of " + curve.getId(), prepare, ecdh)); - new Command.Cleanup(this.card).send(); - } - } -} diff --git a/src/cz/crcs/ectester/reader/test/CardDegenerateSuite.java b/src/cz/crcs/ectester/reader/test/CardDegenerateSuite.java new file mode 100644 index 0000000..7483b2b --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CardDegenerateSuite.java @@ -0,0 +1,55 @@ +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_Key; +import cz.crcs.ectester.common.output.TestWriter; +import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.Result; +import cz.crcs.ectester.common.test.Test; +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 java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +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."); + } + + @Override + protected void runTests() throws Exception { + Map pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "degenerate"); + List>> curveList = EC_Store.mapKeyToCurve(pubkeys.values()); + for (Map.Entry> e : curveList) { + EC_Curve curve = e.getKey(); + List keys = e.getValue(); + + Test allocate = CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS); + 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); + + List ecdhTests = new LinkedList<>(); + for (EC_Key.Public pub : keys) { + 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()); + ecdhTests.add(CommandTest.expect(ecdhCommand, Result.ExpectedValue.FAILURE, "Card correctly rejected point on degenerate curve.", "Card incorrectly accepted point on degenerate curve.")); + } + Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with degenerate public points", ecdhTests.toArray(new Test[0])); + + doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Degenerate curve test of " + curve.getId(), prepare, ecdh)); + new Command.Cleanup(this.card).send(); + } + } +} diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java deleted file mode 100644 index 425fa06..0000000 --- a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java +++ /dev/null @@ -1,75 +0,0 @@ -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_Key; -import cz.crcs.ectester.common.output.TestWriter; -import cz.crcs.ectester.common.test.CompoundTest; -import cz.crcs.ectester.common.test.Result; -import cz.crcs.ectester.common.test.Test; -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 java.util.*; - -import static cz.crcs.ectester.common.test.Result.ExpectedValue; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class CardInvalidCurvesSuite extends CardTestSuite { - - public CardInvalidCurvesSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { - super(writer, cfg, cardManager, "invalid", "The invalid curve suite tests whether the card rejects points outside of the curve during ECDH."); - } - - @Override - protected void runTests() throws Exception { - /* Set original curves (secg/nist/brainpool). Generate local. - * Try ECDH with invalid public keys of increasing order. - */ - Map pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "invalid"); - List>> curveList = EC_Store.mapKeyToCurve(pubkeys.values()); - for (Map.Entry> e : curveList) { - EC_Curve curve = e.getKey(); - List keys = e.getValue(); - - 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 prepare = CompoundTest.all(ExpectedValue.SUCCESS, "Prepare and generate keypair on " + curve.getId(), allocate, set, generate); - - List ecdhTests = new LinkedList<>(); - for (EC_Key.Public pub : keys) { - 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()); - ecdhTests.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve.", "Card incorrectly accepted point on invalid curve.")); - } - Test ecdh = CompoundTest.all(ExpectedValue.SUCCESS, "Perform ECDH with invalid public points", ecdhTests.toArray(new Test[0])); - - Random r = new Random(); - byte[] raw = new byte[128]; - byte[] sig = new byte[40]; - r.nextBytes(raw); - r.nextBytes(sig); - - List ecdsaTests = new LinkedList<>(); - for (EC_Key.Public pub : keys) { - Command setCommand = new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()); - Test setTest = CommandTest.expect(setCommand, Result.ExpectedValue.ANY); - Command ecdsaCommand = new Command.ECDSA_verify(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.Signature_ALG_ECDSA_SHA, raw, sig); - Test ecdsaTest = CommandTest.expect(ecdsaCommand, Result.ExpectedValue.FAILURE); - ecdsaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Verify random ECDSA signature by " + pub.getId(), setTest, ecdsaTest)); - } - Test ecdsa = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Verify random ECDSA signature by invalid public points", ecdsaTests.toArray(new Test[0])); - - Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Test ECDH and ECDSA with points on invalid curves.", ecdh, ecdsa); - - doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), prepare, tests)); - new Command.Cleanup(this.card).send(); - } - } -} diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidSuite.java new file mode 100644 index 0000000..2543027 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CardInvalidSuite.java @@ -0,0 +1,75 @@ +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_Key; +import cz.crcs.ectester.common.output.TestWriter; +import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.Result; +import cz.crcs.ectester.common.test.Test; +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 java.util.*; + +import static cz.crcs.ectester.common.test.Result.ExpectedValue; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class CardInvalidSuite extends CardTestSuite { + + public CardInvalidSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { + super(writer, cfg, cardManager, "invalid", "The invalid curve suite tests whether the card rejects points outside of the curve during ECDH."); + } + + @Override + protected void runTests() throws Exception { + /* Set original curves (secg/nist/brainpool). Generate local. + * Try ECDH with invalid public keys of increasing order. + */ + Map pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "invalid"); + List>> curveList = EC_Store.mapKeyToCurve(pubkeys.values()); + for (Map.Entry> e : curveList) { + EC_Curve curve = e.getKey(); + List keys = e.getValue(); + + 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 prepare = CompoundTest.all(ExpectedValue.SUCCESS, "Prepare and generate keypair on " + curve.getId(), allocate, set, generate); + + List ecdhTests = new LinkedList<>(); + for (EC_Key.Public pub : keys) { + 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()); + ecdhTests.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve.", "Card incorrectly accepted point on invalid curve.")); + } + Test ecdh = CompoundTest.all(ExpectedValue.SUCCESS, "Perform ECDH with invalid public points", ecdhTests.toArray(new Test[0])); + + Random r = new Random(); + byte[] raw = new byte[128]; + byte[] sig = new byte[40]; + r.nextBytes(raw); + r.nextBytes(sig); + + List ecdsaTests = new LinkedList<>(); + for (EC_Key.Public pub : keys) { + Command setCommand = new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()); + Test setTest = CommandTest.expect(setCommand, Result.ExpectedValue.ANY); + Command ecdsaCommand = new Command.ECDSA_verify(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.Signature_ALG_ECDSA_SHA, raw, sig); + Test ecdsaTest = CommandTest.expect(ecdsaCommand, Result.ExpectedValue.FAILURE); + ecdsaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Verify random ECDSA signature by " + pub.getId(), setTest, ecdsaTest)); + } + Test ecdsa = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Verify random ECDSA signature by invalid public points", ecdsaTests.toArray(new Test[0])); + + Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Test ECDH and ECDSA with points on invalid curves.", ecdh, ecdsa); + + doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), prepare, tests)); + new Command.Cleanup(this.card).send(); + } + } +} diff --git a/src/cz/crcs/ectester/reader/test/CardMiscSuite.java b/src/cz/crcs/ectester/reader/test/CardMiscSuite.java new file mode 100644 index 0000000..d969cf9 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CardMiscSuite.java @@ -0,0 +1,54 @@ +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.output.TestWriter; +import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.Result; +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.util.CardUtil; +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 java.util.Map; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class CardMiscSuite extends CardTestSuite { + + public CardMiscSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { + super(writer, cfg, cardManager, "miscellaneous", "Some miscellaneous tests, tries ECDH and ECDSA over supersingular curves and some Barreto-Naehrig curves with small embedding degree and CM discriminant."); + } + + @Override + protected void runTests() throws Exception { + Map ssCurves = EC_Store.getInstance().getObjects(EC_Curve.class, "supersingular"); + Map bnCurves = EC_Store.getInstance().getObjects(EC_Curve.class, "Barreto-Naehrig"); + + testCurves(ssCurves, "supersingular"); + + testCurves(bnCurves, "Barreto-Naehrig"); + } + + private void testCurves(Map curves, String catName) throws Exception { + for (EC_Curve curve : curves.values()) { + Test allocateFirst = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS)); + if (!allocateFirst.ok()) { + doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()) + ".", allocateFirst)); + 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_BOTH), Result.ExpectedValue.SUCCESS); + 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), Result.ExpectedValue.SUCCESS); + Test sig = CommandTest.expect(new Command.ECDSA(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.Signature_ALG_ECDSA_SHA, ECTesterApplet.EXPORT_FALSE, null), Result.ExpectedValue.SUCCESS); + + doTest(CompoundTest.greedyAll(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + " " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, ka, sig)); + new Command.Cleanup(this.card).send(); + } + } +} diff --git a/src/cz/crcs/ectester/reader/test/CardTwistSuite.java b/src/cz/crcs/ectester/reader/test/CardTwistSuite.java new file mode 100644 index 0000000..46da415 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CardTwistSuite.java @@ -0,0 +1,69 @@ +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_Key; +import cz.crcs.ectester.common.output.TestWriter; +import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.Result; +import cz.crcs.ectester.common.test.Test; +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 java.util.*; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class CardTwistSuite extends CardTestSuite { + public CardTwistSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { + super(writer, cfg, cardManager, "twist", "The twist test suite tests whether the card correctly rejects points on the quadratic twist of the curve during ECDH."); + } + + @Override + protected void runTests() throws Exception { + Map pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "twist"); + List>> curveList = EC_Store.mapKeyToCurve(pubkeys.values()); + for (Map.Entry> e : curveList) { + EC_Curve curve = e.getKey(); + List keys = e.getValue(); + + Test allocate = CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS); + 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); + + List ecdhTests = new LinkedList<>(); + for (EC_Key.Public pub : keys) { + 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()); + ecdhTests.add(CommandTest.expect(ecdhCommand, Result.ExpectedValue.FAILURE, "Card correctly rejected point on twist.", "Card incorrectly accepted point on twist.")); + } + Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with public points on twist", ecdhTests.toArray(new Test[0])); + + Random r = new Random(); + byte[] raw = new byte[128]; + byte[] sig = new byte[40]; + r.nextBytes(raw); + r.nextBytes(sig); + + List ecdsaTests = new LinkedList<>(); + for (EC_Key.Public pub : keys) { + Command setCommand = new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()); + Test setTest = CommandTest.expect(setCommand, Result.ExpectedValue.ANY); + Command ecdsaCommand = new Command.ECDSA_verify(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.Signature_ALG_ECDSA_SHA, raw, sig); + Test ecdsaTest = CommandTest.expect(ecdsaCommand, Result.ExpectedValue.FAILURE); + ecdsaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Verify random ECDSA signature by " + pub.getId(), setTest, ecdsaTest)); + } + Test ecdsa = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Verify random ECDSA signature by public points on twist", ecdsaTests.toArray(new Test[0])); + + Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, ecdh, ecdsa); + + doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId(), prepare, tests)); + new Command.Cleanup(this.card).send(); + } + } +} diff --git a/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java b/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java deleted file mode 100644 index ab8e144..0000000 --- a/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java +++ /dev/null @@ -1,69 +0,0 @@ -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_Key; -import cz.crcs.ectester.common.output.TestWriter; -import cz.crcs.ectester.common.test.CompoundTest; -import cz.crcs.ectester.common.test.Result; -import cz.crcs.ectester.common.test.Test; -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 java.util.*; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class CardTwistTestSuite extends CardTestSuite { - public CardTwistTestSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { - super(writer, cfg, cardManager, "twist", "The twist test suite tests whether the card correctly rejects points on the quadratic twist of the curve during ECDH."); - } - - @Override - protected void runTests() throws Exception { - Map pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "twist"); - List>> curveList = EC_Store.mapKeyToCurve(pubkeys.values()); - for (Map.Entry> e : curveList) { - EC_Curve curve = e.getKey(); - List keys = e.getValue(); - - Test allocate = CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS); - 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); - - List ecdhTests = new LinkedList<>(); - for (EC_Key.Public pub : keys) { - 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()); - ecdhTests.add(CommandTest.expect(ecdhCommand, Result.ExpectedValue.FAILURE, "Card correctly rejected point on twist.", "Card incorrectly accepted point on twist.")); - } - Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with public points on twist", ecdhTests.toArray(new Test[0])); - - Random r = new Random(); - byte[] raw = new byte[128]; - byte[] sig = new byte[40]; - r.nextBytes(raw); - r.nextBytes(sig); - - List ecdsaTests = new LinkedList<>(); - for (EC_Key.Public pub : keys) { - Command setCommand = new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()); - Test setTest = CommandTest.expect(setCommand, Result.ExpectedValue.ANY); - Command ecdsaCommand = new Command.ECDSA_verify(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.Signature_ALG_ECDSA_SHA, raw, sig); - Test ecdsaTest = CommandTest.expect(ecdsaCommand, Result.ExpectedValue.FAILURE); - ecdsaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Verify random ECDSA signature by " + pub.getId(), setTest, ecdsaTest)); - } - Test ecdsa = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Verify random ECDSA signature by public points on twist", ecdsaTests.toArray(new Test[0])); - - Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, ecdh, ecdsa); - - doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId(), prepare, tests)); - new Command.Cleanup(this.card).send(); - } - } -} diff --git a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java deleted file mode 100644 index 8b648b9..0000000 --- a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java +++ /dev/null @@ -1,203 +0,0 @@ -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.CompoundTest; -import cz.crcs.ectester.common.test.Result; -import cz.crcs.ectester.common.test.Test; -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 javacard.security.KeyPair; - -import java.math.BigInteger; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Random; - -import static cz.crcs.ectester.common.test.Result.ExpectedValue; -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class CardWrongCurvesSuite extends CardTestSuite { - - public CardWrongCurvesSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { - super(writer, cfg, cardManager, "wrong", "The wrong curve suite tests whether the card rejects domain parameters which are not curves."); - } - - @Override - protected void runTests() throws Exception { - /* Just do the default run on the wrong curves. - * These should generally fail, the curves aren't curves. - */ - Map curves = EC_Store.getInstance().getObjects(EC_Curve.class, "wrong"); - for (Map.Entry e : curves.entrySet()) { - EC_Curve curve = e.getValue(); - List tests = new LinkedList<>(); - Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - if (!key.ok()) { - doTest(CompoundTest.all(ExpectedValue.FAILURE, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()), key)); - continue; - } - tests.add(key); - Test set = runTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.FAILURE)); - Test generate = runTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.FAILURE)); - Test setup = runTest(CompoundTest.any(ExpectedValue.SUCCESS, "Set wrong curve and generate keypairs.", set, generate)); - tests.add(setup); - - for (byte kaType : EC_Consts.KA_TYPES) { - Test allocate = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), ExpectedValue.SUCCESS)); - if (allocate.ok()) { - Test ka = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType), ExpectedValue.FAILURE)); - Test kaTest = runTest(CompoundTest.all(ExpectedValue.SUCCESS, "Allocate and perform KA.", allocate, ka)); - tests.add(kaTest); - } - } - doTest(CompoundTest.function((tsts) -> { - for (int i = 0; i < tsts.length; ++i) { - if (i != 1 && !tsts[i].ok()) { - return new Result(Result.Value.FAILURE, "Some tests did not have the expected result."); - } - } - return new Result(Result.Value.SUCCESS, "All tests had the expected result."); - }, "Wrong curve test of " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()), tests.toArray(new Test[0]))); - } - /* - * Do some interesting tests with corrupting the custom curves. - * For prime field: - * - p = 0 - * - p = 1 - * - p is a square of a prime - * - p is a composite q * s with q, s primes - * - TODO: p divides discriminant - */ - Random r = new Random(); - for (short keyLength : EC_Consts.FP_SIZES) { - byte curve = EC_Consts.getCurve(keyLength, KeyPair.ALG_EC_FP); - Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, keyLength, KeyPair.ALG_EC_FP), ExpectedValue.SUCCESS)); - if (!key.ok()) { - doTest(CompoundTest.all(ExpectedValue.FAILURE, "No support for " + keyLength + "b ALG_EC_FP.", key)); - continue; - } - Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, curve, EC_Consts.PARAMETERS_DOMAIN_FP, null), ExpectedValue.SUCCESS); - Test setup = CompoundTest.all(ExpectedValue.SUCCESS, "KeyPair setup.", key, set); - - Test prime0 = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_FP, EC_Consts.TRANSFORMATION_ZERO), "Set p = 0.", "ECDH with p = 0."); - Test prime1 = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_FP, EC_Consts.TRANSFORMATION_ONE), "Set p = 1.", "ECDH with p = 1."); - - short keyHalf = (short) (keyLength / 2); - BigInteger prime = new BigInteger(keyHalf, 50, r); - BigInteger primePow = prime.pow(2); - byte[] primePowBytes = ECUtil.toByteArray(primePow, keyLength); - EC_Params primePowData = new EC_Params(EC_Consts.PARAMETER_FP, new byte[][]{primePowBytes}); - Test primePower = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, primePowData.getParams(), primePowData.flatten()), "Set p = square of a prime.", "ECDH with p = q^2."); - - BigInteger q = new BigInteger(keyHalf, r); - BigInteger s = new BigInteger(keyHalf, r); - BigInteger compositeValue = q.multiply(s); - byte[] compositeBytes = ECUtil.toByteArray(compositeValue, keyLength); - EC_Params compositeData = new EC_Params(EC_Consts.PARAMETER_FP, new byte[][]{compositeBytes}); - Test composite = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, compositeData.getParams(), compositeData.flatten()), "Set p = product of two primes.", "ECDH with p = q * s."); - - Test wrongPrime = CompoundTest.all(ExpectedValue.SUCCESS, "Tests with corrupted prime parameter.", prime0, prime1, primePower, composite); - - Test resetSetup = CompoundTest.all(ExpectedValue.SUCCESS, "Reset keypair.", set.clone()); - - Test randomG = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_G, (short) (EC_Consts.TRANSFORMATION_FULLRANDOM | EC_Consts.TRANSFORMATION_04_MASK)), "Set G = random non-point/point-like.", "ECDH with non-point G."); - Test zeroG = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_G, EC_Consts.TRANSFORMATION_INFINITY), "Set G = inifnity.", "ECDH with G = infinity."); - Test wrongG = CompoundTest.all(ExpectedValue.SUCCESS, "Tests with corrupted G parameter.", zeroG, randomG); - - byte[] originalR = new byte[keyLength]; - EC_Consts.getCurveParameter(curve, EC_Consts.PARAMETER_R, originalR, (short) 0); - BigInteger originalBigR = new BigInteger(1, originalR); - BigInteger nextPrimeR = originalBigR.nextProbablePrime(); - byte[] nextRBytes = ECUtil.toByteArray(nextPrimeR, keyLength); - EC_Params nextRData = new EC_Params(EC_Consts.PARAMETER_R, new byte[][]{nextRBytes}); - Test primeWrongR = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, nextRData.getParams(), nextRData.flatten()), "Set R = some prime (but [r]G != infinity).", "ECDH with wrong R, prime."); - byte[] nonprimeRBytes = nextRBytes.clone(); - nonprimeRBytes[0] ^= 1; - EC_Params nonprimeWrongRData = new EC_Params(EC_Consts.PARAMETER_R, new byte[][]{nonprimeRBytes}); - Test nonprimeWrongR = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, nonprimeWrongRData.getParams(), nonprimeWrongRData.flatten()), "Set R = some composite (but [r]G != infinity).", "ECDH with wrong R, composite."); - - Test wrongR = CompoundTest.all(ExpectedValue.SUCCESS, "Tests with corrupted R parameter.", primeWrongR, nonprimeWrongR); - - - doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Tests of " + keyLength + "b " + CardUtil.getKeyTypeString(KeyPair.ALG_EC_FP), setup, wrongPrime, resetSetup, wrongG, resetSetup.clone(), wrongR, resetSetup.clone())); - } - - /* - * For binary field: - * - e1, e2 or e3 is larger than m. - * - e1 = e2 = e3 = 0 - */ - for (short keyLength : EC_Consts.F2M_SIZES) { - byte curve = EC_Consts.getCurve(keyLength, KeyPair.ALG_EC_F2M); - Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, keyLength, KeyPair.ALG_EC_F2M), ExpectedValue.SUCCESS)); - if (!key.ok()) { - doTest(CompoundTest.all(ExpectedValue.FAILURE, "No support for " + keyLength + "b ALG_EC_F2M.", key)); - continue; - } - Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, curve, EC_Consts.PARAMETERS_DOMAIN_F2M, null), ExpectedValue.SUCCESS); - Test setup = CompoundTest.all(ExpectedValue.SUCCESS, "KeyPair setup.", key, set); - - Test coeff0 = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_F2M, EC_Consts.TRANSFORMATION_ZERO), "Set e1 = e2 = e3 = 0.", "ECDH with wrong field polynomial: x^" + keyLength); - - short e1 = (short) (2 * keyLength); - short e2 = (short) (3 * keyLength); - short e3 = (short) (4 * keyLength); - byte[][] coeffBytes = new byte[][]{ - ByteUtil.shortToBytes(keyLength), - ByteUtil.shortToBytes(e1), - ByteUtil.shortToBytes(e2), - ByteUtil.shortToBytes(e3)}; - EC_Params coeffParams = new EC_Params(EC_Consts.PARAMETER_F2M, coeffBytes); - Test coeffLarger = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, coeffParams.getParams(), coeffParams.flatten()), "Set e1=" + e1 + ", e2=" + e2 + ", e3=" + e3, "ECDH with wrong field poly, powers larger than " + keyLength); - - Test wrong = CompoundTest.all(ExpectedValue.SUCCESS, "Tests with corrupted field polynomial parameter.", coeff0, coeffLarger); - doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Tests of " + keyLength + "b " + CardUtil.getKeyTypeString(KeyPair.ALG_EC_F2M), setup, wrong)); - } - - /* - * TODO: tests for both Fp and F2m: - * - generator not on curve, - * - generator not on proper subgroup of curve(as specified by order/cofactor), - * - wrong order, - * - wrong cofactor. - */ - } - - private Test ecdhTest(Command setupCmd, String prepareDesc, String fullDesc) { - Test setup = CommandTest.expect(setupCmd, ExpectedValue.FAILURE); - Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.FAILURE); - Test preparePhase = CompoundTest.any(ExpectedValue.SUCCESS, prepareDesc, setup, generate); - Test allocateECDH = CommandTest.expect(new Command.AllocateKeyAgreement(this.card, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), ExpectedValue.SUCCESS); - Test ecdh = 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), ExpectedValue.FAILURE); - - - return CompoundTest.function((tests) -> { - if (preparePhase.ok() | !allocateECDH.ok() | ecdh.ok()) { - return new Result(Result.Value.SUCCESS, "All tests had the expected result."); - } else { - return new Result(Result.Value.FAILURE, "Some tests did not have the expected result."); - } - }, (tests) -> { - preparePhase.run(); - if (preparePhase.ok()) { - return; - } - allocateECDH.run(); - if (!allocateECDH.ok()) { - return; - } - ecdh.run(); - },fullDesc, preparePhase, allocateECDH, ecdh); - } -} diff --git a/src/cz/crcs/ectester/reader/test/CardWrongSuite.java b/src/cz/crcs/ectester/reader/test/CardWrongSuite.java new file mode 100644 index 0000000..6c0d5f5 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CardWrongSuite.java @@ -0,0 +1,203 @@ +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.CompoundTest; +import cz.crcs.ectester.common.test.Result; +import cz.crcs.ectester.common.test.Test; +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 javacard.security.KeyPair; + +import java.math.BigInteger; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import static cz.crcs.ectester.common.test.Result.ExpectedValue; +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class CardWrongSuite extends CardTestSuite { + + public CardWrongSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { + super(writer, cfg, cardManager, "wrong", "The wrong curve suite tests whether the card rejects domain parameters which are not curves."); + } + + @Override + protected void runTests() throws Exception { + /* Just do the default run on the wrong curves. + * These should generally fail, the curves aren't curves. + */ + Map curves = EC_Store.getInstance().getObjects(EC_Curve.class, "wrong"); + for (Map.Entry e : curves.entrySet()) { + EC_Curve curve = e.getValue(); + List tests = new LinkedList<>(); + Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + if (!key.ok()) { + doTest(CompoundTest.all(ExpectedValue.FAILURE, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()), key)); + continue; + } + tests.add(key); + Test set = runTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.FAILURE)); + Test generate = runTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.FAILURE)); + Test setup = runTest(CompoundTest.any(ExpectedValue.SUCCESS, "Set wrong curve and generate keypairs.", set, generate)); + tests.add(setup); + + for (byte kaType : EC_Consts.KA_TYPES) { + Test allocate = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), ExpectedValue.SUCCESS)); + if (allocate.ok()) { + Test ka = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType), ExpectedValue.FAILURE)); + Test kaTest = runTest(CompoundTest.all(ExpectedValue.SUCCESS, "Allocate and perform KA.", allocate, ka)); + tests.add(kaTest); + } + } + doTest(CompoundTest.function((tsts) -> { + for (int i = 0; i < tsts.length; ++i) { + if (i != 1 && !tsts[i].ok()) { + return new Result(Result.Value.FAILURE, "Some tests did not have the expected result."); + } + } + return new Result(Result.Value.SUCCESS, "All tests had the expected result."); + }, "Wrong curve test of " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()), tests.toArray(new Test[0]))); + } + /* + * Do some interesting tests with corrupting the custom curves. + * For prime field: + * - p = 0 + * - p = 1 + * - p is a square of a prime + * - p is a composite q * s with q, s primes + * - TODO: p divides discriminant + */ + Random r = new Random(); + for (short keyLength : EC_Consts.FP_SIZES) { + byte curve = EC_Consts.getCurve(keyLength, KeyPair.ALG_EC_FP); + Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, keyLength, KeyPair.ALG_EC_FP), ExpectedValue.SUCCESS)); + if (!key.ok()) { + doTest(CompoundTest.all(ExpectedValue.FAILURE, "No support for " + keyLength + "b ALG_EC_FP.", key)); + continue; + } + Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, curve, EC_Consts.PARAMETERS_DOMAIN_FP, null), ExpectedValue.SUCCESS); + Test setup = CompoundTest.all(ExpectedValue.SUCCESS, "KeyPair setup.", key, set); + + Test prime0 = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_FP, EC_Consts.TRANSFORMATION_ZERO), "Set p = 0.", "ECDH with p = 0."); + Test prime1 = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_FP, EC_Consts.TRANSFORMATION_ONE), "Set p = 1.", "ECDH with p = 1."); + + short keyHalf = (short) (keyLength / 2); + BigInteger prime = new BigInteger(keyHalf, 50, r); + BigInteger primePow = prime.pow(2); + byte[] primePowBytes = ECUtil.toByteArray(primePow, keyLength); + EC_Params primePowData = new EC_Params(EC_Consts.PARAMETER_FP, new byte[][]{primePowBytes}); + Test primePower = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, primePowData.getParams(), primePowData.flatten()), "Set p = square of a prime.", "ECDH with p = q^2."); + + BigInteger q = new BigInteger(keyHalf, r); + BigInteger s = new BigInteger(keyHalf, r); + BigInteger compositeValue = q.multiply(s); + byte[] compositeBytes = ECUtil.toByteArray(compositeValue, keyLength); + EC_Params compositeData = new EC_Params(EC_Consts.PARAMETER_FP, new byte[][]{compositeBytes}); + Test composite = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, compositeData.getParams(), compositeData.flatten()), "Set p = product of two primes.", "ECDH with p = q * s."); + + Test wrongPrime = CompoundTest.all(ExpectedValue.SUCCESS, "Tests with corrupted prime parameter.", prime0, prime1, primePower, composite); + + Test resetSetup = CompoundTest.all(ExpectedValue.SUCCESS, "Reset keypair.", set.clone()); + + Test randomG = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_G, (short) (EC_Consts.TRANSFORMATION_FULLRANDOM | EC_Consts.TRANSFORMATION_04_MASK)), "Set G = random non-point/point-like.", "ECDH with non-point G."); + Test zeroG = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_G, EC_Consts.TRANSFORMATION_INFINITY), "Set G = inifnity.", "ECDH with G = infinity."); + Test wrongG = CompoundTest.all(ExpectedValue.SUCCESS, "Tests with corrupted G parameter.", zeroG, randomG); + + byte[] originalR = new byte[keyLength]; + EC_Consts.getCurveParameter(curve, EC_Consts.PARAMETER_R, originalR, (short) 0); + BigInteger originalBigR = new BigInteger(1, originalR); + BigInteger nextPrimeR = originalBigR.nextProbablePrime(); + byte[] nextRBytes = ECUtil.toByteArray(nextPrimeR, keyLength); + EC_Params nextRData = new EC_Params(EC_Consts.PARAMETER_R, new byte[][]{nextRBytes}); + Test primeWrongR = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, nextRData.getParams(), nextRData.flatten()), "Set R = some prime (but [r]G != infinity).", "ECDH with wrong R, prime."); + byte[] nonprimeRBytes = nextRBytes.clone(); + nonprimeRBytes[0] ^= 1; + EC_Params nonprimeWrongRData = new EC_Params(EC_Consts.PARAMETER_R, new byte[][]{nonprimeRBytes}); + Test nonprimeWrongR = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, nonprimeWrongRData.getParams(), nonprimeWrongRData.flatten()), "Set R = some composite (but [r]G != infinity).", "ECDH with wrong R, composite."); + + Test wrongR = CompoundTest.all(ExpectedValue.SUCCESS, "Tests with corrupted R parameter.", primeWrongR, nonprimeWrongR); + + + doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Tests of " + keyLength + "b " + CardUtil.getKeyTypeString(KeyPair.ALG_EC_FP), setup, wrongPrime, resetSetup, wrongG, resetSetup.clone(), wrongR, resetSetup.clone())); + } + + /* + * For binary field: + * - e1, e2 or e3 is larger than m. + * - e1 = e2 = e3 = 0 + */ + for (short keyLength : EC_Consts.F2M_SIZES) { + byte curve = EC_Consts.getCurve(keyLength, KeyPair.ALG_EC_F2M); + Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, keyLength, KeyPair.ALG_EC_F2M), ExpectedValue.SUCCESS)); + if (!key.ok()) { + doTest(CompoundTest.all(ExpectedValue.FAILURE, "No support for " + keyLength + "b ALG_EC_F2M.", key)); + continue; + } + Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, curve, EC_Consts.PARAMETERS_DOMAIN_F2M, null), ExpectedValue.SUCCESS); + Test setup = CompoundTest.all(ExpectedValue.SUCCESS, "KeyPair setup.", key, set); + + Test coeff0 = ecdhTest(new Command.Transform(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_F2M, EC_Consts.TRANSFORMATION_ZERO), "Set e1 = e2 = e3 = 0.", "ECDH with wrong field polynomial: x^" + keyLength); + + short e1 = (short) (2 * keyLength); + short e2 = (short) (3 * keyLength); + short e3 = (short) (4 * keyLength); + byte[][] coeffBytes = new byte[][]{ + ByteUtil.shortToBytes(keyLength), + ByteUtil.shortToBytes(e1), + ByteUtil.shortToBytes(e2), + ByteUtil.shortToBytes(e3)}; + EC_Params coeffParams = new EC_Params(EC_Consts.PARAMETER_F2M, coeffBytes); + Test coeffLarger = ecdhTest(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, coeffParams.getParams(), coeffParams.flatten()), "Set e1=" + e1 + ", e2=" + e2 + ", e3=" + e3, "ECDH with wrong field poly, powers larger than " + keyLength); + + Test wrong = CompoundTest.all(ExpectedValue.SUCCESS, "Tests with corrupted field polynomial parameter.", coeff0, coeffLarger); + doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Tests of " + keyLength + "b " + CardUtil.getKeyTypeString(KeyPair.ALG_EC_F2M), setup, wrong)); + } + + /* + * TODO: tests for both Fp and F2m: + * - generator not on curve, + * - generator not on proper subgroup of curve(as specified by order/cofactor), + * - wrong order, + * - wrong cofactor. + */ + } + + private Test ecdhTest(Command setupCmd, String prepareDesc, String fullDesc) { + Test setup = CommandTest.expect(setupCmd, ExpectedValue.FAILURE); + Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.FAILURE); + Test preparePhase = CompoundTest.any(ExpectedValue.SUCCESS, prepareDesc, setup, generate); + Test allocateECDH = CommandTest.expect(new Command.AllocateKeyAgreement(this.card, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), ExpectedValue.SUCCESS); + Test ecdh = 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), ExpectedValue.FAILURE); + + + return CompoundTest.function((tests) -> { + if (preparePhase.ok() | !allocateECDH.ok() | ecdh.ok()) { + return new Result(Result.Value.SUCCESS, "All tests had the expected result."); + } else { + return new Result(Result.Value.FAILURE, "Some tests did not have the expected result."); + } + }, (tests) -> { + preparePhase.run(); + if (preparePhase.ok()) { + return; + } + allocateECDH.run(); + if (!allocateECDH.ok()) { + return; + } + ecdh.run(); + },fullDesc, preparePhase, allocateECDH, ecdh); + } +} -- cgit v1.2.3-70-g09d2