aboutsummaryrefslogtreecommitdiff
path: root/standalone/src
diff options
context:
space:
mode:
authorquapka2024-06-21 16:31:37 +0200
committerquapka2024-06-21 16:31:37 +0200
commitada61982cc70a2c72a6fc765dc9b4a9c01202a27 (patch)
treed92bee42106e850d4da90ad7174ac609ca175eda /standalone/src
parentc051ef2ecfa92723d6dea675ac8c345be92cf165 (diff)
parentc112d3e49bbbbf33cc70d12d196e109543c19a3c (diff)
downloadECTester-ada61982cc70a2c72a6fc765dc9b4a9c01202a27.tar.gz
ECTester-ada61982cc70a2c72a6fc765dc9b4a9c01202a27.tar.zst
ECTester-ada61982cc70a2c72a6fc765dc9b4a9c01202a27.zip
Merge branch 'master' into build-with-nix
Diffstat (limited to 'standalone/src')
-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
43 files changed, 1529 insertions, 508 deletions
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java
index 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");