diff --git a/.gitignore b/.gitignore deleted file mode 100644 index ac51a05..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -bazel-* diff --git a/BUILD b/BUILD deleted file mode 100644 index c9a91e9..0000000 --- a/BUILD +++ /dev/null @@ -1,171 +0,0 @@ -# Wycheproof tests - -java_library( - name = "utils", - srcs = [ - "java/com/google/security/wycheproof/EcUtil.java", - "java/com/google/security/wycheproof/RandomUtil.java", - "java/com/google/security/wycheproof/TestUtil.java", - ], -) - -common_deps = [ - ":utils", - "@gson//:Gson" -] - -test_srcs = glob(["java/com/google/security/wycheproof/testcases/*.java"]) + ["java/com/google/security/wycheproof/WycheproofRunner.java"] - -# These targets run all tests. - -load(":build_defs.bzl", "bouncycastle_all_tests", "spongycastle_all_tests") - -# Generates BouncyCastleAllTests_1_xx target for all available versions, -# plus a BouncyCastleAllTests alias for latest stable. -# -# To test latest stable: -# $ 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 BouncyCastleAllTest_* -bouncycastle_all_tests( - # This test takes a long time, because key generation for DSA and DH generate new parameters. - size = "large", - srcs = ["java/com/google/security/wycheproof/BouncyCastleAllTests.java"] + test_srcs, - test_class = "com.google.security.wycheproof.BouncyCastleAllTests", - deps = common_deps, -) - -java_test( - name = "BouncyCastleAllTestsLocal", - # this target requires specifing a shell variable, thus won't work with the wildcard target patterns. - # with tags=["manual"] it'll be excluded from said patterns. - tags = ["manual"], - size = "large", - srcs = ["java/com/google/security/wycheproof/BouncyCastleAllTests.java"] + test_srcs, - test_class = "com.google.security.wycheproof.BouncyCastleAllTests", - deps = common_deps + ["@local//:bouncycastle_jar"], -) - -# Generates SpongyCastleAllTests_1_xx target for all available versions, -# plus a SpongyCastleAllTests alias for latest stable. -# -# To test latest stable: -# $ bazel test SpongyCastleAllTests -# -# To test other versions, e.g., v1.52.0.0: -# $ bazel test SpongyCastleAllTests_1_52 -# -# To test all known versions (warning, will take a long time): -# $ bazel test SpongyCastleAllTests_* -spongycastle_all_tests( - # This test takes a long time, because key generation for DSA and DH generate new parameters. - size = "large", - srcs = ["java/com/google/security/wycheproof/SpongyCastleAllTests.java"] + test_srcs, - test_class = "com.google.security.wycheproof.SpongyCastleAllTests", - deps = common_deps, -) - -# These targets exclude slow tests. - -load(":build_defs.bzl", "bouncycastle_tests", "spongycastle_tests") - -# Generates BouncyCastleTest_1_xx target for all available versions, -# plus a BouncyCastleTest alias for latest stable. -# -# To test latest stable: -# $ bazel test BouncyCastleTest -# -# To test other versions, e.g., v1.52: -# $ bazel test BouncyCastleTest_1_52 -# -# To test all known versions: -# $ bazel test BouncyCastleTest_* -bouncycastle_tests( - size = "large", - srcs = ["java/com/google/security/wycheproof/BouncyCastleTest.java"] + test_srcs, - test_class = "com.google.security.wycheproof.BouncyCastleTest", - deps = common_deps, -) - -java_test( - name = "BouncyCastleTestLocal", - # this target requires specifing a shell variable, thus won't work with the wildcard target patterns. - # with tags=["manual"] it'll be excluded from said patterns. - tags = ["manual"], - size = "large", - srcs = ["java/com/google/security/wycheproof/BouncyCastleTest.java"] + test_srcs, - test_class = "com.google.security.wycheproof.BouncyCastleTest", - deps = common_deps + ["@local//:bouncycastle_jar"], -) - -# Generates SpongyCastleTest_1_xx target for all available versions, -# plus a SpongyCastleTest alias for latest stable. -# -# To test latest stable: -# $ bazel test SpongyCastleTest -# -# To test other versions, e.g., v1.52.0.0: -# $ bazel test SpongyCastleTest_1_52 -# -# To test all known versions: -# $ bazel test SpongyCastleTest_* -spongycastle_tests( - size = "large", - srcs = ["java/com/google/security/wycheproof/SpongyCastleTest.java"] + test_srcs, - test_class = "com.google.security.wycheproof.SpongyCastleTest", - deps = common_deps, -) - -# OpenJDK tests -java_test( - name = "OpenJDKTest", - size = "large", - srcs = ["java/com/google/security/wycheproof/OpenJDKTest.java"] + test_srcs, - test_class = "com.google.security.wycheproof.OpenJDKTest", - deps = common_deps, -) - -java_test( - name = "OpenJDKAllTests", - size = "large", - srcs = ["java/com/google/security/wycheproof/OpenJDKAllTests.java"] + test_srcs, - test_class = "com.google.security.wycheproof.OpenJDKAllTests", - deps = common_deps, -) - -# Platform-independent tests -java_test( - name = "ProviderIndependentTest", - size = "small", - srcs = ["java/com/google/security/wycheproof/ProviderIndependentTest.java"] + test_srcs, - deps = common_deps, -) - -# Tests using JSON formated test vectors. -testvectors = [ - "//testvectors:aes_gcm", - "//testvectors:aes_gcm_siv", - "//testvectors:dsa", - "//testvectors:ecdsa", - "//testvectors:rsa_signature", -] - -java_test( - name = "JsonTest", - size = "small", - srcs = ["java/com/google/security/wycheproof/JsonTest.java"] + test_srcs, - data = testvectors, - deps = common_deps, -) - -# Load closure rules -load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_deps") - -closure_js_deps( - name = "E2EDeps", - deps = ["@e2e//:E2E"], -) \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index fa97ad3..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,43 +0,0 @@ -Want to contribute? Great! First, read this page (including the small print at -the end). - -### Before you contribute -Before we can use your code, you must sign the -[Google Individual Contributor License Agreement] -(https://cla.developers.google.com/about/google-individual) -(CLA), which you can do online. The CLA is necessary mainly because you own the -copyright to your changes, even after your contribution becomes part of our -codebase, so we need your permission to use and distribute your code. We also -need to be sure of various other things—for instance that you'll tell us if you -know that your code infringes on other people's patents. You don't have to sign -the CLA until after you've submitted your code for review and a member has -approved it, but you must do it before we can put your code into our codebase. -Before you start working on a larger contribution, you should get in touch with -us first through the issue tracker with your idea so that we can help out and -possibly guide you. Coordinating up front makes it much easier to avoid -frustration later on. - -### Disclosure -If your tests uncover security vulnerabilities, please first report directly to -the maintainers of the libraries. You should only submit tests to us once the -bugs have been acknowledged or fixed. - -Google has several -[security reward programs](https://www.google.com/about/appsecurity/programs-home/) -that provide cash rewards for quality security research that identifies or fixes -security vulnerabilities in products that we provide or proactive security -improvements to select open-source products. If your tests found or helped fix -vulnerabilities that are in scope you should submit them to these programs. - -If you have any question with regard to disclosure, please email us at -security@google.com. - -### Code reviews -All submissions, including submissions by project members, require review. We -use GitHub pull requests for this purpose. - -### The small print -Contributions made by corporations are covered by a different agreement than -the one above, the -[Software Grant and Corporate Contributor License Agreement] -(https://cla.developers.google.com/about/google-corporate). \ No newline at end of file diff --git a/E2E.BUILD b/E2E.BUILD deleted file mode 100644 index 838f580..0000000 --- a/E2E.BUILD +++ /dev/null @@ -1,15 +0,0 @@ -load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_library") - -closure_js_library( - name = "E2E", - visibility = ["//visibility:public"], - srcs = glob( - ["src/**/*.js"], - exclude = [ - "src/**/*test.js", - "src/**/*tester.js", - "src/**/*testdata.js", - "src/**/testing/*.js", - "src/**/testing.js"], - ) -) \ No newline at end of file diff --git a/Gson.BUILD b/Gson.BUILD deleted file mode 100644 index fa5f6c5..0000000 --- a/Gson.BUILD +++ /dev/null @@ -1,5 +0,0 @@ -java_library( - name = "Gson", - visibility = ["//visibility:public"], - srcs = glob(["gson/src/main/**/*.java"]) -) \ No newline at end of file diff --git a/LICENSE b/LICENSE index 7a4a3ea..f0f8fa1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,202 +1,13 @@ +Copyright 2016 Google Inc. All Rights Reserved. - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + http://www.apache.org/licenses/LICENSE-2.0 - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/README.google b/README.google new file mode 100644 index 0000000..ffe5ea1 --- /dev/null +++ b/README.google @@ -0,0 +1,12 @@ +URL: https://cs.corp.google.com/piper///depot/google3/third_party/wycheproof +Version: 0.1 +License: Apache 2.0 +License File: LICENSE + +Description: +Developed by Google, Wycheproof is a set of unit tests that check for well-known +vulnerabilities in crypto libraries, e.g., Sun JCE, Bouncy Castle, Conscrypt, +OpenSSL, pycrypto, M2Crypto, etc. + +Local Modifications: +None. diff --git a/README.md b/README.md deleted file mode 100644 index 9e31546..0000000 --- a/README.md +++ /dev/null @@ -1,220 +0,0 @@ -# Project Wycheproof -https://github.com/google/wycheproof - -*Project Wycheproof is named after -[Mount Wycheproof](https://en.wikipedia.org/wiki/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](doc/bugs.md). 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](doc/). - -### Coverage - -Project Wycheproof has tests for the most popular crypto algorithms, including - -- AES-EAX -- AES-GCM -- [DH](doc/dh.md) -- DHIES -- [DSA](doc/dsa.md) -- [ECDH](doc/ecdh.md) -- ECDSA -- ECIES -- [RSA](doc/rsa.md) - -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](http://bouncycastle.org), -[Spongy Castle](https://rtyley.github.io/spongycastle/), and the default -providers in [OpenJDK](http://openjdk.java.net/). - -### Usage - -- Install [Bazel](https://bazel.build/). - -- Install [Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction - Policy - Files](http://stackoverflow.com/questions/6481627/java-security-illegal-key-size-or-default-parameters): - 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_JAR` environment - variable: - -```shell -$ 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: - -```shell -$ 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](https://rtyley.github.io/spongycastle/), replace -BouncyCastle with SpongyCastle in your commands, for example - -``` -bazel test SpongyCastleAllTests -``` - -- To test your current installation of -[OpenJDK](http://openjdk.java.net/): - -``` -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](doc/bugs.md) or the comments on top of the corresponding test -function and test class. - -- To test [Web Cryptography API](https://www.w3.org/TR/WebCryptoAPI/), you first need -to compile [End-to-end](https://github.com/google/end-to-end) because our tests depend on it: - -``` -bazel build E2EDeps -``` - -Since Web Cryptography API works on web browsers, you then need to run a simple web server in your local machine by running, for example: - -``` -python -m SimpleHTTPServer -``` - -Now assuming that your source code folder's name is "wycheproof", open the web browsers -that you want to test and point it to: - -``` -http://localhost:8000/bazel-wycheproof/javascript/webcryptoapi/WebCryptoTest.html -``` - -We have tested Chrome, Firefox, and Microsoft Edge. - -### 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](https://github.com/google/wycheproof/blob/master/java/com/google/security/wycheproof/testcases/DsaTest.java). - - 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](https://github.com/google/wycheproof/blob/master/java/com/google/security/wycheproof/testcases/EcdhTest.java). - -### 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](CONTRIBUTING.md) 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](https://groups.google.com/forum/#!forum/wycheproof-users). To -join, simply send an empty mail to wycheproof-users+subscribe@googlegroups.com. diff --git a/WORKSPACE b/WORKSPACE deleted file mode 100644 index 74a966e..0000000 --- a/WORKSPACE +++ /dev/null @@ -1,154 +0,0 @@ -# for javascript -http_archive( - name = "io_bazel_rules_closure", - strip_prefix = "rules_closure-master", - urls = [ - "https://github.com/bazelbuild/rules_closure/archive/master.zip", - ], -) - -load("@io_bazel_rules_closure//closure:defs.bzl", "closure_repositories") - -closure_repositories() - -# Google End-to-end -new_http_archive( - name = "e2e", - strip_prefix = "end-to-end-a77a8cbd13157139437219a8c87a7e133457c2e7", - sha256 = "1c0d3678a649c75254e035985a209b9e292befdec733af0a4ad3842acef271eb", - url = "https://github.com/google/end-to-end/archive/a77a8cbd13157139437219a8c87a7e133457c2e7.zip", - build_file = "//:E2E.BUILD" -) - -# Google GSON -new_http_archive( - name = "gson", - strip_prefix = "gson-gson-parent-2.8.1", - sha256 = "5b64446a14ee5b29ab62f1bc0341631c20073e141b724afc410aa66dff6d7f2e", - url = "https://github.com/google/gson/archive/gson-parent-2.8.1.tar.gz", - build_file = "//:Gson.BUILD" -) - -maven_jar( - name = "bouncycastle_1_46", - artifact = "org.bouncycastle:bcprov-jdk15on:1.46", -) - -maven_jar( - name = "bouncycastle_1_47", - artifact = "org.bouncycastle:bcprov-jdk15on:1.47", -) - -maven_jar( - name = "bouncycastle_1_48", - artifact = "org.bouncycastle:bcprov-jdk15on:1.48", -) - -maven_jar( - name = "bouncycastle_1_49", - artifact = "org.bouncycastle:bcprov-jdk15on:1.49", -) - -maven_jar( - name = "bouncycastle_1_50", - artifact = "org.bouncycastle:bcprov-jdk15on:1.50", -) - -maven_jar( - name = "bouncycastle_1_51", - artifact = "org.bouncycastle:bcprov-jdk15on:1.51", -) - -maven_jar( - name = "bouncycastle_1_52", - artifact = "org.bouncycastle:bcprov-jdk15on:1.52", -) - -maven_jar( - name = "bouncycastle_1_53", - artifact = "org.bouncycastle:bcprov-jdk15on:1.53", -) - -maven_jar( - name = "bouncycastle_1_54", - artifact = "org.bouncycastle:bcprov-jdk15on:1.54", -) - -maven_jar( - name = "bouncycastle_1_55", - artifact = "org.bouncycastle:bcprov-jdk15on:1.55", -) - -maven_jar( - name = "bouncycastle_1_56", - artifact = "org.bouncycastle:bcprov-jdk15on:1.56", -) - -maven_jar( - name = "bouncycastle_1_57", - artifact = "org.bouncycastle:bcprov-jdk15on:1.57", -) - -maven_jar( - name = "bouncycastle_1_58", - artifact = "org.bouncycastle:bcprov-jdk15on:1.58", -) - -maven_jar( - name = "bouncycastle_1_59", - artifact = "org.bouncycastle:bcprov-jdk15on:1.59", -) - -maven_jar( - name = "spongycastle_core_1_50", - artifact = "com.madgag.spongycastle:core:1.50.0.0", -) - -maven_jar( - name = "spongycastle_prov_1_50", - artifact = "com.madgag.spongycastle:prov:1.50.0.0", -) - -maven_jar( - name = "spongycastle_core_1_51", - artifact = "com.madgag.spongycastle:core:1.51.0.0", -) - -maven_jar( - name = "spongycastle_prov_1_51", - artifact = "com.madgag.spongycastle:prov:1.51.0.0", -) - -maven_jar( - name = "spongycastle_core_1_52", - artifact = "com.madgag.spongycastle:core:1.52.0.0", -) - -maven_jar( - name = "spongycastle_prov_1_52", - artifact = "com.madgag.spongycastle:prov:1.52.0.0", -) - -maven_jar( - name = "spongycastle_core_1_53", - artifact = "com.madgag.spongycastle:core:1.53.0.0", -) - -maven_jar( - name = "spongycastle_prov_1_53", - artifact = "com.madgag.spongycastle:prov:1.53.0.0", -) - -maven_jar( - name = "spongycastle_core_1_54", - artifact = "com.madgag.spongycastle:core:1.54.0.0", -) - -maven_jar( - name = "spongycastle_prov_1_54", - artifact = "com.madgag.spongycastle:prov:1.54.0.0", -) - -load(":local_repository_defs.bzl", "local_jars") - -local_jars(name = "local") diff --git a/build_defs.bzl b/build_defs.bzl deleted file mode 100644 index 1d874a1..0000000 --- a/build_defs.bzl +++ /dev/null @@ -1,119 +0,0 @@ -bouncycastle_versions = range(49, 60) - -# These targets run all tests. -def bouncycastle_all_tests(srcs, deps, size, test_class): - """BouncyCastle version-specific tests.""" - - # Generates BouncyCastleAllTests_1_59, ..., BouncyCastleAllTests_1_49 - for version in bouncycastle_versions: - native.java_test( - name = "BouncyCastleAllTests_1_%s" % version, - srcs = srcs, - deps = deps + [ - "@bouncycastle_1_%s//jar" % version, - ], - size = size, - test_class = test_class, - ) - - # Latest stable. - # We can't use native.alias, because aliased tests are not run. - # So, we simply duplicate the test. - native.java_test( - name = "BouncyCastleAllTests", - srcs = srcs, - deps = deps + ["@bouncycastle_1_%s//jar" % max(bouncycastle_versions)], - size = size, - test_class = test_class, - ) - -# These targets exclude slow tests. -def bouncycastle_tests(srcs, deps, size, test_class): - """BouncyCastle version-specific tests.""" - - # Generates BouncyCastleTest_1_59, ..., BouncyCastleTest_1_49 - for version in bouncycastle_versions: - native.java_test( - name = "BouncyCastleTest_1_%s" % version, - srcs = srcs, - deps = deps + [ - "@bouncycastle_1_%s//jar" % version, - ], - size = size, - test_class = test_class, - ) - - # Latest stable. - # We can't use native.alias, because aliased tests are not run. - # So, we simply duplicate the test. - native.java_test( - name = "BouncyCastleTest", - srcs = srcs, - deps = deps + ["@bouncycastle_1_%s//jar" % max(bouncycastle_versions)], - size = size, - test_class = test_class, - ) - -spongycastle_versions = range(50, 55) - -# These targets run all tests. -def spongycastle_all_tests(srcs, deps, size, test_class): - """SpongyCastle version-specific tests.""" - - # Generates SpongyCastleAllTests_1_54, ..., SpongyCastleAllTests_1_50 - for version in spongycastle_versions: - native.java_test( - name = "SpongyCastleAllTests_1_%s" % version, - srcs = srcs, - deps = deps + [ - "@spongycastle_core_1_%s//jar" % version, - "@spongycastle_prov_1_%s//jar" % version, - ], - size = size, - test_class = test_class, - ) - - # Latest stable. - # We can't use native.alias, because aliased tests are not run. - # So, we simply duplicate the test. - native.java_test( - name = "SpongyCastleAllTests", - srcs = srcs, - deps = deps + [ - "@spongycastle_core_1_%s//jar" % max(spongycastle_versions), - "@spongycastle_prov_1_%s//jar" % max(spongycastle_versions), - ], - size = size, - test_class = test_class, - ) - -# These targets exclude slow tests. -def spongycastle_tests(srcs, deps, size, test_class): - """SpongyCastle version-specific tests.""" - - # Generates SpongyCastleTest_1_54, ..., SpongyCastleTest_1_50 - for version in spongycastle_versions: - native.java_test( - name = "SpongyCastleTest_1_%s" % version, - srcs = srcs, - deps = deps + [ - "@spongycastle_core_1_%s//jar" % version, - "@spongycastle_prov_1_%s//jar" % version, - ], - size = size, - test_class = test_class, - ) - - # Latest stable. - # We can't use native.alias, because aliased tests are not run. - # So, we simply duplicate the test. - native.java_test( - name = "SpongyCastleTest", - srcs = srcs, - deps = deps + [ - "@spongycastle_core_1_%s//jar" % max(spongycastle_versions), - "@spongycastle_prov_1_%s//jar" % max(spongycastle_versions), - ], - size = size, - test_class = test_class, - ) diff --git a/doc/bugs.md b/doc/bugs.md deleted file mode 100644 index 6d9e2c8..0000000 --- a/doc/bugs.md +++ /dev/null @@ -1,65 +0,0 @@ -# Bugs found by Project Wycheproof -See [list of issues](issues.md) for details. - -## Package OpenJDK - -| Summary | Credits | CVE | Upstream Acknowledgement | Tests | -|:---------------------------: |:--------------------------:|:-----------------:|:--------------------------------------: |:---------------------------------------: -| Biased DSA, leaks signing key | Daniel Bleichenbacher |CVE-2016-0695 | Oracle Critical Patch Update April 2016 | DsaTest: testDsaBias, testBiasSha1WithDSA | -| GCM's timing attack, leaks auth key | Quan Nguyen |CVE-2016-3426 | Oracle Critical Patch Update April 2016 | N/A | -| GCM updateAAD | Quan nguyen | N/A | Oracle Critical Patch Update April 2016 | AesGcmTest: testLateUpdateAAD | -| GCM wrapped around counter, leaks auth key | Quan Nguyen | N/A | Oracle Critical Patch Update April 2016 | AesGcmTest: testWrappedAroundCounter | -| DSA ArrayIndexOutOfBoundsException | Daniel Bleichenbacher | CVE-2016-5546 | Oracle Critical Patch Update Jan 2017 | DsaTest: testInvalidSignatures | -| RSA OutOfMemoryError | Daniel Bleichenbacher | CVE-2016-5547 | Oracle Critical Patch Update Jan 2017 | RsaSignatureTest: testVectors | -| DSA accepts modified signatures | Daniel Bleichenbacher | CVE-2016-5546 | Oracle Critical Patch Update Jan 2017 | DsaTest: testModifiedSignatures | -| DSA Timing Attack | Daniel Bleichenbacher | CVE-2016-5548 | Oracle Critical Patch Update Jan 2017 | DsaTest: testTiming | -| ECDSA accepts modified signatures| Daniel Bleichenbacher | CVE-2016-5546 | Oracle Critical Patch Update Jan 2017 | EcdsaTest: testModifiedSignatures | -| ECDSA Timing Attack | Daniel Bleichenbacher | CVE-2016-5549 | Oracle Critical Patch Update Jan 2017 | EcdsaTest: testTiming | -| Biased ECDSA | Daniel Bleichenbacher | | | Ecdsa: testBias | - -## Package Conscrypt - -| Summary | Credits | CVE | Upstream Acknowledgement | Tests | -|:---------------------------: |:--------------------------:|:-----------------:|:--------------------------------------: |:---------------------------------------: -| ECDH Invalid Curve Attack | Daniel Bleichenbacher | N/A | | EcdhTest: multiple tests | -| GCM IV reuse | Daniel Bleichenbacher | N/A | | AesGcmTest: testIvReuse | -| GCM weak default tag length | Quan Nguyen | N/A | | AesGcmTest: testDefaultTagSizeIvParameterSpec | - - -## Package BouncyCastle v1.55 and older -| Summary | Credits | CVE | Upstream Acknowledgement | Tests | -|:---------------------------: |:--------------------------:|:-----------------:|:--------------------------------------: |:---------------------------------------: -| v1.55 ECDH upstream fix was incomplete | Daniel Bleichenbacher | N/A | | Ecdh: multiple tests | -| ECDHC Invalid curve attack | Daniel Bleichenbacher | N/A | | EcdhTest: testModifiedPublic,testModifiedPublicSpec, testWrongOrder | -| v1.55 PKCS #1 RSA is more vulnerable to CCA attack | Daniel Bleichenbacher | N/A | | RsaTest: testExceptions | -| Dhies uses unsafe ECB mode | Daniel Bleichenbacher | CVE-2016-1000344 | | DhiesTest | -| ECIES use unsafe ECB mode by default for "ECIESWithAES" or "ECIESwithDESede" | Daniel Bleichenbacher | CVE-2016-1000352 | | EciesTest: testNotEcb, testDefaultEcies| -| 1.52 ECIESWithAES-CBC is vulnerable to padding oracle attack | Daniel Bleichenbacher | CVE-2016-1000345 | | EciesTest: testExceptions | -| GCM reuses IV after doFinal() | Daniel Bleichenbacher | N/A | | | -| ECDSA accepts invalid signatures | Daniel Bleichenbacher | CVE-2016-1000342 | | EcdsaTest: testModifiedSignatures | -| DSA accepts invalid signatures | Daniel Bleichenbacher | CVE-2016-1000338 | | DsaTest: testModifiedsignatures | -| DSA generates weak key | Daniel Bleichenbacher | CVE-2016-1000343 | | DsaTest: testKeyGeneration | -| Allows invalid DH public key | Daniel Bleichenbacher | CVE-2016-1000346 | | DhTest: incomplete | -| DSA timing attacks | Daniel Bleichenbacher | CVE-2016-1000341 | | DsaTest: testTiming | -| GCM Wrapped Around Counter | Quan Nguyen | CVE-2015-6644 | Nexus Security Bullentin Jan 2016 | AesGcmTest: testWrappedAroundCounter | - -## Package Go JOSE (https://github.com/square/go-jose) -| Summary | Credits | CVE | Upstream Acknowledgement | Tests | -|:---------------------------: |:--------------------------:|:-----------------:|:--------------------------------------: |:---------------------------------------: -| ECDH Invalid Curve Attack | Quan Nguyen | CVE-2016-9121 | $5500 total by Square Inc. for all bugs | To be released | -| Multiple signatures, auth bypass | Quan Nguyen | CVE-2016-9122 | | To be released | -| Integer overflow, HMAC bypass | Quan Nguyen | CVE-2016-9123 | | To be released | -| Accepts embedded HMAC key | Quan Nguyen | N/A | | To be released | - -## Package Go crypto -| Summary | Credits | CVE | Upstream Acknowledgement | Tests | -|:---------------------------: |:--------------------------:|:-----------------:|:--------------------------------------: |:---------------------------------------: -| GCM wrapped around counter | Quan Nguyen | N/A | goo.gl/OdhZcY | - -## Package Nimbus JOSE+JWT (https://connect2id.com/products/nimbus-jose-jwt) -| Summary | Credits | CVE | Upstream Acknowledgement | Tests | -|:---------------------------: |:--------------------------:|:-----------------:|:--------------------------------------: |:---------------------------------------: -| CBC-HMAC is vulnerable to padding oracle attack | Quan Nguyen | N/A | https://goo.gl/ACZQeI | To be released -| CBC-HMAC integer overflow, HMAC bypass | Quan Nguyen | N/A | https://goo.gl/ACZQeI | To be released - - diff --git a/doc/dh.md b/doc/dh.md deleted file mode 100644 index ca8c410..0000000 --- a/doc/dh.md +++ /dev/null @@ -1,141 +0,0 @@ -# Diffie-Hellman - -## Subgroup confinement attacks - -The papers by van Oorshot and Wiener [OW96] rsp. Lim and Lee [LL98] show that -Diffie-Hellman keys can be found much faster if the short exponents are used and -if the multiplicative group modulo p contains small subgroups. In particular an -attacker can try to send a public key that is an element of a small subgroup. If -the receiver does not check for such elements then may be possible to find the -private key modulo the order of the small subgroup. Several countermeasures -against such attacks have been proposed: For example IKE uses fields of order p -where p is a safe prime (i.e. $$q=(p-1)/2),$$ hence the only elements of small -order are 1 and p-1. - -[NIST SP 800-56A] rev. 2, Section 5.5.1.1 only requires that the size of the -subgroup generated by the generator g is big enough to prevent the baby-step -giant-step algorithm. I.e. for 80-bit security p must be at least 1024 bits long -and the prime q must be at least 160 bits long. A 2048 bit prime p and a 224 bit -prime q are sufficient for 112 bit security. To avoid subgroup confinment -attacks NIST requires that public keys are validated, i.e. by checking that a -public key y satisfies the conditions $$2 \leq y \leq p-2$$ and $$y^q \mod p = -1$$ (Section 5.6.2.3.1). Further, after generating the shared secret $$z = -y_a^{x_b} \mod p$$ each party should check that $$z \neq 1.$$ RFC 2785 contains -similar recommendations. The public key validation described by NIST requires -that the order q of the generator g is known to the verifier. Unfortunately, the -order q is missing in [PKCS #3]. [PKCS #3] describes the Diffie-Hellman -parameters only by the values p, g and optionally the key size in bits. - -The class DHParameterSpec that defines the Diffie-Hellman parameters in JCE -contains the same values as [PKCS #3]. In particular, it does not contain the -order of the subgroup q. Moreover, the SUN provider uses the minimal sizes -specified by NIST for q. Essentially the provider reuses the parameters for DSA. - -Therefore, there is no guarantee that an implementation of Diffie-Hellman is secure against -subgroup confinement attacks. Without a key validation it is insecure to use the key-pair -generation from [NIST SP 800-56A] Section 5.6.1.1 (The key-pair generation there only requires that -static and ephemeral private keys are randomly chosen in the range \\(1..q-1)\\). - -To avoid big disasters the tests below require that key sizes are not minimal. I.e., currently -the tests require at least 512 bit keys for 1024 bit fields. We use this lower limit because that -is what the SUN provider is currently doing. - -TODO(bleichen): Find a reference supporting or disproving that decision. - -## Weak parameters - -The DH parameters must be carefully chosen to avoid security issues. A panel at -Eurocrypt'92 discussed the possiblity of trapdoors in DL based primitives -[Eurocrypt92 panel]. A. Lenstra pointed out that the primes chould be chosen -such that the special number field sieve can be used to compute discrete -logarithms. Gordon has analyzed methods to generate and detect weak parameters -[G92]. Section 4 of Gordons paper describes a method that can detect some -special cases, but no general method was given. Recently Fried et al. showed -that 1024 bit discrete logarithms with the special number field sieve are -feasible [FGHT16]. Moreover some libraries use primes that are susceptible to -this attack [FGHT16]. - -TODO(bleichen): So far not test for weak DH parameters has been implemented. -Possibly we should at least implement a test that detects special cases, so -that weak primes (such as the one used in libtomcrypt) are detected. - -DH implementations are sometimes misconfigured. Adrian et al. [WeakDh] analyzed -various implementations and found for example the following problems in the -parameters: p is sometimes composite, p-1 contains no large prime factor, q is -used instead of the generator g. - -## References -[Eurocrypt92 panel]: "The Eurocrypt'92 Controversial Issue Trapdoor Primes and Moduli", -EUROCRYPT '92, LNCS 658, pp. 194-199. - -[G92]: D. M. Gordon. "Designing and detecting trapdoors for discrete log -cryptosystems." CRYPTO’92, pp. 66–75. - -\[FGHT16]: J. Fried, P. Gaudry, N. Heininger, E. Thome. "A kilobit hidden SNFS -discrete logarithm computation". http://eprint.iacr.org/2016/961.pdf - -[OW96]: P. C. van Oorschot, M. J. Wiener, "On Diffie-Hellman key agreement with short exponents", -Eurocrypt 96, pp 332–343. - -[LL98]: C.H. Lim and P.J. Lee, -"A key recovery attack on discrete log-based schemes using a prime order subgroup", -CRYPTO' 98, pp 249–263. - -[WeakDh]: D. Adrian, K. Bhargavan, Z. Durumeric, P. Gaudry, M. Green, -J. A. Halderman, N. Heninger, D. Springall, E. Thomé, Luke Valenta, -B. VanderSloot, E. Wustrow, S. Zanella-Béguelink, P. Zimmermann, -"Imperfect Forward Secrecy: How Diffie-Hellman Fails in Practice" -https://weakdh.org/imperfect-forward-secrecy-ccs15.pdf - -[NIST SP 800-56A], revision 2, May 2013 -http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf - -[PKCS #3]: "Diffie–Hellman Key Agreement", -http://uk.emc.com/emc-plus/rsa-labs/standards-initiatives/pkcs-3-diffie-hellman-key-agreement-standar.htm - -[RFC 2785]: R. Zuccherato, -"Methods for Avoiding 'Small-Subgroup' Attacks on the Diffie-Hellman Key Agreement Method for S/MIME", -March 2000 -https://www.ietf.org/rfc/rfc2785.txt - - diff --git a/doc/dsa.md b/doc/dsa.md deleted file mode 100644 index 0c2f631..0000000 --- a/doc/dsa.md +++ /dev/null @@ -1,192 +0,0 @@ -# DSA - -[TOC] - -The digital signature algorithm (DSA) is one of three signature schemes -descripted in the digital signature standard [DSS]. - -## Key generation - -4.2 Selection of Parameter Sizes and Hash Functions for DSA -The DSS specifies the following choices for the pair (L,N), -where L is the size of p in bits and N is the size of q in bits: - -L | N ----:|----: -1024| 160 -2048| 224 -2048| 256 -3072| 256 - -The tests expect the following properties of the parameters used during -key generation: - -* If only the parameter L is specified by the caller then N should be one - of the options proposed in [DSS]. -* If no size is specified then L should be at least 2048. This is the minimal - key size recommended by NIST for the period up to the year 2030. - -## Signature generation - -The DSA signature algorithm requires that each signature is computed with a new -one-time secret k. This secret value should be close to uniformly distributed. -If that is not the case then DSA signatures can leak the private key that was -used to generate the signature. Two methods for generating the one-time secrets -are described in FIPS PUB 186-4, Section B.5.1 or B.5.2 [DSS]. There is also the -possibility that the use of mismatched implementations for key generation and -signature generation are leaking the private keys. - -## Signature verification - -A DSA signature is a DER encoded tuple of two integers (r,s). To verify a -signature the verifier first checks $$0 < r < q$$ and $$0 < s < q$$. The -verifier then computes: - -$$ -\begin{array}{l} -w=s^{-1} \bmod q\\ -u1 = w \cdot H(m) \bmod q\\ -u2 = w \cdot r \bmod q\\ -\end{array} -$$ - -and then verifies that \\(r = (g^{u1}y^{u2} \bmod p) \bmod q\\) - -## Incorrect computations and range checks. - -Some libraries return 0 as the modular inverse of 0 or q. -This can happen if the library computes the modular -inverse of s as \\(w=s^{q-2} \mod q\\) (gpg4browsers) of simply -if the implementations is buggy (pycrypto). if additionally to such -a bug the range of r,s is not or incorrectly tested then it might -be feasible to forge signatures with the values (r=1, s=0) or (r=1, s=q). -In particular, if a library can be forced to compute \\(s^{-1} \mod q = 0\\) -then the verification would compute \\( w = u1 = u2 = 0 \\) and hence -\\( (g^{u1}y^{u2} \mod p) \mod q = 1 .\\) - -## Timing attacks - -TBD - -# Some notable failures of crypto libraries. - -## JDK - -The jdk8 implementation of SHA1withDSA previously checked the key size as follows: - -```java -@Override - protected void checkKey(DSAParams params) - throws InvalidKeyException { - int valueL = params.getP().bitLength(); - if (valueL > 1024) { - throw new InvalidKeyException("Key is too long for this algorithm"); - } - } -``` - -This check was reasonable, it partially ensures conformance with the NIST -standard. In most cases would prevent the attack described above. - -However, Oracle released a patch that removed the length verification in DSA in -jdk9: http://hg.openjdk.java.net/jdk9/dev/jdk/rev/edd7a67585a5 -https://bugs.openjdk.java.net/browse/JDK-8039921 - -The new code is here: -http://hg.openjdk.java.net/jdk9/dev/jdk/file/edd7a67585a5/src/java.base/share/classes/sun/security/provider/DSA.java - -The change was further backported to jdk8: -http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/rev/3212f1631643 - -Doing this was a serious mistake. It easily allowed incorrect implementations. -While generating 2048 bit DSA keys in jdk7 was not yet supported, doing so in -jdk8 is. To trigger this bug in jdk7 an application had to use a key generated -by a third party library (e.g. OpenSSL). Now, it is possible to trigger the bug -just using JCE. Moreover, the excessive use of default values in JCE makes it -easy to go wrong and rather difficult to spot the errors. - -The bug was for example triggered by the following code snippet: - -```java - KeyPairGenerator keygen = KeyPairGenerator.getInstance("DSA"); - Keygen.initialize(2048); - KeyPair keypair = keygen.genKeyPair(); - Signature s = Signature.getInstance("DSA"); - s.initSign(keypair.getPrivate()); -``` - -The first three lines generate a 2048 bit DSA key. 2048 bits is currently the -smallest key size recommended by NIST. - -```java - KeyPairGenerator keygen = KeyPairGenerator.getInstance("DSA"); - Keygen.initialize(2048); - KeyPair keypair = keygen.genKeyPair(); -``` - -The key size specifies the size of p but not the size of q. The NIST standard -allows either 224 or 256 bits for the size of q. The selection typically depends -on the library. The Sun provider uses 224. Other libraries e.g. OpenSSL -generates by default a 256 bit q for 2048 bit DSA keys. - -The next line contains a default in the initialization - -```java -    Signature s = Signature.getInstance("DSA"); -``` -This line is equivalent to - -```java -    Signature s = Signature.getInstance("SHA1withDSA"); -``` -Hence the code above uses SHA1 but with DSA parameters generated for SHA-224 -or SHA-256 hashes. Allowing this combination by itself is already a mistake, -but a flawed implementaion made the situation even worse. - -The implementation of SHA1withDSA assumeed that the parameter q is 160 bits -long and used this assumption to generate a random 160-bit k when generating a -signature instead of choosing it uniformly in the range (1,q-1). -Hence, k severely biased. Attacks against DSA with biased k are well known. -Howgrave-Graham and Smart analyzed such a situation [HS99]. Their results -show that about 4 signatrues leak enough information to determine -the private key in a few milliseconds. -Nguyen analyzed a similar flaw in GPG [N04]. -I.e., Section 3.2 of Nguyens paper describes essentially the same attack as -used here. More generally, attacks based on lattice reduction were developed -to break a variety of cryptosystems such as the knapsack cryptosystem [O90]. - -## Further notes - -The short algorithm name “DSA” is misleading, since it hides the fact that -`Signature.getInstance(“DSA”)` is equivalent to -`Signature.getInstance(“SHA1withDSA”)`. To reduce the chance of a -misunderstanding short algorithm names should be deprecated. In JCE the hash -algorithm is defined by the algorithm. I.e. depending on the hash algorithm to -use one would call one of: - -```java - Signature.getInstance(“SHA1withDSA”); - Signature.getInstance(“SHA224withDSA”); - Signature.getInstance(“SHA256withDSA”); -``` - -A possible way to push such a change are code analysis tools. "DSA" is in good -company with other algorithm names “RSA”, “AES”, “DES”, all of which default to -weak algorithms. - -## References - -[HS99]: N.A. Howgrave-Graham, N.P. Smart, - “Lattice Attacks on Digital Signature Schemes” - http://www.hpl.hp.com/techreports/1999/HPL-1999-90.pdf - -[N04]: Phong Nguyen, “Can we trust cryptographic software? Cryptographic flaws - in Gnu privacy guard 1.2.3”, Eurocrypt 2004, - https://www.iacr.org/archive/eurocrypt2004/30270550/ProcEC04.pdf - -[O90]: A. M. Odlyzko, "The rise and fall of knapsack cryptosystems", Cryptology - and Computational Number Theory, pp.75-88, 1990 - -[DSS]: FIPS PUB 186-4, "Digital Signature Standard (DSS)", National Institute - of Standards and Technology, July 2013 - http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf diff --git a/doc/ecdh.md b/doc/ecdh.md deleted file mode 100644 index c86b140..0000000 --- a/doc/ecdh.md +++ /dev/null @@ -1,58 +0,0 @@ - -# ECDH - -[TOC] - -##ECDH description: -See https://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman - -##Bugs -Some libraries do not check if the elliptic curve points received from another -party are points on the curve. Encodings of public keys typically contain the -curve for the public key point. If such an encoding is used in the key exchange -then it is important to check that the public and secret key used to compute -the shared ECDH secret are using the same curve. -Some libraries fail to do this check. - -**Potential exploits:** -The damage done depends on the protocol that uses ECDH. E.g. if ECDH is used -with ephemeral keys then the damage is typically limited. If the EC keys are -static, i.e. used for multiple key exchanges then a failure to verify a public -point can disclose the private key used in the same protocol. -(To do: add papers describing the attack). - -##Libraries -**Sun JCE provider:** -ECDH does not check if the points are on the curve. -The implementer must do this. - -**Bouncycastle:** -The ECDH implementation does not check if the point is on the curve. -Furthermore, Bouncycastle does not even check if the public and private key are -on the same curve. It performs a point multiplication \\(x \cdot Y\\) over the -curve specified by the public key. - -**OpenSSL:** -Point verification is done in OpenSSL if the right functions are used. -Since OpenSSL is not well documented it is a bit tricky to find the right -functions. -(To do: maybe add an example). - -##Countermeasures -TODO: -* use point compression. Formats such as X509EncodedKeySpec -in Java include bits that indicate whether the point is compressed or not. -Hence an attacker can always choose to use uncompressed points as long as this -option is incorrectly implemented. -* check that public and private key use the same curve -* restrict the protocol to named curves -* reconstruct the public key explicitly using the parameters of the private - key. - -**Further recommendations:** -If possible I also check if the points are on the curve after point -multiplications on an elliptic curve in the hope to catch implementation -and hardware faults. - -## Some notable bugs: -* ECDHC in bouncy castle could be broken by modifying the order of the public key. diff --git a/doc/index.md b/doc/index.md deleted file mode 100644 index 9fe48b3..0000000 --- a/doc/index.md +++ /dev/null @@ -1,80 +0,0 @@ -# Project Wycheproof - -This page describes the goals and strategies of project Wycheproof. See -[README](../README.md) for an introduction to the project. - -## Defense in depth - -There are a number of tests where we check for expected behaviour -rather than exploitability. Examples: - -* default values: we expect that default values are reasonable and correspond - to recommendations by current standards. Concretely, in 2016 it is not OK - if an RSA key generation uses 1024 bits as default or digital signatures - use SHA-1 as default. -* timing attacks: any timing that relation between keys (or other sensitive) - data and the measured time fails the test. However tests are set up - such that too much noise during the test can prevent that a relation - is detected. -* wrong exceptions: The JCE interface often specifies the exceptions that - should be thrown when the input is invalid. We expect the specified - exceptions in the tests. -* leaking information through exceptions: While it is a good practice to not - return detailed logs to a sender, we consider text in exceptions as - information that a potential attacker can learn. For example padding - failures during decryption should not contain information about the - reason why a decryption failed. -* RSA PKCS #1 signatures: If a signature verification allows signatures - with lots of modifications, then RSA signatures can be forged for small - public exponents. Tests do not measure how many bytes can be modified. - Any accepted modification of the PKCS #1 padding fails the test. - -## Compatibility between providers - -One of the goals of Wycheproof is to test for compatibility issues. -Switching JCE providers should not introduce vulnerabilities simply because -the solution was developed by another provider. - -An example for this was the following observation: When using AES-GCM then -javax.crypto.CipherInputStream worked sort of with JCE and -org.bouncycastle.jcajce.io.CipherInputStream.java worked with BouncyCastle. -However, authentication was skipped in some cases when -javax.crypto.CipherInputStream was used with BouncyCastle. - -## Comparing cryptographic libraries is not a primary goal - -Because of the strategies mentioned above we expect that a comparison of -cryptographic libraries based on the bugs found would be biased: - -* Libraries used internally in Google get more attention. - Serious vulnerabilities in these libraries should be fixed at the time the - tests are added to Wycheproof. On the other hand it is also likely that - tests find a larger number of bugs in these libraries when old versions are - tested. -* Tests often check for expected behaviour and compatibility. - Expected behaviour is often defined by a prominent library. - Pointing out such problems can therefore penalize smaller third party - libraries. -* We are working toward covering as many potential vulnerabilities as possible - with test vectors, because this simplifies porting the tests to other - languages or interfaces. Thus a single test case can cover multiple - vulnerabilities. - -We are not trying to remove this bias when this interferes with more important -goals such as early reporting. -Hence we are reluctant to publish comparisons. - - -## Thoughts on the design of cryptographic libraries - -We should promote robust interfaces with the goal to simplify -the use of the library, code reviews of applications using the -library and testing the library. - -* When cryptographic primitives require randomness then the random - numbers should be chosen by the library. It shouldn't be possible - for a user to provide randomness. If the library itself chooses the - randomness then it is possible (at least to some degree) to check - that the random number generation is appropriate for the primitive. - If the user can provide the randomness then it is not possible to - catch this in our tests. diff --git a/doc/issues.md b/doc/issues.md deleted file mode 100644 index 5732586..0000000 --- a/doc/issues.md +++ /dev/null @@ -1,5 +0,0 @@ -# List of issues in common algorithms -* [RSA](rsa.md) -* [DSA](dsa.md) -* [ECDH](ecdh.md) -* [Diffie-Hellman](dh.md) diff --git a/doc/rsa.md b/doc/rsa.md deleted file mode 100644 index b1f47c5..0000000 --- a/doc/rsa.md +++ /dev/null @@ -1,131 +0,0 @@ -# RSA - -[TOC] - -## RSA key generation - -**Default size:** If a library supports a key default size for RSA keys then -this key size should be at least 2048 bits. This limit is based on the minimum -recommendation of [NIST SP 800-57] part1 revision 4, Table 2, page 53. NIST -recommends a minimal security strength of 112 bits for keys used until 2030. 112 -bit security strength translates to a minimal key size of 2048 bits. Other -organizations recommend somewhat different sizes: [Enisa], Section 3.6 also -suggests that 2048-bit RSA keys provide a security strength of about 112 bits, -but recommends a security strength of 128 bits for near term systems, hence 3072 -bit RSA keys. [ECRYPT II], Section 13.3 suggests at least 2432 bits for new -keys. - -All the references above clearly state that keys smaller than 2048 bits should -only be used in legacy cases. Therefore, it seems wrong to use a default key -size smaller than 2048 bits. If a user really wants a small RSA key then such a -choice should be made by explicitly providing the desired key length during the -initalization of a key pair generator. - -According to https://docs.oracle.com/javase/7/docs/api/javax/crypto/Cipher.html -every implementation of the Java platform is required to implement RSA with both -1024 and 2048 bit key sizes. Hence a 2048 bit default should not lead to -compatibility problems. - -**Cryptographically strong random numbers:** -So far the tests check that java.util.Random is not used. This needs to be -extended. - -**Other bugs:** -The public exponent e should be larger than 1 [CVE-1999-1444] - -## RSA PKCS #1 v1.5 encryption - -PKCS #1 v1.5 padding is susceptible to adaptive chosen ciphertext attacks and -hence should be avoided [B98]. The difficulty of exploiting protocols using -PKCS #1 v1.5 encryption often depends on the amount of information leaked after -decrypting corrupt ciphertexts. Implementations frequently leak information -about the decrypted plaintext in form of error messages. The content of the -error messages are extremely helpful to potential attackers. Bardou et al. -[BFKLSST12] analyze the difficult of attacks based on different types of -information leakage. Smart even describes an attack that only needs about 40 -chosen ciphertexts [S10], though in this case the encryption did not use PKCS #1 -padding. - -**Bugs** - -* Bouncycastle throws detailed exceptions: - InvalidCipherTextException("unknown block type") or - InvalidCipherTextException("block padding incorrect"). - - - -**Tests** To test whether an implementation leaks more information than -necessary a test decrypts some random ciphertexts and catches the exceptions. If -the exceptions are distinguishable then the test assumes that unnecessary -information about the padding is leaked. - -Due to the nature of unit tests not every attack can be detected this way. Some -attacks require a large number of ciphertexts to be detected if random -ciphertexts are used. For example Klima et al. [KPR03] describe an -implementation flaw that could not be detected with our test. - -Timing leakages because of differences in parsing the padding can leak -information (e.g. CVE-2015-7827). Such differences are too small to be reliably -detectable in unit tests. - -## RSA OAEP - -Manger describes an chosen ciphertext attack against RSA in [M01]. There are -implementations that were susceptible to Mangers attack, e.g. [CVE-2012-5081]. - -## RSA PKCS1 signatures -**Potential problems:** - -* Some libraries parse PKCS#1 padding during signature verification - incorrectly. -* Some libraries determine the hash function from the signature (rather than - encoding this in the key) Effect: -* If the verification is buggy then an attacker might be able to generate - signatures for keys with a small (i.e. e=3) public exponent. -* If the hash algorithm is not determined by in an authentic manner then - preimage attacks against weak hashes are possible, even if the hashes are - not used by the signer. - -**Countermeasures:** A good way to implement RSA signature verification is -described in the standard PKCS#1 v.2.2 Section 8.2.2. This standard proposes to -reconstruct the padding during verification and compare the padded hash to the -value $$s^e \bmod n$$ obtained from applying a public key exponentiation to the -signature s. Since this is a recurring bug it makes also a lot of sense to avoid -small public exponents and prefer for example e=65537 . - -**List of broken implementations** -This is a large list. - -## References - -\[B98]: D. Bleichenbacher, "Chosen ciphertext attacks against protocols based on -the RSA encryption standard PKCS# 1" Crypto 98 - -\[M01]: J. Manger, "A chosen ciphertext attack on RSA optimal asymmetric -encryption padding (OAEP) as standardized in PKCS# 1 v2.0", Crypto 2001 This -paper shows that OAEP is susceptible to a chosen ciphertext attack if error -messages distinguish between different failure condidtions. [S10]: N. Smart, -"Errors matter: Breaking RSA-based PIN encryption with thirty ciphertext -validity queries" RSA conference, 2010 This paper shows that padding oracle -attacks can be successful with even a small number of queries. - -\[KPR03]: V. Klima, O. Pokorny, and T. Rosa, "Attacking RSA-based Sessions in -SSL/TLS" https://eprint.iacr.org/2003/052/ - -\[BFKLSST12]: "Efficient padding oracle attacks on cryptographic hardware" R. -Bardou, R. Focardi, Y. Kawamoto, L. Simionato, G. Steel, J.K. Tsay, Crypto 2012 - -\[NIST SP 800-57]: -http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r4.pdf - -\[Enisa]: "Algorithms, key size and parameters report – 2014" -https://www.enisa.europa.eu/publications/algorithms-key-size-and-parameters-report-2014 - -\[ECRYPT II]: Yearly Report on Algorithms and Keysizes (2011-2012), -http://www.ecrypt.eu.org/ecrypt2/documents/D.SPA.20.pdf - -\[CVE-1999-1444]: Alibaba 2.0 generated RSA key pairs with an exponent 1 - -\[CVE-2012-5081]: Java JSSE provider leaked information through exceptions and -timing. Both the PKCS #1 padding and the OAEP padding were broken: -http://www-brs.ub.ruhr-uni-bochum.de/netahtml/HSS/Diss/MeyerChristopher/diss.pdf diff --git a/java/com/google/security/wycheproof/BouncyCastleAllTests.java b/java/com/google/security/wycheproof/BouncyCastleAllTests.java deleted file mode 100644 index 47a4dcf..0000000 --- a/java/com/google/security/wycheproof/BouncyCastleAllTests.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @license - * Copyright 2016 Google Inc. All rights reserved. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.security.wycheproof; - -import com.google.security.wycheproof.WycheproofRunner.Provider; -import com.google.security.wycheproof.WycheproofRunner.ProviderType; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.junit.BeforeClass; -import org.junit.runner.RunWith; -import org.junit.runners.Suite.SuiteClasses; - -/** - * BouncyCastleAllTests runs all tests. - */ -@RunWith(WycheproofRunner.class) -@SuiteClasses({ - AesEaxTest.class, - AesGcmTest.class, - BasicTest.class, - CipherInputStreamTest.class, - CipherOutputStreamTest.class, - DhTest.class, - DhiesTest.class, - DsaTest.class, - EcKeyTest.class, - EcdhTest.class, - EcdsaTest.class, - EciesTest.class, - RsaEncryptionTest.class, - RsaKeyTest.class, - RsaSignatureTest.class, -}) -@Provider(ProviderType.BOUNCY_CASTLE) -public final class BouncyCastleAllTests { - @BeforeClass - public static void setUp() throws Exception { - TestUtil.installOnlyThisProvider(new BouncyCastleProvider()); - } -} diff --git a/java/com/google/security/wycheproof/BouncyCastleTest.java b/java/com/google/security/wycheproof/BouncyCastleTest.java deleted file mode 100644 index 941b94f..0000000 --- a/java/com/google/security/wycheproof/BouncyCastleTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * @license - * Copyright 2016 Google Inc. All rights reserved. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.security.wycheproof; - -import com.google.security.wycheproof.WycheproofRunner.Fast; -import com.google.security.wycheproof.WycheproofRunner.Provider; -import com.google.security.wycheproof.WycheproofRunner.ProviderType; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.junit.BeforeClass; -import org.junit.runner.RunWith; -import org.junit.runners.Suite.SuiteClasses; - -/** - * BouncyCastleTest excludes {@code @SlowTest} tests. - */ -@RunWith(WycheproofRunner.class) -@SuiteClasses({ - AesEaxTest.class, - AesGcmTest.class, - BasicTest.class, - CipherInputStreamTest.class, - CipherOutputStreamTest.class, - DhTest.class, - DhiesTest.class, - DsaTest.class, - EcKeyTest.class, - EcdhTest.class, - EcdsaTest.class, - EciesTest.class, - RsaEncryptionTest.class, - RsaKeyTest.class, - RsaSignatureTest.class, -}) -@Provider(ProviderType.BOUNCY_CASTLE) -@Fast -public final class BouncyCastleTest { - @BeforeClass - public static void setUp() throws Exception { - TestUtil.installOnlyThisProvider(new BouncyCastleProvider()); - } -} diff --git a/java/com/google/security/wycheproof/ConscryptTest.java b/java/com/google/security/wycheproof/ConscryptTest.java deleted file mode 100644 index c4f58d5..0000000 --- a/java/com/google/security/wycheproof/ConscryptTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @license - * Copyright 2016 Google Inc. All rights reserved. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.security.wycheproof; - -import com.google.security.wycheproof.WycheproofRunner.Fast; -import com.google.security.wycheproof.WycheproofRunner.Provider; -import com.google.security.wycheproof.WycheproofRunner.ProviderType; -import org.conscrypt.OpenSSLProvider; -import org.junit.BeforeClass; -import org.junit.runner.RunWith; -import org.junit.runners.Suite.SuiteClasses; - -/** - * Conscrypt is a Java security provider that uses OpenSSL. See {@link https://conscrypt.org/}. - * ConscryptTest excludes {@code @SlowTest} tests. - */ -@RunWith(WycheproofRunner.class) -@SuiteClasses({ - AesGcmTest.class, - BasicTest.class, - CipherInputStreamTest.class, - CipherOutputStreamTest.class, - EcKeyTest.class, - EcdhTest.class, - EcdsaTest.class, - RsaEncryptionTest.class, - RsaKeyTest.class, - RsaSignatureTest.class -}) -@Provider(ProviderType.CONSCRYPT) -@Fast -public final class ConscryptTest { - @BeforeClass - public static void setUp() throws Exception { - TestUtil.installOnlyThisProvider(new OpenSSLProvider()); - } -} diff --git a/java/com/google/security/wycheproof/EcUtil.java b/java/com/google/security/wycheproof/EcUtil.java deleted file mode 100644 index f464cba..0000000 --- a/java/com/google/security/wycheproof/EcUtil.java +++ /dev/null @@ -1,454 +0,0 @@ -/** - * @license - * Copyright 2016 Google Inc. All rights reserved. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.security.wycheproof; - -import java.math.BigInteger; -import java.security.AlgorithmParameters; -import java.security.GeneralSecurityException; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; -import java.security.interfaces.ECPublicKey; -import java.security.spec.ECField; -import java.security.spec.ECFieldFp; -import java.security.spec.ECGenParameterSpec; -import java.security.spec.ECParameterSpec; -import java.security.spec.ECPoint; -import java.security.spec.ECPublicKeySpec; -import java.security.spec.EllipticCurve; -import java.security.spec.InvalidParameterSpecException; -import java.util.Arrays; - -/** - * Some utilities for testing Elliptic curve crypto. This code is for testing only and hasn't been - * reviewed for production. - */ -public class EcUtil { - /** - * Returns the ECParameterSpec for a named curve. Not every provider implements the - * AlgorithmParameters. Therefore, most test use alternative functions. - */ - public static ECParameterSpec getCurveSpec(String name) - throws NoSuchAlgorithmException, InvalidParameterSpecException { - AlgorithmParameters parameters = AlgorithmParameters.getInstance("EC"); - parameters.init(new ECGenParameterSpec(name)); - return parameters.getParameterSpec(ECParameterSpec.class); - } - - /** - * Returns the ECParameterSpec for a named curve. Only a handful curves that are used in the tests - * are implemented. - */ - public static ECParameterSpec getCurveSpecRef(String name) throws NoSuchAlgorithmException { - if (name.equals("secp224r1")) { - return getNistP224Params(); - } else if (name.equals("secp256r1")) { - return getNistP256Params(); - } else if (name.equals("secp384r1")) { - return getNistP384Params(); - } else if (name.equals("secp521r1")) { - return getNistP521Params(); - } else if (name.equals("brainpoolp256r1")) { - return getBrainpoolP256r1Params(); - } else { - throw new NoSuchAlgorithmException("Curve not implemented:" + name); - } - } - - public static ECParameterSpec getNistCurveSpec( - String decimalP, String decimalN, String hexB, String hexGX, String hexGY) { - final BigInteger p = new BigInteger(decimalP); - final BigInteger n = new BigInteger(decimalN); - final BigInteger three = new BigInteger("3"); - final BigInteger a = p.subtract(three); - final BigInteger b = new BigInteger(hexB, 16); - final BigInteger gx = new BigInteger(hexGX, 16); - final BigInteger gy = new BigInteger(hexGY, 16); - final int h = 1; - ECFieldFp fp = new ECFieldFp(p); - java.security.spec.EllipticCurve curveSpec = new java.security.spec.EllipticCurve(fp, a, b); - ECPoint g = new ECPoint(gx, gy); - ECParameterSpec ecSpec = new ECParameterSpec(curveSpec, g, n, h); - return ecSpec; - } - - public static ECParameterSpec getNistP224Params() { - return getNistCurveSpec( - "26959946667150639794667015087019630673557916260026308143510066298881", - "26959946667150639794667015087019625940457807714424391721682722368061", - "b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4", - "b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", - "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34"); - } - - public static ECParameterSpec getNistP256Params() { - return getNistCurveSpec( - "115792089210356248762697446949407573530086143415290314195533631308867097853951", - "115792089210356248762697446949407573529996955224135760342422259061068512044369", - "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", - "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", - "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"); - } - - public static ECParameterSpec getNistP384Params() { - return getNistCurveSpec( - "3940200619639447921227904010014361380507973927046544666794829340" - + "4245721771496870329047266088258938001861606973112319", - "3940200619639447921227904010014361380507973927046544666794690527" - + "9627659399113263569398956308152294913554433653942643", - "b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a" - + "c656398d8a2ed19d2a85c8edd3ec2aef", - "aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38" - + "5502f25dbf55296c3a545e3872760ab7", - "3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" - + "0a60b1ce1d7e819d7a431d7c90ea0e5f"); - } - - public static ECParameterSpec getNistP521Params() { - return getNistCurveSpec( - "6864797660130609714981900799081393217269435300143305409394463459" - + "18554318339765605212255964066145455497729631139148085803712198" - + "7999716643812574028291115057151", - "6864797660130609714981900799081393217269435300143305409394463459" - + "18554318339765539424505774633321719753296399637136332111386476" - + "8612440380340372808892707005449", - "051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10" - + "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", - "c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d" - + "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", - "11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6" - + "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650"); - } - - public static ECParameterSpec getBrainpoolP256r1Params() { - BigInteger p = - new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", 16); - BigInteger a = - new BigInteger("7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", 16); - BigInteger b = - new BigInteger("26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", 16); - BigInteger x = - new BigInteger("8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", 16); - BigInteger y = - new BigInteger("547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", 16); - BigInteger n = - new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16); - final int h = 1; - ECFieldFp fp = new ECFieldFp(p); - EllipticCurve curve = new EllipticCurve(fp, a, b); - ECPoint g = new ECPoint(x, y); - return new ECParameterSpec(curve, g, n, h); - } - - /** - * Compute the Legendre symbol of x mod p. This implementation is slow. Faster would be the - * computation for the Jacobi symbol. - * - * @param x an integer - * @param p a prime modulus - * @returns 1 if x is a quadratic residue, -1 if x is a non-quadratic residue and 0 if x and p are - * not coprime. - * @throws GeneralSecurityException when the computation shows that p is not prime. - */ - public static int legendre(BigInteger x, BigInteger p) throws GeneralSecurityException { - BigInteger q = p.subtract(BigInteger.ONE).shiftRight(1); - BigInteger t = x.modPow(q, p); - if (t.equals(BigInteger.ONE)) { - return 1; - } else if (t.equals(BigInteger.ZERO)) { - return 0; - } else if (t.add(BigInteger.ONE).equals(p)) { - return -1; - } else { - throw new GeneralSecurityException("p is not prime"); - } - } - - /** - * Computes a modular square root. Timing and exceptions can leak information about the inputs. - * Therefore this method must only be used in tests. - * - * @param x the square - * @param p the prime modulus - * @returns a value s such that s^2 mod p == x mod p - * @throws GeneralSecurityException if the square root could not be found. - */ - public static BigInteger modSqrt(BigInteger x, BigInteger p) throws GeneralSecurityException { - if (p.signum() != 1) { - throw new GeneralSecurityException("p must be positive"); - } - x = x.mod(p); - BigInteger squareRoot = null; - // Special case for x == 0. - // This check is necessary for Cipolla's algorithm. - if (x.equals(BigInteger.ZERO)) { - return x; - } - if (p.testBit(0) && p.testBit(1)) { - // Case p % 4 == 3 - // q = (p + 1) / 4 - BigInteger q = p.add(BigInteger.ONE).shiftRight(2); - squareRoot = x.modPow(q, p); - } else if (p.testBit(0) && !p.testBit(1)) { - // Case p % 4 == 1 - // For this case we use Cipolla's algorithm. - // This alogorithm is preferrable to Tonelli-Shanks for primes p where p-1 is divisible by - // a large power of 2, which is a frequent choice since it simplifies modular reduction. - BigInteger a = BigInteger.ONE; - BigInteger d = null; - while (true) { - d = a.multiply(a).subtract(x).mod(p); - // Computes the Legendre symbol. Using the Jacobi symbol would be a faster. Using Legendre - // has the advantage, that it detects a non prime p with high probability. - // On the other hand if p = q^2 then the Jacobi (d/p)==1 for almost all d's and thus - // using the Jacobi symbol here can result in an endless loop with invalid inputs. - int t = legendre(d, p); - if (t == -1) { - break; - } else { - a = a.add(BigInteger.ONE); - } - } - // Since d = a^2 - n is a non-residue modulo p, we have - // a - sqrt(d) == (a+sqrt(d))^p (mod p), - // and hence - // n == (a + sqrt(d))(a - sqrt(d) == (a+sqrt(d))^(p+1) (mod p). - // Thus if n is square then (a+sqrt(d))^((p+1)/2) (mod p) is a square root of n. - BigInteger q = p.add(BigInteger.ONE).shiftRight(1); - BigInteger u = a; - BigInteger v = BigInteger.ONE; - for (int bit = q.bitLength() - 2; bit >= 0; bit--) { - // Compute (u + v sqrt(d))^2 - BigInteger tmp = u.multiply(v); - u = u.multiply(u).add(v.multiply(v).mod(p).multiply(d)).mod(p); - v = tmp.add(tmp).mod(p); - if (q.testBit(bit)) { - tmp = u.multiply(a).add(v.multiply(d)).mod(p); - v = a.multiply(v).add(u).mod(p); - u = tmp; - } - } - squareRoot = u; - } - // The methods used to compute the square root only guarantee a correct result if the - // preconditions (i.e. p prime and x is a square) are satisfied. Otherwise the value is - // undefined. Hence, it is important to verify that squareRoot is indeed a square root. - if (squareRoot != null && squareRoot.multiply(squareRoot).mod(p).compareTo(x) != 0) { - throw new GeneralSecurityException("Could not find square root"); - } - return squareRoot; - } - - /** - * Returns the modulus of the field used by the curve specified in ecParams. - * - * @param curve must be a prime order elliptic curve - * @return the order of the finite field over which curve is defined. - */ - public static BigInteger getModulus(EllipticCurve curve) throws GeneralSecurityException { - java.security.spec.ECField field = curve.getField(); - if (field instanceof java.security.spec.ECFieldFp) { - return ((java.security.spec.ECFieldFp) field).getP(); - } else { - throw new GeneralSecurityException("Only curves over prime order fields are supported"); - } - } - - /** - * Returns the size of an element of the field over which the curve is defined. - * - * @param curve must be a prime order elliptic curve - * @return the size of an element in bits - */ - public static int fieldSizeInBits(EllipticCurve curve) throws GeneralSecurityException { - return getModulus(curve).subtract(BigInteger.ONE).bitLength(); - } - - /** - * Returns the size of an element of the field over which the curve is defined. - * - * @param curve must be a prime order elliptic curve - * @return the size of an element in bytes. - */ - public static int fieldSizeInBytes(EllipticCurve curve) throws GeneralSecurityException { - return (fieldSizeInBits(curve) + 7) / 8; - } - - /** - * Checks that a point is on a given elliptic curve. This method implements the partial public key - * validation routine from Section 5.6.2.6 of NIST SP 800-56A - * http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar08-2007.pdf A partial - * public key validation is sufficient for curves with cofactor 1. See Section B.3 of - * http://www.nsa.gov/ia/_files/SuiteB_Implementer_G-113808.pdf The point validations above are - * taken from recommendations for ECDH, because parameter checks in ECDH are much more important - * than for the case of ECDSA. Performing this test for ECDSA keys is mainly a sanity check. - * - * @param point the point that needs verification - * @param ec the elliptic curve. This must be a curve over a prime order field. - * @throws GeneralSecurityException if the field is binary or if the point is not on the curve. - */ - public static void checkPointOnCurve(ECPoint point, EllipticCurve ec) - throws GeneralSecurityException { - BigInteger p = getModulus(ec); - BigInteger x = point.getAffineX(); - BigInteger y = point.getAffineY(); - if (x == null || y == null) { - throw new GeneralSecurityException("point is at infinity"); - } - // Check 0 <= x < p and 0 <= y < p. - if (x.signum() == -1 || x.compareTo(p) != -1) { - throw new GeneralSecurityException("x is out of range"); - } - if (y.signum() == -1 || y.compareTo(p) != -1) { - throw new GeneralSecurityException("y is out of range"); - } - // Check y^2 == x^3 + a x + b (mod p) - BigInteger lhs = y.multiply(y).mod(p); - BigInteger rhs = x.multiply(x).add(ec.getA()).multiply(x).add(ec.getB()).mod(p); - if (!lhs.equals(rhs)) { - throw new GeneralSecurityException("Point is not on curve"); - } - } - - /** - * Checks a public key. I.e. this checks that the point defining the public key is on the curve. - * - * @param key must be a key defined over a curve using a prime order field. - * @throws GeneralSecurityException if the key is not valid. - */ - public static void checkPublicKey(ECPublicKey key) throws GeneralSecurityException { - checkPointOnCurve(key.getW(), key.getParams().getCurve()); - } - - /** - * Decompress a point - * - * @param x The x-coordinate of the point - * @param bit0 true if the least significant bit of y is set. - * @param ecParams contains the curve of the point. This must be over a prime order field. - */ - public static ECPoint getPoint(BigInteger x, boolean bit0, ECParameterSpec ecParams) - throws GeneralSecurityException { - EllipticCurve ec = ecParams.getCurve(); - ECField field = ec.getField(); - if (!(field instanceof ECFieldFp)) { - throw new GeneralSecurityException("Only curves over prime order fields are supported"); - } - BigInteger p = ((java.security.spec.ECFieldFp) field).getP(); - if (x.compareTo(BigInteger.ZERO) == -1 || x.compareTo(p) != -1) { - throw new GeneralSecurityException("x is out of range"); - } - // Compute rhs == x^3 + a x + b (mod p) - BigInteger rhs = x.multiply(x).add(ec.getA()).multiply(x).add(ec.getB()).mod(p); - BigInteger y = modSqrt(rhs, p); - if (bit0 != y.testBit(0)) { - y = p.subtract(y).mod(p); - } - return new ECPoint(x, y); - } - - /** - * Decompress a point on an elliptic curve. - * - * @param bytes The compressed point. Its representation is z || x where z is 2+lsb(y) and x is - * using a unsigned fixed length big-endian representation. - * @param ecParams the specification of the curve. Only Weierstrass curves over prime order fields - * are implemented. - */ - public static ECPoint decompressPoint(byte[] bytes, ECParameterSpec ecParams) - throws GeneralSecurityException { - EllipticCurve ec = ecParams.getCurve(); - ECField field = ec.getField(); - if (!(field instanceof ECFieldFp)) { - throw new GeneralSecurityException("Only curves over prime order fields are supported"); - } - BigInteger p = ((java.security.spec.ECFieldFp) field).getP(); - int expectedLength = 1 + (p.bitLength() + 7) / 8; - if (bytes.length != expectedLength) { - throw new GeneralSecurityException("compressed point has wrong length"); - } - boolean lsb; - switch (bytes[0]) { - case 2: - lsb = false; - break; - case 3: - lsb = true; - break; - default: - throw new GeneralSecurityException("Invalid format"); - } - BigInteger x = new BigInteger(1, Arrays.copyOfRange(bytes, 1, bytes.length)); - if (x.compareTo(BigInteger.ZERO) == -1 || x.compareTo(p) != -1) { - throw new GeneralSecurityException("x is out of range"); - } - // Compute rhs == x^3 + a x + b (mod p) - BigInteger rhs = x.multiply(x).add(ec.getA()).multiply(x).add(ec.getB()).mod(p); - BigInteger y = modSqrt(rhs, p); - if (lsb != y.testBit(0)) { - y = p.subtract(y).mod(p); - } - return new ECPoint(x, y); - } - - /** - * Returns a weak public key of order 3 such that the public key point is on the curve specified - * in ecParams. This method is used to check ECC implementations for missing step in the - * verification of the public key. E.g. implementations of ECDH must verify that the public key - * contains a point on the curve as well as public and secret key are using the same curve. - * - * @param ecParams the parameters of the key to attack. This must be a curve in Weierstrass form - * over a prime order field. - * @return a weak EC group with a genrator of order 3. - */ - public static ECPublicKeySpec getWeakPublicKey(ECParameterSpec ecParams) - throws GeneralSecurityException { - EllipticCurve curve = ecParams.getCurve(); - KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC"); - keyGen.initialize(ecParams); - BigInteger p = getModulus(curve); - BigInteger three = new BigInteger("3"); - while (true) { - // Generate a point on the original curve - KeyPair keyPair = keyGen.generateKeyPair(); - ECPublicKey pub = (ECPublicKey) keyPair.getPublic(); - ECPoint w = pub.getW(); - BigInteger x = w.getAffineX(); - BigInteger y = w.getAffineY(); - // Find the curve parameters a,b such that 3*w = infinity. - // This is the case if the following equations are satisfied: - // 3x == l^2 (mod p) - // l == (3x^2 + a) / 2*y (mod p) - // y^2 == x^3 + ax + b (mod p) - BigInteger l; - try { - l = modSqrt(x.multiply(three), p); - } catch (GeneralSecurityException ex) { - continue; - } - BigInteger xSqr = x.multiply(x).mod(p); - BigInteger a = l.multiply(y.add(y)).subtract(xSqr.multiply(three)).mod(p); - BigInteger b = y.multiply(y).subtract(x.multiply(xSqr.add(a))).mod(p); - EllipticCurve newCurve = new EllipticCurve(curve.getField(), a, b); - // Just a sanity check. - checkPointOnCurve(w, newCurve); - // Cofactor and order are of course wrong. - ECParameterSpec spec = new ECParameterSpec(newCurve, w, p, 1); - return new ECPublicKeySpec(w, spec); - } - } -} diff --git a/java/com/google/security/wycheproof/JsonTest.java b/java/com/google/security/wycheproof/JsonTest.java deleted file mode 100644 index 145eebe..0000000 --- a/java/com/google/security/wycheproof/JsonTest.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @license - * Copyright 2017 Google Inc. All rights reserved. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.security.wycheproof; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -/** Provider independent tests using the JSON test vectors */ -@RunWith(Suite.class) -@SuiteClasses({JsonSignatureTest.class}) -public final class JsonTest {} diff --git a/java/com/google/security/wycheproof/OpenJDKAllTests.java b/java/com/google/security/wycheproof/OpenJDKAllTests.java deleted file mode 100644 index a2b3b06..0000000 --- a/java/com/google/security/wycheproof/OpenJDKAllTests.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.google.security.wycheproof; - -import com.google.security.wycheproof.WycheproofRunner.Provider; -import com.google.security.wycheproof.WycheproofRunner.ProviderType; -import org.junit.BeforeClass; -import org.junit.runner.RunWith; -import org.junit.runners.Suite.SuiteClasses; - -/** - * Tests for OpenJDK's providers: SunJCE, SunEC, etc. - * OpenJDKAllTests runs all tests. - */ -@RunWith(WycheproofRunner.class) -@SuiteClasses({ - AesGcmTest.class, - BasicTest.class, - CipherInputStreamTest.class, - CipherOutputStreamTest.class, - DhTest.class, - DsaTest.class, - EcKeyTest.class, - EcdhTest.class, - EcdsaTest.class, - RsaEncryptionTest.class, - RsaKeyTest.class, - RsaSignatureTest.class -}) -@Provider(ProviderType.OPENJDK) -public final class OpenJDKAllTests { - @BeforeClass - public static void setUp() throws Exception { - TestUtil.installOnlyOpenJDKProviders(); - } -} diff --git a/java/com/google/security/wycheproof/OpenJDKTest.java b/java/com/google/security/wycheproof/OpenJDKTest.java deleted file mode 100644 index b326fef..0000000 --- a/java/com/google/security/wycheproof/OpenJDKTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.google.security.wycheproof; - -import com.google.security.wycheproof.WycheproofRunner.Fast; -import com.google.security.wycheproof.WycheproofRunner.Provider; -import com.google.security.wycheproof.WycheproofRunner.ProviderType; -import org.junit.BeforeClass; -import org.junit.runner.RunWith; -import org.junit.runners.Suite.SuiteClasses; - -/** - * Tests for OpenJDK's providers: SunJCE, SunEC, etc. - * OpenJDKTest excludes slow tests. - */ -@RunWith(WycheproofRunner.class) -@SuiteClasses({ - AesGcmTest.class, - BasicTest.class, - CipherInputStreamTest.class, - CipherOutputStreamTest.class, - DhTest.class, - DsaTest.class, - EcKeyTest.class, - EcdhTest.class, - EcdsaTest.class, - RsaEncryptionTest.class, - RsaKeyTest.class, - RsaSignatureTest.class -}) -@Provider(ProviderType.OPENJDK) -@Fast -public final class OpenJDKTest { - @BeforeClass - public static void setUp() throws Exception { - TestUtil.installOnlyOpenJDKProviders(); - } -} diff --git a/java/com/google/security/wycheproof/ProviderIndependentTest.java b/java/com/google/security/wycheproof/ProviderIndependentTest.java deleted file mode 100644 index 931fc64..0000000 --- a/java/com/google/security/wycheproof/ProviderIndependentTest.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @license - * Copyright 2016 Google Inc. All rights reserved. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.security.wycheproof; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -/** Provider independent tests */ -@RunWith(Suite.class) -@SuiteClasses({BigIntegerTest.class}) -public final class ProviderIndependentTest {} diff --git a/java/com/google/security/wycheproof/RandomUtil.java b/java/com/google/security/wycheproof/RandomUtil.java deleted file mode 100644 index 388c272..0000000 --- a/java/com/google/security/wycheproof/RandomUtil.java +++ /dev/null @@ -1,185 +0,0 @@ -/** - * @license - * Copyright 2016 Google Inc. All rights reserved. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.security.wycheproof; - -import java.math.BigInteger; -import java.nio.ByteBuffer; -import java.security.GeneralSecurityException; -import java.util.Random; - -/** - * A collection of utilities for testing random number generators. So far this util simply checks - * that random numbers are not generated by java.util.Random. Eventually we plan to add detection - * for other random number generators too. - * - * @author bleichen@google.com (Daniel Bleichenbacher) - */ -public class RandomUtil { - // Constants for java.util.Random; - static final long A = 0x5DEECE66DL; - static final long A_INVERSE = 246154705703781L; - static final long C = 0xBL; - - /** Given a state of a java.util.Random object compute the next state. */ - protected static long nextState(long seed) { - return (seed * A + C) & ((1L << 48) - 1); - } - - /** Give the state after stepping java.util.Random n times. */ - protected static long step(long seed, long n) { - long a = A; - long c = C; - n = n & 0xffffffffffffL; - while (n != 0) { - if ((n & 1) == 1) { - seed = seed * a + c; - } - c = c * (a + 1); - a = a * a; - n = n >> 1; - } - return seed & 0xffffffffffffL; - } - - /** Given a state of a java.util.Random object compute the previous state. */ - protected static long previousState(long seed) { - return ((seed - C) * A_INVERSE) & ((1L << 48) - 1); - } - - /** Computes a seed that would initialize a java.util.Random object with a given state. */ - protected static long getSeedForState(long seed) { - return seed ^ A; - } - - protected static long getStateForSeed(long seed) { - return (seed ^ A) & 0xffffffffffffL; - } - - /** - * Given two subsequent outputs x0 and x1 from java.util.Random this function computes the - * internal state of java.util.Random after returning x0 or returns -1 if no such state exists. - */ - protected static long getState(int x0, int x1) { - long mask = (1L << 48) - 1; - long multiplier = A; - // The state of the random number generator after returning x0 is - // l0 + eps for some 0 <= eps < 2**16. - long l0 = ((long) x0 << 16) & mask; - // The state of the random number generator after returning x1 is - // l1 + delta for some 0 <= delta < 2**16. - long l1 = ((long) x1 << 16) & mask; - // We have l1 + delta = (l0 + eps)*multiplier + 0xBL (mod 2**48). - // This allows to find an upper bound w for eps * multiplier mod 2**48 - // by assuming delta = 2**16-1. - long w = (l1 - l0 * multiplier + 65535L - 0xBL) & mask; - // The reduction eps * multiplier mod 2**48 only cuts off at most 3 bits. - // Hence a simple search is sufficient. The maximal number of loops is 6. - for (long em = w; em < (multiplier << 16); em += 1L << 48) { - // If the high order bits of em are guessed correctly then - // em == eps * multiplier + 65535 - delta. - long eps = em / multiplier; - long state0 = l0 + eps; - long state1 = nextState(state0); - if ((state1 & 0xffffffff0000L) == l1) { - return state0; - } - } - return -1; - } - - /** - * Find a seed such that this integer is the result of - * - *
{@code
-   * Random rand = new Random();
-   * rand.setSeed(seed);
-   * return new BigInteger(k, rand);
-   * }
- * - * where k is max(64, x.BitLength()); - * - *

