aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorquapka2024-06-21 16:31:37 +0200
committerquapka2024-06-21 16:31:37 +0200
commitada61982cc70a2c72a6fc765dc9b4a9c01202a27 (patch)
treed92bee42106e850d4da90ad7174ac609ca175eda
parentc051ef2ecfa92723d6dea675ac8c345be92cf165 (diff)
parentc112d3e49bbbbf33cc70d12d196e109543c19a3c (diff)
downloadECTester-ada61982cc70a2c72a6fc765dc9b4a9c01202a27.tar.gz
ECTester-ada61982cc70a2c72a6fc765dc9b4a9c01202a27.tar.zst
ECTester-ada61982cc70a2c72a6fc765dc9b4a9c01202a27.zip
Merge branch 'master' into build-with-nix
-rw-r--r--.github/workflows/build.yml4
-rw-r--r--README.md5
-rw-r--r--common/build.gradle.kts2
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/ec/CustomECFieldFp.java2
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/output/BaseTextTestWriter.java35
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/output/BaseXMLTestWriter.java10
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java10
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/output/TeeTestWriter.java14
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/output/TestWriter.java24
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/test/TestSuite.java2
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java115
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java11
-rw-r--r--common/src/main/resources/cz/crcs/ectester/data/cofactor/cofactor128p65535.csv2
-rw-r--r--common/src/main/resources/cz/crcs/ectester/data/cofactor/keys.xml2
-rw-r--r--common/src/main/resources/cz/crcs/ectester/data/composite/composite192_pq2.csv2
-rw-r--r--common/src/main/resources/cz/crcs/ectester/data/schema.xsd1
-rw-r--r--common/src/main/resources/cz/crcs/ectester/data/wrong/curves.xml42
-rw-r--r--common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo192.csv1
-rw-r--r--common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo224.csv1
-rw-r--r--common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo256.csv1
-rw-r--r--common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo384.csv1
-rw-r--r--common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo512.csv1
-rw-r--r--common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo521.csv1
-rw-r--r--common/src/main/resources/cz/crcs/ectester/data/wrong/results.xml203
m---------ext/boringssl0
-rw-r--r--reader/build.gradle.kts2
-rw-r--r--reader/src/main/java/cz/crcs/ectester/reader/ECTesterReader.java2
-rw-r--r--standalone/build.gradle.kts4
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java176
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java12
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java9
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/consts/SignatureIdent.java12
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/libs/NativeECLibrary.java4
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/libs/NettleLib.java32
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/libs/ProviderECLibrary.java4
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java126
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java49
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/SigInfo.java80
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/SignalException.java18
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/TimeoutException.java11
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/output/TextTestWriter.java2
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/output/XMLTestWriter.java2
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/output/YAMLTestWriter.java2
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java14
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTestable.java17
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java6
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCompositeSuite.java40
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java39
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java4
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java39
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java12
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneSignatureSuite.java4
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestVectorSuite.java2
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java39
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java36
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile53
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/boringssl.c95
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_signals.c117
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_signals.h53
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cpp_signals.cpp122
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cpp_signals.hpp59
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp88
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/gcrypt.c79
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/ippcp.c70
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/libressl.c87
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/mbedtls.c34
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/native.h136
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/nettle.c99
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/openssl.c73
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c53
-rw-r--r--standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java28
71 files changed, 1966 insertions, 571 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index ab2a2ee..fea8fe5 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -52,7 +52,7 @@ jobs:
strategy:
matrix:
- java: [ "11", "17", "21" ]
+ java: [ "17", "21"]
name: Build reader on Java ${{ matrix.java }}
steps:
- uses: actions/checkout@v4
@@ -88,7 +88,7 @@ jobs:
strategy:
matrix:
- java: [ "11", "17", "21" ]
+ java: [ "17", "21"]
env:
# ffs: https://github.com/adoptium/adoptium-support/issues/485 !!!
# also, add the wolfcrypt JNI path
diff --git a/README.md b/README.md
index f9cbfd7..726be68 100644
--- a/README.md
+++ b/README.md
@@ -36,12 +36,15 @@ There are three parts of ECTester, the JavaCard applet used for testing, the rea
standalone app which tests software libraries. The target platform for ECTester is Linux, but things should work on
Windows as well, although testing of standalone libraries will be limited to Java libraries and Microsoft CNG library.
+The ECTester parts require different Java versions. Reader and standalone parts require Java >= 15 while the applet build
+will be able to target different JavaCard versions based on the Java version, see [this list](https://github.com/martinpaljak/ant-javacard/wiki/JavaCard-SDK-and-JDK-version-compatibility).
+
To build ECTester simply do:
```bash
git submodule update --init --recursive # To initialize submodules (JavaCard SDKs, Microsoft CNG, BoringSSL, ...)
./gradlew :applet:buildJavaCard # To build the applet (cap) -> "applet/build/javacard/applet[221,222,305].cap".
./gradlew :reader:uberJar # To build the reader tool (jar) -> "reader/build/libs/ECTesterReader.jar"
-./gradlew :standalone:libs # To build the native library shims. (Necessary
+./gradlew :standalone:libs # To build the native library shims.
./gradlew :standalone:uberJar # To build the standalone tool (jar) -> "standalone/build/libs/ECTesterStandalone.jar"
```
The applet comes in several flavors, targeting JavaCard `2.2.1`, `2.2.2` and `3.0.5`. The `2.2.2` and later flavors
diff --git a/common/build.gradle.kts b/common/build.gradle.kts
index 0aca7fb..1aff0d7 100644
--- a/common/build.gradle.kts
+++ b/common/build.gradle.kts
@@ -23,5 +23,5 @@ dependencies {
}
java {
- sourceCompatibility = JavaVersion.VERSION_11
+ sourceCompatibility = JavaVersion.VERSION_15
} \ No newline at end of file
diff --git a/common/src/main/java/cz/crcs/ectester/common/ec/CustomECFieldFp.java b/common/src/main/java/cz/crcs/ectester/common/ec/CustomECFieldFp.java
index eafcb72..1fe6eb0 100644
--- a/common/src/main/java/cz/crcs/ectester/common/ec/CustomECFieldFp.java
+++ b/common/src/main/java/cz/crcs/ectester/common/ec/CustomECFieldFp.java
@@ -19,7 +19,7 @@ public class CustomECFieldFp extends ECFieldFp {
@Override
public int getFieldSize() {
- return p.bitCount();
+ return p.bitLength();
}
@Override
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 5c449db..538539b 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
@@ -51,11 +51,13 @@ public abstract class BaseTextTestWriter implements TestWriter {
private String testString(Test t, String prefix, int index) {
boolean compound = t instanceof CompoundTest;
+ boolean cont = compound ? ((CompoundTest) t).getStartedTests().length > 0 : false;
+ boolean root = prefix.equals("");
Result result = t.getResult();
String line = "";
- if (prefix.equals("")) {
+ if (root) {
char[] charLine = new char[BASE_WIDTH + 24];
new String(new char[BASE_WIDTH + 24]).replace("\0", "━").getChars(0, charLine.length - 1, charLine, 0);
charLine[0] = '■';
@@ -68,10 +70,20 @@ public abstract class BaseTextTestWriter implements TestWriter {
StringBuilder out = new StringBuilder();
out.append(t.ok() ? Colors.ok(" OK ") : Colors.error("NOK "));
- out.append(compound ? (prefix.equals("") ? "╋ " : "┳ ") : "━ ");
+ String marker;
+ if (compound) {
+ if (root) {
+ marker = cont ? "╋" : "┻";
+ } else {
+ marker = cont ? "┳" : "━";
+ }
+ } else {
+ marker = "━";
+ }
+ out.append(marker + " ");
int width = BASE_WIDTH - (prefix.length() + 6);
String widthSpec = "%-" + width + "s";
- String desc = ((prefix.equals("")) ? "(" + index + ") " : "") + t.getDescription();
+ String desc = ((root) ? "(" + index + ") " : "") + t.getDescription();
out.append(String.format(widthSpec, desc));
out.append(" ┃ ");
Colors.Foreground valueColor;
@@ -114,6 +126,23 @@ public abstract class BaseTextTestWriter implements TestWriter {
}
@Override
+ public void beginTest(Test t) {
+ if (System.console() != null) {
+ output.print("Running ▶ " + t.getDescription());
+ output.flush();
+ }
+ }
+
+
+ @Override
+ public void endTest(Test t) {
+ if (System.console() != null) {
+ output.print("\33[2K\r");
+ output.flush();
+ }
+ }
+
+ @Override
public void outputTest(Test t, int index) {
if (!t.hasRun())
return;
diff --git a/common/src/main/java/cz/crcs/ectester/common/output/BaseXMLTestWriter.java b/common/src/main/java/cz/crcs/ectester/common/output/BaseXMLTestWriter.java
index 53970dd..5157ef0 100644
--- a/common/src/main/java/cz/crcs/ectester/common/output/BaseXMLTestWriter.java
+++ b/common/src/main/java/cz/crcs/ectester/common/output/BaseXMLTestWriter.java
@@ -116,6 +116,16 @@ public abstract class BaseXMLTestWriter implements TestWriter {
}
@Override
+ public void beginTest(Test t) {
+
+ }
+
+ @Override
+ public void endTest(Test t) {
+
+ }
+
+ @Override
public void outputTest(Test t, int index) {
if (!t.hasRun())
return;
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 e054563..c3a42ea 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
@@ -92,6 +92,16 @@ public abstract class BaseYAMLTestWriter implements TestWriter {
}
@Override
+ public void beginTest(Test t) {
+
+ }
+
+ @Override
+ public void endTest(Test t) {
+
+ }
+
+ @Override
public void outputTest(Test t, int index) {
if (!t.hasRun())
return;
diff --git a/common/src/main/java/cz/crcs/ectester/common/output/TeeTestWriter.java b/common/src/main/java/cz/crcs/ectester/common/output/TeeTestWriter.java
index 58a0a15..7635644 100644
--- a/common/src/main/java/cz/crcs/ectester/common/output/TeeTestWriter.java
+++ b/common/src/main/java/cz/crcs/ectester/common/output/TeeTestWriter.java
@@ -21,6 +21,20 @@ public class TeeTestWriter implements TestWriter {
}
@Override
+ public void beginTest(Test t) {
+ for (TestWriter writer : writers) {
+ writer.beginTest(t);
+ }
+ }
+
+ @Override
+ public void endTest(Test t) {
+ for (TestWriter writer : writers) {
+ writer.endTest(t);
+ }
+ }
+
+ @Override
public void outputTest(Test t, int index) {
for (TestWriter writer : writers) {
writer.outputTest(t, index);
diff --git a/common/src/main/java/cz/crcs/ectester/common/output/TestWriter.java b/common/src/main/java/cz/crcs/ectester/common/output/TestWriter.java
index 67aeccb..7368c0a 100644
--- a/common/src/main/java/cz/crcs/ectester/common/output/TestWriter.java
+++ b/common/src/main/java/cz/crcs/ectester/common/output/TestWriter.java
@@ -19,20 +19,32 @@ public interface TestWriter {
void begin(TestSuite suite);
/**
- * @param t
- * @param index
+ * Begin the test (before it is run).
+ * @param t Test to begin output of.
+ */
+ void beginTest(Test t);
+
+ /**
+ * End the test (after it is run, or errored out).
+ * @param t Test to end output of.
+ */
+ void endTest(Test t);
+
+ /**
+ * @param t Test to output.
+ * @param index Index of the test.
*/
void outputTest(Test t, int index);
/**
- * @param t
- * @param cause
- * @param index
+ * @param t Test to output the error from.
+ * @param cause Throwable to output.
+ * @param index Index of the test.
*/
void outputError(Test t, Throwable cause, int index);
/**
- *
+ * End writing the TestSuite.
*/
void end();
}
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 b12680a..091b008 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
@@ -55,7 +55,9 @@ public abstract class TestSuite {
*/
protected <T extends Test> T runTest(T t) {
running = t;
+ writer.beginTest(t);
t.run();
+ writer.endTest(t);
running = null;
return t;
}
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 f9be536..e7f138e 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
@@ -2,20 +2,25 @@ package cz.crcs.ectester.common.util;
import cz.crcs.ectester.common.ec.*;
import cz.crcs.ectester.data.EC_Store;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.signers.PlainDSAEncoding;
import org.bouncycastle.crypto.signers.StandardDSAEncoding;
+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 java.io.FileInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
-import java.security.KeyPair;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.interfaces.ECKey;
-import java.security.interfaces.ECPrivateKey;
-import java.security.interfaces.ECPublicKey;
+import java.security.*;
+import java.security.interfaces.*;
import java.security.spec.*;
import java.util.LinkedList;
import java.util.List;
@@ -344,6 +349,39 @@ public class ECUtil {
return new KeyPair(pubkey, privkey);
}
+ /**
+ * Validate DER or PLAIN signature format.
+ *
+ * @throws IllegalArgumentException in case of invalid format.
+ * @param signature
+ * @param params
+ * @param hashAlgo
+ * @param sigType
+ */
+ public static void validateSignatureFormat(byte[] signature, ECParameterSpec params, String hashAlgo, String sigType) {
+ BigInteger n = params.getOrder();
+ try {
+ if (sigType.contains("CVC") || sigType.contains("PLAIN")) {
+ PlainDSAEncoding.INSTANCE.decode(n, signature);
+ } else {
+ StandardDSAEncoding.INSTANCE.decode(n, signature);
+ }
+ } catch (Exception e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ /**
+ * Recover the ECDSA signature nonce.
+ *
+ * @param signature
+ * @param data
+ * @param privkey
+ * @param params
+ * @param hashAlgo
+ * @param sigType
+ * @return The nonce.
+ */
public static BigInteger recoverSignatureNonce(byte[] signature, byte[] data, BigInteger privkey, ECParameterSpec params, String hashAlgo, String sigType) {
// We do not know how to reconstruct those nonces so far.
// sigType.contains("ECKCDSA") || sigType.contains("ECNR") || sigType.contains("SM2")
@@ -369,14 +407,18 @@ public class ECUtil {
}
// Parse signature
- BigInteger[] sigPair;
+ BigInteger r;
+ BigInteger s;
if (sigType.contains("CVC") || sigType.contains("PLAIN")) {
- sigPair = PlainDSAEncoding.INSTANCE.decode(n, signature);
+ BigInteger[] sigPair = PlainDSAEncoding.INSTANCE.decode(n, signature);
+ r = sigPair[0];
+ s = sigPair[1];
} else {
- sigPair = StandardDSAEncoding.INSTANCE.decode(n, signature);
+ ASN1Sequence seq = (ASN1Sequence) ASN1Primitive.fromByteArray(signature);
+ r = ((ASN1Integer) seq.getObjectAt(0)).getValue();
+ s = ((ASN1Integer) seq.getObjectAt(1)).getValue();
}
- BigInteger r = sigPair[0];
- BigInteger s = sigPair[1];
+
BigInteger rd = privkey.multiply(r).mod(n);
BigInteger hrd = hashInt.add(rd).mod(n);
@@ -456,6 +498,46 @@ public class ECUtil {
return null;
}
+ public static byte[] pubkeyToBytes(PublicKey pubkey) {
+ if (pubkey instanceof ECPublicKey) {
+ ECPublicKey ecPublicKey = (ECPublicKey) pubkey;
+ return ECUtil.toX962Uncompressed(ecPublicKey.getW(), ecPublicKey.getParams());
+ } else if (pubkey instanceof XECPublicKey) {
+ XECPublicKey xedPublicKey = (XECPublicKey) pubkey;
+ return xedPublicKey.getU().toByteArray();
+ } else if (pubkey instanceof EdECPublicKey) {
+ EdECPublicKey edECPublicKey = (EdECPublicKey) pubkey;
+ return edECPublicKey.getPoint().getY().toByteArray();
+ } else if (pubkey instanceof XDHPublicKey) {
+ XDHPublicKey xdhPublicKey = (XDHPublicKey) pubkey;
+ return xdhPublicKey.getU().toByteArray();
+ // Special-case BouncyCastle XDH
+ } else if (pubkey instanceof EdDSAPublicKey) {
+ EdDSAPublicKey edDSAPublicKey = (EdDSAPublicKey) pubkey;
+ // Special-case BouncyCastle EdDSA
+ return edDSAPublicKey.getPointEncoding();
+ }
+ return null;
+ }
+
+ public static byte[] privkeyToBytes(PrivateKey privkey) {
+ if (privkey instanceof ECPrivateKey) {
+ ECPrivateKey ecPrivateKey = (ECPrivateKey) privkey;
+ return ecPrivateKey.getS().toByteArray();
+ } else if (privkey instanceof XECPrivateKey) {
+ XECPrivateKey xecPrivateKey = (XECPrivateKey) privkey;
+ return xecPrivateKey.getScalar().get();
+ } else if (privkey instanceof EdECPrivateKey) {
+ EdECPrivateKey edECPrivateKey = (EdECPrivateKey) privkey;
+ return edECPrivateKey.getBytes().get();
+ } else if (privkey instanceof XDHPrivateKey || privkey instanceof EdDSAPrivateKey) {
+ // Special-case BouncyCastle XDH and EdDSA
+ PrivateKeyInfo xpkinfo = PrivateKeyInfo.getInstance(privkey.getEncoded());
+ return ASN1OctetString.getInstance(xpkinfo.getPrivateKey().getOctets()).getOctets();
+ }
+ return null;
+ }
+
public static boolean equalKeyPairParameters(ECPrivateKey priv, ECPublicKey pub) {
if (priv == null || pub == null) {
return false;
@@ -465,4 +547,15 @@ public class ECUtil {
priv.getParams().getGenerator().equals(pub.getParams().getGenerator()) &&
priv.getParams().getOrder().equals(pub.getParams().getOrder());
}
+
+ public static boolean equalECParameterSpec(ECParameterSpec left, ECParameterSpec right) {
+ if (left == null || right == null) {
+ return false;
+ }
+
+ return left.getCofactor() == right.getCofactor() &&
+ left.getCurve().equals(right.getCurve()) &&
+ left.getGenerator().equals(right.getGenerator()) &&
+ left.getOrder().equals(right.getOrder());
+ }
}
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 e6e319b..da682b6 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
@@ -81,6 +81,17 @@ public class FileUtil {
return true;
}
+ public static boolean write(String resourcePath, Path outPath) throws IOException {
+ URL reqURL = FileUtil.class.getResource(resourcePath);
+ if (reqURL == null) {
+ return false;
+ }
+ URLConnection reqConn = reqURL.openConnection();
+ Files.copy(reqConn.getInputStream(), outPath, StandardCopyOption.REPLACE_EXISTING);
+ reqConn.getInputStream().close();
+ return true;
+ }
+
public static Path getLibDir() {
return getAppData().resolve("ECTesterStandalone");
}
diff --git a/common/src/main/resources/cz/crcs/ectester/data/cofactor/cofactor128p65535.csv b/common/src/main/resources/cz/crcs/ectester/data/cofactor/cofactor128p65535.csv
index 54da6cc..fb16cdb 100644
--- a/common/src/main/resources/cz/crcs/ectester/data/cofactor/cofactor128p65535.csv
+++ b/common/src/main/resources/cz/crcs/ectester/data/cofactor/cofactor128p65535.csv
@@ -1 +1 @@
-0xdd94e89ef3fba74afc2a67cb91546a93,0x6cf4828ab4960df2b9fcab3990e3959a,0x80a5c32206c83f769c5ed3e4f5b2ea4e,0xd7a4bb4b7e9ad9e81895caeaeac8b739,0x45ebc51cf353974b02b36b9912de041b,0x0000dd95c634ba30617af48fd4eb321b,0xffff \ No newline at end of file
+0xdd94e89ef3fba74afc2a67cb91546a93,0x6cf4828ab4960df2b9fcab3990e3959a,0x80a5c32206c83f769c5ed3e4f5b2ea4e,0x91e251594dab368b04d7dd6d9b99fdef,0xa7da97b3ba62ac554f7202d4f0348133,0x0000dd95c634ba30617af48fd4eb321b,0xffff \ No newline at end of file
diff --git a/common/src/main/resources/cz/crcs/ectester/data/cofactor/keys.xml b/common/src/main/resources/cz/crcs/ectester/data/cofactor/keys.xml
index d6058f0..1b5ec4b 100644
--- a/common/src/main/resources/cz/crcs/ectester/data/cofactor/keys.xml
+++ b/common/src/main/resources/cz/crcs/ectester/data/cofactor/keys.xml
@@ -668,7 +668,7 @@
</pubkey>
<pubkey>
<id>pq/cofactor192/1</id>
- <inline>0x6366613b66339fa580f390d630ccf9b535437229aa8b61cd,0x1b975fa3848bd68f34f6a08b7cf190bcaeaf9782270e2413</inline>
+ <inline>0x28f5b96b08f9dbe661472dbf8e5925b944e42ac5fdfdb2da,0x227e8b2a9b07d1cd67211d4b933bf43eefbb7140e5a65dca</inline>
<curve>composite/pq/composite192/1</curve>
<desc>cofactor order = 0x00000000000000000000035efd8bad55038e6bd22db8b805</desc>
</pubkey>
diff --git a/common/src/main/resources/cz/crcs/ectester/data/composite/composite192_pq2.csv b/common/src/main/resources/cz/crcs/ectester/data/composite/composite192_pq2.csv
index 33fe0f3..c92dcb2 100644
--- a/common/src/main/resources/cz/crcs/ectester/data/composite/composite192_pq2.csv
+++ b/common/src/main/resources/cz/crcs/ectester/data/composite/composite192_pq2.csv
@@ -1 +1 @@
-0xa261fff62647eebf810a404f0c80a971dd7c7838fdc52b5b,0x87502ebb62d26e1eca06c434f8ef069dfb2c287d6183750c,0x4ad6ce1f16e1bfc3d40f0027d787aeadb53846d69099a883,0x6366613b66339fa580f390d630ccf9b535437229aa8b61cd,0x1b975fa3848bd68f34f6a08b7cf190bcaeaf9782270e2413,0x00000000000000000000035efd8bad55038e6bd22db8b805,0x01 \ No newline at end of file
+0xa261fff62647eebf810a404f0c80a971dd7c7838fdc52b5b,0x87502ebb62d26e1eca06c434f8ef069dfb2c287d6183750c,0x4ad6ce1f16e1bfc3d40f0027d787aeadb53846d69099a883,0x16a5b79035a1e561aae737dc7f32f3c03d5f03f73bd405e4,0x3ddad60cc20b136913dcab69a30e5b71e0bf11f859658524,0x00000000000000000000035efd8bad55038e6bd22db8b805,0x01 \ No newline at end of file
diff --git a/common/src/main/resources/cz/crcs/ectester/data/schema.xsd b/common/src/main/resources/cz/crcs/ectester/data/schema.xsd
index 99c9b76..245aa9a 100644
--- a/common/src/main/resources/cz/crcs/ectester/data/schema.xsd
+++ b/common/src/main/resources/cz/crcs/ectester/data/schema.xsd
@@ -82,6 +82,7 @@
<xs:simpleType name="sigType">
<xs:restriction base="xs:string">
+ <xs:enumeration value="*"/>
<xs:enumeration value="SHA1"/>
<xs:enumeration value="SHA224"/>
<xs:enumeration value="SHA256"/>
diff --git a/common/src/main/resources/cz/crcs/ectester/data/wrong/curves.xml b/common/src/main/resources/cz/crcs/ectester/data/wrong/curves.xml
index 2a51474..9087940 100644
--- a/common/src/main/resources/cz/crcs/ectester/data/wrong/curves.xml
+++ b/common/src/main/resources/cz/crcs/ectester/data/wrong/curves.xml
@@ -92,4 +92,46 @@
<file>wrongt571.csv</file>
<desc>The field polynomial is not irreducible in F_2^571[x].</desc>
</curve>
+ <curve>
+ <id>pseudo192</id>
+ <bits>192</bits>
+ <field>prime</field>
+ <file>pseudo192.csv</file>
+ <desc>The field is not prime (but a Carmichael pseudoprime, see https://github.com/crocs-muni/fooling-primality-tests/).</desc>
+ </curve>
+ <curve>
+ <id>pseudo224</id>
+ <bits>224</bits>
+ <field>prime</field>
+ <file>pseudo224.csv</file>
+ <desc>The field is not prime (but a Carmichael pseudoprime, see https://github.com/crocs-muni/fooling-primality-tests/).</desc>
+ </curve>
+ <curve>
+ <id>pseudo256</id>
+ <bits>256</bits>
+ <field>prime</field>
+ <file>pseudo256.csv</file>
+ <desc>The field is not prime (but a Carmichael pseudoprime, see https://github.com/crocs-muni/fooling-primality-tests/).</desc>
+ </curve>
+ <curve>
+ <id>pseudo384</id>
+ <bits>384</bits>
+ <field>prime</field>
+ <file>pseudo384.csv</file>
+ <desc>The field is not prime (but a Carmichael pseudoprime, see https://github.com/crocs-muni/fooling-primality-tests/).</desc>
+ </curve>
+ <curve>
+ <id>pseudo512</id>
+ <bits>512</bits>
+ <field>prime</field>
+ <file>pseudo512.csv</file>
+ <desc>The field is not prime (but a Carmichael pseudoprime, see https://github.com/crocs-muni/fooling-primality-tests/).</desc>
+ </curve>
+ <curve>
+ <id>pseudo521</id>
+ <bits>521</bits>
+ <field>prime</field>
+ <file>pseudo521.csv</file>
+ <desc>The field is not prime (but a Carmichael pseudoprime, see https://github.com/crocs-muni/fooling-primality-tests/).</desc>
+ </curve>
</curves> \ No newline at end of file
diff --git a/common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo192.csv b/common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo192.csv
new file mode 100644
index 0000000..c98e63b
--- /dev/null
+++ b/common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo192.csv
@@ -0,0 +1 @@
+0xf7601c102e5605a4510b865b28287060ae6002956371b4f7,0x429c8107ce7063a45234aeadd30c021acc6bdaff6531af7d,0x9637284c287bc5c97c574dc8f91d03e5f58f516bfdb77601,0x1f7fe14d44df79fcfbd9225173d39784374bc08a80a8dc40,0xdb2ff34213f3214f1aa4e273e48efaf8362292f4e0ed0b9f,0xf7601c102487dad5b1e6fbcb61193546c31f16a71903f85d,0x0001 \ No newline at end of file
diff --git a/common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo224.csv b/common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo224.csv
new file mode 100644
index 0000000..cf781d6
--- /dev/null
+++ b/common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo224.csv
@@ -0,0 +1 @@
+0xf54255f919b6fec4c9c9788c0dc432b8a50b7331e836a4fff9c5bc7f,0x270b8817bc48b1d56401abf8964e6fc785771d2a26130f8a572682f1,0xe28250a72ac83dd064b08cb83e8d2b678330d4dfd5193179088cb5cb,0xd0a2d469eda6a9c5bf9568459a02e2e65901f907f766891ad2a323cd,0x580e1fbfb94793f5880e36d6a2229c2fb082db0f3270f0b3ec4ce2a8,0xf54255f9581e15675cedd50065fa01410df6bfb6e17a2c69747246e5,0x0001 \ No newline at end of file
diff --git a/common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo256.csv b/common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo256.csv
new file mode 100644
index 0000000..ef14dc4
--- /dev/null
+++ b/common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo256.csv
@@ -0,0 +1 @@
+0x89ae5b1ffa52bd5a6e1e9627d2fef2b1658f5ae93ce0dabecead0f8cf294909b,0x35fe79c1bdac3f16080f6f763f1947c97fe841510d807e632fdb0abca45b539d,0x1da2a1152d54cc6d19da48bfbd8c31f6d7aba41fdbb744ef60c3ffb0a1b1b3cb,0x6ef9419070b90eaec6914e8c4809c3fe1c868b9857874abc4929321a021ef679,0x2391630ddc525199e2f65883d35623545cccd58496caa8b2e3fb8a84df6996e6,0x89ae5b1ffad4189f719eb3801d3a65986202d48cbab151d32b992e92dd589161,0x0001 \ No newline at end of file
diff --git a/common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo384.csv b/common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo384.csv
new file mode 100644
index 0000000..ac1f589
--- /dev/null
+++ b/common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo384.csv
@@ -0,0 +1 @@
+0xbddc881aa619fc8a2f4dedb315f0b55c8c0cca4d7aac4e595c96504eb2e8860489bd824340028f49ca90272998729fe7,0x1595f6abcbb9bea724adb7df2129472f9f4d7ed83e2c9e7a52dc8cd12ef36b7a209f46afa553901d7ecf0d98618dabcf,0xb6bf3f61901462bf181b096d61aa7ee00310d110f739cbf95fccf7faa7f529052ee8758210a9d6c10de2790e4ab7f1e3,0x6525e4141411e472233e794116f285835ed743c77d21cac612c9b8a5000fa58407754ff242671f4ca8478b6bece46ad9,0x335f77556d279a9fd8701c26f14a13646b927d3ab86c165fafb5e3ee08f3797b819eb0eea2e6e3a569c63271c406d3bb,0xbddc881aa619fc85d46958aae14456922f956e5a8bf1d5f3f889d9d14ff5ae4ef373c260215503b442e5a6f88e1b609d,0x0001 \ No newline at end of file
diff --git a/common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo512.csv b/common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo512.csv
new file mode 100644
index 0000000..3562558
--- /dev/null
+++ b/common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo512.csv
@@ -0,0 +1 @@
+0xd7489dfb959fd93de1b90bcdd949ea38d11c7e3637ab48f56fb1b2b34e6593fe3cf189e9c2f3166ddefc270747002d1914c558a23dceab08875e75a6b3b3c88f,0x15ae03d8fdf64becd183b64e8a235322be8342124a3e88ae8691ac7e635f424afad39da56169deb4ee25bfb4538054f6208f1bcb7abff14d6ea61ae9f8d2349b,0x7d22f3ece4a500edd384cae7de2f60377a6852e6d3a417374a881b0d83b8f747fba5106a011c76b2176916cd5fa68371c0ba0b2786b1dcdac80ad329b1a83f28,0x0aead0caddeda9ee70fe1976af1a96a410f96fbe65273a986bc88e3e7f3bd6e24d1dc728a04fecfd17e9ddfdfe9472359d39f877761dcdc73a0ee6514ba4894b,0x03f830aef9bfd770119e28a8de3f94119517508839df651129e8a6819c4e86df580179f97821d266d0e205f7536ab49cc04298aa88dde463d638689645188d86,0xd7489dfb959fd93de1b8fe30119d6f138fbeef529543d12c03f91d34c545a75197f79a0083650dbebee8fa12d39f2902101eed3f2e1963470d77dfe2204a02c7,0x0001 \ No newline at end of file
diff --git a/common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo521.csv b/common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo521.csv
new file mode 100644
index 0000000..4e7c30e
--- /dev/null
+++ b/common/src/main/resources/cz/crcs/ectester/data/wrong/pseudo521.csv
@@ -0,0 +1 @@
+0x153212291c26fe063b78bbca97d35dda6b0b349fe3fc1d4dee21786fc85296e22d93ce855a2d3ed048498c6a1f378cea240f029df302cffb658efe9e12379629acb,0x5a4b83e21db14397282aab529b230058a165962eadf8e8f15703ca5b91501463fc8bf866d7f1a2ce785c4ff0c5797e20e3fb6952bd42e3421ed1c589b2853a0c30,0x1196a7bc6d754b0224fcace252f9056acebba295a7a0763a95fd0fa90cca4bbcc1d030cbee049d06e103bb28c8b870a1d5989d9c56870ff7fde969f3bfd0278fbf7,0xd74e5bf4d166a2d75d57d49be58f9bf3900bda81bbb283a8f311d9972c7cd1ed547403b52c657af133297f852f938b6a7ba8ef52c2ca8eb79799b15f7123c5d2af,0x7ed2303056596fb09cfade2ca0f691c515da266565ba5afa4700c6c6ed38091f3cf4fdc67ee1426b849bb9be26c1e8c3b53530fc4510dad8b7badc81bad7276c5b,0x153212291c26fe063b78bc114fd2c18a365faa9b5b3fecbb87c2690125099ddd8baa5052aa2fda7f14120d3d6af0ac185902f97bae06a009588286cf5ce93b1cce3,0x0001 \ No newline at end of file
diff --git a/common/src/main/resources/cz/crcs/ectester/data/wrong/results.xml b/common/src/main/resources/cz/crcs/ectester/data/wrong/results.xml
index e3f0967..18302b1 100644
--- a/common/src/main/resources/cz/crcs/ectester/data/wrong/results.xml
+++ b/common/src/main/resources/cz/crcs/ectester/data/wrong/results.xml
@@ -12,6 +12,16 @@
<desc>A correct signature by the default key.</desc>
</sigResult>
<sigResult>
+ <id>nok/malleable/s+n</id>
+ <sig>SHA1</sig>
+ <inline>0x304502203988322ab9f52c7f11d5d1aa92a2ac0b00275bcad8e934682257323fda67248202210152231596382268e9f3b82b99e386ebb784c21538f1a379523d1b5af44aaf80fe</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
+ <curve>secg/secp256r1</curve>
+ <signkey>wrong/default_priv</signkey>
+ <verifykey>wrong/default_pub</verifykey>
+ <desc>A correct signature modified by adding n to s.</desc>
+ </sigResult>
+ <sigResult>
<id>nok/negated</id>
<sig>SHA1</sig>
<inline>0x304402203988322ab9f52c7f11d5d1aa92a2ac0b00275bcad8e934682257323fda672482022052231597382268e8f3b82b99e386ebb7c7db1a8b4a8bdacd496190314e4c5bad</inline>
@@ -23,8 +33,9 @@
</sigResult>
<sigResult>
<id>nok/random</id>
- <sig>SHA1</sig>
+ <sig>*</sig>
<inline>0x30440220e641671e6415629dc8398e35ae1362cb647f293a92553b1594d57fff58df302c02206baafface035e3758eea0dd9ef734976c70b6dd06f4d81d33f5e28bfb8730624</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
@@ -32,8 +43,9 @@
</sigResult>
<sigResult>
<id>nok/r0</id>
- <sig>SHA1</sig>
- <inline>0x3044022000000000000000000000000000000000000000000000000000000000000000000220d0837b07fe63d225733391e6808a081fd8aeb1359511feba7ca4f266727f968e</inline>
+ <sig>*</sig>
+ <inline>0x30250201000220675e2eb20e1f1ec11c3016f7675d9a2e7a3c3370efde499ccb91920ab3da4ef3</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
@@ -41,8 +53,9 @@
</sigResult>
<sigResult>
<id>nok/s0</id>
- <sig>SHA1</sig>
- <inline>0x304402206bea66d439da6b0b4a0e45b51e76d53336f27f7aa8e35f2008b77a8e021eff0a02200000000000000000000000000000000000000000000000000000000000000000</inline>
+ <sig>*</sig>
+ <inline>0x302502206bea66d439da6b0b4a0e45b51e76d53336f27f7aa8e35f2008b77a8e021eff0a020100</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
@@ -50,8 +63,9 @@
</sigResult>
<sigResult>
<id>nok/r1</id>
- <sig>SHA1</sig>
- <inline>0x3044022000000000000000000000000000000000000000000000000000000000000000010220e660f19ddc20a30adda6ca175577b492e238ef8734b904a31045d453825974d4</inline>
+ <sig>*</sig>
+ <inline>0x302502010102203494a201a1a539189253c5eab77d1cb99ce1b154c642acc85a956cf2eec2bb3f</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
@@ -59,8 +73,9 @@
</sigResult>
<sigResult>
<id>nok/s1</id>
- <sig>SHA1</sig>
- <inline>0x30440220d30ab3301d7132edbead77c0d622bbb7be8626c9ac5ee6c536281e6c18e79ab002200000000000000000000000000000000000000000000000000000000000000001</inline>
+ <sig>*</sig>
+ <inline>0x302502201ee448a2ce4695ac5b71d89553e3dd9688f33041f64aa9aed49c269f6f943c25020101</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
@@ -68,8 +83,9 @@
</sigResult>
<sigResult>
<id>nok/r0s0</id>
- <sig>SHA1</sig>
- <inline>0x30440220000000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000000</inline>
+ <sig>*</sig>
+ <inline>0x3006020100020100</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
@@ -77,8 +93,9 @@
</sigResult>
<sigResult>
<id>nok/r0s1</id>
- <sig>SHA1</sig>
- <inline>0x30440220000000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000001</inline>
+ <sig>*</sig>
+ <inline>0x3006020100020101</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
@@ -86,8 +103,9 @@
</sigResult>
<sigResult>
<id>nok/r1s0</id>
- <sig>SHA1</sig>
- <inline>0x30440220000000000000000000000000000000000000000000000000000000000000000102200000000000000000000000000000000000000000000000000000000000000000</inline>
+ <sig>*</sig>
+ <inline>0x3006020101020100</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
@@ -95,17 +113,99 @@
</sigResult>
<sigResult>
<id>nok/r1s1</id>
- <sig>SHA1</sig>
- <inline>0x30440220000000000000000000000000000000000000000000000000000000000000000102200000000000000000000000000000000000000000000000000000000000000001</inline>
+ <sig>*</sig>
+ <inline>0x3006020101020101</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
<desc>Well-formed invalid signature with r = 1 and s = 1.</desc>
</sigResult>
<sigResult>
+ <id>nok/r0_padded</id>
+ <sig>*</sig>
+ <inline>0x3044022000000000000000000000000000000000000000000000000000000000000000000220675e2eb20e1f1ec11c3016f7675d9a2e7a3c3370efde499ccb91920ab3da4ef3</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
+ <curve>secg/secp256r1</curve>
+ <signkey>wrong/default_priv</signkey>
+ <verifykey>wrong/default_pub</verifykey>
+ <desc>Malformed (zero-padded) invalid signature with r = 0.</desc>
+ </sigResult>
+ <sigResult>
+ <id>nok/s0_padded</id>
+ <sig>*</sig>
+ <inline>0x304402206bea66d439da6b0b4a0e45b51e76d53336f27f7aa8e35f2008b77a8e021eff0a02200000000000000000000000000000000000000000000000000000000000000000</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
+ <curve>secg/secp256r1</curve>
+ <signkey>wrong/default_priv</signkey>
+ <verifykey>wrong/default_pub</verifykey>
+ <desc>Malformed (zero-padded) invalid signature with s = 0.</desc>
+ </sigResult>
+ <sigResult>
+ <id>nok/r1_padded</id>
+ <sig>*</sig>
+ <inline>0x30440220000000000000000000000000000000000000000000000000000000000000000102203494a201a1a539189253c5eab77d1cb99ce1b154c642acc85a956cf2eec2bb3f</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
+ <curve>secg/secp256r1</curve>
+ <signkey>wrong/default_priv</signkey>
+ <verifykey>wrong/default_pub</verifykey>
+ <desc>Malformed (zero-padded) invalid signature with r = 1.</desc>
+ </sigResult>
+ <sigResult>
+ <id>nok/s1_padded</id>
+ <sig>*</sig>
+ <inline>0x304402201ee448a2ce4695ac5b71d89553e3dd9688f33041f64aa9aed49c269f6f943c2502200000000000000000000000000000000000000000000000000000000000000001</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
+ <curve>secg/secp256r1</curve>
+ <signkey>wrong/default_priv</signkey>
+ <verifykey>wrong/default_pub</verifykey>
+ <desc>Malformed (zero-padded) invalid signature with s = 1.</desc>
+ </sigResult>
+ <sigResult>
+ <id>nok/r0s0_padded</id>
+ <sig>*</sig>
+ <inline>0x30440220000000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000000</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
+ <curve>secg/secp256r1</curve>
+ <signkey>wrong/default_priv</signkey>
+ <verifykey>wrong/default_pub</verifykey>
+ <desc>Malformed (zero-padded) invalid signature with r = 0 and s = 0.</desc>
+ </sigResult>
+ <sigResult>
+ <id>nok/r0s1_padded</id>
+ <sig>*</sig>
+ <inline>0x30440220000000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000001</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
+ <curve>secg/secp256r1</curve>
+ <signkey>wrong/default_priv</signkey>
+ <verifykey>wrong/default_pub</verifykey>
+ <desc>Malformed (zero-padded) invalid signature with r = 0 and s = 1.</desc>
+ </sigResult>
+ <sigResult>
+ <id>nok/r1s0_padded</id>
+ <sig>*</sig>
+ <inline>0x30440220000000000000000000000000000000000000000000000000000000000000000102200000000000000000000000000000000000000000000000000000000000000000</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
+ <curve>secg/secp256r1</curve>
+ <signkey>wrong/default_priv</signkey>
+ <verifykey>wrong/default_pub</verifykey>
+ <desc>Malformed (zero-padded) invalid signature with r = 1 and s = 0.</desc>
+ </sigResult>
+ <sigResult>
+ <id>nok/r1s1_padded</id>
+ <sig>*</sig>
+ <inline>0x30440220000000000000000000000000000000000000000000000000000000000000000102200000000000000000000000000000000000000000000000000000000000000001</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
+ <curve>secg/secp256r1</curve>
+ <signkey>wrong/default_priv</signkey>
+ <verifykey>wrong/default_pub</verifykey>
+ <desc>Malformed (zero-padded) invalid signature with r = 1 and s = 1.</desc>
+ </sigResult>
+ <sigResult>
<id>nok/sp</id>
- <sig>SHA1</sig>
- <inline>0x30440220fc48281b60b73752f3e20c25e8a06b335122d5890db28d2969d3145fcd384e7b0220ffffffff00000001000000000000000000000000ffffffffffffffffffffffff</inline>
+ <sig>*</sig>
+ <inline>0x304502207c48281b60b73752f3e20c25e8a06b335122d5890db28d2969d3145fcd384e7b022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
@@ -113,17 +213,49 @@
</sigResult>
<sigResult>
<id>nok/s2p</id>
- <sig>SHA1</sig>
- <inline>0x30450220feba982489753a51a69fd582673d2e62b6b07cc6374237c1424f1e469cb00a98022101fffffffe00000002000000000000000000000001fffffffffffffffffffffffe</inline>
+ <sig>*</sig>
+ <inline>0x304502207eba982489753a51a69fd582673d2e62b6b07cc6374237c1424f1e469cb00a98022101fffffffe00000002000000000000000000000001fffffffffffffffffffffffe</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
<desc>Well-formed invalid signature with s = 2 * p.</desc>
</sigResult>
<sigResult>
+ <id>nok/sn</id>
+ <sig>*</sig>
+ <inline>0x304502207c48281b60b73752f3e20c25e8a06b335122d5890db28d2969d3145fcd384e7b022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
+ <curve>secg/secp256r1</curve>
+ <signkey>wrong/default_priv</signkey>
+ <verifykey>wrong/default_pub</verifykey>
+ <desc>Well-formed invalid signature s = n.</desc>
+ </sigResult>
+ <sigResult>
+ <id>nok/rnsn</id>
+ <sig>*</sig>
+ <inline>0x3046022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
+ <curve>secg/secp256r1</curve>
+ <signkey>wrong/default_priv</signkey>
+ <verifykey>wrong/default_pub</verifykey>
+ <desc>Well-formed invalid signature r = n and s = n.</desc>
+ </sigResult>
+ <sigResult>
+ <id>nok/s2n</id>
+ <sig>*</sig>
+ <inline>0x304502207eba982489753a51a69fd582673d2e62b6b07cc6374237c1424f1e469cb00a98022101fffffffe00000002000000000000000000000001fffffffffffffffffffffffe</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
+ <curve>secg/secp256r1</curve>
+ <signkey>wrong/default_priv</signkey>
+ <verifykey>wrong/default_pub</verifykey>
+ <desc>Well-formed invalid signature with s = 2 * n.</desc>
+ </sigResult>
+ <sigResult>
<id>nok/length_overflow16</id>
- <sig>SHA1</sig>
+ <sig>*</sig>
<inline>0x3083ff000002203988322ab9f52c7f11d5d1aa92a2ac0b00275bcad8e934682257323fda672482022052231597382268e8f3b82b99e386ebb7c7db1a8b4a8bdacd496190314e4c5bad</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
@@ -131,8 +263,9 @@
</sigResult>
<sigResult>
<id>nok/length_overflow32</id>
- <sig>SHA1</sig>
+ <sig>*</sig>
<inline>0x3085ff0000000002203988322ab9f52c7f11d5d1aa92a2ac0b00275bcad8e934682257323fda672482022052231597382268e8f3b82b99e386ebb7c7db1a8b4a8bdacd496190314e4c5bad</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
@@ -140,8 +273,9 @@
</sigResult>
<sigResult>
<id>nok/length_overflow64</id>
- <sig>SHA1</sig>
+ <sig>*</sig>
<inline>0x3089ff000000000000000002203988322ab9f52c7f11d5d1aa92a2ac0b00275bcad8e934682257323fda672482022052231597382268e8f3b82b99e386ebb7c7db1a8b4a8bdacd496190314e4c5bad</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
@@ -149,8 +283,9 @@
</sigResult>
<sigResult>
<id>nok/length_indefinite</id>
- <sig>SHA1</sig>
+ <sig>*</sig>
<inline>0x308002203988322ab9f52c7f11d5d1aa92a2ac0b00275bcad8e934682257323fda672482022052231597382268e8f3b82b99e386ebb7c7db1a8b4a8bdacd496190314e4c5bad</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
@@ -158,8 +293,9 @@
</sigResult>
<sigResult>
<id>nok/long</id>
- <sig>SHA1</sig>
+ <sig>*</sig>
<inline>0x30420220e641671e6415629dc8398e35ae1362cb647f293a92553b1594d57fff58df302c02206baafface035e3758eea0dd9ef734976c70b6dd06f4d81d33f5e28bfb8730624</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
@@ -167,8 +303,9 @@
</sigResult>
<sigResult>
<id>nok/short</id>
- <sig>SHA1</sig>
+ <sig>*</sig>
<inline>0x30460220e641671e6415629dc8398e35ae1362cb647f293a92553b1594d57fff58df302c02206baafface035e3758eea0dd9ef734976c70b6dd06f4d81d33f5e28bfb8730624</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
@@ -176,8 +313,9 @@
</sigResult>
<sigResult>
<id>nok/long_r</id>
- <sig>SHA1</sig>
+ <sig>*</sig>
<inline>0x3044021ee641671e6415629dc8398e35ae1362cb647f293a92553b1594d57fff58df302c02206baafface035e3758eea0dd9ef734976c70b6dd06f4d81d33f5e28bfb8730624</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
@@ -185,8 +323,9 @@
</sigResult>
<sigResult>
<id>nok/long_s</id>
- <sig>SHA1</sig>
+ <sig>*</sig>
<inline>0x30440220e641671e6415629dc8398e35ae1362cb647f293a92553b1594d57fff58df302c021e6baafface035e3758eea0dd9ef734976c70b6dd06f4d81d33f5e28bfb8730624</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
@@ -194,8 +333,9 @@
</sigResult>
<sigResult>
<id>nok/short_r</id>
- <sig>SHA1</sig>
+ <sig>*</sig>
<inline>0x30440222e641671e6415629dc8398e35ae1362cb647f293a92553b1594d57fff58df302c02206baafface035e3758eea0dd9ef734976c70b6dd06f4d81d33f5e28bfb8730624</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
@@ -203,8 +343,9 @@
</sigResult>
<sigResult>
<id>nok/short_s</id>
- <sig>SHA1</sig>
+ <sig>*</sig>
<inline>0x30440220e641671e6415629dc8398e35ae1362cb647f293a92553b1594d57fff58df302c02226baafface035e3758eea0dd9ef734976c70b6dd06f4d81d33f5e28bfb8730624</inline>
+ <raw>0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB</raw>
<curve>secg/secp256r1</curve>
<signkey>wrong/default_priv</signkey>
<verifykey>wrong/default_pub</verifykey>
diff --git a/ext/boringssl b/ext/boringssl
-Subproject 80a243e07ef77156af66efa7d22ac35aba44c1b
+Subproject 67422ed4434116daa8898773692165ddd51a6ac
diff --git a/reader/build.gradle.kts b/reader/build.gradle.kts
index 0e8de4e..0386ea5 100644
--- a/reader/build.gradle.kts
+++ b/reader/build.gradle.kts
@@ -23,7 +23,7 @@ dependencies {
}
java {
- sourceCompatibility = JavaVersion.VERSION_11
+ sourceCompatibility = JavaVersion.VERSION_15
}
application {
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 9ba9890..91f4653 100644
--- a/reader/src/main/java/cz/crcs/ectester/reader/ECTesterReader.java
+++ b/reader/src/main/java/cz/crcs/ectester/reader/ECTesterReader.java
@@ -73,7 +73,7 @@ public class ECTesterReader {
private static String CLI_HEADER;
private static String CLI_FOOTER = "\n" + LICENSE;
- private static final byte[] SELECT_PREFIX = {(byte) 0x00, (byte) 0xa4, (byte) 0x04, (byte) 0x00, (byte) 0x0c};
+ private static final byte[] SELECT_PREFIX = {(byte) 0x00, (byte) 0xa4, (byte) 0x04, (byte) 0x00, (byte) 0x0f};
private static final byte[] AID_PREFIX = {(byte) 0x45, (byte) 0x43, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x65, (byte) 0x72};
private static final byte[] AID_CURRENT_VERSION = {(byte) 0x30, (byte) 0x33, (byte) 0x33}; // VERSION v0.3.3
private static final byte[] AID_SUFFIX_221 = {(byte) 0x20, (byte) 0x32, (byte) 0x32, (byte) 0x31};
diff --git a/standalone/build.gradle.kts b/standalone/build.gradle.kts
index 27764eb..5ad3fb4 100644
--- a/standalone/build.gradle.kts
+++ b/standalone/build.gradle.kts
@@ -25,7 +25,7 @@ dependencies {
}
java {
- sourceCompatibility = JavaVersion.VERSION_11
+ sourceCompatibility = JavaVersion.VERSION_15
}
application {
@@ -90,7 +90,7 @@ tasks.register<Exec>("libs") {
workingDir("src/main/resources/cz/crcs/ectester/standalone/libs/jni")
environment("PROJECT_ROOT_PATH", rootDir.absolutePath)
- val libName = findProperty("libName") ?: ""
+ val libName = findProperty("libName") ?: "all"
if ( libName == "" ) {
println("Building all libraries")
} else {
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 c702dee..e6d8188 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java
@@ -36,10 +36,9 @@ 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.*;
+import cz.crcs.ectester.standalone.libs.jni.SignalException;
+import cz.crcs.ectester.standalone.libs.jni.TimeoutException;
import cz.crcs.ectester.standalone.output.FileTestWriter;
-import cz.crcs.ectester.standalone.output.TextTestWriter;
-import cz.crcs.ectester.standalone.output.XMLTestWriter;
-import cz.crcs.ectester.standalone.output.YAMLTestWriter;
import cz.crcs.ectester.standalone.test.suites.*;
import org.apache.commons.cli.*;
@@ -55,8 +54,7 @@ import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.*;
-import java.security.interfaces.ECPrivateKey;
-import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.*;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
@@ -105,8 +103,13 @@ public class ECTesterStandalone {
reqs.toFile().mkdirs();
if (!System.getProperty("os.name").startsWith("Windows")) {
- FileUtil.writeNewer(LIB_RESOURCE_DIR + "lib_timing.so", reqs.resolve("lib_timing.so"));
+ 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_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());
}
List<ProviderECLibrary> libObjects = new LinkedList<>();
@@ -133,16 +136,6 @@ public class ECTesterStandalone {
}
libs = libObjects.toArray(new ProviderECLibrary[0]);
- //TODO: push this further down to only initialize if necessary.
- // and only initialize the chosen lib (so give libs a name in Java only)
- for (ECLibrary lib : libs) {
- try {
- lib.initialize();
- } catch (Exception ex) {
- System.err.println(ex.getMessage());
- }
- }
-
cfg = new Config(libs);
if (!cfg.readOptions(cli)) {
return;
@@ -299,26 +292,36 @@ public class ECTesterStandalone {
*/
private void listLibraries() {
for (ProviderECLibrary lib : libs) {
- if (lib.isInitialized() && (cfg.selected == null || lib == cfg.selected)) {
+ if (cfg.selected == null || lib == cfg.selected) {
+ try {
+ if (!lib.initialize()) {
+ continue;
+ }
+ } catch (Exception ex) {
+ System.err.println("Error initializing " + lib.fullName());
+ System.err.println(ex.getMessage());
+ continue;
+ }
+
System.out.println("\t- " + Colors.bold(lib.name()));
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());
Set<KeyPairGeneratorIdent> kpgs = lib.getKPGs();
if (!kpgs.isEmpty()) {
- System.out.println(Colors.bold("\t\t- KeyPairGenerators: ") + kpgs.stream().map(KeyPairGeneratorIdent::getName).collect(Collectors.joining(", ")));
+ System.out.println(Colors.bold("\t\t- KeyPairGenerators: ") + kpgs.stream().map(KeyPairGeneratorIdent::getName).sorted().collect(Collectors.joining(", ")));
}
Set<KeyAgreementIdent> eckas = lib.getKAs();
if (!eckas.isEmpty()) {
- System.out.println(Colors.bold("\t\t- KeyAgreements: ") + eckas.stream().map(KeyAgreementIdent::getName).collect(Collectors.joining(", ")));
+ System.out.println(Colors.bold("\t\t- KeyAgreements: ") + eckas.stream().map(KeyAgreementIdent::getName).sorted().collect(Collectors.joining(", ")));
}
Set<SignatureIdent> sigs = lib.getSigs();
if (!sigs.isEmpty()) {
- System.out.println(Colors.bold("\t\t- Signatures: ") + sigs.stream().map(SignatureIdent::getName).collect(Collectors.joining(", ")));
+ System.out.println(Colors.bold("\t\t- Signatures: ") + sigs.stream().map(SignatureIdent::getName).sorted().collect(Collectors.joining(", ")));
}
Set<String> curves = lib.getCurves();
if (!curves.isEmpty()) {
- System.out.println(Colors.bold("\t\t- Curves: ") + String.join(", ", curves));
+ System.out.println(Colors.bold("\t\t- Curves: ") + curves.stream().sorted().collect(Collectors.joining(", ")));
}
System.out.println();
}
@@ -458,8 +461,8 @@ public class ECTesterStandalone {
other = kpg.genKeyPair();
}
- ECPrivateKey privkey = (ECPrivateKey) ECUtil.loadKey(EC_Consts.PARAMETER_S, cli.getOptionValue("ecdh.named-private"), cli.getOptionValue("ecdh.private"), spec);
- ECPublicKey pubkey = (ECPublicKey) ECUtil.loadKey(EC_Consts.PARAMETER_W, cli.getOptionValue("ecdh.named-public"), cli.getOptionValue("ecdh.public"), spec);
+ PrivateKey privkey = (ECPrivateKey) ECUtil.loadKey(EC_Consts.PARAMETER_S, cli.getOptionValue("ecdh.named-private"), cli.getOptionValue("ecdh.private"), spec);
+ PublicKey pubkey = (ECPublicKey) ECUtil.loadKey(EC_Consts.PARAMETER_W, cli.getOptionValue("ecdh.named-public"), cli.getOptionValue("ecdh.public"), spec);
int amount = Integer.parseInt(cli.getOptionValue("ecdh.amount", "1"));
for (int i = 0; i < amount || amount == 0; ++i) {
@@ -471,11 +474,11 @@ public class ECTesterStandalone {
}
if (!cli.hasOption("ecdh.named-private") && !cli.hasOption("ecdh.private")) {
- privkey = (ECPrivateKey) one.getPrivate();
+ privkey = one.getPrivate();
}
if (!cli.hasOption("ecdh.named-public") && !cli.hasOption("ecdh.public")) {
- pubkey = (ECPublicKey) other.getPublic();
+ pubkey = other.getPublic();
}
long elapsed = -System.nanoTime();
@@ -501,8 +504,8 @@ public class ECTesterStandalone {
}
ka = kaIdent.getInstance(lib.getProvider());
- String pub = ByteUtil.bytesToHex(ECUtil.toX962Uncompressed(pubkey.getW(), pubkey.getParams()), false);
- String priv = ByteUtil.bytesToHex(privkey.getS().toByteArray(), false);
+ String pub = ByteUtil.bytesToHex(ECUtil.pubkeyToBytes(pubkey), false);
+ String priv = ByteUtil.bytesToHex(ECUtil.privkeyToBytes(privkey), false);
String dh = ByteUtil.bytesToHex(result, false);
out.printf("%d;%d;%s;%s;%s%n", i, elapsed, pub, priv, dh);
}
@@ -605,17 +608,17 @@ public class ECTesterStandalone {
String hashAlgoOut = sigIdent.getHashAlgo() != null ? String.format("[%s]", sigIdent.getHashAlgo()) : "";
out.printf("index;signTime[%s];verifyTime[%s];data;pubW;privS;signature%s;nonce;verified%n", timeUnit, timeUnit, hashAlgoOut);
- ECPrivateKey privkey = (ECPrivateKey) ECUtil.loadKey(EC_Consts.PARAMETER_S, cli.getOptionValue("ecdsa.named-private"), cli.getOptionValue("ecdsa.private"), spec);
- ECPublicKey pubkey = (ECPublicKey) ECUtil.loadKey(EC_Consts.PARAMETER_W, cli.getOptionValue("ecdsa.named-public"), cli.getOptionValue("ecdsa.public"), spec);
+ PrivateKey privkey = (ECPrivateKey) ECUtil.loadKey(EC_Consts.PARAMETER_S, cli.getOptionValue("ecdsa.named-private"), cli.getOptionValue("ecdsa.private"), spec);
+ PublicKey pubkey = (ECPublicKey) ECUtil.loadKey(EC_Consts.PARAMETER_W, cli.getOptionValue("ecdsa.named-public"), cli.getOptionValue("ecdsa.public"), spec);
KeyPair one;
if (cli.hasOption("ecdsa.fixed")) {
one = kpg.genKeyPair();
if (!cli.hasOption("ecdsa.named-private")) {
- privkey = (ECPrivateKey) one.getPrivate();
+ privkey = one.getPrivate();
}
if (!cli.hasOption("ecdsa.named-public")) {
- pubkey = (ECPublicKey) one.getPublic();
+ pubkey = one.getPublic();
}
}
@@ -626,10 +629,10 @@ public class ECTesterStandalone {
one = kpg.genKeyPair();
if (!cli.hasOption("ecdsa.named-private")) {
- privkey = (ECPrivateKey) one.getPrivate();
+ privkey = one.getPrivate();
}
if (!cli.hasOption("ecdsa.named-public")) {
- pubkey = (ECPublicKey) one.getPublic();
+ pubkey = one.getPublic();
}
}
@@ -653,27 +656,31 @@ public class ECTesterStandalone {
verifyTime = lib.getLastNativeTiming();
}
- String pub = ByteUtil.bytesToHex(ECUtil.toX962Uncompressed(pubkey.getW(), pubkey.getParams()), false);
- String priv = ByteUtil.bytesToHex(privkey.getS().toByteArray(), false);
+ String pub = ByteUtil.bytesToHex(ECUtil.pubkeyToBytes(pubkey), false);
+ String priv = ByteUtil.bytesToHex(ECUtil.privkeyToBytes(privkey), false);
String sign = ByteUtil.bytesToHex(signature, false);
String k = "";
- ECParameterSpec kSpec = spec;
- if (kSpec == null) {
- kSpec = privkey.getParams();
- }
- if (kSpec != null) {
- // Parse the types out of SignatureIdent.
- String hashAlgo = sigIdent.getHashAlgo();
- String sigType = sigIdent.getSigType();
- if (sigType == null) {
- sigType = sigIdent.toString();
+ if (privkey instanceof ECPrivateKey) {
+ ECPrivateKey ecPrivateKey = (ECPrivateKey) privkey;
+ ECParameterSpec kSpec = spec;
+ if (kSpec == null) {
+ kSpec = ecPrivateKey.getParams();
}
+ if (kSpec != null) {
+ // Parse the types out of SignatureIdent.
+ String hashAlgo = sigIdent.getHashAlgo();
+ String sigType = sigIdent.getSigType();
+ if (sigType == null) {
+ sigType = sigIdent.toString();
+ }
- BigInteger kValue = ECUtil.recoverSignatureNonce(signature, data, privkey.getS(), kSpec, hashAlgo, sigType);
- if (kValue != null) {
- k = ByteUtil.bytesToHex(kValue.toByteArray(), false);
+ BigInteger kValue = ECUtil.recoverSignatureNonce(signature, data, ecPrivateKey.getS(), kSpec, hashAlgo, sigType);
+ if (kValue != null) {
+ k = ByteUtil.bytesToHex(kValue.toByteArray(), false);
+ }
}
}
+
out.printf("%d;%d;%d;%s;%s;%s;%s;%s;%d%n", i, signTime, verifyTime, dataString, pub, priv, sign, k, verified ? 1 : 0);
}
@@ -739,16 +746,31 @@ public class ECTesterStandalone {
int amount = Integer.parseInt(cli.getOptionValue("generate.amount", "1"));
for (int i = 0; i < amount || amount == 0; ++i) {
long elapsed = -System.nanoTime();
- KeyPair kp = kpg.genKeyPair();
+ KeyPair kp;
+ try {
+ kp = kpg.genKeyPair();
+ } catch (SignalException exc) {
+ System.err.println(exc.getSigInfo());
+ continue;
+ } catch (TimeoutException exc) {
+ System.err.println(exc);
+ continue;
+ }
elapsed += System.nanoTime();
if (!lib.getNativeTimingSupport().isEmpty()) {
elapsed = lib.getLastNativeTiming();
}
- ECPublicKey publicKey = (ECPublicKey) kp.getPublic();
- ECPrivateKey privateKey = (ECPrivateKey) kp.getPrivate();
-
- String pub = ByteUtil.bytesToHex(ECUtil.toX962Uncompressed(publicKey.getW(), publicKey.getParams()), false);
- String priv = ByteUtil.bytesToHex(privateKey.getS().toByteArray(), false);
+ PublicKey pubkey = kp.getPublic();
+ PrivateKey privkey = kp.getPrivate();
+ byte[] pubBytes = ECUtil.pubkeyToBytes(pubkey);
+ byte[] privBytes = ECUtil.privkeyToBytes(privkey);
+ String pub = ByteUtil.bytesToHex(pubBytes, false);
+ String priv = ByteUtil.bytesToHex(privBytes, false);
+ if (pubBytes == null || privBytes == null) {
+ System.err.println(pubkey.getClass().getCanonicalName());
+ System.err.println(privkey.getClass().getCanonicalName());
+ break;
+ }
out.printf("%d;%d;%s;%s%n", i, elapsed, pub, priv);
}
@@ -763,8 +785,40 @@ public class ECTesterStandalone {
private void test() throws TestException, ParserConfigurationException, FileNotFoundException {
TestWriter writer = new FileTestWriter(cli.getOptionValue("test.format", "text"), !cli.hasOption("test.quiet"), cli.getOptionValues("test.output"));
StandaloneTestSuite suite;
+ String suiteOpt = cli.getArg(0) != null ? cli.getArg(0).toLowerCase() : "default";
+ String testSuite;
+ int testFrom;
+ int testTo;
+ if (suiteOpt.contains(":")) {
+ String[] parts = suiteOpt.split(":");
+ if (parts.length < 2 || parts.length > 3) {
+ System.err.println("Invalid test suite selection.");
+ return;
+ }
+ testSuite = parts[0];
+ try {
+ testFrom = Integer.parseInt(parts[1]);
+ } catch (NumberFormatException nfe) {
+ System.err.println("Invalid test_from number: " + parts[1] + ".");
+ return;
+ }
+ if (parts.length == 3) {
+ try {
+ testTo = Integer.parseInt(parts[2]);
+ } catch (NumberFormatException nfe) {
+ System.err.println("Invalid test_to number: " + parts[2] + ".");
+ return;
+ }
+ } else {
+ testTo = -1;
+ }
+ } else {
+ testSuite = suiteOpt;
+ testFrom = 0;
+ testTo = -1;
+ }
- switch (cli.getArg(0).toLowerCase()) {
+ switch (testSuite) {
case "test-vectors":
suite = new StandaloneTestVectorSuite(writer, cfg, cli);
break;
@@ -798,12 +852,12 @@ public class ECTesterStandalone {
case "performance":
suite = new StandalonePerformanceSuite(writer, cfg, cli);
break;
- case "default":
default:
suite = new StandaloneDefaultSuite(writer, cfg, cli);
+ break;
}
- suite.run();
+ suite.run(testFrom, testTo);
}
/**
@@ -888,7 +942,7 @@ public class ECTesterStandalone {
if (libraryName != null) {
List<ProviderECLibrary> matchedLibs = new LinkedList<>();
for (ProviderECLibrary lib : libs) {
- if (lib.isInitialized() && lib.name().toLowerCase().contains(libraryName.toLowerCase())) {
+ if (lib.name().toLowerCase().contains(libraryName.toLowerCase())) {
matchedLibs.add(lib);
}
}
@@ -900,6 +954,12 @@ public class ECTesterStandalone {
return false;
} else {
selected = matchedLibs.get(0);
+ try {
+ selected.initialize();
+ } catch (Exception ex) {
+ System.err.println("Error initializing " + selected.fullName());
+ System.err.println(ex.getMessage());
+ }
}
}
}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java b/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java
index 60c60e8..c0cf793 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java
@@ -18,10 +18,11 @@ public class KeyAgreementIdent extends Ident {
private static final List<KeyAgreementIdent> ALL = new LinkedList<>();
static {
- //https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html
+ // https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html
// Basic ECDH and ECDHC (plain/raw)
ALL.add(new KeyAgreementIdent("ECDH"));
ALL.add(new KeyAgreementIdent("ECDHC", "ECCDH"));
+
// ECDH and ECDHC with SHA as KDF, OIDs from RFC 3278
ALL.add(new KeyAgreementIdent("ECDHwithSHA1KDF", true, "1.3.133.16.840.63.0.2"));
ALL.add(new KeyAgreementIdent("ECCDHwithSHA1KDF", true, "1.3.133.16.840.63.0.3"));
@@ -33,11 +34,13 @@ public class KeyAgreementIdent extends Ident {
ALL.add(new KeyAgreementIdent("ECCDHwithSHA384KDF", true, "1.3.132.1.14.2"));
ALL.add(new KeyAgreementIdent("ECDHwithSHA512KDF", true, "1.3.132.1.11.3"));
ALL.add(new KeyAgreementIdent("ECCDHwithSHA512KDF", true, "1.3.132.1.14.3"));
+
// Microsoft specific KDF
ALL.add(new KeyAgreementIdent("ECDHwithSHA1KDF(CNG)"));
ALL.add(new KeyAgreementIdent("ECDHwithSHA256KDF(CNG)"));
ALL.add(new KeyAgreementIdent("ECDHwithSHA384KDF(CNG)"));
ALL.add(new KeyAgreementIdent("ECDHwithSHA512KDF(CNG)"));
+
// CKDF requires custom AlgorithmParameterSpec (only BouncyCastle)
//ALL.add(new KeyAgreementIdent("ECDHwithSHA1CKDF", true));
//ALL.add(new KeyAgreementIdent("ECCDHwithSHA1CKDF", true));
@@ -47,6 +50,7 @@ public class KeyAgreementIdent extends Ident {
//ALL.add(new KeyAgreementIdent("ECCDHwithSHA384CKDF", true));
//ALL.add(new KeyAgreementIdent("ECDHwithSHA512CKDF", true));
//ALL.add(new KeyAgreementIdent("ECCDHwithSHA512CKDF", true));
+
// ECMQV - Disable for now as it needs diferent params(too different from DH)
//ALL.add(new KeyAgreementIdent("ECMQV"));
//ALL.add(new KeyAgreementIdent("ECMQVwithSHA1KDF", true));
@@ -59,10 +63,16 @@ public class KeyAgreementIdent extends Ident {
//ALL.add(new KeyAgreementIdent("ECMQVwithSHA256CKDF", true, "1.3.132.1.15.1"));
//ALL.add(new KeyAgreementIdent("ECMQVwithSHA384CKDF", true, "1.3.132.1.15.2"));
//ALL.add(new KeyAgreementIdent("ECMQVwithSHA512CKDF", true, "1.3.132.1.15.3"));
+
// ECVKO - Disable for now as it needs diferent params(too different from DH)
//ALL.add(new KeyAgreementIdent("ECVKO", "ECGOST3410", "1.2.643.2.2.19", "GOST-3410-2001", "1.2.643.2.2.96"));
//ALL.add(new KeyAgreementIdent("ECVKO256", "ECGOST3410-2012-256", "1.2.643.7.1.1.6.1", "1.2.643.7.1.1.1.1"));
//ALL.add(new KeyAgreementIdent("ECVKO512", "ECGOST3410-2012-512", "1.2.643.7.1.1.6.2", "1.2.643.7.1.1.1.2"));
+
+ // XDH (RFC 7748)
+ ALL.add(new KeyAgreementIdent("XDH"));
+ ALL.add(new KeyAgreementIdent("X25519"));
+ ALL.add(new KeyAgreementIdent("X448"));
}
public static KeyAgreementIdent get(String ident) {
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java b/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java
index 83eef75..49b982b 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java
@@ -11,6 +11,7 @@ public class KeyPairGeneratorIdent extends Ident {
private static final List<KeyPairGeneratorIdent> ALL = new LinkedList<>();
static {
+ // Short-Weierstrass
ALL.add(new KeyPairGeneratorIdent("EC"));
ALL.add(new KeyPairGeneratorIdent("ECDH"));
ALL.add(new KeyPairGeneratorIdent("ECDSA"));
@@ -22,6 +23,14 @@ public class KeyPairGeneratorIdent extends Ident {
ALL.add(new KeyPairGeneratorIdent("ECKCDSA"));
// ECGDSA? Botan provides.
ALL.add(new KeyPairGeneratorIdent("ECGDSA"));
+ // Montgomery
+ ALL.add(new KeyPairGeneratorIdent("XDH"));
+ ALL.add(new KeyPairGeneratorIdent("X25519"));
+ ALL.add(new KeyPairGeneratorIdent("X448"));
+ // Twisted-Edwards
+ ALL.add(new KeyPairGeneratorIdent("EdDSA"));
+ ALL.add(new KeyPairGeneratorIdent("Ed25519"));
+ ALL.add(new KeyPairGeneratorIdent("Ed448"));
}
public static KeyPairGeneratorIdent get(String ident) {
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/consts/SignatureIdent.java b/standalone/src/main/java/cz/crcs/ectester/standalone/consts/SignatureIdent.java
index c3913b7..a65d0c5 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/consts/SignatureIdent.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/consts/SignatureIdent.java
@@ -30,17 +30,20 @@ public class SignatureIdent extends Ident {
ALL.add(new SignatureIdent("SHA3-384withECDSA", "SHA3-384/ECDSA", "2.16.840.1.101.3.4.3.11"));
ALL.add(new SignatureIdent("SHA3-512withECDSA", "SHA3-512/ECDSA", "2.16.840.1.101.3.4.3.12"));
ALL.add(new SignatureIdent("RIPEMD160withECDSA", "RIPEMD160/ECDSA", "1.3.36.3.3.2.2"));
+
// ECNR
ALL.add(new SignatureIdent("SHA1withECNR"));
ALL.add(new SignatureIdent("SHA224withECNR"));
ALL.add(new SignatureIdent("SHA256withECNR"));
ALL.add(new SignatureIdent("SHA512withECNR"));
+
// CVC-ECDSA
ALL.add(new SignatureIdent("SHA1withCVC-ECDSA", "SHA1/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.1"));
ALL.add(new SignatureIdent("SHA224withCVC-ECDSA", "SHA224/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.2"));
ALL.add(new SignatureIdent("SHA256withCVC-ECDSA", "SHA256/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.3"));
ALL.add(new SignatureIdent("SHA384withCVC-ECDSA", "SHA384/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.4"));
ALL.add(new SignatureIdent("SHA512withCVC-ECDSA", "SHA512/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.5"));
+
// PLAIN-ECDSA
ALL.add(new SignatureIdent("SHA1withPLAIN-ECDSA", "SHA1/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.1"));
ALL.add(new SignatureIdent("SHA224withPLAIN-ECDSA", "SHA224/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.2"));
@@ -48,6 +51,7 @@ public class SignatureIdent extends Ident {
ALL.add(new SignatureIdent("SHA384withPLAIN-ECDSA", "SHA384/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.4"));
ALL.add(new SignatureIdent("SHA512withPLAIN-ECDSA", "SHA512/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.5"));
ALL.add(new SignatureIdent("RIPEMD160withPLAIN-ECDSA", "RIPEMD160/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.6"));
+
// ECGOST
ALL.add(new SignatureIdent("ECGOST3410", "ECGOST-3410", "GOST-3410-2001"));
ALL.add(new SignatureIdent("GOST3411withECGOST3410", "GOST3411/ECGOST3410", "1.2.643.2.2.3"));
@@ -56,6 +60,7 @@ public class SignatureIdent extends Ident {
ALL.add(new SignatureIdent("ECGOST3410-2012-512", "GOST-3410-2012-512"));
ALL.add(new SignatureIdent("GOST3411-2012-512withECGOST3410-2012-512", "GOST3411-2012-512/ECGOST3410-2012-5120", "1.2.643.7.1.1.3.3"));
ALL.add(new SignatureIdent("SM3withSM2"));
+
// ECDDSA (rfc6979?)
ALL.add(new SignatureIdent("ECDDSA", "SHA1withECDDSA", "SHA1withDETECDSA", "DETECDSA", "ECDETDSA"));
ALL.add(new SignatureIdent("SHA224withECDDSA", "SHA224withDETECDSA"));
@@ -66,6 +71,7 @@ public class SignatureIdent extends Ident {
ALL.add(new SignatureIdent("SHA3-256withECDDSA", "SHA3-256withDETECDSA"));
ALL.add(new SignatureIdent("SHA3-384withECDDSA", "SHA3-384withDETECDSA"));
ALL.add(new SignatureIdent("SHA3-512withECDDSA", "SHA3-512withDETECDSA"));
+
// ECKCDSA? Botan provides.
ALL.add(new SignatureIdent("ECKCDSA", "SHA1withECKCDSA", "1.2.410.200004.1.100.4.3"));
ALL.add(new SignatureIdent("NONEwithECKCDSA"));
@@ -74,6 +80,7 @@ public class SignatureIdent extends Ident {
ALL.add(new SignatureIdent("SHA256withECKCDSA", "1.2.410.200004.1.100.4.5"));
ALL.add(new SignatureIdent("SHA384withECKCDSA"));
ALL.add(new SignatureIdent("SHA512withECKCDSA"));
+
// ECGDSA? Botan provides.
ALL.add(new SignatureIdent("ECGDSA", "SHA1withECGDSA", "1.3.36.3.3.2.5.4.2"));
ALL.add(new SignatureIdent("NONEwithECGDSA"));
@@ -82,6 +89,11 @@ public class SignatureIdent extends Ident {
ALL.add(new SignatureIdent("SHA224withECGDSA", "1.3.36.3.3.2.5.4.4"));
ALL.add(new SignatureIdent("SHA384withECGDSA", "1.3.36.3.3.2.5.4.5"));
ALL.add(new SignatureIdent("SHA512withECGDSA", "1.3.36.3.3.2.5.4.6"));
+
+ // EdDSA (RFC 8032)
+ ALL.add(new SignatureIdent("EdDSA"));
+ ALL.add(new SignatureIdent("Ed25519"));
+ ALL.add(new SignatureIdent("Ed448"));
}
public static SignatureIdent get(String ident) {
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 7f9d96e..c11dbdb 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
@@ -33,7 +33,7 @@ public abstract class NativeECLibrary extends ProviderECLibrary {
Path libPath = libDir.resolve(resource + "." + suffix);
/* Write the shim. */
- boolean found = FileUtil.writeNewer(ECTesterStandalone.LIB_RESOURCE_DIR + resource + "." + suffix, libPath);
+ boolean found = FileUtil.write(ECTesterStandalone.LIB_RESOURCE_DIR + resource + "." + suffix, libPath);
if (!found) {
return false;
}
@@ -44,7 +44,7 @@ public abstract class NativeECLibrary extends ProviderECLibrary {
if (requirement.endsWith(suffix)) {
/* The requirement is bundled, write it */
Path reqPath = libReqDir.resolve(requirement);
- found = FileUtil.writeNewer(ECTesterStandalone.LIB_RESOURCE_DIR + requirement, reqPath);
+ found = FileUtil.write(ECTesterStandalone.LIB_RESOURCE_DIR + requirement, reqPath);
if (!found) {
return false;
}
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 6b60779..d4df414 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
@@ -1,6 +1,15 @@
package cz.crcs.ectester.standalone.libs;
+import cz.crcs.ectester.common.ec.EC_Curve;
+import cz.crcs.ectester.common.util.ECUtil;
+import cz.crcs.ectester.data.EC_Store;
+
+import java.security.InvalidAlgorithmParameterException;
import java.security.Provider;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.util.Arrays;
import java.util.Set;
/**
@@ -17,4 +26,27 @@ public class NettleLib extends NativeECLibrary {
@Override
public native Set<String> getCurves();
+
+ public static ECGenParameterSpec parametersKnown(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException {
+ if (params instanceof ECGenParameterSpec) {
+ if (Arrays.asList("secp192r1", "secp224r1", "secp256r1", "secp384r1", "secp521r1").contains(((ECGenParameterSpec) params).getName())) {
+ return (ECGenParameterSpec) params;
+ }
+ } else if (params instanceof ECParameterSpec) {
+ ECParameterSpec spec = (ECParameterSpec) params;
+ EC_Store store = EC_Store.getInstance();
+ if (ECUtil.equalECParameterSpec(spec, store.getObject(EC_Curve.class, "secg/secp192r1").toSpec())) {
+ return new ECGenParameterSpec("secp192r1");
+ } else if (ECUtil.equalECParameterSpec(spec, store.getObject(EC_Curve.class, "secg/secp224r1").toSpec())) {
+ return new ECGenParameterSpec("secp224r1");
+ } else if (ECUtil.equalECParameterSpec(spec, store.getObject(EC_Curve.class, "secg/secp256r1").toSpec())) {
+ return new ECGenParameterSpec("secp256r1");
+ } else if (ECUtil.equalECParameterSpec(spec, store.getObject(EC_Curve.class, "secg/secp384r1").toSpec())) {
+ return new ECGenParameterSpec("secp384r1");
+ } else if (ECUtil.equalECParameterSpec(spec, store.getObject(EC_Curve.class, "secg/secp521r1").toSpec())) {
+ return new ECGenParameterSpec("secp521r1");
+ }
+ }
+ throw new InvalidAlgorithmParameterException("Unknown curve.");
+ }
}
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 a9a49e9..d9d6749 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
@@ -104,6 +104,10 @@ public abstract class ProviderECLibrary implements ECLibrary {
return name;
}
+ public String fullName() {
+ return name() + " (" + provider.getName() + ")";
+ }
+
public Provider getProvider() {
return provider;
}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
index afed02b..d9a4d40 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
@@ -1,6 +1,9 @@
package cz.crcs.ectester.standalone.libs.jni;
+import cz.crcs.ectester.common.ec.EC_Curve;
import cz.crcs.ectester.common.util.ECUtil;
+import cz.crcs.ectester.data.EC_Store;
+import cz.crcs.ectester.standalone.libs.NettleLib;
import javax.crypto.KeyAgreementSpi;
import javax.crypto.SecretKey;
@@ -11,7 +14,6 @@ import java.security.interfaces.ECPublicKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
-import java.security.spec.InvalidParameterSpecException;
/**
* @author Jan Jancar johny@neuromancer.sk
@@ -61,6 +63,22 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
return secret.length;
}
+ protected byte[] getPubkey() {
+ if (publicKey instanceof NativeECPublicKey) {
+ return ((NativeECPublicKey) publicKey).getData();
+ } else {
+ return ECUtil.pubkeyToBytes(publicKey);
+ }
+ }
+
+ protected byte[] getPrivkey() {
+ if (privateKey instanceof NativeECPrivateKey) {
+ return ((NativeECPrivateKey) privateKey).getData();
+ } else {
+ return ECUtil.privkeyToBytes(privateKey);
+ }
+ }
+
private abstract static class SimpleKeyAgreementSpi extends NativeKeyAgreementSpi {
@Override
@@ -72,51 +90,79 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
this.params = params;
}
- private byte[] getPubkey() {
- if (publicKey instanceof NativeECPublicKey) {
- return ((NativeECPublicKey) publicKey).getData();
- } else {
- return ECUtil.toX962Uncompressed(publicKey.getW(), ((ECParameterSpec) params));
+ @Override
+ protected byte[] engineGenerateSecret() throws IllegalStateException {
+ return generateSecret(getPubkey(), getPrivkey(), (ECParameterSpec) params);
+ }
+
+ abstract byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params);
+
+ @Override
+ protected SecretKey engineGenerateSecret(String algorithm) throws IllegalStateException, NoSuchAlgorithmException, InvalidKeyException {
+ if (algorithm == null) {
+ throw new NoSuchAlgorithmException("Algorithm must not be null.");
}
+ return generateSecret(getPubkey(), getPrivkey(), (ECParameterSpec) params, algorithm);
}
- private byte[] getPrivkey() {
- if (privateKey instanceof NativeECPrivateKey) {
- return ((NativeECPrivateKey) privateKey).getData();
- } else {
- return ECUtil.toByteArray(privateKey.getS(), ((ECParameterSpec) params).getOrder().bitLength());
+ abstract SecretKey generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params, String algorithm);
+ }
+
+ private abstract static class ExtendedKeyAgreementSpi extends NativeKeyAgreementSpi {
+
+ @Override
+ protected void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ if (!(params instanceof ECParameterSpec || params instanceof ECGenParameterSpec)) {
+ throw new InvalidAlgorithmParameterException("Unknown parameter class.");
}
+ engineInit(key, random);
+ this.params = params;
}
@Override
protected byte[] engineGenerateSecret() throws IllegalStateException {
- return generateSecret(getPubkey(), getPrivkey(), (ECParameterSpec) params);
+ return generateSecret(publicKey, privateKey, params);
}
- abstract byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params);
+ abstract byte[] generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, AlgorithmParameterSpec params);
@Override
protected SecretKey engineGenerateSecret(String algorithm) throws IllegalStateException, NoSuchAlgorithmException, InvalidKeyException {
if (algorithm == null) {
throw new NoSuchAlgorithmException("Algorithm must not be null");
}
- return generateSecret(getPubkey(), getPrivkey(), (ECParameterSpec) params, algorithm);
+ return generateSecret(publicKey, privateKey, params, algorithm);
}
- abstract SecretKey generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params, String algorithm);
+ abstract SecretKey generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, AlgorithmParameterSpec params, String algorithm);
}
- private abstract static class ExtendedKeyAgreementSpi extends NativeKeyAgreementSpi {
+ private abstract static class NamedKeyAgreementSpi extends NativeKeyAgreementSpi {
+
+ @Override
+ protected void engineInit(Key key, SecureRandom random) throws InvalidKeyException {
+ if (!(key instanceof ECPrivateKey)) {
+ throw new InvalidKeyException("Key must be instance of ECPrivateKey");
+ }
+ privateKey = (ECPrivateKey) key;
+ try {
+ this.params = parametersKnown(privateKey.getParams());
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new InvalidKeyException(e);
+ }
+ }
@Override
protected void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
if (!(params instanceof ECParameterSpec || params instanceof ECGenParameterSpec)) {
- throw new InvalidAlgorithmParameterException();
+ throw new InvalidAlgorithmParameterException("Unknown parameter class.");
}
engineInit(key, random);
- this.params = params;
+ this.params = parametersKnown(params);
}
+ abstract ECGenParameterSpec parametersKnown(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException;
+
@Override
protected byte[] engineGenerateSecret() throws IllegalStateException {
return generateSecret(publicKey, privateKey, params);
@@ -374,7 +420,7 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
}
}
- public abstract static class Nettle extends SimpleKeyAgreementSpi {
+ public abstract static class Nettle extends NamedKeyAgreementSpi {
private final String type;
public Nettle(String type) {
@@ -382,43 +428,21 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
}
@Override
- byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params) {
- try {
- // TODO: OMG remove this monstrosity.
- AlgorithmParameters tmp = AlgorithmParameters.getInstance("EC");
- tmp.init(params);
- ECGenParameterSpec spec = tmp.getParameterSpec(ECGenParameterSpec.class);
- switch (spec.getName()) {
- case "1.2.840.10045.3.1.7":
- spec = new ECGenParameterSpec("secp256r1");
- break;
- case "1.2.840.10045.3.1.1":
- spec = new ECGenParameterSpec("secp192r1");
- break;
- case "1.3.132.0.33":
- spec = new ECGenParameterSpec("secp224r1");
- break;
- case "1.3.132.0.34":
- spec = new ECGenParameterSpec("secp384r1");
- break;
- case "1.3.132.0.35":
- spec = new ECGenParameterSpec("secp521r1");
- break;
- default:
- return null;
+ ECGenParameterSpec parametersKnown(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException {
+ return NettleLib.parametersKnown(params);
+ }
- }
- return generateSecret(pubkey, privkey, spec);
+ @Override
+ byte[] generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, AlgorithmParameterSpec params) {
+ return generateSecret(getPubkey(), getPrivkey(), (ECGenParameterSpec) params);
+ }
- } catch (NoSuchAlgorithmException | InvalidParameterSpecException e) {
- return null;
- }
+ @Override
+ SecretKey generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, AlgorithmParameterSpec params, String algorithm) {
+ throw new UnsupportedOperationException("Not supported.");
}
native byte[] generateSecret(byte[] pubkey, byte[] privkey, ECGenParameterSpec params);
-
- @Override
- native SecretKey generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params, String algorithm);
}
public static class NettleECDH extends Nettle {
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
index 0a9487f..086c2c4 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
@@ -2,6 +2,7 @@ package cz.crcs.ectester.standalone.libs.jni;
import cz.crcs.ectester.common.ec.EC_Curve;
import cz.crcs.ectester.data.EC_Store;
+import cz.crcs.ectester.standalone.libs.NettleLib;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
@@ -293,7 +294,7 @@ public abstract class NativeKeyPairGeneratorSpi extends KeyPairGeneratorSpi {
@Override
native KeyPair generate(AlgorithmParameterSpec params, SecureRandom random);
}
-
+
public static class Libressl extends NativeKeyPairGeneratorSpi {
public Libressl() {
@@ -319,26 +320,48 @@ public abstract class NativeKeyPairGeneratorSpi extends KeyPairGeneratorSpi {
}
@Override
- native boolean keysizeSupported(int keysize);
+ boolean keysizeSupported(int keysize) {
+ switch (keysize) {
+ case 192, 224, 256, 384, 521:
+ return true;
+ default:
+ return false;
+ }
+ }
@Override
- native boolean paramsSupported(AlgorithmParameterSpec params);
+ boolean paramsSupported(AlgorithmParameterSpec params) {
+ try {
+ NettleLib.parametersKnown(params);
+ return true;
+ } catch (InvalidAlgorithmParameterException ignored) {
+ return false;
+ }
+ }
@Override
- native KeyPair generate(int keysize, SecureRandom random);
+ KeyPair generate(int keysize, SecureRandom random) {
+ EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, "secg/secp" + keysize + "r1");
+ return generate(keysize, random, curve.toSpec());
+ }
+
+ native KeyPair generate(int keysize, SecureRandom random, AlgorithmParameterSpec spec);
@Override
KeyPair generate(AlgorithmParameterSpec params, SecureRandom random) {
- if (params instanceof ECGenParameterSpec) {
- String curveName = ((ECGenParameterSpec) params).getName();
- if (curveName.contains("secp")) {
- curveName = "secg/" + curveName;
- }
- EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName);
- ECParameterSpec spec = curve.toSpec();
- return generate(params, random, spec);
+ ECGenParameterSpec named;
+ try {
+ named = NettleLib.parametersKnown(params);
+ } catch (InvalidAlgorithmParameterException ignored) {
+ return null;
+ }
+ String curveName = named.getName();
+ if (curveName.startsWith("secp")) {
+ curveName = "secg/" + curveName;
}
- return null;
+ EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName);
+ ECParameterSpec spec = curve.toSpec();
+ return generate(params, random, spec);
}
native KeyPair generate(AlgorithmParameterSpec params, SecureRandom random, AlgorithmParameterSpec spec);
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/SigInfo.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/SigInfo.java
new file mode 100644
index 0000000..3cb7bad
--- /dev/null
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/SigInfo.java
@@ -0,0 +1,80 @@
+package cz.crcs.ectester.standalone.libs.jni;
+
+/**
+ * @author Jan Jancar johny@neuromancer.sk
+ */
+public class SigInfo {
+
+ private final int signo;
+ private final int code;
+ private final int errno;
+ private final int pid;
+ private final int uid;
+ private final long addr;
+ private final int status;
+ private final long band;
+ private final long sigval;
+
+ public SigInfo(int signo, int code, int errno, int pid, int uid, long addr, int status, long band, long sigval) {
+ this.signo = signo;
+ this.code = code;
+ this.errno = errno;
+ this.pid = pid;
+ this.uid = uid;
+ this.addr = addr;
+ this.status = status;
+ this.band = band;
+ this.sigval = sigval;
+ }
+
+ public int getSigno() {
+ return signo;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public int getErrno() {
+ return errno;
+ }
+
+ public int getPid() {
+ return pid;
+ }
+
+ public int getUid() {
+ return uid;
+ }
+
+ public long getAddr() {
+ return addr;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+ public long getBand() {
+ return band;
+ }
+
+ public long getSigval() {
+ return sigval;
+ }
+
+ @Override
+ public String toString() {
+ return "SigInfo{" +
+ "signo=" + signo +
+ ", code=" + code +
+ ", errno=" + errno +
+ ", pid=" + pid +
+ ", uid=" + uid +
+ ", addr=" + addr +
+ ", status=" + status +
+ ", band=" + band +
+ ", sigval=" + sigval +
+ '}';
+ }
+}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/SignalException.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/SignalException.java
new file mode 100644
index 0000000..726286e
--- /dev/null
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/SignalException.java
@@ -0,0 +1,18 @@
+package cz.crcs.ectester.standalone.libs.jni;
+
+/**
+ * @author Jan Jancar johny@neuromancer.sk
+ */
+public class SignalException extends RuntimeException {
+
+ private final SigInfo sigInfo;
+
+ public SignalException(SigInfo sigInfo) {
+ super("Signal caught.");
+ this.sigInfo = sigInfo;
+ }
+
+ public SigInfo getSigInfo() {
+ return sigInfo;
+ }
+}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/TimeoutException.java b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/TimeoutException.java
new file mode 100644
index 0000000..c4084b9
--- /dev/null
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/TimeoutException.java
@@ -0,0 +1,11 @@
+package cz.crcs.ectester.standalone.libs.jni;
+
+/**
+ * @author Jan Jancar johny@neuromancer.sk
+ */
+public class TimeoutException extends RuntimeException {
+
+ public TimeoutException(String message) {
+ super(message);
+ }
+}
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 ba345e7..c53adb2 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
@@ -48,7 +48,7 @@ public class TextTestWriter extends BaseTextTestWriter {
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().name()).append(System.lineSeparator());
+ sb.append("═══ ").append(Colors.underline("Library:")).append(" ").append(standaloneSuite.getLibrary().fullName()).append(System.lineSeparator());
return sb.toString();
}
return "";
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/output/XMLTestWriter.java b/standalone/src/main/java/cz/crcs/ectester/standalone/output/XMLTestWriter.java
index 60751f5..2341fc7 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/output/XMLTestWriter.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/output/XMLTestWriter.java
@@ -147,7 +147,7 @@ public class XMLTestWriter extends BaseXMLTestWriter {
result.setAttribute("ectester", ECTesterStandalone.VERSION);
Element name = doc.createElement("name");
- name.setTextContent(standaloneSuite.getLibrary().name());
+ name.setTextContent(standaloneSuite.getLibrary().fullName());
result.appendChild(name);
return result;
}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/output/YAMLTestWriter.java b/standalone/src/main/java/cz/crcs/ectester/standalone/output/YAMLTestWriter.java
index 664fa18..66c5e38 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/output/YAMLTestWriter.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/output/YAMLTestWriter.java
@@ -116,7 +116,7 @@ public class YAMLTestWriter extends BaseYAMLTestWriter {
Map<String, Object> result = new LinkedHashMap<>();
result.put("type", "library");
result.put("ectester", ECTesterStandalone.VERSION);
- result.put("name", standaloneSuite.getLibrary().name());
+ result.put("name", standaloneSuite.getLibrary().fullName());
return result;
}
return null;
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 32f82cb..8c49224 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
@@ -4,6 +4,9 @@ import cz.crcs.ectester.common.test.Result;
import cz.crcs.ectester.common.test.SimpleTest;
import cz.crcs.ectester.common.test.TestCallback;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
+
/**
* @author Jan Jancar johny@neuromancer.sk
*/
@@ -38,6 +41,15 @@ public class KeyGeneratorTest extends SimpleTest<KeyGeneratorTestable> {
@Override
public String getDescription() {
- return "KeyPairGenerator " + testable.getKpg().getAlgorithm();
+ String params = "";
+ if (testable.getKeysize() != 0) {
+ params = String.format("(default %d-bit curve)", testable.getKeysize());
+ } else if (testable.getSpec() instanceof ECGenParameterSpec) {
+ String name = ((ECGenParameterSpec)testable.getSpec()).getName();
+ params = String.format("(%s)", name);
+ } else if (testable.getSpec() instanceof ECParameterSpec) {
+ params = "(custom curve)";
+ }
+ return "KeyPairGenerator " + testable.getKpg().getAlgorithm() + " on " + params;
}
}
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 296ec3c..bc44eb8 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,8 @@ package cz.crcs.ectester.standalone.test.base;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
/**
@@ -12,7 +14,7 @@ public class KeyGeneratorTestable extends StandaloneTestable<KeyGeneratorTestabl
private KeyPair kp;
private final KeyPairGenerator kpg;
private int keysize = 0;
- private ECParameterSpec spec = null;
+ private AlgorithmParameterSpec spec = null;
public KeyGeneratorTestable(KeyPairGenerator kpg) {
this.kpg = kpg;
@@ -28,6 +30,19 @@ public class KeyGeneratorTestable extends StandaloneTestable<KeyGeneratorTestabl
this.spec = spec;
}
+ public KeyGeneratorTestable(KeyPairGenerator kpg, ECGenParameterSpec spec) {
+ this.kpg = kpg;
+ this.spec = spec;
+ }
+
+ public int getKeysize() {
+ return keysize;
+ }
+
+ public AlgorithmParameterSpec getSpec() {
+ return spec;
+ }
+
public KeyPairGenerator getKpg() {
return kpg;
}
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 52b0fbf..bb9a509 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
@@ -76,10 +76,10 @@ public class StandaloneCofactorSuite extends StandaloneTestSuite {
ECParameterSpec spec = curve.toSpec();
KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec);
- Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
+ Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
runTest(generate);
KeyPair kp = kgt.getKeyPair();
- if(kp == null) {
+ 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, "Cofactor test of " + curve.getId() + ".", generateFail));
continue;
@@ -101,7 +101,7 @@ public class StandaloneCofactorSuite extends StandaloneTestSuite {
allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with public points on non-generator subgroup.", specificKaTests.toArray(new Test[0])));
}
}
- if(allKaTests.isEmpty()) {
+ 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]));
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 c59d864..839bb40 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
@@ -85,10 +85,10 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite {
//Generate KeyPair
KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec);
- Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
+ Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
runTest(generate);
KeyPair kp = kgt.getKeyPair();
- if(kp == null) {
+ 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;
@@ -104,14 +104,14 @@ 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, ecpriv, ecpub);
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));
}
allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with various public points.", specificKaTests.toArray(new Test[0])));
}
}
- if(allKaTests.isEmpty()) {
+ 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]));
@@ -153,7 +153,7 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite {
}
private void testGroup(List<EC_Curve> curves, KeyPairGenerator kpg, String testName, Result.ExpectedValue dhValue) throws Exception {
- for (EC_Curve curve : curves) {
+ for (EC_Curve curve : curves) {
String description;
if (testName == null) {
description = curve.getDesc() + " test of " + curve.getId() + ".";
@@ -162,19 +162,19 @@ 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();
+ 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<Test> kaTests = new LinkedList<>();
@@ -185,7 +185,7 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite {
kaTests.add(KeyAgreementTest.expectError(testable, dhValue));
}
}
- if(kaTests.isEmpty()) {
+ if (kaTests.isEmpty()) {
kaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified KeyAgreement types is supported by the library."));
}
@@ -198,7 +198,7 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite {
sigTests.add(SignatureTest.expectError(testable, dhValue));
}
}
- if(sigTests.isEmpty()) {
+ if (sigTests.isEmpty()) {
sigTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified Signature types is supported by the library."));
}
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 9ab8a39..d822a83 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
@@ -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.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.util.*;
@@ -77,22 +78,34 @@ public class StandaloneDegenerateSuite extends StandaloneTestSuite {
KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec);
Test generateSuccess;
- Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
+ Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
runTest(generate);
KeyPair kp = kgt.getKeyPair();
- if(kp != null) {
+ if (kp != null) {
generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate);
- } else { //If KeyPair generation fails, try generating it on a 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.", generateOnDefaultCurve);
+ } 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 {
- 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, "Degenerate curve test of " + curve.getId() + ".", generateFail));
- continue;
+ // 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();
@@ -111,7 +124,7 @@ public class StandaloneDegenerateSuite extends StandaloneTestSuite {
allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with degenerate public points..", specificKaTests.toArray(new Test[0])));
}
}
- if(allKaTests.isEmpty()) {
+ 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]));
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 1900bea..7c46f02 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
@@ -264,10 +264,10 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite {
//generate KeyPair
KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec);
- Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
+ Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
runTest(generate);
KeyPair kp = kgt.getKeyPair();
- if(kp == null) {
+ 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));
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 ace8945..48dfc37 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
@@ -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.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.util.*;
@@ -76,22 +77,34 @@ public class StandaloneInvalidSuite extends StandaloneTestSuite {
KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec);
Test generateSuccess;
- Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
+ Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
runTest(generate);
KeyPair kp = kgt.getKeyPair();
- if(kp != null) {
+ if (kp != null) {
generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate);
- } else { //If KeyPair generation fails, try generating it on a 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.", generateOnDefaultCurve);
+ } 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 {
- 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, "Invalid curve test of " + curve.getId() + ".", generateFail));
- continue;
+ // 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();
@@ -110,7 +123,7 @@ public class StandaloneInvalidSuite extends StandaloneTestSuite {
allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with invalid public points.", specificKaTests.toArray(new Test[0])));
}
}
- if(allKaTests.isEmpty()) {
+ 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]));
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 e3b6d2e..a1b4d75 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
@@ -73,7 +73,7 @@ public class StandalonePerformanceSuite extends StandaloneTestSuite {
KeyGeneratorTestable kgtOther = null;
ECParameterSpec spec = null;
List<Test> kpgTests = new LinkedList<>();
- for(KeyPairGeneratorIdent kpgIdent : kpgIdents) {
+ for (KeyPairGeneratorIdent kpgIdent : kpgIdents) {
KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider());
if (cli.hasOption("test.bits")) {
int bits = Integer.parseInt(cli.getOptionValue("test.bits"));
@@ -111,7 +111,7 @@ public class StandalonePerformanceSuite extends StandaloneTestSuite {
kaTests.add(PerformanceTest.repeat(testable, cfg.selected, kaIdent.getName(), count));
}
}
- if(kaTests.isEmpty()) {
+ if (kaTests.isEmpty()) {
kaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified KeyAgreement types is supported by the library."));
}
doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyAgreement performance tests", kaTests.toArray(new Test[0])));
@@ -121,17 +121,17 @@ public class StandalonePerformanceSuite extends StandaloneTestSuite {
for (SignatureIdent sigIdent : cfg.selected.getSigs()) {
if (sigAlgo == null || sigIdent.containsAny(sigTypes)) {
Signature sig = sigIdent.getInstance(cfg.selected.getProvider());
- sigTests.add(PerformanceTest.repeat(new SignatureTestable(sig, kgtOne, null), cfg.selected, sigIdent.getName(),count));
- if(kgtOne.getKeyPair() != null) {
+ sigTests.add(PerformanceTest.repeat(new SignatureTestable(sig, kgtOne, null), cfg.selected, sigIdent.getName(), count));
+ if (kgtOne.getKeyPair() != null) {
ECPrivateKey signKey = (ECPrivateKey) kgtOne.getKeyPair().getPrivate();
sigTestsNoVerification.add(PerformanceTest.repeat(new SignatureTestable(sig, signKey, null, null), cfg.selected, sigIdent.getName(), count));
}
}
}
- if(sigTestsNoVerification.isEmpty() & !sigTests.isEmpty()) {
+ if (sigTestsNoVerification.isEmpty() & !sigTests.isEmpty()) {
sigTestsNoVerification.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Signature tests with no verification require a successfully generated private key."));
}
- if(sigTests.isEmpty()) {
+ if (sigTests.isEmpty()) {
sigTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified Signature types is supported by the library."));
sigTestsNoVerification.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified Signature types is supported by the library."));
}
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 94e810e..8e5e452 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
@@ -73,6 +73,10 @@ public class StandaloneSignatureSuite extends StandaloneTestSuite {
}
private void ecdsaTest(EC_SigResult sig, SignatureIdent sigIdent, Result.ExpectedValue expected, byte[] defaultData) throws NoSuchAlgorithmException {
+ if (!sig.getSig().equals(sigIdent.getHashAlgo()) && !sig.getSig().equals("*")) {
+ doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "ECDSA test of " + sig.getId() + " not applicable."));
+ return;
+ }
ECPublicKey ecpub = ECUtil.toPublicKey(EC_Store.getInstance().getObject(EC_Key.Public.class, sig.getVerifyKey()));
byte[] data = sig.getSigData();
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 1e1889c..111d354 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
@@ -31,7 +31,7 @@ public class StandaloneTestVectorSuite extends StandaloneTestSuite {
protected void runTests() throws Exception {
Map<String, EC_KAResult> results = EC_Store.getInstance().getObjects(EC_KAResult.class, "test");
for (EC_KAResult result : results.values()) {
- if(!"DH_PLAIN".equals(result.getKA())) {
+ if (!"DH_PLAIN".equals(result.getKA())) {
continue;
}
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 f182952..37adbb2 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
@@ -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.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.util.*;
@@ -76,22 +77,34 @@ public class StandaloneTwistSuite extends StandaloneTestSuite {
KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec);
Test generateSuccess;
- Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
+ Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
runTest(generate);
KeyPair kp = kgt.getKeyPair();
- if(kp != null) {
+ if (kp != null) {
generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate);
- } else { //If KeyPair generation fails, try generating it on a 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.", generateOnDefaultCurve);
+ } 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 {
- 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, "Twist test of " + curve.getId() + ".", generateFail));
- continue;
+ // 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();
@@ -110,7 +123,7 @@ public class StandaloneTwistSuite extends StandaloneTestSuite {
allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with public points on twist.", specificKaTests.toArray(new Test[0])));
}
}
- if(allKaTests.isEmpty()) {
+ 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]));
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 a457a33..1aae9d5 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
@@ -103,7 +103,7 @@ public class StandaloneWrongSuite extends StandaloneTestSuite {
/* Just do the default run on the wrong curves.
* These should generally fail, the curves aren't curves.
*/
- if(!skip) {
+ if (!skip) {
Map<String, EC_Curve> wrongCurves = EC_Store.getInstance().getObjects(EC_Curve.class, "wrong");
for (Map.Entry<String, EC_Curve> e : wrongCurves.entrySet()) {
@@ -151,11 +151,11 @@ public class StandaloneWrongSuite extends StandaloneTestSuite {
short bits = curve.getBits();
final byte[] originalp = curve.getParam(EC_Consts.PARAMETER_FP)[0];
- curve.setParam(EC_Consts.PARAMETER_FP, new byte[][]{ ByteUtil.hexToBytes("0")});
- Test prime0 = ecdhTest(toCustomSpec(curve),"ECDH with p = 0.");
+ curve.setParam(EC_Consts.PARAMETER_FP, new byte[][]{ByteUtil.hexToBytes("0")});
+ Test prime0 = ecdhTest(toCustomSpec(curve), "ECDH with p = 0.");
- curve.setParam(EC_Consts.PARAMETER_FP, new byte[][]{ ByteUtil.hexToBytes("1")});
- Test prime1 = ecdhTest(toCustomSpec(curve),"ECDH with p = 1.");
+ curve.setParam(EC_Consts.PARAMETER_FP, new byte[][]{ByteUtil.hexToBytes("1")});
+ Test prime1 = ecdhTest(toCustomSpec(curve), "ECDH with p = 1.");
short keyHalf = (short) (bits / 2);
BigInteger prime = new BigInteger(keyHalf, 50, r);
@@ -173,23 +173,23 @@ public class StandaloneWrongSuite extends StandaloneTestSuite {
Test composite = ecdhTest(toCustomSpec(curve), "ECDH with p = q * s.");
- Test wrongPrime = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with corrupted prime parameter.", prime0 , prime1, primePower, composite );
+ Test wrongPrime = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with corrupted prime parameter.", prime0, prime1, primePower, composite);
- curve.setParam(EC_Consts.PARAMETER_FP, new byte[][] {originalp});
+ curve.setParam(EC_Consts.PARAMETER_FP, new byte[][]{originalp});
final byte[][] originalG = curve.getParam(EC_Consts.PARAMETER_G);
byte[] Gx = new BigInteger(curve.getBits(), r).toByteArray();
byte[] Gy = new BigInteger(curve.getBits(), r).toByteArray();
- curve.setParam(EC_Consts.PARAMETER_G, new byte[][] {Gx, Gy});
+ curve.setParam(EC_Consts.PARAMETER_G, new byte[][]{Gx, Gy});
Test fullRandomG = ecdhTest(toCustomSpec(curve), "ECDH with G = random data.");
final BigInteger originalBigp = new BigInteger(1, originalp);
byte[] smallerGx = new BigInteger(curve.getBits(), r).mod(originalBigp).toByteArray();
byte[] smallerGy = new BigInteger(curve.getBits(), r).mod(originalBigp).toByteArray();
- curve.setParam(EC_Consts.PARAMETER_G, new byte[][] {smallerGx, smallerGy});
+ curve.setParam(EC_Consts.PARAMETER_G, new byte[][]{smallerGx, smallerGy});
Test randomG = ecdhTest(toCustomSpec(curve), "ECDH with G = random data mod p.");
- curve.setParam(EC_Consts.PARAMETER_G, new byte[][] {ByteUtil.hexToBytes("0"), ByteUtil.hexToBytes("0")});
+ curve.setParam(EC_Consts.PARAMETER_G, new byte[][]{ByteUtil.hexToBytes("0"), ByteUtil.hexToBytes("0")});
Test zeroG = ecdhTest(toCustomSpec(curve), "ECDH with G = infinity.");
Test wrongG = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with corrupted G parameter.", fullRandomG, randomG, zeroG);
@@ -199,7 +199,7 @@ public class StandaloneWrongSuite extends StandaloneTestSuite {
final BigInteger originalBigR = new BigInteger(1, originalR);
List<Test> allRTests = new LinkedList<>();
- if(!skip) {
+ if (!skip) {
byte[] RZero = new byte[]{(byte) 0};
curve.setParam(EC_Consts.PARAMETER_R, new byte[][]{RZero});
allRTests.add(ecdhTest(toCustomSpec(curve), "ECDH with R = 0."));
@@ -215,7 +215,7 @@ public class StandaloneWrongSuite extends StandaloneTestSuite {
prevPrimeR = BigInteger.probablePrime(originalBigR.bitLength() - 1, r);
} while (prevPrimeR.compareTo(originalBigR) >= 0);
byte[] prevRBytes = ECUtil.toByteArray(prevPrimeR, bits);
- curve.setParam(EC_Consts.PARAMETER_R, new byte[][] {prevRBytes});
+ curve.setParam(EC_Consts.PARAMETER_R, new byte[][]{prevRBytes});
allRTests.add(ecdhTest(toCustomSpec(curve), "ECDH with R = some prime (but [r]G != infinity) smaller than original R."));
BigInteger nextPrimeR = originalBigR.nextProbablePrime();
@@ -225,15 +225,15 @@ public class StandaloneWrongSuite extends StandaloneTestSuite {
byte[] nonprimeRBytes = nextRBytes.clone();
nonprimeRBytes[nonprimeRBytes.length - 1] ^= 1;
- curve.setParam(EC_Consts.PARAMETER_R, new byte[][] {nonprimeRBytes} );
+ curve.setParam(EC_Consts.PARAMETER_R, new byte[][]{nonprimeRBytes});
allRTests.add(ecdhTest(toCustomSpec(curve), "ECDH with R = some composite (but [r]G != infinity)."));
Test wrongR = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with corrupted R parameter.", allRTests.toArray(new Test[0]));
- curve.setParam(EC_Consts.PARAMETER_R, new byte[][] {originalR});
+ curve.setParam(EC_Consts.PARAMETER_R, new byte[][]{originalR});
byte[] kRaw = new byte[]{(byte) 0xff};
- curve.setParam(EC_Consts.PARAMETER_K, new byte[][] {kRaw});
+ curve.setParam(EC_Consts.PARAMETER_K, new byte[][]{kRaw});
Test bigK = ecdhTest(toCustomSpec(curve), "ECDH with big K.");
byte[] kZero = new byte[]{(byte) 0};
@@ -241,7 +241,7 @@ public class StandaloneWrongSuite extends StandaloneTestSuite {
Test zeroK = ecdhTest(toCustomSpec(curve), "ECDH with K = 0.");
Test wrongK = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with corrupted K parameter.", bigK, zeroK);
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests of " + bits + "b " + "FP", wrongPrime, wrongG, wrongR , wrongK));
+ doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests of " + bits + "b " + "FP", wrongPrime, wrongG, wrongR, wrongK));
}
@@ -284,10 +284,10 @@ public class StandaloneWrongSuite extends StandaloneTestSuite {
private Test ecdhTest(ECParameterSpec spec, String desc) throws NoSuchAlgorithmException {
//generate KeyPair
KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec);
- Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.FAILURE);
+ Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.FAILURE);
runTest(generate);
KeyPair kp = kgt.getKeyPair();
- if(kp == null) {
+ if (kp == null) {
return CompoundTest.all(Result.ExpectedValue.SUCCESS, desc, generate);
}
ECPublicKey pub = (ECPublicKey) kp.getPublic();
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 1fa16c0..6282574 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
@@ -4,7 +4,7 @@
CC?=gcc
CXX?=g++
-LFLAGS+=-fPIC -shared
+LFLAGS+=-fPIC -shared -L "$(JNI_LIBDIR)" -L "$(JNI_LIBDIR)/server" #-ljsig -ljvm
CFLAGS+=-fPIC -I"$(JNI_INCLUDEDIR)" -I"$(JNI_PLATFORMINCLUDEDIR)" -I. -Wno-deprecated-declarations
CXXFLAGS+=-fPIC -I"$(JNI_INCLUDEDIR)" -I"$(JNI_PLATFORMINCLUDEDIR)" -I. -Wno-deprecated-declarations
@@ -36,12 +36,17 @@ endif
ifneq ($(JAVA_HOME),)
JNI_INCLUDEDIR ?= $(JAVA_HOME)/include
+ JNI_LIBDIR ?= $(JAVA_HOME)/lib
endif
ifeq ($(JNI_INCLUDEDIR),)
$(error "Could not determine JNI include dir. Try specifying either JAVA_HOME or JNI_INCLUDEDIR.")
endif
+ifeq ($(JNI_LIBDIR),)
+ $(error "Could not determine JNI lib dir. Try specifying either JAVA_HOME or JNI_LIBDIR.")
+endif
+
TARGETTRIPLET := $(shell $(CC) -dumpmachine)
ifeq ($(JNI_PLATFORM),)
@@ -68,6 +73,12 @@ c_utils.o: c_utils.c
lib_timing.so: c_timing.c
$(CC) -o $@ -shared $(CFLAGS) -Wl,-soname,lib_timing.so $<
+lib_csignals.so: c_signals.c
+ $(CC) -o $@ -shared $(CFLAGS) -pthread -lpthread -Wl,-soname,lib_csignals.so $<
+
+lib_cppsignals.so: cpp_signals.cpp
+ $(CC) -o $@ -shared $(CFLAGS) -pthread -lpthread -Wl,-soname,lib_cppsignals.so $<
+
cpp_utils.o: cpp_utils.cpp
$(CXX) $(CXXFLAGS) -c $<
@@ -75,8 +86,8 @@ cpp_utils.o: cpp_utils.cpp
# OpenSSL shim
openssl: openssl_provider.so
-openssl_provider.so: openssl.o c_utils.o | lib_timing.so
- $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs openssl) -l:lib_timing.so
+openssl_provider.so: openssl.o c_utils.o | lib_timing.so lib_csignals.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
$(CC) $(shell pkg-config --cflags openssl) $(CFLAGS) -c $<
@@ -88,8 +99,8 @@ 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_boringssl.so
- $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_boringssl.so -l:lib_timing.so
+boringssl_provider.so: boringssl.o c_utils.o | lib_timing.so lib_csignals.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
$(CC) -I$(PROJECT_ROOT_PATH)/ext/boringssl/include/ $(CFLAGS) -c $<
@@ -98,8 +109,8 @@ boringssl.o: boringssl.c
# libgcrypt shim
gcrypt: gcrypt_provider.so
-gcrypt_provider.so: gcrypt.o c_utils.o | lib_timing.so
- $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell libgcrypt-config --libs) -l:lib_timing.so
+gcrypt_provider.so: gcrypt.o c_utils.o | lib_timing.so lib_csignals.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
$(CC) $(shell libgcrypt-config --cflags) $(CFLAGS) -c $<
@@ -108,8 +119,8 @@ gcrypt.o: gcrypt.c
# Libtomcrypt shim
tomcrypt: tomcrypt_provider.so
-tomcrypt_provider.so: tomcrypt.o c_utils.o | lib_timing.so
- $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. -ltommath $(shell pkg-config --libs libtomcrypt) -l:lib_timing.so
+tomcrypt_provider.so: tomcrypt.o c_utils.o | lib_timing.so lib_csignals.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
$(CC) -DLTM_DESC $(shell pkg-config --cflags libtomcrypt) $(CFLAGS) -c $<
@@ -118,8 +129,8 @@ tomcrypt.o: tomcrypt.c
# Botan-2 shim
botan: botan_provider.so
-botan_provider.so: botan.o cpp_utils.o | lib_timing.so
- $(CXX) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs botan-2) -l:lib_timing.so
+botan_provider.so: botan.o cpp_utils.o | lib_timing.so lib_cppsignals.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
$(CXX) $(shell pkg-config --cflags botan-2) $(CXXFLAGS) -c $<
@@ -132,8 +143,8 @@ 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
- $(CXX) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs $(CRYPTOPP_NAME)) -l:lib_timing.so
+cryptopp_provider.so: cryptopp.o cpp_utils.o | lib_timing.so lib_cppsignals.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
$(CXX) $(shell pkg-config --cflags $(CRYPTOPP_NAME)) $(CXXFLAGS) -c $<
@@ -145,8 +156,8 @@ 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_mbedtls.so
- $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_mbedtls.so -l:lib_timing.so
+mbedtls_provider.so: mbedtls.o c_utils.o | lib_timing.so lib_csignals.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
$(CC) -I$(PROJECT_ROOT_PATH)/ext/mbedtls/build/include/ $(CFLAGS) -c $<
@@ -158,8 +169,8 @@ 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_ippcp.so
- $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_ippcp.so -l:lib_timing.so
+ippcp_provider.so: ippcp.o c_utils.o | lib_timing.so lib_csignals.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
$(CC) -I$(PROJECT_ROOT_PATH)/ext/ipp-crypto/build/.build/RELEASE/include/ $(CFLAGS) -c $<
@@ -168,8 +179,8 @@ ippcp.o: ippcp.c
# Nettle shim
nettle: nettle_provider.so
-nettle_provider.so: nettle.o c_utils.o | lib_timing.so
- $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs nettle) -l:lib_timing.so $(shell pkg-config --libs hogweed) -lgmp
+nettle_provider.so: nettle.o c_utils.o | lib_timing.so lib_csignals.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
$(CC) $(shell pkg-config --cflags nettle) $(shell pkg-config --libs hogweed) -lgmp $(CFLAGS) -c $<
@@ -181,8 +192,8 @@ 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_libressl.so
- $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_libressl.so -l:lib_timing.so
+libressl_provider.so: libressl.o c_utils.o | lib_timing.so lib_csignals.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
$(CC) -I$(PROJECT_ROOT_PATH)/ext/libressl/build/include/ $(CFLAGS) -c $<
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/boringssl.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/boringssl.c
index 4cc95a5..919cc79 100644
--- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/boringssl.c
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/boringssl.c
@@ -1,5 +1,6 @@
#include "c_utils.h"
#include "c_timing.h"
+#include "c_signals.h"
#include "native.h"
#include <strings.h>
@@ -288,9 +289,12 @@ static jobject generate_from_curve(JNIEnv *env, const EC_GROUP *curve) {
EC_KEY *key = EC_KEY_new();
EC_KEY_set_group(key, curve);
- native_timing_start();
- int err = EC_KEY_generate_key(key);
- native_timing_stop();
+ int err = 0;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ err = EC_KEY_generate_key(key);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
if (!err) {
throw_new(env, "java/security/GeneralSecurityException", "Error generating key, EC_KEY_generate_key.");
@@ -393,11 +397,20 @@ EC_KEY *barray_to_pubkey(JNIEnv *env, const EC_GROUP *curve, jbyteArray pub) {
jsize pub_len = (*env)->GetArrayLength(env, pub);
jbyte *pub_data = (*env)->GetByteArrayElements(env, pub, NULL);
EC_POINT *pub_point = EC_POINT_new(curve);
- EC_POINT_oct2point(curve, pub_point, (unsigned char *) pub_data, pub_len, NULL);
- (*env)->ReleaseByteArrayElements(env, pub, pub_data, JNI_ABORT);
- EC_KEY_set_public_key(result, pub_point);
- EC_POINT_free(pub_point);
- return result;
+ int retval = EC_POINT_oct2point(curve, pub_point, (unsigned char *) pub_data, pub_len, NULL);
+ (*env)->ReleaseByteArrayElements(env, pub, pub_data, JNI_ABORT);
+ if (!retval) {
+ EC_POINT_free(pub_point);
+ throw_new(env, "java/security/GeneralSecurityException", "Error loading key, EC_POINT_oct2point.");
+ return NULL;
+ }
+ retval = EC_KEY_set_public_key(result, pub_point);
+ EC_POINT_free(pub_point);
+ if (!retval) {
+ throw_new(env, "java/security/GeneralSecurityException", "Error loading key, EC_KEY_set_public_key.");
+ return NULL;
+ }
+ return result;
}
EC_KEY *barray_to_privkey(JNIEnv *env, const EC_GROUP *curve, jbyteArray priv) {
@@ -407,32 +420,46 @@ EC_KEY *barray_to_privkey(JNIEnv *env, const EC_GROUP *curve, jbyteArray priv)
jbyte *priv_data = (*env)->GetByteArrayElements(env, priv, NULL);
BIGNUM *s = BN_bin2bn((unsigned char *) priv_data, priv_len, NULL);
(*env)->ReleaseByteArrayElements(env, priv, priv_data, JNI_ABORT);
- EC_KEY_set_private_key(result, s);
+ int retval = EC_KEY_set_private_key(result, s);
BN_free(s);
+ if (!retval) {
+ throw_new(env, "java/security/GeneralSecurityException", "Error loading key, EC_KEY_set_private_key.");
+ return NULL;
+ }
return result;
}
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Boringssl_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params) {
+ jbyteArray result = NULL;
EC_GROUP *curve = create_curve(env, params);
if (!curve) {
throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found.");
- return NULL;
+ goto free_curve;
}
EC_KEY *pub = barray_to_pubkey(env, curve, pubkey);
+ if (!pub) {
+ goto free_pub;
+ }
EC_KEY *priv = barray_to_privkey(env, curve, privkey);
+ if (!priv) {
+ goto free_priv;
+ }
int field_size = EC_GROUP_get_degree(curve);
size_t secret_len = (field_size + 7)/8;
//TODO: Do more KeyAgreements here, but will have to do the hash-fun manually,
// probably using the ECDH_KDF_X9_62 by wrapping it and dynamically choosing the EVP_MD. from the type string.
- jbyteArray result = (*env)->NewByteArray(env, secret_len);
+ result = (*env)->NewByteArray(env, secret_len);
jbyte *result_data = (*env)->GetByteArrayElements(env, result, NULL);
- native_timing_start();
- int err = ECDH_compute_key(result_data, secret_len, EC_KEY_get0_public_key(pub), priv, NULL);
- native_timing_stop();
+ int err = 0;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ err = ECDH_compute_key(result_data, secret_len, EC_KEY_get0_public_key(pub), priv, NULL);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
if (err <= 0) {
throw_new(env, "java/security/GeneralSecurityException", "Error computing ECDH, ECDH_compute_key.");
@@ -442,8 +469,11 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
}
(*env)->ReleaseByteArrayElements(env, result, result_data, 0);
- EC_KEY_free(pub);
+free_priv:
EC_KEY_free(priv);
+free_pub:
+ EC_KEY_free(pub);
+free_curve:
EC_GROUP_free(curve);
return result;
}
@@ -454,38 +484,46 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgr
}
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Boringssl_sign(JNIEnv *env, jobject self, jbyteArray data, jbyteArray privkey, jobject params) {
+ jbyteArray result = NULL;
EC_GROUP *curve = create_curve(env, params);
if (!curve) {
throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found.");
- return NULL;
+ goto free_curve;
}
EC_KEY *priv = barray_to_privkey(env, curve, privkey);
+ if (!priv) {
+ goto free_priv;
+ }
jsize data_size = (*env)->GetArrayLength(env, data);
jbyte *data_data = (*env)->GetByteArrayElements(env, data, NULL);
// TODO: Do more Signatures here, maybe use the EVP interface to get to the hashes easier and not hash manually?
- native_timing_start();
- ECDSA_SIG *signature = ECDSA_do_sign((unsigned char *) data_data, data_size, priv);
- native_timing_stop();
+ ECDSA_SIG *signature = NULL;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ signature = ECDSA_do_sign((unsigned char *) data_data, data_size, priv);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
(*env)->ReleaseByteArrayElements(env, data, data_data, JNI_ABORT);
if (!signature) {
throw_new(env, "java/security/GeneralSecurityException", "Error signing, ECDSA_do_sign.");
- EC_KEY_free(priv); EC_GROUP_free(curve);
- return NULL;
+ goto free_priv;
}
jsize sig_len = i2d_ECDSA_SIG(signature, NULL);
- jbyteArray result = (*env)->NewByteArray(env, sig_len);
+ result = (*env)->NewByteArray(env, sig_len);
jbyte *result_data = (*env)->GetByteArrayElements(env, result, NULL);
jbyte *result_data_ptr = result_data;
i2d_ECDSA_SIG(signature, (unsigned char **)&result_data_ptr);
(*env)->ReleaseByteArrayElements(env, result, result_data, 0);
ECDSA_SIG_free(signature);
+free_priv:
EC_KEY_free(priv);
+free_curve:
EC_GROUP_free(curve);
return result;
}
@@ -498,6 +536,10 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
}
EC_KEY *pub = barray_to_pubkey(env, curve, pubkey);
+ if (!pub) {
+ EC_GROUP_free(curve);
+ return JNI_FALSE;
+ }
jsize sig_len = (*env)->GetArrayLength(env, signature);
jbyte *sig_data = (*env)->GetByteArrayElements(env, signature, NULL);
@@ -508,9 +550,12 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
jsize data_size = (*env)->GetArrayLength(env, data);
jbyte *data_data = (*env)->GetByteArrayElements(env, data, NULL);
- native_timing_start();
- int result = ECDSA_do_verify((unsigned char *) data_data, data_size, sig_obj, pub);
- native_timing_stop();
+ int result = 0;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ result = ECDSA_do_verify((unsigned char *) data_data, data_size, sig_obj, pub);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
if (result < 0) {
throw_new(env, "java/security/GeneralSecurityException", "Error verifying, ECDSA_do_verify.");
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_signals.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_signals.c
new file mode 100644
index 0000000..b452787
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_signals.c
@@ -0,0 +1,117 @@
+#include "c_utils.h"
+#include "c_signals.h"
+
+#if __linux || __posix
+
+#include <signal.h>
+#include <setjmp.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include <unistd.h>
+
+static siginfo_t last_siginfo;
+static bool initialized = false;
+static bool caught = false;
+static bool timedout = false;
+static sigjmp_buf buf;
+static sigjmp_buf *target = NULL;
+
+struct timer_arg {
+ unsigned int timeout;
+ pthread_t main_thread;
+};
+static struct timer_arg ta;
+static pthread_t timer_thread;
+
+void handler(int signo, siginfo_t *info, void *context) {
+ //printf("Signal, %i\n", signo);
+ last_siginfo = *info;
+ caught = true;
+ siglongjmp(*target, 1);
+}
+
+void alarm_handler(int signo) {
+ //printf("Alarm\n");
+ timedout = true;
+ siglongjmp(*target, 1);
+}
+
+
+sigjmp_buf *get_jmpbuf_c() {
+ return &buf;
+}
+
+static struct sigaction old_segv;
+static struct sigaction old_abrt;
+static struct sigaction old_alrm;
+
+void *timer(void *arg) {
+ sleep(ta.timeout);
+ pthread_kill(ta.main_thread, SIGALRM);
+ return NULL;
+}
+
+void init_signals_c(sigjmp_buf *env, unsigned int timeout) {
+ //printf("Initializing signals!\n");
+ struct sigaction action;
+ action.sa_sigaction = handler;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = SA_SIGINFO;
+
+ sigaction(SIGSEGV, &action, &old_segv);
+ sigaction(SIGABRT, &action, &old_abrt);
+
+ struct sigaction alarm_action;
+ alarm_action.sa_handler = alarm_handler;
+ sigemptyset(&alarm_action.sa_mask);
+ alarm_action.sa_flags = 0;
+ sigaction(SIGALRM, &alarm_action, &old_alrm);
+
+ target = env;
+ initialized = true;
+ caught = false;
+ timedout = false;
+
+ ta.timeout = timeout;
+ ta.main_thread = pthread_self();
+
+ pthread_create(&timer_thread, NULL, timer, (void *)&ta);
+}
+
+
+void deinit_signals_c() {
+ //printf("Deinitializing signals!\n");
+ pthread_cancel(timer_thread);
+
+ sigaction(SIGSEGV, &old_segv, NULL);
+ sigaction(SIGABRT, &old_abrt, NULL);
+ sigaction(SIGALRM, &old_alrm, NULL);
+
+ target = NULL;
+ initialized = false;
+}
+
+bool get_timedout_c() {
+ return timedout;
+}
+
+jobject get_siginfo_c(JNIEnv *env) {
+ if (!caught) {
+ return NULL;
+ }
+
+ jclass local_siginfo_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/SigInfo");
+ jmethodID siginfo_init = (*env)->GetMethodID(env, local_siginfo_class, "<init>", "(IIIIIJIJJ)V");
+ return (*env)->NewObject(env, local_siginfo_class, siginfo_init,
+ (jint) last_siginfo.si_signo,
+ (jint) last_siginfo.si_code,
+ (jint) last_siginfo.si_errno,
+ (jint) last_siginfo.si_pid,
+ (jint) last_siginfo.si_uid,
+ (jlong) last_siginfo.si_addr,
+ (jint) last_siginfo.si_status,
+ (jlong) last_siginfo.si_band,
+ (jlong) 0);
+}
+
+#endif \ No newline at end of file
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_signals.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_signals.h
new file mode 100644
index 0000000..a82b572
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_signals.h
@@ -0,0 +1,53 @@
+#pragma once
+
+#include <jni.h>
+#include <setjmp.h>
+#include <signal.h>
+
+#define TIMEOUT 5
+
+/**
+ *
+ */
+void init_signals_c(jmp_buf *env, unsigned int timeout);
+
+/**
+ *
+ */
+sigjmp_buf *get_jmpbuf_c();
+
+/**
+ *
+ */
+void deinit_signals_c();
+
+/**
+ *
+ */
+bool get_timedout_c();
+
+/**
+ *
+ */
+jobject get_siginfo_c(JNIEnv *env);
+
+
+#define SIG_TRY(timeout) init_signals_c(get_jmpbuf_c(), timeout); \
+ if (!sigsetjmp(*get_jmpbuf_c(), 1))
+#define SIG_CATCH() deinit_signals_c();
+#define SIG_DEINIT() deinit_signals_c();
+#define SIG_HANDLE(env) do { \
+ jobject siginfo = get_siginfo_c(env); \
+ if (siginfo != NULL) { \
+ jclass sigexception_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/SignalException"); \
+ jmethodID new_sigexception = (*env)->GetMethodID(env, sigexception_class, "<init>", "(Lcz/crcs/ectester/standalone/libs/jni/SigInfo;)V"); \
+ jobject sigexception = (*env)->NewObject(env, sigexception_class, new_sigexception, siginfo); \
+ (*env)->Throw(env, sigexception); \
+ } \
+ if (get_timedout_c()) { \
+ jclass timeoutexception_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/TimeoutException"); \
+ (*env)->ThrowNew(env, timeoutexception_class, "Operation timed out."); \
+ } \
+ } while (0)
+#define SIG_CATCH_HANDLE(env) SIG_CATCH(); \
+ SIG_HANDLE(env)
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cpp_signals.cpp b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cpp_signals.cpp
new file mode 100644
index 0000000..999349a
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cpp_signals.cpp
@@ -0,0 +1,122 @@
+#include "cpp_utils.hpp"
+#include "cpp_signals.hpp"
+
+#if __linux || __posix
+
+#include <signal.h>
+#include <setjmp.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include <unistd.h>
+
+static siginfo_t last_siginfo;
+static bool initialized = false;
+static bool caught = false;
+static bool timedout = false;
+static sigjmp_buf buf;
+static sigjmp_buf *target = NULL;
+
+struct timer_arg {
+ unsigned int timeout;
+ pthread_t main_thread;
+};
+static struct timer_arg ta;
+static pthread_t timer_thread;
+
+extern "C"
+{
+
+void handler(int signo, siginfo_t *info, void *context) {
+ //printf("Signal, %i\n", signo);
+ last_siginfo = *info;
+ caught = true;
+ siglongjmp(*target, 1);
+}
+
+void alarm_handler(int signo) {
+ //printf("Alarm\n");
+ timedout = true;
+ siglongjmp(*target, 1);
+}
+
+
+sigjmp_buf *get_jmpbuf_cpp() {
+ return &buf;
+}
+
+static struct sigaction old_segv;
+static struct sigaction old_abrt;
+static struct sigaction old_alrm;
+
+void *timer(void *arg) {
+ sleep(ta.timeout);
+ pthread_kill(ta.main_thread, SIGALRM);
+ return NULL;
+}
+
+void init_signals_cpp(sigjmp_buf *env, unsigned int timeout) {
+ //printf("Initializing signals!\n");
+ struct sigaction action;
+ action.sa_sigaction = handler;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = SA_SIGINFO;
+
+ sigaction(SIGSEGV, &action, &old_segv);
+ sigaction(SIGABRT, &action, &old_abrt);
+
+ struct sigaction alarm_action;
+ alarm_action.sa_handler = alarm_handler;
+ sigemptyset(&alarm_action.sa_mask);
+ alarm_action.sa_flags = 0;
+ sigaction(SIGALRM, &alarm_action, &old_alrm);
+
+ target = env;
+ initialized = true;
+ caught = false;
+ timedout = false;
+
+ ta.timeout = timeout;
+ ta.main_thread = pthread_self();
+
+ pthread_create(&timer_thread, NULL, timer, (void *)&ta);
+}
+
+
+void deinit_signals_cpp() {
+ //printf("Deinitializing signals!\n");
+ pthread_cancel(timer_thread);
+
+ sigaction(SIGSEGV, &old_segv, NULL);
+ sigaction(SIGABRT, &old_abrt, NULL);
+ sigaction(SIGALRM, &old_alrm, NULL);
+
+ target = NULL;
+ initialized = false;
+}
+
+bool get_timedout_cpp() {
+ return timedout;
+}
+
+jobject get_siginfo_cpp(JNIEnv *env) {
+ if (!caught) {
+ return NULL;
+ }
+
+ jclass local_siginfo_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/SigInfo");
+ jmethodID siginfo_init = env->GetMethodID(local_siginfo_class, "<init>", "(IIIIIJIJJ)V");
+ return env->NewObject(local_siginfo_class, siginfo_init,
+ (jint) last_siginfo.si_signo,
+ (jint) last_siginfo.si_code,
+ (jint) last_siginfo.si_errno,
+ (jint) last_siginfo.si_pid,
+ (jint) last_siginfo.si_uid,
+ (jlong) last_siginfo.si_addr,
+ (jint) last_siginfo.si_status,
+ (jlong) last_siginfo.si_band,
+ (jlong) 0);
+}
+
+}
+
+#endif \ No newline at end of file
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cpp_signals.hpp b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cpp_signals.hpp
new file mode 100644
index 0000000..4dc222f
--- /dev/null
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cpp_signals.hpp
@@ -0,0 +1,59 @@
+#pragma once
+
+#include <jni.h>
+#include <setjmp.h>
+#include <signal.h>
+
+#define TIMEOUT 5
+
+extern "C"
+{
+
+/**
+ *
+ */
+void init_signals_cpp(jmp_buf *env, unsigned int timeout);
+
+/**
+ *
+ */
+sigjmp_buf *get_jmpbuf_cpp();
+
+/**
+ *
+ */
+void deinit_signals_cpp();
+
+/**
+ *
+ */
+bool get_timedout_cpp();
+
+/**
+ *
+ */
+jobject get_siginfo_cpp(JNIEnv *env);
+
+
+#define SIG_TRY(timeout) init_signals_cpp(get_jmpbuf_cpp(), timeout); \
+ if (!sigsetjmp(*get_jmpbuf_cpp(), 1))
+#define SIG_CATCH() deinit_signals_cpp();
+#define SIG_DEINIT() deinit_signals_cpp();
+#define SIG_HANDLE(env) do { \
+ jobject siginfo = get_siginfo_cpp(env); \
+ if (siginfo != NULL) { \
+ jclass sigexception_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/SignalException"); \
+ jmethodID new_sigexception = env->GetMethodID(sigexception_class, "<init>", "(Lcz/crcs/ectester/standalone/libs/jni/SigInfo;)V"); \
+ jobject sigexception = env->NewObject(sigexception_class, new_sigexception, siginfo); \
+ env->Throw((jthrowable) sigexception); \
+ } \
+ if (get_timedout_cpp()) { \
+ jclass timeoutexception_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/TimeoutException"); \
+ env->ThrowNew(timeoutexception_class, "Operation timed out."); \
+ } \
+ } while (0)
+#define SIG_CATCH_HANDLE(env) SIG_CATCH(); \
+ SIG_HANDLE(env)
+
+
+} \ No newline at end of file
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 6ec2060..c4c74a6 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
@@ -71,6 +71,16 @@ using CryptoPP::Integer;
#include "cpp_utils.hpp"
#include "c_timing.h"
+#include "cpp_signals.hpp"
+#undef SIG_TRY
+#undef SIG_CATCH_HANDLE
+#undef SIG_CATCH
+#undef SIG_HANDLE
+#undef SIG_DEINIT
+#define SIG_TRY(x)
+#define SIG_CATCH_HANDLE(x)
+#define SIG_CATCH()
+#define SIG_DEINIT()
/*
* Crypto++:
@@ -504,14 +514,17 @@ template <class EC> jobject generate_from_group(JNIEnv *env, DL_GroupParameters_
typename ECDH<EC>::Domain ec_domain(group);
SecByteBlock priv(ec_domain.PrivateKeyLength()), pub(ec_domain.PublicKeyLength());
- try {
- native_timing_start();
- ec_domain.GenerateKeyPair(rng, priv, pub);
- native_timing_stop();
- } catch (Exception & ex) {
- throw_new(env, "java/security/GeneralSecurityException", ex.what());
- return nullptr;
- }
+ SIG_TRY(TIMEOUT) {
+ try {
+ native_timing_start();
+ ec_domain.GenerateKeyPair(rng, priv, pub);
+ native_timing_stop();
+ } catch (Exception & ex) {
+ SIG_DEINIT();
+ throw_new(env, "java/security/GeneralSecurityException", ex.what());
+ return nullptr;
+ }
+ } SIG_CATCH_HANDLE(env);
jbyteArray pub_bytearray = env->NewByteArray(pub.SizeInBytes());
jbyte *pub_bytes = env->GetByteArrayElements(pub_bytearray, nullptr);
@@ -587,31 +600,34 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
bool success;
std::unique_ptr<SecByteBlock> secret;
- try {
- std::unique_ptr<DL_GroupParameters_EC<ECP>> ecp_group = fp_group_from_params(env, params);
- if (ecp_group == nullptr) {
- std::unique_ptr<DL_GroupParameters_EC<EC2N>> ec2n_group = f2m_group_from_params(env, params);
+ SIG_TRY(TIMEOUT) {
+ try {
+ std::unique_ptr<DL_GroupParameters_EC<ECP>> ecp_group = fp_group_from_params(env, params);
+ if (ecp_group == nullptr) {
+ std::unique_ptr<DL_GroupParameters_EC<EC2N>> ec2n_group = f2m_group_from_params(env, params);
- ECDH<EC2N>::Domain dh_agreement(*ec2n_group);
+ ECDH<EC2N>::Domain dh_agreement(*ec2n_group);
- secret = std::make_unique<SecByteBlock>(dh_agreement.AgreedValueLength());
- native_timing_start();
- success = dh_agreement.Agree(*secret, private_key, public_key);
- native_timing_stop();
+ secret = std::make_unique<SecByteBlock>(dh_agreement.AgreedValueLength());
+ native_timing_start();
+ success = dh_agreement.Agree(*secret, private_key, public_key);
+ native_timing_stop();
- } else {
- ECDH<ECP>::Domain dh_agreement(*ecp_group);
+ } else {
+ ECDH<ECP>::Domain dh_agreement(*ecp_group);
- secret = std::make_unique<SecByteBlock>(dh_agreement.AgreedValueLength());
- native_timing_start();
- success = dh_agreement.Agree(*secret, private_key, public_key);
- native_timing_stop();
+ secret = std::make_unique<SecByteBlock>(dh_agreement.AgreedValueLength());
+ native_timing_start();
+ success = dh_agreement.Agree(*secret, private_key, public_key);
+ native_timing_stop();
+ }
+ } catch (Exception & ex) {
+ SIG_DEINIT();
+ throw_new(env, "java/security/GeneralSecurityException", ex.what());
+ return nullptr;
}
- } catch (Exception & ex) {
- throw_new(env, "java/security/GeneralSecurityException", ex.what());
- return nullptr;
- }
+ } SIG_CATCH_HANDLE(env);
if (!success) {
throw_new(env, "java/security/GeneralSecurityException", "Agreement was unsuccessful.");
@@ -642,9 +658,12 @@ jbyteArray sign_message(JNIEnv *env, DL_GroupParameters_EC<EC> group, jbyteArray
jsize data_length = env->GetArrayLength(data);
jbyte *data_bytes = env->GetByteArrayElements(data, nullptr);
- native_timing_start();
- size_t len = signer.SignMessage(rng, (byte *)data_bytes, data_length, (byte *)signature.c_str());
- native_timing_stop();
+ size_t len;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ 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);
signature.resize(len);
@@ -740,9 +759,12 @@ jboolean verify_message(JNIEnv *env, DL_GroupParameters_EC<EC> group, jbyteArray
jsize data_length = env->GetArrayLength(data);
jbyte *data_bytes = env->GetByteArrayElements(data, nullptr);
- native_timing_start();
- bool result = verifier.VerifyMessage((byte *)data_bytes, data_length, sig, sig_len);
- native_timing_stop();
+ bool result;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ result = verifier.VerifyMessage((byte *)data_bytes, data_length, sig, sig_len);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
env->ReleaseByteArrayElements(data, data_bytes, JNI_ABORT);
return result;
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 ef62fbf..795c30a 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
@@ -1,5 +1,6 @@
#include "c_utils.h"
#include "c_timing.h"
+#include "c_signals.h"
#include "native.h"
#include <stdio.h>
@@ -180,8 +181,11 @@ static jobject mpi_to_biginteger(JNIEnv *env, gcry_mpi_t mpi) {
return NULL;
}
- jmethodID biginteger_init = (*env)->GetMethodID(env, biginteger_class, "<init>", "(I[B)V");
jbyteArray bytes = mpi_to_bytearray(env, mpi);
+ if (!bytes) {
+ return NULL;
+ }
+ jmethodID biginteger_init = (*env)->GetMethodID(env, biginteger_class, "<init>", "(I[B)V");
jobject result = (*env)->NewObject(env, biginteger_class, biginteger_init, 1, bytes);
return result;
}
@@ -196,20 +200,6 @@ static gcry_mpi_t biginteger_to_mpi(JNIEnv *env, jobject bigint) {
return bytearray_to_mpi(env, byte_array);
}
-static jint mpi_to_jint(gcry_mpi_t mpi) {
- jint result = 0;
- unsigned long nbits = gcry_mpi_get_nbits(mpi);
- int max_bits = sizeof(jint) * 8;
- for (size_t i = 0; i < nbits && i < max_bits; ++i) {
- if (gcry_mpi_test_bit(mpi, nbits - i - 1)) {
- result = ((result << 1) | 1);
- } else {
- result = (result << 1);
- }
- }
- return result;
-}
-
static jobject buff_to_ecpoint(JNIEnv *env, gcry_buffer_t buff) {
jint coord_size = (buff.len - 1) / 2;
jmethodID biginteger_init = (*env)->GetMethodID(env, biginteger_class, "<init>", "(I[B)V");
@@ -232,9 +222,10 @@ static jobject buff_to_ecpoint(JNIEnv *env, gcry_buffer_t buff) {
static jobject create_ec_param_spec(JNIEnv *env, gcry_sexp_t key) {
jobject result = NULL;
- gcry_mpi_t p, a, b, n, h;
+ gcry_mpi_t p, a, b, n;
+ unsigned int h;
gcry_buffer_t g = {0};
- gcry_error_t err = gcry_sexp_extract_param(key, "ecc", "pab&g+nh", &p, &a, &b, &g, &n, &h, NULL);
+ gcry_error_t err = gcry_sexp_extract_param(key, "ecc", "pab&g+n%uh", &p, &a, &b, &g, &n, &h, NULL);
if (gcry_err_code(err) != GPG_ERR_NO_ERROR) {
throw_new_var(env, "java/security/GeneralSecurityException", "Error exporting domain parameters. Error: %ui", gcry_err_code(err));
goto end;
@@ -244,7 +235,11 @@ static jobject create_ec_param_spec(JNIEnv *env, gcry_sexp_t key) {
jmethodID fp_field_init = (*env)->GetMethodID(env, fp_field_class, "<init>", "(Ljava/math/BigInteger;)V");
jobject field = (*env)->NewObject(env, fp_field_class, fp_field_init, pi);
- jobject ai = mpi_to_biginteger(env, a);
+ jobject ai = mpi_to_biginteger(env, a);
+ if (!ai) {
+ jmethodID biginteger_valueof = (*env)->GetStaticMethodID(env, biginteger_class, "valueOf", "(J)Ljava/math/BigInteger;");
+ ai = (*env)->CallStaticObjectMethod(env, biginteger_class, biginteger_valueof, (jlong)0);
+ }
jobject bi = mpi_to_biginteger(env, b);
jmethodID elliptic_curve_init = (*env)->GetMethodID(env, elliptic_curve_class, "<init>", "(Ljava/security/spec/ECField;Ljava/math/BigInteger;Ljava/math/BigInteger;)V");
@@ -253,7 +248,7 @@ static jobject create_ec_param_spec(JNIEnv *env, gcry_sexp_t key) {
jobject gen = buff_to_ecpoint(env, g);
jobject order = mpi_to_biginteger(env, n);
- jint cofactor = mpi_to_jint(h);
+ jint cofactor = (jint) h;
jmethodID ec_parameter_spec_init = (*env)->GetMethodID(env, ec_parameter_spec_class, "<init>", "(Ljava/security/spec/EllipticCurve;Ljava/security/spec/ECPoint;Ljava/math/BigInteger;I)V");
result = (*env)->NewObject(env, ec_parameter_spec_class, ec_parameter_spec_init, elliptic_curve, gen, order, cofactor);
@@ -264,7 +259,6 @@ end:
gcry_mpi_release(b);
gcry_free(g.data);
gcry_mpi_release(n);
- gcry_mpi_release(h);
return result;
}
@@ -272,9 +266,12 @@ static jobject generate_from_sexp(JNIEnv *env, gcry_sexp_t gen_sexp) {
jobject result = NULL;
gcry_sexp_t key_sexp;
- native_timing_start();
- gcry_error_t err = gcry_pk_genkey(&key_sexp, gen_sexp);
- native_timing_stop();
+ gcry_error_t err;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ err = gcry_pk_genkey(&key_sexp, gen_sexp);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
if (gcry_err_code(err) != GPG_ERR_NO_ERROR) {
throw_new_var(env, "java/security/GeneralSecurityException", "Error generating key. Error: %ui", gcry_err_code(err));
@@ -460,12 +457,15 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
gcry_sexp_t res_sexp;
// TODO: figure out why ecc_encrypt_raw takes signed representation.. Nobody uses that., everybody uses unsigned reduced mod p.
- native_timing_start();
- gcry_error_t err = gcry_pk_encrypt(&res_sexp, enc_sexp, pub);
- native_timing_stop();
+ gcry_error_t err;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ err = gcry_pk_encrypt(&res_sexp, enc_sexp, pub);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
if (gcry_err_code(err) != GPG_ERR_NO_ERROR) {
- throw_new_var(env, "java/security/GeneralSecurityException", "Error performing ECDH. Error: %ui", gcry_err_code(err));
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error performing ECDH. Error: %u", gcry_err_code(err));
goto end;
}
@@ -572,11 +572,15 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
get_sign_data_sexp(env, &data_sexp, this, data);
gcry_sexp_t res_sexp;
- native_timing_start();
- gcry_error_t err = gcry_pk_sign(&res_sexp, data_sexp, priv_sexp);
- native_timing_stop();
+ gcry_error_t err;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ err = gcry_pk_sign(&res_sexp, data_sexp, priv_sexp);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
+
if (gcry_err_code(err) != GPG_ERR_NO_ERROR) {
- throw_new_var(env, "java/security/GeneralSecurityException", "Error performing ECDSA. Error: %ui", gcry_err_code(err));
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error performing ECDSA. Error: %u", gcry_err_code(err));
goto release_init;
}
@@ -584,7 +588,7 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
gcry_buffer_t s_buf = {0};
err = gcry_sexp_extract_param(res_sexp, "ecdsa", "&rs", &r_buf, &s_buf, NULL);
if (gcry_err_code(err) != GPG_ERR_NO_ERROR) {
- throw_new_var(env, "java/security/GeneralSecurityException", "Error extracting ECDSA output. Error: %ui", gcry_err_code(err));
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error extracting ECDSA output. Error: %u", gcry_err_code(err));
goto release_res;
}
result = asn1_der_encode(env, r_buf.data, r_buf.len, s_buf.data, s_buf.len);
@@ -627,13 +631,16 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
gcry_sexp_t sig_sexp;
gcry_sexp_build(&sig_sexp, NULL, "(sig-val (ecdsa (r %M) (s %M)))", r_mpi, s_mpi);
- native_timing_start();
- gcry_error_t err = gcry_pk_verify(sig_sexp, data_sexp, pub_sexp);
- native_timing_stop();
+ gcry_error_t err;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ err = gcry_pk_verify(sig_sexp, data_sexp, pub_sexp);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
if (gcry_err_code(err) != GPG_ERR_NO_ERROR) {
if (gcry_err_code(err) != GPG_ERR_BAD_SIGNATURE) {
- throw_new(env, "java/security/GeneralSecurityException", "Error verif sig.");
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error verif sig. Error: %u", gcry_err_code(err));
goto release_init;
}
} else {
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 2f876d2..fbf917e 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
@@ -1,5 +1,6 @@
#include "c_timing.h"
#include "c_utils.h"
+#include "c_signals.h"
#include <stdint.h>
#include <stdlib.h>
@@ -379,9 +380,12 @@ static jobject generate_from_curve(JNIEnv *env, int keysize, IppsECCPState *curv
int ord_bytes = (ord_bits + 7) / 8;
IppsBigNumState *secret = new_bn(ord_bits);
- native_timing_start();
- IppStatus err = ippsECCPGenKeyPair(secret, point, curve, prng_wrapper, prng_state);
- native_timing_stop();
+ IppStatus err;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ err = ippsECCPGenKeyPair(secret, point, curve, prng_wrapper, prng_state);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
if (err != ippStsNoErr) {
throw_new(env, "java/security/GeneralSecurityException", ippcpGetStatusString(err));
@@ -559,9 +563,12 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
IppsBigNumState *share = new_bn(keysize);
- native_timing_start();
- IppStatus err = ippsECCPSharedSecretDH(priv_bn, pub, share, curve);
- native_timing_stop();
+ IppStatus err;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ err = ippsECCPSharedSecretDH(priv_bn, pub, share, curve);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
free(priv_bn);
free(pub);
@@ -622,23 +629,29 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
jbyte r_buf[ord_bytes];
jbyte s_buf[ord_bytes];
- native_timing_start();
- IppStatus err = ippsECCPGenKeyPair(ephemeral_secret, ephemeral_point, curve, prng_wrapper, prng_state);
- if (err != ippStsNoErr) {
- throw_new(env, "java/security/GeneralSecurityException", ippcpGetStatusString(err));
- goto error;
- }
- err = ippsECCPSetKeyPair(ephemeral_secret, ephemeral_point, ippFalse, curve);
- if (err != ippStsNoErr) {
- throw_new(env, "java/security/GeneralSecurityException", ippcpGetStatusString(err));
- goto error;
- }
- err = ippsECCPSignDSA(data_bn, priv_bn, r, s, curve);
- if (err != ippStsNoErr) {
- throw_new(env, "java/security/GeneralSecurityException", ippcpGetStatusString(err));
- goto error;
- }
- native_timing_stop();
+ IppStatus err;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ err = ippsECCPGenKeyPair(ephemeral_secret, ephemeral_point, curve, prng_wrapper, prng_state);
+ if (err != ippStsNoErr) {
+ SIG_DEINIT();
+ throw_new(env, "java/security/GeneralSecurityException", ippcpGetStatusString(err));
+ goto error;
+ }
+ err = ippsECCPSetKeyPair(ephemeral_secret, ephemeral_point, ippFalse, curve);
+ if (err != ippStsNoErr) {
+ SIG_DEINIT();
+ throw_new(env, "java/security/GeneralSecurityException", ippcpGetStatusString(err));
+ goto error;
+ }
+ err = ippsECCPSignDSA(data_bn, priv_bn, r, s, curve);
+ if (err != ippStsNoErr) {
+ SIG_DEINIT();
+ throw_new(env, "java/security/GeneralSecurityException", ippcpGetStatusString(err));
+ goto error;
+ }
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
bn_get(r, (uint8_t *) r_buf, ord_bytes);
bn_get(s, (uint8_t *) s_buf, ord_bytes);
@@ -713,10 +726,13 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
IppECResult result;
- native_timing_start();
- ippsECCPSetKeyPair(NULL, pub, ippTrue, curve);
- IppStatus err = ippsECCPVerifyDSA(data_bn, r, s, &result, curve);
- native_timing_stop();
+ IppStatus err;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ ippsECCPSetKeyPair(NULL, pub, ippTrue, curve);
+ err = ippsECCPVerifyDSA(data_bn, r, s, &result, curve);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
free(curve);
free(pub);
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/libressl.c b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/libressl.c
index 398ad1e..d329f45 100644
--- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/libressl.c
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/libressl.c
@@ -1,5 +1,6 @@
#include "c_utils.h"
#include "c_timing.h"
+#include "c_signals.h"
#include "native.h"
#include <string.h>
@@ -313,9 +314,12 @@ static jobject generate_from_curve(JNIEnv *env, const EC_GROUP *curve) {
EC_KEY *key = EC_KEY_new();
EC_KEY_set_group(key, curve);
- native_timing_start();
- int err = EC_KEY_generate_key(key);
- native_timing_stop();
+ int err;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ err = EC_KEY_generate_key(key);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
if (!err) {
throw_new(env, "java/security/GeneralSecurityException", "Error generating key, EC_KEY_generate_key.");
@@ -416,10 +420,19 @@ EC_KEY *barray_to_pubkey(JNIEnv *env, const EC_GROUP *curve, jbyteArray pub) {
jsize pub_len = (*env)->GetArrayLength(env, pub);
jbyte *pub_data = (*env)->GetByteArrayElements(env, pub, NULL);
EC_POINT *pub_point = EC_POINT_new(curve);
- EC_POINT_oct2point(curve, pub_point, (unsigned char *) pub_data, pub_len, NULL);
+ int retval = EC_POINT_oct2point(curve, pub_point, (unsigned char *) pub_data, pub_len, NULL);
(*env)->ReleaseByteArrayElements(env, pub, pub_data, JNI_ABORT);
- EC_KEY_set_public_key(result, pub_point);
+ if (!retval) {
+ EC_POINT_free(pub_point);
+ throw_new(env, "java/security/GeneralSecurityException", "Error loading key, EC_POINT_oct2point.");
+ return NULL;
+ }
+ retval = EC_KEY_set_public_key(result, pub_point);
EC_POINT_free(pub_point);
+ if (!retval) {
+ throw_new(env, "java/security/GeneralSecurityException", "Error loading key, EC_KEY_set_public_key.");
+ return NULL;
+ }
return result;
}
@@ -430,32 +443,46 @@ EC_KEY *barray_to_privkey(JNIEnv *env, const EC_GROUP *curve, jbyteArray priv)
jbyte *priv_data = (*env)->GetByteArrayElements(env, priv, NULL);
BIGNUM *s = BN_bin2bn((unsigned char *) priv_data, priv_len, NULL);
(*env)->ReleaseByteArrayElements(env, priv, priv_data, JNI_ABORT);
- EC_KEY_set_private_key(result, s);
+ int retval = EC_KEY_set_private_key(result, s);
BN_free(s);
+ if (!retval) {
+ throw_new(env, "java/security/GeneralSecurityException", "Error loading key, EC_KEY_set_private_key.");
+ return NULL;
+ }
return result;
}
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Libressl_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params) {
+ jbyteArray result = NULL;
EC_GROUP *curve = create_curve(env, params);
if (!curve) {
throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found.");
- return NULL;
+ goto free_curve;
}
EC_KEY *pub = barray_to_pubkey(env, curve, pubkey);
+ if (!pub) {
+ goto free_pub;
+ }
EC_KEY *priv = barray_to_privkey(env, curve, privkey);
+ if (!priv) {
+ goto free_priv;
+ }
int field_size = EC_GROUP_get_degree(curve);
size_t secret_len = (field_size + 7)/8;
//TODO: Do more KeyAgreements here, but will have to do the hash-fun manually,
// probably using the ECDH_KDF_X9_62 by wrapping it and dynamically choosing the EVP_MD. from the type string.
- jbyteArray result = (*env)->NewByteArray(env, secret_len);
+ result = (*env)->NewByteArray(env, secret_len);
jbyte *result_data = (*env)->GetByteArrayElements(env, result, NULL);
- native_timing_start();
- int err = ECDH_compute_key(result_data, secret_len, EC_KEY_get0_public_key(pub), priv, NULL);
- native_timing_stop();
+ int err;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ err = ECDH_compute_key(result_data, secret_len, EC_KEY_get0_public_key(pub), priv, NULL);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
if (err <= 0) {
throw_new(env, "java/security/GeneralSecurityException", "Error computing ECDH, ECDH_compute_key.");
@@ -465,8 +492,11 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
}
(*env)->ReleaseByteArrayElements(env, result, result_data, 0);
- EC_KEY_free(pub);
+free_priv:
EC_KEY_free(priv);
+free_pub:
+ EC_KEY_free(pub);
+free_curve:
EC_GROUP_free(curve);
return result;
}
@@ -477,21 +507,28 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgr
}
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Libressl_sign(JNIEnv *env, jobject self, jbyteArray data, jbyteArray privkey, jobject params) {
+ jbyteArray result = NULL;
EC_GROUP *curve = create_curve(env, params);
if (!curve) {
throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found.");
- return NULL;
+ goto free_curve;
}
EC_KEY *priv = barray_to_privkey(env, curve, privkey);
+ if (!priv) {
+ goto free_priv;
+ }
jsize data_size = (*env)->GetArrayLength(env, data);
jbyte *data_data = (*env)->GetByteArrayElements(env, data, NULL);
// TODO: Do more Signatures here, maybe use the EVP interface to get to the hashes easier and not hash manually?
- native_timing_start();
- ECDSA_SIG *signature = ECDSA_do_sign((unsigned char *) data_data, data_size, priv);
- native_timing_stop();
+ ECDSA_SIG *signature;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ signature = ECDSA_do_sign((unsigned char *) data_data, data_size, priv);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
(*env)->ReleaseByteArrayElements(env, data, data_data, JNI_ABORT);
if (!signature) {
@@ -501,14 +538,16 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
}
jsize sig_len = i2d_ECDSA_SIG(signature, NULL);
- jbyteArray result = (*env)->NewByteArray(env, sig_len);
+ result = (*env)->NewByteArray(env, sig_len);
jbyte *result_data = (*env)->GetByteArrayElements(env, result, NULL);
jbyte *result_data_ptr = result_data;
i2d_ECDSA_SIG(signature, (unsigned char **)&result_data_ptr);
(*env)->ReleaseByteArrayElements(env, result, result_data, 0);
ECDSA_SIG_free(signature);
+free_priv:
EC_KEY_free(priv);
+free_curve:
EC_GROUP_free(curve);
return result;
}
@@ -521,6 +560,10 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
}
EC_KEY *pub = barray_to_pubkey(env, curve, pubkey);
+ if (!pub) {
+ EC_GROUP_free(curve);
+ return JNI_FALSE;
+ }
jsize sig_len = (*env)->GetArrayLength(env, signature);
jbyte *sig_data = (*env)->GetByteArrayElements(env, signature, NULL);
@@ -531,9 +574,13 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
jsize data_size = (*env)->GetArrayLength(env, data);
jbyte *data_data = (*env)->GetByteArrayElements(env, data, NULL);
- native_timing_start();
- int result = ECDSA_do_verify((unsigned char *) data_data, data_size, sig_obj, pub);
- native_timing_stop();
+ int result;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ result = ECDSA_do_verify((unsigned char *) data_data, data_size, sig_obj, pub);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
+
(*env)->ReleaseByteArrayElements(env, data, data_data, JNI_ABORT);
if (result < 0) {
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 ab556d8..7a552da 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
@@ -1,5 +1,6 @@
#include "c_utils.h"
#include "c_timing.h"
+#include "c_signals.h"
#include "native.h"
#include <string.h>
@@ -315,9 +316,12 @@ static jobject generate_from_curve(JNIEnv *env, mbedtls_ecp_group *group) {
}
gen_counter++;
- native_timing_start();
- int error = mbedtls_ecp_gen_keypair(group, &d, &Q, ctr_drbg_wrapper, &ctr_drbg);
- native_timing_stop();
+ int error;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ error = mbedtls_ecp_gen_keypair(group, &d, &Q, ctr_drbg_wrapper, &ctr_drbg);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
if (error) {
throw_new(env, "java/security/GeneralSecurityException", err_to_string(error));
@@ -453,9 +457,11 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
mbedtls_mpi result;
mbedtls_mpi_init(&result);
- native_timing_start();
- error = mbedtls_ecdh_compute_shared(&curve, &result, &pub, &priv, ctr_drbg_wrapper, &ctr_drbg);
- native_timing_stop();
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ error = mbedtls_ecdh_compute_shared(&curve, &result, &pub, &priv, ctr_drbg_wrapper, &ctr_drbg);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
if (error) {
throw_new(env, "java/security/GeneralSecurityException", err_to_string(error));
@@ -504,9 +510,11 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
jsize data_size = (*env)->GetArrayLength(env, data);
jbyte *data_data = (*env)->GetByteArrayElements(env, data, NULL);
- native_timing_start();
- error = mbedtls_ecdsa_sign(&curve, &r, &s, &priv, (unsigned char *) data_data, data_size, ctr_drbg_wrapper, &ctr_drbg);
- native_timing_stop();
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ error = mbedtls_ecdsa_sign(&curve, &r, &s, &priv, (unsigned char *) data_data, data_size, ctr_drbg_wrapper, &ctr_drbg);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
mbedtls_mpi_free(&priv);
mbedtls_ecp_group_free(&curve);
@@ -563,9 +571,11 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
jsize data_size = (*env)->GetArrayLength(env, data);
jbyte *data_data = (*env)->GetByteArrayElements(env, data, NULL);
- native_timing_start();
- error = mbedtls_ecdsa_verify(&curve, (unsigned char *) data_data, data_size, &pub, &r, &s);
- native_timing_stop();
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ error = mbedtls_ecdsa_verify(&curve, (unsigned char *) data_data, data_size, &pub, &r, &s);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
(*env)->ReleaseByteArrayElements(env, data, data_data, JNI_ABORT);
if (error) {
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 dcaf57c..60c59b1 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
@@ -1861,3 +1861,139 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
}
#endif
#endif
+/* Header for class cz_crcs_ectester_standalone_libs_NettleLib */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_NettleLib
+#define _Included_cz_crcs_ectester_standalone_libs_NettleLib
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_NettleLib
+ * Method: createProvider
+ * Signature: ()Ljava/security/Provider;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_NettleLib_createProvider
+ (JNIEnv *, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_NettleLib
+ * Method: getCurves
+ * Signature: ()Ljava/util/Set;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_NettleLib_getCurves
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_Nettle */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Nettle
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Nettle
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Nettle_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Nettle_serialVersionUID 1421746759512286392LL
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Nettle_MAX_ARRAY_SIZE
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Nettle_MAX_ARRAY_SIZE 2147483639L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Nettle_KEYS
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Nettle_KEYS 0L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Nettle_VALUES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Nettle_VALUES 1L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Nettle_ENTRIES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Nettle_ENTRIES 2L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Nettle_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Nettle_serialVersionUID 4112578634029874840LL
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Nettle_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Nettle_serialVersionUID -4298000515446427739LL
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Nettle
+ * Method: setup
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Nettle_setup
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Nettle */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Nettle
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Nettle
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Nettle_DEFAULT_KEYSIZE
+#define cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Nettle_DEFAULT_KEYSIZE 256L
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Nettle
+ * Method: generate
+ * Signature: (ILjava/security/SecureRandom;Ljava/security/spec/AlgorithmParameterSpec;)Ljava/security/KeyPair;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Nettle_generate__ILjava_security_SecureRandom_2Ljava_security_spec_AlgorithmParameterSpec_2
+ (JNIEnv *, jobject, jint, jobject, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Nettle
+ * Method: generate
+ * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;Ljava/security/spec/AlgorithmParameterSpec;)Ljava/security/KeyPair;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Nettle_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2Ljava_security_spec_AlgorithmParameterSpec_2
+ (JNIEnv *, jobject, jobject, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Nettle */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Nettle
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Nettle
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Nettle
+ * Method: generateSecret
+ * Signature: ([B[BLjava/security/spec/ECGenParameterSpec;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Nettle_generateSecret
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Nettle */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Nettle
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Nettle
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Nettle
+ * Method: sign
+ * Signature: ([B[BLjava/security/spec/ECGenParameterSpec;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Nettle_sign
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Nettle
+ * Method: verify
+ * Signature: ([B[B[BLjava/security/spec/ECGenParameterSpec;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Nettle_verify
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#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 dfc8389..e7ec00e 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
@@ -1,5 +1,6 @@
#include "c_utils.h"
#include "c_timing.h"
+#include "c_signals.h"
#include "native.h"
#include <string.h>
@@ -35,7 +36,6 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_NettleLib_create
}
JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Nettle_setup(JNIEnv *env, jobject self) {
-
INIT_PROVIDER(env, provider_class);
ADD_KPG(env, self, "EC", "Nettle");
ADD_KA(env, self, "ECDH", "NettleECDH");
@@ -66,16 +66,6 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_NettleLib_getCur
return result;
}
-JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Nettle_keysizeSupported(JNIEnv *env, jobject self, jint keysize) {
- int supported[] = {192, 224, 256, 384, 521};
- for (int i = 0; i < 5; i++) {
- if (keysize == supported[i]) {
- return JNI_TRUE;
- }
- }
- return JNI_FALSE;
-}
-
static const struct ecc_curve* create_curve_from_name(JNIEnv *env, const char* curve_name) {
if (!curve_name) {
return NULL;
@@ -115,34 +105,6 @@ static const struct ecc_curve* create_curve_from_size(JNIEnv *env, jint keysize)
}
}
-JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Nettle_paramsSupported(JNIEnv *env, jobject self, jobject params){
- if (params == NULL) {
- return JNI_FALSE;
- }
-
- if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
- return JNI_FALSE;
- } else if ((*env)->IsInstanceOf(env, params, ecgen_parameter_spec_class)) {
- jmethodID get_name = (*env)->GetMethodID(env, ecgen_parameter_spec_class, "getName", "()Ljava/lang/String;");
- jstring name = (*env)->CallObjectMethod(env, params, get_name);
- const char *utf_name = (*env)->GetStringUTFChars(env, name, NULL);
-
- char *curve_name[5] = {"secp192r1", "secp224r1", "secp256r1", "secp384r1", "secp521r1"};
- for (int i = 0; i < sizeof(curve_name); i++) {
- if (strcasecmp(utf_name, curve_name[i]) == 0) {
- (*env)->ReleaseStringUTFChars(env, name, utf_name);
- return JNI_TRUE;
- }
- }
- (*env)->ReleaseStringUTFChars(env, name, utf_name);
- return JNI_FALSE;
- } else {
- return JNI_FALSE;
- }
- return JNI_FALSE;
-
-}
-
static jobject generate_from_curve(JNIEnv *env, const struct ecc_curve* curve, jobject spec, int byte_size) {
struct ecc_point pub;
@@ -150,9 +112,12 @@ static jobject generate_from_curve(JNIEnv *env, const struct ecc_curve* curve, j
ecc_point_init(&pub, curve);
ecc_scalar_init(&priv, curve);
- native_timing_start();
- ecdsa_generate_keypair(&pub, &priv, (void *) &yarrow, (nettle_random_func *) yarrow256_random);
- native_timing_stop();
+
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ ecdsa_generate_keypair(&pub, &priv, (void *) &yarrow, (nettle_random_func *) yarrow256_random);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
mpz_t private_value;
mpz_init(private_value);
@@ -206,16 +171,15 @@ static jobject generate_from_curve(JNIEnv *env, const struct ecc_curve* curve, j
return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
}
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Nettle_generate__ILjava_security_SecureRandom_2(JNIEnv *env, jobject self, jint keysize, jobject random) {
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Nettle_generate__ILjava_security_SecureRandom_2Ljava_security_spec_AlgorithmParameterSpec_2(JNIEnv *env, jobject self, jint keysize, jobject random, jobject spec) {
const struct ecc_curve* curve = create_curve_from_size(env, keysize);
if (!curve) {
throw_new(env, "java/lang/UnsupportedOperationException", "Not supported.");
return NULL;
}
int byte_size = (keysize + 7) / 8;
- jobject result = generate_from_curve(env, curve, NULL, byte_size);
+ jobject result = generate_from_curve(env, curve, spec, byte_size);
return result;
- return NULL;
}
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Nettle_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2Ljava_security_spec_AlgorithmParameterSpec_2(JNIEnv *env, jobject self, jobject params, jobject random, jobject spec) {
@@ -261,7 +225,10 @@ int barray_to_pubkey(JNIEnv *env, struct ecc_point* pubKey , jbyteArray pub) {
mpz_import(x, pointLength, 1, sizeof(unsigned char), 0, 0, pub_data+1);
mpz_import(y, pointLength, 1, sizeof(unsigned char), 0, 0, pub_data+1+pointLength);
(*env)->ReleaseByteArrayElements(env, pub, pub_data, JNI_ABORT);
- ecc_point_set(pubKey, x, y);
+ if (ecc_point_set(pubKey, x, y) == 0) {
+ throw_new(env, "java/security/GeneralSecurityException", "Error loading key, ecc_point_set.");
+ return 0;
+ }
return pointLength;
}
@@ -276,7 +243,7 @@ int barray_to_privkey(JNIEnv *env, struct ecc_scalar* privKey, jbyteArray priv)
return priv_len;
}
-JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Nettle_generateSecret___3B_3BLjava_security_spec_ECGenParameterSpec_2(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params) {
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Nettle_generateSecret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params) {
jmethodID get_name = (*env)->GetMethodID(env, ecgen_parameter_spec_class, "getName", "()Ljava/lang/String;");
jstring name = (*env)->CallObjectMethod(env, params, get_name);
const char* utf_name = (*env)->GetStringUTFChars(env, name, NULL);
@@ -303,7 +270,12 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
struct ecc_point eccPubPoint;
ecc_point_init(&eccPubPoint, curve);
- barray_to_pubkey(env, &eccPubPoint, pubkey);
+ int publen = barray_to_pubkey(env, &eccPubPoint, pubkey);
+ if (publen == 0) {
+ ecc_scalar_clear(&privScalar);
+ ecc_point_clear(&eccPubPoint);
+ return NULL;
+ }
struct ecc_point resultPoint;
ecc_point_init(&resultPoint, curve);
@@ -311,9 +283,11 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
jbyteArray result = (*env)->NewByteArray(env, byte_size);
jbyte *result_data = (*env)->GetByteArrayElements(env, result, NULL);
- native_timing_start();
- ecc_point_mul(&resultPoint, &privScalar, &eccPubPoint);
- native_timing_stop();
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ ecc_point_mul(&resultPoint, &privScalar, &eccPubPoint);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
mpz_t x;
mpz_init(x);
@@ -333,11 +307,6 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
return result;
}
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Nettle_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2Ljava_lang_String_2(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params, jstring algorithm) {
- throw_new(env, "java/lang/UnsupportedOperationException", "Not supported.");
- return NULL;
-}
-
// credit to https://github.com/crocs-muni/ECTester/blob/master/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c
size_t signature_to_der(struct dsa_signature* signature, unsigned char *result, int byte_size) {
size_t r_tmpSize;
@@ -461,9 +430,11 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
struct dsa_signature signature;
dsa_signature_init(&signature);
- native_timing_start();
- ecdsa_sign(&privScalar, (void *) &yarrow, (nettle_random_func *) yarrow256_random, data_size, (unsigned char*)data_data, &signature);
- native_timing_stop();
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ ecdsa_sign(&privScalar, (void *) &yarrow, (nettle_random_func *) yarrow256_random, data_size, (unsigned char*)data_data, &signature);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
(*env)->ReleaseByteArrayElements(env, data, data_data, JNI_ABORT);
@@ -515,9 +486,13 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
jsize data_size = (*env)->GetArrayLength(env, data);
jbyte *data_data = (*env)->GetByteArrayElements(env, data, NULL);
- native_timing_start();
- int result = ecdsa_verify(&eccPubPoint, data_size, (unsigned char*)data_data, &eccSignature);
- native_timing_stop();
+ int result;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ result = ecdsa_verify(&eccPubPoint, data_size, (unsigned char*)data_data, &eccSignature);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
+
(*env)->ReleaseByteArrayElements(env, data, data_data, JNI_ABORT);
ecc_point_clear(&eccPubPoint);
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 3fa560e..59eb0db 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
@@ -1,5 +1,6 @@
#include "c_utils.h"
#include "c_timing.h"
+#include "c_signals.h"
#include "native.h"
#include <string.h>
@@ -350,9 +351,12 @@ static jobject generate_from_curve(JNIEnv *env, const EC_GROUP *curve) {
EC_KEY *key = EC_KEY_new();
EC_KEY_set_group(key, curve);
- native_timing_start();
- int result = EC_KEY_generate_key(key);
- native_timing_stop();
+ int result;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ result = EC_KEY_generate_key(key);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
if (!result) {
throw_new(env, "java/security/GeneralSecurityException", "Error generating key, EC_KEY_generate_key.");
@@ -451,10 +455,19 @@ EC_KEY *barray_to_pubkey(JNIEnv *env, const EC_GROUP *curve, jbyteArray pub) {
jsize pub_len = (*env)->GetArrayLength(env, pub);
jbyte *pub_data = (*env)->GetByteArrayElements(env, pub, NULL);
EC_POINT *pub_point = EC_POINT_new(curve);
- EC_POINT_oct2point(curve, pub_point, (unsigned char *) pub_data, pub_len, NULL);
+ int retval = EC_POINT_oct2point(curve, pub_point, (unsigned char *) pub_data, pub_len, NULL);
(*env)->ReleaseByteArrayElements(env, pub, pub_data, JNI_ABORT);
- EC_KEY_set_public_key(result, pub_point);
+ if (!retval) {
+ EC_POINT_free(pub_point);
+ throw_new(env, "java/security/GeneralSecurityException", "Error loading key, EC_POINT_oct2point.");
+ return NULL;
+ }
+ retval = EC_KEY_set_public_key(result, pub_point);
EC_POINT_free(pub_point);
+ if (!retval) {
+ throw_new(env, "java/security/GeneralSecurityException", "Error loading key, EC_KEY_set_public_key.");
+ return NULL;
+ }
return result;
}
@@ -465,8 +478,12 @@ EC_KEY *barray_to_privkey(JNIEnv *env, const EC_GROUP *curve, jbyteArray priv)
jbyte *priv_data = (*env)->GetByteArrayElements(env, priv, NULL);
BIGNUM *s = BN_bin2bn((unsigned char *) priv_data, priv_len, NULL);
(*env)->ReleaseByteArrayElements(env, priv, priv_data, JNI_ABORT);
- EC_KEY_set_private_key(result, s);
+ int retval = EC_KEY_set_private_key(result, s);
BN_free(s);
+ if (!retval) {
+ throw_new(env, "java/security/GeneralSecurityException", "Error loading key, EC_KEY_set_private_key.");
+ return NULL;
+ }
return result;
}
@@ -478,7 +495,13 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
}
EC_KEY *pub = barray_to_pubkey(env, curve, pubkey);
+ if (!pub) {
+ return NULL;
+ }
EC_KEY *priv = barray_to_privkey(env, curve, privkey);
+ if (!priv) {
+ return NULL;
+ }
int field_size = EC_GROUP_get_degree(curve);
size_t secret_len = (field_size + 7)/8;
@@ -488,12 +511,15 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
jbyteArray result = (*env)->NewByteArray(env, secret_len);
jbyte *result_data = (*env)->GetByteArrayElements(env, result, NULL);
- native_timing_start();
- int err = ECDH_compute_key(result_data, secret_len, EC_KEY_get0_public_key(pub), priv, NULL);
- native_timing_stop();
+ int err;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ err = ECDH_compute_key(result_data, secret_len, EC_KEY_get0_public_key(pub), priv, NULL);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
if (err <= 0) {
- throw_new(env, "java/security/GeneralSecurityException", "Error computing ECDH, ECDH_compute_key.");
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error computing ECDH, ECDH_compute_key (%i).", err);
EC_KEY_free(pub); EC_KEY_free(priv); EC_GROUP_free(curve);
(*env)->ReleaseByteArrayElements(env, result, result_data, JNI_ABORT);
return NULL;
@@ -519,14 +545,20 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
}
EC_KEY *priv = barray_to_privkey(env, curve, privkey);
+ if (!priv) {
+ return NULL;
+ }
jsize data_size = (*env)->GetArrayLength(env, data);
jbyte *data_data = (*env)->GetByteArrayElements(env, data, NULL);
// TODO: Do more Signatures here, maybe use the EVP interface to get to the hashes easier and not hash manually?
- native_timing_start();
- ECDSA_SIG *signature = ECDSA_do_sign((unsigned char *) data_data, data_size, priv);
- native_timing_stop();
+ ECDSA_SIG *signature;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ signature = ECDSA_do_sign((unsigned char *) data_data, data_size, priv);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
(*env)->ReleaseByteArrayElements(env, data, data_data, JNI_ABORT);
if (!signature) {
@@ -556,6 +588,9 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
}
EC_KEY *pub = barray_to_pubkey(env, curve, pubkey);
+ if (!pub) {
+ return JNI_FALSE;
+ }
jsize sig_len = (*env)->GetArrayLength(env, signature);
jbyte *sig_data = (*env)->GetByteArrayElements(env, signature, NULL);
@@ -566,13 +601,17 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
jsize data_size = (*env)->GetArrayLength(env, data);
jbyte *data_data = (*env)->GetByteArrayElements(env, data, NULL);
- native_timing_start();
- int result = ECDSA_do_verify((unsigned char *) data_data, data_size, sig_obj, pub);
- native_timing_stop();
+ int result;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ result = ECDSA_do_verify((unsigned char *) data_data, data_size, sig_obj, pub);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
+
(*env)->ReleaseByteArrayElements(env, data, data_data, JNI_ABORT);
if (result < 0) {
- throw_new(env, "java/security/GeneralSecurityException", "Error verifying, ECDSA_do_verify.");
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error verifying, ECDSA_do_verify (%i).", result);
EC_KEY_free(pub); EC_GROUP_free(curve); ECDSA_SIG_free(sig_obj);
return JNI_FALSE;
}
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 efaa3b9..23f28ca 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
@@ -1,5 +1,6 @@
#include "c_utils.h"
#include "c_timing.h"
+#include "c_signals.h"
#include "native.h"
#include <stdio.h>
@@ -191,6 +192,22 @@ static ltc_ecc_set_type* create_curve(JNIEnv *env, jobject params) {
jmethodID get_p = (*env)->GetMethodID(env, fp_field_class, "getP", "()Ljava/math/BigInteger;");
jobject p = (*env)->CallObjectMethod(env, field, get_p);
+ jmethodID biginteger_valueof = (*env)->GetStaticMethodID(env, biginteger_class, "valueOf", "(J)Ljava/math/BigInteger;");
+ jobject three = (*env)->CallStaticObjectMethod(env, biginteger_class, biginteger_valueof, (jlong) 3);
+
+ jmethodID get_a = (*env)->GetMethodID(env, elliptic_curve_class, "getA", "()Ljava/math/BigInteger;");
+ jobject a = (*env)->CallObjectMethod(env, elliptic_curve, get_a);
+
+ jmethodID biginteger_add = (*env)->GetMethodID(env, biginteger_class, "add", "(Ljava/math/BigInteger;)Ljava/math/BigInteger;");
+ jobject a_3 = (*env)->CallObjectMethod(env, a, biginteger_add, three);
+
+ jmethodID biginteger_equals = (*env)->GetMethodID(env, biginteger_class, "equals", "(Ljava/lang/Object;)Z");
+ jboolean eq = (*env)->CallBooleanMethod(env, p, biginteger_equals, a_3);
+
+ if (!eq) {
+ return NULL;
+ }
+
jmethodID get_g = (*env)->GetMethodID(env, ec_parameter_spec_class, "getGenerator", "()Ljava/security/spec/ECPoint;");
jobject g = (*env)->CallObjectMethod(env, params, get_g);
@@ -232,9 +249,12 @@ static void free_curve(ltc_ecc_set_type *curve) {
static jobject generate_from_curve(JNIEnv *env, const ltc_ecc_set_type *curve) {
ecc_key key;
- native_timing_start();
- int err = ecc_make_key_ex(&ltc_prng, find_prng("yarrow"), &key, curve);
- native_timing_stop();
+ int err;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ err = ecc_make_key_ex(&ltc_prng, find_prng("yarrow"), &key, curve);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
if (err != CRYPT_OK) {
throw_new(env, "java/security/GeneralSecurityException", error_to_string(err));
@@ -381,9 +401,12 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
unsigned char result[curve->size];
unsigned long output_len = curve->size;
- native_timing_start();
- int err = ecc_shared_secret(&priv, &pub, result, &output_len);
- native_timing_stop();
+ int err;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ err = ecc_shared_secret(&priv, &pub, result, &output_len);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
if (err != CRYPT_OK) {
throw_new(env, "java/security/GeneralSecurityException", error_to_string(err));
@@ -425,9 +448,12 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
unsigned char result[curve->size*4];
unsigned long output_len = curve->size*4;
- native_timing_start();
- int err = ecc_sign_hash((unsigned char *) data_data, data_size, result, &output_len, &ltc_prng, find_prng("yarrow"), &priv);
- native_timing_stop();
+ int err;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ err = ecc_sign_hash((unsigned char *) data_data, data_size, result, &output_len, &ltc_prng, find_prng("yarrow"), &priv);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
if (err != CRYPT_OK) {
throw_new(env, "java/security/GeneralSecurityException", error_to_string(err));
@@ -467,9 +493,12 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
jbyte *sig_data = (*env)->GetByteArrayElements(env, signature, NULL);
int result;
- native_timing_start();
- int err = ecc_verify_hash((unsigned char *) sig_data, sig_size, (unsigned char *) data_data, data_size, &result, &pub);
- native_timing_stop();
+ int err;
+ SIG_TRY(TIMEOUT) {
+ native_timing_start();
+ err = ecc_verify_hash((unsigned char *) sig_data, sig_size, (unsigned char *) data_data, data_size, &result, &pub);
+ native_timing_stop();
+ } SIG_CATCH_HANDLE(env);
if (err != CRYPT_OK) {
throw_new(env, "java/security/GeneralSecurityException", error_to_string(err));
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 7ff2826..1f82bb0 100644
--- a/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java
+++ b/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java
@@ -2,7 +2,6 @@ package cz.crcs.ectester.standalone;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junitpioneer.jupiter.StdIo;
@@ -91,9 +90,6 @@ public class AppTests {
@MethodSource("libs")
@StdIo()
public void defaultSuite(String libName, StdOut out) {
- // TODO: "Nettle" is very broken here for a weird reason.
- assumeFalse(libName.equals("Nettle"));
-
String[] args = buildCLIArgs(libName, "default");
if (libName.equals("Botan") || libName.equals("Crypto++")) {
args = buildCLIArgs(libName, "default", "--kpg-type", "ECDH");
@@ -124,9 +120,6 @@ public class AppTests {
@ParameterizedTest
@MethodSource("libs")
public void performanceSuite(String libName) {
- // TODO: "Nettle" is very broken here for a weird reason.
- assumeFalse(libName.equals("Nettle"));
-
String[] args = buildCLIArgs(libName, "performance");
if (libName.equals("Botan") || libName.equals("Crypto++")) {
args = buildCLIArgs(libName, "performance", "--kpg-type", "ECDH");
@@ -162,7 +155,6 @@ public class AppTests {
@ParameterizedTest
@MethodSource("libs")
- @Timeout(20)
public void miscSuite(String libName) {
String[] args = buildCLIArgs(libName, "miscellaneous", "-q");
if (libName.equals("Botan") || libName.equals("Crypto++")) {
@@ -173,11 +165,7 @@ public class AppTests {
@ParameterizedTest
@MethodSource("libs")
- @Timeout(20)
public void twistSuite(String libName) {
- // TODO: "Nettle" is very broken here for a weird reason.
- assumeFalse(libName.equals("Nettle"));
-
String[] args = buildCLIArgs(libName, "twist", "-q");
if (libName.equals("Botan") || libName.equals("Crypto++")) {
args = buildCLIArgs(libName, "twist", "--kpg-type", "ECDH", "-q");
@@ -187,11 +175,7 @@ public class AppTests {
@ParameterizedTest
@MethodSource("libs")
- @Timeout(20)
public void degenerateSuite(String libName) {
- // TODO: "Nettle" is very broken here for a weird reason.
- assumeFalse(libName.equals("Nettle"));
-
String[] args = buildCLIArgs(libName, "degenerate", "-q");
if (libName.equals("Botan") || libName.equals("Crypto++")) {
args = buildCLIArgs(libName, "degenerate", "--kpg-type", "ECDH", "-q");
@@ -201,7 +185,6 @@ public class AppTests {
@ParameterizedTest
@MethodSource("libs")
- @Timeout(20)
public void edgeCasesSuite(String libName) {
// TODO: Crypto++ and tomcrypt is broken here.
assumeFalse(libName.equals("Crypto++") || libName.equals("tomcrypt"));
@@ -213,9 +196,9 @@ public class AppTests {
ECTesterStandalone.main(args);
}
+ /*
@ParameterizedTest
@MethodSource("libs")
- @Timeout(20)
// TODO: This breaks the tests because the libs do all sorts of weird stuff here.
@Disabled
public void compositeSuite(String libName) {
@@ -228,10 +211,10 @@ public class AppTests {
}
ECTesterStandalone.main(args);
}
+ */
@ParameterizedTest
@MethodSource("libs")
- @Timeout(20)
public void cofactorSuite(String libName) {
String[] args = buildCLIArgs(libName, "cofactor", "-q");
if (libName.equals("Botan") || libName.equals("Crypto++")) {
@@ -240,9 +223,9 @@ public class AppTests {
ECTesterStandalone.main(args);
}
+ /*
@ParameterizedTest
@MethodSource("libs")
- @Timeout(20)
// TODO: This breaks the tests because the libs do all sorts of weird stuff here.
@Disabled
public void wrongSuite(String libName) {
@@ -255,14 +238,11 @@ public class AppTests {
}
ECTesterStandalone.main(args);
}
+ */
@ParameterizedTest
@MethodSource("libs")
- @Timeout(20)
public void invalidSuite(String libName) {
- // TODO: "Nettle" is very broken here for a weird reason.
- assumeFalse(libName.equals("Nettle"));
-
String[] args = buildCLIArgs(libName, "invalid", "-q");
if (libName.equals("Botan") || libName.equals("Crypto++")) {
args = buildCLIArgs(libName, "invalid", "--kpg-type", "ECDH", "-q");