From ea4e807906815c16c62c4e5719950c7274d1ebab Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 15 Oct 2018 17:48:23 +0200 Subject: Add test for OpenSSl modular reduction bug. --- docs/TESTS.md | 3 ++- src/cz/crcs/ectester/data/other/keys.xml | 14 +++++++++++ src/cz/crcs/ectester/data/other/results.xml | 14 +++++++++++ .../ectester/reader/test/CardEdgeCasesSuite.java | 27 ++++++++++++++++++++++ 4 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 src/cz/crcs/ectester/data/other/keys.xml create mode 100644 src/cz/crcs/ectester/data/other/results.xml 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 @@ + + + + openssl-bug/skey + 0x4543A4D2C9DDD5516FD16D5498034C76D4EAB340276B6BAD8FF57756F4ECA8E6 + secg/secp256r1 + + + openssl-bug/pkey + 0x296D416994A4801B9A48E8C67C98E0C05DE1C0E85D4DC676F32FEACDC4998F0E,0xA91F9BE06C1D50EEB0295A35CA0F130F17EA647147626318E28AEC97F0653749 + secg/secp256r1 + + \ 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 @@ + + + + openssl-bug + DH + 0xdb6f7cd6a06846bf9da9b4928caa5e4b7c8f58d9 + + secg/secp256r1 + other/openssl-bug/pkey + other/openssl-bug/skey + https://eprint.iacr.org/2011/633 + + \ 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() { + @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 curveMap = EC_Store.getInstance().getObjects(EC_Curve.class, "secg"); List 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")); -- cgit v1.2.3-70-g09d2