aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ08nY2018-03-03 23:14:08 +0100
committerJ08nY2018-03-03 23:14:08 +0100
commit510116dd24fdd2e676d405eeede5309acef903f9 (patch)
tree31b8af6131911de80aab28989c9ee84864c60426
parentee2139fe5f076d79382428f85be4108a1801987e (diff)
downloadECTester-510116dd24fdd2e676d405eeede5309acef903f9.tar.gz
ECTester-510116dd24fdd2e676d405eeede5309acef903f9.tar.zst
ECTester-510116dd24fdd2e676d405eeede5309acef903f9.zip
-rw-r--r--docs/CURVES.md5
-rw-r--r--docs/TESTS.md12
-rw-r--r--src/cz/crcs/ectester/reader/ECTesterReader.java7
-rw-r--r--src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java60
4 files changed, 81 insertions, 3 deletions
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<String, EC_Key.Public> pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "cofactor");
+ Map<EC_Curve, List<EC_Key.Public>> curves = new HashMap<>();
+ for (EC_Key.Public key : pubkeys.values()) {
+ EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, key.getCurve());
+ List<EC_Key.Public> keys = curves.getOrDefault(curve, new LinkedList<>());
+ keys.add(key);
+ curves.putIfAbsent(curve, keys);
+ }
+ for (Map.Entry<EC_Curve, List<EC_Key.Public>> e : curves.entrySet()) {
+ EC_Curve curve = e.getKey();
+ List<EC_Key.Public> keys = e.getValue();
+
+ Test allocate = CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS);
+ Test 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<Test> 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();
+ }
+ }
+}