From e8cdbe98cb65ab35b45da818e6b4d4e0b1db5f0d Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 31 Jul 2024 14:41:46 +0200 Subject: Fix YAML outpput ending. --- .../main/java/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java b/common/src/main/java/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java index c3a42ea..e9efbc1 100644 --- a/common/src/main/java/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java +++ b/common/src/main/java/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java @@ -125,6 +125,6 @@ public abstract class BaseYAMLTestWriter implements TestWriter { String out = yaml.dump(result); output.println(out); - output.println("---"); + output.println("..."); } } -- cgit v1.3.1 From 8523e5bf05dd838f90f487446dbe6f1d2fc9045f Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 1 Aug 2024 13:59:38 +0200 Subject: Remove runTest from CardCompositeSuite. --- .../cz/crcs/ectester/reader/test/CardCompositeSuite.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompositeSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompositeSuite.java index a28c2a7..bba211a 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompositeSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompositeSuite.java @@ -36,13 +36,8 @@ public class CardCompositeSuite extends CardTestSuite { for (Map.Entry> curveKeys : mappedKeys.entrySet()) { EC_Curve curve = curveKeys.getKey(); List tests = new LinkedList<>(); - Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_LOCAL, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - if (!allocate.ok()) { - doTest(CompoundTest.all(ExpectedValue.SUCCESS, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()) + ".", allocate)); - continue; - } - tests.add(allocate); - tests.add(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); + Test allocate = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_LOCAL, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS); + Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY); String name; if (cfg.testOptions.contains("preset")) { @@ -50,13 +45,16 @@ public class CardCompositeSuite extends CardTestSuite { } else { name = "generated private key"; } - tests.add(setupKeypairs(curve, ExpectedValue.ANY, CardConsts.KEYPAIR_LOCAL)); + Test setKeypair = setupKeypairs(curve, ExpectedValue.ANY, CardConsts.KEYPAIR_LOCAL); + Test prepare = CompoundTest.all(ExpectedValue.SUCCESS, "Prepare keypair on " + curve.getId() + ".", allocate, set, setKeypair); + for (EC_Key key : curveKeys.getValue()) { Command ecdhCommand = new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); Test ecdh = CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key."); tests.add(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", with " + name + ", " + key.getDesc(), ecdh)); } - doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ".", tests.toArray(new Test[0]))); + Test ecdhTest = CompoundTest.all(ExpectedValue.SUCCESS, "Do ECDH.", tests.toArray(new Test[0])); + doTest(CompoundTest.greedyAll(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ".", prepare, ecdhTest)); } -- cgit v1.3.1 From 6f257dc6529b3d97e92a1a6d4ce8547e10dc15ed Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 1 Aug 2024 14:11:41 +0200 Subject: Fix infinity test in card compression suite. --- reader/src/main/java/cz/crcs/ectester/reader/command/Command.java | 1 + .../main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java | 4 ++-- reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/reader/src/main/java/cz/crcs/ectester/reader/command/Command.java b/reader/src/main/java/cz/crcs/ectester/reader/command/Command.java index 892a481..2bd4c77 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/command/Command.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/command/Command.java @@ -19,6 +19,7 @@ import javax.smartcardio.ResponseAPDU; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java index 8390cd3..ee27673 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java @@ -114,8 +114,8 @@ public class CardCompressionSuite extends CardTestSuite { byte[] pubHybridEncoded = ByteUtil.prependLength(pubHybrid); Test kaBadHybrid = CommandTest.expect(new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType, pubHybridEncoded), Result.ExpectedValue.FAILURE); - byte[] pubInfinityEncoded = {0x01, 0x00}; - Test kaBadInfinity = CommandTest.expect(new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType, pubInfinityEncoded), Result.ExpectedValue.FAILURE); + byte[] pubInfinityEncoded = {0x00}; + Test kaBadInfinity = CommandTest.expect(new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_INFINITY, kaType, pubInfinityEncoded), Result.ExpectedValue.FAILURE); thisTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests of corrupted hybrid form and infinity.", kaBadHybrid, kaBadInfinity)); } kaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyAgreement tests of " + CardUtil.getKATypeString(kaType) + ".", thisTests.toArray(new Test[0]))); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java index 0b030b8..8ce74ee 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java @@ -113,7 +113,7 @@ public class CardWrongSuite extends CardTestSuite { Test randomG = ecdhTest(new Command.Transform(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_G, (short) (EC_Consts.TRANSFORMATION_FULLRANDOM | EC_Consts.TRANSFORMATION_04_MASK)), "Set G = random non-point/point-like.", "ECDH with non-point G."); Test fullRandomG = ecdhTest(new Command.Transform(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_G, EC_Consts.TRANSFORMATION_FULLRANDOM), "Set G = random data.", "ECDH with G = random data."); - Test zeroG = ecdhTest(new Command.Transform(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_G, EC_Consts.TRANSFORMATION_INFINITY), "Set G = inifnity.", "ECDH with G = infinity."); + Test zeroG = ecdhTest(new Command.Transform(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_G, EC_Consts.TRANSFORMATION_INFINITY), "Set G = infinity.", "ECDH with G = infinity."); Test wrongG = CompoundTest.all(ExpectedValue.SUCCESS, "Tests with corrupted G parameter.", randomG, fullRandomG, zeroG); byte[] originalR = EC_Consts.getCurveParameter(curve, EC_Consts.PARAMETER_R); -- cgit v1.3.1 From 1a81cedd68a7f491b88f61570046bace7953c119 Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 1 Aug 2024 15:23:03 +0200 Subject: Add testing of ECTesterReader suites with Jcardsim. --- reader/build.gradle.kts | 2 +- .../java/cz/crcs/ectester/reader/AppTests.java | 98 ++++++++++++++++++++++ 2 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 reader/src/test/java/cz/crcs/ectester/reader/AppTests.java diff --git a/reader/build.gradle.kts b/reader/build.gradle.kts index 0386ea5..10164c7 100644 --- a/reader/build.gradle.kts +++ b/reader/build.gradle.kts @@ -46,7 +46,7 @@ tasks.jacocoTestReport { testlogger { theme = com.adarshr.gradle.testlogger.theme.ThemeType.MOCHA - showStandardStreams = true + showStandardStreams = false } tasks.register("uberJar") { diff --git a/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java b/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java new file mode 100644 index 0000000..ae8618c --- /dev/null +++ b/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java @@ -0,0 +1,98 @@ +package cz.crcs.ectester.reader; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junitpioneer.jupiter.DisabledUntil; +import org.junitpioneer.jupiter.StdIo; +import org.junitpioneer.jupiter.StdOut; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class AppTests { + + @Test + @StdIo() + public void help(StdOut out) { + ECTesterReader.main(new String[]{"-h"}); + String s = out.capturedString(); + assertTrue(s.contains("ECTesterReader")); + } + + @Test + @StdIo() + public void listSuites(StdOut out) { + ECTesterReader.main(new String[]{"--list-suites"}); + String s = out.capturedString(); + assertTrue(s.contains("default test suite")); + } + + @Test + @StdIo() + public void listData(StdOut out) { + ECTesterReader.main(new String[]{"--list-named"}); + String s = out.capturedString(); + assertTrue(s.contains("secg")); + } + + // Add StdIo to all the suite tests when this is resolved: https://github.com/junit-pioneer/junit-pioneer/issues/822 + + @Test + public void defaultSuite() { + ECTesterReader.main(new String[]{"-t", "default", "-s"}); + } + + @Test + public void testVectorSuite() { + ECTesterReader.main(new String[]{"-t", "test-vectors", "-s"}); + } + + @Test + public void compressionSuite() { + ECTesterReader.main(new String[]{"-t", "compression", "-s"}); + } + + @Test + public void wrongSuite() { + ECTesterReader.main(new String[]{"-t", "wrong", "-s", "-y"}); + } + + @Test + public void degenerateSuite() { + ECTesterReader.main(new String[]{"-t", "degenerate", "-s", "-y"}); + } + + @Test + public void cofactorSuite() { + ECTesterReader.main(new String[]{"-t", "cofactor", "-s", "-y"}); + } + + @Test + public void compositeSuite() { + ECTesterReader.main(new String[]{"-t", "composite", "-s", "-y"}); + } + + @Test + public void invalidSuite() { + ECTesterReader.main(new String[]{"-t", "invalid", "-s", "-y"}); + } + + @Test + public void edgeCasesSuite() { + ECTesterReader.main(new String[]{"-t", "edge-cases", "-s", "-y"}); + } + + @Test + public void signatureSuite() { + ECTesterReader.main(new String[]{"-t", "signature", "-s"}); + } + + @Test + public void twistSuite() { + ECTesterReader.main(new String[]{"-t", "twist", "-s", "-y"}); + } + + @Test + public void miscellaneousSuite() { + ECTesterReader.main(new String[]{"-t", "miscellaneous", "-s", "-y"}); + } +} -- cgit v1.3.1 From 474bc97aa21e2ef5ab6c739bf4aa5ebfcda854dc Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 1 Aug 2024 15:27:50 +0200 Subject: Upload code-coverage for reader CI run as well. --- .github/workflows/build.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fea8fe5..b626eb0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -81,6 +81,12 @@ jobs: path: | reader/build/libs/ECTesterReader.jar + - name: Upload code coverage + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + slug: crocs-muni/ECTester + standalone: runs-on: ubuntu-latest permissions: -- cgit v1.3.1 From 08879289c378c66b0a7fdac03bb8b7a7363f2585 Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 1 Aug 2024 15:37:58 +0200 Subject: Improve exception printing. --- .../cz/crcs/ectester/common/output/BaseTextTestWriter.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/common/src/main/java/cz/crcs/ectester/common/output/BaseTextTestWriter.java b/common/src/main/java/cz/crcs/ectester/common/output/BaseTextTestWriter.java index 538539b..a90bc56 100644 --- a/common/src/main/java/cz/crcs/ectester/common/output/BaseTextTestWriter.java +++ b/common/src/main/java/cz/crcs/ectester/common/output/BaseTextTestWriter.java @@ -156,12 +156,16 @@ public abstract class BaseTextTestWriter implements TestWriter { for (Throwable t = error; t != null; t = t.getCause()) { sb.append("═══ ").append(t.toString()).append(" ═══"); sb.append(System.lineSeparator()); + sb.append("═══ Stack trace: ═══").append(System.lineSeparator()); + for (StackTraceElement s : t.getStackTrace()) { + sb.append("═══ ").append(s.toString()).append(" ═══"); + sb.append(System.lineSeparator()); + } + if (t.getCause() != null) { + sb.append("═══ Caused by: ═══").append(System.lineSeparator()); + } } - sb.append("═══ Stack trace: ═══").append(System.lineSeparator()); - for (StackTraceElement s : error.getStackTrace()) { - sb.append("═══ ").append(s.toString()).append(" ═══"); - sb.append(System.lineSeparator()); - } + return sb.toString(); } -- cgit v1.3.1 From 21a43b17ae255df6754a7ab5b29adec0c0d24736 Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 1 Aug 2024 16:18:54 +0200 Subject: Add timeouts to reader tests. --- .../java/cz/crcs/ectester/reader/AppTests.java | 41 +++++++---- .../test/java/cz/crcs/ectester/reader/XFail.java | 86 ++++++++++++++++++++++ .../cz/crcs/ectester/reader/XFaillExtension.java | 86 ++++++++++++++++++++++ 3 files changed, 199 insertions(+), 14 deletions(-) create mode 100644 reader/src/test/java/cz/crcs/ectester/reader/XFail.java create mode 100644 reader/src/test/java/cz/crcs/ectester/reader/XFaillExtension.java diff --git a/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java b/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java index ae8618c..a34d4fd 100644 --- a/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java +++ b/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java @@ -1,11 +1,12 @@ package cz.crcs.ectester.reader; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.junitpioneer.jupiter.DisabledUntil; import org.junitpioneer.jupiter.StdIo; import org.junitpioneer.jupiter.StdOut; +import java.time.Duration; + +import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; import static org.junit.jupiter.api.Assertions.assertTrue; public class AppTests { @@ -37,62 +38,74 @@ public class AppTests { // Add StdIo to all the suite tests when this is resolved: https://github.com/junit-pioneer/junit-pioneer/issues/822 @Test + @XFail(value = "JCardSim sometimes times-out.") public void defaultSuite() { - ECTesterReader.main(new String[]{"-t", "default", "-s"}); + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "default", "-s"})); } @Test + @XFail(value = "JCardSim sometimes times-out.") public void testVectorSuite() { - ECTesterReader.main(new String[]{"-t", "test-vectors", "-s"}); + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "test-vectors", "-s"})); } @Test + @XFail(value = "JCardSim sometimes times-out.") public void compressionSuite() { - ECTesterReader.main(new String[]{"-t", "compression", "-s"}); + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "compression", "-s"})); } @Test + @XFail(value = "JCardSim sometimes times-out.") public void wrongSuite() { - ECTesterReader.main(new String[]{"-t", "wrong", "-s", "-y"}); + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "wrong", "-s", "-y"})); } @Test + @XFail(value = "JCardSim sometimes times-out.") public void degenerateSuite() { - ECTesterReader.main(new String[]{"-t", "degenerate", "-s", "-y"}); + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "degenerate", "-s", "-y"})); } @Test + @XFail(value = "JCardSim sometimes times-out.") public void cofactorSuite() { - ECTesterReader.main(new String[]{"-t", "cofactor", "-s", "-y"}); + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "cofactor", "-s", "-y"})); } @Test + @XFail(value = "JCardSim sometimes times-out.") public void compositeSuite() { - ECTesterReader.main(new String[]{"-t", "composite", "-s", "-y"}); + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "composite", "-s", "-y"})); } @Test + @XFail(value = "JCardSim sometimes times-out.") public void invalidSuite() { - ECTesterReader.main(new String[]{"-t", "invalid", "-s", "-y"}); + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "invalid", "-s", "-y"})); } @Test + @XFail(value = "JCardSim sometimes times-out.") public void edgeCasesSuite() { - ECTesterReader.main(new String[]{"-t", "edge-cases", "-s", "-y"}); + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "edge-cases", "-s", "-y"})); } @Test + @XFail(value = "JCardSim sometimes times-out.") public void signatureSuite() { - ECTesterReader.main(new String[]{"-t", "signature", "-s"}); + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "signature", "-s"})); } @Test + @XFail(value = "JCardSim sometimes times-out.") public void twistSuite() { - ECTesterReader.main(new String[]{"-t", "twist", "-s", "-y"}); + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "twist", "-s", "-y"})); } @Test + @XFail(value = "JCardSim sometimes times-out.") public void miscellaneousSuite() { - ECTesterReader.main(new String[]{"-t", "miscellaneous", "-s", "-y"}); + assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "miscellaneous", "-s", "-y"})); } } diff --git a/reader/src/test/java/cz/crcs/ectester/reader/XFail.java b/reader/src/test/java/cz/crcs/ectester/reader/XFail.java new file mode 100644 index 0000000..f42f530 --- /dev/null +++ b/reader/src/test/java/cz/crcs/ectester/reader/XFail.java @@ -0,0 +1,86 @@ +/* + * Copyright 2016-2023 the original author or authors. + * Taken from https://github.com/junit-pioneer/junit-pioneer/blob/98cef28462c8b7ab66231cc5b7e8daef3b329f67/src/main/java/org/junitpioneer/jupiter/ExpectedToFail.java + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * http://www.eclipse.org/legal/epl-v20.html + */ + +package cz.crcs.ectester.reader; + +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import org.junit.jupiter.api.extension.ExtendWith; + +/** + * {@code @ExpectedToFail} is a JUnit Jupiter extension to mark test methods as temporarily + * 'expected to fail'. Such test methods will still be executed but when they result in a test + * failure or error the test will be aborted. However, if the test method unexpectedly executes + * successfully, it is marked as failure to let the developer know that the test is now + * successful and that the {@code @ExpectedToFail} annotation can be removed. + * + *

The big difference compared to JUnit's {@link org.junit.jupiter.api.Disabled @Disabled} + * annotation is that the developer is informed as soon as a test is successful again. + * This helps to avoid creating duplicate tests by accident and counteracts the accumulation + * of disabled tests over time.

+ * + *

Further, the {@link #withExceptions()} attribute can be used to restrict the extension's behavior + * to specific exceptions. That is, only if the test method ends up throwing one of the specified exceptions + * will the test be aborted. This can, for example, be used when the production code temporarily throws + * an {@link UnsupportedOperationException} because some feature has not been implemented yet, but the + * test method is already implemented and should not fail on a failing assertion. + *

+ * + *

The annotation can only be used on methods and as meta-annotation on other annotation types. + * Similar to {@code @Disabled}, it has to be used in addition to a "testable" annotation, such + * as {@link org.junit.jupiter.api.Test @Test}. Otherwise the annotation has no effect.

+ * + *

Important: This annotation is not intended as a way to mark test methods + * which intentionally cause exceptions. Such test methods should use + * {@link org.junit.jupiter.api.Assertions#assertThrows(Class, org.junit.jupiter.api.function.Executable) assertThrows} + * or similar means to explicitly test for a specific exception class being thrown by a + * specific action.

+ * + *

For more details and examples, see + * the documentation on @ExpectedToFail.

+ * + * @since 1.8.0 + * @see org.junit.jupiter.api.Disabled + */ +@Documented +@Retention(RUNTIME) +/* + * Only supports METHOD and ANNOTATION_TYPE as targets but not test classes because there + * it is not clear what the 'correct' behavior would be when only a few test methods + * execute successfully. Would the developer then have to remove the @ExpectedToFail annotation + * from the test class and annotate methods individually? + */ +@Target({ METHOD, ANNOTATION_TYPE }) +@ExtendWith(XFailExtension.class) +public @interface XFail { + + /** + * Defines the message to show when a test is aborted because it is failing. + * This can be used for example to briefly explain why the tested code is not working + * as intended at the moment. + * An empty string (the default) causes a generic default message to be used. + */ + String value() default ""; + + /** + * Specifies which exceptions are expected to be thrown and will cause the test to be aborted rather than fail. + * An empty array is considered a configuration error and will cause the test to fail. Instead, consider leaving + * the attribute set to the default value when any exception should cause the test to be aborted. + */ + Class[] withExceptions() default { Throwable.class }; + +} \ No newline at end of file diff --git a/reader/src/test/java/cz/crcs/ectester/reader/XFaillExtension.java b/reader/src/test/java/cz/crcs/ectester/reader/XFaillExtension.java new file mode 100644 index 0000000..b190e1a --- /dev/null +++ b/reader/src/test/java/cz/crcs/ectester/reader/XFaillExtension.java @@ -0,0 +1,86 @@ +/* + * Copyright 2016-2023 the original author or authors. + * Taken from https://github.com/junit-pioneer/junit-pioneer/blob/98cef28462c8b7ab66231cc5b7e8daef3b329f67/src/main/java/org/junitpioneer/jupiter/ExpectedToFailExtension.java + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * http://www.eclipse.org/legal/epl-v20.html + */ + +package cz.crcs.ectester.reader; + +import java.lang.reflect.Method; +import java.util.stream.Stream; + +import org.junit.jupiter.api.extension.Extension; +import org.junit.jupiter.api.extension.ExtensionConfigurationException; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.InvocationInterceptor; +import org.junit.jupiter.api.extension.ReflectiveInvocationContext; +import org.junit.platform.commons.support.AnnotationSupport; +import org.opentest4j.AssertionFailedError; +import org.opentest4j.TestAbortedException; + +class XFailExtension implements Extension, InvocationInterceptor { + + @Override + public void interceptTestMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, + ExtensionContext extensionContext) throws Throwable { + invokeAndInvertResult(invocation, extensionContext); + } + + private static void invokeAndInvertResult(Invocation invocation, ExtensionContext extensionContext) + throws Throwable { + XFail expectedToFail = getExpectedToFailAnnotation(extensionContext); + if (expectedToFail.withExceptions().length == 0) { + throw new ExtensionConfigurationException("@XFail withExceptions must not be empty"); + } + + try { + invocation.proceed(); + // at this point, the invocation succeeded, so we'd want to call `fail(...)`, + // but that would get handled by the following `catch` and so it's easier + // to instead fall through to a `fail(...)` after the `catch` block + } + catch (Throwable t) { + if (shouldPreserveException(t)) { + throw t; + } + + if (Stream.of(expectedToFail.withExceptions()).noneMatch(clazz -> clazz.isInstance(t))) { + throw new AssertionFailedError( + "Test marked as temporarily 'expected to fail' failed with an unexpected exception", t); + } + + String message = expectedToFail.value(); + if (message.isEmpty()) { + message = "Test marked as temporarily 'expected to fail' failed as expected"; + } + + throw new TestAbortedException(message, t); + } + } + + /** + * Returns whether the exception should be preserved and reported as is instead + * of considering it an 'expected to fail' exception. + * + *

This method is used for exceptions that abort test execution and should + * have higher precedence than aborted exceptions thrown by this extension.

+ */ + private static boolean shouldPreserveException(Throwable t) { + // Note: Ideally would use the same logic JUnit uses to determine if exception is aborting + // execution, see its class OpenTest4JAndJUnit4AwareThrowableCollector + return t instanceof TestAbortedException; + } + + private static XFail getExpectedToFailAnnotation(ExtensionContext context) { + return AnnotationSupport + .findAnnotation(context.getRequiredTestMethod(), XFail.class) + .orElseThrow(() -> new IllegalStateException("@XFail is missing.")); + + } + +} \ No newline at end of file -- cgit v1.3.1 From b3fe06d3f2dcae7462552dc8b1cf94ab4747cbdc Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 1 Aug 2024 16:23:07 +0200 Subject: Add more reader tests. --- .../java/cz/crcs/ectester/reader/AppTests.java | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java b/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java index a34d4fd..a57697d 100644 --- a/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java +++ b/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java @@ -108,4 +108,29 @@ public class AppTests { public void miscellaneousSuite() { assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "miscellaneous", "-s", "-y"})); } + + @Test + public void generate() { + ECTesterReader.main(new String[]{"-g", "10", "-s", "-fp", "-o", "/dev/null", "-b", "256"}); + } + + @Test + public void ecdh() { + ECTesterReader.main(new String[]{"-dh", "-fp", "-b", "256", "-s"}); + } + + @Test + public void ecdsa() { + ECTesterReader.main(new String[]{"-dsa", "-fp", "-b", "256", "-s"}); + } + + @Test + public void export() { + ECTesterReader.main(new String[]{"-e", "-fp", "-b", "256", "-s", "-o", "/dev/null"}); + } + + @Test + public void info() { + ECTesterReader.main(new String[]{"-nf", "-s"}); + } } -- cgit v1.3.1 From 3639e1069523738fdc1b87a2a0393198b20cce30 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 2 Aug 2024 00:11:37 +0200 Subject: No more runTest in reader. --- .../java/cz/crcs/ectester/common/ec/EC_Curve.java | 11 +- .../cz/crcs/ectester/common/util/CardUtil.java | 17 +++ .../java/cz/crcs/ectester/common/util/ECUtil.java | 113 +++++++++++------- docs/FORMAT.md | 4 +- .../ectester/reader/test/CardCompressionSuite.java | 71 ++++-------- .../ectester/reader/test/CardDefaultSuite.java | 127 +++++++++++---------- .../ectester/reader/test/CardDegenerateSuite.java | 6 +- .../ectester/reader/test/CardEdgeCasesSuite.java | 14 +-- .../ectester/reader/test/CardInvalidSuite.java | 6 +- .../crcs/ectester/reader/test/CardMiscSuite.java | 32 ++++-- .../ectester/reader/test/CardTestVectorSuite.java | 15 +-- .../crcs/ectester/reader/test/CardTwistSuite.java | 6 +- .../crcs/ectester/reader/test/CardWrongSuite.java | 35 ++---- .../crcs/ectester/reader/test/CommandTestable.java | 20 +++- .../crcs/ectester/reader/test/PerformanceTest.java | 22 +++- 15 files changed, 264 insertions(+), 235 deletions(-) diff --git a/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java b/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java index e26fc44..1fd6c3e 100644 --- a/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java +++ b/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java @@ -5,6 +5,7 @@ import org.bouncycastle.math.ec.ECCurve; import java.math.BigInteger; import java.security.spec.*; +import java.util.Arrays; /** * An Elliptic curve, contains parameters Fp/F2M, A, B, G, R, (K)?. @@ -96,7 +97,15 @@ public class EC_Curve extends EC_Params { BigInteger b = new BigInteger(1, getParam(EC_Consts.PARAMETER_B)[0]); BigInteger r = new BigInteger(1, getParam(EC_Consts.PARAMETER_R)[0]); BigInteger k = new BigInteger(1, getParam(EC_Consts.PARAMETER_K)[0]); - return new ECCurve.F2m(m, e1, e2, e3, a, b, r, k); + int[] powers = Arrays.stream(new int[]{e1, e2, e3}).sorted().toArray(); + e1 = powers[0]; + e2 = powers[1]; + e3 = powers[2]; + if (e1 == 0 && e2 == 0) { + return new ECCurve.F2m(m, e3, 0, 0, a, b, r, k); + } else { + return new ECCurve.F2m(m, e1, e2, e3, a, b, r, k); + } } } diff --git a/common/src/main/java/cz/crcs/ectester/common/util/CardUtil.java b/common/src/main/java/cz/crcs/ectester/common/util/CardUtil.java index eeb2159..2ab2d26 100644 --- a/common/src/main/java/cz/crcs/ectester/common/util/CardUtil.java +++ b/common/src/main/java/cz/crcs/ectester/common/util/CardUtil.java @@ -456,6 +456,23 @@ public class CardUtil { } } + public static String getSigTypeAlgoString(byte sigType) { + switch (sigType) { + case EC_Consts.Signature_ALG_ECDSA_SHA: + return "SHA1withECDSA"; + case EC_Consts.Signature_ALG_ECDSA_SHA_224: + return "SHA224withECDSA"; + case EC_Consts.Signature_ALG_ECDSA_SHA_256: + return "SHA256withECDSA"; + case EC_Consts.Signature_ALG_ECDSA_SHA_384: + return "SHA384withECDSA"; + case EC_Consts.Signature_ALG_ECDSA_SHA_512: + return "SHA512withECDSA"; + default: + return "unknown"; + } + } + public static byte getSigType(String sigTypeString) { switch (sigTypeString) { case "ECDSA_SHA": diff --git a/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java b/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java index e7f138e..4d74a87 100644 --- a/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java +++ b/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java @@ -14,6 +14,8 @@ import org.bouncycastle.jcajce.interfaces.EdDSAPrivateKey; import org.bouncycastle.jcajce.interfaces.EdDSAPublicKey; import org.bouncycastle.jcajce.interfaces.XDHPrivateKey; import org.bouncycastle.jcajce.interfaces.XDHPublicKey; +import org.bouncycastle.math.ec.ECCurve; +import org.bouncycastle.math.ec.ECFieldElement; import java.io.FileInputStream; import java.io.IOException; @@ -244,64 +246,87 @@ public class ECUtil { } public static EC_Params fullRandomPoint(EC_Curve curve) { - EllipticCurve ecCurve = curve.toCurve(); - - BigInteger p; - if (ecCurve.getField() instanceof ECFieldFp) { + if (curve.getField() == EC_Consts.ALG_EC_FP) { + EllipticCurve ecCurve = curve.toCurve(); ECFieldFp fp = (ECFieldFp) ecCurve.getField(); - p = fp.getP(); + BigInteger p = fp.getP(); if (!p.isProbablePrime(20)) { return null; } + BigInteger x; + BigInteger rhs; + do { + x = new BigInteger(ecCurve.getField().getFieldSize(), rand).mod(p); + rhs = computeRHS(x, ecCurve.getA(), ecCurve.getB(), p); + } while (!isResidue(rhs, p)); + BigInteger y = modSqrt(rhs, p); + if (rand.nextBoolean()) { + y = p.subtract(y); + } + + byte[] xArr = toByteArray(x, ecCurve.getField().getFieldSize()); + byte[] yArr = toByteArray(y, ecCurve.getField().getFieldSize()); + return new EC_Params(EC_Consts.PARAMETER_W, new byte[][]{xArr, yArr}); } else { - //TODO - return null; - } - BigInteger x; - BigInteger rhs; - do { - x = new BigInteger(ecCurve.getField().getFieldSize(), rand).mod(p); - rhs = computeRHS(x, ecCurve.getA(), ecCurve.getB(), p); - } while (!isResidue(rhs, p)); - BigInteger y = modSqrt(rhs, p); - if (rand.nextBoolean()) { - y = p.subtract(y); - } + ECCurve.F2m bcCurve = (ECCurve.F2m) curve.toBCCurve(); + BigInteger b = new BigInteger(bcCurve.getFieldSize(), rand); + org.bouncycastle.math.ec.ECPoint point; + while (true) { + try { + ECFieldElement.F2m x = (ECFieldElement.F2m) bcCurve.fromBigInteger(b); + byte[] pointTry = ByteUtil.concatenate(new byte[]{0x02}, x.getEncoded()); + point = bcCurve.decodePoint(pointTry); + break; + } catch (IllegalArgumentException iae) { + b = new BigInteger(bcCurve.getFieldSize(), rand); + } + } - byte[] xArr = toByteArray(x, ecCurve.getField().getFieldSize()); - byte[] yArr = toByteArray(y, ecCurve.getField().getFieldSize()); - return new EC_Params(EC_Consts.PARAMETER_W, new byte[][]{xArr, yArr}); + return new EC_Params(EC_Consts.PARAMETER_W, new byte[][] {point.getAffineXCoord().getEncoded(), point.getAffineYCoord().getEncoded()}); + } } public static EC_Params fixedRandomPoint(EC_Curve curve) { - EllipticCurve ecCurve = curve.toCurve(); - - BigInteger p; - if (ecCurve.getField() instanceof ECFieldFp) { + if (curve.getField() == EC_Consts.ALG_EC_FP) { + EllipticCurve ecCurve = curve.toCurve(); ECFieldFp fp = (ECFieldFp) ecCurve.getField(); - p = fp.getP(); + BigInteger p = fp.getP(); if (!p.isProbablePrime(20)) { return null; } - } else { - //TODO - return null; - } + BigInteger x = new BigInteger(1, hashCurve(curve)).mod(p); + BigInteger rhs = computeRHS(x, ecCurve.getA(), ecCurve.getB(), p); + while (!isResidue(rhs, p)) { + x = x.add(BigInteger.ONE).mod(p); + rhs = computeRHS(x, ecCurve.getA(), ecCurve.getB(), p); + } + BigInteger y = modSqrt(rhs, p); + if (y.bitCount() % 2 == 0) { + y = p.subtract(y); + } - BigInteger x = new BigInteger(1, hashCurve(curve)).mod(p); - BigInteger rhs = computeRHS(x, ecCurve.getA(), ecCurve.getB(), p); - while (!isResidue(rhs, p)) { - x = x.add(BigInteger.ONE).mod(p); - rhs = computeRHS(x, ecCurve.getA(), ecCurve.getB(), p); - } - BigInteger y = modSqrt(rhs, p); - if (y.bitCount() % 2 == 0) { - y = p.subtract(y); + byte[] xArr = toByteArray(x, ecCurve.getField().getFieldSize()); + byte[] yArr = toByteArray(y, ecCurve.getField().getFieldSize()); + return new EC_Params(EC_Consts.PARAMETER_W, new byte[][]{xArr, yArr}); + } else { + ECCurve.F2m bcCurve = (ECCurve.F2m) curve.toBCCurve(); + BigInteger b = new BigInteger(1, hashCurve(curve)); + while (b.bitLength() > bcCurve.getFieldSize()) { + b = b.shiftRight(1); + } + org.bouncycastle.math.ec.ECPoint point; + while (true) { + try { + ECFieldElement.F2m x = (ECFieldElement.F2m) bcCurve.fromBigInteger(b); + byte[] pointTry = ByteUtil.concatenate(new byte[]{0x02}, x.getEncoded()); + point = bcCurve.decodePoint(pointTry); + break; + } catch (IllegalArgumentException iae) { + b = b.add(BigInteger.ONE); + } + } + return new EC_Params(EC_Consts.PARAMETER_W, new byte[][] {point.getAffineXCoord().getEncoded(), point.getAffineYCoord().getEncoded()}); } - - byte[] xArr = toByteArray(x, ecCurve.getField().getFieldSize()); - byte[] yArr = toByteArray(y, ecCurve.getField().getFieldSize()); - return new EC_Params(EC_Consts.PARAMETER_W, new byte[][]{xArr, yArr}); } public static ECPoint toPoint(EC_Params params) { @@ -352,11 +377,11 @@ public class ECUtil { /** * Validate DER or PLAIN signature format. * - * @throws IllegalArgumentException in case of invalid format. * @param signature * @param params * @param hashAlgo * @param sigType + * @throws IllegalArgumentException in case of invalid format. */ public static void validateSignatureFormat(byte[] signature, ECParameterSpec params, String hashAlgo, String sigType) { BigInteger n = params.getOrder(); diff --git a/docs/FORMAT.md b/docs/FORMAT.md index 5c29d58..4d30ea6 100644 --- a/docs/FORMAT.md +++ b/docs/FORMAT.md @@ -17,7 +17,7 @@ In the rest of this documentation the following notation is used - `p` - prime F_p - `m` - binary field exponent F_2^m - `e1` - largest exponent of the field polynomial - - `e2` - middle exponenet of the field polynomial, or `0000` if field poly is a trinomial + - `e2` - middle exponent of the field polynomial, or `0000` if field poly is a trinomial - `e3` - smallest exponent (except zero) of the field polynomial, or `0000` if field poly is a trinomial - `a` - a parameter in short Weierstrass curve equation - `b` - b parameter in short Weierstrass curve equation @@ -26,7 +26,7 @@ In the rest of this documentation the following notation is used - `n` - the base-point order - `h` - the base-point cofactor - `wx` - the x coordinate of the public key - - `wy` - the y coordinate of th public key + - `wy` - the y coordinate of the public key - `s` - the private key value ## Curves diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java index ee27673..418ed2f 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java @@ -70,56 +70,40 @@ public class CardCompressionSuite extends CardTestSuite { String spec = keyLength + "b " + CardUtil.getKeyTypeString(field); byte curveId = EC_Consts.getCurve(keyLength, field); - Test allocateFirst = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, field), Result.ExpectedValue.SUCCESS)); - if (!allocateFirst.ok()) { - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for compression test on " + spec + ".", allocateFirst)); - continue; - } - List compressionTests = new LinkedList<>(); + Test allocateFirst = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, field), Result.ExpectedValue.SUCCESS); + Test setCustom = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, curveId, domain, null), Result.ExpectedValue.SUCCESS); + Test genCustom = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), Result.ExpectedValue.SUCCESS); compressionTests.add(allocateFirst); - Test setCustom = runTest(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, curveId, domain, null), Result.ExpectedValue.SUCCESS)); - Test genCustom = runTest(CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), Result.ExpectedValue.SUCCESS)); compressionTests.add(setCustom); compressionTests.add(genCustom); - Response.Export key = new Command.Export(this.card, CardConsts.KEYPAIR_REMOTE, EC_Consts.KEY_PUBLIC, EC_Consts.PARAMETER_W).send(); - byte[] pubkey = key.getParameter(CardConsts.KEYPAIR_REMOTE, EC_Consts.KEY_PUBLIC); EC_Curve secgCurve = EC_Store.getInstance().getObject(EC_Curve.class, "secg", CardUtil.getCurveName(curveId)); - ECPoint pub; - try { - pub = ECUtil.fromX962(pubkey, secgCurve.toCurve()); - } catch (IllegalArgumentException iae) { - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "", compressionTests.toArray(new Test[0]))); - continue; - } + ECPoint pub = ECUtil.toPoint(ECUtil.fixedRandomPoint(secgCurve)); List kaTests = new LinkedList<>(); for (byte kaType : EC_Consts.KA_TYPES) { List thisTests = new LinkedList<>(); - Test allocate = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), Result.ExpectedValue.SUCCESS)); - if (allocate.ok()) { - Test ka = runTest(CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType), Result.ExpectedValue.SUCCESS)); - - thisTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyAgreement setup and basic test.", allocate, ka)); - if (ka.ok()) { - // tests of the good stuff - Test kaCompressed = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS, kaType), Result.ExpectedValue.SUCCESS); - Test kaHybrid = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS_HYBRID, kaType), Result.ExpectedValue.SUCCESS); - thisTests.add(CompoundTest.any(Result.ExpectedValue.SUCCESS, "Tests of compressed and hybrid form.", kaCompressed, kaHybrid)); - - // tests the bad stuff here - byte[] pubHybrid = ECUtil.toX962Hybrid(pub, keyLength); - pubHybrid[pubHybrid.length - 1] ^= 1; - byte[] pubHybridEncoded = ByteUtil.prependLength(pubHybrid); - Test kaBadHybrid = CommandTest.expect(new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType, pubHybridEncoded), Result.ExpectedValue.FAILURE); - - byte[] pubInfinityEncoded = {0x00}; - Test kaBadInfinity = CommandTest.expect(new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_INFINITY, kaType, pubInfinityEncoded), Result.ExpectedValue.FAILURE); - thisTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests of corrupted hybrid form and infinity.", kaBadHybrid, kaBadInfinity)); - } - kaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyAgreement tests of " + CardUtil.getKATypeString(kaType) + ".", thisTests.toArray(new Test[0]))); - } + Test allocate = CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), Result.ExpectedValue.SUCCESS); + Test ka = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType), Result.ExpectedValue.SUCCESS); + + thisTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyAgreement setup and basic test.", allocate, ka)); + // tests of the good stuff + Test kaCompressed = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS, kaType), Result.ExpectedValue.SUCCESS); + Test kaHybrid = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS_HYBRID, kaType), Result.ExpectedValue.SUCCESS); + thisTests.add(CompoundTest.any(Result.ExpectedValue.SUCCESS, "Tests of compressed and hybrid form.", kaCompressed, kaHybrid)); + + // tests the bad stuff here + byte[] pubHybrid = ECUtil.toX962Hybrid(pub, keyLength); + pubHybrid[pubHybrid.length - 1] ^= 1; + byte[] pubHybridEncoded = ByteUtil.prependLength(pubHybrid); + Test kaBadHybrid = CommandTest.expect(new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType, pubHybridEncoded), Result.ExpectedValue.FAILURE); + + byte[] pubInfinityEncoded = {0x00}; + Test kaBadInfinity = CommandTest.expect(new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_INFINITY, kaType, pubInfinityEncoded), Result.ExpectedValue.FAILURE); + thisTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests of corrupted hybrid form and infinity.", kaBadHybrid, kaBadInfinity)); + + kaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyAgreement tests of " + CardUtil.getKATypeString(kaType) + ".", thisTests.toArray(new Test[0]))); } compressionTests.addAll(kaTests); if (cfg.cleanup) { @@ -137,12 +121,7 @@ public class CardCompressionSuite extends CardTestSuite { for (EC_Key.Public key : compressionKeys) { EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, key.getCurve()); List tests = new LinkedList<>(); - Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_LOCAL, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS)); - if (!allocate.ok()) { - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for non-residue test on " + curve.getBits() + "b " + curve.getId() + ".", allocate)); - continue; - } - tests.add(allocate); + tests.add(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_LOCAL, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS)); tests.add(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS)); tests.add(CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS)); byte[] pointData = ECUtil.toX962Compressed(key.getParam(EC_Consts.PARAMETER_W)); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardDefaultSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardDefaultSuite.java index ebb1d3f..c365d52 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardDefaultSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardDefaultSuite.java @@ -13,7 +13,7 @@ import cz.crcs.ectester.reader.command.Command; import java.util.LinkedList; import java.util.List; -import java.util.Random; +import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -44,19 +44,13 @@ public class CardDefaultSuite extends CardTestSuite { short[] keySizes = field == EC_Consts.ALG_EC_FP ? EC_Consts.FP_SIZES : EC_Consts.F2M_SIZES; short domain = field == EC_Consts.ALG_EC_FP ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M; for (short keyLength : keySizes) { - List supportTests = new LinkedList<>(); - Test allocateFirst = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, field), ExpectedValue.SUCCESS)); - if (!allocateFirst.ok()) { - doTest(CompoundTest.all(ExpectedValue.SUCCESS, "No support for " + keyLength + "b " + CardUtil.getKeyTypeString(field) + ".", allocateFirst)); - continue; - } + Test allocateFirst = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, field), ExpectedValue.SUCCESS); + Test genDefault = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), ExpectedValue.SUCCESS); + Test allocateSecond = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, field), ExpectedValue.SUCCESS); + Test setCustom = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.getCurve(keyLength, field), domain, null), ExpectedValue.SUCCESS); + Test genCustom = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), ExpectedValue.SUCCESS); supportTests.add(allocateFirst); - - Test genDefault = runTest(CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), ExpectedValue.SUCCESS)); - Test allocateSecond = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, field), ExpectedValue.SUCCESS)); - Test setCustom = runTest(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.getCurve(keyLength, field), domain, null), ExpectedValue.SUCCESS)); - Test genCustom = runTest(CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), ExpectedValue.SUCCESS)); supportTests.add(genDefault); supportTests.add(allocateSecond); supportTests.add(setCustom); @@ -64,68 +58,77 @@ public class CardDefaultSuite extends CardTestSuite { List kaTests = new LinkedList<>(); for (byte kaType : EC_Consts.KA_TYPES) { - Test allocate = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), ExpectedValue.SUCCESS)); - if (allocate.ok()) { - Command ecdh = new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType); - Test ka = runTest(CommandTest.expect(ecdh, ExpectedValue.SUCCESS)); - Test kaCompressed = runTest(CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS, kaType), ExpectedValue.SUCCESS)); - - String kaDesc = "Test of the " + CardUtil.getKATypeString(kaType) + " KeyAgreement."; - Function kaCallback = (tests) -> { - if (tests[1].ok() || tests[2].ok()) { - return new Result(Value.SUCCESS, "Some ECDH is supported."); + Test allocate = CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), ExpectedValue.SUCCESS); + Command ecdh = new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType); + Test ka = CommandTest.expect(ecdh, ExpectedValue.SUCCESS); + Test kaCompressed = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS, kaType), ExpectedValue.SUCCESS); + + String kaDesc = "Test of the " + CardUtil.getKATypeString(kaType) + " KeyAgreement."; + Function kaCallback = (tests) -> { + if (tests[1].ok() || tests[2].ok()) { + return new Result(Value.SUCCESS, "Some ECDH is supported."); + } else { + return new Result(Value.FAILURE, "ECDH failed."); + } + }; + + Consumer runCallback = tests -> { + for (Test t : tests) { + if (t instanceof PerformanceTest) { + if (tests[0].ok() && tests[1].ok()) { + t.run(); + } } else { - return new Result(Value.FAILURE, "ECDH failed."); + t.run(); } - }; - - Test compound; - if (ka.ok()) { - Test perfTest = runTest(PerformanceTest.repeat(this.card, ecdh, 10)); - compound = runTest(CompoundTest.function(kaCallback, kaDesc, allocate, ka, kaCompressed, perfTest)); - } else { - compound = runTest(CompoundTest.function(kaCallback, kaDesc, allocate, ka, kaCompressed)); } + }; - kaTests.add(compound); - } else { - runTest(allocate); - kaTests.add(allocate); - } + Test perfTest = PerformanceTest.repeat(this.card, ecdh, 10); + Test compound = CompoundTest.function(kaCallback, runCallback, kaDesc, allocate, ka, kaCompressed, perfTest); + kaTests.add(compound); } - Test kaTest = runTest(CompoundTest.any(ExpectedValue.SUCCESS, "KeyAgreement tests.", kaTests.toArray(new Test[0]))); + Test kaTest = CompoundTest.any(ExpectedValue.SUCCESS, "KeyAgreement tests.", kaTests.toArray(new Test[0])); supportTests.add(kaTest); List signTests = new LinkedList<>(); for (byte sigType : EC_Consts.SIG_TYPES) { - Test allocate = runTest(CommandTest.expect(new Command.AllocateSignature(this.card, sigType), ExpectedValue.SUCCESS)); - if (allocate.ok()) { - Command ecdsa = new Command.ECDSA(this.card, CardConsts.KEYPAIR_LOCAL, sigType, CardConsts.EXPORT_FALSE, null); - Test expect = runTest(CommandTest.expect(ecdsa, ExpectedValue.SUCCESS)); - - String signDesc = "Test of the " + CardUtil.getSigTypeString(sigType) + " signature."; - - Random rand = new Random(); - byte[] sigData = new byte[64]; - rand.nextBytes(sigData); - - Test compound; - if (expect.ok()) { - Command ecdsaSign = new Command.ECDSA_sign(this.card, CardConsts.KEYPAIR_LOCAL, sigType, CardConsts.EXPORT_TRUE, sigData); - PerformanceTest signTest = runTest(PerformanceTest.repeat(this.card, "Sign", ecdsaSign, 10)); - byte[] signature = signTest.getResponses()[0].getParam(0); - Command ecdsaVerify = new Command.ECDSA_verify(this.card, CardConsts.KEYPAIR_LOCAL, sigType, sigData, signature); - PerformanceTest verifyTest = runTest(PerformanceTest.repeat(this.card, "Verify", ecdsaVerify, 10)); - compound = runTest(CompoundTest.all(ExpectedValue.SUCCESS, signDesc, allocate, expect, signTest, verifyTest)); + Test allocate = CommandTest.expect(new Command.AllocateSignature(this.card, sigType), ExpectedValue.SUCCESS); + Command ecdsa = new Command.ECDSA(this.card, CardConsts.KEYPAIR_LOCAL, sigType, CardConsts.EXPORT_FALSE, null); + Test sign = CommandTest.expect(ecdsa, ExpectedValue.SUCCESS); + + String signDesc = "Test of the " + CardUtil.getSigTypeString(sigType) + " signature."; + + byte[] sigData = new byte[]{(byte) domain, sigType}; + + Function sigCallback = (tests) -> { + if (tests[1].ok()) { + return new Result(Value.SUCCESS, "Some ECDSA is supported."); } else { - compound = runTest(CompoundTest.all(ExpectedValue.SUCCESS, signDesc, allocate, expect)); + return new Result(Value.FAILURE, "ECDSA failed."); } - signTests.add(compound); - } else { - signTests.add(allocate); - } + }; + Consumer runCallback = tests -> { + for (Test t : tests) { + if (t instanceof PerformanceTest) { + if (tests[0].ok() && tests[1].ok()) { + t.run(); + } + } else { + t.run(); + } + } + }; + + Command ecdsaSign = new Command.ECDSA_sign(this.card, CardConsts.KEYPAIR_LOCAL, sigType, CardConsts.EXPORT_TRUE, sigData); + PerformanceTest signTest = PerformanceTest.repeat(this.card, "Sign", ecdsaSign, 10); + + CommandTestable.FunctionCommandTestable verifyTestable = new CommandTestable.FunctionCommandTestable(() -> new Command.ECDSA_verify(this.card, CardConsts.KEYPAIR_LOCAL, sigType, sigData, signTest.getResponses()[0].getParam(0))); + PerformanceTest verifyTest = PerformanceTest.repeat(this.card, "Verify", verifyTestable, 10); + Test compound = CompoundTest.function(sigCallback, runCallback, signDesc, allocate, sign, signTest, verifyTest); + signTests.add(compound); } - Test signTest = runTest(CompoundTest.any(ExpectedValue.SUCCESS, "Signature tests.", signTests.toArray(new Test[0]))); + Test signTest = CompoundTest.any(ExpectedValue.SUCCESS, "Signature tests.", signTests.toArray(new Test[0])); supportTests.add(signTest); ExpectedValue[] testExpects = {ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS}; List expects = Stream.of(testExpects).collect(Collectors.toList()); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardDegenerateSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardDegenerateSuite.java index e2c07da..c731416 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardDegenerateSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardDegenerateSuite.java @@ -36,11 +36,7 @@ public class CardDegenerateSuite extends CardTestSuite { EC_Curve curve = e.getKey(); List keys = e.getValue(); - Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS)); - if (!allocate.ok()) { - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for " + curve.getId() + ".", allocate)); - continue; - } + Test allocate = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS); Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java index 0a82da3..fb24e30 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java @@ -143,15 +143,11 @@ public class CardEdgeCasesSuite extends CardTestSuite { curves.add(EC_Store.getInstance().getObject(EC_Curve.class, "cofactor/cofactor160p4")); Random rand = new Random(); for (EC_Curve curve : curves) { - Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), EC_Consts.ALG_EC_FP), Result.ExpectedValue.SUCCESS)); - if (!key.ok()) { - doTest(CompoundTest.all(Result.ExpectedValue.FAILURE, "No support for " + curve.getBits() + "b " + curve.getId() + ".", key)); - continue; - } + Test key = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), EC_Consts.ALG_EC_FP), Result.ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS); Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS); CommandTest export = CommandTest.expect(new Command.Export(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.KEY_PUBLIC, EC_Consts.PARAMETER_W), Result.ExpectedValue.SUCCESS); - Test setup = runTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPair setup.", key, set, generate, export)); + Test setup = CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPair setup.", key, set, generate, export); /* byte[] pParam = curve.getParam(EC_Consts.PARAMETER_FP)[0]; @@ -268,11 +264,7 @@ public class CardEdgeCasesSuite extends CardTestSuite { Arrays.sort(ps); Arrays.sort(zeros); - Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, secp160r1.getBits(), EC_Consts.ALG_EC_FP), Result.ExpectedValue.SUCCESS)); - if (!key.ok()) { - doTest(CompoundTest.all(Result.ExpectedValue.FAILURE, "No support for " + secp160r1.getBits() + "b secp160r1.", key)); - return; - } + Test key = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, secp160r1.getBits(), EC_Consts.ALG_EC_FP), Result.ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, secp160r1.getParams(), secp160r1.flatten()), Result.ExpectedValue.SUCCESS); Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS); Test setup = CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPair setup.", key, set, generate); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardInvalidSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardInvalidSuite.java index 4657de0..2fd457d 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardInvalidSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardInvalidSuite.java @@ -40,11 +40,7 @@ public class CardInvalidSuite extends CardTestSuite { EC_Curve curve = e.getKey(); List keys = e.getValue(); - Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - if (!allocate.ok()) { - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for " + curve.getId() + ".", allocate)); - continue; - } + Test allocate = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS); Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), ExpectedValue.SUCCESS); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardMiscSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardMiscSuite.java index da4c0b5..3ffe07c 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardMiscSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardMiscSuite.java @@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.function.Function; /** * @author Jan Jancar johny@neuromancer.sk @@ -49,23 +50,36 @@ public class CardMiscSuite extends CardTestSuite { } private void testCurve(EC_Curve curve, String catName, Result.ExpectedValue expected) { - Test allocateFirst = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS)); - if (!allocateFirst.ok()) { - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst)); - return; - } - + Test allocateFirst = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS); - Test generate = setupKeypairs(curve, Result.ExpectedValue.ANY, CardConsts.KEYPAIR_BOTH); + Test generate = setupKeypairs(curve, Result.ExpectedValue.SUCCESS, CardConsts.KEYPAIR_BOTH); Test ka = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_REMOTE, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), expected); Test sig = CommandTest.expect(new Command.ECDSA_sign(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.Signature_ALG_ECDSA_SHA, CardConsts.EXPORT_FALSE, null), expected); Test perform = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH and ECDSA.", ka, sig); + Function callback = (tests) -> { + if (!tests[0].ok()) { + return new Result(Result.Value.FAILURE, "Could not allocate keypairs."); + } + if (!tests[1].ok()) { + return new Result(Result.Value.FAILURE, "Could not set curve data."); + } + if (!tests[2].ok()) { + return new Result(Result.Value.FAILURE, "Could not generate keypairs."); + } + for (int i = 3; i < tests.length; i++) { + if (!tests[i].ok() && !(tests[i] instanceof CompoundTest)) { + return new Result(Result.Value.FAILURE, "ECDH or ECDSA did not work."); + } + } + return new Result(Result.Value.SUCCESS, "OK"); + }; + if (cfg.cleanup) { Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.ANY); - doTest(CompoundTest.greedyAll(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, perform, cleanup)); + doTest(CompoundTest.function(callback, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, perform, cleanup)); } else { - doTest(CompoundTest.greedyAll(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, perform)); + doTest(CompoundTest.function(callback, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, perform)); } } diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestVectorSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestVectorSuite.java index 07b38d0..4c222cb 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestVectorSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestVectorSuite.java @@ -63,13 +63,7 @@ public class CardTestVectorSuite extends CardTestSuite { throw new IOException("Test vector keys couldn't be located."); } List testVector = new LinkedList<>(); - Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - if (!allocate.ok()) { - doTest(CompoundTest.all(ExpectedValue.SUCCESS, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()) + ".", allocate)); - continue; - } - - testVector.add(allocate); + testVector.add(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); testVector.add(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); testVector.add(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), ExpectedValue.SUCCESS)); testVector.add(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), ExpectedValue.SUCCESS)); @@ -112,12 +106,7 @@ public class CardTestVectorSuite extends CardTestSuite { testCurves.addAll(EC_Store.getInstance().getObjects(EC_Curve.class, "brainpool").values().stream().filter((curve) -> curve.getField() == EC_Consts.ALG_EC_FP).collect(Collectors.toList())); for (EC_Curve curve : testCurves) { List testVector = new LinkedList<>(); - Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - if (!allocate.ok()) { - doTest(CompoundTest.all(ExpectedValue.SUCCESS, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()) + ".", allocate)); - continue; - } - testVector.add(allocate); + testVector.add(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); testVector.add(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); testVector.add(CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), ExpectedValue.SUCCESS)); CommandTest exportLocal = CommandTest.expect(new Command.Export(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.KEY_PUBLIC, EC_Consts.PARAMETER_W), ExpectedValue.ANY); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTwistSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTwistSuite.java index 5c35be7..ea127e0 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTwistSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTwistSuite.java @@ -34,11 +34,7 @@ public class CardTwistSuite extends CardTestSuite { EC_Curve curve = e.getKey(); List keys = e.getValue(); - Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS)); - if (!allocate.ok()) { - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for " + curve.getId() + ".", allocate)); - continue; - } + Test allocate = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS); Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java index 8ce74ee..605b2ec 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java @@ -42,24 +42,17 @@ public class CardWrongSuite extends CardTestSuite { for (Map.Entry e : curves.entrySet()) { EC_Curve curve = e.getValue(); List tests = new LinkedList<>(); - Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - if (!key.ok()) { - doTest(CompoundTest.all(ExpectedValue.FAILURE, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()), key)); - continue; - } - tests.add(key); - Test set = runTest(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.FAILURE)); - Test generate = runTest(setupKeypairs(curve, ExpectedValue.SUCCESS, CardConsts.KEYPAIR_BOTH)); - Test setup = runTest(CompoundTest.any(ExpectedValue.SUCCESS, "Set wrong curve and generate keypairs.", set, generate)); + Test key = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS); + Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.FAILURE); + Test generate = setupKeypairs(curve, ExpectedValue.SUCCESS, CardConsts.KEYPAIR_BOTH); + Test setup = CompoundTest.any(ExpectedValue.SUCCESS, "Set wrong curve and generate keypairs.", key, set, generate); tests.add(setup); for (byte kaType : EC_Consts.KA_TYPES) { - Test allocate = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), ExpectedValue.SUCCESS)); - if (allocate.ok()) { - Test ka = runTest(CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_REMOTE, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType), ExpectedValue.FAILURE)); - Test kaTest = runTest(CompoundTest.all(ExpectedValue.SUCCESS, "Allocate and perform KA.", allocate, ka)); - tests.add(kaTest); - } + Test allocate = CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), ExpectedValue.SUCCESS); + Test ka = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_REMOTE, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType), ExpectedValue.FAILURE); + Test kaTest = CompoundTest.all(ExpectedValue.SUCCESS, "Allocate and perform KA.", allocate, ka); + tests.add(kaTest); } doTest(CompoundTest.function((tsts) -> { for (int i = 0; i < tsts.length; ++i) { @@ -82,11 +75,7 @@ public class CardWrongSuite extends CardTestSuite { Random r = new Random(); for (short keyLength : EC_Consts.FP_SIZES) { byte curve = EC_Consts.getCurve(keyLength, EC_Consts.ALG_EC_FP); - Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, EC_Consts.ALG_EC_FP), ExpectedValue.SUCCESS)); - if (!key.ok()) { - doTest(CompoundTest.all(ExpectedValue.FAILURE, "No support for " + keyLength + "b ALG_EC_FP.", key)); - continue; - } + Test key = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, EC_Consts.ALG_EC_FP), ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, curve, EC_Consts.PARAMETERS_DOMAIN_FP, null), ExpectedValue.SUCCESS); Test setup = CompoundTest.all(ExpectedValue.SUCCESS, "KeyPair setup.", key, set); @@ -162,11 +151,7 @@ public class CardWrongSuite extends CardTestSuite { */ for (short keyLength : EC_Consts.F2M_SIZES) { byte curve = EC_Consts.getCurve(keyLength, EC_Consts.ALG_EC_F2M); - Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, EC_Consts.ALG_EC_F2M), ExpectedValue.SUCCESS)); - if (!key.ok()) { - doTest(CompoundTest.all(ExpectedValue.FAILURE, "No support for " + keyLength + "b ALG_EC_F2M.", key)); - continue; - } + Test key = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, EC_Consts.ALG_EC_F2M), ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, curve, EC_Consts.PARAMETERS_DOMAIN_F2M, null), ExpectedValue.SUCCESS); Test setup = CompoundTest.all(ExpectedValue.SUCCESS, "KeyPair setup.", key, set); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CommandTestable.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CommandTestable.java index f670534..7733e11 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CommandTestable.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CommandTestable.java @@ -6,13 +6,14 @@ import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.response.Response; import javax.smartcardio.CardException; +import java.util.function.Supplier; /** * @author Jan Jancar johny@neuromancer.sk */ public class CommandTestable extends BaseTestable { - private Command command; - private Response response; + protected Command command; + protected Response response; public CommandTestable(Command command) { this.command = command; @@ -41,4 +42,19 @@ public class CommandTestable extends BaseTestable { ok = true; } } + + public static class FunctionCommandTestable extends CommandTestable { + private Supplier supplier; + + public FunctionCommandTestable(Supplier supplier) { + super(null); + this.supplier = supplier; + } + + @Override + public void run() { + this.command = supplier.get(); + super.run(); + } + } } diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/PerformanceTest.java b/reader/src/main/java/cz/crcs/ectester/reader/test/PerformanceTest.java index a725dc2..1171154 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/PerformanceTest.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/PerformanceTest.java @@ -26,26 +26,38 @@ public class PerformanceTest extends SimpleTest { private int count; private String desc; + private PerformanceTest(CardMngr cardManager, CommandTestable testable, TestCallback callback, int count, String desc) { + super(testable, callback); + this.cardManager = cardManager; + this.count = count; + this.desc = desc; + } + private PerformanceTest(CardMngr cardManager, CommandTestable testable, int count, String desc) { - super(testable, new TestCallback() { + this(cardManager, testable, new TestCallback() { @Override public Result apply(CommandTestable testable) { return new Result(Result.Value.SUCCESS); } - }); - this.cardManager = cardManager; - this.count = count; - this.desc = desc; + }, count, desc); } public static PerformanceTest repeat(CardMngr cardManager, Command cmd, int count) { return new PerformanceTest(cardManager, new CommandTestable(cmd), count, null); } + public static PerformanceTest repeat(CardMngr cardManager, CommandTestable testable, int count) { + return new PerformanceTest(cardManager, testable, count, null); + } + public static PerformanceTest repeat(CardMngr cardManager, String desc, Command cmd, int count) { return new PerformanceTest(cardManager, new CommandTestable(cmd), count, desc); } + public static PerformanceTest repeat(CardMngr cardManager, String desc, CommandTestable testable, int count) { + return new PerformanceTest(cardManager, testable, count, desc); + } + @Override public String getDescription() { String rest = String.format("Mean = %d ns, Median = %d ns, Mode = %d ns", mean, median, mode); -- cgit v1.3.1 From 522515fa13d44fbaa52030ed4752abd26c7d3c93 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 2 Aug 2024 12:37:26 +0200 Subject: Disable tests that may cycle indefinitely. --- reader/src/test/java/cz/crcs/ectester/reader/AppTests.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java b/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java index a57697d..173f7e2 100644 --- a/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java +++ b/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java @@ -1,5 +1,6 @@ package cz.crcs.ectester.reader; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junitpioneer.jupiter.StdIo; import org.junitpioneer.jupiter.StdOut; @@ -45,6 +46,7 @@ public class AppTests { @Test @XFail(value = "JCardSim sometimes times-out.") + @Disabled public void testVectorSuite() { assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "test-vectors", "-s"})); } @@ -57,6 +59,7 @@ public class AppTests { @Test @XFail(value = "JCardSim sometimes times-out.") + @Disabled public void wrongSuite() { assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "wrong", "-s", "-y"})); } @@ -69,12 +72,14 @@ public class AppTests { @Test @XFail(value = "JCardSim sometimes times-out.") + @Disabled public void cofactorSuite() { assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "cofactor", "-s", "-y"})); } @Test @XFail(value = "JCardSim sometimes times-out.") + @Disabled public void compositeSuite() { assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "composite", "-s", "-y"})); } -- cgit v1.3.1 From 6c3442125eec0bece2cbb2543a462423c9638362 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 2 Aug 2024 12:46:59 +0200 Subject: Add codecov config. --- .codecov.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .codecov.yml diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 0000000..0e5d8e9 --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,27 @@ +comment: + layout: "condensed_header, condensed_diff, condensed_flags, condensed_components" # show component info in the PR comment + +component_management: + default_rules: # default rules that will be inherited by all components + statuses: + - type: project # in this case every component that doesn't have a status defined will have a project type one + target: auto + branches: + - "!master" + individual_components: + - component_id: applet_package + name: Applet + paths: + - applet/** + - component_id: common_package + name: Common + paths: + - common/** + - component_id: reader_package + name: Reader + paths: + - reader/** + - component_id: standalone_package + name: Standalone + paths: + - standalone/** \ No newline at end of file -- cgit v1.3.1 From ea3e1ba5c3740da7c49b0ab43062c8e55614a9da Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 2 Aug 2024 12:50:28 +0200 Subject: Fix codecov.yml --- .codecov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.codecov.yml b/.codecov.yml index 0e5d8e9..a25c148 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,5 +1,5 @@ comment: - layout: "condensed_header, condensed_diff, condensed_flags, condensed_components" # show component info in the PR comment + layout: "condensed_header, condensed_files, diff, components, condensed_footer" # show component info in the PR comment component_management: default_rules: # default rules that will be inherited by all components -- cgit v1.3.1 From efd218b9637e9f592a14ffe08980aa672f4ed5d6 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 2 Aug 2024 13:25:18 +0200 Subject: Aggregate test coverage over subprojects. --- reader/build.gradle.kts | 3 ++- standalone/build.gradle.kts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/reader/build.gradle.kts b/reader/build.gradle.kts index 10164c7..225f334 100644 --- a/reader/build.gradle.kts +++ b/reader/build.gradle.kts @@ -1,6 +1,7 @@ plugins { application jacoco + id("jacoco-report-aggregation") id("com.adarshr.test-logger") version "4.0.0" } @@ -35,7 +36,7 @@ application { tasks.named("test") { useJUnitPlatform() // Report is always generated after tests run - finalizedBy(tasks.jacocoTestReport) + finalizedBy(tasks.named("testCodeCoverageReport")) } tasks.jacocoTestReport { diff --git a/standalone/build.gradle.kts b/standalone/build.gradle.kts index 5ad3fb4..d022db7 100644 --- a/standalone/build.gradle.kts +++ b/standalone/build.gradle.kts @@ -1,6 +1,7 @@ plugins { application jacoco + id("jacoco-report-aggregation") id("com.google.osdetector") version "1.7.3" id("com.adarshr.test-logger") version "4.0.0" } @@ -42,7 +43,7 @@ tasks.named("test") { ignoreFailures = true useJUnitPlatform() // Report is always generated after tests run - finalizedBy(tasks.jacocoTestReport) + finalizedBy(tasks.named("testCodeCoverageReport")) if (JavaVersion.current() > JavaVersion.VERSION_1_8 && JavaVersion.current() < JavaVersion.VERSION_22) { jvmArgs("--add-exports", "jdk.crypto.ec/sun.security.ec=ALL-UNNAMED" -- cgit v1.3.1 From 70b95b66ba8410c6e18c3f19449d409ab7f48c1e Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 2 Aug 2024 13:45:26 +0200 Subject: Move coverage reports where codecov finds them. --- reader/build.gradle.kts | 5 ++++- standalone/build.gradle.kts | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/reader/build.gradle.kts b/reader/build.gradle.kts index 225f334..1abecdc 100644 --- a/reader/build.gradle.kts +++ b/reader/build.gradle.kts @@ -39,9 +39,12 @@ tasks.named("test") { finalizedBy(tasks.named("testCodeCoverageReport")) } -tasks.jacocoTestReport { +tasks.named("testCodeCoverageReport") { reports { + html.required = true + html.outputLocation.set(layout.buildDirectory.dir("reports/jacoco/test/html")) xml.required = true + xml.outputLocation.set(layout.buildDirectory.file("reports/jacoco/test/jacocoTestReport.xml")) } } diff --git a/standalone/build.gradle.kts b/standalone/build.gradle.kts index d022db7..e1fc265 100644 --- a/standalone/build.gradle.kts +++ b/standalone/build.gradle.kts @@ -62,9 +62,12 @@ tasks.named("test") { ) } -tasks.jacocoTestReport { +tasks.named("testCodeCoverageReport") { reports { + html.required = true + html.outputLocation.set(layout.buildDirectory.dir("reports/jacoco/test/html")) xml.required = true + xml.outputLocation.set(layout.buildDirectory.file("reports/jacoco/test/jacocoTestReport.xml")) } } -- cgit v1.3.1 From 386e01e2a47557acc9440001d40314374e5d982f Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 2 Aug 2024 14:32:31 +0200 Subject: Make standalone Cofactor suite not use runTest. --- .../cz/crcs/ectester/common/test/CompoundTest.java | 25 ++++++++------- .../standalone/test/base/KeyAgreementTestable.java | 37 ++++++++++++++++++++-- .../test/suites/StandaloneCofactorSuite.java | 24 +++++++------- 3 files changed, 60 insertions(+), 26 deletions(-) diff --git a/common/src/main/java/cz/crcs/ectester/common/test/CompoundTest.java b/common/src/main/java/cz/crcs/ectester/common/test/CompoundTest.java index ba4ad4f..ccb0f21 100644 --- a/common/src/main/java/cz/crcs/ectester/common/test/CompoundTest.java +++ b/common/src/main/java/cz/crcs/ectester/common/test/CompoundTest.java @@ -2,6 +2,7 @@ package cz.crcs.ectester.common.test; import java.util.Arrays; import java.util.Objects; +import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Function; @@ -16,13 +17,22 @@ public class CompoundTest extends Test implements Cloneable { private Test[] tests; private String description = ""; - private final static Consumer RUN_ALL = tests -> { + public final static BiFunction EXPECT_ALL = (what, tests) -> { + for (Test test : tests) { + if (!Result.Value.fromExpected(what, test.ok()).ok()) { + return new Result(Result.Value.FAILURE, "Some sub-tests did not have the expected result."); + } + } + return new Result(Result.Value.SUCCESS, "All sub-tests had the expected result."); + }; + + public final static Consumer RUN_ALL = tests -> { for (Test t : tests) { t.run(); } }; - private final static Consumer RUN_GREEDY_ALL = tests -> { + public final static Consumer RUN_GREEDY_ALL = tests -> { for (Test t : tests) { t.run(); if (!t.ok()) { @@ -31,7 +41,7 @@ public class CompoundTest extends Test implements Cloneable { } }; - private final static Consumer RUN_GREEDY_ANY = tests -> { + public final static Consumer RUN_GREEDY_ANY = tests -> { for (Test t : tests) { t.run(); if (t.ok()) { @@ -68,14 +78,7 @@ public class CompoundTest extends Test implements Cloneable { } private static CompoundTest expectAll(Result.ExpectedValue what, Consumer runCallback, Test[] all) { - return new CompoundTest((tests) -> { - for (Test test : tests) { - if (!Result.Value.fromExpected(what, test.ok()).ok()) { - return new Result(Result.Value.FAILURE, "Some sub-tests did not have the expected result."); - } - } - return new Result(Result.Value.SUCCESS, "All sub-tests had the expected result."); - }, runCallback, all); + return new CompoundTest((tests) -> EXPECT_ALL.apply(what, tests), runCallback, all); } public static CompoundTest all(Result.ExpectedValue what, Test... all) { diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyAgreementTestable.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyAgreementTestable.java index 7fd1c5a..24c25c5 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyAgreementTestable.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyAgreementTestable.java @@ -46,7 +46,7 @@ public class KeyAgreementTestable extends StandaloneTestable allKaTests = new LinkedList<>(); for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) { @@ -94,7 +87,7 @@ public class StandaloneCofactorSuite extends StandaloneTestSuite { for (EC_Key.Public pub : keys) { ECPublicKey ecpub = ECUtil.toPublicKey(pub); KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub); + KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpub, kgt); Test keyAgreement = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE); specificKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " cofactor key test.", keyAgreement)); } @@ -104,8 +97,15 @@ public class StandaloneCofactorSuite extends StandaloneTestSuite { if (allKaTests.isEmpty()) { allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library.")); } - Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0])); - doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Cofactor test of " + curve.getId() + ".", generateSuccess, tests)); + Test kaTests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0])); + Function callback = (tests) -> CompoundTest.EXPECT_ALL.apply(Result.ExpectedValue.SUCCESS, tests); + Consumer runCallback = (tests) -> { + tests[0].run(); + if (tests[0].getResult().getValue().equals(Result.Value.SUCCESS)) { + tests[1].run(); + } + }; + doTest(CompoundTest.function(callback, runCallback, "Cofactor test of " + curve.getId() + ".", generate, kaTests)); } } } -- cgit v1.3.1 From e1caa815454855bbf2d4bd6582e19d54477383bd Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 2 Aug 2024 15:12:08 +0200 Subject: Cleanup ident handling in standalone. --- .../test/suites/StandaloneCofactorSuite.java | 26 ++--------- .../test/suites/StandaloneCompositeSuite.java | 26 ++--------- .../test/suites/StandaloneDefaultSuite.java | 28 ++---------- .../test/suites/StandaloneDegenerateSuite.java | 26 ++--------- .../test/suites/StandaloneEdgeCasesSuite.java | 52 +++------------------- .../test/suites/StandaloneInvalidSuite.java | 26 ++--------- .../test/suites/StandaloneMiscSuite.java | 26 ++--------- .../test/suites/StandalonePerformanceSuite.java | 26 ++++------- .../test/suites/StandaloneSignatureSuite.java | 26 ++--------- .../test/suites/StandaloneTestSuite.java | 47 +++++++++++++++++++ .../test/suites/StandaloneTwistSuite.java | 26 ++--------- .../test/suites/StandaloneWrongSuite.java | 51 +++------------------ 12 files changed, 91 insertions(+), 295 deletions(-) diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java index f36bc98..39b4dbc 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java @@ -43,29 +43,9 @@ public class StandaloneCofactorSuite extends StandaloneTestSuite { String kaAlgo = cli.getOptionValue("test.ka-type"); List kaTypes = kaAlgo != null ? Arrays.asList(kaAlgo.split(",")) : new ArrayList<>(); - KeyPairGeneratorIdent kpgIdent; - if (kpgAlgo == null) { - // try EC, if not, fail with: need to specify kpg algo. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains("EC")) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdent = kpgIdentOpt.get(); - } else { - System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type."); - return; - } - } else { - // try the specified, if not, fail with: wrong kpg algo/not found. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains(kpgAlgo)) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdent = kpgIdentOpt.get(); - } else { - System.err.println("The KeyPairGenerator algorithm type of \"" + kpgAlgo + "\" was not found."); - return; - } + KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo); + if (kpgIdent == null) { + return; } Map pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "cofactor"); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCompositeSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCompositeSuite.java index 839bb40..232f356 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCompositeSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCompositeSuite.java @@ -51,29 +51,9 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite { kaTypes = kaAlgo != null ? Arrays.asList(kaAlgo.split(",")) : new ArrayList<>(); sigTypes = sigAlgo != null ? Arrays.asList(sigAlgo.split(",")) : new ArrayList<>(); - KeyPairGeneratorIdent kpgIdent; - if (kpgAlgo == null) { - // try EC, if not, fail with: need to specify kpg algo. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains("EC")) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdent = kpgIdentOpt.get(); - } else { - System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type."); - return; - } - } else { - // try the specified, if not, fail with: wrong kpg algo/not found. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains(kpgAlgo)) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdent = kpgIdentOpt.get(); - } else { - System.err.println("The KeyPairGenerator algorithm type of \"" + kpgAlgo + "\" was not found."); - return; - } + KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo); + if (kpgIdent == null) { + return; } KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider()); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDefaultSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDefaultSuite.java index 1c14ecc..ef9d434 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDefaultSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDefaultSuite.java @@ -33,32 +33,10 @@ public class StandaloneDefaultSuite extends StandaloneTestSuite { String sigAlgo = cli.getOptionValue("test.sig-type"); String keyAlgo = cli.getOptionValue("test.key-type", "AES"); - - KeyPairGeneratorIdent kpgIdent; - if (kpgAlgo == null) { - // try EC, if not, fail with: need to specify kpg algo. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains("EC")) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdent = kpgIdentOpt.get(); - } else { - System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type."); - return; - } - } else { - // try the specified, if not, fail with: wrong kpg algo/not found. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains(kpgAlgo)) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdent = kpgIdentOpt.get(); - } else { - System.err.println("The KeyPairGenerator algorithm type of \"" + kpgAlgo + "\" was not found."); - return; - } + KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo); + if (kpgIdent == null) { + return; } - KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider()); KeyGeneratorTestable kgtOne; diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java index d822a83..89a2c16 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java @@ -42,29 +42,9 @@ public class StandaloneDegenerateSuite extends StandaloneTestSuite { String kaAlgo = cli.getOptionValue("test.ka-type"); List kaTypes = kaAlgo != null ? Arrays.asList(kaAlgo.split(",")) : new ArrayList<>(); - KeyPairGeneratorIdent kpgIdent; - if (kpgAlgo == null) { - // try EC, if not, fail with: need to specify kpg algo. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains("EC")) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdent = kpgIdentOpt.get(); - } else { - System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type."); - return; - } - } else { - // try the specified, if not, fail with: wrong kpg algo/not found. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains(kpgAlgo)) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdent = kpgIdentOpt.get(); - } else { - System.err.println("The KeyPairGenerator algorithm type of \"" + kpgAlgo + "\" was not found."); - return; - } + KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo); + if (kpgIdent == null) { + return; } Map pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "degenerate"); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java index 7c46f02..b72f55a 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java @@ -51,53 +51,13 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite { String kaAlgo = cli.getOptionValue("test.ka-type"); String kpgAlgo = cli.getOptionValue("test.kpg-type"); - if (kaAlgo == null) { - // try ECDH, if not, fail with: need to specify ka algo. - Optional kaIdentOpt = cfg.selected.getKAs().stream() - .filter((ident) -> ident.contains("ECDH")) - .findFirst(); - if (kaIdentOpt.isPresent()) { - kaIdent = kaIdentOpt.get(); - } else { - System.err.println("The default KeyAgreement algorithm type of \"ECDH\" was not found. Need to specify a type."); - return; - } - } else { - // try the specified, if not, fail with: wrong ka algo/not found. - Optional kaIdentOpt = cfg.selected.getKAs().stream() - .filter((ident) -> ident.contains(kaAlgo)) - .findFirst(); - if (kaIdentOpt.isPresent()) { - kaIdent = kaIdentOpt.get(); - } else { - System.err.println("The KeyAgreement algorithm type of \"" + kaAlgo + "\" was not found."); - return; - } + kaIdent = getKeyAgreementIdent(kaAlgo); + if (kaIdent == null) { + return; } - - KeyPairGeneratorIdent kpgIdent; - if (kpgAlgo == null) { - // try EC, if not, fail with: need to specify kpg algo. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains("EC")) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdent = kpgIdentOpt.get(); - } else { - System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type."); - return; - } - } else { - // try the specified, if not, fail with: wrong kpg algo/not found. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains(kpgAlgo)) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdent = kpgIdentOpt.get(); - } else { - System.err.println("The KeyPairGenerator algorithm type of \"" + kpgAlgo + "\" was not found."); - return; - } + KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo); + if (kpgIdent == null) { + return; } KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider()); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java index 48dfc37..436b5ef 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java @@ -41,29 +41,9 @@ public class StandaloneInvalidSuite extends StandaloneTestSuite { String kaAlgo = cli.getOptionValue("test.ka-type"); List kaTypes = kaAlgo != null ? Arrays.asList(kaAlgo.split(",")) : new ArrayList<>(); - KeyPairGeneratorIdent kpgIdent; - if (kpgAlgo == null) { - // try EC, if not, fail with: need to specify kpg algo. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains("EC")) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdent = kpgIdentOpt.get(); - } else { - System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type."); - return; - } - } else { - // try the specified, if not, fail with: wrong kpg algo/not found. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains(kpgAlgo)) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdent = kpgIdentOpt.get(); - } else { - System.err.println("The KeyPairGenerator algorithm type of \"" + kpgAlgo + "\" was not found."); - return; - } + KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo); + if (kpgIdent == null) { + return; } Map pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "invalid"); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java index f3a10eb..90da4b5 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java @@ -51,29 +51,9 @@ public class StandaloneMiscSuite extends StandaloneTestSuite { kaTypes = kaAlgo != null ? Arrays.asList(kaAlgo.split(",")) : new ArrayList<>(); sigTypes = sigAlgo != null ? Arrays.asList(sigAlgo.split(",")) : new ArrayList<>(); - KeyPairGeneratorIdent kpgIdent; - if (kpgAlgo == null) { - // try EC, if not, fail with: need to specify kpg algo. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains("EC")) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdent = kpgIdentOpt.get(); - } else { - System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type."); - return; - } - } else { - // try the specified, if not, fail with: wrong kpg algo/not found. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains(kpgAlgo)) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdent = kpgIdentOpt.get(); - } else { - System.err.println("The KeyPairGenerator algorithm type of \"" + kpgAlgo + "\" was not found."); - return; - } + KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo); + if (kpgIdent == null) { + return; } KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider()); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java index a1b4d75..52b2122 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java @@ -48,26 +48,16 @@ public class StandalonePerformanceSuite extends StandaloneTestSuite { List sigTypes = sigAlgo != null ? Arrays.asList(sigAlgo.split(",")) : new ArrayList<>(); List kpgIdents = new LinkedList<>(); - if (kpgAlgo == null) { - // try EC, if not, fail with: need to specify kpg algo. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains("EC")) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdents.add(kpgIdentOpt.get()); - } else { - System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type."); - return; - } - } else { - // try the specified, if not, fail with: wrong kpg algo/not found. - kpgIdents = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.containsAny(kpgTypes)).collect(Collectors.toList()); - if (kpgIdents.isEmpty()) { - System.err.println("No KeyPairGenerator algorithms of specified types were found."); - return; + for (String kpgChoice : kpgTypes) { + KeyPairGeneratorIdent ident = getKeyPairGeneratorIdent(kpgChoice); + if (ident != null && !kpgIdents.contains(ident)) { + kpgIdents.add(ident); } } + if (kpgIdents.isEmpty()) { + System.err.println("Need some KeyPairGenerators to be able to generate keys. Select at least one supported one using the -gt/--kpg-type option."); + return; + } KeyGeneratorTestable kgtOne = null; KeyGeneratorTestable kgtOther = null; diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneSignatureSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneSignatureSuite.java index 8e5e452..43feb23 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneSignatureSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneSignatureSuite.java @@ -31,29 +31,9 @@ public class StandaloneSignatureSuite extends StandaloneTestSuite { protected void runTests() throws Exception { String sigAlgo = cli.getOptionValue("test.sig-type"); - SignatureIdent sigIdent; - if (sigAlgo == null) { - // try ECDSA, if not, fail with: need to specify sig algo. - Optional sigIdentOpt = cfg.selected.getSigs().stream() - .filter((ident) -> ident.contains("ECDSA")) - .findFirst(); - if (sigIdentOpt.isPresent()) { - sigIdent = sigIdentOpt.get(); - } else { - System.err.println("The default Signature algorithm type of \"ECDSA\" was not found. Need to specify a type."); - return; - } - } else { - // try the specified, if not, fail with: wrong sig algo/not found. - Optional sigIdentOpt = cfg.selected.getSigs().stream() - .filter((ident) -> ident.contains(sigAlgo)) - .findFirst(); - if (sigIdentOpt.isPresent()) { - sigIdent = sigIdentOpt.get(); - } else { - System.err.println("The Signature algorithm type of \"" + sigAlgo + "\" was not found."); - return; - } + SignatureIdent sigIdent = getSignatureIdent(sigAlgo); + if (sigIdent == null) { + return; } Map results = EC_Store.getInstance().getObjects(EC_SigResult.class, "wrong"); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java index e4e0013..8125509 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java @@ -4,8 +4,15 @@ import cz.crcs.ectester.common.cli.TreeCommandLine; import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.TestSuite; import cz.crcs.ectester.standalone.ECTesterStandalone; +import cz.crcs.ectester.standalone.consts.Ident; +import cz.crcs.ectester.standalone.consts.KeyAgreementIdent; +import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent; +import cz.crcs.ectester.standalone.consts.SignatureIdent; import cz.crcs.ectester.standalone.libs.ProviderECLibrary; +import java.util.Optional; +import java.util.Set; + /** * @author Jan Jancar johny@neuromancer.sk */ @@ -22,4 +29,44 @@ public abstract class StandaloneTestSuite extends TestSuite { public ProviderECLibrary getLibrary() { return cfg.selected; } + + private T getIdent(Set options, String choice, String identName, String defaultChoice) { + T ident; + if (choice == null) { + // try EC, if not, fail with: need to specify kpg algo. + Optional identOpt = options.stream() + .filter((i) -> i.contains(defaultChoice)) + .findFirst(); + if (identOpt.isPresent()) { + ident = identOpt.get(); + } else { + System.err.printf("The default %s algorithm type of \"%s\" was not found. Need to specify a type.", identName, defaultChoice); + return null; + } + } else { + // try the specified, if not, fail with: wrong kpg algo/not found. + Optional identOpt = options.stream() + .filter((i) -> i.contains(choice)) + .findFirst(); + if (identOpt.isPresent()) { + ident = identOpt.get(); + } else { + System.err.printf("The %s algorithm type of \"%s\" was not found.", identName, choice); + return null; + } + } + return ident; + } + + KeyPairGeneratorIdent getKeyPairGeneratorIdent(String kpgAlgo) { + return getIdent(cfg.selected.getKPGs(), kpgAlgo, "KeyPairGenerator", "EC"); + } + + KeyAgreementIdent getKeyAgreementIdent(String kaAlgo) { + return getIdent(cfg.selected.getKAs(), kaAlgo, "KeyAgreement", "ECDH"); + } + + SignatureIdent getSignatureIdent(String sigAlgo) { + return getIdent(cfg.selected.getSigs(), sigAlgo, "Signature", "ECDSA"); + } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java index 37adbb2..8655d1d 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java @@ -41,29 +41,9 @@ public class StandaloneTwistSuite extends StandaloneTestSuite { String kaAlgo = cli.getOptionValue("test.ka-type"); List kaTypes = kaAlgo != null ? Arrays.asList(kaAlgo.split(",")) : new ArrayList<>(); - KeyPairGeneratorIdent kpgIdent; - if (kpgAlgo == null) { - // try EC, if not, fail with: need to specify kpg algo. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains("EC")) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdent = kpgIdentOpt.get(); - } else { - System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type."); - return; - } - } else { - // try the specified, if not, fail with: wrong kpg algo/not found. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains(kpgAlgo)) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdent = kpgIdentOpt.get(); - } else { - System.err.println("The KeyPairGenerator algorithm type of \"" + kpgAlgo + "\" was not found."); - return; - } + KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo); + if (kpgIdent == null) { + return; } Map pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "twist"); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java index 1aae9d5..8b3133a 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java @@ -50,54 +50,15 @@ public class StandaloneWrongSuite extends StandaloneTestSuite { String kaAlgo = cli.getOptionValue("test.ka-type"); boolean skip = cli.getArg(1).equalsIgnoreCase("-skip"); - KeyPairGeneratorIdent kpgIdent; - if (kpgAlgo == null) { - // try EC, if not, fail with: need to specify kpg algo. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains("EC")) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdent = kpgIdentOpt.get(); - } else { - System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type."); - return; - } - } else { - // try the specified, if not, fail with: wrong kpg algo/not found. - Optional kpgIdentOpt = cfg.selected.getKPGs().stream() - .filter((ident) -> ident.contains(kpgAlgo)) - .findFirst(); - if (kpgIdentOpt.isPresent()) { - kpgIdent = kpgIdentOpt.get(); - } else { - System.err.println("The KeyPairGenerator algorithm type of \"" + kpgAlgo + "\" was not found."); - return; - } + KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo); + if (kpgIdent == null) { + return; } kpg = kpgIdent.getInstance(cfg.selected.getProvider()); - if (kaAlgo == null) { - // try ECDH, if not, fail with: need to specify ka algo. - Optional kaIdentOpt = cfg.selected.getKAs().stream() - .filter((ident) -> ident.contains("ECDH")) - .findFirst(); - if (kaIdentOpt.isPresent()) { - kaIdent = kaIdentOpt.get(); - } else { - System.err.println("The default KeyAgreement algorithm type of \"ECDH\" was not found. Need to specify a type."); - return; - } - } else { - // try the specified, if not, fail with: wrong ka algo/not found. - Optional kaIdentOpt = cfg.selected.getKAs().stream() - .filter((ident) -> ident.contains(kaAlgo)) - .findFirst(); - if (kaIdentOpt.isPresent()) { - kaIdent = kaIdentOpt.get(); - } else { - System.err.println("The KeyAgreement algorithm type of \"" + kaAlgo + "\" was not found."); - return; - } + kaIdent = getKeyAgreementIdent(kaAlgo); + if (kaIdent == null) { + return; } /* Just do the default run on the wrong curves. -- cgit v1.3.1 From 6f0e99cd8b61a4d3ddecc78c0431b0277c1781a2 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 2 Aug 2024 15:13:47 +0200 Subject: Standalone cleanup. --- .../main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java | 4 ++-- .../java/cz/crcs/ectester/standalone/output/TextTestWriter.java | 7 +++---- .../crcs/ectester/standalone/test/base/KeyAgreementTestable.java | 8 ++++---- .../cz/crcs/ectester/standalone/test/base/PerformanceTest.java | 2 +- .../cz/crcs/ectester/standalone/test/base/SignatureTestable.java | 2 +- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java index e6d8188..4f76639 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -71,7 +71,7 @@ public class ECTesterStandalone { private ProviderECLibrary[] libs; private Config cfg; - private Options opts = new Options(); + private final Options opts = new Options(); private TreeParser optParser; private TreeCommandLine cli; public static final String VERSION = "v0.3.3"; @@ -903,7 +903,7 @@ public class ECTesterStandalone { * */ public static class Config { - private ProviderECLibrary[] libs; + private final ProviderECLibrary[] libs; public ProviderECLibrary selected = null; public boolean color = false; diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/output/TextTestWriter.java b/standalone/src/main/java/cz/crcs/ectester/standalone/output/TextTestWriter.java index c53adb2..13a9e72 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/output/TextTestWriter.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/output/TextTestWriter.java @@ -46,10 +46,9 @@ public class TextTestWriter extends BaseTextTestWriter { protected String deviceString(TestSuite suite) { if (suite instanceof StandaloneTestSuite) { StandaloneTestSuite standaloneSuite = (StandaloneTestSuite) suite; - StringBuilder sb = new StringBuilder(); - sb.append("═══ ").append(Colors.underline("ECTester version:")).append(" ").append(ECTesterStandalone.VERSION).append(System.lineSeparator()); - sb.append("═══ ").append(Colors.underline("Library:")).append(" ").append(standaloneSuite.getLibrary().fullName()).append(System.lineSeparator()); - return sb.toString(); + String sb = "═══ " + Colors.underline("ECTester version:") + " " + ECTesterStandalone.VERSION + System.lineSeparator() + + "═══ " + Colors.underline("Library:") + " " + standaloneSuite.getLibrary().fullName() + System.lineSeparator(); + return sb; } return ""; } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyAgreementTestable.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyAgreementTestable.java index 24c25c5..579904c 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyAgreementTestable.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyAgreementTestable.java @@ -46,7 +46,7 @@ public class KeyAgreementTestable extends StandaloneTestable { - private ProviderECLibrary library; + private final ProviderECLibrary library; private long[] times; private long mean; private long median; diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/SignatureTestable.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/SignatureTestable.java index fe81b10..76074e4 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/SignatureTestable.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/SignatureTestable.java @@ -11,7 +11,7 @@ import java.security.interfaces.ECPublicKey; * @author Jan Jancar johny@neuromancer.sk */ public class SignatureTestable extends StandaloneTestable { - private Signature sig; + private final Signature sig; private ECPrivateKey signKey; private ECPublicKey verifyKey; private KeyGeneratorTestable kgt; -- cgit v1.3.1 From 40c50615d1476b8347e6f6575c4f49911e3a55ff Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 2 Aug 2024 15:25:41 +0200 Subject: Move conversion to custom curve to params class. --- .../java/cz/crcs/ectester/common/ec/EC_Curve.java | 61 ++++++++++++++++------ .../test/suites/StandaloneWrongSuite.java | 28 +--------- 2 files changed, 45 insertions(+), 44 deletions(-) diff --git a/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java b/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java index 1fd6c3e..4ec3237 100644 --- a/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java +++ b/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java @@ -54,22 +54,35 @@ public class EC_Curve extends EC_Params { return "<" + getId() + "> " + (field == EC_Consts.ALG_EC_FP ? "Prime" : "Binary") + " field Elliptic curve (" + String.valueOf(bits) + "b)" + (desc == null ? "" : ": " + desc) + System.lineSeparator() + super.toString(); } - public EllipticCurve toCurve() { - ECField field; - if (this.field == EC_Consts.ALG_EC_FP) { - field = new ECFieldFp(new BigInteger(1, getData(0))); - } else { + private int[] getPowers() { + if (this.field == EC_Consts.ALG_EC_F2M) { byte[][] fieldData = getParam(EC_Consts.PARAMETER_F2M); - int m = ByteUtil.getShort(fieldData[0], 0); int e1 = ByteUtil.getShort(fieldData[1], 0); int e2 = ByteUtil.getShort(fieldData[2], 0); int e3 = ByteUtil.getShort(fieldData[3], 0); - int[] powers; + int[] powers = Arrays.stream(new int[]{e1, e2, e3}).sorted().toArray(); + e1 = powers[0]; + e2 = powers[1]; + e3 = powers[2]; if (e2 == 0 && e3 == 0) { powers = new int[]{e1}; } else { powers = new int[]{e1, e2, e3}; } + return powers; + } else { + return null; + } + } + + public EllipticCurve toCurve() { + ECField field; + if (this.field == EC_Consts.ALG_EC_FP) { + field = new ECFieldFp(new BigInteger(1, getData(0))); + } else { + byte[][] fieldData = getParam(EC_Consts.PARAMETER_F2M); + int m = ByteUtil.getShort(fieldData[0], 0); + int[] powers = getPowers(); field = new ECFieldF2m(m, powers); } @@ -79,6 +92,26 @@ public class EC_Curve extends EC_Params { return new EllipticCurve(field, a, b); } + /** + * Constructs EllipticCurve from EC_Curve even if the parameters of the curve are wrong. + */ + public EllipticCurve toCustomCurve() { + ECField field; + if (this.field == EC_Consts.ALG_EC_FP) { + field = new CustomECFieldFp(new BigInteger(1, this.getData(0))); + } else { + byte[][] fieldData = this.getParam(EC_Consts.PARAMETER_F2M); + int m = ByteUtil.getShort(fieldData[0], 0); + int[] powers = getPowers(); + field = new CustomECFieldF2m(m, powers); + } + + BigInteger a = new BigInteger(1, this.getParam(EC_Consts.PARAMETER_A)[0]); + BigInteger b = new BigInteger(1, this.getParam(EC_Consts.PARAMETER_B)[0]); + + return new CustomEllipticCurve(field, a, b); + } + public ECCurve toBCCurve() { if (this.field == EC_Consts.ALG_EC_FP) { BigInteger p = new BigInteger(1, getParam(EC_Consts.PARAMETER_FP)[0]); @@ -90,21 +123,15 @@ public class EC_Curve extends EC_Params { } else { byte[][] fieldData = getParam(EC_Consts.PARAMETER_F2M); int m = ByteUtil.getShort(fieldData[0], 0); - int e1 = ByteUtil.getShort(fieldData[1], 0); - int e2 = ByteUtil.getShort(fieldData[2], 0); - int e3 = ByteUtil.getShort(fieldData[3], 0); BigInteger a = new BigInteger(1, getParam(EC_Consts.PARAMETER_A)[0]); BigInteger b = new BigInteger(1, getParam(EC_Consts.PARAMETER_B)[0]); BigInteger r = new BigInteger(1, getParam(EC_Consts.PARAMETER_R)[0]); BigInteger k = new BigInteger(1, getParam(EC_Consts.PARAMETER_K)[0]); - int[] powers = Arrays.stream(new int[]{e1, e2, e3}).sorted().toArray(); - e1 = powers[0]; - e2 = powers[1]; - e3 = powers[2]; - if (e1 == 0 && e2 == 0) { - return new ECCurve.F2m(m, e3, 0, 0, a, b, r, k); + int[] powers = getPowers(); + if (powers.length == 1) { + return new ECCurve.F2m(m, powers[0], 0, 0, a, b, r, k); } else { - return new ECCurve.F2m(m, e1, e2, e3, a, b, r, k); + return new ECCurve.F2m(m, powers[0], powers[1], powers[2], a, b, r, k); } } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java index 8b3133a..24a942b 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java @@ -261,35 +261,9 @@ public class StandaloneWrongSuite extends StandaloneTestSuite { return CompoundTest.all(Result.ExpectedValue.SUCCESS, desc, generate, ecdh); } - //constructs EllipticCurve from EC_Curve even if the parameters of the curve are wrong - private EllipticCurve toCustomCurve(EC_Curve curve) { - ECField field; - if (curve.getField() == javacard.security.KeyPair.ALG_EC_FP) { - field = new CustomECFieldFp(new BigInteger(1, curve.getData(0))); - } else { - byte[][] fieldData = curve.getParam(EC_Consts.PARAMETER_F2M); - int m = ByteUtil.getShort(fieldData[0], 0); - int e1 = ByteUtil.getShort(fieldData[1], 0); - int e2 = ByteUtil.getShort(fieldData[2], 0); - int e3 = ByteUtil.getShort(fieldData[3], 0); - int[] powers; - if (e2 == 0 && e3 == 0) { - powers = new int[]{e1}; - } else { - powers = new int[]{e1, e2, e3}; - } - field = new CustomECFieldF2m(m, powers); - } - - BigInteger a = new BigInteger(1, curve.getParam(EC_Consts.PARAMETER_A)[0]); - BigInteger b = new BigInteger(1, curve.getParam(EC_Consts.PARAMETER_B)[0]); - - return new CustomEllipticCurve(field, a, b); - } - //constructs ECParameterSpec from EC_Curve even if the parameters of the curve are wrong private ECParameterSpec toCustomSpec(EC_Curve curve) { - EllipticCurve customCurve = toCustomCurve(curve); + EllipticCurve customCurve = curve.toCustomCurve(); byte[][] G = curve.getParam(EC_Consts.PARAMETER_G); BigInteger gx = new BigInteger(1, G[0]); -- cgit v1.3.1 From 93ab84c656830261db6561b70794c7343a008ff4 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 2 Aug 2024 15:50:10 +0200 Subject: Remove runTest from edge-cases suite. --- .../cz/crcs/ectester/common/test/CompoundTest.java | 13 +++++ .../test/suites/StandaloneCofactorSuite.java | 9 +-- .../test/suites/StandaloneEdgeCasesSuite.java | 64 ++++++++-------------- .../test/suites/StandaloneTestSuite.java | 2 +- 4 files changed, 37 insertions(+), 51 deletions(-) diff --git a/common/src/main/java/cz/crcs/ectester/common/test/CompoundTest.java b/common/src/main/java/cz/crcs/ectester/common/test/CompoundTest.java index ccb0f21..3681400 100644 --- a/common/src/main/java/cz/crcs/ectester/common/test/CompoundTest.java +++ b/common/src/main/java/cz/crcs/ectester/common/test/CompoundTest.java @@ -26,12 +26,25 @@ public class CompoundTest extends Test implements Cloneable { return new Result(Result.Value.SUCCESS, "All sub-tests had the expected result."); }; + public final static Function EXPECT_ALL_SUCCESS = tests -> EXPECT_ALL.apply(Result.ExpectedValue.SUCCESS, tests); + public final static Function EXPECT_ALL_FAILURE = tests -> EXPECT_ALL.apply(Result.ExpectedValue.FAILURE, tests); + public final static Function EXPECT_ALL_ANY = tests -> EXPECT_ALL.apply(Result.ExpectedValue.ANY, tests); + public final static Consumer RUN_ALL = tests -> { for (Test t : tests) { t.run(); } }; + public final static Consumer RUN_ALL_IF_FIRST = tests -> { + tests[0].run(); + if (tests[0].getResult().getValue().equals(Result.Value.SUCCESS)) { + for (int i = 1; i < tests.length; i++) { + tests[i].run(); + } + } + }; + public final static Consumer RUN_GREEDY_ALL = tests -> { for (Test t : tests) { t.run(); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java index 39b4dbc..003d510 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java @@ -78,14 +78,7 @@ public class StandaloneCofactorSuite extends StandaloneTestSuite { allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library.")); } Test kaTests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0])); - Function callback = (tests) -> CompoundTest.EXPECT_ALL.apply(Result.ExpectedValue.SUCCESS, tests); - Consumer runCallback = (tests) -> { - tests[0].run(); - if (tests[0].getResult().getValue().equals(Result.Value.SUCCESS)) { - tests[1].run(); - } - }; - doTest(CompoundTest.function(callback, runCallback, "Cofactor test of " + curve.getId() + ".", generate, kaTests)); + doTest(CompoundTest.function(CompoundTest.EXPECT_ALL_SUCCESS, CompoundTest.RUN_ALL_IF_FIRST, "Cofactor test of " + curve.getId() + ".", generate, kaTests)); } } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java index b72f55a..d441235 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java @@ -136,20 +136,10 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite { //generate KeyPair KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec); Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); - runTest(generate); - KeyPair kp = kgt.getKeyPair(); - if (kp == null) { - Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + - ". " + " Other tests will be skipped.", generate); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with edge-case private key values over" + curve.getId() + ".", generateFail)); - continue; - } - Test generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate KeyPair.", generate); - ECPublicKey ecpub = (ECPublicKey) kp.getPublic(); //perform ECDH tests - Test zeroS = ecdhTest(ecpub, BigInteger.ZERO, spec, "ECDH with S = 0.", Result.ExpectedValue.FAILURE); - Test oneS = ecdhTest(ecpub, BigInteger.ONE, spec, "ECDH with S = 1.", Result.ExpectedValue.FAILURE); + Test zeroS = ecdhTest(kgt, BigInteger.ZERO, spec, "ECDH with S = 0.", Result.ExpectedValue.FAILURE); + Test oneS = ecdhTest(kgt, BigInteger.ONE, spec, "ECDH with S = 1.", Result.ExpectedValue.FAILURE); byte[] rParam = curve.getParam(EC_Consts.PARAMETER_R)[0]; BigInteger R = new BigInteger(1, rParam); @@ -168,14 +158,14 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite { BigInteger rm1 = R.subtract(BigInteger.ONE); BigInteger rp1 = R.add(BigInteger.ONE); - Test alternateS = ecdhTest(ecpub, alternate, spec, "ECDH with S = 101010101...01010.", Result.ExpectedValue.SUCCESS); - Test alternateOtherS = ecdhTest(ecpub, alternateOther, spec, "ECDH with S = 010101010...10101.", Result.ExpectedValue.SUCCESS); - Test fullS = ecdhTest(ecpub, full, spec, "ECDH with S = 111111111...11111 (but < r).", Result.ExpectedValue.SUCCESS); - Test smallerS = ecdhTest(ecpub, smaller, spec, "ECDH with S < r.", Result.ExpectedValue.SUCCESS); - Test exactS = ecdhTest(ecpub, R, spec, "ECDH with S = r.", Result.ExpectedValue.FAILURE); - Test largeS = ecdhTest(ecpub, larger, spec, "ECDH with S > r.", Result.ExpectedValue.ANY); - Test rm1S = ecdhTest(ecpub, rm1, spec, "ECDH with S = r - 1.", Result.ExpectedValue.SUCCESS); - Test rp1S = ecdhTest(ecpub, rp1, spec, "ECDH with S = r + 1.", Result.ExpectedValue.ANY); + Test alternateS = ecdhTest(kgt, alternate, spec, "ECDH with S = 101010101...01010.", Result.ExpectedValue.SUCCESS); + Test alternateOtherS = ecdhTest(kgt, alternateOther, spec, "ECDH with S = 010101010...10101.", Result.ExpectedValue.SUCCESS); + Test fullS = ecdhTest(kgt, full, spec, "ECDH with S = 111111111...11111 (but < r).", Result.ExpectedValue.SUCCESS); + Test smallerS = ecdhTest(kgt, smaller, spec, "ECDH with S < r.", Result.ExpectedValue.SUCCESS); + Test exactS = ecdhTest(kgt, R, spec, "ECDH with S = r.", Result.ExpectedValue.FAILURE); + Test largeS = ecdhTest(kgt, larger, spec, "ECDH with S > r.", Result.ExpectedValue.ANY); + Test rm1S = ecdhTest(kgt, rm1, spec, "ECDH with S = r - 1.", Result.ExpectedValue.SUCCESS); + Test rp1S = ecdhTest(kgt, rp1, spec, "ECDH with S = r + 1.", Result.ExpectedValue.ANY); byte[] k = curve.getParam(EC_Consts.PARAMETER_K)[0]; BigInteger K = new BigInteger(1, k); @@ -185,12 +175,12 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite { Result.ExpectedValue kExpected = K.equals(BigInteger.ONE) ? Result.ExpectedValue.SUCCESS : Result.ExpectedValue.FAILURE; - Test krS /*ONE!*/ = ecdhTest(ecpub, kr, spec, "ECDH with S = k * r.", Result.ExpectedValue.FAILURE); - Test krm1S = ecdhTest(ecpub, krm1, spec, "ECDH with S = (k * r) - 1.", kExpected); - Test krp1S = ecdhTest(ecpub, krp1, spec, "ECDH with S = (k * r) + 1.", Result.ExpectedValue.ANY); + Test krS /*ONE!*/ = ecdhTest(kgt, kr, spec, "ECDH with S = k * r.", Result.ExpectedValue.FAILURE); + Test krm1S = ecdhTest(kgt, krm1, spec, "ECDH with S = (k * r) - 1.", kExpected); + Test krp1S = ecdhTest(kgt, krp1, spec, "ECDH with S = (k * r) + 1.", Result.ExpectedValue.ANY); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with edge-case private key values over " + curve.getId() + ".", - generateSuccess, zeroS, oneS, alternateS, alternateOtherS, fullS, smallerS, exactS, largeS, rm1S, rp1S, krS, krm1S, krp1S)); + doTest(CompoundTest.function(CompoundTest.EXPECT_ALL_SUCCESS, CompoundTest.RUN_ALL_IF_FIRST, "Tests with edge-case private key values over " + curve.getId() + ".", + generate, zeroS, oneS, alternateS, alternateOtherS, fullS, smallerS, exactS, largeS, rm1S, rp1S, krS, krm1S, krp1S)); } EC_Curve secp160r1 = EC_Store.getInstance().getObject(EC_Curve.class, "secg/secp160r1"); @@ -225,29 +215,19 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite { //generate KeyPair KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec); Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); - runTest(generate); - KeyPair kp = kgt.getKeyPair(); - if (kp == null) { - Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " - + secp160r1.getBits() + "b secp160r1." + " Other tests will be skipped.", generate); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Test private key values near zero, near p and near/larger than the order on" + secp160r1.getId() + ".", generateFail)); - return; - } - Test generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate KeyPair.", generate); - ECPublicKey ecpub = (ECPublicKey) kp.getPublic(); //perform ECDH tests Test[] zeroTests = new Test[n]; int i = 0; for (BigInteger nearZero : zeros) { - zeroTests[i++] = ecdhTest(ecpub, nearZero, spec, nearZero.toString(16), Result.ExpectedValue.SUCCESS); + zeroTests[i++] = ecdhTest(kgt, nearZero, spec, nearZero.toString(16), Result.ExpectedValue.SUCCESS); } Test zeroTest = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Near zero.", zeroTests); Test[] pTests = new Test[n]; i = 0; for (BigInteger nearP : ps) { - pTests[i++] = ecdhTest(ecpub, nearP, spec, nearP.toString(16) + (nearP.compareTo(p) > 0 ? " (>p)" : " (<=p)"), Result.ExpectedValue.SUCCESS); + pTests[i++] = ecdhTest(kgt, nearP, spec, nearP.toString(16) + (nearP.compareTo(p) > 0 ? " (>p)" : " (<=p)"), Result.ExpectedValue.SUCCESS); } Test pTest = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Near p.", pTests); @@ -255,19 +235,19 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite { i = 0; for (BigInteger nearR : rs) { if (nearR.compareTo(r) >= 0) { - rTests[i++] = ecdhTest(ecpub, nearR, spec, nearR.toString(16) + " (>=r)", Result.ExpectedValue.FAILURE); + rTests[i++] = ecdhTest(kgt, nearR, spec, nearR.toString(16) + " (>=r)", Result.ExpectedValue.FAILURE); } else { - rTests[i++] = ecdhTest(ecpub, nearR, spec, nearR.toString(16) + " ( RUN_ALL_IF_FIRST = tests -> { tests[0].run(); - if (tests[0].getResult().getValue().equals(Result.Value.SUCCESS)) { + if (tests[0].getResult().getValue().equals(Result.Value.SUCCESS) || tests[0].getResult().getValue().equals(Result.Value.UXSUCCESS)) { for (int i = 1; i < tests.length; i++) { tests[i].run(); } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java index 24a942b..4634ab0 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java @@ -69,29 +69,18 @@ public class StandaloneWrongSuite extends StandaloneTestSuite { for (Map.Entry e : wrongCurves.entrySet()) { EC_Curve curve = e.getValue(); - ECParameterSpec spec = curve.toSpec(); + ECParameterSpec spec = toCustomSpec(curve); String type = curve.getField() == javacard.security.KeyPair.ALG_EC_FP ? "FP" : "F2M"; //try generating a keypair KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec); Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); - runTest(generate); - KeyPair kp = kgt.getKeyPair(); - if (kp == null) { - Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ".", generate); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Wrong curve test of " + curve.getBits() - + "b " + type + ". " + curve.getDesc(), generateFail)); - continue; - } - Test generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate); - ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate(); - ECPublicKey ecpub = (ECPublicKey) kp.getPublic(); KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub); + KeyAgreementTestable testable = new KeyAgreementTestable(ka, kgt, kgt); Test ecdh = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Wrong curve test of " + curve.getBits() - + "b " + type + ". " + curve.getDesc(), generateSuccess, ecdh)); + doTest(CompoundTest.function(CompoundTest.EXPECT_ALL_SUCCESS, CompoundTest.RUN_ALL_IF_FIRST, "Wrong curve test of " + curve.getBits() + + "b " + type + ". " + curve.getDesc(), generate, ecdh)); } } @@ -225,7 +214,7 @@ public class StandaloneWrongSuite extends StandaloneTestSuite { ByteUtil.shortToBytes((short) 0), ByteUtil.shortToBytes((short) 0)}; curve.setParam(EC_Consts.PARAMETER_F2M, coeffBytes); - Test coeff0 = ecdhTest(toCustomSpec(curve), "ECDH with wrong field polynomial: x^"); + Test coeff0 = ecdhTest(toCustomSpec(curve), "ECDH with wrong field polynomial: 0"); short e1 = (short) (2 * bits); short e2 = (short) (3 * bits); @@ -246,19 +235,12 @@ public class StandaloneWrongSuite extends StandaloneTestSuite { //generate KeyPair KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec); Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.FAILURE); - runTest(generate); - KeyPair kp = kgt.getKeyPair(); - if (kp == null) { - return CompoundTest.all(Result.ExpectedValue.SUCCESS, desc, generate); - } - ECPublicKey pub = (ECPublicKey) kp.getPublic(); - ECPrivateKey priv = (ECPrivateKey) kp.getPrivate(); //perform ECDH KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = new KeyAgreementTestable(ka, priv, pub); + KeyAgreementTestable testable = new KeyAgreementTestable(ka, kgt, kgt); Test ecdh = KeyAgreementTest.expect(testable, Result.ExpectedValue.FAILURE); - return CompoundTest.all(Result.ExpectedValue.SUCCESS, desc, generate, ecdh); + return CompoundTest.function(CompoundTest.EXPECT_ALL_SUCCESS, CompoundTest.RUN_ALL_IF_FIRST, desc, generate, ecdh); } //constructs ECParameterSpec from EC_Curve even if the parameters of the curve are wrong -- cgit v1.3.1 From c7ddf947a8f7939c5a29265ef94617de6df7d8ef Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 2 Aug 2024 17:28:05 +0200 Subject: Remove runTest from misc suite. --- .../java/cz/crcs/ectester/common/util/ECUtil.java | 2 +- .../test/suites/StandaloneMiscSuite.java | 28 ++++++++-------------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java b/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java index 4d74a87..6eb0b1a 100644 --- a/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java +++ b/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java @@ -202,7 +202,7 @@ public class ECUtil { } } - private static byte[] hashCurve(EC_Curve curve) { + public static byte[] hashCurve(EC_Curve curve) { int bytes = (curve.getBits() + 7) / 8; byte[] result = new byte[bytes]; SHA1Digest digest = new SHA1Digest(); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java index 90da4b5..657c2ff 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java @@ -6,6 +6,7 @@ import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.CompoundTest; import cz.crcs.ectester.common.test.Result; import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.standalone.ECTesterStandalone; import cz.crcs.ectester.standalone.consts.KeyAgreementIdent; @@ -22,6 +23,8 @@ import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import java.util.*; +import static cz.crcs.ectester.common.util.ECUtil.hashCurve; + /** * @author David Hofman */ @@ -50,7 +53,7 @@ public class StandaloneMiscSuite extends StandaloneTestSuite { kaTypes = kaAlgo != null ? Arrays.asList(kaAlgo.split(",")) : new ArrayList<>(); sigTypes = sigAlgo != null ? Arrays.asList(sigAlgo.split(",")) : new ArrayList<>(); - + KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo); if (kpgIdent == null) { return; @@ -78,29 +81,18 @@ public class StandaloneMiscSuite extends StandaloneTestSuite { private void testCurve(EC_Curve curve, String catName, KeyPairGenerator kpg, Result.ExpectedValue expected) throws NoSuchAlgorithmException { //generate KeyPair KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, curve.toSpec()); - Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); - runTest(generate); - KeyPair kp = kgt.getKeyPair(); - if(kp == null) { - Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + - ". " + " Other tests will be skipped.", generate); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", generateFail)); - return; - } - Test generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate); - ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate(); - ECPublicKey ecpub = (ECPublicKey) kp.getPublic(); + Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); //perform KeyAgreement tests List kaTests = new LinkedList<>(); for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) { if (kaAlgo == null || kaIdent.containsAny(kaTypes)) { KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub); + KeyAgreementTestable testable = new KeyAgreementTestable(ka, kgt, kgt); kaTests.add(KeyAgreementTest.expectError(testable, expected)); } } - if(kaTests.isEmpty()) { + if (kaTests.isEmpty()) { kaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified KeyAgreement types is supported by the library.")); } @@ -109,17 +101,17 @@ public class StandaloneMiscSuite extends StandaloneTestSuite { for (SignatureIdent sigIdent : cfg.selected.getSigs()) { if (sigAlgo == null || sigIdent.containsAny(sigTypes)) { Signature sig = sigIdent.getInstance(cfg.selected.getProvider()); - SignatureTestable testable = new SignatureTestable(sig, ecpriv, ecpub, null); + SignatureTestable testable = new SignatureTestable(sig, kgt, hashCurve(curve)); sigTests.add(SignatureTest.expectError(testable, expected)); } } - if(sigTests.isEmpty()) { + if (sigTests.isEmpty()) { sigTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified Signature types is supported by the library.")); } Test performKeyAgreements = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform specified KeyAgreements.", kaTests.toArray(new Test[0])); Test performSignatures = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform specified Signatures.", sigTests.toArray(new Test[0])); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", generateSuccess, performKeyAgreements, performSignatures)); + doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", generate, performKeyAgreements, performSignatures)); } private void testCurves(Collection curves, String catName, KeyPairGenerator kpg, Result.ExpectedValue expected) throws NoSuchAlgorithmException { -- cgit v1.3.1 From be0fc8c2065b22ae761eb1417c0571f6eeddb8b2 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 2 Aug 2024 17:41:10 +0200 Subject: Fix Botan ECKCDSA. --- .../cz/crcs/ectester/standalone/libs/jni/botan.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp index c5bc5f1..4227997 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp @@ -496,11 +496,16 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig emsa = "EMSA1(SHA-512)"; } + Botan::Signature_Format sigformat = Botan::Signature_Format::DER_SEQUENCE; + if (type_str.find("ECKCDSA") != std::string::npos) { + sigformat = Botan::Signature_Format::IEEE_1363; + } + jsize data_length = env->GetArrayLength(data); jbyte *data_bytes = env->GetByteArrayElements(data, nullptr); std::vector sig; try { - Botan::PK_Signer signer(*skey, rng, emsa, Botan::DER_SEQUENCE); + Botan::PK_Signer signer(*skey, rng, emsa, sigformat); native_timing_start(); sig = signer.sign_message((uint8_t*) data_bytes, data_length, rng); @@ -581,6 +586,11 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna emsa = "EMSA1(SHA-512)"; } + Botan::Signature_Format sigformat = Botan::Signature_Format::DER_SEQUENCE; + if (type_str.find("ECKCDSA") != std::string::npos) { + sigformat = Botan::Signature_Format::IEEE_1363; + } + jsize data_length = env->GetArrayLength(data); jsize sig_length = env->GetArrayLength(signature); jbyte *data_bytes = env->GetByteArrayElements(data, nullptr); @@ -589,7 +599,7 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna bool result; try { - Botan::PK_Verifier verifier(*pkey, emsa, Botan::DER_SEQUENCE); + Botan::PK_Verifier verifier(*pkey, emsa, sigformat); native_timing_start(); result = verifier.verify_message((uint8_t*)data_bytes, data_length, (uint8_t*)sig_bytes, sig_length); -- cgit v1.3.1 From 2990dc3cd105cced05b6ce883a9ef86725e746f5 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 2 Aug 2024 17:41:25 +0200 Subject: Remove runTest from performance suite. --- .../ectester/standalone/test/suites/StandalonePerformanceSuite.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java index 52b2122..30a0c0f 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java @@ -84,8 +84,8 @@ public class StandalonePerformanceSuite extends StandaloneTestSuite { kgtOther = new KeyGeneratorTestable(kpg); } kpgTests.add(PerformanceTest.repeat(kgtOne, cfg.selected, kpgIdent.getName(), count)); + kpgTests.add(PerformanceTest.repeat(kgtOther, cfg.selected, kpgIdent.getName(), count)); } - runTest(KeyGeneratorTest.expect(kgtOther, Result.ExpectedValue.SUCCESS)); doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPairGenerator performance tests", kpgTests.toArray(new Test[0]))); List kaTests = new LinkedList<>(); -- cgit v1.3.1 From 60097937c8eabfc5514da3b181ae32ba89d46931 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 2 Aug 2024 17:54:18 +0200 Subject: Remove runTest from composite suite. --- .../test/suites/StandaloneCompositeSuite.java | 30 ++++------------------ 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCompositeSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCompositeSuite.java index 232f356..38d76bc 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCompositeSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCompositeSuite.java @@ -66,15 +66,6 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite { //Generate KeyPair KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec); Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); - runTest(generate); - KeyPair kp = kgt.getKeyPair(); - if (kp == null) { - Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ".", generateFail)); - continue; - } - Test generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate); - ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate(); //Perform KeyAgreement tests List allKaTests = new LinkedList<>(); @@ -84,7 +75,7 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite { for (EC_Key.Public pub : curveKeys.getValue()) { ECPublicKey ecpub = ECUtil.toPublicKey(pub); KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub); + KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpub, kgt); Test keyAgreement = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE); specificKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", with generated private key, " + pub.getDesc(), keyAgreement)); } @@ -95,7 +86,7 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite { allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library.")); } Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0])); - doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ".", generateSuccess, tests)); + doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ".", generate, tests)); } @@ -144,24 +135,13 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite { //generate KeyPair KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, curve.toSpec()); Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); - runTest(generate); - KeyPair kp = kgt.getKeyPair(); - if (kp == null) { - Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + - ". " + " Other tests will be skipped.", generate); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, description, generateFail)); - continue; - } - Test generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate); - ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate(); - ECPublicKey ecpub = (ECPublicKey) kp.getPublic(); //perform KeyAgreement tests List kaTests = new LinkedList<>(); for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) { if (kaAlgo == null || kaIdent.containsAny(kaTypes)) { KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub); + KeyAgreementTestable testable = new KeyAgreementTestable(ka, kgt, kgt); kaTests.add(KeyAgreementTest.expectError(testable, dhValue)); } } @@ -174,7 +154,7 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite { for (SignatureIdent sigIdent : cfg.selected.getSigs()) { if (sigAlgo == null || sigIdent.containsAny(sigTypes)) { Signature sig = sigIdent.getInstance(cfg.selected.getProvider()); - SignatureTestable testable = new SignatureTestable(sig, ecpriv, ecpub, null); + SignatureTestable testable = new SignatureTestable(sig, kgt, null); sigTests.add(SignatureTest.expectError(testable, dhValue)); } } @@ -184,7 +164,7 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite { Test performKeyAgreements = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform specified KeyAgreements.", kaTests.toArray(new Test[0])); Test performSignatures = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform specified Signatures.", sigTests.toArray(new Test[0])); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, description, generateSuccess, performKeyAgreements, performSignatures)); + doTest(CompoundTest.function(CompoundTest.EXPECT_ALL_SUCCESS, CompoundTest.RUN_ALL_IF_FIRST, description, generate, performKeyAgreements, performSignatures)); } } } -- cgit v1.3.1 From 6cb0cf8a66ede1f98cfeed323c028d0a2b825aef Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 2 Aug 2024 18:05:12 +0200 Subject: Unify Invalid, Degenerate and Twist suites on standalone. --- .../java/cz/crcs/ectester/common/ec/EC_Curve.java | 11 +- .../test/suites/StandaloneDegenerateSuite.java | 100 +----------------- .../test/suites/StandaloneForeignSuite.java | 112 +++++++++++++++++++++ .../test/suites/StandaloneInvalidSuite.java | 99 +----------------- .../test/suites/StandaloneTwistSuite.java | 100 +----------------- 5 files changed, 122 insertions(+), 300 deletions(-) create mode 100644 standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java diff --git a/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java b/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java index 4ec3237..acb822f 100644 --- a/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java +++ b/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java @@ -64,10 +64,13 @@ public class EC_Curve extends EC_Params { e1 = powers[0]; e2 = powers[1]; e3 = powers[2]; - if (e2 == 0 && e3 == 0) { - powers = new int[]{e1}; + System.err.println(e1); + System.err.println(e2); + System.err.println(e3); + if (e1 == 0 && e2 == 0) { + powers = new int[]{e3}; } else { - powers = new int[]{e1, e2, e3}; + powers = new int[]{e3, e2, e1}; } return powers; } else { @@ -131,7 +134,7 @@ public class EC_Curve extends EC_Params { if (powers.length == 1) { return new ECCurve.F2m(m, powers[0], 0, 0, a, b, r, k); } else { - return new ECCurve.F2m(m, powers[0], powers[1], powers[2], a, b, r, k); + return new ECCurve.F2m(m, powers[2], powers[1], powers[0], a, b, r, k); } } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java index 89a2c16..5a27f95 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java @@ -1,114 +1,16 @@ package cz.crcs.ectester.standalone.test.suites; import cz.crcs.ectester.common.cli.TreeCommandLine; -import cz.crcs.ectester.common.ec.EC_Curve; -import cz.crcs.ectester.common.ec.EC_Key; import cz.crcs.ectester.common.output.TestWriter; -import cz.crcs.ectester.common.test.CompoundTest; -import cz.crcs.ectester.common.test.Result; -import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.common.util.ECUtil; -import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.standalone.ECTesterStandalone; -import cz.crcs.ectester.standalone.consts.KeyAgreementIdent; -import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent; -import cz.crcs.ectester.standalone.test.base.KeyAgreementTest; -import cz.crcs.ectester.standalone.test.base.KeyAgreementTestable; -import cz.crcs.ectester.standalone.test.base.KeyGeneratorTest; -import cz.crcs.ectester.standalone.test.base.KeyGeneratorTestable; - -import javax.crypto.KeyAgreement; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; -import java.security.spec.ECGenParameterSpec; -import java.security.spec.ECParameterSpec; -import java.util.*; /** * @author David Hofman */ -public class StandaloneDegenerateSuite extends StandaloneTestSuite { +public class StandaloneDegenerateSuite extends StandaloneForeignSuite { public StandaloneDegenerateSuite(TestWriter writer, ECTesterStandalone.Config cfg, TreeCommandLine cli) { super(writer, cfg, cli, "degenerate", "The degenerate suite tests whether the library rejects points outside of the curve during ECDH.", "The tested points lie on a part of the plane for which some Edwards, Hessian and Huff form addition formulas degenerate into exponentiation in the base finite field.", "Supports options:", "\t - gt/kpg-type", "\t - kt/ka-type (select multiple types by separating them with commas)"); } - - @Override - protected void runTests() throws Exception { - String kpgAlgo = cli.getOptionValue("test.kpg-type"); - String kaAlgo = cli.getOptionValue("test.ka-type"); - List kaTypes = kaAlgo != null ? Arrays.asList(kaAlgo.split(",")) : new ArrayList<>(); - - KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo); - if (kpgIdent == null) { - return; - } - - Map pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "degenerate"); - Map> curveList = EC_Store.mapKeyToCurve(pubkeys.values()); - for (Map.Entry> e : curveList.entrySet()) { - EC_Curve curve = e.getKey(); - List keys = e.getValue(); - - KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider()); - ECParameterSpec spec = curve.toSpec(); - KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec); - - Test generateSuccess; - Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); - runTest(generate); - KeyPair kp = kgt.getKeyPair(); - if (kp != null) { - generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate); - } else { - // If KeyPair generation fails, try generating it on named curve instead. - ECGenParameterSpec namedSpec = new ECGenParameterSpec(curve.getId()); - KeyGeneratorTestable kgtOnNamedCurve = new KeyGeneratorTestable(kpg, namedSpec); - Test generateOnNamedCurve = KeyGeneratorTest.expectError(kgtOnNamedCurve, Result.ExpectedValue.ANY); - runTest(generateOnNamedCurve); - kp = kgtOnNamedCurve.getKeyPair(); - if (kp != null) { - generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (named curve).", generateOnNamedCurve); - } else { - // If even the named curve generation fails, try generating with the default curve instead. Use this key only if it has the same domain parameters as our public key. - KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits()); - Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY); - runTest(generateOnDefaultCurve); - kp = kgtOnDefaultCurve.getKeyPair(); - if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) { - generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (default curve).", generateOnDefaultCurve); - } else { - Test generateNotEqual = CompoundTest.function(tests -> new Result(Result.Value.FAILURE, "Default parameters do not match the curve " + curve.getId()), "Default parameters do not match the curve " + curve.getId(), generateOnDefaultCurve); - Test generateFail = CompoundTest.any(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate, generateOnNamedCurve, generateNotEqual); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Degenerate curve test of " + curve.getId() + ".", generateFail)); - continue; - } - } - } - ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate(); - - List allKaTests = new LinkedList<>(); - for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) { - if (kaAlgo == null || kaIdent.containsAny(kaTypes)) { - List specificKaTests = new LinkedList<>(); - for (EC_Key.Public pub : keys) { - ECPublicKey ecpub = ECUtil.toPublicKey(pub); - KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub); - Test keyAgreement = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE); - specificKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " degenerate key test.", keyAgreement)); - } - allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with degenerate public points..", specificKaTests.toArray(new Test[0]))); - } - } - if (allKaTests.isEmpty()) { - allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library.")); - } - Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0])); - doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Degenerate curve test of " + curve.getId() + ".", generateSuccess, tests)); - } - } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java new file mode 100644 index 0000000..7aebf23 --- /dev/null +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java @@ -0,0 +1,112 @@ +package cz.crcs.ectester.standalone.test.suites; + +import cz.crcs.ectester.common.cli.TreeCommandLine; +import cz.crcs.ectester.common.ec.EC_Curve; +import cz.crcs.ectester.common.ec.EC_Key; +import cz.crcs.ectester.common.output.TestWriter; +import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.Result; +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.util.ECUtil; +import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.standalone.ECTesterStandalone; +import cz.crcs.ectester.standalone.consts.KeyAgreementIdent; +import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent; +import cz.crcs.ectester.standalone.test.base.KeyAgreementTest; +import cz.crcs.ectester.standalone.test.base.KeyAgreementTestable; +import cz.crcs.ectester.standalone.test.base.KeyGeneratorTest; +import cz.crcs.ectester.standalone.test.base.KeyGeneratorTestable; + +import javax.crypto.KeyAgreement; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.interfaces.ECPrivateKey; +import java.security.interfaces.ECPublicKey; +import java.security.spec.ECGenParameterSpec; +import java.security.spec.ECParameterSpec; +import java.util.*; + +public abstract class StandaloneForeignSuite extends StandaloneTestSuite { + private String capName; + + public StandaloneForeignSuite(TestWriter writer, ECTesterStandalone.Config cfg, TreeCommandLine cli, String name, String... description) { + super(writer, cfg, cli, name, description); + this.capName = name.substring(0, 1).toUpperCase() + name.substring(1); + } + + @Override + protected void runTests() throws Exception { + String kpgAlgo = cli.getOptionValue("test.kpg-type"); + String kaAlgo = cli.getOptionValue("test.ka-type"); + List kaTypes = kaAlgo != null ? Arrays.asList(kaAlgo.split(",")) : new ArrayList<>(); + + KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo); + if (kpgIdent == null) { + return; + } + + Map pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, this.name); + Map> curveList = EC_Store.mapKeyToCurve(pubkeys.values()); + for (Map.Entry> e : curveList.entrySet()) { + EC_Curve curve = e.getKey(); + List keys = e.getValue(); + + KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider()); + ECParameterSpec spec = curve.toSpec(); + KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec); + + Test generateSuccess; + Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); + runTest(generate); + KeyPair kp = kgt.getKeyPair(); + if (kp != null) { + generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate); + } else { + // If KeyPair generation fails, try generating it on named curve instead. + ECGenParameterSpec namedSpec = new ECGenParameterSpec(curve.getId()); + KeyGeneratorTestable kgtOnNamedCurve = new KeyGeneratorTestable(kpg, namedSpec); + Test generateOnNamedCurve = KeyGeneratorTest.expectError(kgtOnNamedCurve, Result.ExpectedValue.ANY); + runTest(generateOnNamedCurve); + kp = kgtOnNamedCurve.getKeyPair(); + if (kp != null) { + generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (named curve).", generateOnNamedCurve); + } else { + // If even the named curve generation fails, try generating with the default curve instead. Use this key only if it has the same domain parameters as our public key. + KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits()); + Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY); + runTest(generateOnDefaultCurve); + kp = kgtOnDefaultCurve.getKeyPair(); + if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) { + generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (default curve).", generateOnDefaultCurve); + } else { + Test generateNotEqual = CompoundTest.function(tests -> new Result(Result.Value.FAILURE, "Default parameters do not match the curve " + curve.getId()), "Default parameters do not match the curve " + curve.getId(), generateOnDefaultCurve); + Test generateFail = CompoundTest.any(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate, generateOnNamedCurve, generateNotEqual); + doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, this.capName + " curve test of " + curve.getId() + ".", generateFail)); + continue; + } + } + } + ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate(); + + List allKaTests = new LinkedList<>(); + for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) { + if (kaAlgo == null || kaIdent.containsAny(kaTypes)) { + List specificKaTests = new LinkedList<>(); + for (EC_Key.Public pub : keys) { + ECPublicKey ecpub = ECUtil.toPublicKey(pub); + KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); + KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub); + Test keyAgreement = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE); + specificKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " invalid key test.", keyAgreement)); + } + allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with invalid public points.", specificKaTests.toArray(new Test[0]))); + } + } + if (allKaTests.isEmpty()) { + allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library.")); + } + Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0])); + doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, this.capName + " curve test of " + curve.getId() + ".", generateSuccess, tests)); + } + } +} diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java index 436b5ef..d1b9a88 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java @@ -1,113 +1,16 @@ package cz.crcs.ectester.standalone.test.suites; import cz.crcs.ectester.common.cli.TreeCommandLine; -import cz.crcs.ectester.common.ec.EC_Curve; -import cz.crcs.ectester.common.ec.EC_Key; import cz.crcs.ectester.common.output.TestWriter; -import cz.crcs.ectester.common.test.CompoundTest; -import cz.crcs.ectester.common.test.Result; -import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.common.util.ECUtil; -import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.standalone.ECTesterStandalone; -import cz.crcs.ectester.standalone.consts.KeyAgreementIdent; -import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent; -import cz.crcs.ectester.standalone.test.base.KeyAgreementTest; -import cz.crcs.ectester.standalone.test.base.KeyAgreementTestable; -import cz.crcs.ectester.standalone.test.base.KeyGeneratorTest; -import cz.crcs.ectester.standalone.test.base.KeyGeneratorTestable; -import javax.crypto.KeyAgreement; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; -import java.security.spec.ECGenParameterSpec; -import java.security.spec.ECParameterSpec; -import java.util.*; /** * @author David Hofman */ -public class StandaloneInvalidSuite extends StandaloneTestSuite { +public class StandaloneInvalidSuite extends StandaloneForeignSuite { public StandaloneInvalidSuite(TestWriter writer, ECTesterStandalone.Config cfg, TreeCommandLine cli) { super(writer, cfg, cli, "invalid", "The invalid curve suite tests whether the library rejects points outside of the curve during ECDH.", "Supports options:", "\t - gt/kpg-type", "\t - kt/ka-type (select multiple types by separating them with commas)"); } - - @Override - protected void runTests() throws Exception { - String kpgAlgo = cli.getOptionValue("test.kpg-type"); - String kaAlgo = cli.getOptionValue("test.ka-type"); - List kaTypes = kaAlgo != null ? Arrays.asList(kaAlgo.split(",")) : new ArrayList<>(); - - KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo); - if (kpgIdent == null) { - return; - } - - Map pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "invalid"); - Map> curveList = EC_Store.mapKeyToCurve(pubkeys.values()); - for (Map.Entry> e : curveList.entrySet()) { - EC_Curve curve = e.getKey(); - List keys = e.getValue(); - - KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider()); - ECParameterSpec spec = curve.toSpec(); - KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec); - - Test generateSuccess; - Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); - runTest(generate); - KeyPair kp = kgt.getKeyPair(); - if (kp != null) { - generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate); - } else { - // If KeyPair generation fails, try generating it on named curve instead. - ECGenParameterSpec namedSpec = new ECGenParameterSpec(curve.getId()); - KeyGeneratorTestable kgtOnNamedCurve = new KeyGeneratorTestable(kpg, namedSpec); - Test generateOnNamedCurve = KeyGeneratorTest.expectError(kgtOnNamedCurve, Result.ExpectedValue.ANY); - runTest(generateOnNamedCurve); - kp = kgtOnNamedCurve.getKeyPair(); - if (kp != null) { - generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (named curve).", generateOnNamedCurve); - } else { - // If even the named curve generation fails, try generating with the default curve instead. Use this key only if it has the same domain parameters as our public key. - KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits()); - Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY); - runTest(generateOnDefaultCurve); - kp = kgtOnDefaultCurve.getKeyPair(); - if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) { - generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (default curve).", generateOnDefaultCurve); - } else { - Test generateNotEqual = CompoundTest.function(tests -> new Result(Result.Value.FAILURE, "Default parameters do not match the curve " + curve.getId()), "Default parameters do not match the curve " + curve.getId(), generateOnDefaultCurve); - Test generateFail = CompoundTest.any(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate, generateOnNamedCurve, generateNotEqual); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId() + ".", generateFail)); - continue; - } - } - } - ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate(); - - List allKaTests = new LinkedList<>(); - for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) { - if (kaAlgo == null || kaIdent.containsAny(kaTypes)) { - List specificKaTests = new LinkedList<>(); - for (EC_Key.Public pub : keys) { - ECPublicKey ecpub = ECUtil.toPublicKey(pub); - KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub); - Test keyAgreement = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE); - specificKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " invalid key test.", keyAgreement)); - } - allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with invalid public points.", specificKaTests.toArray(new Test[0]))); - } - } - if (allKaTests.isEmpty()) { - allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library.")); - } - Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0])); - doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId() + ".", generateSuccess, tests)); - } - } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java index 8655d1d..1f08a80 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java @@ -1,113 +1,15 @@ package cz.crcs.ectester.standalone.test.suites; import cz.crcs.ectester.common.cli.TreeCommandLine; -import cz.crcs.ectester.common.ec.EC_Curve; -import cz.crcs.ectester.common.ec.EC_Key; import cz.crcs.ectester.common.output.TestWriter; -import cz.crcs.ectester.common.test.CompoundTest; -import cz.crcs.ectester.common.test.Result; -import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.common.util.ECUtil; -import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.standalone.ECTesterStandalone; -import cz.crcs.ectester.standalone.consts.KeyAgreementIdent; -import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent; -import cz.crcs.ectester.standalone.test.base.KeyAgreementTest; -import cz.crcs.ectester.standalone.test.base.KeyAgreementTestable; -import cz.crcs.ectester.standalone.test.base.KeyGeneratorTest; -import cz.crcs.ectester.standalone.test.base.KeyGeneratorTestable; - -import javax.crypto.KeyAgreement; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; -import java.security.spec.ECGenParameterSpec; -import java.security.spec.ECParameterSpec; -import java.util.*; /** * @author David Hofman */ -public class StandaloneTwistSuite extends StandaloneTestSuite { +public class StandaloneTwistSuite extends StandaloneForeignSuite { public StandaloneTwistSuite(TestWriter writer, ECTesterStandalone.Config cfg, TreeCommandLine cli) { super(writer, cfg, cli, "twist", "The twist test suite tests whether the library correctly rejects points on the quadratic twist of the curve during ECDH.", "Supports options:", "\t - gt/kpg-type", "\t - kt/ka-type (select multiple types by separating them with commas)"); } - - @Override - protected void runTests() throws Exception { - String kpgAlgo = cli.getOptionValue("test.kpg-type"); - String kaAlgo = cli.getOptionValue("test.ka-type"); - List kaTypes = kaAlgo != null ? Arrays.asList(kaAlgo.split(",")) : new ArrayList<>(); - - KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo); - if (kpgIdent == null) { - return; - } - - Map pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "twist"); - Map> curveList = EC_Store.mapKeyToCurve(pubkeys.values()); - for (Map.Entry> e : curveList.entrySet()) { - EC_Curve curve = e.getKey(); - List keys = e.getValue(); - - KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider()); - ECParameterSpec spec = curve.toSpec(); - KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec); - - Test generateSuccess; - Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); - runTest(generate); - KeyPair kp = kgt.getKeyPair(); - if (kp != null) { - generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate); - } else { - // If KeyPair generation fails, try generating it on named curve instead. - ECGenParameterSpec namedSpec = new ECGenParameterSpec(curve.getId()); - KeyGeneratorTestable kgtOnNamedCurve = new KeyGeneratorTestable(kpg, namedSpec); - Test generateOnNamedCurve = KeyGeneratorTest.expectError(kgtOnNamedCurve, Result.ExpectedValue.ANY); - runTest(generateOnNamedCurve); - kp = kgtOnNamedCurve.getKeyPair(); - if (kp != null) { - generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (named curve).", generateOnNamedCurve); - } else { - // If even the named curve generation fails, try generating with the default curve instead. Use this key only if it has the same domain parameters as our public key. - KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits()); - Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY); - runTest(generateOnDefaultCurve); - kp = kgtOnDefaultCurve.getKeyPair(); - if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) { - generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (default curve).", generateOnDefaultCurve); - } else { - Test generateNotEqual = CompoundTest.function(tests -> new Result(Result.Value.FAILURE, "Default parameters do not match the curve " + curve.getId()), "Default parameters do not match the curve " + curve.getId(), generateOnDefaultCurve); - Test generateFail = CompoundTest.any(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate, generateOnNamedCurve, generateNotEqual); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId() + ".", generateFail)); - continue; - } - } - } - ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate(); - - List allKaTests = new LinkedList<>(); - for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) { - if (kaAlgo == null || kaIdent.containsAny(kaTypes)) { - List specificKaTests = new LinkedList<>(); - for (EC_Key.Public pub : keys) { - ECPublicKey ecpub = ECUtil.toPublicKey(pub); - KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub); - Test keyAgreement = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE); - specificKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " twist key test.", keyAgreement)); - } - allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with public points on twist.", specificKaTests.toArray(new Test[0]))); - } - } - if (allKaTests.isEmpty()) { - allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library.")); - } - Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0])); - doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId() + ".", generateSuccess, tests)); - } - } } -- cgit v1.3.1 From 6ed466cdeab999abd4c62a824106ab1078053934 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 2 Aug 2024 18:39:54 +0200 Subject: Remove runTest from the rest of the standalone suites. --- .../java/cz/crcs/ectester/common/ec/EC_Curve.java | 3 - .../cz/crcs/ectester/common/test/TestSuite.java | 2 +- .../standalone/test/base/KeyGeneratorTest.java | 8 +- .../test/suites/StandaloneForeignSuite.java | 125 +++++++++++++++------ 4 files changed, 98 insertions(+), 40 deletions(-) diff --git a/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java b/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java index acb822f..7147c18 100644 --- a/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java +++ b/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java @@ -64,9 +64,6 @@ public class EC_Curve extends EC_Params { e1 = powers[0]; e2 = powers[1]; e3 = powers[2]; - System.err.println(e1); - System.err.println(e2); - System.err.println(e3); if (e1 == 0 && e2 == 0) { powers = new int[]{e3}; } else { diff --git a/common/src/main/java/cz/crcs/ectester/common/test/TestSuite.java b/common/src/main/java/cz/crcs/ectester/common/test/TestSuite.java index 091b008..0f2b1b0 100644 --- a/common/src/main/java/cz/crcs/ectester/common/test/TestSuite.java +++ b/common/src/main/java/cz/crcs/ectester/common/test/TestSuite.java @@ -53,7 +53,7 @@ public abstract class TestSuite { * @return The test that was run. * @throws TestException */ - protected T runTest(T t) { + private T runTest(T t) { running = t; writer.beginTest(t); t.run(); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java index 8c49224..f35741a 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java @@ -43,13 +43,13 @@ public class KeyGeneratorTest extends SimpleTest { public String getDescription() { String params = ""; if (testable.getKeysize() != 0) { - params = String.format("(default %d-bit curve)", testable.getKeysize()); + params = String.format("on (default %d-bit curve)", testable.getKeysize()); } else if (testable.getSpec() instanceof ECGenParameterSpec) { String name = ((ECGenParameterSpec)testable.getSpec()).getName(); - params = String.format("(%s)", name); + params = String.format("on (%s)", name); } else if (testable.getSpec() instanceof ECParameterSpec) { - params = "(custom curve)"; + params = "on (custom curve)"; } - return "KeyPairGenerator " + testable.getKpg().getAlgorithm() + " on " + params; + return "KeyPairGenerator " + testable.getKpg().getAlgorithm() + " " + params; } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java index 7aebf23..21431ae 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java @@ -22,6 +22,7 @@ import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; +import java.security.spec.AlgorithmParameterSpec; import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; import java.util.*; @@ -50,43 +51,103 @@ public abstract class StandaloneForeignSuite extends StandaloneTestSuite { for (Map.Entry> e : curveList.entrySet()) { EC_Curve curve = e.getKey(); List keys = e.getValue(); + ECPublicKey singlePkey = ECUtil.toPublicKey(keys.get(0)); KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider()); ECParameterSpec spec = curve.toSpec(); + ECGenParameterSpec namedSpec = new ECGenParameterSpec(curve.getId()); + KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec); + KeyGeneratorTestable kgtOnNamedCurve = new KeyGeneratorTestable(kpg, namedSpec); + KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits()); + + // This is some nasty hacking... + KeyGeneratorTestable theKgt = new KeyGeneratorTestable(kpg) { + private KeyGeneratorTestable current = null; - Test generateSuccess; - Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); - runTest(generate); - KeyPair kp = kgt.getKeyPair(); - if (kp != null) { - generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate); - } else { - // If KeyPair generation fails, try generating it on named curve instead. - ECGenParameterSpec namedSpec = new ECGenParameterSpec(curve.getId()); - KeyGeneratorTestable kgtOnNamedCurve = new KeyGeneratorTestable(kpg, namedSpec); - Test generateOnNamedCurve = KeyGeneratorTest.expectError(kgtOnNamedCurve, Result.ExpectedValue.ANY); - runTest(generateOnNamedCurve); - kp = kgtOnNamedCurve.getKeyPair(); - if (kp != null) { - generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (named curve).", generateOnNamedCurve); - } else { - // If even the named curve generation fails, try generating with the default curve instead. Use this key only if it has the same domain parameters as our public key. - KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits()); - Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY); - runTest(generateOnDefaultCurve); - kp = kgtOnDefaultCurve.getKeyPair(); - if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) { - generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (default curve).", generateOnDefaultCurve); - } else { - Test generateNotEqual = CompoundTest.function(tests -> new Result(Result.Value.FAILURE, "Default parameters do not match the curve " + curve.getId()), "Default parameters do not match the curve " + curve.getId(), generateOnDefaultCurve); - Test generateFail = CompoundTest.any(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate, generateOnNamedCurve, generateNotEqual); - doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, this.capName + " curve test of " + curve.getId() + ".", generateFail)); - continue; + @Override + public Exception getException() { + if (current != null) { + return current.getException(); } + return super.getException(); } - } - ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate(); + + @Override + public KeyGeneratorStage getStage() { + if (current != null) { + return current.getStage(); + } + return super.getStage(); + } + + @Override + public void run() { + stage = KeyGeneratorStage.Init; + kgt.run(); + if (kgt.ok()) { + ok = true; + error = false; + current = kgt; + hasRun = true; + return; + } + kgtOnNamedCurve.run(); + if (kgtOnNamedCurve.ok()) { + ok = true; + error = false; + current = kgtOnNamedCurve; + hasRun = true; + return; + } + kgtOnDefaultCurve.run(); + if (kgtOnDefaultCurve.ok() && ECUtil.equalKeyPairParameters((ECPrivateKey) kgtOnDefaultCurve.getKeyPair().getPrivate(), singlePkey)) { + ok = true; + error = false; + current = kgtOnDefaultCurve; + hasRun = true; + } + } + + @Override + public KeyPair getKeyPair() { + if (current != null) { + return current.getKeyPair(); + } + return super.getKeyPair(); + } + + @Override + public KeyPairGenerator getKpg() { + if (current != null) { + return current.getKpg(); + } + return super.getKpg(); + } + + @Override + public AlgorithmParameterSpec getSpec() { + if (current != null) { + return current.getSpec(); + } + return super.getSpec(); + } + + @Override + public int getKeysize() { + if (current != null) { + return current.getKeysize(); + } + return super.getKeysize(); + } + }; + + Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.SUCCESS); + Test generateOnNamedCurve = KeyGeneratorTest.expectError(kgtOnNamedCurve, Result.ExpectedValue.SUCCESS); + Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.SUCCESS); + Test generateFinal = KeyGeneratorTest.expectError(theKgt, Result.ExpectedValue.SUCCESS); + //generate, generateOnNamedCurve, generateOnDefaultCurve, + Test generateAny = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate a keypair on the standard curve.", generateFinal); List allKaTests = new LinkedList<>(); for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) { @@ -95,7 +156,7 @@ public abstract class StandaloneForeignSuite extends StandaloneTestSuite { for (EC_Key.Public pub : keys) { ECPublicKey ecpub = ECUtil.toPublicKey(pub); KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub); + KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpub, theKgt); Test keyAgreement = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE); specificKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " invalid key test.", keyAgreement)); } @@ -106,7 +167,7 @@ public abstract class StandaloneForeignSuite extends StandaloneTestSuite { allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library.")); } Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0])); - doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, this.capName + " curve test of " + curve.getId() + ".", generateSuccess, tests)); + doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, this.capName + " curve test of " + curve.getId() + ".", generateAny, tests)); } } } -- cgit v1.3.1 From 88c9d01a666770abf1d8dcc699934f0800185f4b Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 2 Aug 2024 19:18:16 +0200 Subject: Handle numeric lib versions better. --- .../src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp | 3 +-- .../src/main/resources/cz/crcs/ectester/standalone/libs/jni/mbedtls.c | 2 +- .../main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c | 4 ++++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp index 4227997..52c8dbb 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp @@ -33,12 +33,11 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_createP jmethodID init = env->GetMethodID(local_provider_class, "", "(Ljava/lang/String;DLjava/lang/String;)V"); const char* info_str = Botan::version_cstr(); - const char* v_str = Botan::short_version_cstr(); std::string name_str = Botan::short_version_string(); name_str.insert(0, "Botan "); jstring name = env->NewStringUTF(name_str.c_str()); - double version = strtod(v_str, nullptr); + double version = BOTAN_VERSION_MAJOR + ((double)BOTAN_VERSION_MINOR/100) + ((double)BOTAN_VERSION_PATCH/1000); jstring info = env->NewStringUTF(info_str); return env->NewObject(provider_class, init, name, version, info); diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/mbedtls.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/mbedtls.c index 7a552da..5fc879b 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/mbedtls.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/mbedtls.c @@ -28,7 +28,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MbedTLSLib_creat jmethodID init = (*env)->GetMethodID(env, local_provider_class, "", "(Ljava/lang/String;DLjava/lang/String;)V"); jstring name = (*env)->NewStringUTF(env, MBEDTLS_VERSION_STRING_FULL); - double version = MBEDTLS_VERSION_MAJOR + (MBEDTLS_VERSION_MINOR/10) + (MBEDTLS_VERSION_PATCH/100); + double version = MBEDTLS_VERSION_MAJOR + ((double)MBEDTLS_VERSION_MINOR/10) + ((double)MBEDTLS_VERSION_PATCH/100); return (*env)->NewObject(env, provider_class, init, name, version, name); } diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c index 23f28ca..ec107b8 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c @@ -5,8 +5,10 @@ #include "native.h" #include #include +#include #include + static prng_state ltc_prng; static jclass provider_class; @@ -18,7 +20,9 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_crea jmethodID init = (*env)->GetMethodID(env, local_provider_class, "", "(Ljava/lang/String;DLjava/lang/String;)V"); jstring name = (*env)->NewStringUTF(env, "libtomcrypt " SCRYPT); + char *locale = setlocale(LC_NUMERIC, "C"); double version = strtod(SCRYPT, NULL); + setlocale(LC_NUMERIC, locale); return (*env)->NewObject(env, provider_class, init, name, version, name); } -- cgit v1.3.1 From e9eda520476df1d06502fd184d4c53ffbcb2886c Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 5 Aug 2024 14:15:28 +0200 Subject: Allow for control over deterministic/randomized test-runs in reader. --- .../cz/crcs/ectester/reader/ECTesterReader.java | 62 +++++++++--------- .../ectester/reader/output/TextTestWriter.java | 3 +- .../ectester/reader/test/CardCofactorSuite.java | 11 ++-- .../ectester/reader/test/CardCompositeSuite.java | 11 +--- .../ectester/reader/test/CardCompressionSuite.java | 3 +- .../ectester/reader/test/CardDefaultSuite.java | 2 +- .../ectester/reader/test/CardDegenerateSuite.java | 6 +- .../ectester/reader/test/CardEdgeCasesSuite.java | 8 ++- .../ectester/reader/test/CardInvalidSuite.java | 4 +- .../crcs/ectester/reader/test/CardMiscSuite.java | 2 +- .../ectester/reader/test/CardSignatureSuite.java | 2 +- .../crcs/ectester/reader/test/CardTestSuite.java | 73 +++++++++++++--------- .../ectester/reader/test/CardTestVectorSuite.java | 2 +- .../crcs/ectester/reader/test/CardTwistSuite.java | 4 +- .../crcs/ectester/reader/test/CardWrongSuite.java | 4 +- 15 files changed, 101 insertions(+), 96 deletions(-) diff --git a/reader/src/main/java/cz/crcs/ectester/reader/ECTesterReader.java b/reader/src/main/java/cz/crcs/ectester/reader/ECTesterReader.java index 91f4653..6f624a0 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/ECTesterReader.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/ECTesterReader.java @@ -69,7 +69,7 @@ public class ECTesterReader { public static final String VERSION = "v0.3.3"; public static String GIT_COMMIT = ""; private static String DESCRIPTION; - private static String LICENSE = "MIT Licensed\nCopyright © 2016-2019 Petr Svenda \nCopyright © 2016-2019 Jan Jancar "; + private static String LICENSE = "MIT Licensed\nCopyright © 2016-2024 Petr Svenda \nCopyright © 2016-2024 Jan Jancar "; private static String CLI_HEADER; private static String CLI_FOOTER = "\n" + LICENSE; @@ -86,13 +86,15 @@ public class ECTesterReader { ClassLoader cl = ECTesterReader.class.getClassLoader(); try { URL url = cl.getResource("META-INF/MANIFEST.MF"); - Manifest manifest = new Manifest(url.openStream()); - String commit = manifest.getMainAttributes().getValue("Git-Commit"); - GIT_COMMIT = (commit == null) ? "" : "(git " + commit + ")"; + if (url != null) { + Manifest manifest = new Manifest(url.openStream()); + String commit = manifest.getMainAttributes().getValue("Git-Commit"); + GIT_COMMIT = (commit == null) ? "" : "(git " + commit + ")"; + } } catch (Exception ignored) { } - DESCRIPTION = "ECTesterReader " + VERSION + GIT_COMMIT + ", a javacard Elliptic Curve Cryptography support tester/utility."; + DESCRIPTION = "ECTesterReader " + VERSION + GIT_COMMIT + ", a JavaCard Elliptic Curve Cryptography tester/utility."; CLI_HEADER = "\n" + DESCRIPTION + "\n\n"; } @@ -338,10 +340,11 @@ public class ECTesterReader { opts.addOption(Option.builder("f").longOpt("fresh").desc("Generate fresh keys (set domain parameters before every generation).").build()); opts.addOption(Option.builder().longOpt("time").desc("Output better timing values, by running command in dry run mode and normal mode, and subtracting the two.").build()); opts.addOption(Option.builder().longOpt("time-unit").desc("Use given time unit in measurement, one of: milli, micro, nano.").hasArg().argName("unit").build()); - opts.addOption(Option.builder().longOpt("cleanup").desc("Send the cleanup command trigerring JCSystem.requestObjectDeletion() after some operations.").build()); + opts.addOption(Option.builder().longOpt("cleanup").desc("Send the cleanup command triggering JCSystem.requestObjectDeletion() after some operations.").build()); opts.addOption(Option.builder("s").longOpt("simulate").desc("Simulate a card with jcardsim instead of using a terminal.").build()); opts.addOption(Option.builder("y").longOpt("yes").desc("Accept all warnings and prompts.").build()); - opts.addOption(Option.builder("to").longOpt("test-options").desc("Test options to use:\n- preset: Use preset semi-random private keys (derived from curve) instead of generating keypairs on the cards when the test needs one.\n- random: Use fully random private keys instead of generating keypairs.").hasArg().argName("options").build()); + opts.addOption(Option.builder("tk").longOpt("test-key").desc("Key setup technique to use in test suites:\n- generate (default): Generate keypairs on the card.\n- deterministic: Prepare keypairs deterministically off-card.\n- random: Prepare keypairs randomly off-card.").hasArg().argName("option").build()); + opts.addOption(Option.builder("td").longOpt("test-data").desc("Data setup technique to use in test suites:\n- random (default): Prepare data randomly off-card.\n- deterministic: Prepare data deterministically off-card.").hasArg().argName("option").build()); opts.addOption(Option.builder("ka").longOpt("ka-type").desc("Set KeyAgreement object [type], corresponds to JC.KeyAgreement constants.").hasArg().argName("type").optionalArg(true).build()); opts.addOption(Option.builder("sig").longOpt("sig-type").desc("Set Signature object [type], corresponds to JC.Signature constants.").hasArg().argName("type").optionalArg(true).build()); @@ -370,9 +373,6 @@ public class ECTesterReader { for (String line : suite.getDescription()) { System.out.println("\t" + line); } - if (suite.getOptions() != null) { - System.out.println("\t" + Colors.underline("Options:") + " " + Arrays.toString(suite.getOptions())); - } } System.out.println(); System.out.println("For more information, look at the documentation at https://github.com/crocs-muni/ECTester."); @@ -380,13 +380,13 @@ public class ECTesterReader { private void info() throws CardException { Response.GetInfo info = new Command.GetInfo(cardManager).send(); - System.out.println(String.format("Card ATR:\t\t\t\t%s", ByteUtil.bytesToHex(cardManager.getATR().getBytes(), false))); - System.out.println(String.format("Card protocol:\t\t\t\t%s", cardManager.getProtocol())); - System.out.println(String.format("ECTester applet version:\t\t%s", info.getVersion())); - System.out.println(String.format("ECTester applet APDU support:\t\t%s", (info.getBase() == CardConsts.BASE_221) ? "basic" : "extended length")); - System.out.println(String.format("JavaCard API version:\t\t\t%.1f", info.getJavaCardVersion())); - System.out.println(String.format("JavaCard supports system cleanup:\t%s", info.getCleanupSupport())); - System.out.println(String.format("Array sizes (apduBuf,ram,ram2,apduArr):\t%d %d %d %d", info.getApduBufferLength(), info.getRamArrayLength(), info.getRamArray2Length(), info.getApduArrayLength())); + System.out.printf("Card ATR:\t\t\t\t%s%n", ByteUtil.bytesToHex(cardManager.getATR().getBytes(), false)); + System.out.printf("Card protocol:\t\t\t\t%s%n", cardManager.getProtocol()); + System.out.printf("ECTester applet version:\t\t%s%n", info.getVersion()); + System.out.printf("ECTester applet APDU support:\t\t%s%n", (info.getBase() == CardConsts.BASE_221) ? "basic" : "extended length"); + System.out.printf("JavaCard API version:\t\t\t%.1f%n", info.getJavaCardVersion()); + System.out.printf("JavaCard supports system cleanup:\t%s%n", info.getCleanupSupport()); + System.out.printf("Array sizes (apduBuf,ram,ram2,apduArr):\t%d %d %d %d%n", info.getApduBufferLength(), info.getRamArrayLength(), info.getRamArray2Length(), info.getApduArrayLength()); } /** @@ -866,7 +866,8 @@ public class ECTesterReader { public byte ECKAType = EC_Consts.KeyAgreement_ALG_EC_SVDP_DH; public int ECDSACount; public byte ECDSAType = EC_Consts.Signature_ALG_ECDSA_SHA; - public Set testOptions; + public String testKeySetup; + public String testDataSetup; /** * Reads and validates options, also sets defaults. @@ -1044,25 +1045,20 @@ public class ECTesterReader { testSuite = selected; } - String[] opts = cli.getOptionValue("test-options", "").split(","); - List validOpts = Arrays.asList("preset", "random"); - testOptions = new HashSet<>(); - for (String opt : opts) { - if (opt.equals("")) { - continue; - } - if (!validOpts.contains(opt)) { - System.err.println(Colors.error("Unknown test option " + opt + ". Should be one of: " + Arrays.toString(validOpts.toArray()))); - return false; - } else { - testOptions.add(opt); - } + testKeySetup = cli.getOptionValue("test-key", "generate"); + List testKeyOpts = Arrays.asList("generate", "deterministic", "random"); + if (!testKeyOpts.contains(testKeySetup)) { + System.err.println(Colors.error("Unknown test option " + testKeySetup + ". Should be one of: " + Arrays.toString(testKeyOpts.toArray()))); + return false; } - if (testOptions.contains("preset") && testOptions.contains("random")) { - System.err.println("Cannot have both preset and random option enabled."); + testDataSetup = cli.getOptionValue("test-data", "random"); + List testDataOpts = Arrays.asList("deterministic", "random"); + if (!testDataOpts.contains(testDataSetup)) { + System.err.println(Colors.error("Unknown test option " + testDataSetup + ". Should be one of: " + Arrays.toString(testDataOpts.toArray()))); return false; } + } else if (cli.hasOption("ecdh")) { if (primeField == binaryField) { System.err.print(Colors.error("Need to specify field with -fp or -f2m. (not both)")); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/output/TextTestWriter.java b/reader/src/main/java/cz/crcs/ectester/reader/output/TextTestWriter.java index 532ace5..3ba5431 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/output/TextTestWriter.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -52,7 +52,8 @@ public class TextTestWriter extends BaseTextTestWriter { sb.append("═══ ").append(Colors.underline("Card ATR:")).append(" ").append(ByteUtil.bytesToHex(cardSuite.getCard().getATR().getBytes(), false)).append(System.lineSeparator()); sb.append("═══ ").append(Colors.underline("JavaCard version:")).append(" ").append(info.getJavaCardVersion()).append(System.lineSeparator()); sb.append("═══ ").append(Colors.underline("Array sizes (apduBuf, ram, ram2, apduArr):")).append(" ").append(String.format("%d %d %d %d", info.getApduBufferLength(), info.getRamArrayLength(), info.getRamArray2Length(), info.getApduArrayLength())).append(System.lineSeparator()); - sb.append("═══ ").append(Colors.underline("Test options:")).append(" ").append(String.join(",", cardSuite.getCfg().testOptions)).append(System.lineSeparator()); + sb.append("═══ ").append(Colors.underline("Test key setup:")).append(" ").append(cardSuite.getCfg().testKeySetup).append(System.lineSeparator()); + sb.append("═══ ").append(Colors.underline("Test data setup:")).append(" ").append(cardSuite.getCfg().testDataSetup).append(System.lineSeparator()); CardMngr.CPLC cplc = cardSuite.getCard().getCPLC(); if (!cplc.values().isEmpty()) { sb.append("═══ ").append(Colors.underline("Card CPLC data:")).append(System.lineSeparator()); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCofactorSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCofactorSuite.java index 01e9d02..b0ad2d3 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCofactorSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCofactorSuite.java @@ -5,7 +5,6 @@ import cz.crcs.ectester.common.ec.EC_Key; import cz.crcs.ectester.common.ec.EC_Consts; import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.CompoundTest; -import cz.crcs.ectester.common.test.Result; import cz.crcs.ectester.common.test.Test; import cz.crcs.ectester.common.util.CardUtil; import cz.crcs.ectester.common.util.CardConsts; @@ -25,7 +24,7 @@ import static cz.crcs.ectester.common.test.Result.ExpectedValue; */ public class CardCofactorSuite extends CardTestSuite { public CardCofactorSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { - super(writer, cfg, cardManager, "cofactor", new String[]{"preset", "random"}, "The cofactor test suite tests whether the card correctly rejects points on the curve", + super(writer, cfg, cardManager, "cofactor", "The cofactor test suite tests whether the card correctly rejects points on the curve", "but not in the subgroup generated by the generator(so of small order, dividing the cofactor) during ECDH."); } @@ -45,12 +44,12 @@ public class CardCofactorSuite extends CardTestSuite { List ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Test setPub = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Result.ExpectedValue.FAILURE); - Test ecdh = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_REMOTE, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.FAILURE); - Test objectEcdh = CompoundTest.any(Result.ExpectedValue.SUCCESS, CardUtil.getKATypeString(EC_Consts.KeyAgreement_ALG_EC_SVDP_DH) + " test with cofactor pubkey.", setPub, ecdh); + Test setPub = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), ExpectedValue.FAILURE); + Test ecdh = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_REMOTE, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), ExpectedValue.FAILURE); + Test objectEcdh = CompoundTest.any(ExpectedValue.SUCCESS, CardUtil.getKATypeString(EC_Consts.KeyAgreement_ALG_EC_SVDP_DH) + " test with cofactor pubkey.", setPub, ecdh); Command ecdhCommand = new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); Test rawEcdh = CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on non-generator subgroup.", "Card incorrectly accepted point on non-generator subgroup."); - ecdhTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " cofactor key test.", objectEcdh, rawEcdh)); + ecdhTests.add(CompoundTest.all(ExpectedValue.SUCCESS, pub.getId() + " cofactor key test.", objectEcdh, rawEcdh)); } Test ecdh = CompoundTest.all(ExpectedValue.SUCCESS, "Perform ECDH with public points on non-generator subgroup.", ecdhTests.toArray(new Test[0])); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompositeSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompositeSuite.java index bba211a..71890e1 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompositeSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompositeSuite.java @@ -6,7 +6,6 @@ import cz.crcs.ectester.common.ec.EC_Consts; import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.CompoundTest; import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.common.util.CardUtil; import cz.crcs.ectester.common.util.CardConsts; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; @@ -25,7 +24,7 @@ import static cz.crcs.ectester.common.test.Result.ExpectedValue; public class CardCompositeSuite extends CardTestSuite { public CardCompositeSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { - super(writer, cfg, cardManager, "composite", new String[]{"preset", "random"}, "The composite suite runs ECDH over curves with composite order.", + super(writer, cfg, cardManager, "composite", "The composite suite runs ECDH over curves with composite order.", "Various types of compositeness is tested: smooth numbers, Carmichael pseudo-prime, prime square, product of two large primes."); } @@ -39,19 +38,13 @@ public class CardCompositeSuite extends CardTestSuite { Test allocate = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_LOCAL, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY); - String name; - if (cfg.testOptions.contains("preset")) { - name = "preset semi-random private key"; - } else { - name = "generated private key"; - } Test setKeypair = setupKeypairs(curve, ExpectedValue.ANY, CardConsts.KEYPAIR_LOCAL); Test prepare = CompoundTest.all(ExpectedValue.SUCCESS, "Prepare keypair on " + curve.getId() + ".", allocate, set, setKeypair); for (EC_Key key : curveKeys.getValue()) { Command ecdhCommand = new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); Test ecdh = CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key."); - tests.add(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", with " + name + ", " + key.getDesc(), ecdh)); + tests.add(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", with " + key.getDesc(), ecdh)); } Test ecdhTest = CompoundTest.all(ExpectedValue.SUCCESS, "Do ECDH.", tests.toArray(new Test[0])); doTest(CompoundTest.greedyAll(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ".", prepare, ecdhTest)); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java index 418ed2f..3598224 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java @@ -15,7 +15,6 @@ import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; import cz.crcs.ectester.reader.command.Command; -import cz.crcs.ectester.reader.response.Response; import java.security.spec.ECPoint; import java.util.LinkedList; @@ -79,7 +78,7 @@ public class CardCompressionSuite extends CardTestSuite { compressionTests.add(genCustom); EC_Curve secgCurve = EC_Store.getInstance().getObject(EC_Curve.class, "secg", CardUtil.getCurveName(curveId)); - ECPoint pub = ECUtil.toPoint(ECUtil.fixedRandomPoint(secgCurve)); + ECPoint pub = ECUtil.toPoint(preparePubkey(secgCurve)); List kaTests = new LinkedList<>(); for (byte kaType : EC_Consts.KA_TYPES) { diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardDefaultSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardDefaultSuite.java index c365d52..5ac8f1a 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardDefaultSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardDefaultSuite.java @@ -27,7 +27,7 @@ import static cz.crcs.ectester.common.test.Result.Value; public class CardDefaultSuite extends CardTestSuite { public CardDefaultSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { - super(writer, cfg, cardManager, "default", null, "The default test suite tests basic support and performance of ECDH and ECDSA."); + super(writer, cfg, cardManager, "default", "The default test suite tests basic support and performance of ECDH and ECDSA."); } @Override diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardDegenerateSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardDegenerateSuite.java index c731416..6817390 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardDegenerateSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardDegenerateSuite.java @@ -24,7 +24,7 @@ import java.util.Map; public class CardDegenerateSuite extends CardTestSuite { public CardDegenerateSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { - super(writer, cfg, cardManager, "degenerate", null, "The degenerate suite tests whether the card rejects points outside of the curve during ECDH.", + super(writer, cfg, cardManager, "degenerate", "The degenerate suite tests whether the card rejects points outside of the curve during ECDH.", "The tested points lie on a part of the plane for which some Edwards, Hessian and Huff form addition formulas degenerate into exponentiation in the base finite field."); } @@ -38,7 +38,7 @@ public class CardDegenerateSuite extends CardTestSuite { Test allocate = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS); - Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS); + Test generate = setupKeypairs(curve, Result.ExpectedValue.SUCCESS, CardConsts.KEYPAIR_LOCAL); Test prepare = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Prepare and generate keypair on " + curve.getId() + ".", allocate, set, generate); @@ -47,7 +47,7 @@ public class CardDegenerateSuite extends CardTestSuite { Test setPub = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Result.ExpectedValue.FAILURE); Test ecdh = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_REMOTE, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.FAILURE, "Card correctly rejected point on degenerate curve.", "Card incorrectly accepted point on degenerate curve."); Test objectEcdh = CompoundTest.any(Result.ExpectedValue.SUCCESS, CardUtil.getKATypeString(EC_Consts.KeyAgreement_ALG_EC_SVDP_DH) + " test with degenerate pubkey.", setPub, ecdh); - Command ecdhCommand = new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + Command ecdhCommand = new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); Test rawEcdh = CommandTest.expect(ecdhCommand, Result.ExpectedValue.FAILURE, "Card correctly rejected point on degenerate curve.", "Card incorrectly accepted point on degenerate curve."); ecdhTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " degenerate key test.", objectEcdh, rawEcdh)); //TODO: actually get the result of ECDH here, as well as export privkey and compare to exponentiation in Fp^*. diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java index fb24e30..00bc34e 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java @@ -26,7 +26,7 @@ import java.util.stream.Collectors; */ public class CardEdgeCasesSuite extends CardTestSuite { public CardEdgeCasesSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { - super(writer, cfg, cardManager, "edge-cases", null, "The edge-cases test suite tests various inputs to ECDH which may cause an implementation to achieve a certain edge-case state during it.", + super(writer, cfg, cardManager, "edge-cases", "The edge-cases test suite tests various inputs to ECDH which may cause an implementation to achieve a certain edge-case state during it.", "Some of the data is from the google/Wycheproof project. Tests include CVE-2017-10176 and CVE-2017-8932.", "Also tests values of the private key and public key that would trigger the OpenSSL modular multiplication bug on the P-256 curve.", "Various edge private key values are also tested."); @@ -141,11 +141,12 @@ public class CardEdgeCasesSuite extends CardTestSuite { List curves = curveMap.entrySet().stream().filter((e) -> e.getKey().endsWith("r1") && e.getValue().getField() == EC_Consts.ALG_EC_FP).map(Map.Entry::getValue).collect(Collectors.toList()); curves.add(EC_Store.getInstance().getObject(EC_Curve.class, "cofactor/cofactor128p2")); curves.add(EC_Store.getInstance().getObject(EC_Curve.class, "cofactor/cofactor160p4")); - Random rand = new Random(); + for (EC_Curve curve : curves) { + Random rand = setupRandom(curve); Test key = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), EC_Consts.ALG_EC_FP), Result.ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS); - Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS); + Test generate = setupKeypairs(curve, Result.ExpectedValue.SUCCESS, CardConsts.KEYPAIR_LOCAL); CommandTest export = CommandTest.expect(new Command.Export(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.KEY_PUBLIC, EC_Consts.PARAMETER_W), Result.ExpectedValue.SUCCESS); Test setup = CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPair setup.", key, set, generate, export); @@ -237,6 +238,7 @@ public class CardEdgeCasesSuite extends CardTestSuite { } EC_Curve secp160r1 = EC_Store.getInstance().getObject(EC_Curve.class, "secg/secp160r1"); + Random rand = setupRandom(secp160r1); byte[] pData = secp160r1.getParam(EC_Consts.PARAMETER_FP)[0]; BigInteger p = new BigInteger(1, pData); byte[] rData = secp160r1.getParam(EC_Consts.PARAMETER_R)[0]; diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardInvalidSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardInvalidSuite.java index 2fd457d..cacfba9 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardInvalidSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardInvalidSuite.java @@ -26,7 +26,7 @@ import static cz.crcs.ectester.common.test.Result.ExpectedValue; public class CardInvalidSuite extends CardTestSuite { public CardInvalidSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { - super(writer, cfg, cardManager, "invalid", null, "The invalid curve suite tests whether the card rejects points outside of the curve during ECDH."); + super(writer, cfg, cardManager, "invalid", "The invalid curve suite tests whether the card rejects points outside of the curve during ECDH."); } @Override @@ -42,7 +42,7 @@ public class CardInvalidSuite extends CardTestSuite { Test allocate = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS); - Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), ExpectedValue.SUCCESS); + Test generate = setupKeypairs(curve, Result.ExpectedValue.SUCCESS, CardConsts.KEYPAIR_LOCAL); Test prepare = CompoundTest.all(ExpectedValue.SUCCESS, "Prepare and generate keypair on " + curve.getId() + ".", allocate, set, generate); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardMiscSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardMiscSuite.java index 3ffe07c..38dcf80 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardMiscSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardMiscSuite.java @@ -24,7 +24,7 @@ import java.util.function.Function; public class CardMiscSuite extends CardTestSuite { public CardMiscSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { - super(writer, cfg, cardManager, "miscellaneous", new String[]{"preset", "random"}, "Some miscellaneous tests, tries ECDH and ECDSA over supersingular curves, anomalous curves,", + super(writer, cfg, cardManager, "miscellaneous", "Some miscellaneous tests, tries ECDH and ECDSA over supersingular curves, anomalous curves,", "Barreto-Naehrig curves with small embedding degree and CM discriminant, MNT curves,", "some Montgomery curves transformed to short Weierstrass form and Curve25519 transformed to short Weierstrass form."); } diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardSignatureSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardSignatureSuite.java index 086654a..0bf897a 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardSignatureSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardSignatureSuite.java @@ -22,7 +22,7 @@ import java.util.Map; */ public class CardSignatureSuite extends CardTestSuite { public CardSignatureSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { - super(writer, cfg, cardManager, "signature", null, "The signature test suite tests verifying various malformed and well-formed but invalid ECDSA signatures."); + super(writer, cfg, cardManager, "signature", "The signature test suite tests verifying various malformed and well-formed but invalid ECDSA signatures."); } @Override diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestSuite.java index 15c4469..af66a75 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestSuite.java @@ -14,7 +14,8 @@ import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; import cz.crcs.ectester.reader.command.Command; -import java.util.Arrays; +import java.nio.ByteBuffer; +import java.security.SecureRandom; /** * @author Jan Jancar johny@neuromancer.sk @@ -22,13 +23,11 @@ import java.util.Arrays; public abstract class CardTestSuite extends TestSuite { ECTesterReader.Config cfg; CardMngr card; - String[] options; - CardTestSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager, String name, String[] options, String... description) { + CardTestSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager, String name, String... description) { super(writer, name, description); this.card = cardManager; this.cfg = cfg; - this.options = options; } public CardMngr getCard() { @@ -39,34 +38,16 @@ public abstract class CardTestSuite extends TestSuite { return cfg; } - public String[] getOptions() { - if (options != null) { - return options.clone(); - } else { - return options; - } - } - - public Test setupKeypairs(EC_Curve curve, Result.ExpectedValue expected, byte keyPair) { - if ((Arrays.asList(options).contains("preset") && cfg.testOptions.contains("preset")) || (Arrays.asList(options).contains("random") && cfg.testOptions.contains("random"))) { + protected Test setupKeypairs(EC_Curve curve, Result.ExpectedValue expected, byte keyPair) { + if (cfg.testKeySetup.equals("deterministic") || cfg.testKeySetup.equals("random")) { Test setLocal = null; if ((keyPair & CardConsts.KEYPAIR_LOCAL) != 0) { - EC_Params priv; - if (cfg.testOptions.contains("preset")) { - priv = ECUtil.fixedRandomKey(curve); - } else { - priv = ECUtil.fullRandomKey(curve); - } + EC_Params priv = preparePrivkey(curve); setLocal = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.CURVE_external, priv.getParams(), priv.flatten()), expected); } Test setRemote = null; if ((keyPair & CardConsts.KEYPAIR_REMOTE) != 0) { - EC_Params pub; - if (cfg.testOptions.contains("preset")) { - pub = ECUtil.fixedRandomPoint(curve); - } else { - pub = ECUtil.fullRandomPoint(curve); - } + EC_Params pub = preparePubkey(curve); if (pub == null) { setRemote = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_REMOTE), expected); } else { @@ -80,15 +61,49 @@ public abstract class CardTestSuite extends TestSuite { return setRemote; } else { String desc; - if (cfg.testOptions.contains("preset")) { - desc = "Set semi-random parameters."; + if (cfg.testKeySetup.equals("deterministic")) { + desc = "Set deterministic parameters."; } else { desc = "Set fully-random parameters."; } - return CompoundTest.all(expected, desc, setLocal, setRemote); + return CompoundTest.all(Result.ExpectedValue.SUCCESS, desc, setLocal, setRemote); } } else { return CommandTest.expect(new Command.Generate(this.card, keyPair), expected); } } + + protected EC_Params preparePrivkey(EC_Curve curve) { + if (cfg.testKeySetup.equals("deterministic")) { + return ECUtil.fixedRandomKey(curve); + } else { + return ECUtil.fullRandomKey(curve); + } + } + + protected EC_Params preparePubkey(EC_Curve curve) { + if (cfg.testKeySetup.equals("deterministic")) { + return ECUtil.fixedRandomPoint(curve); + } else { + return ECUtil.fullRandomPoint(curve); + } + } + + protected SecureRandom setupRandom(EC_Curve curve) { + if (cfg.testDataSetup.equals("random")) { + return new SecureRandom(); + } else { + return new SecureRandom(ECUtil.hashCurve(curve)); + } + } + + protected SecureRandom setupRandom(int seed) { + if (cfg.testDataSetup.equals("random")) { + return new SecureRandom(); + } else { + ByteBuffer b = ByteBuffer.allocate(4); + b.putInt(seed); + return new SecureRandom(b.array()); + } + } } diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestVectorSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestVectorSuite.java index 4c222cb..28c5e12 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestVectorSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestVectorSuite.java @@ -40,7 +40,7 @@ import static cz.crcs.ectester.common.test.Result.Value; public class CardTestVectorSuite extends CardTestSuite { public CardTestVectorSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { - super(writer, cfg, cardManager, "test-vectors", null, "The test-vectors suite contains a collection of test vectors which test basic ECDH correctness."); + super(writer, cfg, cardManager, "test-vectors", "The test-vectors suite contains a collection of test vectors which test basic ECDH correctness."); } @Override diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTwistSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTwistSuite.java index ea127e0..6679f60 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTwistSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTwistSuite.java @@ -23,7 +23,7 @@ import java.util.Map; */ public class CardTwistSuite extends CardTestSuite { public CardTwistSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { - super(writer, cfg, cardManager, "twist", null, "The twist test suite tests whether the card correctly rejects points on the quadratic twist of the curve during ECDH."); + super(writer, cfg, cardManager, "twist", "The twist test suite tests whether the card correctly rejects points on the quadratic twist of the curve during ECDH."); } @Override @@ -36,7 +36,7 @@ public class CardTwistSuite extends CardTestSuite { Test allocate = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS); - Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS); + Test generate = setupKeypairs(curve, Result.ExpectedValue.SUCCESS, CardConsts.KEYPAIR_LOCAL); Test prepare = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Prepare and generate keypair on " + curve.getId() + ".", allocate, set, generate); diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java index 605b2ec..f24dabd 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java @@ -30,7 +30,7 @@ import static cz.crcs.ectester.common.test.Result.ExpectedValue; public class CardWrongSuite extends CardTestSuite { public CardWrongSuite(TestWriter writer, ECTesterReader.Config cfg, CardMngr cardManager) { - super(writer, cfg, cardManager, "wrong", new String[]{"preset", "random"}, "The wrong curve suite tests whether the card rejects domain parameters which are not curves."); + super(writer, cfg, cardManager, "wrong", "The wrong curve suite tests whether the card rejects domain parameters which are not curves."); } @Override @@ -72,9 +72,9 @@ public class CardWrongSuite extends CardTestSuite { * - p is a composite q * s with q, s primes * - TODO: p divides discriminant */ - Random r = new Random(); for (short keyLength : EC_Consts.FP_SIZES) { byte curve = EC_Consts.getCurve(keyLength, EC_Consts.ALG_EC_FP); + Random r = setupRandom(curve); Test key = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, EC_Consts.ALG_EC_FP), ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, curve, EC_Consts.PARAMETERS_DOMAIN_FP, null), ExpectedValue.SUCCESS); Test setup = CompoundTest.all(ExpectedValue.SUCCESS, "KeyPair setup.", key, set); -- cgit v1.3.1 From 09f3ebfbae5ea8ca0c22542309af1837cc58a699 Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 5 Aug 2024 14:24:06 +0200 Subject: Add output tests to reader. --- .../src/test/java/cz/crcs/ectester/reader/OutputTests.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 reader/src/test/java/cz/crcs/ectester/reader/OutputTests.java diff --git a/reader/src/test/java/cz/crcs/ectester/reader/OutputTests.java b/reader/src/test/java/cz/crcs/ectester/reader/OutputTests.java new file mode 100644 index 0000000..5300e98 --- /dev/null +++ b/reader/src/test/java/cz/crcs/ectester/reader/OutputTests.java @@ -0,0 +1,13 @@ +package cz.crcs.ectester.reader; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class OutputTests { + + @ParameterizedTest + @ValueSource(strings = {"text", "xml", "yml"}) + public void formats(String format) { + ECTesterReader.main(new String[]{"-t", "default", "-s", "-o", String.format("%s:out.%s", format, format),}); + } +} -- cgit v1.3.1 From 46b290eb6d24cd0d337d54421c8e10c9acbd6a6f Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 5 Aug 2024 15:43:22 +0200 Subject: Add support for deterministic PRNG to OpenSSL. --- .../ectester/standalone/ECTesterStandalone.java | 42 ++++- .../crcs/ectester/standalone/libs/OpensslLib.java | 6 + .../standalone/libs/ProviderECLibrary.java | 15 +- .../cz/crcs/ectester/standalone/libs/jni/native.h | 183 +-------------------- .../cz/crcs/ectester/standalone/libs/jni/openssl.c | 53 ++++++ 5 files changed, 120 insertions(+), 179 deletions(-) diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java index 4f76639..7967bcb 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -191,7 +191,8 @@ public class ECTesterStandalone { Option output = Option.builder("o").longOpt("output").desc("Output into file . The file can be prefixed by the format (one of text,yml,xml), such as: xml:.").hasArgs().argName("output_file").optionalArg(false).numberOfArgs(1).build(); Option outputRaw = Option.builder("o").longOpt("output").desc("Output CSV into file .").hasArgs().argName("output_file").optionalArg(false).numberOfArgs(1).build(); Option quiet = Option.builder("q").longOpt("quiet").desc("Do not output to stdout.").build(); - Option timeSource = Option.builder("ts").longOpt("time-source").desc("Use a given native timing source: {rdtsc, monotonic, monotonic-raw, cputime-process, cputime-thread, perfcount}").hasArgs().argName("source").optionalArg(false).numberOfArgs(1).build(); + Option timeSource = Option.builder("ts").longOpt("time-source").desc("Use a given native timing source: {rdtsc, monotonic, monotonic-raw, cputime-process, cputime-thread}").hasArgs().argName("source").optionalArg(false).numberOfArgs(1).build(); + Option prngSeed = Option.builder("ps").longOpt("prng-seed").desc("Use a deterministic PRNG with the given seed (hexadecimal).").hasArgs().argName("seed").optionalArg(false).numberOfArgs(1).build(); Options testOpts = new Options(); testOpts.addOption(bits); @@ -199,6 +200,7 @@ public class ECTesterStandalone { testOpts.addOption(curveName); testOpts.addOption(output); testOpts.addOption(quiet); + testOpts.addOption(prngSeed); testOpts.addOption(Option.builder("gt").longOpt("kpg-type").desc("Set the KeyPairGenerator object [type].").hasArg().argName("type").optionalArg(false).build()); testOpts.addOption(Option.builder("kt").longOpt("ka-type").desc("Set the KeyAgreement object [type].").hasArg().argName("type").optionalArg(false).build()); testOpts.addOption(Option.builder("st").longOpt("sig-type").desc("Set the Signature object [type].").hasArg().argName("type").optionalArg(false).build()); @@ -215,6 +217,7 @@ public class ECTesterStandalone { ecdhOpts.addOption(curveName); ecdhOpts.addOption(outputRaw); ecdhOpts.addOption(timeSource); + ecdhOpts.addOption(prngSeed); ecdhOpts.addOption(Option.builder("t").longOpt("type").desc("Set KeyAgreement object [type].").hasArg().argName("type").optionalArg(false).build()); ecdhOpts.addOption(Option.builder().longOpt("key-type").desc("Set the key [algorithm] for which the key should be derived in KeyAgreements with KDF. Default is \"AES\".").hasArg().argName("algorithm").optionalArg(false).build()); ecdhOpts.addOption(Option.builder("n").longOpt("amount").hasArg().argName("amount").optionalArg(false).desc("Do ECDH [amount] times.").build()); @@ -231,6 +234,7 @@ public class ECTesterStandalone { ecdsaOpts.addOption(curveName); ecdsaOpts.addOption(outputRaw); ecdsaOpts.addOption(timeSource); + ecdsaOpts.addOption(prngSeed); ecdsaOpts.addOptionGroup(privateKey); ecdsaOpts.addOptionGroup(publicKey); ecdsaOpts.addOption(Option.builder().longOpt("fixed").desc("Perform all ECDSA with fixed keypair.").build()); @@ -246,6 +250,7 @@ public class ECTesterStandalone { generateOpts.addOption(curveName); generateOpts.addOption(outputRaw); generateOpts.addOption(timeSource); + generateOpts.addOption(prngSeed); generateOpts.addOption(Option.builder("n").longOpt("amount").hasArg().argName("amount").optionalArg(false).desc("Generate [amount] of EC keys.").build()); generateOpts.addOption(Option.builder("t").longOpt("type").hasArg().argName("type").optionalArg(false).desc("Set KeyPairGenerator object [type].").build()); ParserOptions generate = new ParserOptions(new DefaultParser(), generateOpts, "Generate EC keypairs."); @@ -307,6 +312,7 @@ public class ECTesterStandalone { System.out.println(Colors.bold("\t\t- Fullname: ") + lib.getProvider().getName()); System.out.println(Colors.bold("\t\t- Version: ") + lib.getProvider().getVersionStr()); System.out.println(Colors.bold("\t\t- Supports native timing: ") + lib.getNativeTimingSupport().toString()); + System.out.println(Colors.bold("\t\t- Supports deterministic PRNG: ") + lib.supportsDeterministicPRNG()); Set kpgs = lib.getKPGs(); if (!kpgs.isEmpty()) { System.out.println(Colors.bold("\t\t- KeyPairGenerators: ") + kpgs.stream().map(KeyPairGeneratorIdent::getName).sorted().collect(Collectors.joining(", "))); @@ -430,6 +436,12 @@ public class ECTesterStandalone { kpg.initialize(spec); } + if (cli.hasOption("ecdh.prng-seed")) { + String seedString = cli.getOptionValue("ecdh.prng-seed"); + byte[] seed = ByteUtil.hexToBytes(seedString, true); + lib.setupDeterministicPRNG(seed); + } + if (cli.hasOption("ecdh.time-source")) { if (!lib.setNativeTimingType(cli.getOptionValue("ecdh.time-source"))) { System.err.println("Couldn't set native time source."); @@ -586,6 +598,12 @@ public class ECTesterStandalone { kpg.initialize(new ECGenParameterSpec(curveName)); } + if (cli.hasOption("ecdsa.prng-seed")) { + String seedString = cli.getOptionValue("ecdsa.prng-seed"); + byte[] seed = ByteUtil.hexToBytes(seedString, true); + lib.setupDeterministicPRNG(seed); + } + if (cli.hasOption("ecdsa.time-source")) { if (!lib.setNativeTimingType(cli.getOptionValue("ecdsa.time-source"))) { System.err.println("Couldn't set native time source."); @@ -722,6 +740,12 @@ public class ECTesterStandalone { kpg.initialize(new ECGenParameterSpec(curveName)); } + if (cli.hasOption("generate.prng-seed")) { + String seedString = cli.getOptionValue("generate.prng-seed"); + byte[] seed = ByteUtil.hexToBytes(seedString, true); + lib.setupDeterministicPRNG(seed); + } + if (cli.hasOption("generate.time-source")) { if (!lib.setNativeTimingType(cli.getOptionValue("generate.time-source"))) { System.err.println("Couldn't set native time source."); @@ -818,6 +842,13 @@ public class ECTesterStandalone { testTo = -1; } + ProviderECLibrary lib = cfg.selected; + if (cli.hasOption("test.prng-seed")) { + String seedString = cli.getOptionValue("test.prng-seed"); + byte[] seed = ByteUtil.hexToBytes(seedString, true); + lib.setupDeterministicPRNG(seed); + } + switch (testSuite) { case "test-vectors": suite = new StandaloneTestVectorSuite(writer, cfg, cli); @@ -997,6 +1028,15 @@ public class ECTesterStandalone { } } + if (cli.isNext("generate") || cli.isNext("ecdh") || cli.isNext("ecdsa") || cli.isNext("test")) { + if (cli.hasOption(next + ".prng-seed")) { + if (!selected.supportsDeterministicPRNG()) { + System.err.printf("Deterministic PRNG is not supported by library %s.%n", selected.name()); + return false; + } + } + } + return true; } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/OpensslLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/OpensslLib.java index 61f00a4..13490f9 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/OpensslLib.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/OpensslLib.java @@ -16,4 +16,10 @@ public class OpensslLib extends NativeECLibrary { @Override public native Set getCurves(); + + @Override + public native boolean supportsDeterministicPRNG(); + + @Override + public native void setupDeterministicPRNG(byte[] seed); } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/ProviderECLibrary.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/ProviderECLibrary.java index d9d6749..936120f 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/ProviderECLibrary.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/ProviderECLibrary.java @@ -69,21 +69,28 @@ public abstract class ProviderECLibrary implements ECLibrary { } public boolean setNativeTimingType(String type) { - return false; + return false; } public long getNativeTimingResolution() { return 0; } - public String getNativeTimingUnit() { - return null; - } + public String getNativeTimingUnit() { + return null; + } public long getLastNativeTiming() { return 0; } + public boolean supportsDeterministicPRNG() { + return false; + } + + public void setupDeterministicPRNG(byte[] seed) { + } + @Override public Set getKAs() { return getIdents("KeyAgreement", KeyAgreementIdent::get); diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h index 60c59b1..89f4b63 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h @@ -617,186 +617,21 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_creat JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_getCurves (JNIEnv *, jobject); -#ifdef __cplusplus -} -#endif -#endif -/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl */ - -#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl -#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl -#ifdef __cplusplus -extern "C" { -#endif -#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID 1421746759512286392LL -#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_MAX_ARRAY_SIZE -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_MAX_ARRAY_SIZE 2147483639L -#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_KEYS -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_KEYS 0L -#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_VALUES -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_VALUES 1L -#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_ENTRIES -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_ENTRIES 2L -#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID 4112578634029874840LL -#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID -4298000515446427739LL -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl - * Method: setup - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Openssl_setup - (JNIEnv *, jobject); - -#ifdef __cplusplus -} -#endif -#endif -/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl */ - -#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl -#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl -#ifdef __cplusplus -extern "C" { -#endif -#undef cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl_DEFAULT_KEYSIZE -#define cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl_DEFAULT_KEYSIZE 256L /* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl - * Method: keysizeSupported - * Signature: (I)Z - */ -JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_keysizeSupported - (JNIEnv *, jobject, jint); - -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl - * Method: paramsSupported - * Signature: (Ljava/security/spec/AlgorithmParameterSpec;)Z - */ -JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_paramsSupported - (JNIEnv *, jobject, jobject); - -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl - * Method: generate - * Signature: (ILjava/security/SecureRandom;)Ljava/security/KeyPair; - */ -JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_generate__ILjava_security_SecureRandom_2 - (JNIEnv *, jobject, jint, jobject); - -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl - * Method: generate - * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)Ljava/security/KeyPair; - */ -JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2 - (JNIEnv *, jobject, jobject, jobject); - -#ifdef __cplusplus -} -#endif -#endif -/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Openssl */ - -#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Openssl -#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Openssl -#ifdef __cplusplus -extern "C" { -#endif -#ifdef __cplusplus -} -#endif -#endif -/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Openssl */ - -#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Openssl -#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Openssl -#ifdef __cplusplus -extern "C" { -#endif -#ifdef __cplusplus -} -#endif -#endif -/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Openssl */ - -#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Openssl -#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Openssl -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Openssl - * Method: generateSecret - * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B - */ -JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Openssl_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2 - (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject); - -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Openssl - * Method: generateSecret - * Signature: ([B[BLjava/security/spec/ECParameterSpec;Ljava/lang/String;)Ljavax/crypto/SecretKey; - */ -JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Openssl_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2Ljava_lang_String_2 - (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject, jstring); - -#ifdef __cplusplus -} -#endif -#endif -/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl */ - -#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl -#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl - * Method: sign - * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B - */ -JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Openssl_sign - (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject); - -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl - * Method: verify - * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z - */ -JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Openssl_verify - (JNIEnv *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject); - -#ifdef __cplusplus -} -#endif -#endif -/* Header for class cz_crcs_ectester_standalone_libs_MscngLib */ - -#ifndef _Included_cz_crcs_ectester_standalone_libs_MscngLib -#define _Included_cz_crcs_ectester_standalone_libs_MscngLib -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: cz_crcs_ectester_standalone_libs_MscngLib - * Method: createProvider - * Signature: ()Ljava/security/Provider; + * Class: cz_crcs_ectester_standalone_libs_OpensslLib + * Method: supportsDeterministicPRNG + * Signature: ()Z */ -JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_createProvider +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_supportsDeterministicPRNG (JNIEnv *, jobject); /* - * Class: cz_crcs_ectester_standalone_libs_MscngLib - * Method: getCurves - * Signature: ()Ljava/util/Set; + * Class: cz_crcs_ectester_standalone_libs_OpensslLib + * Method: setupDeterministicPRNG + * Signature: ([B)V */ -JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_getCurves - (JNIEnv *, jobject); +JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_setupDeterministicPRNG + (JNIEnv *, jobject, jbyteArray); #ifdef __cplusplus } diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/openssl.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/openssl.c index 59eb0db..d791646 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/openssl.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/openssl.c @@ -14,6 +14,7 @@ #include #include #include +#include @@ -69,6 +70,58 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_getCu return result; } +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_supportsDeterministicPRNG(JNIEnv *env, jobject self) { + return JNI_TRUE; +} + +static int stdlib_rand_seed(const void *buf, int num) +{ + unsigned int s = 0; + for (int i = 0; i < num && i < sizeof(unsigned int); ++i) { + s |= ((unsigned char*)buf)[i] << 8*i; + } + srand(s); + return 1; +} + +// Fill the buffer with random bytes. For each byte in the buffer, we generate +// a random number and clamp it to the range of a byte, 0-255. +static int stdlib_rand_bytes(unsigned char *buf, int num) +{ + for (int index = 0; index < num; ++index) + { + buf[index] = rand() % 256; + } + return 1; +} + +static void stdlib_rand_cleanup() {} +static int stdlib_rand_add(const void *buf, int num, double add_entropy) +{ + return 1; +} +static int stdlib_rand_status() +{ + return 1; +} + +RAND_METHOD stdlib_rand_meth = { stdlib_rand_seed, + stdlib_rand_bytes, + stdlib_rand_cleanup, + stdlib_rand_add, + stdlib_rand_bytes, + stdlib_rand_status +}; + +JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_setupDeterministicPRNG(JNIEnv *env, jobject self, jbyteArray seed) { + printf("Enabling rand method.\n"); + RAND_set_rand_method(&stdlib_rand_meth); + jbyte *seed_data = (*env)->GetByteArrayElements(env, seed, NULL); + jsize seed_length = (*env)->GetArrayLength(env, seed); + RAND_seed(seed_data, seed_length); + (*env)->ReleaseByteArrayElements(env, seed, seed_data, JNI_ABORT); +} + JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_keysizeSupported(JNIEnv *env, jobject self, jint keysize) { size_t ncurves = EC_get_builtin_curves(NULL, 0); EC_builtin_curve curves[ncurves]; -- cgit v1.3.1 From a3af2abefa537d570c4018729465abf32444fe15 Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 5 Aug 2024 16:13:11 +0200 Subject: Add deterministic PRNG support to tomcrypt. --- .../crcs/ectester/standalone/libs/TomcryptLib.java | 6 + .../cz/crcs/ectester/standalone/libs/jni/native.h | 158 ++------------------- .../cz/crcs/ectester/standalone/libs/jni/openssl.c | 1 - .../crcs/ectester/standalone/libs/jni/tomcrypt.c | 15 ++ 4 files changed, 31 insertions(+), 149 deletions(-) diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/TomcryptLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/TomcryptLib.java index 8c000a2..1897617 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/TomcryptLib.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/TomcryptLib.java @@ -17,4 +17,10 @@ public class TomcryptLib extends NativeECLibrary { @Override public native Set getCurves(); + + @Override + public native boolean supportsDeterministicPRNG(); + + @Override + public native void setupDeterministicPRNG(byte[] seed); } diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h index 89f4b63..68e96c8 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h @@ -74,159 +74,21 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_crea JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_getCurves (JNIEnv *, jobject); -#ifdef __cplusplus -} -#endif -#endif -/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt */ - -#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt -#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt -#ifdef __cplusplus -extern "C" { -#endif -#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID 1421746759512286392LL -#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_MAX_ARRAY_SIZE -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_MAX_ARRAY_SIZE 2147483639L -#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_KEYS -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_KEYS 0L -#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_VALUES -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_VALUES 1L -#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_ENTRIES -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_ENTRIES 2L -#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID 4112578634029874840LL -#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID -4298000515446427739LL -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt - * Method: setup - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024TomCrypt_setup - (JNIEnv *, jobject); - -#ifdef __cplusplus -} -#endif -#endif -/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt */ - -#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt -#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt -#ifdef __cplusplus -extern "C" { -#endif -#undef cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt_DEFAULT_KEYSIZE -#define cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt_DEFAULT_KEYSIZE 256L -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt - * Method: keysizeSupported - * Signature: (I)Z - */ -JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024TomCrypt_keysizeSupported - (JNIEnv *, jobject, jint); - -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt - * Method: paramsSupported - * Signature: (Ljava/security/spec/AlgorithmParameterSpec;)Z - */ -JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024TomCrypt_paramsSupported - (JNIEnv *, jobject, jobject); - -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt - * Method: generate - * Signature: (ILjava/security/SecureRandom;)Ljava/security/KeyPair; - */ -JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024TomCrypt_generate__ILjava_security_SecureRandom_2 - (JNIEnv *, jobject, jint, jobject); - /* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt - * Method: generate - * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)Ljava/security/KeyPair; - */ -JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024TomCrypt_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2 - (JNIEnv *, jobject, jobject, jobject); - -#ifdef __cplusplus -} -#endif -#endif -/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_TomCrypt */ - -#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_TomCrypt -#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_TomCrypt -#ifdef __cplusplus -extern "C" { -#endif -#ifdef __cplusplus -} -#endif -#endif -/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_TomCrypt */ - -#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_TomCrypt -#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_TomCrypt -#ifdef __cplusplus -extern "C" { -#endif -#ifdef __cplusplus -} -#endif -#endif -/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt */ - -#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt -#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt - * Method: generateSecret - * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B - */ -JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024TomCrypt_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2 - (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject); - -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt - * Method: generateSecret - * Signature: ([B[BLjava/security/spec/ECParameterSpec;Ljava/lang/String;)Ljavax/crypto/SecretKey; - */ -JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024TomCrypt_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2Ljava_lang_String_2 - (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject, jstring); - -#ifdef __cplusplus -} -#endif -#endif -/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw */ - -#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw -#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw - * Method: sign - * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B + * Class: cz_crcs_ectester_standalone_libs_TomcryptLib + * Method: supportsDeterministicPRNG + * Signature: ()Z */ -JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024TomCryptRaw_sign - (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject); +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_supportsDeterministicPRNG + (JNIEnv *, jobject); /* - * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw - * Method: verify - * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z + * Class: cz_crcs_ectester_standalone_libs_TomcryptLib + * Method: setupDeterministicPRNG + * Signature: ([B)V */ -JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024TomCryptRaw_verify - (JNIEnv *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject); +JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_setupDeterministicPRNG + (JNIEnv *, jobject, jbyteArray); #ifdef __cplusplus } diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/openssl.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/openssl.c index d791646..0b07821 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/openssl.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/openssl.c @@ -114,7 +114,6 @@ RAND_METHOD stdlib_rand_meth = { stdlib_rand_seed, }; JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_setupDeterministicPRNG(JNIEnv *env, jobject self, jbyteArray seed) { - printf("Enabling rand method.\n"); RAND_set_rand_method(&stdlib_rand_meth); jbyte *seed_data = (*env)->GetByteArrayElements(env, seed, NULL); jsize seed_length = (*env)->GetArrayLength(env, seed); diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c index ec107b8..6e9dfbf 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c @@ -76,6 +76,21 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_getC return result; } + +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_supportsDeterministicPRNG(JNIEnv *env, jobject self) { + return JNI_TRUE; +} + +JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_setupDeterministicPRNG(JNIEnv *env, jobject self, jbyteArray seed) { + yarrow_start(<c_prng); + jbyte *seed_data = (*env)->GetByteArrayElements(env, seed, NULL); + jsize seed_length = (*env)->GetArrayLength(env, seed); + yarrow_add_entropy(seed_data, seed_length, <c_prng); + yarrow_ready(<c_prng); + (*env)->ReleaseByteArrayElements(env, seed, seed_data, JNI_ABORT); +} + + JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024TomCrypt_keysizeSupported(JNIEnv *env, jobject this, jint keysize){ int key_bytes = (keysize + 7) / 8; const ltc_ecc_set_type * curve = ltc_ecc_sets; -- cgit v1.3.1 From 33a859073f34fab3843b80754de1a558d1b125f9 Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 5 Aug 2024 16:18:27 +0200 Subject: Fix messed up native header file. --- .../cz/crcs/ectester/standalone/libs/jni/native.h | 335 +++++++++++++++++++++ 1 file changed, 335 insertions(+) diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h index 68e96c8..b1296cc 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h @@ -90,6 +90,160 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_sup JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_setupDeterministicPRNG (JNIEnv *, jobject, jbyteArray); +#ifdef __cplusplus +} +#endif +#endif +/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt +#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt +#ifdef __cplusplus +extern "C" { +#endif +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID 1421746759512286392LL +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_MAX_ARRAY_SIZE +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_MAX_ARRAY_SIZE 2147483639L +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_KEYS +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_KEYS 0L +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_VALUES +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_VALUES 1L +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_ENTRIES +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_ENTRIES 2L +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID 4112578634029874840LL +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID -4298000515446427739LL +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt + * Method: setup + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024TomCrypt_setup + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif +/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt +#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt +#ifdef __cplusplus +extern "C" { +#endif +#undef cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt_DEFAULT_KEYSIZE +#define cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt_DEFAULT_KEYSIZE 256L +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt + * Method: keysizeSupported + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024TomCrypt_keysizeSupported + (JNIEnv *, jobject, jint); + +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt + * Method: paramsSupported + * Signature: (Ljava/security/spec/AlgorithmParameterSpec;)Z + */ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024TomCrypt_paramsSupported + (JNIEnv *, jobject, jobject); + +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt + * Method: generate + * Signature: (ILjava/security/SecureRandom;)Ljava/security/KeyPair; + */ +JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024TomCrypt_generate__ILjava_security_SecureRandom_2 + (JNIEnv *, jobject, jint, jobject); + +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_TomCrypt + * Method: generate + * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)Ljava/security/KeyPair; + */ +JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024TomCrypt_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2 + (JNIEnv *, jobject, jobject, jobject); + +#ifdef __cplusplus +} +#endif +#endif +/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_TomCrypt */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_TomCrypt +#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_TomCrypt +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif +/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_TomCrypt */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_TomCrypt +#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_TomCrypt +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif +/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt +#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt + * Method: generateSecret + * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B + */ +JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024TomCrypt_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2 + (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject); + +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt + * Method: generateSecret + * Signature: ([B[BLjava/security/spec/ECParameterSpec;Ljava/lang/String;)Ljavax/crypto/SecretKey; + */ +JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024TomCrypt_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2Ljava_lang_String_2 + (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject, jstring); + +#ifdef __cplusplus +} +#endif +#endif +/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw +#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw + * Method: sign + * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B + */ +JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024TomCryptRaw_sign + (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject); + +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_TomCryptRaw + * Method: verify + * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z + */ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024TomCryptRaw_verify + (JNIEnv *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject); + #ifdef __cplusplus } #endif @@ -495,6 +649,187 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_supp JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_setupDeterministicPRNG (JNIEnv *, jobject, jbyteArray); +#ifdef __cplusplus +} +#endif +#endif +/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl +#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl +#ifdef __cplusplus +extern "C" { +#endif +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID 1421746759512286392LL +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_MAX_ARRAY_SIZE +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_MAX_ARRAY_SIZE 2147483639L +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_KEYS +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_KEYS 0L +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_VALUES +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_VALUES 1L +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_ENTRIES +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_ENTRIES 2L +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID 4112578634029874840LL +#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID -4298000515446427739LL +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl + * Method: setup + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Openssl_setup + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif +/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl +#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl +#ifdef __cplusplus +extern "C" { +#endif +#undef cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl_DEFAULT_KEYSIZE +#define cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl_DEFAULT_KEYSIZE 256L +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl + * Method: keysizeSupported + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_keysizeSupported + (JNIEnv *, jobject, jint); + +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl + * Method: paramsSupported + * Signature: (Ljava/security/spec/AlgorithmParameterSpec;)Z + */ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_paramsSupported + (JNIEnv *, jobject, jobject); + +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl + * Method: generate + * Signature: (ILjava/security/SecureRandom;)Ljava/security/KeyPair; + */ +JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_generate__ILjava_security_SecureRandom_2 + (JNIEnv *, jobject, jint, jobject); + +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl + * Method: generate + * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)Ljava/security/KeyPair; + */ +JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2 + (JNIEnv *, jobject, jobject, jobject); + +#ifdef __cplusplus +} +#endif +#endif +/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Openssl */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Openssl +#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Openssl +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif +/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Openssl */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Openssl +#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Openssl +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif +/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Openssl */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Openssl +#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Openssl +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Openssl + * Method: generateSecret + * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B + */ +JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Openssl_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2 + (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject); + +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Openssl + * Method: generateSecret + * Signature: ([B[BLjava/security/spec/ECParameterSpec;Ljava/lang/String;)Ljavax/crypto/SecretKey; + */ +JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Openssl_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2Ljava_lang_String_2 + (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject, jstring); + +#ifdef __cplusplus +} +#endif +#endif +/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl +#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl + * Method: sign + * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B + */ +JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Openssl_sign + (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject); + +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Openssl + * Method: verify + * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z + */ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Openssl_verify + (JNIEnv *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject); + +#ifdef __cplusplus +} +#endif +#endif +/* Header for class cz_crcs_ectester_standalone_libs_MscngLib */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_MscngLib +#define _Included_cz_crcs_ectester_standalone_libs_MscngLib +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: cz_crcs_ectester_standalone_libs_MscngLib + * Method: createProvider + * Signature: ()Ljava/security/Provider; + */ +JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_createProvider + (JNIEnv *, jobject); + +/* + * Class: cz_crcs_ectester_standalone_libs_MscngLib + * Method: getCurves + * Signature: ()Ljava/util/Set; + */ +JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_getCurves + (JNIEnv *, jobject); + #ifdef __cplusplus } #endif -- cgit v1.3.1 From abb89ea702d046e27ea457df31a7d69bab3b0802 Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 5 Aug 2024 17:50:11 +0200 Subject: Add deterministic PRNG to Botan. --- .../ectester/standalone/ECTesterStandalone.java | 20 +++++++-- .../cz/crcs/ectester/standalone/libs/BotanLib.java | 6 +++ .../crcs/ectester/standalone/libs/OpensslLib.java | 2 +- .../standalone/libs/ProviderECLibrary.java | 3 +- .../crcs/ectester/standalone/libs/TomcryptLib.java | 2 +- .../cz/crcs/ectester/standalone/libs/jni/Makefile | 4 +- .../cz/crcs/ectester/standalone/libs/jni/botan.cpp | 47 ++++++++++++++++------ .../cz/crcs/ectester/standalone/libs/jni/native.h | 24 +++++++++-- .../cz/crcs/ectester/standalone/libs/jni/openssl.c | 3 +- .../crcs/ectester/standalone/libs/jni/tomcrypt.c | 3 +- 10 files changed, 86 insertions(+), 28 deletions(-) diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java index 7967bcb..3194796 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -439,7 +439,10 @@ public class ECTesterStandalone { if (cli.hasOption("ecdh.prng-seed")) { String seedString = cli.getOptionValue("ecdh.prng-seed"); byte[] seed = ByteUtil.hexToBytes(seedString, true); - lib.setupDeterministicPRNG(seed); + if (!lib.setupDeterministicPRNG(seed)) { + System.err.println("Couldn't set PRNG seed."); + return; + } } if (cli.hasOption("ecdh.time-source")) { @@ -601,7 +604,10 @@ public class ECTesterStandalone { if (cli.hasOption("ecdsa.prng-seed")) { String seedString = cli.getOptionValue("ecdsa.prng-seed"); byte[] seed = ByteUtil.hexToBytes(seedString, true); - lib.setupDeterministicPRNG(seed); + if (!lib.setupDeterministicPRNG(seed)) { + System.err.println("Couldn't set PRNG seed."); + return; + } } if (cli.hasOption("ecdsa.time-source")) { @@ -743,7 +749,10 @@ public class ECTesterStandalone { if (cli.hasOption("generate.prng-seed")) { String seedString = cli.getOptionValue("generate.prng-seed"); byte[] seed = ByteUtil.hexToBytes(seedString, true); - lib.setupDeterministicPRNG(seed); + if (!lib.setupDeterministicPRNG(seed)) { + System.err.println("Couldn't set PRNG seed."); + return; + } } if (cli.hasOption("generate.time-source")) { @@ -846,7 +855,10 @@ public class ECTesterStandalone { if (cli.hasOption("test.prng-seed")) { String seedString = cli.getOptionValue("test.prng-seed"); byte[] seed = ByteUtil.hexToBytes(seedString, true); - lib.setupDeterministicPRNG(seed); + if (!lib.setupDeterministicPRNG(seed)) { + System.err.println("Couldn't set PRNG seed."); + return; + } } switch (testSuite) { diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/BotanLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/BotanLib.java index e8f6e13..c072e84 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/BotanLib.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/BotanLib.java @@ -17,4 +17,10 @@ public class BotanLib extends NativeECLibrary { @Override public native Set getCurves(); + + @Override + public native boolean supportsDeterministicPRNG(); + + @Override + public native boolean setupDeterministicPRNG(byte[] seed); } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/OpensslLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/OpensslLib.java index 13490f9..69c84bc 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/OpensslLib.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/OpensslLib.java @@ -21,5 +21,5 @@ public class OpensslLib extends NativeECLibrary { public native boolean supportsDeterministicPRNG(); @Override - public native void setupDeterministicPRNG(byte[] seed); + public native boolean setupDeterministicPRNG(byte[] seed); } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/ProviderECLibrary.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/ProviderECLibrary.java index 936120f..a9178f6 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/ProviderECLibrary.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/ProviderECLibrary.java @@ -88,7 +88,8 @@ public abstract class ProviderECLibrary implements ECLibrary { return false; } - public void setupDeterministicPRNG(byte[] seed) { + public boolean setupDeterministicPRNG(byte[] seed) { + return false; } @Override diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/TomcryptLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/TomcryptLib.java index 1897617..e499451 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/TomcryptLib.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/TomcryptLib.java @@ -22,5 +22,5 @@ public class TomcryptLib extends NativeECLibrary { public native boolean supportsDeterministicPRNG(); @Override - public native void setupDeterministicPRNG(byte[] seed); + public native boolean setupDeterministicPRNG(byte[] seed); } diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile index 6282574..aec0c03 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile @@ -12,9 +12,9 @@ DEBUG ?= 0 PROJECT_ROOT_PATH ?= ../../../../../../../../../.. ifeq ($(DEBUG), 1) - CFLAGS+=-g -Wall + CFLAGS+=-g -O0 -Wall LFLAGS+=-g - CXXFLAGS+=-g -Wall + CXXFLAGS+=-g -O0 -Wall else CFLAGS+=-O2 LFLAGS+=-O2 diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp index 52c8dbb..b3977e1 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp @@ -4,7 +4,9 @@ #include #include #include +#include #include +#include #include #include @@ -23,7 +25,7 @@ */ static jclass provider_class; -static Botan::AutoSeeded_RNG rng; +std::unique_ptr rng = std::make_unique(); JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_createProvider(JNIEnv *env, jobject self) { /* Create the custom provider. */ @@ -82,7 +84,7 @@ JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_ init_classes(env, "Botan"); } -JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_getCurves(JNIEnv *env, jobject self){ +JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_getCurves(JNIEnv *env, jobject self) { jclass set_class = env->FindClass("java/util/TreeSet"); jmethodID set_ctr = env->GetMethodID(set_class, "", "()V"); @@ -99,6 +101,25 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_getCurv return result; } +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_supportsDeterministicPRNG(JNIEnv *env, jobject self) { + return JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_setupDeterministicPRNG(JNIEnv *env, jobject self, jbyteArray seed) { + jsize seed_length = env->GetArrayLength(seed); + if (seed_length < 32) { + fprintf(stderr, "Error setting seed, needs to be at least 32 bytes.\n"); + return JNI_FALSE; + } + jbyte *seed_data = env->GetByteArrayElements(seed, nullptr); + Botan::secure_vector vec((uint8_t *)seed_data, (uint8_t *)seed_data + seed_length); + Botan::ChaCha_RNG *cha = new Botan::ChaCha_RNG(vec); + rng.reset(cha); + env->ReleaseByteArrayElements(seed, seed_data, JNI_ABORT); + return JNI_TRUE; +} + + JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Botan_keysizeSupported(JNIEnv *env, jobject self, jint keysize){ return JNI_TRUE; } @@ -252,13 +273,13 @@ static jobject generate_from_group(JNIEnv* env, jobject self, Botan::EC_Group gr try { native_timing_start(); if (type_str == "ECDH") { - skey = std::make_unique(rng, group); + skey = std::make_unique(*rng, group); } else if (type_str == "ECDSA") { - skey = std::make_unique(rng, group); + skey = std::make_unique(*rng, group); } else if (type_str == "ECKCDSA") { - skey = std::make_unique(rng, group); + skey = std::make_unique(*rng, group); } else if (type_str == "ECGDSA") { - skey = std::make_unique(rng, group); + skey = std::make_unique(*rng, group); } native_timing_stop(); } catch (Botan::Exception & ex) { @@ -375,7 +396,7 @@ jbyteArray generate_secret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteAr Botan::BigInt privkey_scalar((unsigned char *) privkey_data, privkey_length); env->ReleaseByteArrayElements(privkey, privkey_data, JNI_ABORT); - Botan::ECDH_PrivateKey skey(rng, curve_group, privkey_scalar); + Botan::ECDH_PrivateKey skey(*rng, curve_group, privkey_scalar); jsize pubkey_length = env->GetArrayLength(pubkey); jbyte *pubkey_data = env->GetByteArrayElements(pubkey, nullptr); @@ -402,7 +423,7 @@ jbyteArray generate_secret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteAr size_t key_len = (get_kdf_bits(env, algorithm) + 7) / 8; std::string kdf = get_kdf(type_str, &key_len); - Botan::PK_Key_Agreement ka(skey, rng, kdf); + Botan::PK_Key_Agreement ka(skey, *rng, kdf); std::vector derived; try { @@ -469,11 +490,11 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig std::unique_ptr skey; try { if (type_str.find("ECDSA") != std::string::npos) { - skey = std::make_unique(rng, curve_group, privkey_scalar); + skey = std::make_unique(*rng, curve_group, privkey_scalar); } else if (type_str.find("ECKCDSA") != std::string::npos) { - skey = std::make_unique(rng, curve_group, privkey_scalar); + skey = std::make_unique(*rng, curve_group, privkey_scalar); } else if (type_str.find("ECGDSA") != std::string::npos) { - skey = std::make_unique(rng, curve_group, privkey_scalar); + skey = std::make_unique(*rng, curve_group, privkey_scalar); } } catch (Botan::Exception & ex) { throw_new(env, "java/security/GeneralSecurityException", ex.what()); @@ -504,10 +525,10 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig jbyte *data_bytes = env->GetByteArrayElements(data, nullptr); std::vector sig; try { - Botan::PK_Signer signer(*skey, rng, emsa, sigformat); + Botan::PK_Signer signer(*skey, *rng, emsa, sigformat); native_timing_start(); - sig = signer.sign_message((uint8_t*) data_bytes, data_length, rng); + sig = signer.sign_message((uint8_t*) data_bytes, data_length, *rng); native_timing_stop(); } catch (Botan::Exception & ex) { throw_new(env, "java/security/GeneralSecurityException", ex.what()); diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h index b1296cc..49be801 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h @@ -85,9 +85,9 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_sup /* * Class: cz_crcs_ectester_standalone_libs_TomcryptLib * Method: setupDeterministicPRNG - * Signature: ([B)V + * Signature: ([B)Z */ -JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_setupDeterministicPRNG +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_setupDeterministicPRNG (JNIEnv *, jobject, jbyteArray); #ifdef __cplusplus @@ -271,6 +271,22 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_createP JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_getCurves (JNIEnv *, jobject); +/* + * Class: cz_crcs_ectester_standalone_libs_BotanLib + * Method: supportsDeterministicPRNG + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_supportsDeterministicPRNG + (JNIEnv *, jobject); + +/* + * Class: cz_crcs_ectester_standalone_libs_BotanLib + * Method: setupDeterministicPRNG + * Signature: ([B)Z + */ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_setupDeterministicPRNG + (JNIEnv *, jobject, jbyteArray); + #ifdef __cplusplus } #endif @@ -644,9 +660,9 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_supp /* * Class: cz_crcs_ectester_standalone_libs_OpensslLib * Method: setupDeterministicPRNG - * Signature: ([B)V + * Signature: ([B)Z */ -JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_setupDeterministicPRNG +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_setupDeterministicPRNG (JNIEnv *, jobject, jbyteArray); #ifdef __cplusplus diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/openssl.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/openssl.c index 0b07821..5110c8b 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/openssl.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/openssl.c @@ -113,12 +113,13 @@ RAND_METHOD stdlib_rand_meth = { stdlib_rand_seed, stdlib_rand_status }; -JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_setupDeterministicPRNG(JNIEnv *env, jobject self, jbyteArray seed) { +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_setupDeterministicPRNG(JNIEnv *env, jobject self, jbyteArray seed) { RAND_set_rand_method(&stdlib_rand_meth); jbyte *seed_data = (*env)->GetByteArrayElements(env, seed, NULL); jsize seed_length = (*env)->GetArrayLength(env, seed); RAND_seed(seed_data, seed_length); (*env)->ReleaseByteArrayElements(env, seed, seed_data, JNI_ABORT); + return JNI_TRUE; } JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_keysizeSupported(JNIEnv *env, jobject self, jint keysize) { diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c index 6e9dfbf..12c1936 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c @@ -81,13 +81,14 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_sup return JNI_TRUE; } -JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_setupDeterministicPRNG(JNIEnv *env, jobject self, jbyteArray seed) { +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_setupDeterministicPRNG(JNIEnv *env, jobject self, jbyteArray seed) { yarrow_start(<c_prng); jbyte *seed_data = (*env)->GetByteArrayElements(env, seed, NULL); jsize seed_length = (*env)->GetArrayLength(env, seed); yarrow_add_entropy(seed_data, seed_length, <c_prng); yarrow_ready(<c_prng); (*env)->ReleaseByteArrayElements(env, seed, seed_data, JNI_ABORT); + return JNI_TRUE; } -- cgit v1.3.1 From 231e33a8bfd352574ef999c4e91f28c5e8551bdf Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 6 Aug 2024 19:58:50 +0200 Subject: Simplify KeyAgreementTestable. --- .../standalone/test/base/KeyAgreementTestable.java | 176 +++++++++++---------- .../test/suites/StandaloneCofactorSuite.java | 2 +- .../test/suites/StandaloneCompositeSuite.java | 4 +- .../test/suites/StandaloneDefaultSuite.java | 4 +- .../test/suites/StandaloneEdgeCasesSuite.java | 6 +- .../test/suites/StandaloneForeignSuite.java | 2 +- .../test/suites/StandaloneMiscSuite.java | 2 +- .../test/suites/StandalonePerformanceSuite.java | 4 +- .../test/suites/StandaloneTestVectorSuite.java | 2 +- .../test/suites/StandaloneWrongSuite.java | 4 +- 10 files changed, 107 insertions(+), 99 deletions(-) diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyAgreementTestable.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyAgreementTestable.java index 579904c..308ade7 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyAgreementTestable.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyAgreementTestable.java @@ -5,6 +5,7 @@ import javax.crypto.SecretKey; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import java.security.spec.AlgorithmParameterSpec; @@ -21,90 +22,20 @@ public class KeyAgreementTestable extends StandaloneTestable() { @Override public Result apply(KeyAgreementTestable testable) { @@ -247,7 +247,7 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite { private Test ecdhTest(KeyGeneratorTestable kgt, BigInteger SParam, ECParameterSpec spec, String desc, Result.ExpectedValue expect) throws NoSuchAlgorithmException { ECPrivateKey priv = new RawECPrivateKey(SParam, spec); KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = new KeyAgreementTestable(ka, kgt, priv); + KeyAgreementTestable testable = KeyAgreementTestable.builder().ka(ka).privateKey(priv).publicKgt(kgt).build(); return CompoundTest.all(Result.ExpectedValue.SUCCESS, desc, KeyAgreementTest.expectError(testable, expect)); } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java index 21431ae..2139233 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java @@ -156,7 +156,7 @@ public abstract class StandaloneForeignSuite extends StandaloneTestSuite { for (EC_Key.Public pub : keys) { ECPublicKey ecpub = ECUtil.toPublicKey(pub); KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpub, theKgt); + KeyAgreementTestable testable = KeyAgreementTestable.builder().ka(ka).publicKey(ecpub).privateKgt(theKgt).build(); Test keyAgreement = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE); specificKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " invalid key test.", keyAgreement)); } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java index 657c2ff..801b2ca 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java @@ -88,7 +88,7 @@ public class StandaloneMiscSuite extends StandaloneTestSuite { for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) { if (kaAlgo == null || kaIdent.containsAny(kaTypes)) { KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = new KeyAgreementTestable(ka, kgt, kgt); + KeyAgreementTestable testable = KeyAgreementTestable.builder().ka(ka).publicKgt(kgt).privateKgt(kgt).build(); kaTests.add(KeyAgreementTest.expectError(testable, expected)); } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java index 30a0c0f..8127e6d 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java @@ -94,9 +94,9 @@ public class StandalonePerformanceSuite extends StandaloneTestSuite { KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); KeyAgreementTestable testable; if (kaIdent.requiresKeyAlgo()) { - testable = new KeyAgreementTestable(ka, kgtOne, kgtOther, spec, keyAlgo); + testable = KeyAgreementTestable.builder().ka(ka).privateKgt(kgtOne).publicKgt(kgtOther).spec(spec).keyAlgo(keyAlgo).build(); } else { - testable = new KeyAgreementTestable(ka, kgtOne, kgtOther, spec); + testable = KeyAgreementTestable.builder().ka(ka).privateKgt(kgtOne).publicKgt(kgtOther).spec(spec).build(); } kaTests.add(PerformanceTest.repeat(testable, cfg.selected, kaIdent.getName(), count)); } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestVectorSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestVectorSuite.java index 111d354..7faae99 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestVectorSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestVectorSuite.java @@ -56,7 +56,7 @@ public class StandaloneTestVectorSuite extends StandaloneTestSuite { KeyAgreementIdent kaIdent = KeyAgreementIdent.get("ECDH"); KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = new KeyAgreementTestable(ka, privkey, pubkey); + KeyAgreementTestable testable = KeyAgreementTestable.builder().ka(ka).privateKey(privkey).publicKey(pubkey).build(); doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Test vector " + result.getId(), KeyAgreementTest.match(testable, result.getData(0)))); } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java index 4634ab0..1990f22 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java @@ -77,7 +77,7 @@ public class StandaloneWrongSuite extends StandaloneTestSuite { Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = new KeyAgreementTestable(ka, kgt, kgt); + KeyAgreementTestable testable = KeyAgreementTestable.builder().ka(ka).privateKgt(kgt).publicKgt(kgt).build(); Test ecdh = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE); doTest(CompoundTest.function(CompoundTest.EXPECT_ALL_SUCCESS, CompoundTest.RUN_ALL_IF_FIRST, "Wrong curve test of " + curve.getBits() + "b " + type + ". " + curve.getDesc(), generate, ecdh)); @@ -238,7 +238,7 @@ public class StandaloneWrongSuite extends StandaloneTestSuite { //perform ECDH KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = new KeyAgreementTestable(ka, kgt, kgt); + KeyAgreementTestable testable = KeyAgreementTestable.builder().ka(ka).privateKgt(kgt).publicKgt(kgt).build(); Test ecdh = KeyAgreementTest.expect(testable, Result.ExpectedValue.FAILURE); return CompoundTest.function(CompoundTest.EXPECT_ALL_SUCCESS, CompoundTest.RUN_ALL_IF_FIRST, desc, generate, ecdh); } -- cgit v1.3.1 From 9b1b1a6f6da1e4c8429ba1632103d276f3cbdaad Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 6 Aug 2024 20:25:35 +0200 Subject: Cleanup KeyGeneratorTestable. --- .../standalone/test/base/KeyGeneratorTestable.java | 68 +++++++++++++++++++++- .../test/suites/StandaloneDefaultSuite.java | 12 ++-- .../test/suites/StandaloneEdgeCasesSuite.java | 4 +- .../test/suites/StandaloneForeignSuite.java | 6 +- .../test/suites/StandaloneMiscSuite.java | 2 +- .../test/suites/StandalonePerformanceSuite.java | 12 ++-- .../test/suites/StandaloneWrongSuite.java | 4 +- 7 files changed, 86 insertions(+), 22 deletions(-) diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTestable.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTestable.java index bc44eb8..8865576 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTestable.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTestable.java @@ -3,6 +3,7 @@ package cz.crcs.ectester.standalone.test.base; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.KeyPairGenerator; +import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; @@ -15,11 +16,23 @@ public class KeyGeneratorTestable extends StandaloneTestable() { @Override public Result apply(KeyAgreementTestable testable) { @@ -134,7 +134,7 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite { ECParameterSpec spec = curve.toSpec(); //generate KeyPair - KeyGeneratorTestable kgt = KeyGeneratorTestable.builder().keyPairGenerator(kpg).spec(spec).build(); + KeyGeneratorTestable kgt = KeyGeneratorTestable.builder().keyPairGenerator(kpg).spec(spec).random(getRandom()).build(); Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); //perform ECDH tests @@ -213,7 +213,7 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite { Arrays.sort(zeros); //generate KeyPair - KeyGeneratorTestable kgt = KeyGeneratorTestable.builder().keyPairGenerator(kpg).spec(spec).build(); + KeyGeneratorTestable kgt = KeyGeneratorTestable.builder().keyPairGenerator(kpg).spec(spec).random(getRandom()).build(); Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); //perform ECDH tests @@ -247,7 +247,7 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite { private Test ecdhTest(KeyGeneratorTestable kgt, BigInteger SParam, ECParameterSpec spec, String desc, Result.ExpectedValue expect) throws NoSuchAlgorithmException { ECPrivateKey priv = new RawECPrivateKey(SParam, spec); KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = KeyAgreementTestable.builder().ka(ka).privateKey(priv).publicKgt(kgt).build(); + KeyAgreementTestable testable = KeyAgreementTestable.builder().ka(ka).privateKey(priv).publicKgt(kgt).random(getRandom()).build(); return CompoundTest.all(Result.ExpectedValue.SUCCESS, desc, KeyAgreementTest.expectError(testable, expect)); } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java index 5385fa2..da5d19a 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java @@ -57,9 +57,9 @@ public abstract class StandaloneForeignSuite extends StandaloneTestSuite { ECParameterSpec spec = curve.toSpec(); ECGenParameterSpec namedSpec = new ECGenParameterSpec(curve.getId()); - KeyGeneratorTestable kgt = KeyGeneratorTestable.builder().keyPairGenerator(kpg).spec(spec).build(); - KeyGeneratorTestable kgtOnNamedCurve = KeyGeneratorTestable.builder().keyPairGenerator(kpg).spec(namedSpec).build(); - KeyGeneratorTestable kgtOnDefaultCurve = KeyGeneratorTestable.builder().keyPairGenerator(kpg).keysize(curve.getBits()).build(); + KeyGeneratorTestable kgt = KeyGeneratorTestable.builder().keyPairGenerator(kpg).random(getRandom()).spec(spec).build(); + KeyGeneratorTestable kgtOnNamedCurve = KeyGeneratorTestable.builder().keyPairGenerator(kpg).random(getRandom()).spec(namedSpec).build(); + KeyGeneratorTestable kgtOnDefaultCurve = KeyGeneratorTestable.builder().keyPairGenerator(kpg).random(getRandom()).keysize(curve.getBits()).build(); // This is some nasty hacking... KeyGeneratorTestable theKgt = new KeyGeneratorTestable(kpg) { @@ -156,7 +156,7 @@ public abstract class StandaloneForeignSuite extends StandaloneTestSuite { for (EC_Key.Public pub : keys) { ECPublicKey ecpub = ECUtil.toPublicKey(pub); KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = KeyAgreementTestable.builder().ka(ka).publicKey(ecpub).privateKgt(theKgt).build(); + KeyAgreementTestable testable = KeyAgreementTestable.builder().ka(ka).publicKey(ecpub).privateKgt(theKgt).random(getRandom()).build(); Test keyAgreement = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE); specificKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " invalid key test.", keyAgreement)); } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java index d0d83e6..87ad0b3 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java @@ -81,7 +81,7 @@ public class StandaloneMiscSuite extends StandaloneTestSuite { private void testCurve(EC_Curve curve, String catName, KeyPairGenerator kpg, Result.ExpectedValue expected) throws NoSuchAlgorithmException { //generate KeyPair - KeyGeneratorTestable kgt = KeyGeneratorTestable.builder().keyPairGenerator(kpg).spec(curve.toSpec()).build(); + KeyGeneratorTestable kgt = KeyGeneratorTestable.builder().keyPairGenerator(kpg).spec(curve.toSpec()).random(getRandom()).build(); Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); //perform KeyAgreement tests @@ -89,7 +89,7 @@ public class StandaloneMiscSuite extends StandaloneTestSuite { for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) { if (kaAlgo == null || kaIdent.containsAny(kaTypes)) { KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = KeyAgreementTestable.builder().ka(ka).publicKgt(kgt).privateKgt(kgt).build(); + KeyAgreementTestable testable = KeyAgreementTestable.builder().ka(ka).publicKgt(kgt).privateKgt(kgt).random(getRandom()).build(); kaTests.add(KeyAgreementTest.expectError(testable, expected)); } } @@ -103,7 +103,7 @@ public class StandaloneMiscSuite extends StandaloneTestSuite { if (sigAlgo == null || sigIdent.containsAny(sigTypes)) { Signature sig = sigIdent.getInstance(cfg.selected.getProvider()); byte[] data = sigIdent.toString().getBytes(); - SignatureTestable testable = new SignatureTestable(sig, kgt, data, null); + SignatureTestable testable = new SignatureTestable(sig, kgt, data, getRandom()); sigTests.add(SignatureTest.expectError(testable, expected)); } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java index e3a5969..909b252 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java @@ -67,8 +67,8 @@ public class StandalonePerformanceSuite extends StandaloneTestSuite { KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider()); if (cli.hasOption("test.bits")) { int bits = Integer.parseInt(cli.getOptionValue("test.bits")); - kgtOne = KeyGeneratorTestable.builder().keyPairGenerator(kpg).keysize(bits).build(); - kgtOther = KeyGeneratorTestable.builder().keyPairGenerator(kpg).keysize(bits).build(); + kgtOne = KeyGeneratorTestable.builder().keyPairGenerator(kpg).keysize(bits).random(getRandom()).build(); + kgtOther = KeyGeneratorTestable.builder().keyPairGenerator(kpg).keysize(bits).random(getRandom()).build(); } else if (cli.hasOption("test.named-curve")) { String curveName = cli.getOptionValue("test.named-curve"); EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName); @@ -77,11 +77,11 @@ public class StandalonePerformanceSuite extends StandaloneTestSuite { return; } spec = curve.toSpec(); - kgtOne = KeyGeneratorTestable.builder().keyPairGenerator(kpg).spec(spec).build(); - kgtOther = KeyGeneratorTestable.builder().keyPairGenerator(kpg).spec(spec).build(); + kgtOne = KeyGeneratorTestable.builder().keyPairGenerator(kpg).spec(spec).random(getRandom()).build(); + kgtOther = KeyGeneratorTestable.builder().keyPairGenerator(kpg).spec(spec).random(getRandom()).build(); } else { - kgtOne = KeyGeneratorTestable.builder().keyPairGenerator(kpg).build(); - kgtOther = KeyGeneratorTestable.builder().keyPairGenerator(kpg).build(); + kgtOne = KeyGeneratorTestable.builder().keyPairGenerator(kpg).random(getRandom()).build(); + kgtOther = KeyGeneratorTestable.builder().keyPairGenerator(kpg).random(getRandom()).build(); } kpgTests.add(PerformanceTest.repeat(kgtOne, cfg.selected, kpgIdent.getName(), count)); kpgTests.add(PerformanceTest.repeat(kgtOther, cfg.selected, kpgIdent.getName(), count)); @@ -94,9 +94,9 @@ public class StandalonePerformanceSuite extends StandaloneTestSuite { KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); KeyAgreementTestable testable; if (kaIdent.requiresKeyAlgo()) { - testable = KeyAgreementTestable.builder().ka(ka).privateKgt(kgtOne).publicKgt(kgtOther).spec(spec).keyAlgo(keyAlgo).build(); + testable = KeyAgreementTestable.builder().ka(ka).privateKgt(kgtOne).publicKgt(kgtOther).spec(spec).random(getRandom()).keyAlgo(keyAlgo).build(); } else { - testable = KeyAgreementTestable.builder().ka(ka).privateKgt(kgtOne).publicKgt(kgtOther).spec(spec).build(); + testable = KeyAgreementTestable.builder().ka(ka).privateKgt(kgtOne).publicKgt(kgtOther).spec(spec).random(getRandom()).build(); } kaTests.add(PerformanceTest.repeat(testable, cfg.selected, kaIdent.getName(), count)); } @@ -112,11 +112,11 @@ public class StandalonePerformanceSuite extends StandaloneTestSuite { if (sigAlgo == null || sigIdent.containsAny(sigTypes)) { Signature sig = sigIdent.getInstance(cfg.selected.getProvider()); byte[] data = sigIdent.toString().getBytes(); - sigTests.add(PerformanceTest.repeat(new SignatureTestable(sig, kgtOne, data, null), cfg.selected, sigIdent.getName(), count)); + sigTests.add(PerformanceTest.repeat(new SignatureTestable(sig, kgtOne, data, getRandom()), cfg.selected, sigIdent.getName(), count)); // TODO: The following will always fail as a runTest is not done at this point. if (kgtOne.getKeyPair() != null) { ECPrivateKey signKey = (ECPrivateKey) kgtOne.getKeyPair().getPrivate(); - sigTestsNoVerification.add(PerformanceTest.repeat(new SignatureTestable(sig, signKey, null, data, null), cfg.selected, sigIdent.getName(), count)); + sigTestsNoVerification.add(PerformanceTest.repeat(new SignatureTestable(sig, signKey, null, data, getRandom()), cfg.selected, sigIdent.getName(), count)); } } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneSignatureSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneSignatureSuite.java index 81ed535..740dca7 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneSignatureSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneSignatureSuite.java @@ -65,7 +65,7 @@ public class StandaloneSignatureSuite extends StandaloneTestSuite { } Signature signature = sigIdent.getInstance(cfg.selected.getProvider()); - SignatureTestable testable = new SignatureTestable(signature, ecpub, data, sig.getData(0), null); + SignatureTestable testable = new SignatureTestable(signature, ecpub, data, sig.getData(0), getRandom()); doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "ECDSA test of " + sig.getId() + ".", SignatureTest.expectError(testable, expected))); } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java index ac164e1..284194c 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java @@ -3,6 +3,7 @@ package cz.crcs.ectester.standalone.test.suites; import cz.crcs.ectester.common.cli.TreeCommandLine; import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.TestSuite; +import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.standalone.ECTesterStandalone; import cz.crcs.ectester.standalone.consts.Ident; import cz.crcs.ectester.standalone.consts.KeyAgreementIdent; @@ -10,6 +11,7 @@ import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent; import cz.crcs.ectester.standalone.consts.SignatureIdent; import cz.crcs.ectester.standalone.libs.ProviderECLibrary; +import java.security.SecureRandom; import java.util.Optional; import java.util.Set; @@ -19,17 +21,34 @@ import java.util.Set; public abstract class StandaloneTestSuite extends TestSuite { TreeCommandLine cli; ECTesterStandalone.Config cfg; + SecureRandom random; + byte[] seed; public StandaloneTestSuite(TestWriter writer, ECTesterStandalone.Config cfg, TreeCommandLine cli, String name, String... description) { super(writer, name, description); this.cfg = cfg; this.cli = cli; + if (cli.hasOption("test.prng-seed")) { + String seedString = cli.getOptionValue("generate.prng-seed"); + this.seed = ByteUtil.hexToBytes(seedString, true); + } else { + seed = new SecureRandom().generateSeed(16); + } + this.random = new SecureRandom(seed); } public ProviderECLibrary getLibrary() { return cfg.selected; } + public byte[] getSeed() { + return seed; + } + + SecureRandom getRandom() { + return this.random; + } + private T getIdent(Set options, String choice, String identName, String defaultChoice) { T ident; if (choice == null) { diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestVectorSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestVectorSuite.java index 7faae99..1766953 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestVectorSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestVectorSuite.java @@ -56,7 +56,7 @@ public class StandaloneTestVectorSuite extends StandaloneTestSuite { KeyAgreementIdent kaIdent = KeyAgreementIdent.get("ECDH"); KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = KeyAgreementTestable.builder().ka(ka).privateKey(privkey).publicKey(pubkey).build(); + KeyAgreementTestable testable = KeyAgreementTestable.builder().ka(ka).privateKey(privkey).publicKey(pubkey).random(getRandom()).build(); doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Test vector " + result.getId(), KeyAgreementTest.match(testable, result.getData(0)))); } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java index dacaa15..fe954a8 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java @@ -73,11 +73,11 @@ public class StandaloneWrongSuite extends StandaloneTestSuite { String type = curve.getField() == javacard.security.KeyPair.ALG_EC_FP ? "FP" : "F2M"; //try generating a keypair - KeyGeneratorTestable kgt = KeyGeneratorTestable.builder().keyPairGenerator(kpg).spec(spec).build(); + KeyGeneratorTestable kgt = KeyGeneratorTestable.builder().keyPairGenerator(kpg).spec(spec).random(getRandom()).build(); Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY); KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = KeyAgreementTestable.builder().ka(ka).privateKgt(kgt).publicKgt(kgt).build(); + KeyAgreementTestable testable = KeyAgreementTestable.builder().ka(ka).privateKgt(kgt).publicKgt(kgt).random(getRandom()).build(); Test ecdh = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE); doTest(CompoundTest.function(CompoundTest.EXPECT_ALL_SUCCESS, CompoundTest.RUN_ALL_IF_FIRST, "Wrong curve test of " + curve.getBits() + "b " + type + ". " + curve.getDesc(), generate, ecdh)); @@ -233,12 +233,12 @@ public class StandaloneWrongSuite extends StandaloneTestSuite { private Test ecdhTest(ECParameterSpec spec, String desc) throws NoSuchAlgorithmException { //generate KeyPair - KeyGeneratorTestable kgt = KeyGeneratorTestable.builder().keyPairGenerator(kpg).spec(spec).build(); + KeyGeneratorTestable kgt = KeyGeneratorTestable.builder().keyPairGenerator(kpg).spec(spec).random(getRandom()).build(); Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.FAILURE); //perform ECDH KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider()); - KeyAgreementTestable testable = KeyAgreementTestable.builder().ka(ka).privateKgt(kgt).publicKgt(kgt).build(); + KeyAgreementTestable testable = KeyAgreementTestable.builder().ka(ka).privateKgt(kgt).publicKgt(kgt).random(getRandom()).build(); Test ecdh = KeyAgreementTest.expect(testable, Result.ExpectedValue.FAILURE); return CompoundTest.function(CompoundTest.EXPECT_ALL_SUCCESS, CompoundTest.RUN_ALL_IF_FIRST, desc, generate, ecdh); } -- cgit v1.3.1 From b8054933b3d07ef8bfc3bec56b2bb795c1d01e5e Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 7 Aug 2024 13:02:34 +0200 Subject: Add support for deterministic PRNG to SunEC and BouncyCastle. --- .../java/cz/crcs/ectester/common/util/Util.java | 23 ++++- .../crcs/ectester/reader/test/CardTestSuite.java | 5 +- .../ectester/standalone/ECTesterStandalone.java | 113 +++++++++++++-------- .../ectester/standalone/libs/BouncyCastleLib.java | 12 +++ .../cz/crcs/ectester/standalone/libs/SunECLib.java | 12 +++ .../test/suites/StandaloneEdgeCasesSuite.java | 2 +- .../test/suites/StandaloneTestSuite.java | 3 +- .../test/suites/StandaloneWrongSuite.java | 2 +- 8 files changed, 122 insertions(+), 50 deletions(-) diff --git a/common/src/main/java/cz/crcs/ectester/common/util/Util.java b/common/src/main/java/cz/crcs/ectester/common/util/Util.java index 5b0cd79..9e6daa2 100644 --- a/common/src/main/java/cz/crcs/ectester/common/util/Util.java +++ b/common/src/main/java/cz/crcs/ectester/common/util/Util.java @@ -1,5 +1,8 @@ package cz.crcs.ectester.common.util; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + /** * @author Jan Jancar johny@neuromancer.sk */ @@ -18,11 +21,25 @@ public class Util { public static int getVersion() { String version = System.getProperty("java.version"); - if(version.startsWith("1.")) { + if (version.startsWith("1.")) { version = version.substring(2, 3); } else { int dot = version.indexOf("."); - if(dot != -1) { version = version.substring(0, dot); } - } return Integer.parseInt(version); + if (dot != -1) { + version = version.substring(0, dot); + } + } + return Integer.parseInt(version); + } + + public static SecureRandom getRandom(byte[] seed) { + SecureRandom random; + try { + random = SecureRandom.getInstance("DRBG"); + } catch (NoSuchAlgorithmException ignored) { + return null; + } + random.setSeed(seed); + return random; } } diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestSuite.java index af66a75..e2d9dd1 100644 --- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestSuite.java +++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestSuite.java @@ -10,6 +10,7 @@ import cz.crcs.ectester.common.test.Test; import cz.crcs.ectester.common.test.TestSuite; import cz.crcs.ectester.common.util.CardConsts; import cz.crcs.ectester.common.util.ECUtil; +import cz.crcs.ectester.common.util.Util; import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.ECTesterReader; import cz.crcs.ectester.reader.command.Command; @@ -93,7 +94,7 @@ public abstract class CardTestSuite extends TestSuite { if (cfg.testDataSetup.equals("random")) { return new SecureRandom(); } else { - return new SecureRandom(ECUtil.hashCurve(curve)); + return Util.getRandom(ECUtil.hashCurve(curve)); } } @@ -103,7 +104,7 @@ public abstract class CardTestSuite extends TestSuite { } else { ByteBuffer b = ByteBuffer.allocate(4); b.putInt(seed); - return new SecureRandom(b.array()); + return Util.getRandom(b.array()); } } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java index 3194796..f358662 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -415,12 +415,26 @@ public class ECTesterStandalone { throw new NoSuchAlgorithmException(algo); } + SecureRandom random; + if (cli.hasOption("ecdh.prng-seed")) { + String seedString = cli.getOptionValue("ecdh.prng-seed"); + byte[] seed = ByteUtil.hexToBytes(seedString, true); + random = SecureRandom.getInstance("DRBG"); + random.setSeed(seed); + if (!lib.setupDeterministicPRNG(seed)) { + System.err.println("Couldn't set PRNG seed."); + return; + } + } else { + random = new SecureRandom(); + } + KeyAgreement ka = kaIdent.getInstance(lib.getProvider()); KeyPairGenerator kpg = kpIdent.getInstance(lib.getProvider()); AlgorithmParameterSpec spec = null; if (cli.hasOption("ecdh.bits")) { int bits = Integer.parseInt(cli.getOptionValue("ecdh.bits")); - kpg.initialize(bits); + kpg.initialize(bits, random); } else if (cli.hasOption("ecdh.named-curve")) { String curveName = cli.getOptionValue("ecdh.named-curve"); EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName); @@ -429,20 +443,15 @@ public class ECTesterStandalone { return; } spec = curve.toSpec(); - kpg.initialize(spec); + kpg.initialize(spec, random); } else if (cli.hasOption("ecdh.curve-name")) { String curveName = cli.getOptionValue("ecdh.curve-name"); spec = new ECGenParameterSpec(curveName); - kpg.initialize(spec); - } - - if (cli.hasOption("ecdh.prng-seed")) { - String seedString = cli.getOptionValue("ecdh.prng-seed"); - byte[] seed = ByteUtil.hexToBytes(seedString, true); - if (!lib.setupDeterministicPRNG(seed)) { - System.err.println("Couldn't set PRNG seed."); - return; - } + kpg.initialize(spec, random); + } else if (cli.hasOption("ecdh.prng-seed") && !(lib instanceof NativeECLibrary)) { + // TODO: This only happens if at least one of the (pubkey and privkey) needs to be generated. + System.err.println("Unable to pass PRNG seed to a non-native library without specifying either key-size, named curve or curve name options."); + return; } if (cli.hasOption("ecdh.time-source")) { @@ -498,9 +507,9 @@ public class ECTesterStandalone { long elapsed = -System.nanoTime(); if (spec instanceof ECParameterSpec && lib instanceof NativeECLibrary) { - ka.init(privkey, spec); + ka.init(privkey, spec, random); } else { - ka.init(privkey); + ka.init(privkey, random); } ka.doPhase(pubkey, true); elapsed += System.nanoTime(); @@ -534,6 +543,22 @@ public class ECTesterStandalone { * */ private void ecdsa() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IOException, SignatureException { + ProviderECLibrary lib = cfg.selected; + + SecureRandom random; + if (cli.hasOption("ecdsa.prng-seed")) { + String seedString = cli.getOptionValue("ecdsa.prng-seed"); + byte[] seed = ByteUtil.hexToBytes(seedString, true); + random = SecureRandom.getInstance("DRBG"); + random.setSeed(seed); + if (!lib.setupDeterministicPRNG(seed)) { + System.err.println("Couldn't set PRNG seed."); + return; + } + } else { + random = new SecureRandom(); + } + byte[] data; String dataString; if (cli.hasOption("ecdsa.file")) { @@ -546,12 +571,12 @@ public class ECTesterStandalone { data = Files.readAllBytes(in.toPath()); dataString = ""; } else { - Random random = new Random(); + Random dataRandom = new Random(); data = new byte[32]; - random.nextBytes(data); + dataRandom.nextBytes(data); dataString = ByteUtil.bytesToHex(data, false); } - ProviderECLibrary lib = cfg.selected; + String algo = cli.getOptionValue("ecdsa.type", "ECDSA"); SignatureIdent sigIdent = lib.getSigs().stream() .filter((ident) -> ident.contains(algo)) @@ -586,7 +611,7 @@ public class ECTesterStandalone { ECParameterSpec spec = null; if (cli.hasOption("ecdsa.bits")) { int bits = Integer.parseInt(cli.getOptionValue("ecdsa.bits")); - kpg.initialize(bits); + kpg.initialize(bits, random); } else if (cli.hasOption("ecdsa.named-curve")) { String curveName = cli.getOptionValue("ecdsa.named-curve"); EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName); @@ -595,19 +620,14 @@ public class ECTesterStandalone { return; } spec = curve.toSpec(); - kpg.initialize(spec); + kpg.initialize(spec, random); } else if (cli.hasOption("ecdsa.curve-name")) { String curveName = cli.getOptionValue("ecdsa.curve-name"); - kpg.initialize(new ECGenParameterSpec(curveName)); - } - - if (cli.hasOption("ecdsa.prng-seed")) { - String seedString = cli.getOptionValue("ecdsa.prng-seed"); - byte[] seed = ByteUtil.hexToBytes(seedString, true); - if (!lib.setupDeterministicPRNG(seed)) { - System.err.println("Couldn't set PRNG seed."); - return; - } + kpg.initialize(new ECGenParameterSpec(curveName), random); + } else if (cli.hasOption("ecdsa.prng-seed") && !(lib instanceof NativeECLibrary)) { + // TODO: This only happens if at least one of the (pubkey and privkey) needs to be generated. + System.err.println("Unable to pass PRNG seed to a non-native library without specifying either key-size, named curve or curve name options."); + return; } if (cli.hasOption("ecdsa.time-source")) { @@ -660,7 +680,7 @@ public class ECTesterStandalone { } } - sig.initSign(privkey); + sig.initSign(privkey, random); sig.update(data); long signTime = -System.nanoTime(); @@ -729,10 +749,25 @@ public class ECTesterStandalone { if (ident == null) { throw new NoSuchAlgorithmException(algo); } + + SecureRandom random; + if (cli.hasOption("generate.prng-seed")) { + String seedString = cli.getOptionValue("generate.prng-seed"); + byte[] seed = ByteUtil.hexToBytes(seedString, true); + random = SecureRandom.getInstance("DRBG"); + random.setSeed(seed); + if (!lib.setupDeterministicPRNG(seed)) { + System.err.println("Couldn't set PRNG seed."); + return; + } + } else { + random = new SecureRandom(); + } + KeyPairGenerator kpg = ident.getInstance(lib.getProvider()); if (cli.hasOption("generate.bits")) { int bits = Integer.parseInt(cli.getOptionValue("generate.bits")); - kpg.initialize(bits); + kpg.initialize(bits, random); } else if (cli.hasOption("generate.named-curve")) { String curveName = cli.getOptionValue("generate.named-curve"); EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName); @@ -740,19 +775,13 @@ public class ECTesterStandalone { System.err.println("Curve not found: " + curveName); return; } - kpg.initialize(curve.toSpec()); + kpg.initialize(curve.toSpec(), random); } else if (cli.hasOption("generate.curve-name")) { String curveName = cli.getOptionValue("generate.curve-name"); - kpg.initialize(new ECGenParameterSpec(curveName)); - } - - if (cli.hasOption("generate.prng-seed")) { - String seedString = cli.getOptionValue("generate.prng-seed"); - byte[] seed = ByteUtil.hexToBytes(seedString, true); - if (!lib.setupDeterministicPRNG(seed)) { - System.err.println("Couldn't set PRNG seed."); - return; - } + kpg.initialize(new ECGenParameterSpec(curveName), random); + } else if (cli.hasOption("generate.prng-seed") && !(lib instanceof NativeECLibrary)) { + System.err.println("Unable to pass PRNG seed to a non-native library without specifying either key-size, named curve or curve name options."); + return; } if (cli.hasOption("generate.time-source")) { diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/BouncyCastleLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/BouncyCastleLib.java index e8a4d30..0a7ea8c 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/BouncyCastleLib.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/BouncyCastleLib.java @@ -25,4 +25,16 @@ public class BouncyCastleLib extends ProviderECLibrary { } return result; } + + @Override + public boolean supportsDeterministicPRNG() { + return true; + } + + @Override + public boolean setupDeterministicPRNG(byte[] seed) { + // This is done by passing the SecureRandom into the individual KeyPairGenerator, KeyAgreement and Signature + // instances. Thus, this does nothing. + return true; + } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/SunECLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/SunECLib.java index 7209dc3..c38300d 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/SunECLib.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/SunECLib.java @@ -25,4 +25,16 @@ public class SunECLib extends ProviderECLibrary { } return result; } + + @Override + public boolean supportsDeterministicPRNG() { + return true; + } + + @Override + public boolean setupDeterministicPRNG(byte[] seed) { + // This is done by passing the SecureRandom into the individual KeyPairGenerator, KeyAgreement and Signature + // instances. Thus, this does nothing. + return true; + } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java index 01c3a53..12a9f16 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java @@ -129,7 +129,7 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite { e.getKey().endsWith("r1") && e.getValue().getField() == javacard.security.KeyPair.ALG_EC_FP).map(Map.Entry::getValue).collect(Collectors.toList()); curves.add(EC_Store.getInstance().getObject(EC_Curve.class, "cofactor/cofactor128p2")); curves.add(EC_Store.getInstance().getObject(EC_Curve.class, "cofactor/cofactor160p4")); - Random rand = new Random(); + Random rand = getRandom(); for (EC_Curve curve : curves) { ECParameterSpec spec = curve.toSpec(); diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java index 284194c..3ce58e1 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java @@ -4,6 +4,7 @@ import cz.crcs.ectester.common.cli.TreeCommandLine; import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.TestSuite; import cz.crcs.ectester.common.util.ByteUtil; +import cz.crcs.ectester.common.util.Util; import cz.crcs.ectester.standalone.ECTesterStandalone; import cz.crcs.ectester.standalone.consts.Ident; import cz.crcs.ectester.standalone.consts.KeyAgreementIdent; @@ -34,7 +35,7 @@ public abstract class StandaloneTestSuite extends TestSuite { } else { seed = new SecureRandom().generateSeed(16); } - this.random = new SecureRandom(seed); + this.random = Util.getRandom(seed); } public ProviderECLibrary getLibrary() { diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java index fe954a8..1a18188 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java @@ -96,7 +96,7 @@ public class StandaloneWrongSuite extends StandaloneTestSuite { Map curveMap = EC_Store.getInstance().getObjects(EC_Curve.class, "secg"); List curves = curveMap.entrySet().stream().filter((e) -> e.getKey().endsWith("r1") && e.getValue().getField() == javacard.security.KeyPair.ALG_EC_FP).map(Map.Entry::getValue).collect(Collectors.toList()); - Random r = new Random(); + Random r = getRandom(); for (EC_Curve curve : curves) { short bits = curve.getBits(); final byte[] originalp = curve.getParam(EC_Consts.PARAMETER_FP)[0]; -- cgit v1.3.1 From 6e399ce3dec913be7728c2892301dd3eceb2cd83 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 7 Aug 2024 13:31:39 +0200 Subject: Test deterministic keygen in standalone. --- .../java/cz/crcs/ectester/common/util/Util.java | 2 +- .../ectester/standalone/ECTesterStandalone.java | 10 +++--- .../java/cz/crcs/ectester/standalone/AppTests.java | 39 ++++++++++++++++++++++ 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/common/src/main/java/cz/crcs/ectester/common/util/Util.java b/common/src/main/java/cz/crcs/ectester/common/util/Util.java index 9e6daa2..1d9bcf4 100644 --- a/common/src/main/java/cz/crcs/ectester/common/util/Util.java +++ b/common/src/main/java/cz/crcs/ectester/common/util/Util.java @@ -35,7 +35,7 @@ public class Util { public static SecureRandom getRandom(byte[] seed) { SecureRandom random; try { - random = SecureRandom.getInstance("DRBG"); + random = SecureRandom.getInstance("SHA1PRNG"); } catch (NoSuchAlgorithmException ignored) { return null; } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java index f358662..44fc1b4 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -31,6 +31,7 @@ import cz.crcs.ectester.common.test.TestException; import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.common.util.ECUtil; import cz.crcs.ectester.common.util.FileUtil; +import cz.crcs.ectester.common.util.Util; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.standalone.consts.KeyAgreementIdent; import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent; @@ -419,8 +420,7 @@ public class ECTesterStandalone { if (cli.hasOption("ecdh.prng-seed")) { String seedString = cli.getOptionValue("ecdh.prng-seed"); byte[] seed = ByteUtil.hexToBytes(seedString, true); - random = SecureRandom.getInstance("DRBG"); - random.setSeed(seed); + random = Util.getRandom(seed); if (!lib.setupDeterministicPRNG(seed)) { System.err.println("Couldn't set PRNG seed."); return; @@ -549,8 +549,7 @@ public class ECTesterStandalone { if (cli.hasOption("ecdsa.prng-seed")) { String seedString = cli.getOptionValue("ecdsa.prng-seed"); byte[] seed = ByteUtil.hexToBytes(seedString, true); - random = SecureRandom.getInstance("DRBG"); - random.setSeed(seed); + random = Util.getRandom(seed); if (!lib.setupDeterministicPRNG(seed)) { System.err.println("Couldn't set PRNG seed."); return; @@ -754,8 +753,7 @@ public class ECTesterStandalone { if (cli.hasOption("generate.prng-seed")) { String seedString = cli.getOptionValue("generate.prng-seed"); byte[] seed = ByteUtil.hexToBytes(seedString, true); - random = SecureRandom.getInstance("DRBG"); - random.setSeed(seed); + random = Util.getRandom(seed); if (!lib.setupDeterministicPRNG(seed)) { System.err.println("Couldn't set PRNG seed."); return; diff --git a/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java b/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java index d401e58..6072e68 100644 --- a/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java +++ b/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java @@ -10,9 +10,11 @@ import org.junitpioneer.jupiter.StdOut; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.PrintStream; +import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; +import java.util.stream.Collectors; import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.*; @@ -85,6 +87,43 @@ public class AppTests { return args.toArray(new String[]{}); } + @SuppressWarnings("JUnitMalformedDeclaration") + @ParameterizedTest + @MethodSource("libs") + @StdIo() + public void deterministicGenerate(String libName, StdOut out) { + String[] args = new String[]{"generate", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-n", "10", "-nc", "secg/secp256r1", libName}; + switch (libName) { + case "Botan": + case "Crypto++": + args = new String[]{"generate", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-n", "10", "-nc", "secg/secp256r1", "-t", "ECDH", libName}; + break; + case "Nettle": + case "libgcrypt": + case "wolfCrypt": + args = new String[]{"generate", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-n", "10", "-cn", "secp256r1", libName}; + break; + case "BoringSSL": + args = new String[]{"generate", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-n", "10", "-cn", "prime256v1", libName}; + break; + } + ECTesterStandalone.main(args); + String out1 = out.capturedString(); + ECTesterStandalone.main(args); + String out2 = out.capturedString().substring(out1.length()); + if (!out1.contains(";")) + return; + List lines1 = out1.lines().collect(Collectors.toList()); + List lines2 = out2.lines().collect(Collectors.toList()); + assertEquals(lines1.size(), lines2.size()); + for (int i = 0; i < lines1.size(); ++i) { + String[] parts1 = lines1.get(i).split(";"); + String[] parts2 = lines2.get(i).split(";"); + assertEquals(parts1[2], parts2[2]); + assertEquals(parts1[3], parts2[3]); + } + } + @SuppressWarnings("JUnitMalformedDeclaration") @ParameterizedTest @MethodSource("libs") -- cgit v1.3.1 From c55d804aed8b63eb62c74018a720c4804c43c681 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 7 Aug 2024 13:34:46 +0200 Subject: Allow for passing Random to wolfCrypt. --- .../java/cz/crcs/ectester/standalone/libs/WolfCryptLib.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/WolfCryptLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/WolfCryptLib.java index c8d5ad5..390e45f 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/WolfCryptLib.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/WolfCryptLib.java @@ -25,4 +25,16 @@ public class WolfCryptLib extends ProviderECLibrary { public Set getCurves() { return new HashSet<>(); } + + @Override + public boolean supportsDeterministicPRNG() { + return true; + } + + @Override + public boolean setupDeterministicPRNG(byte[] seed) { + // This is done by passing the SecureRandom into the individual KeyPairGenerator, KeyAgreement and Signature + // instances. Thus, this does nothing. + return true; + } } -- cgit v1.3.1 From aa37d2b0853670cb6e13e41ae65cd74f6b64d021 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 7 Aug 2024 13:48:00 +0200 Subject: Add deterministic PRNG support to Nettle. --- .../crcs/ectester/standalone/libs/NettleLib.java | 6 ++++ .../cz/crcs/ectester/standalone/libs/jni/native.h | 15 ++++++++++ .../cz/crcs/ectester/standalone/libs/jni/nettle.c | 32 +++++++++++++++++++--- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NettleLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NettleLib.java index d4df414..aa90c38 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NettleLib.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NettleLib.java @@ -49,4 +49,10 @@ public class NettleLib extends NativeECLibrary { } throw new InvalidAlgorithmParameterException("Unknown curve."); } + + @Override + public native boolean supportsDeterministicPRNG(); + + @Override + public native boolean setupDeterministicPRNG(byte[] seed); } diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h index 49be801..b8b2af1 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h @@ -1932,6 +1932,21 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_NettleLib_create JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_NettleLib_getCurves (JNIEnv *, jobject); +/* +* Class: cz_crcs_ectester_standalone_libs_NettleLib +* Method: supportsDeterministicPRNG +* Signature: ()Z +*/ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_NettleLib_supportsDeterministicPRNG +(JNIEnv *, jobject); + +/* +* Class: cz_crcs_ectester_standalone_libs_NettleLib +* Method: setupDeterministicPRNG +* Signature: ([B)Z +*/ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_NettleLib_setupDeterministicPRNG +(JNIEnv *, jobject, jbyteArray); #ifdef __cplusplus } #endif diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/nettle.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/nettle.c index e7ec00e..08b09d5 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/nettle.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/nettle.c @@ -44,10 +44,16 @@ JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_ init_classes(env, "Nettle"); yarrow256_init(&yarrow, 0, NULL); - uint8_t file = open("/dev/random", O_RDONLY); - yarrow256_seed(&yarrow, YARROW256_SEED_FILE_SIZE, &file); - close(file); - + FILE *urandom = fopen("/dev/urandom", "rb"); + uint8_t seed[YARROW256_SEED_FILE_SIZE]; + if (urandom) { + size_t read = 0; + while (read < sizeof(seed)) { + read += fread(((uint8_t *)&seed) + read, 1, sizeof(seed) - read, urandom); + } + fclose(urandom); + } + yarrow256_seed(&yarrow, YARROW256_SEED_FILE_SIZE, seed); } JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_NettleLib_getCurves(JNIEnv *env, jobject self) { @@ -66,6 +72,24 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_NettleLib_getCur return result; } +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_NettleLib_supportsDeterministicPRNG(JNIEnv *env, jobject self) { + return JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_NettleLib_setupDeterministicPRNG(JNIEnv *env, jobject self, jbyteArray seed) { + jsize seed_length = (*env)->GetArrayLength(env, seed); + if (seed_length < YARROW256_SEED_FILE_SIZE) { + fprintf(stderr, "Error setting seed, needs to be at least %i bytes.\n", YARROW256_SEED_FILE_SIZE); + return JNI_FALSE; + } + + jbyte *seed_data = (*env)->GetByteArrayElements(env, seed, NULL); + yarrow256_init(&yarrow, 0, NULL); + yarrow256_seed(&yarrow, YARROW256_SEED_FILE_SIZE, seed_data); + (*env)->ReleaseByteArrayElements(env, seed, seed_data, JNI_ABORT); + return JNI_TRUE; +} + static const struct ecc_curve* create_curve_from_name(JNIEnv *env, const char* curve_name) { if (!curve_name) { return NULL; -- cgit v1.3.1 From ae4e8f69b68e51973a20ba59d2fc6fd1e7849972 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 7 Aug 2024 14:00:59 +0200 Subject: Add deterministic PRNG support to ippcp. --- .../cz/crcs/ectester/standalone/libs/IppcpLib.java | 6 ++++++ .../cz/crcs/ectester/standalone/libs/jni/ippcp.c | 23 ++++++++++++++++++++++ .../cz/crcs/ectester/standalone/libs/jni/native.h | 16 +++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/IppcpLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/IppcpLib.java index 115fe00..fa51585 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/IppcpLib.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/IppcpLib.java @@ -17,4 +17,10 @@ public class IppcpLib extends NativeECLibrary { @Override public native Set getCurves(); + + @Override + public native boolean supportsDeterministicPRNG(); + + @Override + public native boolean setupDeterministicPRNG(byte[] seed); } diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/ippcp.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/ippcp.c index fbf917e..86f0f7e 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/ippcp.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/ippcp.c @@ -136,6 +136,29 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_getCurv return result; } + +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_supportsDeterministicPRNG(JNIEnv *env, jobject self) { + return JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_setupDeterministicPRNG(JNIEnv *env, jobject self, jbyteArray seed) { + jsize seed_length = (*env)->GetArrayLength(env, seed); + if (seed_length % 4 != 0) { + fprintf(stderr, "Error setting seed, needs to be a multiple of 4 bytes.\n"); + return JNI_FALSE; + } + int bn_size; + ippsBigNumGetSize(seed_length / 4, &bn_size); + uint8_t bn_buf[bn_size]; + IppsBigNumState *bn = (IppsBigNumState *)bn_buf; + ippsBigNumInit(seed_length / 4, bn); + jbyte *seed_data = (*env)->GetByteArrayElements(env, seed, NULL); + ippsSet_BN(IppsBigNumPOS, seed_length / 4, (Ipp32u *) seed_data, bn); + ippsPRNGSetSeed(bn, prng_state); + (*env)->ReleaseByteArrayElements(env, seed, seed_data, JNI_ABORT); + return JNI_TRUE; +} + JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Ippcp_keysizeSupported(JNIEnv *env, jobject this, jint keysize) { diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h index b8b2af1..627f38f 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h @@ -1570,6 +1570,22 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_createP JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_getCurves (JNIEnv *, jobject); +/* +* Class: cz_crcs_ectester_standalone_libs_IppcpLib +* Method: supportsDeterministicPRNG +* Signature: ()Z +*/ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_supportsDeterministicPRNG +(JNIEnv *, jobject); + +/* +* Class: cz_crcs_ectester_standalone_libs_IppcpLib +* Method: setupDeterministicPRNG +* Signature: ([B)Z +*/ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_setupDeterministicPRNG +(JNIEnv *, jobject, jbyteArray); + #ifdef __cplusplus } #endif -- cgit v1.3.1 From 84858177fe6c2b9bdc6ea9785a92781ba1237e04 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 7 Aug 2024 20:18:23 +0200 Subject: Add deterministic RNG to mbedTLS. --- .../crcs/ectester/standalone/libs/MbedTLSLib.java | 6 +++ .../cz/crcs/ectester/standalone/libs/jni/mbedtls.c | 46 ++++++++++++++++++++-- .../cz/crcs/ectester/standalone/libs/jni/native.h | 16 ++++++++ .../java/cz/crcs/ectester/standalone/AppTests.java | 3 ++ 4 files changed, 67 insertions(+), 4 deletions(-) diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/MbedTLSLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/MbedTLSLib.java index e44598c..efc8cad 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/MbedTLSLib.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/MbedTLSLib.java @@ -17,4 +17,10 @@ public class MbedTLSLib extends NativeECLibrary { @Override public native Set getCurves(); + + @Override + public native boolean supportsDeterministicPRNG(); + + @Override + public native boolean setupDeterministicPRNG(byte[] seed); } diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/mbedtls.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/mbedtls.c index 5fc879b..8f5e0fb 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/mbedtls.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/mbedtls.c @@ -16,7 +16,8 @@ static mbedtls_ctr_drbg_context ctr_drbg; -static mbedtls_entropy_context entropy; +static mbedtls_entropy_context urandom_entropy; +static mbedtls_entropy_context fixed_entropy; static jclass provider_class; @@ -62,6 +63,17 @@ static int dev_urandom(void *data, unsigned char *output, size_t len, size_t *ol return 0; } +static unsigned char seed_store[32] = {0}; + +static int fixed_random(void *data, unsigned char *output, size_t len, size_t *olen) { + for (size_t i = 0; i < len; ++i) { + output[i] = seed_store[i % 32]; + } + *olen = len; + return 0; +} + + static int ctr_drbg_wrapper(void *ctx, unsigned char *buf, size_t len) { native_timing_pause(); int result = mbedtls_ctr_drbg_random(ctx, buf, len); @@ -77,9 +89,9 @@ JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_ ADD_SIG(env, this, "NONEwithECDSA", "MbedTLSECDSAwithNONE"); mbedtls_ctr_drbg_init(&ctr_drbg); - mbedtls_entropy_init(&entropy); - mbedtls_entropy_add_source(&entropy, dev_urandom, NULL, 32, MBEDTLS_ENTROPY_SOURCE_STRONG); - mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0); + mbedtls_entropy_init(&urandom_entropy); + mbedtls_entropy_add_source(&urandom_entropy, dev_urandom, NULL, 32, MBEDTLS_ENTROPY_SOURCE_STRONG); + mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &urandom_entropy, NULL, 0); init_classes(env, "MbedTLS"); } @@ -101,6 +113,32 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MbedTLSLib_getCu return result; } +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_MbedTLSLib_supportsDeterministicPRNG(JNIEnv *env, jobject this) { + return JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_MbedTLSLib_setupDeterministicPRNG(JNIEnv *env, jobject this, jbyteArray seed) { + jsize seed_length = (*env)->GetArrayLength(env, seed); + if (seed_length > 32) { + fprintf(stderr, "Error setting seed, needs to be at most 32 bytes, is %i.\n", seed_length); + return JNI_FALSE; + } + jbyte *seed_data = (*env)->GetByteArrayElements(env, seed, NULL); + memcpy(seed_store, seed_data, seed_length); + (*env)->ReleaseByteArrayElements(env, seed, seed_data, JNI_ABORT); + + memset(&ctr_drbg, 0, sizeof(ctr_drbg)); + mbedtls_ctr_drbg_init(&ctr_drbg); + + mbedtls_entropy_init(&fixed_entropy); + // This is NASTY! We are accessing something the library does not want us to. + fixed_entropy.private_source_count = 0; + mbedtls_entropy_add_source(&fixed_entropy, fixed_random, NULL, 32, MBEDTLS_ENTROPY_SOURCE_STRONG); + mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &fixed_entropy, NULL, 0); + + return JNI_TRUE; +} + JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024MbedTLS_keysizeSupported(JNIEnv *env, jobject this, jint keysize) { for (const mbedtls_ecp_curve_info *curve_info = mbedtls_ecp_curve_list(); curve_info->grp_id != MBEDTLS_ECP_DP_NONE; diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h index 627f38f..287b450 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h @@ -1389,6 +1389,22 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MbedTLSLib_creat JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MbedTLSLib_getCurves (JNIEnv *, jobject); +/* + * Class: cz_crcs_ectester_standalone_libs_MbedTLSLib + * Method: supportsDeterministicPRNG + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_MbedTLSLib_supportsDeterministicPRNG + (JNIEnv *, jobject); + +/* + * Class: cz_crcs_ectester_standalone_libs_MbedTLSLib + * Method: setupDeterministicPRNG + * Signature: ([B)Z + */ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_MbedTLSLib_setupDeterministicPRNG + (JNIEnv *, jobject, jbyteArray); + #ifdef __cplusplus } #endif diff --git a/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java b/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java index 6072e68..8693b7b 100644 --- a/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java +++ b/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java @@ -106,6 +106,9 @@ public class AppTests { case "BoringSSL": args = new String[]{"generate", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-n", "10", "-cn", "prime256v1", libName}; break; + case "mbedTLS": + args = new String[]{"generate", "-ps", "12345678", "-n", "10", "-nc", "secg/secp256r1", libName}; + break; } ECTesterStandalone.main(args); String out1 = out.capturedString(); -- cgit v1.3.1 From 50c576e0f28eac393985073d7d91dac1262bf5da Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 7 Aug 2024 20:34:48 +0200 Subject: Add deterministic RNG to Crypto++. --- .../crcs/ectester/standalone/libs/CryptoppLib.java | 6 +++++ .../crcs/ectester/standalone/libs/jni/cryptopp.cpp | 27 +++++++++++++++++++--- .../cz/crcs/ectester/standalone/libs/jni/native.h | 16 +++++++++++++ .../java/cz/crcs/ectester/standalone/AppTests.java | 4 +++- 4 files changed, 49 insertions(+), 4 deletions(-) diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/CryptoppLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/CryptoppLib.java index 66aa9ea..25f2de4 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/CryptoppLib.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/CryptoppLib.java @@ -17,4 +17,10 @@ public class CryptoppLib extends NativeECLibrary { @Override public native Set getCurves(); + + @Override + public native boolean supportsDeterministicPRNG(); + + @Override + public native boolean setupDeterministicPRNG(byte[] seed); } diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp index c4c74a6..1f82f8a 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp @@ -22,8 +22,12 @@ using CryptoPP::Exception; using CryptoPP::byte; #include "cryptopp/osrng.h" +using CryptoPP::RandomNumberGenerator; using CryptoPP::AutoSeededRandomPool; +#include "cryptopp/mersenne.h" +using CryptoPP::MT19937; + #include "cryptopp/sha.h" using CryptoPP::SHA1; using CryptoPP::SHA224; @@ -89,7 +93,7 @@ using CryptoPP::Integer; */ static jclass provider_class; -static AutoSeededRandomPool rng; +static std::unique_ptr rng = std::make_unique(); JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_createProvider(JNIEnv *env, jobject self) { @@ -187,6 +191,23 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_getC return result; } +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_supportsDeterministicPRNG(JNIEnv *env, jobject self) { + return JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_setupDeterministicPRNG(JNIEnv *env, jobject self, jbyteArray seed) { + jsize seed_length = env->GetArrayLength(seed); + if (seed_length > 4) { + fprintf(stderr, "Error setting seed, needs to be at most 4 bytes.\n"); + return JNI_FALSE; + } + jbyte *seed_data = env->GetByteArrayElements(seed, nullptr); + uint32_t seed_int = seed_data[0] | seed_data[1] << 8 | seed_data[2] << 16 | seed_data[3] << 24; + rng.reset(new MT19937(seed_int)); + env->ReleaseByteArrayElements(seed, seed_data, JNI_ABORT); + return JNI_TRUE; +} + JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Cryptopp_keysizeSupported(JNIEnv *env, jobject self, jint keysize){ std::vector ecp_oids = get_curve_oids(); for (auto & ecp_oid : ecp_oids) { @@ -517,7 +538,7 @@ template jobject generate_from_group(JNIEnv *env, DL_GroupParameters_ SIG_TRY(TIMEOUT) { try { native_timing_start(); - ec_domain.GenerateKeyPair(rng, priv, pub); + ec_domain.GenerateKeyPair(*rng, priv, pub); native_timing_stop(); } catch (Exception & ex) { SIG_DEINIT(); @@ -661,7 +682,7 @@ jbyteArray sign_message(JNIEnv *env, DL_GroupParameters_EC group, jbyteArray size_t len; SIG_TRY(TIMEOUT) { native_timing_start(); - len = signer.SignMessage(rng, (byte *)data_bytes, data_length, (byte *)signature.c_str()); + len = signer.SignMessage(*rng, (byte *)data_bytes, data_length, (byte *)signature.c_str()); native_timing_stop(); } SIG_CATCH_HANDLE(env); env->ReleaseByteArrayElements(data, data_bytes, JNI_ABORT); diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h index 287b450..91cada9 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h @@ -468,6 +468,22 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_crea JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_getCurves (JNIEnv *, jobject); +/* + * Class: cz_crcs_ectester_standalone_libs_CryptoppLib + * Method: supportsDeterministicPRNG + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_supportsDeterministicPRNG + (JNIEnv *, jobject); + +/* + * Class: cz_crcs_ectester_standalone_libs_CryptoppLib + * Method: setupDeterministicPRNG + * Signature: ([B)Z + */ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_setupDeterministicPRNG + (JNIEnv *, jobject, jbyteArray); + #ifdef __cplusplus } #endif diff --git a/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java b/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java index 8693b7b..6e8ec76 100644 --- a/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java +++ b/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java @@ -95,9 +95,11 @@ public class AppTests { String[] args = new String[]{"generate", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-n", "10", "-nc", "secg/secp256r1", libName}; switch (libName) { case "Botan": - case "Crypto++": args = new String[]{"generate", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-n", "10", "-nc", "secg/secp256r1", "-t", "ECDH", libName}; break; + case "Crypto++": + args = new String[]{"generate", "-ps", "12345678", "-n", "10", "-nc", "secg/secp256r1", "-t", "ECDH", libName}; + break; case "Nettle": case "libgcrypt": case "wolfCrypt": -- cgit v1.3.1 From c447744282771b4922faf3fbd4080ed7b31adc02 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 7 Aug 2024 20:59:22 +0200 Subject: Split off deterministic tests. --- .../ectester/standalone/ECTesterStandalone.java | 33 +++-- .../java/cz/crcs/ectester/standalone/AppTests.java | 45 ------- .../ectester/standalone/DeterministicTests.java | 137 +++++++++++++++++++++ 3 files changed, 162 insertions(+), 53 deletions(-) create mode 100644 standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java index 44fc1b4..dc61192 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -193,7 +193,14 @@ public class ECTesterStandalone { Option outputRaw = Option.builder("o").longOpt("output").desc("Output CSV into file .").hasArgs().argName("output_file").optionalArg(false).numberOfArgs(1).build(); Option quiet = Option.builder("q").longOpt("quiet").desc("Do not output to stdout.").build(); Option timeSource = Option.builder("ts").longOpt("time-source").desc("Use a given native timing source: {rdtsc, monotonic, monotonic-raw, cputime-process, cputime-thread}").hasArgs().argName("source").optionalArg(false).numberOfArgs(1).build(); - Option prngSeed = Option.builder("ps").longOpt("prng-seed").desc("Use a deterministic PRNG with the given seed (hexadecimal).").hasArgs().argName("seed").optionalArg(false).numberOfArgs(1).build(); + Option prngSeed = Option.builder("ps").longOpt("prng-seed").desc("Use a deterministic PRNG with the given [seed] (hexadecimal) in the library.").hasArgs().argName("seed").optionalArg(false).numberOfArgs(1).build(); + Option file = Option.builder("f").longOpt("file").hasArg().argName("file").optionalArg(false).desc("Input [file] to sign.").build(); + Option message = Option.builder("d").longOpt("data").desc("Sign the given [message].").hasArgs().argName("message").optionalArg(false).numberOfArgs(1).build(); + Option messageSeed = Option.builder("ds").longOpt("data-seed").desc("Use a deterministic PRNG with the given [seed] (hexadecimal) to generate the messages.").hasArgs().argName("seed").optionalArg(false).numberOfArgs(1).build(); + OptionGroup ecdsaMessage = new OptionGroup(); + ecdsaMessage.addOption(file); + ecdsaMessage.addOption(message); + ecdsaMessage.addOption(messageSeed); Options testOpts = new Options(); testOpts.addOption(bits); @@ -241,7 +248,7 @@ public class ECTesterStandalone { ecdsaOpts.addOption(Option.builder().longOpt("fixed").desc("Perform all ECDSA with fixed keypair.").build()); ecdsaOpts.addOption(Option.builder("t").longOpt("type").desc("Set Signature object [type].").hasArg().argName("type").optionalArg(false).build()); ecdsaOpts.addOption(Option.builder("n").longOpt("amount").hasArg().argName("amount").optionalArg(false).desc("Do ECDSA [amount] times.").build()); - ecdsaOpts.addOption(Option.builder("f").longOpt("file").hasArg().argName("file").optionalArg(false).desc("Input [file] to sign.").build()); + ecdsaOpts.addOptionGroup(ecdsaMessage); ParserOptions ecdsa = new ParserOptions(new DefaultParser(), ecdsaOpts, "Perform EC based Signature."); actions.put("ecdsa", ecdsa); @@ -558,8 +565,9 @@ public class ECTesterStandalone { random = new SecureRandom(); } - byte[] data; - String dataString; + byte[] data = null; + String dataString = null; + SecureRandom dataRandom = null; if (cli.hasOption("ecdsa.file")) { String fileName = cli.getOptionValue("ecdsa.file"); File in = new File(fileName); @@ -569,11 +577,15 @@ public class ECTesterStandalone { } data = Files.readAllBytes(in.toPath()); dataString = ""; + } else if (cli.hasOption("ecdsa.data")) { + dataString = cli.getOptionValue("ecdsa.data"); + data = ByteUtil.hexToBytes(dataString); + } else if (cli.hasOption("ecdsa.data-seed")) { + String seedString = cli.getOptionValue("ecdsa.prng-seed"); + byte[] seed = ByteUtil.hexToBytes(seedString, true); + dataRandom = Util.getRandom(seed); } else { - Random dataRandom = new Random(); - data = new byte[32]; - dataRandom.nextBytes(data); - dataString = ByteUtil.bytesToHex(data, false); + dataRandom = new SecureRandom(); } String algo = cli.getOptionValue("ecdsa.type", "ECDSA"); @@ -679,6 +691,11 @@ public class ECTesterStandalone { } } + if (dataRandom != null) { + data = dataRandom.generateSeed(16); + dataString = ByteUtil.bytesToHex(data, false); + } + sig.initSign(privkey, random); sig.update(data); diff --git a/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java b/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java index 6e8ec76..1ff9556 100644 --- a/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java +++ b/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java @@ -1,6 +1,5 @@ package cz.crcs.ectester.standalone; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -10,11 +9,9 @@ import org.junitpioneer.jupiter.StdOut; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.PrintStream; -import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; -import java.util.stream.Collectors; import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.*; @@ -87,48 +84,6 @@ public class AppTests { return args.toArray(new String[]{}); } - @SuppressWarnings("JUnitMalformedDeclaration") - @ParameterizedTest - @MethodSource("libs") - @StdIo() - public void deterministicGenerate(String libName, StdOut out) { - String[] args = new String[]{"generate", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-n", "10", "-nc", "secg/secp256r1", libName}; - switch (libName) { - case "Botan": - args = new String[]{"generate", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-n", "10", "-nc", "secg/secp256r1", "-t", "ECDH", libName}; - break; - case "Crypto++": - args = new String[]{"generate", "-ps", "12345678", "-n", "10", "-nc", "secg/secp256r1", "-t", "ECDH", libName}; - break; - case "Nettle": - case "libgcrypt": - case "wolfCrypt": - args = new String[]{"generate", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-n", "10", "-cn", "secp256r1", libName}; - break; - case "BoringSSL": - args = new String[]{"generate", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-n", "10", "-cn", "prime256v1", libName}; - break; - case "mbedTLS": - args = new String[]{"generate", "-ps", "12345678", "-n", "10", "-nc", "secg/secp256r1", libName}; - break; - } - ECTesterStandalone.main(args); - String out1 = out.capturedString(); - ECTesterStandalone.main(args); - String out2 = out.capturedString().substring(out1.length()); - if (!out1.contains(";")) - return; - List lines1 = out1.lines().collect(Collectors.toList()); - List lines2 = out2.lines().collect(Collectors.toList()); - assertEquals(lines1.size(), lines2.size()); - for (int i = 0; i < lines1.size(); ++i) { - String[] parts1 = lines1.get(i).split(";"); - String[] parts2 = lines2.get(i).split(";"); - assertEquals(parts1[2], parts2[2]); - assertEquals(parts1[3], parts2[3]); - } - } - @SuppressWarnings("JUnitMalformedDeclaration") @ParameterizedTest @MethodSource("libs") diff --git a/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java b/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java new file mode 100644 index 0000000..de9e65f --- /dev/null +++ b/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java @@ -0,0 +1,137 @@ +package cz.crcs.ectester.standalone; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.junitpioneer.jupiter.StdIo; +import org.junitpioneer.jupiter.StdOut; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class DeterministicTests { + + static Stream libs() { + return Stream.of("Botan", "BouncyCastle", "Crypto++", "IPPCP", "mbedTLS", "Nettle", "OpenSSL", "SunEC", "tomcrypt"); + } + + @SuppressWarnings("JUnitMalformedDeclaration") + @ParameterizedTest + @MethodSource("libs") + @StdIo() + public void generate(String libName, StdOut out) { + String[] args = new String[]{"generate", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-n", "10", "-nc", "secg/secp256r1", libName}; + switch (libName) { + case "Botan": + args = new String[]{"generate", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-n", "10", "-nc", "secg/secp256r1", "-t", "ECDH", libName}; + break; + case "Crypto++": + args = new String[]{"generate", "-ps", "12345678", "-n", "10", "-nc", "secg/secp256r1", "-t", "ECDH", libName}; + break; + case "Nettle": + args = new String[]{"generate", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-n", "10", "-cn", "secp256r1", libName}; + break; + case "mbedTLS": + args = new String[]{"generate", "-ps", "12345678", "-n", "10", "-nc", "secg/secp256r1", libName}; + break; + } + ECTesterStandalone.main(args); + String out1 = out.capturedString(); + ECTesterStandalone.main(args); + String out2 = out.capturedString().substring(out1.length()); + if (!out1.contains(";")) + return; + List lines1 = out1.lines().collect(Collectors.toList()); + List lines2 = out2.lines().collect(Collectors.toList()); + assertEquals(lines1.size(), lines2.size()); + for (int i = 0; i < lines1.size(); ++i) { + String[] parts1 = lines1.get(i).split(";"); + String[] parts2 = lines2.get(i).split(";"); + assertEquals(parts1[2], parts2[2]); + assertEquals(parts1[3], parts2[3]); + } + } + + @SuppressWarnings("JUnitMalformedDeclaration") + @ParameterizedTest + @MethodSource("libs") + @StdIo() + public void ecdh(String libName, StdOut out) { + String[] args = new String[]{"ecdh", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-n", "10", "-nc", "secg/secp256r1", libName}; + switch (libName) { + case "Nettle": + args = new String[]{"ecdh", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-n", "10", "-cn", "secp256r1", libName}; + break; + case "Crypto++": + args = new String[]{"ecdh", "-ps", "12345678", "-n", "10", "-nc", "secg/secp256r1", "-t", "ECDH", libName}; + break; + case "mbedTLS": + args = new String[]{"ecdh", "-ps", "12345678", "-n", "10", "-nc", "secg/secp256r1", libName}; + break; + } + ECTesterStandalone.main(args); + String out1 = out.capturedString(); + ECTesterStandalone.main(args); + String out2 = out.capturedString().substring(out1.length()); + if (!out1.contains(";")) + return; + List lines1 = out1.lines().collect(Collectors.toList()); + List lines2 = out2.lines().collect(Collectors.toList()); + assertEquals(lines1.size(), lines2.size()); + for (int i = 0; i < lines1.size(); ++i) { + String[] parts1 = lines1.get(i).split(";"); + String[] parts2 = lines2.get(i).split(";"); + assertEquals(parts1[2], parts2[2]); // pubkey + assertEquals(parts1[3], parts2[3]); // privkey + assertEquals(parts1[4], parts2[4]); // secret + } + } + + @SuppressWarnings("JUnitMalformedDeclaration") + @ParameterizedTest + @MethodSource("libs") + @StdIo() + public void ecdsa(String libName, StdOut out) { + String[] args = new String[]{"ecdsa", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-d", "1234", "-n", "10", "-nc", "secg/secp256r1", libName}; + switch (libName) { + case "Nettle": + args = new String[]{"ecdsa", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-d", "1234", "-n", "10", "-cn", "secp256r1", "-t", "NONEwithECDSA", libName}; + break; + case "OpenSSL": + case "tomcrypt": + args = new String[]{"ecdsa", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-d", "1234", "-n", "10", "-nc", "secg/secp256r1", "-t", "NONEwithECDSA", libName}; + break; + case "IPPCP": + // TODO: Weird, IPPCP cannot sign less than 4 bytes. + args = new String[]{"ecdsa", "-ps", "123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234", "-d", "12345678", "-n", "10", "-nc", "secg/secp256r1", "-t", "NONEwithECDSA", libName}; + break; + case "Crypto++": + args = new String[]{"ecdsa", "-ps", "12345678", "-d", "1234", "-n", "10", "-nc", "secg/secp256r1", "-t", "ECDSA", libName}; + break; + case "mbedTLS": + args = new String[]{"ecdsa", "-ps", "12345678", "-d", "1234", "-n", "10", "-nc", "secg/secp256r1", "-t", "NONEwithECDSA", libName}; + break; + } + ECTesterStandalone.main(args); + String out1 = out.capturedString(); + ECTesterStandalone.main(args); + String out2 = out.capturedString().substring(out1.length()); + if (!out1.contains(";")) + return; + List lines1 = out1.lines().collect(Collectors.toList()); + List lines2 = out2.lines().collect(Collectors.toList()); + assertEquals(lines1.size(), lines2.size()); + for (int i = 0; i < lines1.size(); ++i) { + String[] parts1 = lines1.get(i).split(";"); + String[] parts2 = lines2.get(i).split(";"); + assertEquals(parts1[3], parts2[3]); // data + assertEquals(parts1[4], parts2[4]); // pubkey + assertEquals(parts1[5], parts2[5]); // privkey + assertEquals(parts1[6], parts2[6]); // signature + assertEquals(parts1[7], parts2[7]); // nonce + } + } +} -- cgit v1.3.1 From 6416595eeb031869de50a87f123855c5ad7bbc76 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 7 Aug 2024 20:59:46 +0200 Subject: WolfCrypt is not deterministic? --- .../java/cz/crcs/ectester/standalone/libs/WolfCryptLib.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/WolfCryptLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/WolfCryptLib.java index 390e45f..c8d5ad5 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/WolfCryptLib.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/WolfCryptLib.java @@ -25,16 +25,4 @@ public class WolfCryptLib extends ProviderECLibrary { public Set getCurves() { return new HashSet<>(); } - - @Override - public boolean supportsDeterministicPRNG() { - return true; - } - - @Override - public boolean setupDeterministicPRNG(byte[] seed) { - // This is done by passing the SecureRandom into the individual KeyPairGenerator, KeyAgreement and Signature - // instances. Thus, this does nothing. - return true; - } } -- cgit v1.3.1 From c58adb1f975af0938e2716ae328b37e31da3bbe0 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 7 Aug 2024 21:07:53 +0200 Subject: Fix listSuites. --- standalone/build.gradle.kts | 1 - .../cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/standalone/build.gradle.kts b/standalone/build.gradle.kts index e1fc265..d485bcb 100644 --- a/standalone/build.gradle.kts +++ b/standalone/build.gradle.kts @@ -40,7 +40,6 @@ tasks.named("test") { doFirst { resultsDir.mkdirs(); } - ignoreFailures = true useJUnitPlatform() // Report is always generated after tests run finalizedBy(tasks.named("testCodeCoverageReport")) diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java index 3ce58e1..bfea628 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java @@ -29,8 +29,8 @@ public abstract class StandaloneTestSuite extends TestSuite { super(writer, name, description); this.cfg = cfg; this.cli = cli; - if (cli.hasOption("test.prng-seed")) { - String seedString = cli.getOptionValue("generate.prng-seed"); + if (cli != null && cli.hasOption("test.prng-seed")) { + String seedString = cli.getOptionValue("test.prng-seed"); this.seed = ByteUtil.hexToBytes(seedString, true); } else { seed = new SecureRandom().generateSeed(16); -- cgit v1.3.1 From 06fd1cee79c7587e08a3240992c58f7fb361d7fd Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 7 Aug 2024 21:18:01 +0200 Subject: Add deterministic PRNG example to docs. --- README.md | 122 +++++++++++++-------- .../ectester/standalone/DeterministicTests.java | 1 - 2 files changed, 79 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 726be68..379f05f 100644 --- a/README.md +++ b/README.md @@ -440,103 +440,121 @@ To install, place them in `${java.home}/jre/lib/security/`. Snippet below shows how the `list-libs` command for well, listing currently supported libraries, behaves if all supported libraries are present (on Linux). ``` > java -jar ECTesterStandalone.jar list-libs - - Sun Elliptic Curve provider - - Version: 21.000000 + - SunEC + - Fullname: SunEC + - Version: 21 - Supports native timing: [] - - KeyPairGenerators: EC - - KeyAgreements: ECDH - - Signatures: SHA3-256withECDSA, NONEwithECDSA, ECDSA, SHA3-384withECDSA, SHA384withECDSA, SHA3-512withECDSA, SHA224withECDSA, SHA512withECDSA, SHA3-224withECDSA, SHA256withECDSA + - Supports deterministic PRNG: true + - KeyPairGenerators: EC, Ed25519, Ed448, EdDSA, X25519, X448, XDH + - KeyAgreements: ECDH, X25519, X448, XDH + - Signatures: ECDSA, Ed25519, Ed448, EdDSA, NONEwithECDSA, SHA224withECDSA, SHA256withECDSA, SHA3-224withECDSA, SHA3-256withECDSA, SHA3-384withECDSA, SHA3-512withECDSA, SHA384withECDSA, SHA512withECDSA - Curves: secp256r1, secp384r1, secp521r1 - - BouncyCastle Security Provider v1.77 - - Version: 1.770000 + - BouncyCastle + - Fullname: BC + - Version: 1.77 - Supports native timing: [] - - KeyPairGenerators: ECDSA, ECMQV, EC, ECDH, ECDHC - - KeyAgreements: ECCDHwithSHA384KDF, ECDHwithSHA384KDF, ECDHwithSHA256KDF, ECDHwithSHA1KDF, ECDHwithSHA224KDF, ECDH, ECDHC, ECDHwithSHA512KDF, ECCDHwithSHA1KDF, ECCDHwithSHA512KDF, ECCDHwithSHA224KDF, ECCDHwithSHA256KDF - - Signatures: SHA1withCVC-ECDSA, NONEwithECDSA, ECGOST3410, SHA256withECNR, ECGOST3410-2012-512, SHA512withECDDSA, GOST3411-2012-512withECGOST3410-2012-512, SHA3-512withECDSA, SHA384withPLAIN-ECDSA, SHA256withECDSA, SHA256withECDDSA, SHA224withECDDSA, SHA3-256withECDSA, ECDSA, SHA256withPLAIN-ECDSA, SHA224withECNR, SHA384withECDDSA, SHA512withECNR, SHA256withCVC-ECDSA, SHA1withECNR, ECDDSA, SHA1withPLAIN-ECDSA, GOST3411-2012-256withECGOST3410-2012-256, SHA512withPLAIN-ECDSA, SHA384withCVC-ECDSA, SHA224withCVC-ECDSA, SHA3-224withECDSA, SHA3-224withECDDSA, SHA224withPLAIN-ECDSA, SHA3-384withECDDSA, SHA384withECDSA, SHA3-384withECDSA, SHA3-512withECDDSA, SM3withSM2, GOST3411withECGOST3410, ECGOST3410-2012-256, SHA224withECDSA, SHA512withECDSA, RIPEMD160withECDSA, SHA512withCVC-ECDSA, RIPEMD160withPLAIN-ECDSA, SHA3-256withECDDSA + - Supports deterministic PRNG: true + - KeyPairGenerators: EC, ECDH, ECDHC, ECDSA, ECMQV, Ed25519, Ed448, EdDSA, X25519, X448, XDH + - KeyAgreements: ECCDHwithSHA1KDF, ECCDHwithSHA224KDF, ECCDHwithSHA256KDF, ECCDHwithSHA384KDF, ECCDHwithSHA512KDF, ECDH, ECDHC, ECDHwithSHA1KDF, ECDHwithSHA224KDF, ECDHwithSHA256KDF, ECDHwithSHA384KDF, ECDHwithSHA512KDF, X25519, X448, XDH + - Signatures: ECDDSA, ECDSA, ECGOST3410, ECGOST3410-2012-256, ECGOST3410-2012-512, Ed25519, Ed448, EdDSA, GOST3411-2012-256withECGOST3410-2012-256, GOST3411-2012-512withECGOST3410-2012-512, GOST3411withECGOST3410, NONEwithECDSA, RIPEMD160withECDSA, RIPEMD160withPLAIN-ECDSA, SHA1withCVC-ECDSA, SHA1withECNR, SHA1withPLAIN-ECDSA, SHA224withCVC-ECDSA, SHA224withECDDSA, SHA224withECDSA, SHA224withECNR, SHA224withPLAIN-ECDSA, SHA256withCVC-ECDSA, SHA256withECDDSA, SHA256withECDSA, SHA256withECNR, SHA256withPLAIN-ECDSA, SHA3-224withECDDSA, SHA3-224withECDSA, SHA3-256withECDDSA, SHA3-256withECDSA, SHA3-384withECDDSA, SHA3-384withECDSA, SHA3-512withECDDSA, SHA3-512withECDSA, SHA384withCVC-ECDSA, SHA384withECDDSA, SHA384withECDSA, SHA384withPLAIN-ECDSA, SHA512withCVC-ECDSA, SHA512withECDDSA, SHA512withECDSA, SHA512withECNR, SHA512withPLAIN-ECDSA, SM3withSM2 - Curves: B-163, B-233, B-283, B-409, B-571, FRP256v1, GostR3410-2001-CryptoPro-A, GostR3410-2001-CryptoPro-B, GostR3410-2001-CryptoPro-C, GostR3410-2001-CryptoPro-XchA, GostR3410-2001-CryptoPro-XchB, K-163, K-233, K-283, K-409, K-571, P-192, P-224, P-256, P-384, P-521, Tc26-Gost-3410-12-256-paramSetA, Tc26-Gost-3410-12-512-paramSetA, Tc26-Gost-3410-12-512-paramSetB, Tc26-Gost-3410-12-512-paramSetC, brainpoolP160r1, brainpoolP160t1, brainpoolP192r1, brainpoolP192t1, brainpoolP224r1, brainpoolP224t1, brainpoolP256r1, brainpoolP256t1, brainpoolP320r1, brainpoolP320t1, brainpoolP384r1, brainpoolP384t1, brainpoolP512r1, brainpoolP512t1, c2pnb163v1, c2pnb163v2, c2pnb163v3, c2pnb176w1, c2pnb208w1, c2pnb272w1, c2pnb304w1, c2pnb368w1, c2tnb191v1, c2tnb191v2, c2tnb191v3, c2tnb239v1, c2tnb239v2, c2tnb239v3, c2tnb359v1, c2tnb431r1, prime192v1, prime192v2, prime192v3, prime239v1, prime239v2, prime239v3, prime256v1, secp112r1, secp112r2, secp128r1, secp128r2, secp160k1, secp160r1, secp160r2, secp192k1, secp192r1, secp224k1, secp224r1, secp256k1, secp256r1, secp384r1, secp521r1, sect113r1, sect113r2, sect131r1, sect131r2, sect163k1, sect163r1, sect163r2, sect193r1, sect193r2, sect233k1, sect233r1, sect239k1, sect283k1, sect283r1, sect409k1, sect409r1, sect571k1, sect571r1, sm2p256v1, wapi192v1, wapip192v1 - - libtomcrypt 1.18.2 - - Version: 1.000000 + - tomcrypt + - Fullname: libtomcrypt 1.18.2 + - Version: 1.18 - Supports native timing: [cputime-processor, cputime-thread, monotonic, monotonic-raw, rdtsc] + - Supports deterministic PRNG: true - KeyPairGenerators: EC - KeyAgreements: ECDH - Signatures: NONEwithECDSA - Curves: ECC-192, ECC-224, ECC-256, ECC-384, ECC-521, SECP112R1, SECP128R1, SECP160R1 - - Botan 2.19.3 (release, dated 20221116, revision git:15dc32f12d05e99a267f0fc47d88b678b71b8b05, distribution unspecified) - - Version: 2.000000 + - Botan + - Fullname: Botan 2.19.5 + - Version: 2.193 - Supports native timing: [cputime-processor, cputime-thread, monotonic, monotonic-raw, rdtsc] - - KeyPairGenerators: ECGDSA, ECKCDSA, ECDSA, ECDH - - KeyAgreements: ECDHwithSHA384KDF, ECDHwithSHA256KDF, ECDHwithSHA1KDF, ECDHwithSHA224KDF, ECDH, ECDHwithSHA512KDF - - Signatures: NONEwithECDSA, NONEwithECKCDSA, SHA256withECKCDSA, SHA512withECGDSA, SHA256withECDSA, NONEwithECGDSA, ECKCDSA, ECDSA, SHA224withECKCDSA, SHA384withECKCDSA, SHA224withECGDSA, SHA384withECDSA, ECGDSA, SHA384withECGDSA, SHA224withECDSA, SHA512withECDSA, SHA512withECKCDSA + - Supports deterministic PRNG: true + - KeyPairGenerators: ECDH, ECDSA, ECGDSA, ECKCDSA + - KeyAgreements: ECDH, ECDHwithSHA1KDF, ECDHwithSHA224KDF, ECDHwithSHA256KDF, ECDHwithSHA384KDF, ECDHwithSHA512KDF + - Signatures: ECDSA, ECGDSA, ECKCDSA, NONEwithECDSA, NONEwithECGDSA, NONEwithECKCDSA, SHA224withECDSA, SHA224withECGDSA, SHA224withECKCDSA, SHA256withECDSA, SHA256withECKCDSA, SHA384withECDSA, SHA384withECGDSA, SHA384withECKCDSA, SHA512withECDSA, SHA512withECGDSA, SHA512withECKCDSA - Curves: brainpool160r1, brainpool192r1, brainpool224r1, brainpool256r1, brainpool320r1, brainpool384r1, brainpool512r1, frp256v1, gost_256A, gost_512A, secp160k1, secp160r1, secp160r2, secp192k1, secp192r1, secp224k1, secp224r1, secp256k1, secp256r1, secp384r1, secp521r1, sm2p256v1, x962_p192v2, x962_p192v3, x962_p239v1, x962_p239v2, x962_p239v3 - - Crypto++ 8.9.0 - - Version: 8.000000 + - Crypto++ + - Fullname: Crypto++ + - Version: 8.0 - Supports native timing: [cputime-processor, cputime-thread, monotonic, monotonic-raw, rdtsc] - - KeyPairGenerators: ECDSA, ECDH + - Supports deterministic PRNG: true + - KeyPairGenerators: ECDH, ECDSA - KeyAgreements: ECDH - - Signatures: ECDSA, SHA384withECDSA, SHA224withECDSA, SHA512withECDSA, SHA256withECDSA + - Signatures: ECDSA, SHA224withECDSA, SHA256withECDSA, SHA384withECDSA, SHA512withECDSA - Curves: 1.2.156.10197.1.301, 1.2.156.10197.1.301.3.1, 1.2.840.10045.3.1.1, 1.2.840.10045.3.1.7, 1.3.132.0.1, 1.3.132.0.10, 1.3.132.0.15, 1.3.132.0.16, 1.3.132.0.17, 1.3.132.0.2, 1.3.132.0.22, 1.3.132.0.23, 1.3.132.0.24, 1.3.132.0.25, 1.3.132.0.26, 1.3.132.0.27, 1.3.132.0.28, 1.3.132.0.29, 1.3.132.0.3, 1.3.132.0.30, 1.3.132.0.31, 1.3.132.0.32, 1.3.132.0.33, 1.3.132.0.34, 1.3.132.0.35, 1.3.132.0.36, 1.3.132.0.37, 1.3.132.0.38, 1.3.132.0.39, 1.3.132.0.4, 1.3.132.0.5, 1.3.132.0.6, 1.3.132.0.7, 1.3.132.0.8, 1.3.132.0.9, 1.3.36.3.3.2.8.1.1.1, 1.3.36.3.3.2.8.1.1.11, 1.3.36.3.3.2.8.1.1.13, 1.3.36.3.3.2.8.1.1.3, 1.3.36.3.3.2.8.1.1.5, 1.3.36.3.3.2.8.1.1.7, 1.3.36.3.3.2.8.1.1.9 - - OpenSSL 3.2.1 30 Jan 2024 - - Version: 3.200000 + - OpenSSL + - Fullname: OpenSSL 3.2.1 30 Jan 2024 + - Version: 3.2 - Supports native timing: [cputime-processor, cputime-thread, monotonic, monotonic-raw, rdtsc] + - Supports deterministic PRNG: true - KeyPairGenerators: EC - KeyAgreements: ECDH - Signatures: NONEwithECDSA - Curves: Oakley-EC2N-3, Oakley-EC2N-4, SM2, brainpoolP160r1, brainpoolP160t1, brainpoolP192r1, brainpoolP192t1, brainpoolP224r1, brainpoolP224t1, brainpoolP256r1, brainpoolP256t1, brainpoolP320r1, brainpoolP320t1, brainpoolP384r1, brainpoolP384t1, brainpoolP512r1, brainpoolP512t1, c2pnb163v1, c2pnb163v2, c2pnb163v3, c2pnb176v1, c2pnb208w1, c2pnb272w1, c2pnb304w1, c2pnb368w1, c2tnb191v1, c2tnb191v2, c2tnb191v3, c2tnb239v1, c2tnb239v2, c2tnb239v3, c2tnb359v1, c2tnb431r1, prime192v1, prime192v2, prime192v3, prime239v1, prime239v2, prime239v3, prime256v1, secp112r1, secp112r2, secp128r1, secp128r2, secp160k1, secp160r1, secp160r2, secp192k1, secp224k1, secp224r1, secp256k1, secp384r1, secp521r1, sect113r1, sect113r2, sect131r1, sect131r2, sect163k1, sect163r1, sect163r2, sect193r1, sect193r2, sect233k1, sect233r1, sect239k1, sect283k1, sect283r1, sect409k1, sect409r1, sect571k1, sect571r1, wap-wsg-idm-ecid-wtls1, wap-wsg-idm-ecid-wtls10, wap-wsg-idm-ecid-wtls11, wap-wsg-idm-ecid-wtls12, wap-wsg-idm-ecid-wtls3, wap-wsg-idm-ecid-wtls4, wap-wsg-idm-ecid-wtls5, wap-wsg-idm-ecid-wtls6, wap-wsg-idm-ecid-wtls7, wap-wsg-idm-ecid-wtls8, wap-wsg-idm-ecid-wtls9 - - OpenSSL 1.1.1 (compatible; BoringSSL) - - Version: 1.110000 + - BoringSSL + - Fullname: OpenSSL 1.1.1 (compatible; BoringSSL) + - Version: 1.11 - Supports native timing: [cputime-processor, cputime-thread, monotonic, monotonic-raw, rdtsc] + - Supports deterministic PRNG: false - KeyPairGenerators: EC - KeyAgreements: ECDH - Signatures: NONEwithECDSA - Curves: prime256v1, secp224r1, secp384r1, secp521r1 - - libgcrypt 1.10.3-unknown - - Version: 1.000000 + - libgcrypt + - Fullname: libgcrypt 1.11.0-unknown + - Version: 1.11 - Supports native timing: [cputime-processor, cputime-thread, monotonic, monotonic-raw, rdtsc] + - Supports deterministic PRNG: false - KeyPairGenerators: EC - KeyAgreements: ECDH - - Signatures: SHA224withECDDSA, SHA256withECDDSA, NONEwithECDSA, ECDSA, ECDDSA, SHA384withECDSA, SHA512withECDDSA, SHA224withECDSA, SHA512withECDSA, SHA384withECDDSA, SHA256withECDSA + - Signatures: ECDDSA, ECDSA, NONEwithECDSA, SHA224withECDDSA, SHA224withECDSA, SHA256withECDDSA, SHA256withECDSA, SHA384withECDDSA, SHA384withECDSA, SHA512withECDDSA, SHA512withECDSA - Curves: Curve25519, Ed25519, Ed448, GOST2001-CryptoPro-A, GOST2001-CryptoPro-B, GOST2001-CryptoPro-C, GOST2001-test, GOST2012-256-A, GOST2012-512-tc26-A, GOST2012-512-tc26-B, GOST2012-512-tc26-C, GOST2012-512-test, NIST P-192, NIST P-224, NIST P-256, NIST P-384, NIST P-521, X448, brainpoolP160r1, brainpoolP192r1, brainpoolP224r1, brainpoolP256r1, brainpoolP320r1, brainpoolP384r1, brainpoolP512r1, secp256k1, sm2p256v1 - - wolfCrypt JCE Provider - - Version: 1.500000 - - Supports native timing: [] - - KeyAgreements: ECDH - - Signatures: ECDSA, SHA384withECDSA, SHA512withECDSA, SHA256withECDSA - - - Mbed TLS 3.5.2 - - Version: 3.000000 + - mbedTLS + - Fullname: Mbed TLS 3.5.2 + - Version: 3.52 - Supports native timing: [cputime-processor, cputime-thread, monotonic, monotonic-raw, rdtsc] + - Supports deterministic PRNG: true - KeyPairGenerators: EC - KeyAgreements: ECDH - Signatures: NONEwithECDSA - Curves: brainpoolP256r1, brainpoolP384r1, brainpoolP512r1, secp192k1, secp192r1, secp224k1, secp224r1, secp256k1, secp256r1, secp384r1, secp521r1, x25519, x448 - - 2021.7.0 (11.5 ) (-) - - Version: 2021.700000 + - IPPCP + - Fullname: ippCP AVX2 (l9) + - Version: 2021.7 - Supports native timing: [cputime-processor, cputime-thread, monotonic, monotonic-raw, rdtsc] + - Supports deterministic PRNG: true - KeyPairGenerators: EC - KeyAgreements: ECDH - Signatures: NONEwithECDSA - Curves: secp112r1, secp112r2, secp128r1, secp128r2, secp160r1, secp160r2, secp192r1, secp224r1, secp256r1, secp384r1, secp521r1 - Nettle - - Version: 3.900000 + - Fullname: Nettle + - Version: 3.9 - Supports native timing: [cputime-processor, cputime-thread, monotonic, monotonic-raw, rdtsc] + - Supports deterministic PRNG: true - KeyPairGenerators: EC - KeyAgreements: ECDH - Signatures: NONEwithECDSA - Curves: secp192r1, secp224r1, secp256r1, secp384r1, secp521r1 - - LibreSSL 3.9.0 - - Version: 3.900000 + - LibreSSL + - Fullname: LibreSSL 3.9.0 + - Version: 3.9 - Supports native timing: [cputime-processor, cputime-thread, monotonic, monotonic-raw, rdtsc] + - Supports deterministic PRNG: false - KeyPairGenerators: EC - KeyAgreements: ECDH - Signatures: NONEwithECDSA @@ -559,7 +577,7 @@ index;time[nano];pubW;privS Snippet below demonstrates performing 10 ECDSA signatures, without hashing the message (`-t NONEwithECDSA`) on the `secp256r1` curve, with a fixed keypair throught the process (`--fixed`), utilizing the rdtsc instruction to measure duration (`--time-source`) and using the MatrixSSL library. ``` -> java -jar ECTesterStandalone.jar ecdsa -n 10 -t NONEwithECDSA -nc secg/secp256r1 --fixed --time-source rdtsc Matrix +> java -jar ECTesterStandalone.jar ecdsa -n 10 -t NONEwithECDSA -nc secg/secp256r1 --fixed --time-source rdtsc OpenSSL index;signTime[instr];verifyTime[instr];data;pubW;privS;signature[NONE];nonce;verified 0;6785333;18200703;24b064ff5a4d08df6f982d0e139677fb4e66602bea01e381e16d4d3614fd09d5;0429ef9b52fc5c9b8711c938820f4d15d6aab1dcd8aa5a80e754233f23c622a5a174cca795068aff9c979bff7e6f1345b529612a4d16df6adf56b8ac250a1fafc3;54d06d1a79b2b43dc072b96ca7b9f045fda84ac13f74ef81fab0d561a47d11d1;3045022070ca3dfe2017892d23a2301b2465ab387af7999c79de7dae53ec04d1600a25800221009fc9a6fe20c7930b9d8be40424ab4b08fa641f339efa81e6ccf5497cd71180f0;57ebf83913734ff0a78fa952da12996c48da17fbcf5967e74eb3e2c6b5e726b1;1 1;8582180;16170010;24b064ff5a4d08df6f982d0e139677fb4e66602bea01e381e16d4d3614fd09d5;0429ef9b52fc5c9b8711c938820f4d15d6aab1dcd8aa5a80e754233f23c622a5a174cca795068aff9c979bff7e6f1345b529612a4d16df6adf56b8ac250a1fafc3;54d06d1a79b2b43dc072b96ca7b9f045fda84ac13f74ef81fab0d561a47d11d1;3045022100efd3efc1bb2ed243eec9bea4bc331966e869c02df1fc8686a7649708c106595a022050e9a2548bac56bb3287f27c1761136947eefaa8a92f31978ed9485a03cb8f3d;0f5d3cc25d3eb69177b7917631f5639a088773873e91c1adb0a2b753987cace8;1 @@ -571,7 +589,7 @@ index;signTime[instr];verifyTime[instr];data;pubW;privS;signature[NONE];nonce;ve Snippet below demonstrates performing 10000 ECDH key agreements, using the curve name `secp256r1` (`-cn`, the difference between the `-cn` option and the `-nc` option is that the latter looks up the curve in ECTester's database and passes the parameters to the library explicitly, while the former passes the name to the library) using the MbedTLS library. ``` -> java -jar ECTesterStandalone.jar ecdh -n 10000 -cn secp256r1 mbed +> java -jar ECTesterStandalone.jar ecdh -n 10000 -cn secp256r1 mbedTLS index;time[nano];pubW;privS;secret[NONE] 0;5952101;04367ef86b5fbf1b4716bf7822342ebb19a9b6bcfbdb4f4950bf090ba2d1263579dac3e8447c21202432c76f89a0b48a1c16970e4fde67853c8d389da3f02fcdfc;00ecc7b46513149ab19fbeb1c49c1706712dc7da3899add30eb935e18fe5851d79;a94524fa98e0e5b3e139afdb89b73b843e48d5491b19585a5dcae02f20f13088 1;6099022;0439803db68efddbfc3fba1feae41118b02e35d009670fbb4c5dfe6a56fe20829b42e101d0c55bf905276ac71af7e215714cf41742c1f8a2d102761b9eb307d209;6f43118f50ddfef724288ad4f116354bec4735370cb221547b76b18832daaea9;d1b90ed000ca9542ac2101383397a7180cdcd6896b1ccfb5b719da734ad96bf1 @@ -585,6 +603,24 @@ index;time[nano];pubW;privS;secret[NONE] ... ``` +Snippet below demonstrates the support for using a deterministic PRNG (`-ps`) in some of the libraries (see the output of `list-libs`): +``` +> java -jar ECTesterStandalone.jar generate -n 5 -ps 1234 -b 256 Bouncy +index;time[nano];pubW;privS +0;33664582;04db8bdd6cb30d08a0355d48b65ddfc123944d29395f9f5e1bc2bfe70b4ee44ad39e4005df1e61251b4e9a9d8d47b78fd4ce98181883d2bfd634743758397f54ae;00e08df38827302c3315b833022189f61af3af9fbcb6e53697724374861f1982ee +1;3584575;0458bc7baf831c1a316a8deb9fb3109841f10d3cb8828b583b9883a518fa04633488e2fa991e70c98612c989fdfd6aa25118947e8a17bfc36ad1f51a8bdc473e3d;0f5a481f518751bbd2112e4fcc3d1ac60cd66a474af9a57cedbd1e62a52b6bd9 +2;2746750;04827d7247b6d478cc85df313a9ea4f102301b0bd125b18e0111cd02e53b319830b2d0218551504cfc6b1226ac7fa430388f677cab2ea36997e344078328d12207;222898920190d28dac732b8e1fa69dd9907c667604c54db70c41b4815eafc94b +3;2828535;0473104cec678c5ea20857435f19280975c2a3b2d22e7f8005c33d019de6b707012960b96a80f0f358a69dcd5dd34c748cae3fa9f45b720f5a7d241017010c1af1;3fb2f7c3a15f86f000017e42f79557befe7472ff462d3321bc13a043c251345c +4;14181365;04854011114eb3e0fcf21f2416e0adbb0fc81d84530860ca40b6a86c85aa4e66b455382b71f8b6144f6294376912334ff1b23bb49da8fe1bda0e0e89ccbe9145f6;65675a954fff3287be1fc61dbb176f6784ece16c6b5675d556c57fd58974b358 +> java -jar ECTesterStandalone.jar generate -n 5 -ps 1234 -b 256 Bouncy +index;time[nano];pubW;privS +0;35138528;04db8bdd6cb30d08a0355d48b65ddfc123944d29395f9f5e1bc2bfe70b4ee44ad39e4005df1e61251b4e9a9d8d47b78fd4ce98181883d2bfd634743758397f54ae;00e08df38827302c3315b833022189f61af3af9fbcb6e53697724374861f1982ee +1;2351304;0458bc7baf831c1a316a8deb9fb3109841f10d3cb8828b583b9883a518fa04633488e2fa991e70c98612c989fdfd6aa25118947e8a17bfc36ad1f51a8bdc473e3d;0f5a481f518751bbd2112e4fcc3d1ac60cd66a474af9a57cedbd1e62a52b6bd9 +2;3315124;04827d7247b6d478cc85df313a9ea4f102301b0bd125b18e0111cd02e53b319830b2d0218551504cfc6b1226ac7fa430388f677cab2ea36997e344078328d12207;222898920190d28dac732b8e1fa69dd9907c667604c54db70c41b4815eafc94b +3;2883430;0473104cec678c5ea20857435f19280975c2a3b2d22e7f8005c33d019de6b707012960b96a80f0f358a69dcd5dd34c748cae3fa9f45b720f5a7d241017010c1af1;3fb2f7c3a15f86f000017e42f79557befe7472ff462d3321bc13a043c251345c +4;2060970;04854011114eb3e0fcf21f2416e0adbb0fc81d84530860ca40b6a86c85aa4e66b455382b71f8b6144f6294376912334ff1b23bb49da8fe1bda0e0e89ccbe9145f6;65675a954fff3287be1fc61dbb176f6784ece16c6b5675d556c57fd58974b358 +``` + It is recommended to disable [CPU frequency scaling](https://wiki.archlinux.org/index.php/CPU_frequency_scaling) of your processor before performing collection of timing data, as it adds significant noise to the data as it kicks in. Also, running the collection on very high priority and locked to a single core (`taskset -c 0`) helps as well. ## Analysis diff --git a/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java b/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java index de9e65f..bebb3c5 100644 --- a/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java +++ b/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java @@ -5,7 +5,6 @@ import org.junit.jupiter.params.provider.MethodSource; import org.junitpioneer.jupiter.StdIo; import org.junitpioneer.jupiter.StdOut; -import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; -- cgit v1.3.1 From b6c35d175e5d71ec7e3840d984ff77840af9344e Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 7 Aug 2024 22:52:45 +0200 Subject: Continue on test errors. --- .github/workflows/build.yml | 2 +- .../ectester/standalone/test/suites/StandalonePerformanceSuite.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b626eb0..de3f6cb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -189,7 +189,7 @@ jobs: run: ./gradlew standalone:run --args="list-libs" - name: Test - run: ./gradlew standalone:test + run: ./gradlew standalone:test --continue - name: Upload build artifacts uses: actions/upload-artifact@v4 diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java index 909b252..46e4141 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java @@ -38,9 +38,9 @@ public class StandalonePerformanceSuite extends StandaloneTestSuite { @Override protected void runTests() throws Exception { - String kpgAlgo = cli.getOptionValue("test.kpg-type"); - String kaAlgo = cli.getOptionValue("test.ka-type"); - String sigAlgo = cli.getOptionValue("test.sig-type"); + String kpgAlgo = cli.getOptionValue("test.kpg-type", "EC"); + String kaAlgo = cli.getOptionValue("test.ka-type", "ECDH"); + String sigAlgo = cli.getOptionValue("test.sig-type", "ECDSA"); String keyAlgo = cli.getOptionValue("test.key-type", "AES"); List kpgTypes = kpgAlgo != null ? Arrays.asList(kpgAlgo.split(",")) : new ArrayList<>(); -- cgit v1.3.1 From 01ffcfd9770e4fccec022d1b8309a4be9cfbe678 Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 8 Aug 2024 10:06:17 +0200 Subject: Try to see what goes wrong in the tests. --- .github/workflows/build.yml | 17 +++++++++++++++++ standalone/build.gradle.kts | 2 ++ 2 files changed, 19 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index de3f6cb..7594eb8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -205,8 +205,25 @@ jobs: path: | standalone/build/results/ + - name: Upload tests + uses: actions/upload-artifact@v4 + with: + name: tests-standalone-${{ matrix.java }} + path: | + standalone/build/reports/tests/test/ + - name: Upload code coverage uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} slug: crocs-muni/ECTester + + - name: Upload code coverage + uses: codecov/test-results-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + slug: crocs-muni/ECTester + files: >- + standalone/test-results/test/TEST-cz.crcs.ectester.standalone.AppTests.xml, standalone/test-results/test/TEST-cz.crcs.ectester.standalone.DeterministicTests.xml, + standalone/test-results/test/TEST-cz.crcs.ectester.standalone.IdentTests.xml, standalone/test-results/test/TEST-cz.crcs.ectester.standalone.LibTests.xml, + standalone/test-results/test/TEST-cz.crcs.ectester.standalone.OutputTests.xml, diff --git a/standalone/build.gradle.kts b/standalone/build.gradle.kts index d485bcb..35ae3e5 100644 --- a/standalone/build.gradle.kts +++ b/standalone/build.gradle.kts @@ -41,6 +41,8 @@ tasks.named("test") { resultsDir.mkdirs(); } useJUnitPlatform() + ignoreFailures = true + failFast = false // Report is always generated after tests run finalizedBy(tasks.named("testCodeCoverageReport")) -- cgit v1.3.1 From a0702af3b7de96cc14475539099f675d3b098df7 Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 8 Aug 2024 12:01:34 +0200 Subject: Fix test path for codecov. --- .github/workflows/build.yml | 8 ++++---- standalone/build.gradle.kts | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7594eb8..8bfe32c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -218,12 +218,12 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} slug: crocs-muni/ECTester - - name: Upload code coverage + - name: Upload test coverage uses: codecov/test-results-action@v1 with: token: ${{ secrets.CODECOV_TOKEN }} slug: crocs-muni/ECTester files: >- - standalone/test-results/test/TEST-cz.crcs.ectester.standalone.AppTests.xml, standalone/test-results/test/TEST-cz.crcs.ectester.standalone.DeterministicTests.xml, - standalone/test-results/test/TEST-cz.crcs.ectester.standalone.IdentTests.xml, standalone/test-results/test/TEST-cz.crcs.ectester.standalone.LibTests.xml, - standalone/test-results/test/TEST-cz.crcs.ectester.standalone.OutputTests.xml, + standalone/build/test-results/test/TEST-cz.crcs.ectester.standalone.AppTests.xml, standalone/build/test-results/test/TEST-cz.crcs.ectester.standalone.DeterministicTests.xml, + standalone/build/test-results/test/TEST-cz.crcs.ectester.standalone.IdentTests.xml, standalone/build/test-results/test/TEST-cz.crcs.ectester.standalone.LibTests.xml, + standalone/build/test-results/test/TEST-cz.crcs.ectester.standalone.OutputTests.xml diff --git a/standalone/build.gradle.kts b/standalone/build.gradle.kts index 35ae3e5..86ee84f 100644 --- a/standalone/build.gradle.kts +++ b/standalone/build.gradle.kts @@ -53,6 +53,8 @@ tasks.named("test") { jvmArgs("--add-exports", "java.base/sun.security.ec=ALL-UNNAMED") } + jvmArgs("-Xmx8G", "-Xms2G") + // Add wolfcrypt JNI lib path to LD_LIBRARY_PATH (as our native library loading does not handle it) environment( "LD_LIBRARY_PATH", "$rootDir/ext/wolfcrypt-jni/lib/:" + System.getenv("LD_LIBRARY_PATH") -- cgit v1.3.1 From 7465c1dcea1cea7c6dc70eded76272ece7455690 Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 8 Aug 2024 12:28:54 +0200 Subject: Do not ignore failures in standalone tests. --- standalone/build.gradle.kts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/standalone/build.gradle.kts b/standalone/build.gradle.kts index 86ee84f..c5bd604 100644 --- a/standalone/build.gradle.kts +++ b/standalone/build.gradle.kts @@ -41,8 +41,7 @@ tasks.named("test") { resultsDir.mkdirs(); } useJUnitPlatform() - ignoreFailures = true - failFast = false + // Report is always generated after tests run finalizedBy(tasks.named("testCodeCoverageReport")) -- cgit v1.3.1 From 92ddf4c7fa96fb25f27eac9374e60c742f3d82da Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 8 Aug 2024 16:33:52 +0200 Subject: Add preload library for spoofing system RNG outputs. --- .../cz/crcs/ectester/standalone/libs/jni/Makefile | 9 +- .../cz/crcs/ectester/standalone/libs/jni/gcrypt.c | 3 +- .../cz/crcs/ectester/standalone/libs/jni/preload.c | 255 +++++++++++++++++++++ 3 files changed, 263 insertions(+), 4 deletions(-) create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/preload.c diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile index aec0c03..c45c8d8 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile @@ -73,6 +73,9 @@ c_utils.o: c_utils.c lib_timing.so: c_timing.c $(CC) -o $@ -shared $(CFLAGS) -Wl,-soname,lib_timing.so $< +lib_preload.so: preload.c + $(CC) -shared -fPIC -ldl $< -o $@ + lib_csignals.so: c_signals.c $(CC) -o $@ -shared $(CFLAGS) -pthread -lpthread -Wl,-soname,lib_csignals.so $< @@ -99,7 +102,7 @@ boringssl: boringssl_provider.so lib_boringssl.so: cp $(PROJECT_ROOT_PATH)/ext/boringssl/build/crypto/libcrypto.so lib_boringssl.so -boringssl_provider.so: boringssl.o c_utils.o | lib_timing.so lib_csignals.so lib_boringssl.so +boringssl_provider.so: boringssl.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so lib_boringssl.so $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_boringssl.so -l:lib_timing.so -l:lib_csignals.so boringssl.o: boringssl.c @@ -109,7 +112,7 @@ boringssl.o: boringssl.c # libgcrypt shim gcrypt: gcrypt_provider.so -gcrypt_provider.so: gcrypt.o c_utils.o | lib_timing.so lib_csignals.so +gcrypt_provider.so: gcrypt.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. -pthread -lpthread $(shell libgcrypt-config --libs) -l:lib_timing.so -l:lib_csignals.so gcrypt.o: gcrypt.c @@ -192,7 +195,7 @@ libressl: libressl_provider.so lib_libressl.so: cp $(PROJECT_ROOT_PATH)/ext/libressl/build/crypto/libcrypto.so lib_libressl.so -libressl_provider.so: libressl.o c_utils.o | lib_timing.so lib_csignals.so lib_libressl.so +libressl_provider.so: libressl.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so lib_libressl.so $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_libressl.so -l:lib_timing.so -l:lib_csignals.so libressl.o: libressl.c diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/gcrypt.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/gcrypt.c index 795c30a..7be778c 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/gcrypt.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/gcrypt.c @@ -42,6 +42,7 @@ JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_ gcry_control(GCRYCTL_DISABLE_SECMEM, 0); //gcry_control(GCRYCTL_SET_DEBUG_FLAGS, 1); gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0); + gcry_control(GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM); gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); INIT_PROVIDER(env, provider_class); @@ -651,4 +652,4 @@ release_init: gcry_sexp_release(pub_sexp); gcry_sexp_release(data_sexp); return result; -} \ No newline at end of file +} diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/preload.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/preload.c new file mode 100644 index 0000000..ff7b67b --- /dev/null +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/preload.c @@ -0,0 +1,255 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef int (*open_t)(const char *pathname, int flags, ...); +static open_t real_open; +typedef int (*openat_t)(int fd, const char *pathname, int flags, ...); +static openat_t real_openat; +typedef ssize_t (*read_t)(int fd, void *buf, size_t count); +static read_t real_read; +typedef FILE *(*fopen_t)(const char *pathname, const char *mode); +static fopen_t real_fopen; +typedef size_t (*fread_t)(void *ptr, size_t size, size_t nmemb, FILE *stream); +static fread_t real_fread; +typedef ssize_t (*getrandom_t)(void *buf, size_t buflen, unsigned int flags); +static getrandom_t real_getrandom; +typedef int (*getentropy_t)(void *buffer, size_t length); +static getentropy_t real_getentropy; +typedef long (*syscall_t)(long number, ...); +static syscall_t real_syscall; +typedef uint32_t (*arc4random_t)(void); +static arc4random_t real_arc4random; +typedef uint32_t (*arc4random_uniform_t)(uint32_t upper_bound); +static arc4random_uniform_t real_arc4random_uniform; +typedef void (*arc4random_buf_t)(void *buf, size_t n); +static arc4random_buf_t real_arc4random_buf; + +static int *random_fds = NULL; +static size_t random_fds_used = 0; +static size_t random_fds_allocd = 0; + +void check_random_fds() { + if (random_fds_allocd == 0) { + random_fds_allocd = 10; + random_fds = calloc(random_fds_allocd, sizeof(int)); + } else if (random_fds_allocd == random_fds_used) { + random_fds_allocd *= 2; + random_fds = realloc(random_fds, random_fds_allocd * sizeof(int)); + } +} + +void store_random_fd(int fd) { + check_random_fds(); + random_fds[random_fds_used++] = fd; +} + +int open(const char *pathname, int flags, ...) { + if (!real_open) { + real_open = dlsym(RTLD_NEXT, "open"); + } + + va_list args; + va_start(args, flags); + int mode = va_arg(args, int); + va_end(args); + + int result = real_open(pathname, flags, mode); + if (strcmp(pathname, "/dev/random") == 0 || strcmp(pathname, "/dev/urandom") == 0) { + fprintf(stderr, "called open(%s, %i, %i)\n", pathname, flags, mode); + store_random_fd(result); + } + return result; +} + +int openat(int fd, const char *pathname, int flags, ...) { + if (!real_openat) { + real_openat = dlsym(RTLD_NEXT, "openat"); + } + + va_list args; + va_start(args, flags); + int mode = va_arg(args, int); + va_end(args); + + int result = real_openat(fd, pathname, flags, mode); + if (strcmp(pathname, "/dev/random") == 0 || strcmp(pathname, "/dev/urandom") == 0) { + fprintf(stderr, "called openat(%s, %i, %i)\n", pathname, flags, mode); + store_random_fd(result); + } + return result; +} + +ssize_t read(int fd, void *buf, size_t count) { + if (!real_read) { + real_read = dlsym(RTLD_NEXT, "read"); + } + + for (int i = 0; i < random_fds_used; ++i) { + int random_fd = random_fds[i]; + if (random_fd == fd) { + fprintf(stderr, "read from random\n"); + uint8_t *buffer = (uint8_t*)buf; + for (size_t c = 0; c < count; ++c) { + buffer[c] = (uint8_t)0x00; + } + return count; + } + } + + return real_read(fd, buf, count); +} + +static FILE **random_files = NULL; +static size_t random_files_used = 0; +static size_t random_files_allocd = 0; + +void check_random_files() { + if (random_files_allocd == 0) { + random_files_allocd = 10; + random_files = calloc(random_files_allocd, sizeof(FILE *)); + } else if (random_files_allocd == random_files_used) { + random_files_allocd *= 2; + random_files = realloc(random_files, random_files_allocd * sizeof(FILE*)); + } +} + +void store_random_file(FILE *file) { + check_random_files(); + random_files[random_files_used++] = file; +} + +FILE *fopen(const char *pathname, const char *mode) { + if (!real_fopen) { + real_fopen = dlsym(RTLD_NEXT, "fopen"); + } + + FILE *result = real_fopen(pathname, mode); + + if (strcmp(pathname, "/dev/random") == 0 || strcmp(pathname, "/dev/urandom") == 0) { + fprintf(stderr, "called fopen(%s, %s)\n", pathname, mode); + store_random_file(result); + } + return result; +} + +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { + if (!real_fread) { + real_fread = dlsym(RTLD_NEXT, "fread"); + } + + for (int i = 0; i < random_files_used; ++i) { + FILE *random_file = random_files[i]; + if (random_file == stream) { + fprintf(stderr, "fread from random\n"); + uint8_t *buffer = (uint8_t*)ptr; + for (size_t c = 0; c < size * nmemb; ++c) { + buffer[c] = (uint8_t)0x00; + } + return size * nmemb; + } + } + + return real_fread(ptr, size, nmemb, stream); +} + +ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) { + if (!real_getrandom) { + real_getrandom = dlsym(RTLD_NEXT, "getrandom"); + } + + fprintf(stderr, "called getrandom(*, %lu, %u)\n", buflen, flags); + uint8_t *buffer = (uint8_t*)buf; + for (size_t i = 0; i < buflen; ++i) { + buffer[i] = (uint8_t)0x00; + } + return buflen; +} + +int getentropy(void *buffer, size_t length) { + if (!real_getentropy) { + real_getentropy = dlsym(RTLD_NEXT, "getentropy"); + } + + fprintf(stderr, "called getentropy(*, %lu)\n", length); + uint8_t *buf = (uint8_t*)buffer; + for (size_t i = 0; i < length; ++i) { + buf[i] = (uint8_t)0x00; + } + return 0; +} + +long syscall(long number, ...) { + if (!real_syscall) { + real_syscall = dlsym(RTLD_NEXT, "syscall"); + } + va_list args; + + va_start(args, number); + long int a0 = va_arg(args, long int); + long int a1 = va_arg(args, long int); + long int a2 = va_arg(args, long int); + long int a3 = va_arg(args, long int); + long int a4 = va_arg(args, long int); + long int a5 = va_arg(args, long int); + va_end(args); + + if (number == SYS_getrandom) { + fprintf(stderr, "called syscall(getrandom, %li, %li, %li, %li, %li, %li)\n", a0, a1, a2, a3, a4, a5); + uint8_t *buf = (uint8_t*)a0; + long n = a1; + for (size_t i = 0; i < n; ++i) { + buf[i] = (uint8_t)0x00; + } + return n; + } + return real_syscall(number, a0, a1, a2, a3, a4, a5); +} + +uint32_t arc4random(void) { + if (!real_arc4random) { + real_arc4random = dlsym(RTLD_NEXT, "arc4random"); + } + + fprintf(stderr, "called arc4random\n"); + return 0; +} + +uint32_t arc4random_uniform(uint32_t upper_bound) { + if (!real_arc4random_uniform) { + real_arc4random_uniform = dlsym(RTLD_NEXT, "arc4random_uniform"); + } + + fprintf(stderr, "called arc4random_uniform(%u)\n", upper_bound); + return 0; +} + +void arc4random_buf(void *buf, size_t n) { + if (!real_arc4random_buf) { + real_arc4random_buf = dlsym(RTLD_NEXT, "arc4random_buf"); + } + + fprintf(stderr, "called arc4random_buf(%p, %lu)\n", buf, n); + uint8_t *buffer = (uint8_t*)buf; + for (size_t i = 0; i < n; ++i) { + buffer[i] = (uint8_t)0x00; + } +} + + +void __attribute__((destructor)) dealloc() { + if (random_fds != NULL) { + free(random_fds); + } + if (random_files != NULL) { + free(random_files); + } +} -- cgit v1.3.1 From 960b3c6f01876719c8642ff4b3d8fd76e2de3f9b Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 8 Aug 2024 17:04:49 +0200 Subject: Make gcrypt amenable to deterministic RNG by enabling FIPS PRNG. --- .../cz/crcs/ectester/standalone/libs/jni/Makefile | 14 +++++++------- .../cz/crcs/ectester/standalone/libs/jni/gcrypt.c | 5 ++--- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile index c45c8d8..d243f68 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile @@ -89,7 +89,7 @@ cpp_utils.o: cpp_utils.cpp # OpenSSL shim openssl: openssl_provider.so -openssl_provider.so: openssl.o c_utils.o | lib_timing.so lib_csignals.so +openssl_provider.so: openssl.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs openssl) -l:lib_timing.so -l:lib_csignals.so openssl.o: openssl.c @@ -122,7 +122,7 @@ gcrypt.o: gcrypt.c # Libtomcrypt shim tomcrypt: tomcrypt_provider.so -tomcrypt_provider.so: tomcrypt.o c_utils.o | lib_timing.so lib_csignals.so +tomcrypt_provider.so: tomcrypt.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. -ltommath $(shell pkg-config --libs libtomcrypt) -l:lib_timing.so -l:lib_csignals.so tomcrypt.o: tomcrypt.c @@ -132,7 +132,7 @@ tomcrypt.o: tomcrypt.c # Botan-2 shim botan: botan_provider.so -botan_provider.so: botan.o cpp_utils.o | lib_timing.so lib_cppsignals.so +botan_provider.so: botan.o cpp_utils.o | lib_timing.so lib_cppsignals.so lib_preload.so $(CXX) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs botan-2) -l:lib_timing.so -l:lib_cppsignals.so botan.o: botan.cpp @@ -146,7 +146,7 @@ ifeq ($(shell pkg-config --exists $(CRYPTOPP_NAME); echo $$?),1) endif cryptopp: cryptopp_provider.so -cryptopp_provider.so: cryptopp.o cpp_utils.o | lib_timing.so lib_cppsignals.so +cryptopp_provider.so: cryptopp.o cpp_utils.o | lib_timing.so lib_cppsignals.so lib_preload.so $(CXX) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs $(CRYPTOPP_NAME)) -l:lib_timing.so -l:lib_cppsignals.so cryptopp.o: cryptopp.cpp @@ -159,7 +159,7 @@ mbedtls: mbedtls_provider.so lib_mbedtls.so: cp $(PROJECT_ROOT_PATH)/ext/mbedtls/build/library/libmbedcrypto.so lib_mbedtls.so -mbedtls_provider.so: mbedtls.o c_utils.o | lib_timing.so lib_csignals.so lib_mbedtls.so +mbedtls_provider.so: mbedtls.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so lib_mbedtls.so $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_mbedtls.so -l:lib_timing.so -l:lib_csignals.so mbedtls.o: mbedtls.c @@ -172,7 +172,7 @@ ippcp: ippcp_provider.so lib_ippcp.so: cp $(PROJECT_ROOT_PATH)/ext/ipp-crypto/build/.build/RELEASE/lib/libippcp.so lib_ippcp.so -ippcp_provider.so: ippcp.o c_utils.o | lib_timing.so lib_csignals.so lib_ippcp.so +ippcp_provider.so: ippcp.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so lib_ippcp.so $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_ippcp.so -l:lib_timing.so -l:lib_csignals.so ippcp.o: ippcp.c @@ -182,7 +182,7 @@ ippcp.o: ippcp.c # Nettle shim nettle: nettle_provider.so -nettle_provider.so: nettle.o c_utils.o | lib_timing.so lib_csignals.so +nettle_provider.so: nettle.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs nettle) -l:lib_timing.so -l:lib_csignals.so $(shell pkg-config --libs hogweed) -lgmp nettle.o: nettle.c diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/gcrypt.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/gcrypt.c index 7be778c..40376f9 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/gcrypt.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/gcrypt.c @@ -25,6 +25,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_GcryptLib_create jmethodID init = (*env)->GetMethodID(env, local_provider_class, "", "(Ljava/lang/String;DLjava/lang/String;)V"); + gcry_control(GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS); const char *running_with = gcry_check_version(GCRYPT_VERSION); if (!running_with) { return NULL; @@ -40,10 +41,8 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_GcryptLib_create JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Gcrypt_setup(JNIEnv *env, jobject this) { gcry_control(GCRYCTL_DISABLE_SECMEM, 0); - //gcry_control(GCRYCTL_SET_DEBUG_FLAGS, 1); - gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0); - gcry_control(GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM); gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); + //gcry_control(GCRYCTL_SET_DEBUG_FLAGS, 1); INIT_PROVIDER(env, provider_class); -- cgit v1.3.1 From 97169fc1c9c493e829aa81d36b30f38583f4afc1 Mon Sep 17 00:00:00 2001 From: quapka Date: Fri, 9 Aug 2024 16:35:52 +0200 Subject: Fallback to HOME enviromental var --- common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java b/common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java index da682b6..982dbed 100644 --- a/common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java +++ b/common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java @@ -50,10 +50,10 @@ public class FileUtil { if (dataHome != null) { appData = Paths.get(dataHome); } else { - appData = Paths.get(System.getProperty("user.home"), ".local", "share"); + appData = Paths.get(System.getenv("HOME"), ".local", "share"); } } else { - appData = Paths.get(System.getProperty("user.home"), ".local", "share"); + appData = Paths.get(System.getenv("HOME"), ".local", "share"); } } return appData; -- cgit v1.3.1 From 77469ff0f8daaa1c47719d88885d5a66431cdce5 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 9 Aug 2024 16:42:32 +0200 Subject: Add deterministic PRNG via preload of RNG functions. --- standalone/build.gradle.kts | 4 + .../ectester/standalone/ECTesterStandalone.java | 50 +++- .../ectester/standalone/libs/BoringsslLib.java | 6 + .../crcs/ectester/standalone/libs/GcryptLib.java | 6 + .../crcs/ectester/standalone/libs/LibresslLib.java | 6 + .../ectester/standalone/libs/NativeECLibrary.java | 3 + .../cz/crcs/ectester/standalone/libs/jni/Makefile | 37 ++- .../crcs/ectester/standalone/libs/jni/c_preload.c | 316 +++++++++++++++++++++ .../cz/crcs/ectester/standalone/libs/jni/c_prng.c | 18 ++ .../cz/crcs/ectester/standalone/libs/jni/native.h | 8 + .../cz/crcs/ectester/standalone/libs/jni/preload.c | 255 ----------------- .../standalone/libs/jni/prng/KeccakDuplex-common.h | 37 +++ .../standalone/libs/jni/prng/KeccakDuplex.inc | 192 +++++++++++++ .../libs/jni/prng/KeccakDuplexWidth200.c | 29 ++ .../libs/jni/prng/KeccakDuplexWidth200.h | 25 ++ .../standalone/libs/jni/prng/KeccakP-200-SnP.h | 34 +++ .../standalone/libs/jni/prng/KeccakP-200-compact.c | 187 ++++++++++++ .../standalone/libs/jni/prng/KeccakPRG-common.h | 28 ++ .../ectester/standalone/libs/jni/prng/KeccakPRG.h | 20 ++ .../standalone/libs/jni/prng/KeccakPRG.inc | 123 ++++++++ .../standalone/libs/jni/prng/KeccakPRGWidth200.c | 22 ++ .../standalone/libs/jni/prng/KeccakPRGWidth200.h | 24 ++ .../crcs/ectester/standalone/libs/jni/prng/align.h | 32 +++ .../crcs/ectester/standalone/libs/jni/prng/prng.c | 21 ++ .../crcs/ectester/standalone/libs/jni/prng/prng.h | 13 + .../ectester/standalone/DeterministicTests.java | 4 +- 26 files changed, 1228 insertions(+), 272 deletions(-) create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_preload.c create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_prng.c create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplex-common.h create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplex.inc create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplexWidth200.c create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplexWidth200.h create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakP-200-SnP.h create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakP-200-compact.c create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRG-common.h create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRG.h create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRG.inc create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRGWidth200.c create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRGWidth200.h create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/align.h create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/prng.c create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/prng.h diff --git a/standalone/build.gradle.kts b/standalone/build.gradle.kts index c5bd604..07bf2ab 100644 --- a/standalone/build.gradle.kts +++ b/standalone/build.gradle.kts @@ -58,6 +58,10 @@ tasks.named("test") { environment( "LD_LIBRARY_PATH", "$rootDir/ext/wolfcrypt-jni/lib/:" + System.getenv("LD_LIBRARY_PATH") ) + // Add our preload to tests, so they do not need to start another process. + environment( + "LD_PRELOAD", "$rootDir/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/lib_preload.so" + ) // Add a path where we will store our test results. environment( "RESULT_PATH", resultsDir.absolutePath diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java index dc61192..6822a30 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -23,6 +23,7 @@ */ package cz.crcs.ectester.standalone; +import com.sun.source.tree.StringTemplateTree; import cz.crcs.ectester.common.cli.*; import cz.crcs.ectester.common.ec.EC_Consts; import cz.crcs.ectester.common.ec.EC_Curve; @@ -105,12 +106,52 @@ public class ECTesterStandalone { if (!System.getProperty("os.name").startsWith("Windows")) { FileUtil.write(LIB_RESOURCE_DIR + "lib_timing.so", reqs.resolve("lib_timing.so")); - System.load(reqs.resolve("lib_timing.so").toString()); - + FileUtil.write(LIB_RESOURCE_DIR + "lib_preload.so", reqs.resolve("lib_preload.so")); + FileUtil.write(LIB_RESOURCE_DIR + "lib_prng.so", reqs.resolve("lib_prng.so")); FileUtil.write(LIB_RESOURCE_DIR + "lib_csignals.so", reqs.resolve("lib_csignals.so")); - System.load(reqs.resolve("lib_csignals.so").toString()); FileUtil.write(LIB_RESOURCE_DIR + "lib_cppsignals.so", reqs.resolve("lib_cppsignals.so")); - System.load(reqs.resolve("lib_cppsignals.so").toString()); + + String preloadLibPath = reqs.resolve("lib_preload.so").toAbsolutePath().toString(); + String preload = System.getenv("LD_PRELOAD"); + if (preload == null && !cli.hasOption("no-preload")) { + ProcessBuilder builder = new ProcessBuilder(); + Map env = builder.environment(); + env.put("LD_PRELOAD", preloadLibPath); + + ProcessHandle.Info info = ProcessHandle.current().info(); + List argList = new LinkedList<>(); + if (info.command().isPresent()) { + argList.add(info.command().get()); + } else { + System.err.println("Cannot locate command to spawn preloaded-subprocess."); + return; + } + if (info.arguments().isPresent()) { + argList.addAll(List.of(info.arguments().get())); + } else { + System.err.println("Cannot locate arguments to spawn preloaded-subprocess."); + return; + } + builder.command(argList); + builder.inheritIO(); + + Process process = builder.start(); + int result; + while (true) { + try { + result = process.waitFor(); + break; + } catch (InterruptedException ignored) { + } + } + System.exit(result); + } else { + // Load the utility libs. + System.load(reqs.resolve("lib_prng.so").toString()); + System.load(reqs.resolve("lib_timing.so").toString()); + System.load(reqs.resolve("lib_csignals.so").toString()); + System.load(reqs.resolve("lib_cppsignals.so").toString()); + } } List libObjects = new LinkedList<>(); @@ -296,6 +337,7 @@ public class ECTesterStandalone { opts.addOption(Option.builder("V").longOpt("version").desc("Print version info.").build()); opts.addOption(Option.builder("h").longOpt("help").desc("Print help(about ).").hasArg().argName("command").optionalArg(true).build()); opts.addOption(Option.builder("C").longOpt("color").desc("Print stuff with color, requires ANSI terminal.").build()); + opts.addOption(Option.builder().longOpt("no-preload").desc("Do not use LD_PRELOAD.").build()); return optParser.parse(opts, args); } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/BoringsslLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/BoringsslLib.java index af4d969..06e6b4a 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/BoringsslLib.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/BoringsslLib.java @@ -16,4 +16,10 @@ public class BoringsslLib extends NativeECLibrary { @Override public native Set getCurves(); + + @Override + public boolean supportsDeterministicPRNG() { + // This is provided by the native preload that hooks all randomness sources. + return true; + } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/GcryptLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/GcryptLib.java index 83d78ef..d1452a9 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/GcryptLib.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/GcryptLib.java @@ -17,4 +17,10 @@ public class GcryptLib extends NativeECLibrary { @Override public native Set getCurves(); + + @Override + public boolean supportsDeterministicPRNG() { + // This is provided by the native preload that hooks all randomness sources. + return true; + } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/LibresslLib.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/LibresslLib.java index 2dba049..e53399c 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/LibresslLib.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/LibresslLib.java @@ -16,4 +16,10 @@ public class LibresslLib extends NativeECLibrary { @Override public native Set getCurves(); + + @Override + public boolean supportsDeterministicPRNG() { + // This is provided by the native preload that hooks all randomness sources. + return true; + } } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NativeECLibrary.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NativeECLibrary.java index c11dbdb..fb4e430 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NativeECLibrary.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/NativeECLibrary.java @@ -86,5 +86,8 @@ public abstract class NativeECLibrary extends ProviderECLibrary { @Override public native long getLastNativeTiming(); + @Override + public native boolean setupDeterministicPRNG(byte[] seed); + abstract Provider createProvider(); } diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile index d243f68..f947c78 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile @@ -73,8 +73,17 @@ c_utils.o: c_utils.c lib_timing.so: c_timing.c $(CC) -o $@ -shared $(CFLAGS) -Wl,-soname,lib_timing.so $< -lib_preload.so: preload.c - $(CC) -shared -fPIC -ldl $< -o $@ +prng.o: prng/prng.c + $(CC) $(CFLAGS) -c $< + +lib_prng.so: c_prng.c + $(CC) -o $@ -shared -Wl,-soname,lib_prng.so $(CFLAGS) $< + +c_preload.o: c_preload.c + $(CC) $(CFLAGS) -c $< + +lib_preload.so: c_preload.o prng.o + $(CC) -o $@ -shared $(CFLAGS) -ldl -Wl,-soname,lib_preload.so $^ lib_csignals.so: c_signals.c $(CC) -o $@ -shared $(CFLAGS) -pthread -lpthread -Wl,-soname,lib_csignals.so $< @@ -86,10 +95,14 @@ cpp_utils.o: cpp_utils.cpp $(CXX) $(CXXFLAGS) -c $< +clibs: lib_timing.so lib_csignals.so lib_preload.so lib_prng.so + +cpplibs: lib_timing.so lib_cppsignals.so lib_preload.so lib_prng.so + # OpenSSL shim openssl: openssl_provider.so -openssl_provider.so: openssl.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so +openssl_provider.so: openssl.o c_utils.o | clibs $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs openssl) -l:lib_timing.so -l:lib_csignals.so openssl.o: openssl.c @@ -102,7 +115,7 @@ boringssl: boringssl_provider.so lib_boringssl.so: cp $(PROJECT_ROOT_PATH)/ext/boringssl/build/crypto/libcrypto.so lib_boringssl.so -boringssl_provider.so: boringssl.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so lib_boringssl.so +boringssl_provider.so: boringssl.o c_utils.o | clibs lib_boringssl.so $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_boringssl.so -l:lib_timing.so -l:lib_csignals.so boringssl.o: boringssl.c @@ -112,7 +125,7 @@ boringssl.o: boringssl.c # libgcrypt shim gcrypt: gcrypt_provider.so -gcrypt_provider.so: gcrypt.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so +gcrypt_provider.so: gcrypt.o c_utils.o | clibs $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. -pthread -lpthread $(shell libgcrypt-config --libs) -l:lib_timing.so -l:lib_csignals.so gcrypt.o: gcrypt.c @@ -122,7 +135,7 @@ gcrypt.o: gcrypt.c # Libtomcrypt shim tomcrypt: tomcrypt_provider.so -tomcrypt_provider.so: tomcrypt.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so +tomcrypt_provider.so: tomcrypt.o c_utils.o | clibs $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. -ltommath $(shell pkg-config --libs libtomcrypt) -l:lib_timing.so -l:lib_csignals.so tomcrypt.o: tomcrypt.c @@ -132,7 +145,7 @@ tomcrypt.o: tomcrypt.c # Botan-2 shim botan: botan_provider.so -botan_provider.so: botan.o cpp_utils.o | lib_timing.so lib_cppsignals.so lib_preload.so +botan_provider.so: botan.o cpp_utils.o | cpplibs $(CXX) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs botan-2) -l:lib_timing.so -l:lib_cppsignals.so botan.o: botan.cpp @@ -146,7 +159,7 @@ ifeq ($(shell pkg-config --exists $(CRYPTOPP_NAME); echo $$?),1) endif cryptopp: cryptopp_provider.so -cryptopp_provider.so: cryptopp.o cpp_utils.o | lib_timing.so lib_cppsignals.so lib_preload.so +cryptopp_provider.so: cryptopp.o cpp_utils.o | cpplibs $(CXX) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs $(CRYPTOPP_NAME)) -l:lib_timing.so -l:lib_cppsignals.so cryptopp.o: cryptopp.cpp @@ -159,7 +172,7 @@ mbedtls: mbedtls_provider.so lib_mbedtls.so: cp $(PROJECT_ROOT_PATH)/ext/mbedtls/build/library/libmbedcrypto.so lib_mbedtls.so -mbedtls_provider.so: mbedtls.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so lib_mbedtls.so +mbedtls_provider.so: mbedtls.o c_utils.o | clibs lib_mbedtls.so $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_mbedtls.so -l:lib_timing.so -l:lib_csignals.so mbedtls.o: mbedtls.c @@ -172,7 +185,7 @@ ippcp: ippcp_provider.so lib_ippcp.so: cp $(PROJECT_ROOT_PATH)/ext/ipp-crypto/build/.build/RELEASE/lib/libippcp.so lib_ippcp.so -ippcp_provider.so: ippcp.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so lib_ippcp.so +ippcp_provider.so: ippcp.o c_utils.o | clibs lib_ippcp.so $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_ippcp.so -l:lib_timing.so -l:lib_csignals.so ippcp.o: ippcp.c @@ -182,7 +195,7 @@ ippcp.o: ippcp.c # Nettle shim nettle: nettle_provider.so -nettle_provider.so: nettle.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so +nettle_provider.so: nettle.o c_utils.o | clibs $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs nettle) -l:lib_timing.so -l:lib_csignals.so $(shell pkg-config --libs hogweed) -lgmp nettle.o: nettle.c @@ -195,7 +208,7 @@ libressl: libressl_provider.so lib_libressl.so: cp $(PROJECT_ROOT_PATH)/ext/libressl/build/crypto/libcrypto.so lib_libressl.so -libressl_provider.so: libressl.o c_utils.o | lib_timing.so lib_csignals.so lib_preload.so lib_libressl.so +libressl_provider.so: libressl.o c_utils.o | clibs lib_libressl.so $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_libressl.so -l:lib_timing.so -l:lib_csignals.so libressl.o: libressl.c diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_preload.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_preload.c new file mode 100644 index 0000000..1f597a3 --- /dev/null +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_preload.c @@ -0,0 +1,316 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "native.h" +#include "prng/prng.h" + + +#ifdef DEBUG_PRELOAD + +void print_buf(uint8_t *buf, size_t len) { + for (int i = 0; i < len; ++i) { + fprintf(stderr, "%02x ", buf[i]); + } + fprintf(stderr, "\n"); +} + +#else + +#define print_buf(buf, len) + +#endif + +typedef int (*open_t)(const char *pathname, int flags, ...); +static open_t real_open; +typedef int (*openat_t)(int fd, const char *pathname, int flags, ...); +static openat_t real_openat; +typedef ssize_t (*read_t)(int fd, void *buf, size_t count); +static read_t real_read; +typedef FILE *(*fopen_t)(const char *pathname, const char *mode); +static fopen_t real_fopen; +typedef size_t (*fread_t)(void *ptr, size_t size, size_t nmemb, FILE *stream); +static fread_t real_fread; +typedef ssize_t (*getrandom_t)(void *buf, size_t buflen, unsigned int flags); +static getrandom_t real_getrandom; +typedef int (*getentropy_t)(void *buffer, size_t length); +static getentropy_t real_getentropy; +typedef long (*syscall_t)(long number, ...); +static syscall_t real_syscall; +typedef uint32_t (*arc4random_t)(void); +static arc4random_t real_arc4random; +typedef uint32_t (*arc4random_uniform_t)(uint32_t upper_bound); +static arc4random_uniform_t real_arc4random_uniform; +typedef void (*arc4random_buf_t)(void *buf, size_t n); +static arc4random_buf_t real_arc4random_buf; + +prng_state preload_prng_state; +bool preload_prng_enabled = false; + +static int *random_fds = NULL; +static size_t random_fds_used = 0; +static size_t random_fds_allocd = 0; + +void check_random_fds() { + if (random_fds_allocd == 0) { + random_fds_allocd = 10; + random_fds = calloc(random_fds_allocd, sizeof(int)); + } else if (random_fds_allocd == random_fds_used) { + random_fds_allocd *= 2; + random_fds = realloc(random_fds, random_fds_allocd * sizeof(int)); + } +} + +void store_random_fd(int fd) { + check_random_fds(); + random_fds[random_fds_used++] = fd; +} + +int open(const char *pathname, int flags, ...) { + if (!real_open) { + real_open = dlsym(RTLD_NEXT, "open"); + } + + va_list args; + va_start(args, flags); + int mode = va_arg(args, int); + va_end(args); + + int result = real_open(pathname, flags, mode); + if (strcmp(pathname, "/dev/random") == 0 || strcmp(pathname, "/dev/urandom") == 0) { +#ifdef DEBUG_PRELOAD + fprintf(stderr, "called open(%s, %i, %i)\n", pathname, flags, mode); +#endif + store_random_fd(result); + } + return result; +} + +int openat(int fd, const char *pathname, int flags, ...) { + if (!real_openat) { + real_openat = dlsym(RTLD_NEXT, "openat"); + } + + va_list args; + va_start(args, flags); + int mode = va_arg(args, int); + va_end(args); + + int result = real_openat(fd, pathname, flags, mode); + if (strcmp(pathname, "/dev/random") == 0 || strcmp(pathname, "/dev/urandom") == 0) { +#ifdef DEBUG_PRELOAD + fprintf(stderr, "called openat(%s, %i, %i)\n", pathname, flags, mode); +#endif + store_random_fd(result); + } + return result; +} + +ssize_t read(int fd, void *buf, size_t count) { + if (!real_read) { + real_read = dlsym(RTLD_NEXT, "read"); + } + + if (preload_prng_enabled) { + for (int i = 0; i < random_fds_used; ++i) { + int random_fd = random_fds[i]; + if (random_fd == fd) { + prng_get(&preload_prng_state, buf, count); +#ifdef DEBUG_PRELOAD + fprintf(stderr, "read from random\n"); + print_buf(buf, count); +#endif + return count; + } + } + } + + return real_read(fd, buf, count); +} + +static FILE **random_files = NULL; +static size_t random_files_used = 0; +static size_t random_files_allocd = 0; + +void check_random_files() { + if (random_files_allocd == 0) { + random_files_allocd = 10; + random_files = calloc(random_files_allocd, sizeof(FILE *)); + } else if (random_files_allocd == random_files_used) { + random_files_allocd *= 2; + random_files = realloc(random_files, random_files_allocd * sizeof(FILE*)); + } +} + +void store_random_file(FILE *file) { + check_random_files(); + random_files[random_files_used++] = file; +} + +FILE *fopen(const char *pathname, const char *mode) { + if (!real_fopen) { + real_fopen = dlsym(RTLD_NEXT, "fopen"); + } + + FILE *result = real_fopen(pathname, mode); + + if (strcmp(pathname, "/dev/random") == 0 || strcmp(pathname, "/dev/urandom") == 0) { +#ifdef DEBUG_PRELOAD + fprintf(stderr, "called fopen(%s, %s)\n", pathname, mode); +#endif + store_random_file(result); + } + return result; +} + +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { + if (!real_fread) { + real_fread = dlsym(RTLD_NEXT, "fread"); + } + + if (preload_prng_enabled) { + for (int i = 0; i < random_files_used; ++i) { + FILE *random_file = random_files[i]; + if (random_file == stream) { + prng_get(&preload_prng_state, ptr, size * nmemb); +#ifdef DEBUG_PRELOAD + fprintf(stderr, "fread from random\n"); + print_buf(ptr, size * nmemb); +#endif + return size * nmemb; + } + } + } + + return real_fread(ptr, size, nmemb, stream); +} + +ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) { + if (!real_getrandom) { + real_getrandom = dlsym(RTLD_NEXT, "getrandom"); + } + +#ifdef DEBUG_PRELOAD + fprintf(stderr, "called getrandom(*, %lu, %u)\n", buflen, flags); +#endif + if (preload_prng_enabled) { + prng_get(&preload_prng_state, buf, buflen); + print_buf(buf, buflen); + return buflen; + } else { + return real_getrandom(buf, buflen, flags); + } +} + +int getentropy(void *buffer, size_t length) { + if (!real_getentropy) { + real_getentropy = dlsym(RTLD_NEXT, "getentropy"); + } + +#ifdef DEBUG_PRELOAD + fprintf(stderr, "called getentropy(*, %lu)\n", length); +#endif + if (preload_prng_enabled) { + prng_get(&preload_prng_state, buffer, length); + print_buf(buffer, length); + return 0; + } else { + return real_getentropy(buffer, length); + } +} + +long syscall(long number, ...) { + if (!real_syscall) { + real_syscall = dlsym(RTLD_NEXT, "syscall"); + } + va_list args; + + va_start(args, number); + long int a0 = va_arg(args, long int); + long int a1 = va_arg(args, long int); + long int a2 = va_arg(args, long int); + long int a3 = va_arg(args, long int); + long int a4 = va_arg(args, long int); + long int a5 = va_arg(args, long int); + va_end(args); + + if (number == SYS_getrandom) { +#ifdef DEBUG_PRELOAD + fprintf(stderr, "called syscall(getrandom, %li, %li, %li, %li, %li, %li)\n", a0, a1, a2, a3, a4, a5); +#endif + if (preload_prng_enabled) { + uint8_t *buf = (uint8_t*)a0; + long n = a1; + prng_get(&preload_prng_state, buf, n); + print_buf(buf, n); + return n; + } + } + return real_syscall(number, a0, a1, a2, a3, a4, a5); +} + +uint32_t arc4random(void) { + if (!real_arc4random) { + real_arc4random = dlsym(RTLD_NEXT, "arc4random"); + } + +#ifdef DEBUG_PRELOAD + fprintf(stderr, "called arc4random\n"); +#endif + if (preload_prng_enabled) { + uint32_t val = 0; + prng_get(&preload_prng_state, (uint8_t*)&val, sizeof(val)); +#ifdef DEBUG_PRELOAD + fprintf(stderr, "%u\n", val); +#endif + return val; + } else { + return real_arc4random(); + } +} + +uint32_t arc4random_uniform(uint32_t upper_bound) { + if (!real_arc4random_uniform) { + real_arc4random_uniform = dlsym(RTLD_NEXT, "arc4random_uniform"); + } + +#ifdef DEBUG_PRELOAD + fprintf(stderr, "called arc4random_uniform(%u)\n", upper_bound); +#endif + if (preload_prng_enabled) { + uint64_t val = 0; + prng_get(&preload_prng_state, (uint8_t*)&val, sizeof(val)); + uint32_t result = (uint32_t)(val % (uint64_t)upper_bound); +#ifdef DEBUG_PRELOAD + fprintf(stderr, "%u\n", result); +#endif + return result; + } else { + return real_arc4random_uniform(upper_bound); + } +} + +void arc4random_buf(void *buf, size_t n) { + if (!real_arc4random_buf) { + real_arc4random_buf = dlsym(RTLD_NEXT, "arc4random_buf"); + } + +#ifdef DEBUG_PRELOAD + fprintf(stderr, "called arc4random_buf(%p, %lu) = ", buf, n); +#endif + if (preload_prng_enabled) { + prng_get(&preload_prng_state, buf, n); + print_buf(buf, n); + } else { + real_arc4random_buf(buf, n); + } +} \ No newline at end of file diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_prng.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_prng.c new file mode 100644 index 0000000..13bd172 --- /dev/null +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_prng.c @@ -0,0 +1,18 @@ +#include +#include +#include "prng/prng.h" + +extern prng_state preload_prng_state; +extern bool preload_prng_enabled; + +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_NativeECLibrary_setupDeterministicPRNG(JNIEnv *env, jobject self, jbyteArray seed) { + jsize seed_length = (*env)->GetArrayLength(env, seed); + jbyte *seed_data = (*env)->GetByteArrayElements(env, seed, NULL); + + preload_prng_enabled = true; + prng_init(&preload_prng_state); + prng_seed(&preload_prng_state, seed_data, seed_length); + + (*env)->ReleaseByteArrayElements(env, seed, seed_data, JNI_ABORT); + return JNI_TRUE; +} \ No newline at end of file diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h index 91cada9..881243f 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h @@ -47,6 +47,14 @@ JNIEXPORT jstring JNICALL Java_cz_crcs_ectester_standalone_libs_NativeECLibrary_ JNIEXPORT jlong JNICALL Java_cz_crcs_ectester_standalone_libs_NativeECLibrary_getLastNativeTiming (JNIEnv *, jobject); +/* + * Class: cz_crcs_ectester_standalone_libs_NativeECLibrary + * Method: setupDeterministicPRNG + * Signature: ([B)Z + */ +JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_NativeECLibrary_setupDeterministicPRNG + (JNIEnv *, jobject, jbyteArray); + #ifdef __cplusplus } #endif diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/preload.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/preload.c index ff7b67b..e69de29 100644 --- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/preload.c +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/preload.c @@ -1,255 +0,0 @@ -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef int (*open_t)(const char *pathname, int flags, ...); -static open_t real_open; -typedef int (*openat_t)(int fd, const char *pathname, int flags, ...); -static openat_t real_openat; -typedef ssize_t (*read_t)(int fd, void *buf, size_t count); -static read_t real_read; -typedef FILE *(*fopen_t)(const char *pathname, const char *mode); -static fopen_t real_fopen; -typedef size_t (*fread_t)(void *ptr, size_t size, size_t nmemb, FILE *stream); -static fread_t real_fread; -typedef ssize_t (*getrandom_t)(void *buf, size_t buflen, unsigned int flags); -static getrandom_t real_getrandom; -typedef int (*getentropy_t)(void *buffer, size_t length); -static getentropy_t real_getentropy; -typedef long (*syscall_t)(long number, ...); -static syscall_t real_syscall; -typedef uint32_t (*arc4random_t)(void); -static arc4random_t real_arc4random; -typedef uint32_t (*arc4random_uniform_t)(uint32_t upper_bound); -static arc4random_uniform_t real_arc4random_uniform; -typedef void (*arc4random_buf_t)(void *buf, size_t n); -static arc4random_buf_t real_arc4random_buf; - -static int *random_fds = NULL; -static size_t random_fds_used = 0; -static size_t random_fds_allocd = 0; - -void check_random_fds() { - if (random_fds_allocd == 0) { - random_fds_allocd = 10; - random_fds = calloc(random_fds_allocd, sizeof(int)); - } else if (random_fds_allocd == random_fds_used) { - random_fds_allocd *= 2; - random_fds = realloc(random_fds, random_fds_allocd * sizeof(int)); - } -} - -void store_random_fd(int fd) { - check_random_fds(); - random_fds[random_fds_used++] = fd; -} - -int open(const char *pathname, int flags, ...) { - if (!real_open) { - real_open = dlsym(RTLD_NEXT, "open"); - } - - va_list args; - va_start(args, flags); - int mode = va_arg(args, int); - va_end(args); - - int result = real_open(pathname, flags, mode); - if (strcmp(pathname, "/dev/random") == 0 || strcmp(pathname, "/dev/urandom") == 0) { - fprintf(stderr, "called open(%s, %i, %i)\n", pathname, flags, mode); - store_random_fd(result); - } - return result; -} - -int openat(int fd, const char *pathname, int flags, ...) { - if (!real_openat) { - real_openat = dlsym(RTLD_NEXT, "openat"); - } - - va_list args; - va_start(args, flags); - int mode = va_arg(args, int); - va_end(args); - - int result = real_openat(fd, pathname, flags, mode); - if (strcmp(pathname, "/dev/random") == 0 || strcmp(pathname, "/dev/urandom") == 0) { - fprintf(stderr, "called openat(%s, %i, %i)\n", pathname, flags, mode); - store_random_fd(result); - } - return result; -} - -ssize_t read(int fd, void *buf, size_t count) { - if (!real_read) { - real_read = dlsym(RTLD_NEXT, "read"); - } - - for (int i = 0; i < random_fds_used; ++i) { - int random_fd = random_fds[i]; - if (random_fd == fd) { - fprintf(stderr, "read from random\n"); - uint8_t *buffer = (uint8_t*)buf; - for (size_t c = 0; c < count; ++c) { - buffer[c] = (uint8_t)0x00; - } - return count; - } - } - - return real_read(fd, buf, count); -} - -static FILE **random_files = NULL; -static size_t random_files_used = 0; -static size_t random_files_allocd = 0; - -void check_random_files() { - if (random_files_allocd == 0) { - random_files_allocd = 10; - random_files = calloc(random_files_allocd, sizeof(FILE *)); - } else if (random_files_allocd == random_files_used) { - random_files_allocd *= 2; - random_files = realloc(random_files, random_files_allocd * sizeof(FILE*)); - } -} - -void store_random_file(FILE *file) { - check_random_files(); - random_files[random_files_used++] = file; -} - -FILE *fopen(const char *pathname, const char *mode) { - if (!real_fopen) { - real_fopen = dlsym(RTLD_NEXT, "fopen"); - } - - FILE *result = real_fopen(pathname, mode); - - if (strcmp(pathname, "/dev/random") == 0 || strcmp(pathname, "/dev/urandom") == 0) { - fprintf(stderr, "called fopen(%s, %s)\n", pathname, mode); - store_random_file(result); - } - return result; -} - -size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { - if (!real_fread) { - real_fread = dlsym(RTLD_NEXT, "fread"); - } - - for (int i = 0; i < random_files_used; ++i) { - FILE *random_file = random_files[i]; - if (random_file == stream) { - fprintf(stderr, "fread from random\n"); - uint8_t *buffer = (uint8_t*)ptr; - for (size_t c = 0; c < size * nmemb; ++c) { - buffer[c] = (uint8_t)0x00; - } - return size * nmemb; - } - } - - return real_fread(ptr, size, nmemb, stream); -} - -ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) { - if (!real_getrandom) { - real_getrandom = dlsym(RTLD_NEXT, "getrandom"); - } - - fprintf(stderr, "called getrandom(*, %lu, %u)\n", buflen, flags); - uint8_t *buffer = (uint8_t*)buf; - for (size_t i = 0; i < buflen; ++i) { - buffer[i] = (uint8_t)0x00; - } - return buflen; -} - -int getentropy(void *buffer, size_t length) { - if (!real_getentropy) { - real_getentropy = dlsym(RTLD_NEXT, "getentropy"); - } - - fprintf(stderr, "called getentropy(*, %lu)\n", length); - uint8_t *buf = (uint8_t*)buffer; - for (size_t i = 0; i < length; ++i) { - buf[i] = (uint8_t)0x00; - } - return 0; -} - -long syscall(long number, ...) { - if (!real_syscall) { - real_syscall = dlsym(RTLD_NEXT, "syscall"); - } - va_list args; - - va_start(args, number); - long int a0 = va_arg(args, long int); - long int a1 = va_arg(args, long int); - long int a2 = va_arg(args, long int); - long int a3 = va_arg(args, long int); - long int a4 = va_arg(args, long int); - long int a5 = va_arg(args, long int); - va_end(args); - - if (number == SYS_getrandom) { - fprintf(stderr, "called syscall(getrandom, %li, %li, %li, %li, %li, %li)\n", a0, a1, a2, a3, a4, a5); - uint8_t *buf = (uint8_t*)a0; - long n = a1; - for (size_t i = 0; i < n; ++i) { - buf[i] = (uint8_t)0x00; - } - return n; - } - return real_syscall(number, a0, a1, a2, a3, a4, a5); -} - -uint32_t arc4random(void) { - if (!real_arc4random) { - real_arc4random = dlsym(RTLD_NEXT, "arc4random"); - } - - fprintf(stderr, "called arc4random\n"); - return 0; -} - -uint32_t arc4random_uniform(uint32_t upper_bound) { - if (!real_arc4random_uniform) { - real_arc4random_uniform = dlsym(RTLD_NEXT, "arc4random_uniform"); - } - - fprintf(stderr, "called arc4random_uniform(%u)\n", upper_bound); - return 0; -} - -void arc4random_buf(void *buf, size_t n) { - if (!real_arc4random_buf) { - real_arc4random_buf = dlsym(RTLD_NEXT, "arc4random_buf"); - } - - fprintf(stderr, "called arc4random_buf(%p, %lu)\n", buf, n); - uint8_t *buffer = (uint8_t*)buf; - for (size_t i = 0; i < n; ++i) { - buffer[i] = (uint8_t)0x00; - } -} - - -void __attribute__((destructor)) dealloc() { - if (random_fds != NULL) { - free(random_fds); - } - if (random_files != NULL) { - free(random_files); - } -} diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplex-common.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplex-common.h new file mode 100644 index 0000000..6371611 --- /dev/null +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplex-common.h @@ -0,0 +1,37 @@ +/* +Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, +Michaël Peeters, Gilles Van Assche and Ronny Van Keer, +hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakDuplexCommon_h_ +#define _KeccakDuplexCommon_h_ + +#include "align.h" + +#define KCP_DeclareDuplexStructure(prefix, size, alignment) \ + ALIGN(alignment) typedef struct prefix##_DuplexInstanceStruct { \ + unsigned char state[size]; \ + unsigned int rate; \ + unsigned int byteInputIndex; \ + unsigned int byteOutputIndex; \ + } prefix##_DuplexInstance; + +#define KCP_DeclareDuplexFunctions(prefix) \ + int prefix##_DuplexInitialize(prefix##_DuplexInstance *duplexInstance, unsigned int rate, unsigned int capacity); \ + int prefix##_Duplexing(prefix##_DuplexInstance *duplexInstance, const unsigned char *sigmaBegin, unsigned int sigmaBeginByteLen, unsigned char *Z, unsigned int ZByteLen, unsigned char delimitedSigmaEnd); \ + int prefix##_DuplexingFeedPartialInput(prefix##_DuplexInstance *duplexInstance, const unsigned char *input, unsigned int inputByteLen); \ + int prefix##_DuplexingFeedZeroes(prefix##_DuplexInstance *duplexInstance, unsigned int inputByteLen); \ + int prefix##_DuplexingOverwritePartialInput(prefix##_DuplexInstance *duplexInstance, const unsigned char *input, unsigned int inputByteLen); \ + int prefix##_DuplexingOverwriteWithZeroes(prefix##_DuplexInstance *duplexInstance, unsigned int inputByteLen); \ + int prefix##_DuplexingGetFurtherOutput(prefix##_DuplexInstance *duplexInstance, unsigned char *out, unsigned int outByteLen); \ + int prefix##_DuplexingGetFurtherOutputAndAdd(prefix##_DuplexInstance *duplexInstance, const unsigned char *input, unsigned char *output, unsigned int outputByteLen); + +#endif diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplex.inc b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplex.inc new file mode 100644 index 0000000..bd58043 --- /dev/null +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplex.inc @@ -0,0 +1,192 @@ +/* +Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, +Michaël Peeters, Gilles Van Assche and Ronny Van Keer, +hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#define JOIN0(a, b) a ## b +#define JOIN(a, b) JOIN0(a, b) + +#define DuplexInstance JOIN(prefix, _DuplexInstance) +#define DuplexInitialize JOIN(prefix, _DuplexInitialize) +#define Duplexing JOIN(prefix, _Duplexing) +#define DuplexingFeedPartialInput JOIN(prefix, _DuplexingFeedPartialInput) +#define DuplexingFeedZeroes JOIN(prefix, _DuplexingFeedZeroes) +#define DuplexingOverwritePartialInput JOIN(prefix, _DuplexingOverwritePartialInput) +#define DuplexingOverwriteWithZeroes JOIN(prefix, _DuplexingOverwriteWithZeroes) +#define DuplexingGetFurtherOutput JOIN(prefix, _DuplexingGetFurtherOutput) +#define DuplexingGetFurtherOutputAndAdd JOIN(prefix, _DuplexingGetFurtherOutputAndAdd) + +#define SnP_stateSizeInBytes JOIN(SnP, _stateSizeInBytes) +#define SnP_stateAlignment JOIN(SnP, _stateAlignment) +#define SnP_StaticInitialize JOIN(SnP, _StaticInitialize) +#define SnP_Initialize JOIN(SnP, _Initialize) +#define SnP_AddByte JOIN(SnP, _AddByte) +#define SnP_AddBytes JOIN(SnP, _AddBytes) +#define SnP_OverwriteBytes JOIN(SnP, _OverwriteBytes) +#define SnP_OverwriteWithZeroes JOIN(SnP, _OverwriteWithZeroes) +#define SnP_ExtractBytes JOIN(SnP, _ExtractBytes) +#define SnP_ExtractAndAddBytes JOIN(SnP, _ExtractAndAddBytes) + +int DuplexInitialize(DuplexInstance *instance, unsigned int rate, unsigned int capacity) +{ + if (rate+capacity != SnP_width) + return 1; + if ((rate <= 2) || (rate > SnP_width)) + return 1; + SnP_StaticInitialize(); + instance->rate = rate; + SnP_Initialize(instance->state); + instance->byteInputIndex = 0; + instance->byteOutputIndex = (instance->rate+7)/8; + return 0; +} + +int Duplexing(DuplexInstance *instance, const unsigned char *sigmaBegin, unsigned int sigmaBeginByteLen, unsigned char *Z, unsigned int ZByteLen, unsigned char delimitedSigmaEnd) +{ + const unsigned int rho_max = instance->rate - 2; + + if (delimitedSigmaEnd == 0) + return 1; + if ((instance->byteInputIndex+sigmaBeginByteLen)*8 > rho_max) + return 1; + if (rho_max - sigmaBeginByteLen*8 < 7) { + unsigned int maxBitsInDelimitedSigmaEnd = rho_max - sigmaBeginByteLen*8; + if (delimitedSigmaEnd >= (1 << (maxBitsInDelimitedSigmaEnd+1))) + return 1; + } + if (ZByteLen > (instance->rate+7)/8) + return 1; /* The output length must not be greater than the rate (rounded up to a byte) */ + + SnP_AddBytes(instance->state, sigmaBegin, instance->byteInputIndex, sigmaBeginByteLen); + #ifdef KeccakReference + { + unsigned char block[SnP_width/8]; + memcpy(block, sigmaBegin, sigmaBeginByteLen); + block[sigmaBeginByteLen] = delimitedSigmaEnd; + memset(block+sigmaBeginByteLen+1, 0, sizeof(block)-sigmaBeginByteLen-1); + block[(instance->rate-1)/8] |= 1 << ((instance->rate-1) % 8); + displayBytes(1, "Block to be absorbed (after padding)", block, (instance->rate+7)/8); + } + #endif + + /* Last few bits, whose delimiter coincides with first bit of padding */ + SnP_AddByte(instance->state, delimitedSigmaEnd, instance->byteInputIndex+sigmaBeginByteLen); + /* Second bit of padding */ + SnP_AddByte(instance->state, (unsigned char)1 << ((instance->rate - 1)%8), (instance->rate - 1)/8); + SnP_Permute(instance->state); + SnP_ExtractBytes(instance->state, Z, 0, ZByteLen); + + if (ZByteLen*8 > instance->rate) { + unsigned char mask = (unsigned char)(1 << (instance->rate % 8)) - 1; + Z[ZByteLen-1] &= mask; + } + + instance->byteInputIndex = 0; + instance->byteOutputIndex = ZByteLen; + + return 0; +} + +int DuplexingFeedPartialInput(DuplexInstance *instance, const unsigned char *input, unsigned int inputByteLen) +{ + const unsigned int rho_max = instance->rate - 2; + + if ((instance->byteInputIndex+inputByteLen)*8 > rho_max) + return 1; + + SnP_AddBytes(instance->state, input, instance->byteInputIndex, inputByteLen); + instance->byteInputIndex += inputByteLen; + return 0; +} + +int DuplexingFeedZeroes(DuplexInstance *instance, unsigned int inputByteLen) +{ + const unsigned int rho_max = instance->rate - 2; + + if ((instance->byteInputIndex+inputByteLen)*8 > rho_max) + return 1; + + instance->byteInputIndex += inputByteLen; + return 0; +} + +int DuplexingOverwritePartialInput(DuplexInstance *instance, const unsigned char *input, unsigned int inputByteLen) +{ + const unsigned int rho_max = instance->rate - 2; + + if ((instance->byteInputIndex+inputByteLen)*8 > rho_max) + return 1; + + SnP_OverwriteBytes(instance->state, input, instance->byteInputIndex, inputByteLen); + instance->byteInputIndex += inputByteLen; + return 0; +} + +int DuplexingOverwriteWithZeroes(DuplexInstance *instance, unsigned int inputByteLen) +{ + const unsigned int rho_max = instance->rate - 2; + + if ((instance->byteInputIndex != 0) || (inputByteLen*8 > rho_max)) + return 1; + + SnP_OverwriteWithZeroes(instance->state, inputByteLen); + instance->byteInputIndex = inputByteLen; + + return 0; +} + +int DuplexingGetFurtherOutput(DuplexInstance *instance, unsigned char *output, unsigned int outputByteLen) +{ + if ((outputByteLen+instance->byteOutputIndex) > (instance->rate+7)/8) + return 1; /* The output length must not be greater than the rate (rounded up to a byte) */ + + SnP_ExtractBytes(instance->state, output, instance->byteOutputIndex, outputByteLen); + instance->byteOutputIndex += outputByteLen; + if (instance->byteOutputIndex*8 > instance->rate) { + unsigned char mask = (1 << (instance->rate % 8)) - 1; + output[outputByteLen-1] &= mask; + } + return 0; +} + +int DuplexingGetFurtherOutputAndAdd(DuplexInstance *instance, const unsigned char *input, unsigned char *output, unsigned int outputByteLen) +{ + if ((outputByteLen+instance->byteOutputIndex) > (instance->rate+7)/8) + return 1; /* The output length must not be greater than the rate (rounded up to a byte) */ + + SnP_ExtractAndAddBytes(instance->state, input, output, instance->byteOutputIndex, outputByteLen); + instance->byteOutputIndex += outputByteLen; + if (instance->byteOutputIndex*8 > instance->rate) { + unsigned char mask = (1 << (instance->rate % 8)) - 1; + output[outputByteLen-1] &= mask; + } + return 0; +} + +#undef DuplexInstance +#undef DuplexInitialize +#undef Duplexing +#undef DuplexingFeedPartialInput +#undef DuplexingFeedZeroes +#undef DuplexingOverwritePartialInput +#undef DuplexingOverwriteWithZeroes +#undef DuplexingGetFurtherOutput +#undef DuplexingGetFurtherOutputAndAdd +#undef SnP_stateSizeInBytes +#undef SnP_stateAlignment +#undef SnP_StaticInitialize +#undef SnP_Initialize +#undef SnP_AddByte +#undef SnP_AddBytes +#undef SnP_OverwriteBytes +#undef SnP_OverwriteWithZeroes +#undef SnP_ExtractBytes +#undef SnP_ExtractAndAddBytes diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplexWidth200.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplexWidth200.c new file mode 100644 index 0000000..d6f56d2 --- /dev/null +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplexWidth200.c @@ -0,0 +1,29 @@ +/* +Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, +Michaël Peeters, Gilles Van Assche and Ronny Van Keer, +hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include "KeccakDuplexWidth200.h" + +#ifndef KeccakP200_excluded + #include "KeccakP-200-SnP.h" + + #define prefix KeccakWidth200 + #define SnP KeccakP200 + #define SnP_width 200 + #define SnP_Permute KeccakP200_Permute_18rounds + #include "KeccakDuplex.inc" + #undef prefix + #undef SnP + #undef SnP_width + #undef SnP_Permute + #undef SnP_FastLoop_Absorb +#endif diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplexWidth200.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplexWidth200.h new file mode 100644 index 0000000..8bb76f4 --- /dev/null +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakDuplexWidth200.h @@ -0,0 +1,25 @@ +/* +Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, +Michaël Peeters, Gilles Van Assche and Ronny Van Keer, +hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakDuplexWidth200_h_ +#define _KeccakDuplexWidth200_h_ + +#include "KeccakDuplex-common.h" + +#ifndef KeccakP200_excluded + #include "KeccakP-200-SnP.h" + KCP_DeclareDuplexStructure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment) + KCP_DeclareDuplexFunctions(KeccakWidth200) +#endif + +#endif diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakP-200-SnP.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakP-200-SnP.h new file mode 100644 index 0000000..4acf932 --- /dev/null +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakP-200-SnP.h @@ -0,0 +1,34 @@ +/* +Implementation by Ronny Van Keer, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ + +--- + +Please refer to SnP-documentation.h for more details. +*/ + +#ifndef _KeccakP_200_SnP_h_ +#define _KeccakP_200_SnP_h_ + +#define KeccakP200_implementation "8-bit compact implementation" +#define KeccakP200_stateSizeInBytes 25 +#define KeccakP200_stateAlignment 1 + +#define KeccakP200_StaticInitialize() +void KeccakP200_Initialize(void *state); +void KeccakP200_AddByte(void *state, unsigned char data, unsigned int offset); +void KeccakP200_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP200_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP200_OverwriteWithZeroes(void *state, unsigned int byteCount); +void KeccakP200_Permute_Nrounds(void *state, unsigned int nrounds); +void KeccakP200_Permute_18rounds(void *state); +void KeccakP200_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP200_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length); + +#endif diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakP-200-compact.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakP-200-compact.c new file mode 100644 index 0000000..f07bae9 --- /dev/null +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakP-200-compact.c @@ -0,0 +1,187 @@ +/* +Implementation by Ronny Van Keer, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ + +--- + +This file implements Keccak-p[200] in a SnP-compatible way. +Please refer to SnP-documentation.h for more details. + +This implementation comes with KeccakP-200-SnP.h in the same folder. +Please refer to LowLevel.build for the exact list of other files it must be combined with. +*/ + +#include +#include +#include "KeccakP-200-SnP.h" + +// #define DIVISION_INSTRUCTION /* comment if no division instruction or more compact when not using division */ +#define UNROLL_CHILOOP /* comment if more compact using for loop */ + +typedef unsigned char UINT8; +typedef unsigned int tSmallUInt; /*INFO It could be more optimized to use "unsigned char" on an 8-bit CPU */ +typedef UINT8 tKeccakLane; + +#define ROL8(a, offset) (UINT8)((((UINT8)a) << (offset&7)) ^ (((UINT8)a) >> (8-(offset&7)))) + +const UINT8 KeccakP200_RotationConstants[25] = +{ + 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 +}; + +const UINT8 KeccakP200_PiLane[25] = +{ + 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 +}; + +#if defined(DIVISION_INSTRUCTION) +#define MOD5(argValue) ((argValue) % 5) +#else +const UINT8 KeccakP200_Mod5[10] = +{ + 0, 1, 2, 3, 4, 0, 1, 2, 3, 4 +}; +#define MOD5(argValue) KeccakP200_Mod5[argValue] +#endif + +const UINT8 KeccakF200_RoundConstants[] = +{ + 0x01, 0x82, 0x8a, 0x00, 0x8b, 0x01, 0x81, 0x09, 0x8a, 0x88, 0x09, 0x0a, 0x8b, 0x8b, 0x89, 0x03, 0x02, 0x80 +}; + +/* ---------------------------------------------------------------- */ + +void KeccakP200_Initialize(void *argState) +{ + memset( argState, 0, 25 * sizeof(tKeccakLane) ); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP200_AddByte(void *argState, unsigned char byte, unsigned int offset) +{ + ((tKeccakLane*)argState)[offset] ^= byte; +} + +/* ---------------------------------------------------------------- */ + +void KeccakP200_AddBytes(void *argState, const unsigned char *data, unsigned int offset, unsigned int length) +{ + tSmallUInt i; + tKeccakLane * state = (tKeccakLane*)argState + offset; + for(i=0; ibyteInputIndex +#define DuplexGetOutputIndex(duplex) (duplex)->byteOutputIndex +#define DuplexSetOutputIndex(duplex, i) (duplex)->byteOutputIndex = (i) + +int SpongePRG_Initialize(SpongePRG_Instance *instance, unsigned int capacity) +{ + unsigned int rate; + unsigned int rhoInBytes; + + if (capacity > (SnP_width-10)) + return 1; + + rate = SnP_width - capacity; + rhoInBytes = (rate-2)/8; + + if ( (rhoInBytes == 0) || (rhoInBytes >= SnP_width/8) ) + return 1; + return DuplexInitialize(&instance->duplex, rate, capacity); +} + +int SpongePRG_Feed(SpongePRG_Instance *instance, const unsigned char *input, unsigned int inputByteLen) +{ + unsigned int rhoInBytes = (instance->duplex.rate-2)/8; + int error = 0; + + while( !error && ((DuplexGetInputIndex(&instance->duplex) + inputByteLen) >= rhoInBytes)) { + unsigned int localSize = rhoInBytes - DuplexGetInputIndex(&instance->duplex); + error |= DuplexingFeedPartialInput(&instance->duplex, input, localSize); + error |= Duplexing(&instance->duplex, 0, 0, 0, 0, 0x01); + input += localSize; + inputByteLen -= localSize; + } + if (!error) + error = DuplexingFeedPartialInput(&instance->duplex, input, inputByteLen); + DuplexSetOutputIndex(&instance->duplex, rhoInBytes); + return error; +} + +int SpongePRG_Fetch(SpongePRG_Instance *instance, unsigned char *output, unsigned int outputByteLen) +{ + unsigned int rhoInBytes = (instance->duplex.rate-2)/8; + int error = 0; + + if (DuplexGetOutputIndex(&instance->duplex) < rhoInBytes) { + unsigned int localSize = rhoInBytes - DuplexGetOutputIndex(&instance->duplex); + localSize = (localSize <= outputByteLen) ? localSize : outputByteLen; + error = DuplexingGetFurtherOutput(&instance->duplex, output, localSize); + output += localSize; + outputByteLen -= localSize; + } + + while( !error && (outputByteLen > 0) ) { + error = Duplexing(&instance->duplex, 0, 0, 0, 0, 0x01); + if (!error) { + unsigned int localSize = (rhoInBytes <= outputByteLen) ? rhoInBytes : outputByteLen; + error = DuplexingGetFurtherOutput(&instance->duplex, output, localSize); + output += localSize; + outputByteLen -= localSize; + } + } + return error; +} + +int SpongePRG_Forget(SpongePRG_Instance *instance) +{ + unsigned int rhoInBytes = (instance->duplex.rate-2)/8; + unsigned int capacity = SnP_width - instance->duplex.rate; + int error; + + if ((rhoInBytes*8) < capacity) + return 1; + + error = Duplexing(&instance->duplex, 0, 0, 0, 0, 0x01); + if ( !error ) { + error = DuplexingOverwriteWithZeroes(&instance->duplex, rhoInBytes); + if ( !error ) + error = Duplexing(&instance->duplex, 0, 0, 0, 0, 0x01); + } + DuplexSetOutputIndex(&instance->duplex, rhoInBytes); + return error; +} + +#undef SpongePRG_Instance +#undef SpongePRG_Initialize +#undef SpongePRG_Feed +#undef SpongePRG_Fetch +#undef SpongePRG_Forget + +#undef DuplexInstance +#undef DuplexInitialize +#undef Duplexing +#undef DuplexingFeedPartialInput +#undef DuplexingOverwriteWithZeroes +#undef DuplexingGetFurtherOutput +#undef DuplexGetInputIndex +#undef DuplexGetOutputIndex +#undef DuplexSetOutputIndex diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRGWidth200.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRGWidth200.c new file mode 100644 index 0000000..067375e --- /dev/null +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRGWidth200.c @@ -0,0 +1,22 @@ +/* +Implementation by Gilles Van Assche, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include "KeccakPRGWidth200.h" + +#ifndef KeccakP200_excluded + #include "KeccakP-200-SnP.h" + + #define prefix KeccakWidth200 + #define SnP_width 200 + #include "KeccakPRG.inc" + #undef prefix + #undef SnP_width +#endif diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRGWidth200.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRGWidth200.h new file mode 100644 index 0000000..d7cfcc9 --- /dev/null +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/KeccakPRGWidth200.h @@ -0,0 +1,24 @@ +/* +Implementation by Gilles Van Assche, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakPRGWidth200_h_ +#define _KeccakPRGWidth200_h_ + +#include "KeccakDuplexWidth200.h" +#include "KeccakPRG-common.h" + +#ifndef KeccakP200_excluded + #include "KeccakP-200-SnP.h" + KCP_DeclareSpongePRG_Structure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment) + KCP_DeclareSpongePRG_Functions(KeccakWidth200) +#endif + +#endif diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/align.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/align.h new file mode 100644 index 0000000..90c1b37 --- /dev/null +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/align.h @@ -0,0 +1,32 @@ +/* +Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, +Michaël Peeters, Gilles Van Assche and Ronny Van Keer, +hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _align_h_ +#define _align_h_ + +/* on Mac OS-X and possibly others, ALIGN(x) is defined in param.h, and -Werror chokes on the redef. */ +#ifdef ALIGN +#undef ALIGN +#endif + +#if defined(__GNUC__) +#define ALIGN(x) __attribute__ ((aligned(x))) +#elif defined(_MSC_VER) +#define ALIGN(x) __declspec(align(x)) +#elif defined(__ARMCC_VERSION) +#define ALIGN(x) __align(x) +#else +#define ALIGN(x) +#endif + +#endif diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/prng.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/prng.c new file mode 100644 index 0000000..c44db6f --- /dev/null +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/prng.c @@ -0,0 +1,21 @@ +#include "KeccakPRG.h" +#include "KeccakP-200-compact.c" +#include "KeccakDuplexWidth200.c" +#include "KeccakPRGWidth200.c" +#include "prng.h" +#include + + +void prng_init(prng_state *state) { + memset(state, 0, sizeof(state)); + KeccakWidth200_SpongePRG_Initialize(state, 70); +} + +void prng_seed(prng_state *state, const uint8_t *seed, size_t size) { + KeccakWidth200_SpongePRG_Feed(state, seed, size); + KeccakWidth200_SpongePRG_Forget(state); +} + +void prng_get(prng_state *state, uint8_t *out, size_t size) { + KeccakWidth200_SpongePRG_Fetch(state, out, size); +} \ No newline at end of file diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/prng.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/prng.h new file mode 100644 index 0000000..2cc4f21 --- /dev/null +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/prng/prng.h @@ -0,0 +1,13 @@ +#include "KeccakPRG.h" +#include + +typedef KeccakWidth200_SpongePRG_Instance prng_state; + +void prng_init(prng_state *state); + +void prng_seed(prng_state *state, const uint8_t *seed, size_t size); + +void prng_get(prng_state *state, uint8_t *out, size_t size); + + + diff --git a/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java b/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java index bebb3c5..e5caae8 100644 --- a/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java +++ b/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java @@ -14,7 +14,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; public class DeterministicTests { static Stream libs() { - return Stream.of("Botan", "BouncyCastle", "Crypto++", "IPPCP", "mbedTLS", "Nettle", "OpenSSL", "SunEC", "tomcrypt"); + return Stream.of("Botan", "BouncyCastle", "Crypto++", "IPPCP", "mbedTLS", "Nettle", "OpenSSL", "SunEC", "tomcrypt", "LibreSSL"); + // BoringSSL and libgcrypt cannot be easily tested here, because they initialize their RNG only once per process. } @SuppressWarnings("JUnitMalformedDeclaration") @@ -110,6 +111,7 @@ public class DeterministicTests { case "Crypto++": args = new String[]{"ecdsa", "-ps", "12345678", "-d", "1234", "-n", "10", "-nc", "secg/secp256r1", "-t", "ECDSA", libName}; break; + case "LibreSSL": case "mbedTLS": args = new String[]{"ecdsa", "-ps", "12345678", "-d", "1234", "-n", "10", "-nc", "secg/secp256r1", "-t", "NONEwithECDSA", libName}; break; -- cgit v1.3.1 From 6a71e2dd13ddda22feead680ce0c6a5ffeea4cf7 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 9 Aug 2024 16:49:18 +0200 Subject: Ditch preload.c --- .../src/main/resources/cz/crcs/ectester/standalone/libs/jni/preload.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/preload.c diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/preload.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/preload.c deleted file mode 100644 index e69de29..0000000 -- cgit v1.3.1 From be605a27d095d95cfb477d339b1b6e698d83fa76 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 9 Aug 2024 16:53:35 +0200 Subject: Fix orphan import. --- .../src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java | 1 - 1 file changed, 1 deletion(-) diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java index 6822a30..04537f0 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -23,7 +23,6 @@ */ package cz.crcs.ectester.standalone; -import com.sun.source.tree.StringTemplateTree; import cz.crcs.ectester.common.cli.*; import cz.crcs.ectester.common.ec.EC_Consts; import cz.crcs.ectester.common.ec.EC_Curve; -- cgit v1.3.1 From 1fcbe537eefeaebfda7403b166e92278941ddf20 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 9 Aug 2024 17:00:43 +0200 Subject: Fallback only if user.home is junk. --- common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java b/common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java index 982dbed..734e957 100644 --- a/common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java +++ b/common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java @@ -44,14 +44,18 @@ public class FileUtil { if (System.getProperty("os.name").startsWith("Windows")) { appData = Paths.get(System.getenv("AppData")); + return appData; } else { if (System.getProperty("os.name").startsWith("Linux")) { String dataHome = System.getenv("XDG_DATA_HOME"); if (dataHome != null) { appData = Paths.get(dataHome); - } else { - appData = Paths.get(System.getenv("HOME"), ".local", "share"); + return appData; } + } + String userHome = System.getProperty("user.home"); + if (userHome != null && !userHome.equals("?")) { + appData = Paths.get(userHome, ".local", "share"); } else { appData = Paths.get(System.getenv("HOME"), ".local", "share"); } -- cgit v1.3.1 From c6b752a7a8980372ff6a5f49660f94d9495e5f33 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 9 Aug 2024 17:19:57 +0200 Subject: Do not test deterministic LibreSSL in CI. --- .../src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java b/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java index e5caae8..5c7a21f 100644 --- a/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java +++ b/standalone/src/test/java/cz/crcs/ectester/standalone/DeterministicTests.java @@ -14,8 +14,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; public class DeterministicTests { static Stream libs() { - return Stream.of("Botan", "BouncyCastle", "Crypto++", "IPPCP", "mbedTLS", "Nettle", "OpenSSL", "SunEC", "tomcrypt", "LibreSSL"); + return Stream.of("Botan", "BouncyCastle", "Crypto++", "IPPCP", "mbedTLS", "Nettle", "OpenSSL", "SunEC", "tomcrypt"); // BoringSSL and libgcrypt cannot be easily tested here, because they initialize their RNG only once per process. + // LibreSSL hangs in CI. } @SuppressWarnings("JUnitMalformedDeclaration") -- cgit v1.3.1