summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/TESTS.md3
-rw-r--r--src/cz/crcs/ectester/data/other/keys.xml14
-rw-r--r--src/cz/crcs/ectester/data/other/results.xml14
-rw-r--r--src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java27
4 files changed, 57 insertions, 1 deletions
diff --git a/docs/TESTS.md b/docs/TESTS.md
index 2d535f8..c639722 100644
--- a/docs/TESTS.md
+++ b/docs/TESTS.md
@@ -144,7 +144,8 @@ of two large primes, sets the generator with order of one prime and tries points
## 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).
+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) and an OpenSSL modular reduction bug
+presented in [Practical realisation and elimination of an ECC-related software bug attack](https://eprint.iacr.org/2011/633).
Various custom edge private key values are also tested.
CVE-2017-10176 was in implementation issue in the SunEC Java library (and NSS ([CVE-2017-7781](https://nvd.nist.gov/vuln/detail/CVE-2017-7781)), thus also anything that used it) that caused the implementation to reach the point at infinity during ECDH computation.
diff --git a/src/cz/crcs/ectester/data/other/keys.xml b/src/cz/crcs/ectester/data/other/keys.xml
new file mode 100644
index 0000000..d06de81
--- /dev/null
+++ b/src/cz/crcs/ectester/data/other/keys.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<keys xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="../schema.xsd">
+ <privkey>
+ <id>openssl-bug/skey</id>
+ <inline>0x4543A4D2C9DDD5516FD16D5498034C76D4EAB340276B6BAD8FF57756F4ECA8E6</inline>
+ <curve>secg/secp256r1</curve>
+ </privkey>
+ <pubkey>
+ <id>openssl-bug/pkey</id>
+ <inline>0x296D416994A4801B9A48E8C67C98E0C05DE1C0E85D4DC676F32FEACDC4998F0E,0xA91F9BE06C1D50EEB0295A35CA0F130F17EA647147626318E28AEC97F0653749</inline>
+ <curve>secg/secp256r1</curve>
+ </pubkey>
+</keys> \ No newline at end of file
diff --git a/src/cz/crcs/ectester/data/other/results.xml b/src/cz/crcs/ectester/data/other/results.xml
new file mode 100644
index 0000000..ba8c83c
--- /dev/null
+++ b/src/cz/crcs/ectester/data/other/results.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<results xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="../schema.xsd">
+ <kaResult>
+ <id>openssl-bug</id>
+ <ka>DH</ka>
+ <inline>0xdb6f7cd6a06846bf9da9b4928caa5e4b7c8f58d9</inline>
+ <!-- == SHA1(0x1D0F27241C177385B0D5025029FABD5D5D8475DA4E267DCD177B49C63605C25A) -->
+ <curve>secg/secp256r1</curve>
+ <onekey>other/openssl-bug/pkey</onekey>
+ <otherkey>other/openssl-bug/skey</otherkey>
+ <desc>https://eprint.iacr.org/2011/633</desc>
+ </kaResult>
+</results> \ No newline at end of file
diff --git a/src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java b/src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java
index cd31179..b68b2ec 100644
--- a/src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java
@@ -110,6 +110,33 @@ public class CardEdgeCasesSuite extends CardTestSuite {
doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, description, groupTests.toArray(new Test[0])));
}
+ {
+ EC_KAResult openssl_bug = EC_Store.getInstance().getObject(EC_KAResult.class, "other", "openssl-bug");
+ EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, openssl_bug.getCurve());
+ EC_Key.Private skey = EC_Store.getInstance().getObject(EC_Key.Private.class, openssl_bug.getOtherKey());
+ EC_Key.Public pkey = EC_Store.getInstance().getObject(EC_Key.Public.class, openssl_bug.getOneKey());
+ Test key = CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), KeyPair.ALG_EC_FP), 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 setPrivate = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, skey.flatten(EC_Consts.PARAMETER_S)), Result.ExpectedValue.SUCCESS);
+ Test setPublic = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, pkey.flatten(EC_Consts.PARAMETER_W)), Result.ExpectedValue.SUCCESS);
+ Test ecdh = CommandTest.function(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, openssl_bug.getJavaCardKA()), new TestCallback<CommandTestable>() {
+ @Override
+ public Result apply(CommandTestable testable) {
+ Response.ECDH dh = (Response.ECDH) testable.getResponse();
+ if (!dh.successful())
+ return new Result(Result.Value.FAILURE, "ECDH was unsuccessful.");
+ if (!dh.hasSecret())
+ return new Result(Result.Value.FAILURE, "ECDH response did not contain the derived secret.");
+ if (ByteUtil.compareBytes(dh.getSecret(), 0, openssl_bug.getData(0), 0, dh.secretLength())) {
+ return new Result(Result.Value.FAILURE, "OpenSSL bug is present, derived secret matches example.");
+ }
+ return new Result(Result.Value.SUCCESS);
+ }
+ });
+
+ doTest(CompoundTest.greedyAll(Result.ExpectedValue.SUCCESS, "Test OpenSSL modular reduction bug.", key, set, setPrivate, setPublic, ecdh));
+ }
+
Map<String, EC_Curve> curveMap = EC_Store.getInstance().getObjects(EC_Curve.class, "secg");
List<EC_Curve> curves = curveMap.entrySet().stream().filter((e) -> e.getKey().endsWith("r1") && e.getValue().getField() == KeyPair.ALG_EC_FP).map(Map.Entry::getValue).collect(Collectors.toList());
curves.add(EC_Store.getInstance().getObject(EC_Curve.class, "cofactor/cofactor128p2"));