aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build-standalone.xml5
-rw-r--r--docs/LIBS.md9
-rw-r--r--src/cz/crcs/ectester/reader/output/TextTestWriter.java6
-rw-r--r--src/cz/crcs/ectester/standalone/ECTesterStandalone.java17
-rw-r--r--src/cz/crcs/ectester/standalone/libs/OpensslLib.java19
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/Makefile10
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java6
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java6
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java18
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java10
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/botan.cpp50
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp53
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/native.h125
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/openssl.c393
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c1
-rw-r--r--src/cz/crcs/ectester/standalone/output/TextTestWriter.java5
16 files changed, 617 insertions, 116 deletions
diff --git a/build-standalone.xml b/build-standalone.xml
index 4190300..f1ff001 100644
--- a/build-standalone.xml
+++ b/build-standalone.xml
@@ -122,6 +122,11 @@
<class name="cz.crcs.ectester.standalone.libs.jni.NativeECPrivateKey$Cryptopp"/>
<class name="cz.crcs.ectester.standalone.libs.jni.NativeKeyAgreementSpi$Cryptopp"/>
<class name="cz.crcs.ectester.standalone.libs.jni.NativeSignatureSpi$Cryptopp"/>
+ <class name="cz.crcs.ectester.standalone.libs.OpensslLib"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeProvider$Openssl"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeKeyPairGeneratorSpi$Openssl"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeECPublicKey$Openssl"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeECPrivateKey$Openssl"/>
</javah>
</target>
</project>
diff --git a/docs/LIBS.md b/docs/LIBS.md
index bfe20cd..59a183f 100644
--- a/docs/LIBS.md
+++ b/docs/LIBS.md
@@ -5,8 +5,8 @@ Popular libraries with at least some ECC support:
- [libgcrypt](https://www.gnupg.org/related_software/libgcrypt/)
- [mbedTLS](https://tls.mbed.org/)
- [Nettle](http://www.lysator.liu.se/~nisse/nettle/)
- - [OpenSSL](https://www.openssl.org/)
- [OpenSSL (FIPS mode)](https://www.openssl.org/docs/fipsnotes.html)
+ - BoringSSL
- [Microsoft CNG](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376210(v=vs.85).aspx)
- [Microsoft .NET crypto](https://docs.microsoft.com/en-us/dotnet/standard/security/cryptography-model)
@@ -54,6 +54,13 @@ Popular libraries with at least some ECC support:
- Uses Lopez-Dahab (Montgomery) ladder, XZ coordinates (ec2_mont.c): Fast multiplication on elliptic curves over GF(2^m) without precomputation (Algorithm 2P)
- Contains an implementation of IEEE P1363 algorithm A.10.3 using affine coordinates (ec2_aff.c)
- Has some custom arithmetic for some of the NIST primes.
+ - [OpenSSL](https://www.openssl.org/)
+ - C
+ - For prime field curves:
+ - Uses Jacobian coordinates, and Montgomery ladder, also uses wNAF-based interleaving multi-exponentiation method(ec_mult.c): http://www.bmoeller.de/pdf/TI-01-08.multiexp.pdf
+ - Also uses multiplication with precomputation by wNAF splitting(ec_mult.c)
+ - For binary field curves:
+ - Uses Jacobian coordinates, and Lopez-Dahab ladder, also uses wNAF-based interleaving multi-exponentiation method(ec2_smpl.c)
- [Botan](https://botan.randombit.net/)
- C++
- Uses blinded(randomized) Montgomery ladder.
diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java
index a8e4ce9..ad35012 100644
--- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java
+++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java
@@ -43,12 +43,12 @@ public class TextTestWriter extends BaseTextTestWriter {
if (suite instanceof CardTestSuite) {
CardTestSuite cardSuite = (CardTestSuite) suite;
StringBuilder sb = new StringBuilder();
- sb.append("═══ " + Colors.underline("ECTester version:") + " " + ECTesterReader.VERSION + ECTesterReader.GIT_COMMIT).append(System.lineSeparator());
- sb.append("═══ " + Colors.underline("Card ATR:") + " ").append(ByteUtil.bytesToHex(cardSuite.getCard().getATR().getBytes(), false)).append(System.lineSeparator());
+ sb.append("═══ ").append(Colors.underline("ECTester version:")).append(" ").append(ECTesterReader.VERSION).append(ECTesterReader.GIT_COMMIT).append(System.lineSeparator());
+ sb.append("═══ ").append(Colors.underline("Card ATR:")).append(" ").append(ByteUtil.bytesToHex(cardSuite.getCard().getATR().getBytes(), false)).append(System.lineSeparator());
try {
CardMngr.CPLC cplc = cardSuite.getCard().getCPLC();
if (!cplc.values().isEmpty()) {
- sb.append("═══ " + Colors.underline("Card CPLC data:")).append(System.lineSeparator());
+ sb.append("═══ ").append(Colors.underline("Card CPLC data:")).append(System.lineSeparator());
for (Map.Entry<CardMngr.CPLC.Field, byte[]> entry : cplc.values().entrySet()) {
CardMngr.CPLC.Field field = entry.getKey();
byte[] value = entry.getValue();
diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
index c223af6..9df6c61 100644
--- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
+++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
@@ -66,7 +66,7 @@ import java.util.stream.Collectors;
* @version v0.2.0
*/
public class ECTesterStandalone {
- private ProviderECLibrary[] libs = new ProviderECLibrary[]{new SunECLib(), new BouncyCastleLib(), new TomcryptLib(), new BotanLib(), new CryptoppLib()};
+ private ProviderECLibrary[] libs = new ProviderECLibrary[]{new SunECLib(), new BouncyCastleLib(), new TomcryptLib(), new BotanLib(), new CryptoppLib(), new OpensslLib()};
private Config cfg;
private Options opts = new Options();
@@ -205,6 +205,7 @@ public class ECTesterStandalone {
opts.addOption(Option.builder("V").longOpt("version").desc("Print version info.").build());
opts.addOption(Option.builder("h").longOpt("help").desc("Print help.").build());
+ opts.addOption(Option.builder("C").longOpt("color").desc("Print stuff with color, requires ANSI terminal.").build());
return optParser.parse(opts, args);
}
@@ -215,22 +216,22 @@ public class ECTesterStandalone {
private void listLibraries() {
for (ProviderECLibrary lib : libs) {
if (lib.isInitialized() && (cfg.selected == null || lib == cfg.selected)) {
- System.out.println("\t- " + lib.name());
+ System.out.println("\t- " + Colors.bold(lib.name()));
Set<KeyPairGeneratorIdent> kpgs = lib.getKPGs();
if (!kpgs.isEmpty()) {
- System.out.println("\t\t- KeyPairGenerators: " + String.join(", ", kpgs.stream().map(KeyPairGeneratorIdent::getName).collect(Collectors.toList())));
+ System.out.println(Colors.bold("\t\t- KeyPairGenerators: ") + String.join(", ", kpgs.stream().map(KeyPairGeneratorIdent::getName).collect(Collectors.toList())));
}
Set<KeyAgreementIdent> eckas = lib.getKAs();
if (!eckas.isEmpty()) {
- System.out.println("\t\t- KeyAgreements: " + String.join(", ", eckas.stream().map(KeyAgreementIdent::getName).collect(Collectors.toList())));
+ System.out.println(Colors.bold("\t\t- KeyAgreements: ") + String.join(", ", eckas.stream().map(KeyAgreementIdent::getName).collect(Collectors.toList())));
}
Set<SignatureIdent> sigs = lib.getSigs();
if (!sigs.isEmpty()) {
- System.out.println("\t\t- Signatures: " + String.join(", ", sigs.stream().map(SignatureIdent::getName).collect(Collectors.toList())));
+ System.out.println(Colors.bold("\t\t- Signatures: ") + String.join(", ", sigs.stream().map(SignatureIdent::getName).collect(Collectors.toList())));
}
Set<String> curves = lib.getCurves();
if (!curves.isEmpty()) {
- System.out.println("\t\t- Curves: " + String.join(", ", curves));
+ System.out.println(Colors.bold("\t\t- Curves: ") + String.join(", ", curves));
}
System.out.println();
}
@@ -540,12 +541,16 @@ public class ECTesterStandalone {
public static class Config {
private ProviderECLibrary[] libs;
public ProviderECLibrary selected = null;
+ public boolean color = false;
public Config(ProviderECLibrary[] libs) {
this.libs = libs;
}
boolean readOptions(TreeCommandLine cli) {
+ color = cli.hasOption("color");
+ Colors.enabled = color;
+
if (cli.isNext("generate") || cli.isNext("export") || cli.isNext("ecdh") || cli.isNext("ecdsa") || cli.isNext("test")) {
if (!cli.hasArg(-1)) {
System.err.println("Missing library name argument.");
diff --git a/src/cz/crcs/ectester/standalone/libs/OpensslLib.java b/src/cz/crcs/ectester/standalone/libs/OpensslLib.java
new file mode 100644
index 0000000..e558336
--- /dev/null
+++ b/src/cz/crcs/ectester/standalone/libs/OpensslLib.java
@@ -0,0 +1,19 @@
+package cz.crcs.ectester.standalone.libs;
+
+import java.security.Provider;
+import java.util.Set;
+
+/**
+ * @author Jan Jancar johny@neuromancer.sk
+ */
+public class OpensslLib extends NativeECLibrary {
+ public OpensslLib() {
+ super("openssl_provider", "crypto");
+ }
+
+ @Override
+ native Provider createProvider();
+
+ @Override
+ public native Set<String> getCurves();
+}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/Makefile b/src/cz/crcs/ectester/standalone/libs/jni/Makefile
index 17c1efb..9c3557c 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/Makefile
+++ b/src/cz/crcs/ectester/standalone/libs/jni/Makefile
@@ -42,7 +42,7 @@ CFLAGS+=-fPIC -g -I"$(JNI_INCLUDEDIR)" -I"$(JNI_PLATFORMINCLUDEDIR)" -I.
CXXFLAGS+=-fPIC -g -I"$(JNI_INCLUDEDIR)" -I"$(JNI_PLATFORMINCLUDEDIR)" -I.
-all: tomcrypt_provider.so botan_provider.so cryptopp_provider.so
+all: tomcrypt_provider.so botan_provider.so cryptopp_provider.so openssl_provider.so
# Common utils
c_utils.o: c_utils.c
@@ -52,6 +52,14 @@ cpp_utils.o: cpp_utils.cpp
$(CXX) $(CXXFLAGS) -c $<
+# OpenSSL shim
+openssl_provider.so: openssl.o c_utils.o
+ $(CC) -fPIC -g -shared -o $@ $^ -L. $(shell pkg-config --libs openssl)
+
+openssl.o: openssl.c
+ $(CC) $(shel pkg-config --cflags openssl) $(CFLAGS) -c $<
+
+
# Libtomcrypt shim
tomcrypt_provider.so: tomcrypt.o c_utils.o
$(CC) -fPIC -g -shared -o $@ $^ -L. -ltommath $(shell pkg-config --libs libtomcrypt)
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
index a209fa1..39539df 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
@@ -71,4 +71,10 @@ public abstract class NativeECPrivateKey implements ECPrivateKey {
super(keyData, params);
}
}
+
+ public static class Openssl extends Raw {
+ public Openssl(byte[] keyData, ECParameterSpec params) {
+ super(keyData, params);
+ }
+ }
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
index f53cd26..1085083 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
@@ -73,4 +73,10 @@ public abstract class NativeECPublicKey implements ECPublicKey {
super(keyData, params);
}
}
+
+ public static class Openssl extends ANSIX962 {
+ public Openssl(byte[] keyData, ECParameterSpec params) {
+ super(keyData, params);
+ }
+ }
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
index a7b1a61..6e441e5 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
@@ -155,4 +155,22 @@ public abstract class NativeKeyPairGeneratorSpi extends KeyPairGeneratorSpi {
super("ECDSA");
}
}
+
+ public static class Openssl extends NativeKeyPairGeneratorSpi {
+ public Openssl() {
+ initialize(256, new SecureRandom());
+ }
+
+ @Override
+ native boolean keysizeSupported(int keysize);
+
+ @Override
+ native boolean paramsSupported(AlgorithmParameterSpec params);
+
+ @Override
+ native KeyPair generate(int keysize, SecureRandom random);
+
+ @Override
+ native KeyPair generate(AlgorithmParameterSpec params, SecureRandom random);
+ }
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java
index 593295e..a4967e5 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java
@@ -49,4 +49,14 @@ public abstract class NativeProvider extends Provider {
@Override
native void setup();
}
+
+ public static class Openssl extends NativeProvider {
+
+ public Openssl(String name, double version, String info) {
+ super(name, version, info);
+ }
+
+ @Override
+ native void setup();
+ }
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/botan.cpp b/src/cz/crcs/ectester/standalone/libs/jni/botan.cpp
index 6a1e6d6..a37cb88 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/botan.cpp
+++ b/src/cz/crcs/ectester/standalone/libs/jni/botan.cpp
@@ -20,11 +20,6 @@
static jclass provider_class;
-/*
- * Class: cz_crcs_ectester_standalone_libs_BotanLib
- * Method: createProvider
- * Signature: ()Ljava/security/Provider;
- */
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_createProvider(JNIEnv *env, jobject self) {
/* Create the custom provider. */
jclass local_provider_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/NativeProvider$Botan");
@@ -44,11 +39,6 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_createP
return env->NewObject(provider_class, init, name, version, info);
}
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan
- * Method: setup
- * Signature: ()V
- */
JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Botan_setup(JNIEnv *env, jobject self){
jmethodID provider_put = env->GetMethodID(provider_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
@@ -88,11 +78,6 @@ JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_
init_classes(env, "Botan");
}
-/*
- * Class: cz_crcs_ectester_standalone_libs_BotanLib
- * Method: getCurves
- * Signature: ()Ljava/util/Set;
- */
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_getCurves(JNIEnv *env, jobject self){
jclass set_class = env->FindClass("java/util/TreeSet");
@@ -111,20 +96,10 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_getCurv
return result;
}
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Botan
- * Method: keysizeSupported
- * Signature: (I)Z
- */
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Botan_keysizeSupported(JNIEnv *env, jobject self, jint keysize){
return JNI_TRUE;
}
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Botan
- * Method: paramsSupported
- * Signature: (Ljava/security/spec/AlgorithmParameterSpec;)Z
- */
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Botan_paramsSupported(JNIEnv *env, jobject self, jobject params){
if (params == NULL) {
return JNI_FALSE;
@@ -319,11 +294,6 @@ static jobject generate_from_group(JNIEnv* env, jobject self, Botan::EC_Group gr
return env->NewObject(keypair_class, keypair_init, pubkey, privkey);
}
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Botan
- * Method: generate
- * Signature: (ILjava/security/SecureRandom;)Ljava/security/KeyPair;
- */
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Botan_generate__ILjava_security_SecureRandom_2(JNIEnv *env, jobject self, jint keysize, jobject random){
const std::set<std::string>& curves = Botan::EC_Group::known_named_groups();
for (auto it = curves.begin(); it != curves.end(); ++it) {
@@ -339,21 +309,11 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
return NULL;
}
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Botan
- * Method: generate
- * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)Ljava/security/KeyPair;
- */
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Botan_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random){
Botan::EC_Group curve_group = group_from_params(env, params);
return generate_from_group(env, self, curve_group);
}
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Botan
- * Method: generateSecret
- * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
- */
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Botan_generateSecret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params){
Botan::EC_Group curve_group = group_from_params(env, params);
@@ -420,11 +380,6 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
return result;
}
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Botan
- * Method: sign
- * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
- */
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Botan_sign(JNIEnv *env, jobject self, jbyteArray data, jbyteArray privkey, jobject params){
Botan::EC_Group curve_group = group_from_params(env, params);
@@ -488,11 +443,6 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
return result;
}
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Botan
- * Method: verify
- * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z
- */
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Botan_verify(JNIEnv *env, jobject self, jbyteArray signature, jbyteArray data, jbyteArray pubkey, jobject params){
Botan::EC_Group curve_group = group_from_params(env, params);
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp b/src/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp
index e83f808..0ba026f 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp
+++ b/src/cz/crcs/ectester/standalone/libs/jni/cryptopp.cpp
@@ -70,11 +70,6 @@ using CryptoPP::Integer;
static jclass provider_class;
-/*
- * Class: cz_crcs_ectester_standalone_libs_CryptoppLib
- * Method: createProvider
- * Signature: ()Ljava/security/Provider;
- */
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_createProvider(JNIEnv *env, jobject self) {
/* Create the custom provider. */
jclass local_provider_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/NativeProvider$Cryptopp");
@@ -100,11 +95,6 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_crea
return env->NewObject(provider_class, init, name, version, info);
}
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp
- * Method: setup
- * Signature: ()V
- */
JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Cryptopp_setup(JNIEnv *env, jobject self){
jmethodID provider_put = env->GetMethodID(provider_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
@@ -157,11 +147,6 @@ static std::string oid_to_str(const OID &oid) {
return ss.str();
}
-/*
- * Class: cz_crcs_ectester_standalone_libs_CryptoppLib
- * Method: getCurves
- * Signature: ()Ljava/util/Set;
- */
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_getCurves(JNIEnv *env, jobject self){
jclass set_class = env->FindClass("java/util/TreeSet");
@@ -180,11 +165,6 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_getC
return result;
}
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Cryptopp
- * Method: keysizeSupported
- * Signature: (I)Z
- */
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Cryptopp_keysizeSupported(JNIEnv *env, jobject self, jint keysize){
std::vector<OID> ecp_oids = get_curve_oids<ECP>();
for (auto oid = ecp_oids.begin(); oid != ecp_oids.end(); ++oid) {
@@ -204,11 +184,6 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPa
return JNI_FALSE;
}
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Cryptopp
- * Method: paramsSupported
- * Signature: (Ljava/security/spec/AlgorithmParameterSpec;)Z
- */
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Cryptopp_paramsSupported(JNIEnv *env, jobject self, jobject params){
if (params == NULL) {
return JNI_FALSE;
@@ -546,11 +521,6 @@ template <class EC> jobject generate_from_group(JNIEnv *env, DL_GroupParameters_
return env->NewObject(keypair_class, keypair_init, pubkey, privkey);
}
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Cryptopp
- * Method: generate
- * Signature: (ILjava/security/SecureRandom;)Ljava/security/KeyPair;
- */
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Cryptopp_generate__ILjava_security_SecureRandom_2(JNIEnv *env, jobject self, jint keysize, jobject random){
std::vector<OID> ecp_oids = get_curve_oids<ECP>();
for (auto oid = ecp_oids.begin(); oid != ecp_oids.end(); ++oid) {
@@ -572,11 +542,6 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
return NULL;
}
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Cryptopp
- * Method: generate
- * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)Ljava/security/KeyPair;
- */
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Cryptopp_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random) {
std::unique_ptr<DL_GroupParameters_EC<ECP>> ecp_group = fp_group_from_params(env, params);
if (ecp_group == nullptr) {
@@ -588,12 +553,6 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
return NULL;
}
-
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Cryptopp
- * Method: generateSecret
- * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
- */
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Cryptopp_generateSecret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params) {
jsize privkey_length = env->GetArrayLength(privkey);
jbyte *privkey_data = env->GetByteArrayElements(privkey, NULL);
@@ -663,12 +622,6 @@ jbyteArray sign_message(JNIEnv *env, DL_GroupParameters_EC<EC> group, jbyteArray
return result;
}
-
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Cryptopp
- * Method: sign
- * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
- */
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Cryptopp_sign(JNIEnv *env, jobject self, jbyteArray data, jbyteArray privkey, jobject params) {
jclass cryptopp_sig_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi$Cryptopp");
jfieldID type_id = env->GetFieldID(cryptopp_sig_class, "type", "Ljava/lang/String;");
@@ -715,7 +668,6 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
return result;
}
-
template <class EC, class H>
jboolean verify_message(JNIEnv *env, DL_GroupParameters_EC<EC> group, jbyteArray data, jbyteArray signature, jbyteArray pubkey) {
typename EC::Point pkey_point;
@@ -739,11 +691,6 @@ jboolean verify_message(JNIEnv *env, DL_GroupParameters_EC<EC> group, jbyteArray
return result;
}
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Cryptopp
- * Method: verify
- * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z
- */
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Cryptopp_verify(JNIEnv *env, jobject self, jbyteArray signature, jbyteArray data, jbyteArray pubkey, jobject params) {
jclass cryptopp_sig_class = env->FindClass("cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi$Cryptopp");
jfieldID type_id = env->GetFieldID(cryptopp_sig_class, "type", "Ljava/lang/String;");
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/native.h b/src/cz/crcs/ectester/standalone/libs/jni/native.h
index 9385a4b..6aacdd3 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/native.h
+++ b/src/cz/crcs/ectester/standalone/libs/jni/native.h
@@ -513,3 +513,128 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
}
#endif
#endif
+/* Header for class cz_crcs_ectester_standalone_libs_OpensslLib */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_OpensslLib
+#define _Included_cz_crcs_ectester_standalone_libs_OpensslLib
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_OpensslLib
+ * Method: createProvider
+ * Signature: ()Ljava/security/Provider;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_createProvider
+ (JNIEnv *, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_OpensslLib
+ * Method: getCurves
+ * Signature: ()Ljava/util/Set;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_getCurves
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID 1421746759512286392LL
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_MAX_ARRAY_SIZE
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_MAX_ARRAY_SIZE 2147483639L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_KEYS
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_KEYS 0L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_VALUES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_VALUES 1L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_ENTRIES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_ENTRIES 2L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID 4112578634029874840LL
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID -4298000515446427739LL
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl
+ * Method: setup
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Openssl_setup
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl
+ * Method: keysizeSupported
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_keysizeSupported
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl
+ * Method: paramsSupported
+ * Signature: (Ljava/security/spec/AlgorithmParameterSpec;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_paramsSupported
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl
+ * Method: generate
+ * Signature: (ILjava/security/SecureRandom;)Ljava/security/KeyPair;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_generate__ILjava_security_SecureRandom_2
+ (JNIEnv *, jobject, jint, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Openssl
+ * Method: generate
+ * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)Ljava/security/KeyPair;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2
+ (JNIEnv *, jobject, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Openssl */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Openssl
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Openssl
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Openssl */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Openssl
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Openssl
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/openssl.c b/src/cz/crcs/ectester/standalone/libs/jni/openssl.c
new file mode 100644
index 0000000..ae6a222
--- /dev/null
+++ b/src/cz/crcs/ectester/standalone/libs/jni/openssl.c
@@ -0,0 +1,393 @@
+#include "native.h"
+#include <string.h>
+#include <stdio.h>
+
+#include <openssl/conf.h>
+#include <openssl/opensslv.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/ec.h>
+#include <openssl/obj_mac.h>
+#include <openssl/bn.h>
+
+#include "c_utils.h"
+
+
+static jclass provider_class;
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_createProvider(JNIEnv *env, jobject self) {
+ /* Create the custom provider. */
+ jclass local_provider_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeProvider$Openssl");
+ provider_class = (*env)->NewGlobalRef(env, local_provider_class);
+
+ jmethodID init = (*env)->GetMethodID(env, local_provider_class, "<init>", "(Ljava/lang/String;DLjava/lang/String;)V");
+
+ jstring name = (*env)->NewStringUTF(env, OPENSSL_VERSION_TEXT);
+ double version = ((double)((OPENSSL_VERSION_NUMBER & 0xff000000L) >> 30)) + ((double)((OPENSSL_VERSION_NUMBER & 0xff0000L) >> 20));
+
+ return (*env)->NewObject(env, provider_class, init, name, version, name);
+}
+
+JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Openssl_setup(JNIEnv *env, jobject self) {
+ OPENSSL_no_config();
+ ERR_load_crypto_strings();
+ OpenSSL_add_all_algorithms();
+
+ jmethodID provider_put = (*env)->GetMethodID(env, provider_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+
+ jstring ec = (*env)->NewStringUTF(env, "KeyPairGenerator.EC");
+ jstring ec_value = (*env)->NewStringUTF(env, "cz.crcs.ectester.standalone.libs.jni.NativeKeyPairGeneratorSpi$Openssl");
+ (*env)->CallObjectMethod(env, self, provider_put, ec, ec_value);
+
+ init_classes(env, "Openssl");
+}
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_getCurves(JNIEnv *env, jobject self) {
+ jclass hash_set_class = (*env)->FindClass(env, "java/util/TreeSet");
+
+ jmethodID hash_set_ctr = (*env)->GetMethodID(env, hash_set_class, "<init>", "()V");
+ jmethodID hash_set_add = (*env)->GetMethodID(env, hash_set_class, "add", "(Ljava/lang/Object;)Z");
+
+ jobject result = (*env)->NewObject(env, hash_set_class, hash_set_ctr);
+
+ size_t ncurves = EC_get_builtin_curves(NULL, 0);
+ EC_builtin_curve curves[ncurves];
+ EC_get_builtin_curves(curves, ncurves);
+
+ for (size_t i = 0; i < ncurves; ++i) {
+ jstring curve_name = (*env)->NewStringUTF(env, OBJ_nid2sn(curves[i].nid));
+ (*env)->CallBooleanMethod(env, result, hash_set_add, curve_name);
+ }
+
+ return result;
+}
+
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_keysizeSupported(JNIEnv *env, jobject self, jint keysize) {
+ size_t ncurves = EC_get_builtin_curves(NULL, 0);
+ EC_builtin_curve curves[ncurves];
+ EC_get_builtin_curves(curves, ncurves);
+
+ for (size_t i = 0; i < ncurves; ++i) {
+ EC_GROUP *curve = EC_GROUP_new_by_curve_name(curves[i].nid);
+ if (EC_GROUP_get_degree(curve) == keysize) {
+ EC_GROUP_clear_free(curve);
+ return JNI_TRUE;
+ }
+ EC_GROUP_free(curve);
+ }
+ return JNI_FALSE;
+}
+
+static jobject bignum_to_biginteger(JNIEnv *env, const BIGNUM *bn) {
+ jmethodID biginteger_init = (*env)->GetMethodID(env, biginteger_class, "<init>", "(I[B)V");
+ int size = BN_num_bytes(bn);
+ jbyteArray bytes = (*env)->NewByteArray(env, size);
+ jbyte *data = (*env)->GetByteArrayElements(env, bytes, NULL);
+ BN_bn2bin(bn, data);
+ (*env)->ReleaseByteArrayElements(env, bytes, data, JNI_COMMIT);
+ jobject result = (*env)->NewObject(env, biginteger_class, biginteger_init, 0, bytes);
+ return result;
+}
+
+static BIGNUM *biginteger_to_bignum(JNIEnv *env, jobject bigint) {
+ jmethodID to_byte_array = (*env)->GetMethodID(env, biginteger_class, "toByteArray", "()[B");
+
+ jbyteArray byte_array = (jbyteArray) (*env)->CallObjectMethod(env, bigint, to_byte_array);
+ jsize byte_length = (*env)->GetArrayLength(env, byte_array);
+ jbyte *byte_data = (*env)->GetByteArrayElements(env, byte_array, NULL);
+ BIGNUM *result = BN_bin2bn(byte_data, byte_length, NULL);
+ (*env)->ReleaseByteArrayElements(env, byte_array, byte_data, JNI_ABORT);
+ return result;
+}
+
+static EC_GROUP *create_curve(JNIEnv *env, jobject params) {
+ jmethodID get_curve = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCurve", "()Ljava/security/spec/EllipticCurve;");
+ jobject elliptic_curve = (*env)->CallObjectMethod(env, params, get_curve);
+
+ jmethodID get_field = (*env)->GetMethodID(env, elliptic_curve_class, "getField", "()Ljava/security/spec/ECField;");
+ jobject field = (*env)->CallObjectMethod(env, elliptic_curve, get_field);
+
+ jmethodID get_bits = (*env)->GetMethodID(env, fp_field_class, "getFieldSize", "()I");
+ jint bits = (*env)->CallIntMethod(env, field, get_bits);
+ jint bytes = (bits + 7) / 8;
+
+ jmethodID get_a = (*env)->GetMethodID(env, elliptic_curve_class, "getA", "()Ljava/math/BigInteger;");
+ jobject a = (*env)->CallObjectMethod(env, elliptic_curve, get_a);
+ BIGNUM *a_bn = biginteger_to_bignum(env, a);
+
+ jmethodID get_b = (*env)->GetMethodID(env, elliptic_curve_class, "getB", "()Ljava/math/BigInteger;");
+ jobject b = (*env)->CallObjectMethod(env, elliptic_curve, get_b);
+ BIGNUM *b_bn = biginteger_to_bignum(env, b);
+
+ jmethodID get_g = (*env)->GetMethodID(env, ec_parameter_spec_class, "getGenerator", "()Ljava/security/spec/ECPoint;");
+ jobject g = (*env)->CallObjectMethod(env, params, get_g);
+
+ jmethodID get_x = (*env)->GetMethodID(env, point_class, "getAffineX", "()Ljava/math/BigInteger;");
+ jobject gx = (*env)->CallObjectMethod(env, g, get_x);
+ BIGNUM *gx_bn = biginteger_to_bignum(env, gx);
+
+ jmethodID get_y = (*env)->GetMethodID(env, point_class, "getAffineY", "()Ljava/math/BigInteger;");
+ jobject gy = (*env)->CallObjectMethod(env, g, get_y);
+ BIGNUM *gy_bn = biginteger_to_bignum(env, gy);
+
+ EC_GROUP *result;
+ EC_POINT *g_point;
+
+ if ((*env)->IsInstanceOf(env, field, fp_field_class)) {
+ jmethodID get_p = (*env)->GetMethodID(env, fp_field_class, "getP", "()Ljava/math/BigInteger;");
+ jobject p = (*env)->CallObjectMethod(env, field, get_p);
+
+ BIGNUM *p_bn = biginteger_to_bignum(env, p);
+ result = EC_GROUP_new_curve_GFp(p_bn, a_bn, b_bn, NULL);
+ BN_free(p_bn);
+
+ g_point = EC_POINT_new(result);
+ EC_POINT_set_affine_coordinates_GFp(result, g_point, gx_bn, gy_bn, NULL);
+ } else if ((*env)->IsInstanceOf(env, field, f2m_field_class)) {
+
+ jmethodID get_reduction_poly = (*env)->GetMethodID(env, f2m_field_class, "getReductionPolynomial", "()Ljava/math/BigInteger;");
+ jobject red_poly = (*env)->CallObjectMethod(env, field, get_reduction_poly);
+
+ BIGNUM *p_bn = biginteger_to_bignum(env, red_poly);
+ result = EC_GROUP_new_curve_GF2m(p_bn, a_bn, b_bn, NULL);
+ BN_free(p_bn);
+
+ g_point = EC_POINT_new(result);
+ EC_POINT_set_affine_coordinates_GF2m(result, g_point, gx_bn, gy_bn, NULL);
+ } else {
+ return NULL;
+ }
+
+ BN_free(a_bn);
+ BN_free(b_bn);
+
+ jmethodID get_n = (*env)->GetMethodID(env, ec_parameter_spec_class, "getOrder", "()Ljava/math/BigInteger;");
+ jobject n = (*env)->CallObjectMethod(env, params, get_n);
+ BIGNUM *n_bn = biginteger_to_bignum(env, n);
+
+ jmethodID get_h = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCofactor", "()I");
+ jint h = (*env)->CallIntMethod(env, params, get_h);
+ BIGNUM *h_bn = BN_new();
+ BN_set_word(h_bn, h);
+
+ EC_GROUP_set_generator(result, g_point, n_bn, h_bn);
+
+ BN_free(gx_bn);
+ BN_free(gy_bn);
+ BN_free(n_bn);
+ BN_free(h_bn);
+
+ return result;
+}
+
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_paramsSupported(JNIEnv *env, jobject self, jobject params){
+ if (params == NULL) {
+ return JNI_FALSE;
+ }
+
+ if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
+ EC_GROUP *curve = create_curve(env, params);
+ jboolean result = (EC_GROUP_check(curve, NULL) == 1) ? JNI_TRUE : JNI_FALSE;
+ EC_GROUP_free(curve);
+ return result;
+ } 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);
+ size_t ncurves = EC_get_builtin_curves(NULL, 0);
+ EC_builtin_curve curves[ncurves];
+ EC_get_builtin_curves(curves, ncurves);
+ for (size_t i = 0; i < ncurves; ++i) {
+ if (strcasecmp(utf_name, OBJ_nid2sn(curves[i].nid)) == 0) {
+ (*env)->ReleaseStringUTFChars(env, name, utf_name);
+ return JNI_TRUE;
+ }
+ }
+ (*env)->ReleaseStringUTFChars(env, name, utf_name);
+ return JNI_FALSE;
+ } else {
+ return JNI_FALSE;
+ }
+}
+
+static jobject create_ec_param_spec(JNIEnv *env, const EC_GROUP *curve) {
+ int field_type = EC_METHOD_get_field_type(EC_GROUP_method_of(curve));
+ BIGNUM *a;
+ BIGNUM *b;
+
+ BIGNUM *gx;
+ BIGNUM *gy;
+ jobject field;
+
+ if (field_type == NID_X9_62_prime_field) {
+ BIGNUM *p = BN_new();
+ a = BN_new();
+ b = BN_new();
+ EC_GROUP_get_curve_GFp(curve, p, a, b, NULL);
+
+ jobject p_int = bignum_to_biginteger(env, p);
+
+ jmethodID fp_field_init = (*env)->GetMethodID(env, fp_field_class, "<init>", "(Ljava/math/BigInteger;)V");
+ field = (*env)->NewObject(env, fp_field_class, fp_field_init, p_int);
+
+ BN_free(p);
+
+ gx = BN_new();
+ gy = BN_new();
+ EC_POINT_get_affine_coordinates_GFp(curve, EC_GROUP_get0_generator(curve), gx, gy, NULL);
+
+ } else if (field_type == NID_X9_62_characteristic_two_field) {
+ a = BN_new();
+ b = BN_new();
+ EC_GROUP_get_curve_GF2m(curve, NULL, a, b, NULL);
+
+ int basis_type = EC_GROUP_get_basis_type(curve);
+ jintArray ks;
+ jint *ks_data;
+ if (basis_type == NID_X9_62_tpBasis) {
+ ks = (*env)->NewIntArray(env, 1);
+ ks_data = (*env)->GetIntArrayElements(env, ks, NULL);
+ EC_GROUP_get_trinomial_basis(curve, &ks_data[0]);
+ } else if (basis_type == NID_X9_62_ppBasis) {
+ ks = (*env)->NewIntArray(env, 3);
+ ks_data = (*env)->GetIntArrayElements(env, ks, NULL);
+ EC_GROUP_get_pentanomial_basis(curve, &ks_data[0], &ks_data[1], &ks_data[2]);
+ } else {
+ return NULL;
+ }
+ (*env)->ReleaseIntArrayElements(env, ks, ks_data, JNI_COMMIT);
+
+ jint m = EC_GROUP_get_degree(curve);
+
+ jmethodID f2m_field_init = (*env)->GetMethodID(env, f2m_field_class, "<init>", "(I[I)V");
+ field = (*env)->NewObject(env, f2m_field_class, f2m_field_init, m, ks);
+
+ gx = BN_new();
+ gy = BN_new();
+ EC_POINT_get_affine_coordinates_GF2m(curve, EC_GROUP_get0_generator(curve), gx, gy, NULL);
+ } else {
+ return NULL;
+ }
+
+ jobject a_int = bignum_to_biginteger(env, a);
+ jobject b_int = bignum_to_biginteger(env, b);
+
+ jmethodID elliptic_curve_init = (*env)->GetMethodID(env, elliptic_curve_class, "<init>", "(Ljava/security/spec/ECField;Ljava/math/BigInteger;Ljava/math/BigInteger;)V");
+ jobject elliptic_curve = (*env)->NewObject(env, elliptic_curve_class, elliptic_curve_init, field, a_int, b_int);
+ fprintf(stderr, "field: %p, a_int: %p, b_int: %p\n", field, a_int, b_int);
+ fflush(stderr);
+
+ BN_free(a);
+ BN_free(b);
+
+ jobject gx_int = bignum_to_biginteger(env, gx);
+ jobject gy_int = bignum_to_biginteger(env, gy);
+
+ BN_free(gx);
+ BN_free(gy);
+
+ jmethodID point_init = (*env)->GetMethodID(env, point_class, "<init>", "(Ljava/math/BigInteger;Ljava/math/BigInteger;)V");
+ jobject g = (*env)->NewObject(env, point_class, point_init, gx_int, gy_int);
+
+ jobject order = bignum_to_biginteger(env, EC_GROUP_get0_order(curve));
+ jint cofactor = BN_get_word(EC_GROUP_get0_cofactor(curve));
+
+ jmethodID ec_parameter_spec_init = (*env)->GetMethodID(env, ec_parameter_spec_class, "<init>", "(Ljava/security/spec/EllipticCurve;Ljava/security/spec/ECPoint;Ljava/math/BigInteger;I)V");
+ return (*env)->NewObject(env, ec_parameter_spec_class, ec_parameter_spec_init, elliptic_curve, g, order, cofactor);
+}
+
+static jobject generate_from_curve(JNIEnv *env, const EC_GROUP *curve) {
+ jint keysize = EC_GROUP_get_degree(curve);
+ unsigned long key_bytes = (keysize + 7) / 8;
+
+ EC_KEY *key = EC_KEY_new();
+ EC_KEY_set_group(key, curve);
+ EC_KEY_generate_key(key);
+
+ jbyteArray priv_bytes = (*env)->NewByteArray(env, key_bytes);
+ jbyte *key_priv = (*env)->GetByteArrayElements(env, priv_bytes, NULL);
+ BN_bn2binpad(EC_KEY_get0_private_key(key), key_priv, key_bytes);
+ (*env)->ReleaseByteArrayElements(env, priv_bytes, key_priv, JNI_COMMIT);
+
+ unsigned long key_len = 2*keysize + 1;
+ jbyteArray pub_bytes = (*env)->NewByteArray(env, key_len);
+ jbyte *key_pub = (*env)->GetByteArrayElements(env, pub_bytes, NULL);
+ EC_POINT_point2oct(curve, EC_KEY_get0_public_key(key), POINT_CONVERSION_UNCOMPRESSED, key_pub, key_len, NULL);
+ (*env)->ReleaseByteArrayElements(env, pub_bytes, key_pub, JNI_COMMIT);
+
+ EC_KEY_free(key);
+
+ jobject ec_param_spec = create_ec_param_spec(env, curve);
+
+ jobject ec_pub_param_spec = (*env)->NewLocalRef(env, ec_param_spec);
+ jmethodID ec_pub_init = (*env)->GetMethodID(env, pubkey_class, "<init>", "([BLjava/security/spec/ECParameterSpec;)V");
+ jobject pubkey = (*env)->NewObject(env, pubkey_class, ec_pub_init, pub_bytes, ec_param_spec);
+
+ jobject ec_priv_param_spec = (*env)->NewLocalRef(env, ec_param_spec);
+ jmethodID ec_priv_init = (*env)->GetMethodID(env, privkey_class, "<init>", "([BLjava/security/spec/ECParameterSpec;)V");
+ jobject privkey = (*env)->NewObject(env, privkey_class, ec_priv_init, priv_bytes, ec_priv_param_spec);
+
+ jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "<init>", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V");
+ return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
+}
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_generate__ILjava_security_SecureRandom_2(JNIEnv *env, jobject self, jint keysize, jobject random) {
+ size_t ncurves = EC_get_builtin_curves(NULL, 0);
+ EC_builtin_curve curves[ncurves];
+ EC_get_builtin_curves(curves, ncurves);
+
+ EC_GROUP *curve = NULL;
+ for (size_t i = 0; i < ncurves; ++i) {
+ curve = EC_GROUP_new_by_curve_name(curves[i].nid);
+ if (EC_GROUP_get_degree(curve) == keysize) {
+ break;
+ }
+ EC_GROUP_free(curve);
+ }
+
+ if (!curve) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve for given bitsize not found.");
+ return NULL;
+ }
+
+ jobject result = generate_from_curve(env, curve);
+ EC_GROUP_free(curve);
+ return result;
+}
+
+
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Openssl_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random) {
+ if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
+ EC_GROUP *curve = create_curve(env, params);
+ jobject result = generate_from_curve(env, curve);
+ EC_GROUP_free(curve);
+ return result;
+ } 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);
+ size_t ncurves = EC_get_builtin_curves(NULL, 0);
+ EC_builtin_curve curves[ncurves];
+ EC_get_builtin_curves(curves, ncurves);
+ EC_GROUP *curve;
+ for (size_t i = 0; i < ncurves; ++i) {
+ if (strcasecmp(utf_name, OBJ_nid2sn(curves[i].nid)) == 0) {
+ curve = EC_GROUP_new_by_curve_name(curves[i].nid);
+ break;
+ }
+ }
+ (*env)->ReleaseStringUTFChars(env, name, utf_name);
+ if (!curve) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve for given bitsize not found.");
+ return NULL;
+ }
+ jobject result = generate_from_curve(env, curve);
+ EC_GROUP_free(curve);
+ return result;
+ } else {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found.");
+ return NULL;
+ }
+} \ No newline at end of file
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c b/src/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c
index 29ee707..dc3abd9 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c
@@ -128,6 +128,7 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPa
}
curve++;
}
+ (*env)->ReleaseStringUTFChars(env, name, utf_name);
return JNI_FALSE;
} else {
return JNI_FALSE;
diff --git a/src/cz/crcs/ectester/standalone/output/TextTestWriter.java b/src/cz/crcs/ectester/standalone/output/TextTestWriter.java
index 2e29b07..93be3a8 100644
--- a/src/cz/crcs/ectester/standalone/output/TextTestWriter.java
+++ b/src/cz/crcs/ectester/standalone/output/TextTestWriter.java
@@ -1,5 +1,6 @@
package cz.crcs.ectester.standalone.output;
+import cz.crcs.ectester.common.cli.Colors;
import cz.crcs.ectester.common.output.BaseTextTestWriter;
import cz.crcs.ectester.common.test.TestSuite;
import cz.crcs.ectester.common.test.Testable;
@@ -45,8 +46,8 @@ public class TextTestWriter extends BaseTextTestWriter {
if (suite instanceof StandaloneTestSuite) {
StandaloneTestSuite standaloneSuite = (StandaloneTestSuite) suite;
StringBuilder sb = new StringBuilder();
- sb.append("═══ ECTester version: " + ECTesterStandalone.VERSION).append(System.lineSeparator());
- sb.append("═══ ").append(standaloneSuite.getLibrary().name()).append(System.lineSeparator());
+ sb.append("═══ ").append(Colors.underline("ECTester version:")).append(" ").append(ECTesterStandalone.VERSION).append(System.lineSeparator());
+ sb.append("═══ ").append(Colors.underline("Library:")).append(standaloneSuite.getLibrary().name()).append(System.lineSeparator());
return sb.toString();
}
return "";