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. --- docs/TESTS.md | 68 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 24 deletions(-) (limited to 'docs/TESTS.md') diff --git a/docs/TESTS.md b/docs/TESTS.md index c4f38dc..72c328d 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -1,12 +1,13 @@ -# Tests +# Test suites - `default` - `test-vectors` - `wrong` - `composite` - `invalid` + - `twist` -**NOTE: The `wrong`, `composite` and `invalid` test suites caused temporary DoS of some cards. These test suites prompt you for +**NOTE: The `wrong`, `composite`, `invalid` and `twist` test suites caused temporary/permanent DoS of some cards. These test suites prompt you for confirmation before running, be cautious.** ## Default @@ -18,14 +19,10 @@ This test suite is run if no argument is provided to `-t / --test`. For example: ```bash -java -jar ECTester.jar -a -fp -t +java -jar ECTester.jar -t ``` -tests all(`-a`), prime field(`-fp`), using the default test suite. +tests prime field and binary field curves, using the default test suite. -```bash -java -jar ECTester.jar-a -f2m -t -``` -tests all(`-a`), binary field(`-f2m`), curves. ## Test-Vectors Tests using known test vectors provided by NIST/SECG/Brainpool: @@ -40,25 +37,33 @@ Tests using known test vectors provided by NIST/SECG/Brainpool: For example: ```bash -java -jar ECTester.jar -t test-vectors -nc nist -a -f2m -``` -tests all(`-a`), binary field(`-f2m`) NIST curves for which test-vectors are provided. Although this test suite is better for general testing: -```bash -java -jar ECTester.jar -t test-vectors -a +java -jar ECTester.jar -t test-vectors ``` +tests all curves for which test-vectors are provided. + + ## Wrong -Tests using the default tests on a category of wrong curves. These curves are not really curves as they have: +Tests on a category of wrong curves. These curves are not really curves as they have: - 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: + - Fp: + - p = 0 + - p = 1 + - p = q^2; q prime + - p = q * s; q and s prime + - F2m: + - e1 = e2 = e3 = 0 + - m < e1 < e2 < e3 + +These tests should fail generally. -These tests should fail generally. They are equivalent with `java -jar ECTester.jar -nc wrong -t`, the default tests over the `wrong` category -of curves. - For example: ```bash -java -jar ECTester.jar -t wrong -b 521 -fp +java -jar ECTester.jar -t wrong ``` -tests a 521 bit(`-b`), prime-field(`-fp`) wrong curve. +does all wrong curve tests. + ## Composite Tests using curves that don't have a prime order/nearly prime order. @@ -67,16 +72,31 @@ by the applet. Operations over such curves are susceptible to small-subgroup att For example: ```bash -java -jar ECTester.jar -t composite -b 160 -fp +java -jar ECTester.jar -t composite ``` + ## Invalid -Tests using known named curves from several categories(SECG/NIST/Brainpool) against pregenerated *invalid* public keys. -These tests should definitely fail, a success here implies the card is susceptible to invalid curve attacks. +Tests using known named curves from several categories(SECG/NIST/Brainpool) against pre-generated *invalid* public keys. +ECDH should definitely fail, a success here implies the card is susceptible to invalid curve attacks. +See [Practical Invalid Curve Attacks on TLS-ECDH](https://www.nds.rub.de/media/nds/veroeffentlichungen/2015/09/14/main-full.pdf) for more information. For example: ```bash -java -jar ECTester.jar -t invalid -nc nist -a -fp +java -jar ECTester.jar -t invalid ``` -tests using all(`-a`), prime-field(`-fp`) NIST curves and pregenerated *invalid* public keys for these curves. \ No newline at end of file +tests using all curves with pregenerated *invalid* public keys for these curves. + + +## Twist +Tests using known named curves froms several categories(SECG/NIST) against pre-generated points on twists of said curves. +ECDH should fail, a success here implies the card is not twist secure, if a curve with an unsecure twist is used, +the card might compute on the twist, if a point on the twist is supplied. + +See [SafeCurves on twist security](https://safecurves.cr.yp.to/twist.html) for more information. + +For example: +```bash +java -jar ECTester.jar -t twist +``` \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 510116dd24fdd2e676d405eeede5309acef903f9 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 3 Mar 2018 23:14:08 +0100 Subject: Add Cofactor test suite. --- docs/CURVES.md | 5 ++ docs/TESTS.md | 12 ++++- src/cz/crcs/ectester/reader/ECTesterReader.java | 7 ++- .../reader/test/CardCofactorTestSuite.java | 60 ++++++++++++++++++++++ 4 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java (limited to 'docs/TESTS.md') diff --git a/docs/CURVES.md b/docs/CURVES.md index a04e82f..a815c5c 100644 --- a/docs/CURVES.md +++ b/docs/CURVES.md @@ -60,4 +60,9 @@ Generated manually. Contains pre-generated points on twists of known named curves from NIST, SECG. These points can be used to attack some implementations. +Generated using [ecgen](https://github.com/J08nY/ecgen). + +### cofactor +Contains curves that are composite order, with points not on the subgroup generated by the generator. + Generated using [ecgen](https://github.com/J08nY/ecgen). \ No newline at end of file diff --git a/docs/TESTS.md b/docs/TESTS.md index 72c328d..8f8fa2e 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -6,8 +6,9 @@ - `composite` - `invalid` - `twist` + - `cofactor` -**NOTE: The `wrong`, `composite`, `invalid` and `twist` test suites caused temporary/permanent DoS of some cards. These test suites prompt you for +**NOTE: The `wrong`, `composite`, `invalid`,`twist` and `cofactor` test suites caused temporary/permanent DoS of some cards. These test suites prompt you for confirmation before running, be cautious.** ## Default @@ -99,4 +100,13 @@ See [SafeCurves on twist security](https://safecurves.cr.yp.to/twist.html) for m For example: ```bash java -jar ECTester.jar -t twist +``` + +## Cofactor +Tests whether the card correctly rejects points that lie on the curve but not on the subgroup generated by the specified generator +during ECDH. + +For example: +```bash +java -jar ECTester.jar -t cofactor ``` \ 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 9c80bd2..1e8b8a4 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -246,7 +246,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- invalid:\n- twist:\n- wrong:\n- composite:\n- test-vectors:").hasArg().argName("test_suite").optionalArg(true).build()); + actions.addOption(Option.builder("t").longOpt("test").desc("Test ECC support. [test_suite]:\n- default:\n- invalid:\n- twist:\n- cofactor:\n- wrong:\n- composite:\n- test-vectors:").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()); @@ -431,6 +431,9 @@ public class ECTesterReader { case "twist": suite = new CardTwistTestSuite(writer, cfg, cardManager); break; + case "cofactor": + suite = new CardCofactorTestSuite(writer, cfg, cardManager); + break; default: System.err.println("Unknown test suite."); return; @@ -760,7 +763,7 @@ public class ECTesterReader { } testSuite = cli.getOptionValue("test", "default").toLowerCase(); - String[] tests = new String[]{"default", "composite", "invalid", "test-vectors", "wrong", "twist"}; + String[] tests = new String[]{"default", "composite", "invalid", "test-vectors", "wrong", "twist", "cofactor"}; if (!Arrays.asList(tests).contains(testSuite)) { System.err.println("Unknown test suite " + testSuite + ". Should be one of: " + Arrays.toString(tests)); return false; diff --git a/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java b/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java new file mode 100644 index 0000000..d3aef3a --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java @@ -0,0 +1,60 @@ +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.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class CardCofactorTestSuite extends CardTestSuite { + public CardCofactorTestSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { + super(writer, cfg, cardManager, "cofactor", "The cofactor test suite tests whether the card correctly rejects points on the curve but not in the subgroup generated by the generator during ECDH."); + } + + @Override + protected void runTests() throws Exception { + Map pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "cofactor"); + Map> curves = new HashMap<>(); + for (EC_Key.Public key : pubkeys.values()) { + EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, key.getCurve()); + List keys = curves.getOrDefault(curve, new LinkedList<>()); + keys.add(key); + curves.putIfAbsent(curve, keys); + } + for (Map.Entry> e : curves.entrySet()) { + 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.CORRUPTION_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])); + + doTest(CompoundTest.greedyAll(Result.ExpectedValue.SUCCESS, "Cofactor test of " + curve.getId(), prepare, ecdh)); + new Command.Cleanup(this.card).send(); + } + } +} -- cgit v1.2.3-70-g09d2 From 2a077441dc10918acf8a1f4f7c671d31b832ff4f Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 6 Mar 2018 01:21:48 +0100 Subject: Add points on non-generator subgroup for SECG curves to cofactor category. --- docs/TESTS.md | 3 +- src/cz/crcs/ectester/data/cofactor/keys.xml | 62 ++++--- src/cz/crcs/ectester/data/cofactor/secg_keys.xml | 216 +++++++++++++++++++++++ 3 files changed, 252 insertions(+), 29 deletions(-) create mode 100644 src/cz/crcs/ectester/data/cofactor/secg_keys.xml (limited to 'docs/TESTS.md') diff --git a/docs/TESTS.md b/docs/TESTS.md index 8f8fa2e..d2eb500 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -47,6 +47,7 @@ tests all curves for which test-vectors are provided. Tests on a category of wrong curves. These curves are not really curves as they have: - 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: - Fp: - p = 0 @@ -68,7 +69,7 @@ does all wrong curve tests. ## Composite 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 +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. For example: diff --git a/src/cz/crcs/ectester/data/cofactor/keys.xml b/src/cz/crcs/ectester/data/cofactor/keys.xml index 2d827cd..f65080a 100644 --- a/src/cz/crcs/ectester/data/cofactor/keys.xml +++ b/src/cz/crcs/ectester/data/cofactor/keys.xml @@ -1,91 +1,97 @@ + + ]> + - cofactor2p128_1 + cofactor2p128/0 0x1274cf343b12c9de044a312c7e0d88b1,0x00000000000000000000000000000000 cofactor/cofactor2p128 - + order = 2 - cofactor4p128_1 + cofactor4p128/0 0x4e5a1eb60f6d2cb5c24f6ea54a675cd6,0x00000000000000000000000000000000 cofactor/cofactor4p128 - + order = 2 - cofactor8p128_1 + cofactor8p128/0 0x31eb5f732057b0ea57eed55f4259d85d,0x00000000000000000000000000000000 cofactor/cofactor8p128 - + order = 2 - cofactor16p128_1 + cofactor16p128/0 0x89578c4527e2d5e8a95905e30f0889e3,0x00000000000000000000000000000000 cofactor/cofactor16p128 - + order = 2 - cofactor32p128_1 + cofactor32p128/0 0x097191ee5ded1c36f2ec6bba78e7e6ea,0x00000000000000000000000000000000 cofactor/cofactor32p128 - + order = 2 - cofactor64p128_1 + cofactor64p128/0 0x1d360b7f2f805be59aedeaae2813ee1f,0x00000000000000000000000000000000 cofactor/cofactor64p128 - + order = 2 - cofactor128p128_1 + cofactor128p128/0 0x485b34188824c54f115f31891c18795c,0x00000000000000000000000000000000 cofactor/cofactor128p128 - + order = 2 - cofactor2t163_1 + cofactor2t163/0 0x000000000000000000000000000000000000000000,0x0132720c6aa3f2ca65d18f2de81e5e6b8ad4a3ef9d cofactor/cofactor2t163 - + order = 2 - cofactor4t163_1 + cofactor4t163/0 0x000000000000000000000000000000000000000000,0x00b93d46bc80b487e7738644e85bb6d29c2dca2600 cofactor/cofactor4t163 - + order = 2 - cofactor8t163_1 + cofactor8t163/0 0x000000000000000000000000000000000000000000,0x0569879d9674b06578f62ec2f341ddd3b648dfdf51 cofactor/cofactor8t163 - + order = 2 - cofactor16t163_1 + cofactor16t163/0 0x000000000000000000000000000000000000000000,0x04274cf55c49c32ca4c0e30b891e03b3b1c6597df0 cofactor/cofactor16t163 - + order = 2 - cofactor32t163_1 + cofactor32t163/0 0x000000000000000000000000000000000000000000,0x0409969efb468e8f07954a3b4bf7610a0d8b5d4753 cofactor/cofactor32t163 - + order = 2 - cofactor64t163_1 + cofactor64t163/0 0x000000000000000000000000000000000000000000,0x068c5445c03a59d697573b09ae0804e2891bb98208 cofactor/cofactor64t163 - + order = 2 - cofactor128t163_1 + cofactor128t163/0 0x000000000000000000000000000000000000000000,0x06be374502a948489de2e7d8d82cb6b62a493b77a0 cofactor/cofactor128t163 - + order = 2 + + &secg; diff --git a/src/cz/crcs/ectester/data/cofactor/secg_keys.xml b/src/cz/crcs/ectester/data/cofactor/secg_keys.xml new file mode 100644 index 0000000..d9d3896 --- /dev/null +++ b/src/cz/crcs/ectester/data/cofactor/secg_keys.xml @@ -0,0 +1,216 @@ + + + sect163k1/0 + 0x000000000000000000000000000000000000000000,0x000000000000000000000000000000000000000001 + secg/sect163k1 + order = 2 + + + sect163k1/1 + 0x07759edd174e24fd20b34e6d43e51230f0f7f892ab,0x05e4bf4321769ea3f4dc92abe028069f8db0fc0dc1 + secg/sect163k1 + order = 0x800000000000000000004021145c1981b33f14bde + + + + sect163r1/0 + 0x000000000000000000000000000000000000000000,0x009917a2556e1856bc7ea9a472cd01bfb889b95835 + secg/sect163r1 + order = 2 + + + sect163r1/1 + 0x05a78dd5973d0d39a5970d49b7a13df98558981dcb,0x0340755fa31149f5bf1dd4bf1fa3ef38432babbe13 + secg/sect163r1 + order = 0x7fffffffffffffffffffe91556d1385394e204f36 + + + + sect163r2/0 + 0x000000000000000000000000000000000000000000,0x02c25b85badf8927593d21c366da89c03969f34da5 + secg/sect163r2 + order = 2 + + + sect163r2/1 + 0x00b8a6683b6d99c044e1086e4eef5d2bd80fd2df41,0x04f6dfa693e7017de96c6e002871b72b3eb6d77b83 + secg/sect163r2 + order = 0x80000000000000000000525fcefce182548469866 + + + + sect233k1/0 + 0x000000000000000000000000000000000000000000000000000000000000,0x000000000000000000000000000000000000000000000000000000000001 + secg/sect233k1 + order = 2 + + + sect233k1/1 + 0x000000000000000000000000000000000000000000000000000000000001,0x000000000000000000000000000000000000000000000000000000000001 + secg/sect233k1 + order = 2 + + + sect233k1/2 + 0x01c90d47aff1ed1172eb861cbc5f11ade07f775b1fdd89b1665c464a97d9,0x002b41324d806a174953fb4ccf8bbeb4fd36cef6f30ccc93618dd282a8e0 + secg/sect233k1 + order = 0x100000000000000000000000000000d3ab7722b79a8ddf635abe2e757be + + + sect233k1/3 + 0x01f477bff0fda3ecd2fa1dff08045717ccf615189375e2437f539c1e1687,0x019f18a66f38eda89284e3979b2aa6ae034cc4a6c7999080815af028bafe + secg/sect233k1 + order = 0x200000000000000000000000000001a756ee456f351bbec6b57c5ceaf7c + + + + sect233r1/0 + 0x000000000000000000000000000000000000000000000000000000000000,0x0187f85627b97874e747ee31e06d71caaeea52f21253e5f946d061da9138 + secg/sect233r1 + order = 2 + + + sect233r1/1 + 0x00fe7bac18bdc41b4adbabaaa5dd95e7a170b63bb3519b5d897205fe779f,0x0109d0b6ef40d7f05129ee664be44ae57393716c0233857db6a3358926f7 + secg/sect233r1 + order = 0x2000000000000000000000000000027d2e9ce5f14d244063a4c079fc1ae + + + + sect239k1/0 + 0x000000000000000000000000000000000000000000000000000000000000,0x000000000000000000000000000000000000000000000000000000000001 + secg/sect239k1 + order = 2 + + + sect239k1/1 + 0x000000000000000000000000000000000000000000000000000000000001,0x000000000000000000000000000000000000000000000000000000000001 + secg/sect239k1 + order = 4 + + + sect239k1/2 + 0x2e97f4bf96f4598e4dbbba188895e14b068d9c21ab8e261ffc7d43abc0f2,0x16e86c56595addfdaad811d4bc01df886838cb761332a5bd65f846d63dd3 + secg/sect239k1 + order = 0x400000000000000000000000000000b4f3fd8cf96dd23e383b5001c8f14a + + + sect239k1/3 + 0x718e787b457b7baf3b58bf38c42dd3347802801386fbbe78c4dd5ea31cc0,0x180ad3b3a1182279d21cdd1de3067572c5fe64c3641cc171515c68128cb9 + secg/sect239k1 + order = 0x80000000000000000000000000000169e7fb19f2dba47c7076a00391e294 + + + + sect283k1/0 + 0x000000000000000000000000000000000000000000000000000000000000000000000000,0x000000000000000000000000000000000000000000000000000000000000000000000001 + secg/sect283k1 + order = 2 + + + sect283k1/1 + 0x000000000000000000000000000000000000000000000000000000000000000000000001,0x000000000000000000000000000000000000000000000000000000000000000000000000 + secg/sect283k1 + order = 4 + + + sect283k1/2 + 0x07801fcb7c8e5dd6f8c21c60dd7c13cd472dedffe20c3331d084eb4ba32f7b4b13a3510c,0x01960ead4b2a835d27a626fab5fc6e779b511c680a5e6af9b42d67228261a2add4220335 + secg/sect283k1 + order = 0x3ffffffffffffffffffffffffffffffffffd35c5da0eaee4cbbfeff288a3c0c3c2c78c2 + + + sect283k1/3 + 0x00896ce7c7065cc160ca721127910f598edc8b1e9be077d4756f31aee5705a00302d2e1d,0x0381c6394dbf16cf75f9e79c830e57e5a398ba77258e6d224692940eb925ec0b78ece889 + secg/sect283k1 + order = 0x7ffffffffffffffffffffffffffffffffffa6b8bb41d5dc9977fdfe511478187858f184 + + + + sect283r1/0 + 0x000000000000000000000000000000000000000000000000000000000000000000000000,0x072bcc9c5792b1ebe81983089fb6f835a2fd220a304424ca17c082ae17442aede9b9b3f6 + secg/sect283r1 + order = 2 + + + sect283r1/1 + 0x0743efa0a997ab11f696f61403759fa6dac093afe26160fa6d4620dc10c73ecbd07d868d,0x013abc297e8c6568601a70a323208d22730b654374643683bb913daaf0910ff492cfb1c5 + secg/sect283r1 + order = 0x7ffffffffffffffffffffffffffffffffffdf20732cc1f92715202cb60854f9df5b660e + + + + sect409k1/0 + 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 + secg/sect409k1 + order = 2 + + + sect409k1/1 + 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 + secg/sect409k1 + order = 4 + + + sect409k1/2 + 0x013b10b72703d774f4873f985742cce57b9377e5f89049e493eac66748870f718ae0f3ae227b6d75f7e5f810d91da79f985cefdc,0x001aea0d33e0ae234db866482308cbc579e9c7cab1fad1b62dac2a3ea16bec7ca504da1d86370fc748d1ddbc443c8a920c7b9d14 + secg/sect409k1 + order = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffcbf0765a9d440801d88aafabda7c7cf94b696b90771c03cbf9e + + + sect409k1/3 + 0x00a6cc45b0ed549286beb3f391467dcd5106fed4fb850e0ca45ac7a5291fa1f73c2ebd66b5eb2fc6c3ad93a225c20e29d76172e1,0x019c34bda5074fe8c75e1017d8b64a87766467083fb6e17a4fc57ca39c6801a31eb71e824fa225922e361db0946c4a3e7445468d + secg/sect409k1 + order = 0x1fffffffffffffffffffffffffffffffffffffffffffffffffff97e0ecb53a881003b1155f57b4f8f9f296d2d720ee380797f3c + + + + sect409r1/0 + 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,0x009935f7e4768ee2ef22f9b4a29f53cb5d93ab2ed0ad7ce57c1b2649fde895950cf6576773326c528a48e27b872accf0bc25d5ef + secg/sect409r1 + order = 2 + + + sect409r1/1 + 0x01f8a55ff6e55b1d023eca11efc629aedba15e7683f948a84ef6e3746470b2fe9f9c694f862714ec8dbb35ae8e5b760f488ae84a,0x00c0bbc113adacdb9815bb210178b081ef4b40c949fe52345ad21eab210667cc10b5ac0e60d7bb44fee1d6c544b3cc3a18ad0a23 + secg/sect409r1 + order = 0x20000000000000000000000000000000000000000000000000003c555ad4c25e6660f7cbf48f8793c0a5f0702c99a6fb34422e6 + + + + sect571k1/0 + 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 + secg/sect571k1 + order = 2 + + + sect571k1/1 + 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + secg/sect571k1 + order = 4 + + + sect571k1/2 + 0x0311efd68e031548397fd197f3c9ea9ef2048b3835bbb52c06cc89fa29a609be1a4215805132ed6c30ed743e6221f34c5d43acd3777c88a42578a7b02d2a9af488c138b206832707,0x01692831faeb78797365873933fd9c5f5223d2bceba37aa6a4f6d128973e3263b124300568f039541e51c6214409523179aaecdf76e789921d84e12991113eacd03727d4c9754920 + secg/sect571k1 + order = 0x400000000000000000000000000000000000000000000000000000000000000000000002630a1c3e334c7c9672351b722fe82716c61b097cbac72703d23bd68b9fcef1ec6f82002 + + + sect571k1/3 + 0x0519146e2a901338dce58310d786d30fd6806c620f6a7a9ba4389534dcdf16c6becdacb853fad56e4b048465b4037450468fb9bc6259448ce84a92fd8bfe9c3663dad3da48089517,0x05671e892895ca17683107f21da7741a3fdf47e546dfc6b6d2ed83c970ac88c33b7b522b0a1fe9a7dda46a7075d4881e88b9fc7f3a2002883f6c7d651f9c94252340b59b8abc0aeb + secg/sect571k1 + order = 0x800000000000000000000000000000000000000000000000000000000000000000000004c614387c6698f92ce46a36e45fd04e2d8c3612f9758e4e07a477ad173f9de3d8df04004 + + + + sect571r1/0 + 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,0x0732d556640c20b5dd739a058dffd58268d41c59135429eb041d7aa1255902e6362c4800a874ab0b60536b58460cd20c06f0340e3594a7f771bedfc10ce39b64699b08443b761c43 + secg/sect571r1 + order = 2 + + + sect571r1/1 + 0x01e4b7514be19101ec1d9f032bdba65dd1d73465bc1425e3847f44b7b2c78669358ab7bb34dec5202db32c0e65f8f4e0c5c0db8ae19537307ba6391dfa7831375b1b3957d403477a,0x00f04eb4a9ce0f18f879143faea24107682602d9319105a62c2758da491014ae34280a32830a1e239d0e89b3a3ff60acb640afc01aa56dcb8344423f0ad9f071af3d95d7675578fc + secg/sect571r1 + order = 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffccc39c31feab30e6100b3630d0470a3d8fbb39422c3bd27aa2e9acdd0705d3765fd09c8e + \ No newline at end of file -- cgit v1.2.3-70-g09d2 From ea6cc551158e9e124e2ad82cb29948ea547acf2b Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 28 Apr 2018 19:47:47 +0200 Subject: Add documentation about degenerate test suite. --- README.md | 4 +++- docs/CURVES.md | 6 ++++++ docs/TESTS.md | 15 ++++++++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) (limited to 'docs/TESTS.md') diff --git a/README.md b/README.md index 71c7042..5ff720d 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,6 @@ Following operations are tested: - Setting of custom curve and KeyPair generation - Generation of shared secret via ECDH - Signature via ECDSA -- Behavior of card when invalid curves/points are provided (should fail) See `java -jar ECTesterReader.jar -h` for more. @@ -39,6 +38,9 @@ See `java -jar ECTesterReader.jar -h` for more. -t,--test Test ECC support. [test_suite]: - default: - invalid: + - twist: + - degenerate: + - cofactor: - wrong: - composite: - test-vectors: diff --git a/docs/CURVES.md b/docs/CURVES.md index a815c5c..a0454a3 100644 --- a/docs/CURVES.md +++ b/docs/CURVES.md @@ -62,6 +62,12 @@ These points can be used to attack some implementations. Generated using [ecgen](https://github.com/J08nY/ecgen). +### degenerate +Contains pre-generated points on the line `Y: x = 0`. These points are constructed from elements of prime +order in the multiplicative group F_p given a curve over it. + +Generate manually using [PARI/GP](http://pari.math.u-bordeaux.fr/). + ### cofactor Contains curves that are composite order, with points not on the subgroup generated by the generator. diff --git a/docs/TESTS.md b/docs/TESTS.md index d2eb500..bd70206 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -6,9 +6,10 @@ - `composite` - `invalid` - `twist` + - `degenerate` - `cofactor` -**NOTE: The `wrong`, `composite`, `invalid`,`twist` and `cofactor` test suites caused temporary/permanent DoS of some cards. These test suites prompt you for +**NOTE: The `wrong`, `composite`, `invalid`,`twist`, `cofactor` and `degenerate` test suites caused temporary/permanent DoS of some cards. These test suites prompt you for confirmation before running, be cautious.** ## Default @@ -103,6 +104,18 @@ For example: java -jar ECTester.jar -t twist ``` +## Degenerate +Tests using known named curves froms several categories(SECG/NIST) against pre-generated points on the degenerate line +`Y: x = 0`. ECDH should fail, a success here might mean the card does not check that the point lies on the correct curve +and uses a curve model vulnerable to such degenerate points. + +See [Degenerate Curve Attachs - Extending Invalid Curve Attacks to Edwards Curves and Other Models](https://eprint.iacr.org/2015/1233.pdf) for more information. + +For example: +```bash +java -jar ECTester.jar -t degenerate +``` + ## Cofactor Tests whether the card correctly rejects points that lie on the curve but not on the subgroup generated by the specified generator during ECDH. -- cgit v1.2.3-70-g09d2 From 92c28a15e018e55b8f195993414f769ecf96a663 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 28 Apr 2018 21:19:16 +0200 Subject: Add degenerate curves for brainpool 512 bit prime curve. --- docs/TESTS.md | 2 +- src/cz/crcs/ectester/data/degenerate/brainpool.xml | 51 ++++++++++++++++++++-- 2 files changed, 49 insertions(+), 4 deletions(-) (limited to 'docs/TESTS.md') diff --git a/docs/TESTS.md b/docs/TESTS.md index bd70206..5f4dd9c 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -109,7 +109,7 @@ Tests using known named curves froms several categories(SECG/NIST) against pre-g `Y: x = 0`. ECDH should fail, a success here might mean the card does not check that the point lies on the correct curve and uses a curve model vulnerable to such degenerate points. -See [Degenerate Curve Attachs - Extending Invalid Curve Attacks to Edwards Curves and Other Models](https://eprint.iacr.org/2015/1233.pdf) for more information. +See [Degenerate Curve Attacks - Extending Invalid Curve Attacks to Edwards Curves and Other Models](https://eprint.iacr.org/2015/1233.pdf) for more information. For example: ```bash diff --git a/src/cz/crcs/ectester/data/degenerate/brainpool.xml b/src/cz/crcs/ectester/data/degenerate/brainpool.xml index 9dc860a..3dd2f54 100644 --- a/src/cz/crcs/ectester/data/degenerate/brainpool.xml +++ b/src/cz/crcs/ectester/data/degenerate/brainpool.xml @@ -310,8 +310,53 @@ generator of Fp^* - + + brainpoolP512r1/0 + 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca703308717d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f2 + brainpool/brainpoolP512r1 + degenerate order = 2 + + + brainpoolP512r1/1 + 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,0x177c47f1f2bd3306efe5a93ed046a559abbb32424d5887e6c3f49c23c907c5a3b68aee1d7ae4247ba3491698c3c7c4dd9e105383f58984e45b4104cce042417b + brainpool/brainpoolP512r1 + degenerate order = 7 + + + brainpoolP512r1/2 + 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,0x9b9e9905d13f35cc5b6578523e0380be922803fa98bcde94c920aca572a8fb4a432520b51b0f9eb3d854aa14aa5ef9fcc4ac08bf06eaec4b98ffdf90244f67d7 + brainpool/brainpoolP512r1 + degenerate order = 61 + + + brainpoolP512r1/3 + 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,0x77b03a217034dd2adcbcbfbdfe879b4ce1f0ecdd6025d1c3da80bef3e905a34bfdcb88362d553219b025cb8123698296c437411ecba452db94d829729def073e + brainpool/brainpoolP512r1 + degenerate order = 329430728783919403 + + + brainpoolP512r1/4 + 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,0x890e0b1d03bd78442f0144b752cce879cec7a069497a83a6dac714a37221fa282ef147385b796653c2b98c87c003a7285ee98f69ed3df135c6a59adf8f17be5a + brainpool/brainpoolP512r1 + degenerate order = 18335424362847464339 + + + brainpoolP512r1/5 + 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,0x25c0f1328c75876e338e66fb112cd47e8936c41b57dbf2c97de9c6bf300fb035bbcb20fb44046e6172c00939075da436b9c7d84941a9b98219fced6d9e17da64 + brainpool/brainpoolP512r1 + degenerate order = 120179186709126902983513742993 + + + brainpoolP512r1/6 + 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,0x1d93c72f487fc4ad34cb0c522dda3a7067b1b5c11175fc90ebbd086f639cad2d30d345e5596a93136e48aad4226cdb1a320e4b0aa68da2ca62cd5fe51c601f8e + brainpool/brainpoolP512r1 + degenerate order = 14435454750020088047685444818571282397270727096595623715684950293729763357371155607979 + + + brainpoolP512r1/gen + 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002 + brainpool/brainpoolP512r1 + generator of Fp^* + -- cgit v1.2.3-70-g09d2 From 78e5e3d53c20bac2cb33e7ace8565173651c6155 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 2 May 2018 20:33:42 +0200 Subject: Add compression suite to docs and comments. --- README.md | 60 +++++++++++++--------- docs/TESTS.md | 23 ++++++--- src/cz/crcs/ectester/reader/ECTesterReader.java | 2 +- .../ectester/reader/test/CardCompressionSuite.java | 3 +- 4 files changed, 54 insertions(+), 34 deletions(-) (limited to 'docs/TESTS.md') diff --git a/README.md b/README.md index 5ff720d..7b280bb 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ See `java -jar ECTesterReader.jar -h` for more. -t,--test Test ECC support. [test_suite]: - default: - invalid: + - compression: - twist: - degenerate: - cofactor: @@ -158,32 +159,41 @@ This shows that JCardsim simulates 112b Fp support with default curve present an > java -jar ECTesterReader.jar -t -s ═══ Running test suite: default ═══ - ═══ The default test suite run basic support of ECDH and ECDSA. + ═══ The default test suite tests basic support of ECDH and ECDSA. + ═══ Date: 2018.05.02 20:29:38 + ═══ ECTester version: v0.2.0 ═══ Card ATR: 3bfa1800008131fe454a434f5033315632333298 - NOK ┳ Tests of 112b ALG_EC_FP support. Some. ┃ FAILURE ┃ Some sub-tests did not have the expected result. - ┣ OK ━ Allocated both keypairs 112b ALG_EC_FP ┃ SUCCESS ┃ 50 ms ┃ OK (0x9000) OK (0x9000) - ┣ OK ━ Generated both keypairs ┃ SUCCESS ┃ 37 ms ┃ OK (0x9000) OK (0x9000) - ┣ OK ━ Set custom curve parameters on both keypairs ┃ SUCCESS ┃ 0 ms ┃ OK (0x9000) OK (0x9000) - ┣ OK ━ Generated both keypairs ┃ SUCCESS ┃ 16 ms ┃ OK (0x9000) OK (0x9000) - ┣ OK ┳ Test of the ALG_EC_SVDP_DH KeyAgreement. ┃ SUCCESS ┃ All sub-tests had the expected result. - ┃ ┣ OK ━ Allocated KeyAgreement(ALG_EC_SVDP_DH) object ┃ SUCCESS ┃ 2 ms ┃ OK (0x9000) - ┃ ┣ OK ━ ALG_EC_SVDP_DH of local pubkey and remote privkey(unchanged point) ┃ SUCCESS ┃ 7 ms ┃ OK (0x9000) - ┃ ┗ OK ━ ALG_EC_SVDP_DH of local pubkey and remote privkey(COMPRESSED point) ┃ SUCCESS ┃ 14 ms ┃ OK (0x9000) - ┣ OK ┳ Test of the ALG_EC_SVDP_DHC KeyAgreement. ┃ SUCCESS ┃ All sub-tests had the expected result. - ┃ ┣ OK ━ Allocated KeyAgreement(ALG_EC_SVDP_DHC) object ┃ SUCCESS ┃ 0 ms ┃ OK (0x9000) - ┃ ┣ OK ━ ALG_EC_SVDP_DHC of local pubkey and remote privkey(unchanged point) ┃ SUCCESS ┃ 3 ms ┃ OK (0x9000) - ┃ ┗ OK ━ ALG_EC_SVDP_DHC of local pubkey and remote privkey(COMPRESSED point) ┃ SUCCESS ┃ 5 ms ┃ OK (0x9000) - ┣ NOK ━ Allocated KeyAgreement(ALG_EC_SVDP_DH_PLAIN) object ┃ FAILURE ┃ 0 ms ┃ fail (NO_SUCH_ALG, 0x0003) - ┣ NOK ━ Allocated KeyAgreement(ALG_EC_SVDP_DHC_PLAIN) object ┃ FAILURE ┃ 0 ms ┃ fail (NO_SUCH_ALG, 0x0003) - ┣ NOK ━ Allocated KeyAgreement(ALG_EC_PACE_GM) object ┃ FAILURE ┃ 0 ms ┃ fail (NO_SUCH_ALG, 0x0003) - ┣ NOK ━ Allocated KeyAgreement(ALG_EC_SVDP_DH_PLAIN_XY) object ┃ FAILURE ┃ 0 ms ┃ fail (NO_SUCH_ALG, 0x0003) - ┣ OK ┳ Test of the ALG_ECDSA_SHA signature. ┃ SUCCESS ┃ All sub-tests had the expected result. - ┃ ┣ OK ━ Allocated Signature(ALG_ECDSA_SHA) object ┃ SUCCESS ┃ 7 ms ┃ OK (0x9000) - ┃ ┗ OK ━ ALG_ECDSA_SHA with local keypair(random data) ┃ SUCCESS ┃ 43 ms ┃ OK (0x9000) - ┣ NOK ━ Allocated Signature(ALG_ECDSA_SHA_224) object ┃ FAILURE ┃ 0 ms ┃ fail (NO_SUCH_ALG, 0x0003) - ┣ NOK ━ Allocated Signature(ALG_ECDSA_SHA_256) object ┃ FAILURE ┃ 0 ms ┃ fail (NO_SUCH_ALG, 0x0003) - ┣ NOK ━ Allocated Signature(ALG_ECDSA_SHA_384) object ┃ FAILURE ┃ 0 ms ┃ fail (NO_SUCH_ALG, 0x0003) - ┗ NOK ━ Allocated Signature(ALG_ECDSA_SHA_512) object ┃ FAILURE ┃ 0 ms ┃ fail (NO_SUCH_ALG, 0x0003) + OK ┳ Tests of 112b ALG_EC_FP support. ┃ SUCCESS ┃ All sub-tests matched the expected mask. + ┣ OK ━ Allocate both keypairs 112b ALG_EC_FP ┃ SUCCESS ┃ 22 ms ┃ OK (0x9000) OK (0x9000) + ┣ OK ━ Generate both keypairs ┃ SUCCESS ┃ 23 ms ┃ OK (0x9000) OK (0x9000) + ┣ OK ━ Allocate both keypairs 112b ALG_EC_FP ┃ SUCCESS ┃ 0 ms ┃ OK (0x9000) OK (0x9000) + ┣ OK ━ Set custom curve parameters on both keypairs ┃ SUCCESS ┃ 0 ms ┃ OK (0x9000) OK (0x9000) + ┣ OK ━ Generate both keypairs ┃ SUCCESS ┃ 8 ms ┃ OK (0x9000) OK (0x9000) + ┣ OK ┳ KeyAgreement tests. ┃ SUCCESS ┃ Some sub-tests did have the expected result. + ┃ ┣ OK ┳ Test of the ALG_EC_SVDP_DH KeyAgreement. ┃ SUCCESS ┃ Some ECDH is supported. + ┃ ┃ ┣ OK ━ Allocate KeyAgreement(ALG_EC_SVDP_DH) object ┃ SUCCESS ┃ 1 ms ┃ OK (0x9000) + ┃ ┃ ┣ OK ━ ALG_EC_SVDP_DH of local pubkey and remote privkey(unchanged point) ┃ SUCCESS ┃ 2 ms ┃ OK (0x9000) + ┃ ┃ ┣ OK ━ ALG_EC_SVDP_DH of local pubkey and remote privkey(COMPRESSED point) ┃ SUCCESS ┃ 2 ms ┃ OK (0x9000) + ┃ ┃ ┗ OK ━ Mean = 1722885 ns, Median = 1718807 ns, Mode = 1614047 ns ┃ SUCCESS ┃ 1 ms ┃ OK (0x9000) + ┃ ┣ OK ┳ Test of the ALG_EC_SVDP_DHC KeyAgreement. ┃ SUCCESS ┃ Some ECDH is supported. + ┃ ┃ ┣ OK ━ Allocate KeyAgreement(ALG_EC_SVDP_DHC) object ┃ SUCCESS ┃ 0 ms ┃ OK (0x9000) + ┃ ┃ ┣ OK ━ ALG_EC_SVDP_DHC of local pubkey and remote privkey(unchanged point) ┃ SUCCESS ┃ 1 ms ┃ OK (0x9000) + ┃ ┃ ┣ OK ━ ALG_EC_SVDP_DHC of local pubkey and remote privkey(COMPRESSED point) ┃ SUCCESS ┃ 1 ms ┃ OK (0x9000) + ┃ ┃ ┗ OK ━ Mean = 1563980 ns, Median = 1549170 ns, Mode = 1514747 ns ┃ SUCCESS ┃ 1 ms ┃ OK (0x9000) + ┃ ┣ NOK ━ Allocate KeyAgreement(ALG_EC_SVDP_DH_PLAIN) object ┃ FAILURE ┃ 0 ms ┃ fail (NO_SUCH_ALG, 0x0003) + ┃ ┣ NOK ━ Allocate KeyAgreement(ALG_EC_SVDP_DHC_PLAIN) object ┃ FAILURE ┃ 0 ms ┃ fail (NO_SUCH_ALG, 0x0003) + ┃ ┣ NOK ━ Allocate KeyAgreement(ALG_EC_PACE_GM) object ┃ FAILURE ┃ 0 ms ┃ fail (NO_SUCH_ALG, 0x0003) + ┃ ┗ NOK ━ Allocate KeyAgreement(ALG_EC_SVDP_DH_PLAIN_XY) object ┃ FAILURE ┃ 0 ms ┃ fail (NO_SUCH_ALG, 0x0003) + ┗ OK ┳ Signature tests. ┃ SUCCESS ┃ Some sub-tests did have the expected result. + ┣ OK ┳ Test of the ALG_ECDSA_SHA signature. ┃ SUCCESS ┃ All sub-tests had the expected result. + ┃ ┣ OK ━ Allocate Signature(ALG_ECDSA_SHA) object ┃ SUCCESS ┃ 3 ms ┃ OK (0x9000) + ┃ ┣ OK ━ ALG_ECDSA_SHA with local keypair(random data) ┃ SUCCESS ┃ 14 ms ┃ OK (0x9000) + ┃ ┣ OK ━ Sign (Mean = 1890914 ns, Median = 1500125 ns, Mode = 1422588 ns) ┃ SUCCESS ┃ 1 ms ┃ OK (0x9000) + ┃ ┗ OK ━ Verify (Mean = 1873952 ns, Median = 1870348 ns, Mode = 1843902 ns) ┃ SUCCESS ┃ 1 ms ┃ OK (0x9000) + ┣ NOK ━ Allocate Signature(ALG_ECDSA_SHA_224) object ┃ FAILURE ┃ 0 ms ┃ fail (NO_SUCH_ALG, 0x0003) + ┣ NOK ━ Allocate Signature(ALG_ECDSA_SHA_256) object ┃ FAILURE ┃ 0 ms ┃ fail (NO_SUCH_ALG, 0x0003) + ┣ NOK ━ Allocate Signature(ALG_ECDSA_SHA_384) object ┃ FAILURE ┃ 0 ms ┃ fail (NO_SUCH_ALG, 0x0003) + ┗ NOK ━ Allocate Signature(ALG_ECDSA_SHA_512) object ┃ FAILURE ┃ 0 ms ┃ fail (NO_SUCH_ALG, 0x0003) #### Legend - Some general information about the test suite and card is output first, test data follows after. diff --git a/docs/TESTS.md b/docs/TESTS.md index 5f4dd9c..d2c3ab5 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -2,14 +2,15 @@ - `default` - `test-vectors` - - `wrong` - - `composite` - - `invalid` - - `twist` - - `degenerate` - - `cofactor` + - `compression` + - `wrong`* + - `composite`* + - `invalid`* + - `twist`* + - `degenerate`* + - `cofactor`* -**NOTE: The `wrong`, `composite`, `invalid`,`twist`, `cofactor` and `degenerate` test suites caused temporary/permanent DoS of some cards. These test suites prompt you for +**\*NOTE: The `wrong`, `composite`, `invalid`,`twist`, `cofactor` and `degenerate` test suites caused temporary/permanent DoS of some cards. These test suites prompt you for confirmation before running, be cautious.** ## Default @@ -43,6 +44,14 @@ java -jar ECTester.jar -t test-vectors ``` tests all curves for which test-vectors are provided. +## Compression +Tests support for compression of public points in ECDH as specified in ANSI X9.62. Tests ECDH with points in compressed +and hybrid form. Also tests card response to a hybrid point with wrong `y` coordinate and to the point at infinity(as public key in ECDH). + +For example: +```bash +java -jar ECTester.jar -t compression +``` ## Wrong Tests on a category of wrong curves. These curves are not really curves as they have: diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index 6098cd4..68bb3d8 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -247,7 +247,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- invalid:\n- twist:\n- degenerate:\n- cofactor:\n- wrong:\n- composite:\n- test-vectors:").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:").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()); diff --git a/src/cz/crcs/ectester/reader/test/CardCompressionSuite.java b/src/cz/crcs/ectester/reader/test/CardCompressionSuite.java index 7300653..e58c38d 100644 --- a/src/cz/crcs/ectester/reader/test/CardCompressionSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCompressionSuite.java @@ -24,7 +24,8 @@ import java.util.List; */ public class CardCompressionSuite extends CardTestSuite { public CardCompressionSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { - super(writer, cfg, cardManager, "compression", ""); + super(writer, cfg, cardManager, "compression", "The compression test suite tests cards support for compressed points in ECDH (as per ANSI X9.62).\n" + + "It also tests for handling of bogus input by using the point at infinity and a hybrid point with the y coordinate corrupted."); } @Override -- cgit v1.2.3-70-g09d2 From d22fb876d79dd16cb1f762a732ba8acb6c8b401c Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 25 May 2018 20:56:40 +0200 Subject: Add docs about edge-cases suite and wycheproof data. --- docs/CURVES.md | 7 ++++++- docs/TESTS.md | 17 ++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) (limited to 'docs/TESTS.md') diff --git a/docs/CURVES.md b/docs/CURVES.md index a0454a3..78a5a4c 100644 --- a/docs/CURVES.md +++ b/docs/CURVES.md @@ -71,4 +71,9 @@ Generate manually using [PARI/GP](http://pari.math.u-bordeaux.fr/). ### cofactor Contains curves that are composite order, with points not on the subgroup generated by the generator. -Generated using [ecgen](https://github.com/J08nY/ecgen). \ No newline at end of file +Generated using [ecgen](https://github.com/J08nY/ecgen). + +## Other + +### Wycheproof +Contains some test vectors from the [google/Wycheproof](https://github.com/google/wycheproof) project. \ No newline at end of file diff --git a/docs/TESTS.md b/docs/TESTS.md index d2c3ab5..ebb8150 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -9,8 +9,9 @@ - `twist`* - `degenerate`* - `cofactor`* + - `edge-cases`* -**\*NOTE: The `wrong`, `composite`, `invalid`,`twist`, `cofactor` and `degenerate` test suites caused temporary/permanent DoS of some cards. These test suites prompt you for +**\*NOTE: The `wrong`, `composite`, `invalid`,`twist`, `cofactor`, `edge-cases` and `degenerate` test suites caused temporary/permanent DoS of some cards. These test suites prompt you for confirmation before running, be cautious.** ## Default @@ -132,4 +133,18 @@ during ECDH. For example: ```bash java -jar ECTester.jar -t cofactor +``` + +## Edge-Cases +Tests various inputs to ECDH which may cause an implementation to achieve a certain edge-case state during ECDH. +Some of the data is from the google/Wycheproof project. Tests include [CVE-2017-10176](https://nvd.nist.gov/vuln/detail/CVE-2017-10176) and [CVE-2017-8932](https://nvd.nist.gov/vuln/detail/CVE-2017-8932). + +CVE-2017-10176 was in implementation issue in the SunEC Java library that caused the implementation to reach the point at infinity during ECDH computation. + +CVE-2017-8932 was an implementation issue in the Go standard library, in particular its scalar multiplication algorithm on the +P-256 curve which leaked information about the private key. + +For example: +```bash +java -jar ECTester.jar -t edge-cases ``` \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 07cfc81f909ebeee6ea88a5671749bc44e5c6769 Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 28 Jun 2018 17:15:30 +0200 Subject: Add descriptions to composite curve data. --- docs/TESTS.md | 4 + src/cz/crcs/ectester/data/composite/curves.xml | 87 +++++++++++++--------- .../ectester/reader/test/CardWrongCurvesSuite.java | 2 +- 3 files changed, 56 insertions(+), 37 deletions(-) (limited to 'docs/TESTS.md') diff --git a/docs/TESTS.md b/docs/TESTS.md index ebb8150..c62234b 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -65,6 +65,10 @@ This test suite also does some additional tests with corrupting the field parame - p = 1 - p = q^2; q prime - p = q * s; q and s prime + - G = infinity + - G = random point not on curve + - r = some prime (and \[r\]G != infinity) + - r = some composite number (and \[r\]G != infinity) - F2m: - e1 = e2 = e3 = 0 - m < e1 < e2 < e3 diff --git a/src/cz/crcs/ectester/data/composite/curves.xml b/src/cz/crcs/ectester/data/composite/curves.xml index 4d6a16a..a1abe2e 100644 --- a/src/cz/crcs/ectester/data/composite/curves.xml +++ b/src/cz/crcs/ectester/data/composite/curves.xml @@ -6,83 +6,98 @@ 128 prime composite128.csv - - - small/composite128 - 128 - prime - composite128_small.csv + r = order = 0x03 * 0x05 * 0x3b * 0x3a107e02cd073c8e24bf55730f1733 whole/composite160 160 prime composite160.csv - - - small/composite160 - 160 - prime - composite160_small.csv + r = order = 0x02 * 0x03 * 0x6b * 0x1ee99b75143833bbc11d409601c25f9566a001 whole/composite192 192 prime composite192.csv - - - small/composite192 - 192 - prime - composite192_small.csv + r = order = 0x02 * 0x03 * 0x05 * 0x13 * 0x19bc3c00e2a7ad9e40d12e5d9e29a2b5ce80b3a3e84295 whole/composite224 224 prime composite224.csv - - - small/composite224 - 224 - prime - composite224_small.csv + r = order = 0x02 * 0x03 * 0x1d * 0x1538e6a6dc906d724a7bf51c77bce9d46865bd92d8bca01f887405 whole/composite256 256 prime composite256.csv - - - small/composite256 - 256 - prime - composite256_small.csv + r = order = 0x02 * 0x05 * 0x11 * 0x1382cadcdd2b90b90b81eda82433bf574b5d8f5654dcc62341c7e967f2e811 whole/composite384 384 prime composite384.csv - - - small/composite384 - 384 - prime - composite384_small.csv + r = order = 0x05 * 0x0b * 0x3d * 0xb16aa7dc50145337cf1b2f38018ccb5cf44c22a2f7d7c22bbe5c572d2cb9a04cb1081357c6a1c97cc39ab62596867 whole/composite521 521 prime composite521.csv + r = order = 0x02 * 0x05 * 0x1f * 0x4a5aac4fac3ea253b66c3e650f5173b30467f28b8e841d37ce69bb0831a5939ad3dd082b750577ec4592d4d58916c87a9b732d8ddae435c26f8f779d2467f50f + + + + small/composite128 + 128 + prime + composite128_small.csv + r = 0x03 + + + small/composite160 + 160 + prime + composite160_small.csv + r = 0x03 + + + small/composite192 + 192 + prime + composite192_small.csv + r = 0x03 + + + small/composite224 + 224 + prime + composite224_small.csv + r = 0x03 + + + small/composite256 + 256 + prime + composite256_small.csv + r = 0x05 + + + small/composite384 + 384 + prime + composite384_small.csv + r = 0x05 small/composite521 521 prime composite521_small.csv + r = 0x05 \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java index f95a386..8b648b9 100644 --- a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java @@ -111,8 +111,8 @@ public class CardWrongCurvesSuite extends CardTestSuite { Test resetSetup = CompoundTest.all(ExpectedValue.SUCCESS, "Reset keypair.", set.clone()); - 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 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]; -- 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 'docs/TESTS.md') 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 050541a45d16597099e86b14d0fdf4e123a8e93e Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 3 Jul 2018 15:03:31 +0200 Subject: Update docs and README. --- README.md | 2 ++ docs/CURVES.md | 10 ++++++++++ docs/TESTS.md | 3 ++- 3 files changed, 14 insertions(+), 1 deletion(-) (limited to 'docs/TESTS.md') diff --git a/README.md b/README.md index 7b280bb..9305e3c 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,8 @@ See `java -jar ECTesterReader.jar -h` for more. constants. -sig,--sig-type Set Signature object [type], corresponds to JC.Signature constants. + -C,--color Print stuff with color, requires ANSI + terminal. ``` ### Actions diff --git a/docs/CURVES.md b/docs/CURVES.md index 78a5a4c..a9b8b68 100644 --- a/docs/CURVES.md +++ b/docs/CURVES.md @@ -33,6 +33,16 @@ GOST R 34.10-2001: RFC5832 curves. [Source](https://tools.ietf.org/html/rfc5832) +### Barreto-Naehrig +Barreto-Naehrig curves from: A Family of Implementation-Friendly BN Elliptic Curves + +[Source](https://eprint.iacr.org/2010/429.pdf) + +### Other +An assortment of some other curves. +Montgomery curves transformed into short Weierstrass form from +Curve25519 transformed into short Weierstrass form. + ## Generated diff --git a/docs/TESTS.md b/docs/TESTS.md index 59bd27b..5ec3b63 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -135,7 +135,8 @@ java -jar ECTester.jar -t degenerate ## Cofactor Tests whether the card correctly rejects points that lie on the curve but not on the subgroup generated by the specified generator -during ECDH. +during ECDH. Does this with curves where the cofactor subgroup has small order, then with curves that have order equal to the product +of two large primes, sets the generator with order of one prime and tries points on the subgroup of the other prime order. For example: ```bash -- 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 'docs/TESTS.md') 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 From 80ec2bcb69d62267e97f1801f21aed5fe46f109f Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 23 Jul 2018 18:53:35 +0200 Subject: Update docs on TESTS. --- README.md | 5 +++++ docs/TESTS.md | 22 +++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) (limited to 'docs/TESTS.md') diff --git a/README.md b/README.md index 1bcef72..daabdd9 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,9 @@ See `java -jar ECTesterReader.jar -h` for more. text,yml,xml. -f,--fresh Generate fresh keys (set domain parameters before every generation). + --cleanup Send the cleanup command trigerring + JCSystem.requestObjectDeletion() + after some operations. -s,--simulate Simulate a card with jcardsim instead of using a terminal. -y,--yes Accept all warnings and prompts. @@ -218,6 +221,8 @@ If you are interested in testing support for other JavaCard algorithms, please v Currently supported libraries include: - BouncyCastle - SunEC + - OpenSSL + - Crypto++ - libtomcrypt - botan diff --git a/docs/TESTS.md b/docs/TESTS.md index 4d71ea6..5811577 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -66,10 +66,16 @@ This test suite also does some additional tests with corrupting the parameters: - p = 1 - p = q^2; q prime - p = q * s; q and s prime - - G = infinity - G = random point not on curve - - r = some prime (and \[r\]G != infinity) + - G = random data + - G = infinity + - r = 0 + - r = 1 + - r = some prime larger than original r (and \[r\]G != infinity) + - r = some prime smaller than original r (and \[r\]G != infninity) - r = some composite number (and \[r\]G != infinity) + - k = 0xff + - k = 0 - F2m: - e1 = e2 = e3 = 0 - m < e1 < e2 < e3 @@ -88,7 +94,10 @@ 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 = quite a smooth number, many small factors, r = |G| + - r = small prime(of increasing bit lengths), r = |G| + - r = p * q = |G| + - r = G = Carmichael number = p * q * s - \[r\]G = infinity but r != |G|, so |G| divides r For example: @@ -147,12 +156,19 @@ java -jar ECTester.jar -t cofactor ## Edge-Cases Tests various inputs to ECDH which may cause an implementation to achieve a certain edge-case state during ECDH. Some of the data is from the google/Wycheproof project. Tests include [CVE-2017-10176](https://nvd.nist.gov/vuln/detail/CVE-2017-10176) and [CVE-2017-8932](https://nvd.nist.gov/vuln/detail/CVE-2017-8932). +Various custom edge private key values are also tested. CVE-2017-10176 was in implementation issue in the SunEC Java library that caused the implementation to reach the point at infinity during ECDH computation. CVE-2017-8932 was an implementation issue in the Go standard library, in particular its scalar multiplication algorithm on the P-256 curve which leaked information about the private key. +Custom private key values over SECG curves are tested: + - s = 0, s = 1 + - s < r, s = r, s > r + - s = r - 1, s = r + 1 + - s = k\*r - 1, s = k\*r, s = k\*r + 1 + For example: ```bash java -jar ECTester.jar -t edge-cases -- cgit v1.2.3-70-g09d2