From 1ec0cd462865f06c673e54ed4556079d3a0917a6 Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 25 Apr 2024 17:08:37 +0200 Subject: Add XDH and EdDSA keygen. --- .../ectester/standalone/ECTesterStandalone.java | 58 ++++++++++++++++++---- .../standalone/consts/KeyPairGeneratorIdent.java | 9 ++++ 2 files changed, 57 insertions(+), 10 deletions(-) (limited to 'standalone/src/main') 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..bf9a9ef 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -37,11 +37,14 @@ 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.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.*; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.jcajce.interfaces.EdDSAPrivateKey; +import org.bouncycastle.jcajce.interfaces.EdDSAPublicKey; +import org.bouncycastle.jcajce.interfaces.XDHPrivateKey; +import org.bouncycastle.jcajce.interfaces.XDHPublicKey; import javax.crypto.KeyAgreement; import javax.crypto.SecretKey; @@ -55,8 +58,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; @@ -158,6 +160,8 @@ public class ECTesterStandalone { listIdents(); } else if (cli.isNext("ecdh")) { ecdh(); + } else if (cli.isNext("xdh")) { + xdh(); } else if (cli.isNext("ecdsa")) { ecdsa(); } else if (cli.isNext("generate")) { @@ -232,6 +236,11 @@ public class ECTesterStandalone { ParserOptions ecdh = new ParserOptions(new DefaultParser(), ecdhOpts, "Perform EC based KeyAgreement."); actions.put("ecdh", ecdh); + Options xdhOpts = new Options(); + xdhOpts.addOption(Option.builder("n").longOpt("amount").hasArg().argName("amount").optionalArg(false).desc("Do XDH [amount] times.").build()); + ParserOptions xdh = new ParserOptions(new DefaultParser(), xdhOpts, "Perform XDH (x25519/x448)."); + actions.put("xdh", xdh); + Options ecdsaOpts = new Options(); ecdsaOpts.addOption(bits); ecdsaOpts.addOption(namedCurve); @@ -512,6 +521,10 @@ public class ECTesterStandalone { } } + private void xdh() { + + } + /** * */ @@ -744,11 +757,36 @@ public class ECTesterStandalone { 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(); + String pub; + String priv; + if (pubkey instanceof ECPublicKey && privkey instanceof ECPrivateKey) { + ECPublicKey publicKey = (ECPublicKey) pubkey; + ECPrivateKey privateKey = (ECPrivateKey) privkey; + pub = ByteUtil.bytesToHex(ECUtil.toX962Uncompressed(publicKey.getW(), publicKey.getParams()), false); + priv = ByteUtil.bytesToHex(privateKey.getS().toByteArray(), false); + } else if (pubkey instanceof XECPublicKey && privkey instanceof XECPrivateKey) { + pub = ByteUtil.bytesToHex(((XECPublicKey) pubkey).getU().toByteArray(), false); + priv = ByteUtil.bytesToHex(((XECPrivateKey) privkey).getScalar().get(), false); + } else if (pubkey instanceof EdECPublicKey && privkey instanceof EdECPrivateKey) { + pub = ByteUtil.bytesToHex(((EdECPublicKey) pubkey).getPoint().getY().toByteArray(), false); + priv = ByteUtil.bytesToHex(((EdECPrivateKey) privkey).getBytes().get(), false); + } else if (pubkey instanceof XDHPublicKey && privkey instanceof XDHPrivateKey) { + // Special-case BouncyCastle XDH + pub = ByteUtil.bytesToHex(((XDHPublicKey) pubkey).getU().toByteArray(), false); + PrivateKeyInfo pkinfo = PrivateKeyInfo.getInstance(privkey.getEncoded()); + priv = ByteUtil.bytesToHex(ASN1OctetString.getInstance(pkinfo.getPrivateKey().getOctets()).getOctets(), false); + } else if (pubkey instanceof EdDSAPublicKey && privkey instanceof EdDSAPrivateKey) { + // Special-case BouncyCastle EdDSA + pub = ByteUtil.bytesToHex(((EdDSAPublicKey) pubkey).getPointEncoding(), false); + PrivateKeyInfo pkinfo = PrivateKeyInfo.getInstance(privkey.getEncoded()); + priv = ByteUtil.bytesToHex(ASN1OctetString.getInstance(pkinfo.getPrivateKey().getOctets()).getOctets(), false); + } else { + System.err.println(pubkey.getClass().getCanonicalName()); + System.err.println(privkey.getClass().getCanonicalName()); + break; + } out.printf("%d;%d;%s;%s%n", i, elapsed, pub, priv); } 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 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) { -- cgit v1.3.1 From 05bb80b365928e232416b2b0d4a7a915a00078e9 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 26 Apr 2024 23:35:53 +0200 Subject: Sort lists of items in standalone CLI. --- .../main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'standalone/src/main') 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 bf9a9ef..c5693e8 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -315,19 +315,19 @@ public class ECTesterStandalone { System.out.println(Colors.bold("\t\t- Supports native timing: ") + lib.getNativeTimingSupport().toString()); Set 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 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 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 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(); } -- cgit v1.3.1 From 8f9179da726be18ab883ac716296dbe2c411d805 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 26 Apr 2024 23:36:06 +0200 Subject: Add XDH and EdDSA idents --- .../crcs/ectester/standalone/consts/KeyAgreementIdent.java | 12 +++++++++++- .../cz/crcs/ectester/standalone/consts/SignatureIdent.java | 12 ++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) (limited to 'standalone/src/main') 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 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/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) { -- cgit v1.3.1 From 6a9f2181e9fa0fad8732261bb923b0c24b232747 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 27 Apr 2024 00:06:25 +0200 Subject: Add XDH to standalone CLI. --- .../java/cz/crcs/ectester/common/util/ECUtil.java | 54 ++++++++++++++++++--- .../ectester/standalone/ECTesterStandalone.java | 56 +++++----------------- 2 files changed, 61 insertions(+), 49 deletions(-) (limited to 'standalone/src/main') diff --git a/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java b/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java index f9be536..74fccc9 100644 --- a/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java +++ b/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java @@ -2,20 +2,22 @@ package cz.crcs.ectester.common.util; import cz.crcs.ectester.common.ec.*; import cz.crcs.ectester.data.EC_Store; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.signers.PlainDSAEncoding; import org.bouncycastle.crypto.signers.StandardDSAEncoding; +import org.bouncycastle.jcajce.interfaces.EdDSAPrivateKey; +import org.bouncycastle.jcajce.interfaces.EdDSAPublicKey; +import org.bouncycastle.jcajce.interfaces.XDHPrivateKey; +import org.bouncycastle.jcajce.interfaces.XDHPublicKey; import java.io.FileInputStream; import java.io.IOException; import java.math.BigInteger; import java.nio.charset.StandardCharsets; -import java.security.KeyPair; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.interfaces.ECKey; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; +import java.security.*; +import java.security.interfaces.*; import java.security.spec.*; import java.util.LinkedList; import java.util.List; @@ -456,6 +458,46 @@ public class ECUtil { return null; } + public static byte[] pubkeyToBytes(PublicKey pubkey) { + if (pubkey instanceof ECPublicKey) { + ECPublicKey ecPublicKey = (ECPublicKey) pubkey; + return ECUtil.toX962Uncompressed(ecPublicKey.getW(), ecPublicKey.getParams()); + } else if (pubkey instanceof XECPublicKey) { + XECPublicKey xedPublicKey = (XECPublicKey) pubkey; + return xedPublicKey.getU().toByteArray(); + } else if (pubkey instanceof EdECPublicKey) { + EdECPublicKey edECPublicKey = (EdECPublicKey) pubkey; + return edECPublicKey.getPoint().getY().toByteArray(); + } else if (pubkey instanceof XDHPublicKey) { + XDHPublicKey xdhPublicKey = (XDHPublicKey) pubkey; + return xdhPublicKey.getU().toByteArray(); + // Special-case BouncyCastle XDH + } else if (pubkey instanceof EdDSAPublicKey) { + EdDSAPublicKey edDSAPublicKey = (EdDSAPublicKey) pubkey; + // Special-case BouncyCastle EdDSA + return edDSAPublicKey.getPointEncoding(); + } + return null; + } + + public static byte[] privkeyToBytes(PrivateKey privkey) { + if (privkey instanceof ECPrivateKey) { + ECPrivateKey ecPrivateKey = (ECPrivateKey) privkey; + return ecPrivateKey.getS().toByteArray(); + } else if (privkey instanceof XECPrivateKey) { + XECPrivateKey xecPrivateKey = (XECPrivateKey) privkey; + return xecPrivateKey.getScalar().get(); + } else if (privkey instanceof EdECPrivateKey) { + EdECPrivateKey edECPrivateKey = (EdECPrivateKey) privkey; + return edECPrivateKey.getBytes().get(); + } else if (privkey instanceof XDHPrivateKey || privkey instanceof EdDSAPrivateKey) { + // Special-case BouncyCastle XDH and EdDSA + PrivateKeyInfo xpkinfo = PrivateKeyInfo.getInstance(privkey.getEncoded()); + return ASN1OctetString.getInstance(xpkinfo.getPrivateKey().getOctets()).getOctets(); + } + return null; + } + public static boolean equalKeyPairParameters(ECPrivateKey priv, ECPublicKey pub) { if (priv == null || pub == null) { return false; 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 c5693e8..2dc5040 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -62,6 +62,7 @@ import java.security.interfaces.*; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; +import java.security.spec.NamedParameterSpec; import java.util.*; import java.util.stream.Collectors; @@ -160,8 +161,6 @@ public class ECTesterStandalone { listIdents(); } else if (cli.isNext("ecdh")) { ecdh(); - } else if (cli.isNext("xdh")) { - xdh(); } else if (cli.isNext("ecdsa")) { ecdsa(); } else if (cli.isNext("generate")) { @@ -236,11 +235,6 @@ public class ECTesterStandalone { ParserOptions ecdh = new ParserOptions(new DefaultParser(), ecdhOpts, "Perform EC based KeyAgreement."); actions.put("ecdh", ecdh); - Options xdhOpts = new Options(); - xdhOpts.addOption(Option.builder("n").longOpt("amount").hasArg().argName("amount").optionalArg(false).desc("Do XDH [amount] times.").build()); - ParserOptions xdh = new ParserOptions(new DefaultParser(), xdhOpts, "Perform XDH (x25519/x448)."); - actions.put("xdh", xdh); - Options ecdsaOpts = new Options(); ecdsaOpts.addOption(bits); ecdsaOpts.addOption(namedCurve); @@ -467,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) { @@ -480,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(); @@ -510,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); } @@ -521,10 +515,6 @@ public class ECTesterStandalone { } } - private void xdh() { - - } - /** * */ @@ -759,30 +749,11 @@ public class ECTesterStandalone { } PublicKey pubkey = kp.getPublic(); PrivateKey privkey = kp.getPrivate(); - String pub; - String priv; - if (pubkey instanceof ECPublicKey && privkey instanceof ECPrivateKey) { - ECPublicKey publicKey = (ECPublicKey) pubkey; - ECPrivateKey privateKey = (ECPrivateKey) privkey; - pub = ByteUtil.bytesToHex(ECUtil.toX962Uncompressed(publicKey.getW(), publicKey.getParams()), false); - priv = ByteUtil.bytesToHex(privateKey.getS().toByteArray(), false); - } else if (pubkey instanceof XECPublicKey && privkey instanceof XECPrivateKey) { - pub = ByteUtil.bytesToHex(((XECPublicKey) pubkey).getU().toByteArray(), false); - priv = ByteUtil.bytesToHex(((XECPrivateKey) privkey).getScalar().get(), false); - } else if (pubkey instanceof EdECPublicKey && privkey instanceof EdECPrivateKey) { - pub = ByteUtil.bytesToHex(((EdECPublicKey) pubkey).getPoint().getY().toByteArray(), false); - priv = ByteUtil.bytesToHex(((EdECPrivateKey) privkey).getBytes().get(), false); - } else if (pubkey instanceof XDHPublicKey && privkey instanceof XDHPrivateKey) { - // Special-case BouncyCastle XDH - pub = ByteUtil.bytesToHex(((XDHPublicKey) pubkey).getU().toByteArray(), false); - PrivateKeyInfo pkinfo = PrivateKeyInfo.getInstance(privkey.getEncoded()); - priv = ByteUtil.bytesToHex(ASN1OctetString.getInstance(pkinfo.getPrivateKey().getOctets()).getOctets(), false); - } else if (pubkey instanceof EdDSAPublicKey && privkey instanceof EdDSAPrivateKey) { - // Special-case BouncyCastle EdDSA - pub = ByteUtil.bytesToHex(((EdDSAPublicKey) pubkey).getPointEncoding(), false); - PrivateKeyInfo pkinfo = PrivateKeyInfo.getInstance(privkey.getEncoded()); - priv = ByteUtil.bytesToHex(ASN1OctetString.getInstance(pkinfo.getPrivateKey().getOctets()).getOctets(), false); - } else { + 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; @@ -801,7 +772,6 @@ 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; - switch (cli.getArg(0).toLowerCase()) { case "test-vectors": suite = new StandaloneTestVectorSuite(writer, cfg, cli); @@ -836,9 +806,9 @@ public class ECTesterStandalone { case "performance": suite = new StandalonePerformanceSuite(writer, cfg, cli); break; - case "default": default: suite = new StandaloneDefaultSuite(writer, cfg, cli); + break; } suite.run(); -- cgit v1.3.1 From e5e8072363c53b155df42238e049d7929b2380f1 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 27 Apr 2024 00:10:57 +0200 Subject: Add EdDSA to standalone CLI. --- .../ectester/standalone/ECTesterStandalone.java | 53 ++++++++++------------ 1 file changed, 25 insertions(+), 28 deletions(-) (limited to 'standalone/src/main') 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 2dc5040..ab7e45b 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -39,12 +39,6 @@ import cz.crcs.ectester.standalone.libs.*; import cz.crcs.ectester.standalone.output.FileTestWriter; import cz.crcs.ectester.standalone.test.suites.*; import org.apache.commons.cli.*; -import org.bouncycastle.asn1.ASN1OctetString; -import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.jcajce.interfaces.EdDSAPrivateKey; -import org.bouncycastle.jcajce.interfaces.EdDSAPublicKey; -import org.bouncycastle.jcajce.interfaces.XDHPrivateKey; -import org.bouncycastle.jcajce.interfaces.XDHPublicKey; import javax.crypto.KeyAgreement; import javax.crypto.SecretKey; @@ -62,7 +56,6 @@ import java.security.interfaces.*; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; -import java.security.spec.NamedParameterSpec; import java.util.*; import java.util.stream.Collectors; @@ -608,17 +601,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(); } } @@ -629,10 +622,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(); } } @@ -656,27 +649,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); } -- cgit v1.3.1 From d11222dc25c2a5363b451dd9dbc81482530c9107 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 30 Apr 2024 17:20:02 +0200 Subject: Add way of handling SIGSEGV and SIGABRT in native code. --- .../ectester/standalone/ECTesterStandalone.java | 16 +++- .../crcs/ectester/standalone/libs/jni/SigInfo.java | 80 +++++++++++++++++++ .../standalone/libs/jni/SignalException.java | 18 +++++ .../standalone/libs/jni/TimeoutException.java | 11 +++ .../cz/crcs/ectester/standalone/libs/jni/Makefile | 14 +++- .../crcs/ectester/standalone/libs/jni/c_signals.c | 93 ++++++++++++++++++++++ .../crcs/ectester/standalone/libs/jni/c_signals.h | 58 ++++++++++++++ .../cz/crcs/ectester/standalone/libs/jni/gcrypt.c | 7 ++ 8 files changed, 293 insertions(+), 4 deletions(-) create mode 100644 standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/SigInfo.java create mode 100644 standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/SignalException.java create mode 100644 standalone/src/main/java/cz/crcs/ectester/standalone/libs/jni/TimeoutException.java create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_signals.c create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_signals.h (limited to 'standalone/src/main') 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 ab7e45b..82c2362 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -36,6 +36,8 @@ 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.test.suites.*; import org.apache.commons.cli.*; @@ -103,6 +105,9 @@ public class ECTesterStandalone { if (!System.getProperty("os.name").startsWith("Windows")) { FileUtil.writeNewer(LIB_RESOURCE_DIR + "lib_timing.so", reqs.resolve("lib_timing.so")); System.load(reqs.resolve("lib_timing.so").toString()); + + FileUtil.writeNewer(LIB_RESOURCE_DIR + "lib_signals.so", reqs.resolve("lib_signals.so")); + System.load(reqs.resolve("lib_signals.so").toString()); } List libObjects = new LinkedList<>(); @@ -739,7 +744,16 @@ 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(); 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/resources/cz/crcs/ectester/standalone/libs/jni/Makefile b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile index 1fa16c0..aef1bd3 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,9 @@ c_utils.o: c_utils.c lib_timing.so: c_timing.c $(CC) -o $@ -shared $(CFLAGS) -Wl,-soname,lib_timing.so $< +lib_signals.so: c_signals.c + $(CC) -o $@ -shared $(CFLAGS) -Wl,-soname,lib_signals.so $< + cpp_utils.o: cpp_utils.cpp $(CXX) $(CXXFLAGS) -c $< @@ -98,8 +106,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_signals.so + $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell libgcrypt-config --libs) -l:lib_timing.so -l:lib_signals.so gcrypt.o: gcrypt.c $(CC) $(shell libgcrypt-config --cflags) $(CFLAGS) -c $< 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..f4adaa5 --- /dev/null +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_signals.c @@ -0,0 +1,93 @@ +#include "c_utils.h" +#include "c_signals.h" + +#if __linux || __posix + +#include +#include +#include + +// TODO: Handle alarms properly. +// Create a new thread, make it sleep, then send alarm to the main thread. + +static siginfo_t last_siginfo; +static bool initialized = false; +static bool caught = false; +static bool timedout = false; +static jmp_buf *target = NULL; + +void handler(int signo, siginfo_t *info, void *context) { + last_siginfo = *info; + caught = true; + longjmp(*target, 1); +} + +void alarm_handler(int signo) { + timedout = true; +} + +static jmp_buf buf; + +jmp_buf *get_jmpbuf() { + return &buf; +} + +static struct sigaction old_segv; +static struct sigaction old_abrt; +static struct sigaction old_alrm; + +void init_signals(jmp_buf *env) { + 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; +} + + +void deinit_signals() { + sigaction(SIGSEGV, NULL, &old_segv); + sigaction(SIGABRT, NULL, &old_abrt); + sigaction(SIGALRM, NULL, &old_alrm); + + target = NULL; + initialized = false; +} + +bool get_timedout() { + return timedout; +} + +jobject get_siginfo(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, "", "(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..95fc693 --- /dev/null +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_signals.h @@ -0,0 +1,58 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * + */ +void init_signals(jmp_buf *env); + +/** + * + */ +jmp_buf *get_jmpbuf(); + +/** + * + */ +void deinit_signals(); + +/** + * + */ +bool get_timedout(); + +/** + * + */ +jobject get_siginfo(JNIEnv *env); + + +#define SIG_TRY() init_signals(get_jmpbuf()); \ + if (!setjmp(*get_jmpbuf())) +#define SIG_CATCH() deinit_signals(); +#define SIG_HANDLE(env) do { \ + jobject siginfo = get_siginfo(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, "", "(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()) { \ + jclass timeoutexception_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/TimeoutException"); \ + (*env)->ThrowNew(env, timeoutexception_class, "Operation timed out."); \ + } \ +} while (0) + + + +#ifdef __cplusplus +} +#endif 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..3df7656 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 @@ -276,6 +277,12 @@ static jobject generate_from_sexp(JNIEnv *env, gcry_sexp_t gen_sexp) { gcry_error_t err = gcry_pk_genkey(&key_sexp, gen_sexp); native_timing_stop(); + SIG_TRY() { + //raise(SIGSEGV); + } SIG_CATCH(); + + SIG_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)); goto release_sexp; -- cgit v1.3.1 From 7e551f5cd6e28787a15287b1efe3630a4c32c826 Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 6 May 2024 17:27:25 +0200 Subject: Allow for timeouts in native code. --- .../cz/crcs/ectester/standalone/libs/jni/Makefile | 4 +-- .../crcs/ectester/standalone/libs/jni/c_signals.c | 40 +++++++++++++++++----- .../crcs/ectester/standalone/libs/jni/c_signals.h | 9 ++--- .../cz/crcs/ectester/standalone/libs/jni/gcrypt.c | 6 ---- 4 files changed, 39 insertions(+), 20 deletions(-) (limited to 'standalone/src/main') 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 aef1bd3..93e1539 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 @@ -74,7 +74,7 @@ lib_timing.so: c_timing.c $(CC) -o $@ -shared $(CFLAGS) -Wl,-soname,lib_timing.so $< lib_signals.so: c_signals.c - $(CC) -o $@ -shared $(CFLAGS) -Wl,-soname,lib_signals.so $< + $(CC) -o $@ -shared $(CFLAGS) -pthread -lpthread -Wl,-soname,lib_signals.so $< cpp_utils.o: cpp_utils.cpp $(CXX) $(CXXFLAGS) -c $< @@ -107,7 +107,7 @@ boringssl.o: boringssl.c gcrypt: gcrypt_provider.so gcrypt_provider.so: gcrypt.o c_utils.o | lib_timing.so lib_signals.so - $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell libgcrypt-config --libs) -l:lib_timing.so -l:lib_signals.so + $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. -pthread -lpthread $(shell libgcrypt-config --libs) -l:lib_timing.so -l:lib_signals.so gcrypt.o: gcrypt.c $(CC) $(shell libgcrypt-config --cflags) $(CFLAGS) -c $< 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 index f4adaa5..a1ea9f1 100644 --- 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 @@ -6,29 +6,38 @@ #include #include #include - -// TODO: Handle alarms properly. -// Create a new thread, make it sleep, then send alarm to the main thread. +#include +#include static siginfo_t last_siginfo; static bool initialized = false; static bool caught = false; static bool timedout = false; -static jmp_buf *target = NULL; +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; - longjmp(*target, 1); + siglongjmp(*target, 1); } void alarm_handler(int signo) { + //printf("Alarm\n"); timedout = true; + siglongjmp(*target, 1); } -static jmp_buf buf; -jmp_buf *get_jmpbuf() { +sigjmp_buf *get_jmpbuf() { return &buf; } @@ -36,7 +45,14 @@ static struct sigaction old_segv; static struct sigaction old_abrt; static struct sigaction old_alrm; -void init_signals(jmp_buf *env) { +void *timer(void *arg) { + sleep(ta.timeout); + pthread_kill(ta.main_thread, SIGALRM); + return NULL; +} + +void init_signals(sigjmp_buf *env, unsigned int timeout) { + //printf("Initializing signals!\n"); struct sigaction action; action.sa_sigaction = handler; sigemptyset(&action.sa_mask); @@ -55,10 +71,18 @@ void init_signals(jmp_buf *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() { + //printf("Deinitializing signals!\n"); + pthread_cancel(timer_thread); + sigaction(SIGSEGV, NULL, &old_segv); sigaction(SIGABRT, NULL, &old_abrt); sigaction(SIGALRM, NULL, &old_alrm); 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 index 95fc693..dec7223 100644 --- 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 @@ -2,6 +2,7 @@ #include #include +#include #ifdef __cplusplus extern "C" @@ -11,12 +12,12 @@ extern "C" /** * */ -void init_signals(jmp_buf *env); +void init_signals(jmp_buf *env, unsigned int timeout); /** * */ -jmp_buf *get_jmpbuf(); +sigjmp_buf *get_jmpbuf(); /** * @@ -34,8 +35,8 @@ bool get_timedout(); jobject get_siginfo(JNIEnv *env); -#define SIG_TRY() init_signals(get_jmpbuf()); \ - if (!setjmp(*get_jmpbuf())) +#define SIG_TRY(timeout) init_signals(get_jmpbuf(), timeout); \ + if (!sigsetjmp(*get_jmpbuf(), 1)) #define SIG_CATCH() deinit_signals(); #define SIG_HANDLE(env) do { \ jobject siginfo = get_siginfo(env); \ 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 3df7656..3ddaef4 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 @@ -277,12 +277,6 @@ static jobject generate_from_sexp(JNIEnv *env, gcry_sexp_t gen_sexp) { gcry_error_t err = gcry_pk_genkey(&key_sexp, gen_sexp); native_timing_stop(); - SIG_TRY() { - //raise(SIGSEGV); - } SIG_CATCH(); - - SIG_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)); goto release_sexp; -- cgit v1.3.1 From ba84b595ed8c0ae34b8c3540414327f8db3e4a62 Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 6 May 2024 18:12:15 +0200 Subject: Add lib_signals to all shims. --- .../cz/crcs/ectester/standalone/libs/jni/Makefile | 34 +++++++++++----------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'standalone/src/main') 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 93e1539..dca660f 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 @@ -83,7 +83,7 @@ cpp_utils.o: cpp_utils.cpp # OpenSSL shim openssl: openssl_provider.so -openssl_provider.so: openssl.o c_utils.o | lib_timing.so +openssl_provider.so: openssl.o c_utils.o | lib_timing.so lib_signals.so $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs openssl) -l:lib_timing.so openssl.o: openssl.c @@ -96,8 +96,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_signals.so lib_boringssl.so + $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_boringssl.so -l:lib_timing.so -l:lib_signals.so boringssl.o: boringssl.c $(CC) -I$(PROJECT_ROOT_PATH)/ext/boringssl/include/ $(CFLAGS) -c $< @@ -116,8 +116,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_signals.so + $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. -ltommath $(shell pkg-config --libs libtomcrypt) -l:lib_timing.so -l:lib_signals.so tomcrypt.o: tomcrypt.c $(CC) -DLTM_DESC $(shell pkg-config --cflags libtomcrypt) $(CFLAGS) -c $< @@ -126,8 +126,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_signals.so + $(CXX) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs botan-2) -l:lib_timing.so -l:lib_signals.so botan.o: botan.cpp $(CXX) $(shell pkg-config --cflags botan-2) $(CXXFLAGS) -c $< @@ -140,8 +140,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_signals.so + $(CXX) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs $(CRYPTOPP_NAME)) -l:lib_timing.so -l:lib_signals.so cryptopp.o: cryptopp.cpp $(CXX) $(shell pkg-config --cflags $(CRYPTOPP_NAME)) $(CXXFLAGS) -c $< @@ -153,8 +153,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_signals.so lib_mbedtls.so + $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_mbedtls.so -l:lib_timing.so -l:lib_signals.so mbedtls.o: mbedtls.c $(CC) -I$(PROJECT_ROOT_PATH)/ext/mbedtls/build/include/ $(CFLAGS) -c $< @@ -166,8 +166,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_signals.so lib_ippcp.so + $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_ippcp.so -l:lib_timing.so -l:lib_signals.so ippcp.o: ippcp.c $(CC) -I$(PROJECT_ROOT_PATH)/ext/ipp-crypto/build/.build/RELEASE/include/ $(CFLAGS) -c $< @@ -176,8 +176,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_signals.so + $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs nettle) -l:lib_timing.so -l:lib_signals.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 $< @@ -189,8 +189,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_signals.so lib_libressl.so + $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_libressl.so -l:lib_timing.so -l:lib_signals.so libressl.o: libressl.c $(CC) -I$(PROJECT_ROOT_PATH)/ext/libressl/build/include/ $(CFLAGS) -c $< -- cgit v1.3.1 From 5c823806439086c486bbddcb1cf79bc17247e24c Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 6 May 2024 19:31:48 +0200 Subject: Add signal handling to BoringSSL. --- .../ectester/standalone/output/TextTestWriter.java | 2 +- .../crcs/ectester/standalone/libs/jni/boringssl.c | 37 +++++++++++++++------- .../crcs/ectester/standalone/libs/jni/c_signals.h | 5 ++- 3 files changed, 30 insertions(+), 14 deletions(-) (limited to 'standalone/src/main') 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..36ff1af 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().name()).append(" (").append(standaloneSuite.getLibrary().getProvider().getName()).append(")").append(System.lineSeparator()); return sb.toString(); } return ""; 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..6878549 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 @@ -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."); @@ -430,9 +434,12 @@ 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 = 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."); @@ -466,9 +473,12 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig 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) { @@ -508,9 +518,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.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_signals.h index dec7223..4420a4d 100644 --- 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 @@ -9,6 +9,8 @@ extern "C" { #endif +#define TIMEOUT 5 + /** * */ @@ -51,7 +53,8 @@ jobject get_siginfo(JNIEnv *env); (*env)->ThrowNew(env, timeoutexception_class, "Operation timed out."); \ } \ } while (0) - +#define SIG_CATCH_HANDLE(env) SIG_CATCH(); \ + SIG_HANDLE(env) #ifdef __cplusplus -- cgit v1.3.1 From f8ca335dc6b5c42cd124fca1704c715771d8128c Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 6 May 2024 19:49:11 +0200 Subject: Output full library name in machine-readable test reports. --- .../main/java/cz/crcs/ectester/standalone/libs/ProviderECLibrary.java | 4 ++++ .../main/java/cz/crcs/ectester/standalone/output/TextTestWriter.java | 2 +- .../main/java/cz/crcs/ectester/standalone/output/XMLTestWriter.java | 2 +- .../main/java/cz/crcs/ectester/standalone/output/YAMLTestWriter.java | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) (limited to 'standalone/src/main') 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/output/TextTestWriter.java b/standalone/src/main/java/cz/crcs/ectester/standalone/output/TextTestWriter.java index 36ff1af..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(" (").append(standaloneSuite.getLibrary().getProvider().getName()).append(")").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 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; -- cgit v1.3.1 From b76b401cf1131cb19764dd6cc88c104b85fb8f1a Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 7 May 2024 10:47:02 +0200 Subject: Add signal handling to Crypto++. --- .../crcs/ectester/standalone/libs/jni/c_signals.h | 17 +++++ .../crcs/ectester/standalone/libs/jni/cryptopp.cpp | 79 +++++++++++++--------- .../java/cz/crcs/ectester/standalone/AppTests.java | 8 --- 3 files changed, 63 insertions(+), 41 deletions(-) (limited to 'standalone/src/main') 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 index 4420a4d..466628a 100644 --- 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 @@ -40,6 +40,22 @@ jobject get_siginfo(JNIEnv *env); #define SIG_TRY(timeout) init_signals(get_jmpbuf(), timeout); \ if (!sigsetjmp(*get_jmpbuf(), 1)) #define SIG_CATCH() deinit_signals(); +#define SIG_DEINIT() deinit_signals(); +#ifdef __cplusplus +#define SIG_HANDLE(env) do { \ + jobject siginfo = get_siginfo(env); \ + if (siginfo != NULL) { \ + jclass sigexception_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/SignalException"); \ + jmethodID new_sigexception = env->GetMethodID(sigexception_class, "", "(Lcz/crcs/ectester/standalone/libs/jni/SigInfo;)V"); \ + jobject sigexception = env->NewObject(sigexception_class, new_sigexception, siginfo); \ + env->Throw((jthrowable) sigexception); \ + } \ + if (get_timedout()) { \ + jclass timeoutexception_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/TimeoutException"); \ + env->ThrowNew(timeoutexception_class, "Operation timed out."); \ + } \ +} while (0) +#else #define SIG_HANDLE(env) do { \ jobject siginfo = get_siginfo(env); \ if (siginfo != NULL) { \ @@ -53,6 +69,7 @@ jobject get_siginfo(JNIEnv *env); (*env)->ThrowNew(env, timeoutexception_class, "Operation timed out."); \ } \ } while (0) +#endif #define SIG_CATCH_HANDLE(env) SIG_CATCH(); \ SIG_HANDLE(env) 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..e5deedb 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,7 @@ using CryptoPP::Integer; #include "cpp_utils.hpp" #include "c_timing.h" +#include "c_signals.h" /* * Crypto++: @@ -504,14 +505,17 @@ template jobject generate_from_group(JNIEnv *env, DL_GroupParameters_ typename ECDH::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 +591,34 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey bool success; std::unique_ptr secret; - try { - std::unique_ptr> ecp_group = fp_group_from_params(env, params); - if (ecp_group == nullptr) { - std::unique_ptr> ec2n_group = f2m_group_from_params(env, params); + SIG_TRY(TIMEOUT) { + try { + std::unique_ptr> ecp_group = fp_group_from_params(env, params); + if (ecp_group == nullptr) { + std::unique_ptr> ec2n_group = f2m_group_from_params(env, params); - ECDH::Domain dh_agreement(*ec2n_group); + ECDH::Domain dh_agreement(*ec2n_group); - secret = std::make_unique(dh_agreement.AgreedValueLength()); - native_timing_start(); - success = dh_agreement.Agree(*secret, private_key, public_key); - native_timing_stop(); + secret = std::make_unique(dh_agreement.AgreedValueLength()); + native_timing_start(); + success = dh_agreement.Agree(*secret, private_key, public_key); + native_timing_stop(); - } else { - ECDH::Domain dh_agreement(*ecp_group); + } else { + ECDH::Domain dh_agreement(*ecp_group); - secret = std::make_unique(dh_agreement.AgreedValueLength()); - native_timing_start(); - success = dh_agreement.Agree(*secret, private_key, public_key); - native_timing_stop(); + secret = std::make_unique(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 +649,12 @@ jbyteArray sign_message(JNIEnv *env, DL_GroupParameters_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 +750,12 @@ jboolean verify_message(JNIEnv *env, DL_GroupParameters_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/test/java/cz/crcs/ectester/standalone/AppTests.java b/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java index 7ff2826..8802bb4 100644 --- a/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java +++ b/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java @@ -162,7 +162,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,7 +172,6 @@ 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")); @@ -187,7 +185,6 @@ 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")); @@ -201,7 +198,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")); @@ -215,7 +211,6 @@ public class AppTests { @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) { @@ -231,7 +226,6 @@ public class AppTests { @ParameterizedTest @MethodSource("libs") - @Timeout(20) public void cofactorSuite(String libName) { String[] args = buildCLIArgs(libName, "cofactor", "-q"); if (libName.equals("Botan") || libName.equals("Crypto++")) { @@ -242,7 +236,6 @@ public class AppTests { @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) { @@ -258,7 +251,6 @@ public class AppTests { @ParameterizedTest @MethodSource("libs") - @Timeout(20) public void invalidSuite(String libName) { // TODO: "Nettle" is very broken here for a weird reason. assumeFalse(libName.equals("Nettle")); -- cgit v1.3.1 From a765087f0fb9d21eb26780a187dbca23e9267376 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 7 May 2024 15:43:18 +0200 Subject: Fix signal restoration in signal handling. --- .../main/resources/cz/crcs/ectester/standalone/libs/jni/c_signals.c | 6 +++--- standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'standalone/src/main') 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 index a1ea9f1..dd08bb8 100644 --- 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 @@ -83,9 +83,9 @@ void deinit_signals() { //printf("Deinitializing signals!\n"); pthread_cancel(timer_thread); - sigaction(SIGSEGV, NULL, &old_segv); - sigaction(SIGABRT, NULL, &old_abrt); - sigaction(SIGALRM, NULL, &old_alrm); + sigaction(SIGSEGV, &old_segv, NULL); + sigaction(SIGABRT, &old_abrt, NULL); + sigaction(SIGALRM, &old_alrm, NULL); target = NULL; initialized = false; 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 8802bb4..c94824c 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; -- cgit v1.3.1 From 910ccecc91097616e407ed85bba91eae80309174 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 7 May 2024 16:17:32 +0200 Subject: Disable signal handling in Crypto++. --- .../main/resources/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'standalone/src/main') 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 e5deedb..3590ef2 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 @@ -72,6 +72,10 @@ using CryptoPP::Integer; #include "cpp_utils.hpp" #include "c_timing.h" #include "c_signals.h" +#define SIG_TRY(x) +#define SIG_CATCH_HANDLE(x) +#define SIG_CATCH() +#define SIG_DEINIT() /* * Crypto++: -- cgit v1.3.1 From 0f26779b0e94a46697f11b5f6262495ec412434c Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 7 May 2024 16:25:04 +0200 Subject: Add signal handling to tomcrypt. --- .../crcs/ectester/standalone/libs/jni/tomcrypt.c | 37 +++++++++++++++------- 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'standalone/src/main') 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..9593e9b 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 @@ -232,9 +233,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(<c_prng, find_prng("yarrow"), &key, curve); - native_timing_stop(); + int err; + SIG_TRY(TIMEOUT) { + native_timing_start(); + err = ecc_make_key_ex(<c_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 +385,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 +432,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, <c_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, <c_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 +477,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)); -- cgit v1.3.1 From 568d704359aab7435c92e6a71713ed89564dcef8 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 7 May 2024 16:29:51 +0200 Subject: Add signal handling to OpenSSL. --- .../cz/crcs/ectester/standalone/libs/jni/openssl.c | 38 +++++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) (limited to 'standalone/src/main') 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..fc02e9d 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 @@ -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."); @@ -488,9 +492,12 @@ 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."); @@ -524,9 +531,12 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig 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) { @@ -566,9 +576,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) { -- cgit v1.3.1 From bcd5077163d34e34d490f26875772fa62a4ee068 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 7 May 2024 16:31:54 +0200 Subject: Add signal handling to Nettle. --- .../cz/crcs/ectester/standalone/libs/jni/nettle.c | 36 ++++++++++++++-------- 1 file changed, 24 insertions(+), 12 deletions(-) (limited to 'standalone/src/main') 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..48b8f26 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 @@ -150,9 +151,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); @@ -311,9 +315,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); @@ -461,9 +467,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 +523,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); -- cgit v1.3.1 From aeaeef42697153a5b1cb9b0b5a64f9495af83157 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 7 May 2024 16:46:49 +0200 Subject: Fix OpenSSL build with signals. --- .../src/main/resources/cz/crcs/ectester/standalone/libs/jni/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'standalone/src/main') 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 dca660f..2354194 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 @@ -84,7 +84,7 @@ cpp_utils.o: cpp_utils.cpp openssl: openssl_provider.so openssl_provider.so: openssl.o c_utils.o | lib_timing.so lib_signals.so - $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs openssl) -l:lib_timing.so + $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs openssl) -l:lib_timing.so -l:lib_signals.so openssl.o: openssl.c $(CC) $(shell pkg-config --cflags openssl) $(CFLAGS) -c $< -- cgit v1.3.1 From 757621b3240482194f66146089dba960eeb5837c Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 7 May 2024 17:10:24 +0200 Subject: Add signal handling to mbedTLS. --- .../cz/crcs/ectester/standalone/libs/jni/mbedtls.c | 34 ++++++++++++++-------- 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'standalone/src/main') 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 @@ -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) { -- cgit v1.3.1 From 8454c5781dd0b2ab92666c2f3d2a2bfff102de01 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 7 May 2024 17:12:04 +0200 Subject: Add signal handling to LibreSSL. --- .../crcs/ectester/standalone/libs/jni/libressl.c | 38 +++++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) (limited to 'standalone/src/main') 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..7d50836 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 @@ -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."); @@ -453,9 +457,12 @@ 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."); @@ -489,9 +496,12 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig 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) { @@ -531,9 +541,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) { -- cgit v1.3.1 From e3dea615dbdf1170d304f638ab46f51115ce40be Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 7 May 2024 17:14:55 +0200 Subject: Add signal handling to ipp-cp. --- .../cz/crcs/ectester/standalone/libs/jni/ippcp.c | 70 +++++++++++++--------- 1 file changed, 43 insertions(+), 27 deletions(-) (limited to 'standalone/src/main') 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 #include @@ -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); -- cgit v1.3.1 From ca1be45c3e39a3d667b0d5a7023958487c8d55a2 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 7 May 2024 17:16:25 +0200 Subject: Add signal handling to gcrypt. --- .../cz/crcs/ectester/standalone/libs/jni/gcrypt.c | 37 +++++++++++++++------- 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'standalone/src/main') 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 3ddaef4..705a873 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 @@ -273,9 +273,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)); @@ -461,9 +464,12 @@ 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)); @@ -573,9 +579,13 @@ 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)); goto release_init; @@ -628,9 +638,12 @@ 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) { -- cgit v1.3.1 From 2b80f0abca83172e586ca192e16db00b3951226a Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 7 May 2024 17:53:43 +0200 Subject: Attempt to enable signal handling for Cpp, fail. --- .../ectester/standalone/ECTesterStandalone.java | 6 +- .../cz/crcs/ectester/standalone/libs/jni/Makefile | 47 ++++---- .../crcs/ectester/standalone/libs/jni/c_signals.h | 50 ++------- .../ectester/standalone/libs/jni/cpp_signals.cpp | 122 +++++++++++++++++++++ .../ectester/standalone/libs/jni/cpp_signals.hpp | 59 ++++++++++ .../crcs/ectester/standalone/libs/jni/cryptopp.cpp | 7 +- 6 files changed, 228 insertions(+), 63 deletions(-) create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cpp_signals.cpp create mode 100644 standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cpp_signals.hpp (limited to 'standalone/src/main') 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 82c2362..6ef1be7 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -106,8 +106,10 @@ public class ECTesterStandalone { FileUtil.writeNewer(LIB_RESOURCE_DIR + "lib_timing.so", reqs.resolve("lib_timing.so")); System.load(reqs.resolve("lib_timing.so").toString()); - FileUtil.writeNewer(LIB_RESOURCE_DIR + "lib_signals.so", reqs.resolve("lib_signals.so")); - System.load(reqs.resolve("lib_signals.so").toString()); + FileUtil.writeNewer(LIB_RESOURCE_DIR + "lib_csignals.so", reqs.resolve("lib_csignals.so")); + System.load(reqs.resolve("lib_csignals.so").toString()); + FileUtil.writeNewer(LIB_RESOURCE_DIR + "lib_cppsignals.so", reqs.resolve("lib_cppsignals.so")); + System.load(reqs.resolve("lib_cppsignals.so").toString()); } List libObjects = new LinkedList<>(); 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 2354194..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 @@ -73,8 +73,11 @@ c_utils.o: c_utils.c lib_timing.so: c_timing.c $(CC) -o $@ -shared $(CFLAGS) -Wl,-soname,lib_timing.so $< -lib_signals.so: c_signals.c - $(CC) -o $@ -shared $(CFLAGS) -pthread -lpthread -Wl,-soname,lib_signals.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 $< @@ -83,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 lib_signals.so - $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs openssl) -l:lib_timing.so -l:lib_signals.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 $< @@ -96,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_signals.so lib_boringssl.so - $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_boringssl.so -l:lib_timing.so -l:lib_signals.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 $< @@ -106,8 +109,8 @@ boringssl.o: boringssl.c # libgcrypt shim gcrypt: gcrypt_provider.so -gcrypt_provider.so: gcrypt.o c_utils.o | lib_timing.so lib_signals.so - $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. -pthread -lpthread $(shell libgcrypt-config --libs) -l:lib_timing.so -l:lib_signals.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 $< @@ -116,8 +119,8 @@ gcrypt.o: gcrypt.c # Libtomcrypt shim tomcrypt: tomcrypt_provider.so -tomcrypt_provider.so: tomcrypt.o c_utils.o | lib_timing.so lib_signals.so - $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. -ltommath $(shell pkg-config --libs libtomcrypt) -l:lib_timing.so -l:lib_signals.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 $< @@ -126,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 lib_signals.so - $(CXX) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs botan-2) -l:lib_timing.so -l:lib_signals.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 $< @@ -140,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 lib_signals.so - $(CXX) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs $(CRYPTOPP_NAME)) -l:lib_timing.so -l:lib_signals.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 $< @@ -153,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_signals.so lib_mbedtls.so - $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_mbedtls.so -l:lib_timing.so -l:lib_signals.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 $< @@ -166,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_signals.so lib_ippcp.so - $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_ippcp.so -l:lib_timing.so -l:lib_signals.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 $< @@ -176,8 +179,8 @@ ippcp.o: ippcp.c # Nettle shim nettle: nettle_provider.so -nettle_provider.so: nettle.o c_utils.o | lib_timing.so lib_signals.so - $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. $(shell pkg-config --libs nettle) -l:lib_timing.so -l:lib_signals.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 $< @@ -189,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_signals.so lib_libressl.so - $(CC) $(LFLAGS) -o $@ -Wl,-rpath,'$$ORIGIN/lib' $^ -L. lib_libressl.so -l:lib_timing.so -l:lib_signals.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/c_signals.h b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/c_signals.h index 466628a..3f3c473 100644 --- 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 @@ -4,11 +4,6 @@ #include #include -#ifdef __cplusplus -extern "C" -{ -#endif - #define TIMEOUT 5 /** @@ -41,39 +36,18 @@ jobject get_siginfo(JNIEnv *env); if (!sigsetjmp(*get_jmpbuf(), 1)) #define SIG_CATCH() deinit_signals(); #define SIG_DEINIT() deinit_signals(); -#ifdef __cplusplus -#define SIG_HANDLE(env) do { \ - jobject siginfo = get_siginfo(env); \ - if (siginfo != NULL) { \ - jclass sigexception_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/SignalException"); \ - jmethodID new_sigexception = env->GetMethodID(sigexception_class, "", "(Lcz/crcs/ectester/standalone/libs/jni/SigInfo;)V"); \ - jobject sigexception = env->NewObject(sigexception_class, new_sigexception, siginfo); \ - env->Throw((jthrowable) sigexception); \ - } \ - if (get_timedout()) { \ - jclass timeoutexception_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/TimeoutException"); \ - env->ThrowNew(timeoutexception_class, "Operation timed out."); \ - } \ -} while (0) -#else #define SIG_HANDLE(env) do { \ - jobject siginfo = get_siginfo(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, "", "(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()) { \ - jclass timeoutexception_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/TimeoutException"); \ - (*env)->ThrowNew(env, timeoutexception_class, "Operation timed out."); \ - } \ -} while (0) -#endif + jobject siginfo = get_siginfo(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, "", "(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()) { \ + 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) - - -#ifdef __cplusplus -} -#endif 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..75bc17c --- /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 +#include +#include +#include +#include + +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() { + 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(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() { + //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() { + return timedout; +} + +jobject get_siginfo(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, "", "(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..b926656 --- /dev/null +++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/cpp_signals.hpp @@ -0,0 +1,59 @@ +#pragma once + +#include +#include +#include + +#define TIMEOUT 5 + +extern "C" +{ + +/** + * + */ +void init_signals(jmp_buf *env, unsigned int timeout); + +/** + * + */ +sigjmp_buf *get_jmpbuf(); + +/** + * + */ +void deinit_signals(); + +/** + * + */ +bool get_timedout(); + +/** + * + */ +jobject get_siginfo(JNIEnv *env); + + +#define SIG_TRY(timeout) init_signals(get_jmpbuf(), timeout); \ + if (!sigsetjmp(*get_jmpbuf(), 1)) +#define SIG_CATCH() deinit_signals(); +#define SIG_DEINIT() deinit_signals(); +#define SIG_HANDLE(env) do { \ + jobject siginfo = get_siginfo(env); \ + if (siginfo != NULL) { \ + jclass sigexception_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/SignalException"); \ + jmethodID new_sigexception = env->GetMethodID(sigexception_class, "", "(Lcz/crcs/ectester/standalone/libs/jni/SigInfo;)V"); \ + jobject sigexception = env->NewObject(sigexception_class, new_sigexception, siginfo); \ + env->Throw((jthrowable) sigexception); \ + } \ + if (get_timedout()) { \ + 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 3590ef2..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,7 +71,12 @@ using CryptoPP::Integer; #include "cpp_utils.hpp" #include "c_timing.h" -#include "c_signals.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() -- cgit v1.3.1 From 219fb8d3385604070dc2ee9cac5ee7c74bd34749 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 7 May 2024 18:02:22 +0200 Subject: Separatate C and Cpp signal handling. --- .../crcs/ectester/standalone/libs/jni/c_signals.c | 10 +++++----- .../crcs/ectester/standalone/libs/jni/c_signals.h | 22 +++++++++++----------- .../ectester/standalone/libs/jni/cpp_signals.cpp | 10 +++++----- .../ectester/standalone/libs/jni/cpp_signals.hpp | 22 +++++++++++----------- 4 files changed, 32 insertions(+), 32 deletions(-) (limited to 'standalone/src/main') 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 index dd08bb8..b452787 100644 --- 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 @@ -37,7 +37,7 @@ void alarm_handler(int signo) { } -sigjmp_buf *get_jmpbuf() { +sigjmp_buf *get_jmpbuf_c() { return &buf; } @@ -51,7 +51,7 @@ void *timer(void *arg) { return NULL; } -void init_signals(sigjmp_buf *env, unsigned int timeout) { +void init_signals_c(sigjmp_buf *env, unsigned int timeout) { //printf("Initializing signals!\n"); struct sigaction action; action.sa_sigaction = handler; @@ -79,7 +79,7 @@ void init_signals(sigjmp_buf *env, unsigned int timeout) { } -void deinit_signals() { +void deinit_signals_c() { //printf("Deinitializing signals!\n"); pthread_cancel(timer_thread); @@ -91,11 +91,11 @@ void deinit_signals() { initialized = false; } -bool get_timedout() { +bool get_timedout_c() { return timedout; } -jobject get_siginfo(JNIEnv *env) { +jobject get_siginfo_c(JNIEnv *env) { if (!caught) { return NULL; } 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 index 3f3c473..a82b572 100644 --- 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 @@ -9,42 +9,42 @@ /** * */ -void init_signals(jmp_buf *env, unsigned int timeout); +void init_signals_c(jmp_buf *env, unsigned int timeout); /** * */ -sigjmp_buf *get_jmpbuf(); +sigjmp_buf *get_jmpbuf_c(); /** * */ -void deinit_signals(); +void deinit_signals_c(); /** * */ -bool get_timedout(); +bool get_timedout_c(); /** * */ -jobject get_siginfo(JNIEnv *env); +jobject get_siginfo_c(JNIEnv *env); -#define SIG_TRY(timeout) init_signals(get_jmpbuf(), timeout); \ - if (!sigsetjmp(*get_jmpbuf(), 1)) -#define SIG_CATCH() deinit_signals(); -#define SIG_DEINIT() deinit_signals(); +#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(env); \ + 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, "", "(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()) { \ + 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."); \ } \ 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 index 75bc17c..999349a 100644 --- 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 @@ -40,7 +40,7 @@ void alarm_handler(int signo) { } -sigjmp_buf *get_jmpbuf() { +sigjmp_buf *get_jmpbuf_cpp() { return &buf; } @@ -54,7 +54,7 @@ void *timer(void *arg) { return NULL; } -void init_signals(sigjmp_buf *env, unsigned int timeout) { +void init_signals_cpp(sigjmp_buf *env, unsigned int timeout) { //printf("Initializing signals!\n"); struct sigaction action; action.sa_sigaction = handler; @@ -82,7 +82,7 @@ void init_signals(sigjmp_buf *env, unsigned int timeout) { } -void deinit_signals() { +void deinit_signals_cpp() { //printf("Deinitializing signals!\n"); pthread_cancel(timer_thread); @@ -94,11 +94,11 @@ void deinit_signals() { initialized = false; } -bool get_timedout() { +bool get_timedout_cpp() { return timedout; } -jobject get_siginfo(JNIEnv *env) { +jobject get_siginfo_cpp(JNIEnv *env) { if (!caught) { return NULL; } 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 index b926656..4dc222f 100644 --- 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 @@ -12,42 +12,42 @@ extern "C" /** * */ -void init_signals(jmp_buf *env, unsigned int timeout); +void init_signals_cpp(jmp_buf *env, unsigned int timeout); /** * */ -sigjmp_buf *get_jmpbuf(); +sigjmp_buf *get_jmpbuf_cpp(); /** * */ -void deinit_signals(); +void deinit_signals_cpp(); /** * */ -bool get_timedout(); +bool get_timedout_cpp(); /** * */ -jobject get_siginfo(JNIEnv *env); +jobject get_siginfo_cpp(JNIEnv *env); -#define SIG_TRY(timeout) init_signals(get_jmpbuf(), timeout); \ - if (!sigsetjmp(*get_jmpbuf(), 1)) -#define SIG_CATCH() deinit_signals(); -#define SIG_DEINIT() deinit_signals(); +#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(env); \ + 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, "", "(Lcz/crcs/ectester/standalone/libs/jni/SigInfo;)V"); \ jobject sigexception = env->NewObject(sigexception_class, new_sigexception, siginfo); \ env->Throw((jthrowable) sigexception); \ } \ - if (get_timedout()) { \ + if (get_timedout_cpp()) { \ jclass timeoutexception_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/TimeoutException"); \ env->ThrowNew(timeoutexception_class, "Operation timed out."); \ } \ -- cgit v1.3.1 From ba76bd7c04a94b52f57eda418e270dc658976c12 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 10 May 2024 16:08:43 +0200 Subject: Fix Nettle issues. Fixes #23. --- .../java/cz/crcs/ectester/common/util/ECUtil.java | 11 ++ .../crcs/ectester/standalone/libs/NettleLib.java | 32 +++++ .../standalone/libs/jni/NativeKeyAgreementSpi.java | 128 +++++++++++-------- .../libs/jni/NativeKeyPairGeneratorSpi.java | 49 ++++++-- .../cz/crcs/ectester/standalone/libs/jni/native.h | 136 +++++++++++++++++++++ .../cz/crcs/ectester/standalone/libs/jni/nettle.c | 51 +------- .../java/cz/crcs/ectester/standalone/AppTests.java | 15 --- 7 files changed, 294 insertions(+), 128 deletions(-) (limited to 'standalone/src/main') diff --git a/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java b/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java index 74fccc9..54c5131 100644 --- a/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java +++ b/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java @@ -507,4 +507,15 @@ public class ECUtil { priv.getParams().getGenerator().equals(pub.getParams().getGenerator()) && priv.getParams().getOrder().equals(pub.getParams().getOrder()); } + + public static boolean equalECParameterSpec(ECParameterSpec left, ECParameterSpec right) { + if (left == null || right == null) { + return false; + } + + return left.getCofactor() == right.getCofactor() && + left.getCurve().equals(right.getCurve()) && + left.getGenerator().equals(right.getGenerator()) && + left.getOrder().equals(right.getOrder()); + } } diff --git a/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 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/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; - - } - return generateSecret(pubkey, privkey, spec); - - } catch (NoSuchAlgorithmException | InvalidParameterSpecException e) { - return null; - } + ECGenParameterSpec parametersKnown(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { + return NettleLib.parametersKnown(params); } - native byte[] generateSecret(byte[] pubkey, byte[] privkey, ECGenParameterSpec params); + @Override + byte[] generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, AlgorithmParameterSpec params) { + return generateSecret(getPubkey(), getPrivkey(), (ECGenParameterSpec) params); + } @Override - native SecretKey generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params, String algorithm); + SecretKey generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, AlgorithmParameterSpec params, String algorithm) { + throw new UnsupportedOperationException("Not supported."); + } + + native byte[] generateSecret(byte[] pubkey, byte[] privkey, ECGenParameterSpec params); } 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/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 48b8f26..24ba699 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 @@ -36,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"); @@ -67,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; @@ -116,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; @@ -210,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) { @@ -280,7 +240,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); @@ -339,11 +299,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; 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 c39ee54..1f82bb0 100644 --- a/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java +++ b/standalone/src/test/java/cz/crcs/ectester/standalone/AppTests.java @@ -90,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"); @@ -123,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"); @@ -172,9 +166,6 @@ public class AppTests { @ParameterizedTest @MethodSource("libs") 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"); @@ -185,9 +176,6 @@ public class AppTests { @ParameterizedTest @MethodSource("libs") 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"); @@ -255,9 +243,6 @@ public class AppTests { @ParameterizedTest @MethodSource("libs") 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"); -- cgit v1.3.1 From 9a16c642af2ca81b12b4545a7227b3746639e4d0 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 14 May 2024 14:23:44 +0200 Subject: The signature test vectors are for SHA1 only, check this in standalone. --- .../ectester/standalone/test/suites/StandaloneSignatureSuite.java | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'standalone/src/main') 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..bafaa90 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())) { + 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(); -- cgit v1.3.1 From b6ea0edd26ff6873d3596c68523d27c6e528a034 Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 20 May 2024 12:26:26 +0200 Subject: Add way of selecting tests in Standalone. --- .../ectester/standalone/ECTesterStandalone.java | 37 ++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'standalone/src/main') 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 6ef1be7..2b9a853 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -785,7 +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; - switch (cli.getArg(0).toLowerCase()) { + 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 (testSuite) { case "test-vectors": suite = new StandaloneTestVectorSuite(writer, cfg, cli); break; @@ -824,7 +857,7 @@ public class ECTesterStandalone { break; } - suite.run(); + suite.run(testFrom, testTo); } /** -- cgit v1.3.1 From 0bc459385a67f0a0f09abda7c1c768fc14e20a5f Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 20 May 2024 13:37:35 +0200 Subject: Add check for a=-3 in tomcrypt. --- .../cz/crcs/ectester/standalone/libs/jni/tomcrypt.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'standalone/src/main') 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 9593e9b..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 @@ -192,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); -- cgit v1.3.1 From 99d463bd5f34ada3f6dcd92073960590b68afbb3 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 14 Jun 2024 14:19:26 +0200 Subject: More detailed signature format tests. --- .../java/cz/crcs/ectester/common/util/ECUtil.java | 39 ++++- .../resources/cz/crcs/ectester/data/schema.xsd | 1 + .../cz/crcs/ectester/data/wrong/results.xml | 163 +++++++++++++++++---- .../test/suites/StandaloneSignatureSuite.java | 2 +- 4 files changed, 170 insertions(+), 35 deletions(-) (limited to 'standalone/src/main') diff --git a/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java b/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java index 907d75f..e7f138e 100644 --- a/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java +++ b/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java @@ -349,6 +349,39 @@ public class ECUtil { return new KeyPair(pubkey, privkey); } + /** + * Validate DER or PLAIN signature format. + * + * @throws IllegalArgumentException in case of invalid format. + * @param signature + * @param params + * @param hashAlgo + * @param sigType + */ + public static void validateSignatureFormat(byte[] signature, ECParameterSpec params, String hashAlgo, String sigType) { + BigInteger n = params.getOrder(); + try { + if (sigType.contains("CVC") || sigType.contains("PLAIN")) { + PlainDSAEncoding.INSTANCE.decode(n, signature); + } else { + StandardDSAEncoding.INSTANCE.decode(n, signature); + } + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + + /** + * Recover the ECDSA signature nonce. + * + * @param signature + * @param data + * @param privkey + * @param params + * @param hashAlgo + * @param sigType + * @return The nonce. + */ public static BigInteger recoverSignatureNonce(byte[] signature, byte[] data, BigInteger privkey, ECParameterSpec params, String hashAlgo, String sigType) { // We do not know how to reconstruct those nonces so far. // sigType.contains("ECKCDSA") || sigType.contains("ECNR") || sigType.contains("SM2") @@ -381,9 +414,9 @@ public class ECUtil { r = sigPair[0]; s = sigPair[1]; } else { - ASN1Sequence seq = (ASN1Sequence)ASN1Primitive.fromByteArray(signature); - r = ((ASN1Integer)seq.getObjectAt(0)).getValue(); - s = ((ASN1Integer)seq.getObjectAt(1)).getValue(); + ASN1Sequence seq = (ASN1Sequence) ASN1Primitive.fromByteArray(signature); + r = ((ASN1Integer) seq.getObjectAt(0)).getValue(); + s = ((ASN1Integer) seq.getObjectAt(1)).getValue(); } diff --git a/common/src/main/resources/cz/crcs/ectester/data/schema.xsd b/common/src/main/resources/cz/crcs/ectester/data/schema.xsd index 99c9b76..245aa9a 100644 --- a/common/src/main/resources/cz/crcs/ectester/data/schema.xsd +++ b/common/src/main/resources/cz/crcs/ectester/data/schema.xsd @@ -82,6 +82,7 @@ + diff --git a/common/src/main/resources/cz/crcs/ectester/data/wrong/results.xml b/common/src/main/resources/cz/crcs/ectester/data/wrong/results.xml index e3f0967..af5d6dd 100644 --- a/common/src/main/resources/cz/crcs/ectester/data/wrong/results.xml +++ b/common/src/main/resources/cz/crcs/ectester/data/wrong/results.xml @@ -23,8 +23,9 @@ nok/random - SHA1 + * 0x30440220e641671e6415629dc8398e35ae1362cb647f293a92553b1594d57fff58df302c02206baafface035e3758eea0dd9ef734976c70b6dd06f4d81d33f5e28bfb8730624 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub @@ -32,8 +33,9 @@ nok/r0 - SHA1 - 0x3044022000000000000000000000000000000000000000000000000000000000000000000220d0837b07fe63d225733391e6808a081fd8aeb1359511feba7ca4f266727f968e + * + 0x30250201000220675e2eb20e1f1ec11c3016f7675d9a2e7a3c3370efde499ccb91920ab3da4ef3 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub @@ -41,8 +43,9 @@ nok/s0 - SHA1 - 0x304402206bea66d439da6b0b4a0e45b51e76d53336f27f7aa8e35f2008b77a8e021eff0a02200000000000000000000000000000000000000000000000000000000000000000 + * + 0x302502206bea66d439da6b0b4a0e45b51e76d53336f27f7aa8e35f2008b77a8e021eff0a020100 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub @@ -50,8 +53,9 @@ nok/r1 - SHA1 - 0x3044022000000000000000000000000000000000000000000000000000000000000000010220e660f19ddc20a30adda6ca175577b492e238ef8734b904a31045d453825974d4 + * + 0x302502010102203494a201a1a539189253c5eab77d1cb99ce1b154c642acc85a956cf2eec2bb3f + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub @@ -59,8 +63,9 @@ nok/s1 - SHA1 - 0x30440220d30ab3301d7132edbead77c0d622bbb7be8626c9ac5ee6c536281e6c18e79ab002200000000000000000000000000000000000000000000000000000000000000001 + * + 0x302502201ee448a2ce4695ac5b71d89553e3dd9688f33041f64aa9aed49c269f6f943c25020101 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub @@ -68,8 +73,9 @@ nok/r0s0 - SHA1 - 0x30440220000000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000000 + * + 0x3006020100020100 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub @@ -77,8 +83,9 @@ nok/r0s1 - SHA1 - 0x30440220000000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000001 + * + 0x3006020100020101 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub @@ -86,8 +93,9 @@ nok/r1s0 - SHA1 - 0x30440220000000000000000000000000000000000000000000000000000000000000000102200000000000000000000000000000000000000000000000000000000000000000 + * + 0x3006020101020100 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub @@ -95,35 +103,119 @@ nok/r1s1 - SHA1 - 0x30440220000000000000000000000000000000000000000000000000000000000000000102200000000000000000000000000000000000000000000000000000000000000001 + * + 0x3006020101020101 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub Well-formed invalid signature with r = 1 and s = 1. + + nok/r0_padded + * + 0x3044022000000000000000000000000000000000000000000000000000000000000000000220675e2eb20e1f1ec11c3016f7675d9a2e7a3c3370efde499ccb91920ab3da4ef3 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB + secg/secp256r1 + wrong/default_priv + wrong/default_pub + Malformed (zero-padded) invalid signature with r = 0. + + + nok/s0_padded + * + 0x304402206bea66d439da6b0b4a0e45b51e76d53336f27f7aa8e35f2008b77a8e021eff0a02200000000000000000000000000000000000000000000000000000000000000000 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB + secg/secp256r1 + wrong/default_priv + wrong/default_pub + Malformed (zero-padded) invalid signature with s = 0. + + + nok/r1_padded + * + 0x30440220000000000000000000000000000000000000000000000000000000000000000102203494a201a1a539189253c5eab77d1cb99ce1b154c642acc85a956cf2eec2bb3f + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB + secg/secp256r1 + wrong/default_priv + wrong/default_pub + Malformed (zero-padded) invalid signature with r = 1. + + + nok/s1_padded + * + 0x304402201ee448a2ce4695ac5b71d89553e3dd9688f33041f64aa9aed49c269f6f943c2502200000000000000000000000000000000000000000000000000000000000000001 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB + secg/secp256r1 + wrong/default_priv + wrong/default_pub + Malformed (zero-padded) invalid signature with s = 1. + + + nok/r0s0_padded + * + 0x30440220000000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000000 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB + secg/secp256r1 + wrong/default_priv + wrong/default_pub + Malformed (zero-padded) invalid signature with r = 0 and s = 0. + + + nok/r0s1_padded + * + 0x30440220000000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000001 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB + secg/secp256r1 + wrong/default_priv + wrong/default_pub + Malformed (zero-padded) invalid signature with r = 0 and s = 1. + + + nok/r1s0_padded + * + 0x30440220000000000000000000000000000000000000000000000000000000000000000102200000000000000000000000000000000000000000000000000000000000000000 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB + secg/secp256r1 + wrong/default_priv + wrong/default_pub + Malformed (zero-padded) invalid signature with r = 1 and s = 0. + + + nok/r1s1_padded + * + 0x30440220000000000000000000000000000000000000000000000000000000000000000102200000000000000000000000000000000000000000000000000000000000000001 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB + secg/secp256r1 + wrong/default_priv + wrong/default_pub + Malformed (zero-padded) invalid signature with r = 1 and s = 1. + nok/sp - SHA1 + * 0x30440220fc48281b60b73752f3e20c25e8a06b335122d5890db28d2969d3145fcd384e7b0220ffffffff00000001000000000000000000000000ffffffffffffffffffffffff + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub - Well-formed invalid signature s = p. + Malformed (zero-padded) invalid signature s = p. nok/s2p - SHA1 + * 0x30450220feba982489753a51a69fd582673d2e62b6b07cc6374237c1424f1e469cb00a98022101fffffffe00000002000000000000000000000001fffffffffffffffffffffffe + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub - Well-formed invalid signature with s = 2 * p. + Malformed (zero-padded) invalid signature with s = 2 * p. nok/length_overflow16 - SHA1 + * 0x3083ff000002203988322ab9f52c7f11d5d1aa92a2ac0b00275bcad8e934682257323fda672482022052231597382268e8f3b82b99e386ebb7c7db1a8b4a8bdacd496190314e4c5bad + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub @@ -131,8 +223,9 @@ nok/length_overflow32 - SHA1 + * 0x3085ff0000000002203988322ab9f52c7f11d5d1aa92a2ac0b00275bcad8e934682257323fda672482022052231597382268e8f3b82b99e386ebb7c7db1a8b4a8bdacd496190314e4c5bad + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub @@ -140,8 +233,9 @@ nok/length_overflow64 - SHA1 + * 0x3089ff000000000000000002203988322ab9f52c7f11d5d1aa92a2ac0b00275bcad8e934682257323fda672482022052231597382268e8f3b82b99e386ebb7c7db1a8b4a8bdacd496190314e4c5bad + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub @@ -149,8 +243,9 @@ nok/length_indefinite - SHA1 + * 0x308002203988322ab9f52c7f11d5d1aa92a2ac0b00275bcad8e934682257323fda672482022052231597382268e8f3b82b99e386ebb7c7db1a8b4a8bdacd496190314e4c5bad + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub @@ -158,8 +253,9 @@ nok/long - SHA1 + * 0x30420220e641671e6415629dc8398e35ae1362cb647f293a92553b1594d57fff58df302c02206baafface035e3758eea0dd9ef734976c70b6dd06f4d81d33f5e28bfb8730624 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub @@ -167,8 +263,9 @@ nok/short - SHA1 + * 0x30460220e641671e6415629dc8398e35ae1362cb647f293a92553b1594d57fff58df302c02206baafface035e3758eea0dd9ef734976c70b6dd06f4d81d33f5e28bfb8730624 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub @@ -176,8 +273,9 @@ nok/long_r - SHA1 + * 0x3044021ee641671e6415629dc8398e35ae1362cb647f293a92553b1594d57fff58df302c02206baafface035e3758eea0dd9ef734976c70b6dd06f4d81d33f5e28bfb8730624 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub @@ -185,8 +283,9 @@ nok/long_s - SHA1 + * 0x30440220e641671e6415629dc8398e35ae1362cb647f293a92553b1594d57fff58df302c021e6baafface035e3758eea0dd9ef734976c70b6dd06f4d81d33f5e28bfb8730624 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub @@ -194,8 +293,9 @@ nok/short_r - SHA1 + * 0x30440222e641671e6415629dc8398e35ae1362cb647f293a92553b1594d57fff58df302c02206baafface035e3758eea0dd9ef734976c70b6dd06f4d81d33f5e28bfb8730624 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub @@ -203,8 +303,9 @@ nok/short_s - SHA1 + * 0x30440220e641671e6415629dc8398e35ae1362cb647f293a92553b1594d57fff58df302c02226baafface035e3758eea0dd9ef734976c70b6dd06f4d81d33f5e28bfb8730624 + 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB secg/secp256r1 wrong/default_priv wrong/default_pub 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 bafaa90..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,7 +73,7 @@ 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())) { + if (!sig.getSig().equals(sigIdent.getHashAlgo()) && !sig.getSig().equals("*")) { doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "ECDSA test of " + sig.getId() + " not applicable.")); return; } -- cgit v1.3.1 From e27e478c0a3ecf37b6e83d63986cc8c53d851095 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 14 Jun 2024 14:45:03 +0200 Subject: Check return values in OpenSSL key loads. Fixes #28. --- .../cz/crcs/ectester/standalone/libs/jni/openssl.c | 31 +++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'standalone/src/main') 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 fc02e9d..7a6070d 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 @@ -455,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; } @@ -469,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; } @@ -482,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; @@ -526,6 +545,9 @@ 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); @@ -566,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); -- cgit v1.3.1 From d4c6426df7d1d66c7e2a2f1000d252edfe51c43a Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 15 Jun 2024 12:07:23 +0200 Subject: Error codes in OpenSSL shim. --- .../src/main/resources/cz/crcs/ectester/standalone/libs/jni/openssl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'standalone/src/main') 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 7a6070d..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 @@ -519,7 +519,7 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey } 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; @@ -611,7 +611,7 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna (*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; } -- cgit v1.3.1 From 9be29890dc246cac61649052c8501adbb7dfe3d2 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 19 Jun 2024 10:37:52 +0200 Subject: Add pubkey checks to LibreSSL and BoringSSL. Fixes #28. --- .../crcs/ectester/standalone/libs/jni/boringssl.c | 58 +++++++++++++++++----- .../crcs/ectester/standalone/libs/jni/libressl.c | 49 +++++++++++++++--- 2 files changed, 86 insertions(+), 21 deletions(-) (limited to 'standalone/src/main') 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 6878549..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 @@ -397,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) { @@ -411,27 +420,38 @@ 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); int err = 0; @@ -449,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; } @@ -461,13 +484,17 @@ 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); @@ -483,19 +510,20 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig (*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; } @@ -508,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); 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 7d50836..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 @@ -420,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; } @@ -434,27 +443,38 @@ 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); int err; @@ -472,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; } @@ -484,13 +507,17 @@ 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); @@ -511,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; } @@ -531,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); -- cgit v1.3.1 From b7d077792a282b27875218ef808de067e4953150 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 19 Jun 2024 11:07:32 +0200 Subject: Add point validation to Nettle. --- .../resources/cz/crcs/ectester/standalone/libs/jni/nettle.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'standalone/src/main') 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 24ba699..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 @@ -225,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; } @@ -267,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); -- cgit v1.3.1 From 5fee2ecff3c6eee47ca0138bc23603f4c7741c30 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 19 Jun 2024 11:19:42 +0200 Subject: Reformat. --- .../test/suites/StandaloneCofactorSuite.java | 6 ++-- .../test/suites/StandaloneCompositeSuite.java | 40 +++++++++++----------- .../test/suites/StandaloneDegenerateSuite.java | 8 ++--- .../test/suites/StandaloneEdgeCasesSuite.java | 4 +-- .../test/suites/StandaloneInvalidSuite.java | 8 ++--- .../test/suites/StandalonePerformanceSuite.java | 12 +++---- .../test/suites/StandaloneTestVectorSuite.java | 2 +- .../test/suites/StandaloneTwistSuite.java | 8 ++--- .../test/suites/StandaloneWrongSuite.java | 36 +++++++++---------- 9 files changed, 62 insertions(+), 62 deletions(-) (limited to 'standalone/src/main') 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 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 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..45000df 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 @@ -77,17 +77,17 @@ 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)))) { + if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) { generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generateOnDefaultCurve); } else { Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate); @@ -111,7 +111,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..391fc34 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 @@ -76,17 +76,17 @@ 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)))) { + if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) { generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generateOnDefaultCurve); } else { Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate); @@ -110,7 +110,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 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/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 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..84228e7 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 @@ -76,17 +76,17 @@ 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)))) { + if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) { generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generateOnDefaultCurve); } else { Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate); @@ -110,7 +110,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 wrongCurves = EC_Store.getInstance().getObjects(EC_Curve.class, "wrong"); for (Map.Entry 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 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(); -- cgit v1.3.1 From c38ef1edaa6e0a1e97cf81274c8b2c24fea63bce Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 19 Jun 2024 12:53:14 +0200 Subject: Fix libgcrypt with secp256k1. --- .../resources/cz/crcs/ectester/standalone/libs/jni/gcrypt.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'standalone/src/main') 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 705a873..0c141dd 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 @@ -181,8 +181,11 @@ static jobject mpi_to_biginteger(JNIEnv *env, gcry_mpi_t mpi) { return NULL; } - jmethodID biginteger_init = (*env)->GetMethodID(env, biginteger_class, "", "(I[B)V"); jbyteArray bytes = mpi_to_bytearray(env, mpi); + if (!bytes) { + return NULL; + } + jmethodID biginteger_init = (*env)->GetMethodID(env, biginteger_class, "", "(I[B)V"); jobject result = (*env)->NewObject(env, biginteger_class, biginteger_init, 1, bytes); return result; } @@ -245,7 +248,11 @@ static jobject create_ec_param_spec(JNIEnv *env, gcry_sexp_t key) { jmethodID fp_field_init = (*env)->GetMethodID(env, fp_field_class, "", "(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, "", "(Ljava/security/spec/ECField;Ljava/math/BigInteger;Ljava/math/BigInteger;)V"); -- cgit v1.3.1 From 57c4f0ea9e428e3634bae389d9f8409a856a15f7 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 19 Jun 2024 14:59:38 +0200 Subject: Fix libgcrypt issues. --- .../standalone/test/base/KeyGeneratorTest.java | 14 ++++++++- .../standalone/test/base/KeyGeneratorTestable.java | 17 ++++++++++- .../test/suites/StandaloneDegenerateSuite.java | 33 +++++++++++++++------- .../test/suites/StandaloneInvalidSuite.java | 33 +++++++++++++++------- .../test/suites/StandaloneTwistSuite.java | 33 +++++++++++++++------- .../cz/crcs/ectester/standalone/libs/jni/gcrypt.c | 30 ++++++-------------- 6 files changed, 106 insertions(+), 54 deletions(-) (limited to 'standalone/src/main') 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 { @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 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(); 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 391fc34..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.*; @@ -81,17 +82,29 @@ public class StandaloneInvalidSuite extends StandaloneTestSuite { KeyPair kp = kgt.getKeyPair(); if (kp != null) { generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate); - } else { //If KeyPair generation fails, try generating it on 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(); 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 84228e7..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.*; @@ -81,17 +82,29 @@ public class StandaloneTwistSuite extends StandaloneTestSuite { KeyPair kp = kgt.getKeyPair(); if (kp != null) { generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate); - } else { //If KeyPair generation fails, try generating it on 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(); 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 0c141dd..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 @@ -200,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, "", "(I[B)V"); @@ -236,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; @@ -261,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, "", "(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); @@ -272,7 +259,6 @@ end: gcry_mpi_release(b); gcry_free(g.data); gcry_mpi_release(n); - gcry_mpi_release(h); return result; } @@ -479,7 +465,7 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey } 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; } @@ -594,7 +580,7 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig } 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; } @@ -602,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); @@ -654,7 +640,7 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna 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 { -- cgit v1.3.1 From 9c2b3c836bddddd9486d7ed74b5a95af683ff83e Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 21 Jun 2024 14:23:31 +0200 Subject: Always write shims to shim directory, do not check for freshness. --- .../src/main/java/cz/crcs/ectester/common/util/FileUtil.java | 11 +++++++++++ ext/boringssl | 2 +- .../java/cz/crcs/ectester/standalone/ECTesterStandalone.java | 6 +++--- .../cz/crcs/ectester/standalone/libs/NativeECLibrary.java | 4 ++-- 4 files changed, 17 insertions(+), 6 deletions(-) (limited to 'standalone/src/main') diff --git a/common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java b/common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java index e6e319b..da682b6 100644 --- a/common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java +++ b/common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java @@ -81,6 +81,17 @@ public class FileUtil { return true; } + public static boolean write(String resourcePath, Path outPath) throws IOException { + URL reqURL = FileUtil.class.getResource(resourcePath); + if (reqURL == null) { + return false; + } + URLConnection reqConn = reqURL.openConnection(); + Files.copy(reqConn.getInputStream(), outPath, StandardCopyOption.REPLACE_EXISTING); + reqConn.getInputStream().close(); + return true; + } + public static Path getLibDir() { return getAppData().resolve("ECTesterStandalone"); } diff --git a/ext/boringssl b/ext/boringssl index 80a243e..67422ed 160000 --- a/ext/boringssl +++ b/ext/boringssl @@ -1 +1 @@ -Subproject commit 80a243e07ef77156af66efa7d22ac35aba44c1b3 +Subproject commit 67422ed4434116daa8898773692165ddd51a6ac2 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 2b9a853..10e95ca 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -103,12 +103,12 @@ 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.writeNewer(LIB_RESOURCE_DIR + "lib_csignals.so", reqs.resolve("lib_csignals.so")); + FileUtil.write(LIB_RESOURCE_DIR + "lib_csignals.so", reqs.resolve("lib_csignals.so")); System.load(reqs.resolve("lib_csignals.so").toString()); - FileUtil.writeNewer(LIB_RESOURCE_DIR + "lib_cppsignals.so", reqs.resolve("lib_cppsignals.so")); + FileUtil.write(LIB_RESOURCE_DIR + "lib_cppsignals.so", reqs.resolve("lib_cppsignals.so")); System.load(reqs.resolve("lib_cppsignals.so").toString()); } 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; } -- cgit v1.3.1 From c112d3e49bbbbf33cc70d12d196e109543c19a3c Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 21 Jun 2024 14:36:23 +0200 Subject: Push library initialization deeper and only initialize when necessary. --- .../ectester/standalone/ECTesterStandalone.java | 30 +++++++++++++--------- 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'standalone/src/main') 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 10e95ca..e6d8188 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -136,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; @@ -302,7 +292,17 @@ 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()); @@ -942,7 +942,7 @@ public class ECTesterStandalone { if (libraryName != null) { List 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); } } @@ -954,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()); + } } } } -- cgit v1.3.1