Returns -1 if no such seed exists. - */ - // TODO(bleichen): We want to detect cases where some of the bits - // (i.e. most significant bits or least significant bits have - // been modified. Often this happens during the generation - // of primes or other things. - // TODO(bleichen): This method is incomplete. - protected static long getSeedFor(java.math.BigInteger x) { - byte[] bytes = x.toByteArray(); - if (bytes.length == 0) { - return -1; - } - ByteBuffer buffer = ByteBuffer.allocate(8); - int offset = bytes[0] == 0 ? 1 : 0; - if (bytes.length - offset < 8) { - int size = bytes.length - offset; - buffer.position(8 - size); - buffer.put(bytes, offset, size); - } else { - buffer.put(bytes, offset, 8); - } - buffer.flip(); - buffer.order(java.nio.ByteOrder.LITTLE_ENDIAN); - int x0 = buffer.getInt(); - int x1 = buffer.getInt(); - long state = getState(x0, x1); - if (state == -1) { - return -1; - } - return getSeedForState(previousState(state)); - } - - /** Attempts to find a seed such that it generates the prime p. Returns -1 if no seed is found. */ - static long getSeedForPrime(BigInteger p) { - int confidence = 64; - Random rand = new Random(); - int size = p.bitLength(); - // Prime generation often sets the most significant bit. - // Hence, clearing the most significant bit can help to find - // the seed used for the prime generation. - for (BigInteger x : new BigInteger[] {p, p.clearBit(size - 1)}) { - long seed = getSeedFor(x); - if (seed != -1) { - rand.setSeed(seed); - BigInteger q = new BigInteger(size, confidence, rand); - if (q.equals(p)) { - return seed; - } - } - } - return -1; - } - - /** - * Checks whether p is a random prime. A prime generated with a secure random number generator - * passes with probability > 1-2^{-32}. No checks are performed for primes smaller than 96 bits. - * - * @throws GeneralSecurityException if the prime was generated using java.util.Random - */ - static void checkPrime(BigInteger p) throws GeneralSecurityException { - // We can't reliably detect java.util.Random for small primes. - if (p.bitLength() < 96) { - return; - } - long seed = getSeedForPrime(p); - if (seed != -1) { - throw new GeneralSecurityException( - "java.util.Random with seed " + seed + " was likely used to generate prime"); - } - } -} diff --git a/java/com/google/security/wycheproof/SpongyCastleAllTests.java b/java/com/google/security/wycheproof/SpongyCastleAllTests.java deleted file mode 100644 index 5566827..0000000 --- a/java/com/google/security/wycheproof/SpongyCastleAllTests.java +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @license - * Copyright 2016 Google Inc. All rights reserved. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.security.wycheproof; - -import com.google.security.wycheproof.WycheproofRunner.Provider; -import com.google.security.wycheproof.WycheproofRunner.ProviderType; -import org.junit.BeforeClass; -import org.junit.runner.RunWith; -import org.junit.runners.Suite.SuiteClasses; -import org.spongycastle.jce.provider.BouncyCastleProvider; - -/** - * SpongyCastleTest excludes {@code @SlowTest} tests. - * SpongyCastleAllTests runs all tests. - */ -@RunWith(WycheproofRunner.class) -@SuiteClasses({ - AesEaxTest.class, - AesGcmTest.class, - BasicTest.class, - CipherInputStreamTest.class, - CipherOutputStreamTest.class, - DhTest.class, - DhiesTest.class, - DsaTest.class, - EcKeyTest.class, - EcdhTest.class, - EcdsaTest.class, - EciesTest.class, - RsaEncryptionTest.class, - RsaKeyTest.class, - RsaSignatureTest.class, -}) -@Provider(ProviderType.SPONGY_CASTLE) -public final class SpongyCastleAllTests { - @BeforeClass - public static void setUp() throws Exception { - TestUtil.installOnlyThisProvider(new BouncyCastleProvider()); - } -} diff --git a/java/com/google/security/wycheproof/SpongyCastleTest.java b/java/com/google/security/wycheproof/SpongyCastleTest.java deleted file mode 100644 index 73c8ca1..0000000 --- a/java/com/google/security/wycheproof/SpongyCastleTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @license - * Copyright 2016 Google Inc. All rights reserved. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.security.wycheproof; - -import com.google.security.wycheproof.WycheproofRunner.Fast; -import com.google.security.wycheproof.WycheproofRunner.Provider; -import com.google.security.wycheproof.WycheproofRunner.ProviderType; -import org.junit.BeforeClass; -import org.junit.runner.RunWith; -import org.junit.runners.Suite.SuiteClasses; -import org.spongycastle.jce.provider.BouncyCastleProvider; - -/** - * Spongy Castle is a Bouncy Castle clone with a few changes to make it work on Android. - * SpongyCastleTest excludes {@code @SlowTest} tests. - */ -@RunWith(WycheproofRunner.class) -@SuiteClasses({ - AesEaxTest.class, - AesGcmTest.class, - BasicTest.class, - CipherInputStreamTest.class, - CipherOutputStreamTest.class, - DhTest.class, - DhiesTest.class, - DsaTest.class, - EcKeyTest.class, - EcdhTest.class, - EcdsaTest.class, - EciesTest.class, - RsaEncryptionTest.class, - RsaKeyTest.class, - RsaSignatureTest.class, -}) -@Provider(ProviderType.SPONGY_CASTLE) -@Fast -public final class SpongyCastleTest { - @BeforeClass - public static void setUp() throws Exception { - TestUtil.installOnlyThisProvider(new BouncyCastleProvider()); - } -} diff --git a/java/com/google/security/wycheproof/TestUtil.java b/java/com/google/security/wycheproof/TestUtil.java deleted file mode 100644 index ae21adc..0000000 --- a/java/com/google/security/wycheproof/TestUtil.java +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @license - * Copyright 2016 Google Inc. All rights reserved. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.security.wycheproof; - -import java.nio.ByteBuffer; -import java.security.Provider; -import java.security.Security; - -/** Test utilities */ -public class TestUtil { - - public static String bytesToHex(byte[] bytes) { - // bytesToHex is used to convert output from Cipher. - // cipher.update can return null, which is equivalent to returning - // no plaitext rsp. ciphertext. - if (bytes == null) { - return ""; - } - String chars = "0123456789abcdef"; - StringBuilder result = new StringBuilder(2 * bytes.length); - for (byte b : bytes) { - // convert to unsigned - int val = b & 0xff; - result.append(chars.charAt(val / 16)); - result.append(chars.charAt(val % 16)); - } - return result.toString(); - } - - /** - * Returns a hexadecimal representation of the bytes written to ByteBuffer (i.e. all the bytes - * before position()). - */ - public static String byteBufferToHex(ByteBuffer buffer) { - ByteBuffer tmp = buffer.duplicate(); - tmp.flip(); - byte[] bytes = new byte[tmp.remaining()]; - tmp.get(bytes); - return bytesToHex(bytes); - } - - public static byte[] hexToBytes(String hex) throws IllegalArgumentException { - if (hex.length() % 2 != 0) { - throw new IllegalArgumentException("Expected a string of even length"); - } - int size = hex.length() / 2; - byte[] result = new byte[size]; - for (int i = 0; i < size; i++) { - int hi = Character.digit(hex.charAt(2 * i), 16); - int lo = Character.digit(hex.charAt(2 * i + 1), 16); - if ((hi == -1) || (lo == -1)) { - throw new IllegalArgumentException("input is not hexadecimal"); - } - result[i] = (byte) (16 * hi + lo); - } - return result; - } - - public static void installOnlyThisProvider(Provider provider) { - for (Provider p : Security.getProviders()) { - Security.removeProvider(p.getName()); - } - Security.insertProviderAt(provider, 1); - } - - public static void installOnlyOpenJDKProviders() throws Exception { - for (Provider p : Security.getProviders()) { - Security.removeProvider(p.getName()); - } - installOpenJDKProvider("com.sun.net.ssl.internal.ssl.Provider"); - installOpenJDKProvider("com.sun.crypto.provider.SunJCE"); - installOpenJDKProvider("com.sun.security.sasl.Provider"); - installOpenJDKProvider("org.jcp.xml.dsig.internal.dom.XMLDSigRI"); - installOpenJDKProvider("sun.security.ec.SunEC"); - installOpenJDKProvider("sun.security.jgss.SunProvider"); - installOpenJDKProvider("sun.security.provider.Sun"); - installOpenJDKProvider("sun.security.rsa.SunRsaSign"); - installOpenJDKProvider("sun.security.smartcardio.SunPCSC"); - } - - private static void installOpenJDKProvider(String className) throws Exception { - Provider provider = (Provider) Class.forName(className).getConstructor().newInstance(); - Security.insertProviderAt(provider, 1); - } -} diff --git a/java/com/google/security/wycheproof/WycheproofRunner.java b/java/com/google/security/wycheproof/WycheproofRunner.java deleted file mode 100644 index e4da431..0000000 --- a/java/com/google/security/wycheproof/WycheproofRunner.java +++ /dev/null @@ -1,206 +0,0 @@ -/** - * @license - * Copyright 2013 Google Inc. All rights reserved. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.security.wycheproof; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.Arrays; -import org.junit.runner.Description; -import org.junit.runner.manipulation.Filter; -import org.junit.runner.manipulation.NoTestsRemainException; -import org.junit.runners.Suite; -import org.junit.runners.model.InitializationError; -import org.junit.runners.model.RunnerBuilder; - -/** - *

A custom JUnit4 runner that, with annotations, allows choosing tests to run on a specific - * provider. To use it, annotate a runner class with {@code RunWith(WycheproofRunner.class)}, and - * {@code SuiteClasses({AesGcmTest.class, ...})}. When you run this class, it will run all the tests - * in all the suite classes. - * - *

To exclude certain tests, a runner class should be annotated with {@code @Provider} which - * indicates the target provider. Test exclusion is defined as follows: - *