First, background and history: In Java, an ECDH public key can be encoded as a SubjectPublicKeyInfo spec [1]. This spec contains the public point, and a named curve or curve parameters [2]. To test ECDH libraries, Wycheproof generates public key specs with modified curve parameters, and checks that the libraries must reject them [3]. Android M and N (and possibly other versions) do not reject said public keys specs. Given a spec Android just takes the field ID, and derives the rest of the parameters. This leads to a somewhat interesting situation: not only Android accepts Wycheproof's modified public key specs, but it also computes the shared secrets correctly and securely. So we changed Wycheproof to accept Android's behavior, and added to each test case the expected shared secret, had the public key spec not been modified. What went wrong: The expected shared secrets for "modified prime" and "public key of order 3" test are incorrect. I found that the public key specs (the "public" field in the ecdh_test.json) don't contain the same public point as in other tests. I'm not sure this is intentional, but because the public point is different the expected shared secret must be different too. Let's look at test case #336. Its expected shared secret is the same as test case #335. Yet two test cases contain two different public points, as shown below ( the public point is the last BIT STRING, it starts with 04): # Test case 335 0 304: SEQUENCE { 4 233: SEQUENCE { 7 7: OBJECT IDENTIFIER '1 2 840 10045 2 1' 16 221: SEQUENCE { 19 1: INTEGER 1 22 44: SEQUENCE { 24 7: OBJECT IDENTIFIER '1 2 840 10045 1 1' 33 33: INTEGER : 00 FF FF FF FF 00 00 00 01 00 00 00 00 00 00 00 : 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF : FF : } 68 68: SEQUENCE { 70 32: OCTET STRING : FF FF FF FF 00 00 00 01 00 00 00 00 00 00 00 00 : 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FC 104 32: OCTET STRING : 5A C6 35 D8 AA 3A 93 E7 B3 EB BD 55 76 98 86 BC : 65 1D 06 B0 CC 53 B0 F6 3B CE 3C 3E 27 D2 60 4B : } 138 65: OCTET STRING : 04 6B 17 D1 F2 E1 2C 42 47 F8 BC E6 E5 63 A4 40 : F2 77 03 7D 81 2D EB 33 A0 F4 A1 39 45 D8 98 C2 : 96 4F E3 42 E2 FE 1A 7F 9B 8E E7 EB 4A 7C 0F 9E : 16 2B CE 33 57 6B 31 5E CE CB B6 40 68 37 BF 51 : F5 205 33: INTEGER : 00 FF FF FF FF 00 00 00 00 FF FF FF FF FF FF FF : FF BC E6 FA AD A7 17 9E 84 F3 B9 CA C2 FC 63 25 : 51 : } : } 240 66: BIT STRING : 04 15 10 26 4C 18 9C 3D 52 3F F9 91 6A BD 70 69 : EF A6 96 8D 8D C7 DD B6 45 7D 78 69 B5 3E A6 0C : DC FA FB 7E D4 78 6D A1 5D 29 EE 59 25 6F 53 6D : A3 57 5A 48 88 C1 BB 0A 95 B2 56 F4 A7 E9 FD 76 : 4A : } # Test case 336: 0 307: SEQUENCE { 4 236: SEQUENCE { 7 7: OBJECT IDENTIFIER '1 2 840 10045 2 1' 16 224: SEQUENCE { 19 1: INTEGER 1 22 44: SEQUENCE { 24 7: OBJECT IDENTIFIER '1 2 840 10045 1 1' 33 33: INTEGER : 00 FD 09 10 59 A6 89 36 35 F9 00 E9 44 9D 63 F5 : 72 B2 AE BC 4C FF 7B 4E 5E 33 F1 B2 00 E8 BB C1 : 45 : } 68 68: SEQUENCE { 70 32: OCTET STRING : 02 F6 EF A5 59 76 C9 CB 06 FF 16 BB 62 9C 0A 8D : 4D 51 43 B4 00 84 B1 A1 CC 0E 4D FF 17 44 3E B7 104 32: OCTET STRING : 5A C6 35 D8 AA 3A 93 E7 B3 EB BD 55 76 98 86 BC : 65 1D 06 B0 CC 53 B0 F6 3B CE 3C 3E 27 D2 60 4B : } 138 65: OCTET STRING : 04 00 00 00 00 00 00 00 00 00 00 06 59 7F A9 4B : 1F D9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : 02 1B 8C 7D D7 7F 9A 95 62 79 22 EC EE FE A7 3F : 02 8F 1E C9 5B A9 B8 FA 95 A3 AD 24 BD F9 FF F4 : 14 205 33: INTEGER : 00 FF FF FF FF 00 00 00 00 FF FF FF FF FF FF FF : FF BC E6 FA AD A7 17 9E 84 F3 B9 CA C2 FC 63 25 : 51 240 1: INTEGER 1 : } : } 243 66: BIT STRING : 04 00 00 00 00 00 00 00 00 00 00 06 59 7F A9 4B : 1F D9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : 02 1B 8C 7D D7 7F 9A 95 62 79 22 EC EE FE A7 3F : 02 8F 1E C9 5B A9 B8 FA 95 A3 AD 24 BD F9 FF F4 : 14 : } [1] https://tools.ietf.org/html/rfc5280#section-4.1.2.7. [2] https://tools.ietf.org/html/rfc3279#section-2.3.5 [3] Many libraries don't, and usually that leads to vulnerabilities that leak the private key. PiperOrigin-RevId: 204515375 GitOrigin-RevId: 26b6eb30145d94209b9d828db7c6a0b0ed6be695
Project Wycheproof
https://github.com/google/wycheproof
Project Wycheproof is named after Mount Wycheproof, the smallest mountain in the world. The main motivation for the project is to have a goal that is achievable. The smaller the mountain the more likely it is to be able to climb it.
[TOC]
Introduction
Project Wycheproof tests crypto libraries against known attacks. It is developed and maintained by members of Google Security Team, but it is not an official Google product.
At Google, we rely on many third party cryptographic software libraries. Unfortunately, in cryptography, subtle mistakes can have catastrophic consequences, and we found that libraries fall into such implementation pitfalls much too often and for much too long. Good implementation guidelines, however, are hard to come by: understanding how to implement cryptography securely requires digesting decades' worth of academic literature. We recognize that software engineers fix and prevent bugs with unit testing, and we found that cryptographic loopholes can be resolved by the same means.
These observations have prompted us to develop Project Wycheproof, a collection of unit tests that detect known weaknesses or check for expected behaviors of some cryptographic algorithm. Project Wycheproof provides tests for most cryptographic algorithms, including RSA, elliptic curve crypto and authenticated encryption. Our cryptographers have systematically surveyed the literature and implemented most known attacks. We have over 80 test cases which have uncovered more than 40 bugs. For example, we found that we could recover the private key of widely-used DSA and ECDHC implementations.
While we are committed to develop as many attacks as possible, Project Wycheproof is by no means complete. Passing the tests does not imply that the library is secure, it just means that it is not vulnerable to the attacks that Project Wycheproof tests for. Cryptographers are also constantly discovering new attacks. Nevertheless, with Project Wycheproof developers and users now can check their libraries against a large number of known attacks, without having to spend years reading academic papers or become cryptographers themselves.
For more information on the goals and strategies of Project Wycheproof, please check out our doc.
Coverage
Project Wycheproof has tests for the most popular crypto algorithms, including
The tests detect whether a library is vulnerable to many attacks, including
- Invalid curve attacks
- Biased nonces in digital signature schemes
- Of course, all Bleichenbacher’s attacks
- And many more -- we have over 80 test cases
Our first set of tests are written in Java, because Java has a common cryptographic interface. This allowed us to test multiple providers with a single test suite. While this interface is somewhat low level, and should not be used directly, we still apply a "defense in depth" argument and expect that the implementations are as robust as possible. For example, we consider weak default values to be a significant security flaw. We are converting as many tests into sets of test vectors to simplify porting the tests to other languages. We provide ready-to-use test runners for Java Cryptography Architecture providers such as Bouncy Castle, Spongy Castle, and the default providers in OpenJDK.
Usage
-
Install Bazel.
-
Install Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files: this enables tests with large key sizes. Otherwise you'll see a lot of "illegal key size" exceptions.
-
Check out the tests
git clone https://github.com/google/wycheproof.git
- To test latest stable version of Bouncy Castle:
bazel test BouncyCastleAllTests
- To test other versions, e.g., v1.52:
bazel test BouncyCastleAllTests_1_52
- To test all known versions (warning, will take a long time):
bazel test BouncyCastleAllTests_*
- To test a local jar, set the
WYCHEPROOF_BOUNCYCASTLE_JARenvironment variable:
$ WYCHEPROOF_BOUNCYCASTLE_JAR=/path/to/bouncycastle
$ bazel test BouncyCastleTestLocal
$ bazel test BouncyCastleAllTestsLocal
Note: bazel does not currently invalidate the build on environment changes. If
you change the WYCHEPROOF_BOUNCYCASTLE_JAR environment variable, run bazel clean to force a rebuild:
$ WYCHEPROOF_BOUNCYCASTLE_JAR=/path/to/bouncycastle
$ bazel test BouncyCastleTestLocal
$ WYCHEPROOF_BOUNCYCASTLE_JAR=/path/to/other/jar
$ bazel clean
$ bazel test BouncyCastleTestLocal
- To test Spongy Castle, replace BouncyCastle with SpongyCastle in your commands, for example
bazel test SpongyCastleAllTests
- To test your current installation of OpenJDK:
bazel test OpenJDKAllTests
Note that OpenJDKAllTests expects that OpenJDK is your default JDK, so it might refuse to run or its results might be incorrect if you are using some other JDK. If you downloaded your JDK from Oracle or https://java.com, you're probably using Oracle JDK, which should be compatible with OpenJDK, thus the tests should run correctly.
Some tests take a very long time to finish. If you want to exclude them, use BouncyCastleTest, SpongyCastleTest or OpenJDKTest -- these targets exclude all slow tests (which are annotated with @SlowTest).
Most test targets are failing, and each failure might be a security issue. To learn more about what a failed test means, you might want to check out our documentation or the comments on top of the corresponding test function and test class.
Hall of Bugs
Here are some of the notable vulnerabilities that are uncovered by Project Wycheproof:
-
OpenJDK's SHA1withDSA leaks private keys > 1024 bits
- Test: testBiasSha1WithDSA in DsaTest.
- This bug is the same as [CVE-2003-0971 - GnuPG generated ElGamal signatures that leaked the private key] (https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2003-0971).
-
Bouncy Castle's ECDHC leaks private keys
- Test: testModifiedPublic and testWrongOrderEcdhc in EcdhTest.
Maintainers
Project Wycheproof is maintained by:
- Daniel Bleichenbacher
- Thai Duong
- Emilia Kasper
- Quan Nguyen
Contact and mailing list
If you want to contribute, please read CONTRIBUTING and send us pull requests. You can also report bugs or request new tests.
If you'd like to talk to our developers or get notified about major new tests, you may want to subscribe to our mailing list. To join, simply send an empty mail to wycheproof-users+subscribe@googlegroups.com.