diff options
| -rw-r--r-- | docs/TESTS.md | 3 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/data/other/keys.xml | 14 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/data/other/results.xml | 14 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java | 27 |
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")); |
