aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatěj Grabovský2019-11-18 17:17:25 +0100
committerMatěj Grabovský2019-12-08 19:05:19 +0100
commitbd5dd3aa41bacd96d2c3b5982ee31ca10e665c2c (patch)
tree2ae3e3b26eb12b93dfb19966d527463969d699a3
parent13eb7884878ff10aa0a768077166710861af2fcc (diff)
downloadECTester-bd5dd3aa41bacd96d2c3b5982ee31ca10e665c2c.tar.gz
ECTester-bd5dd3aa41bacd96d2c3b5982ee31ca10e665c2c.tar.zst
ECTester-bd5dd3aa41bacd96d2c3b5982ee31ca10e665c2c.zip
-rw-r--r--.gitmodules3
-rw-r--r--build-standalone.xml7
m---------ext/libressl0
-rw-r--r--src/cz/crcs/ectester/standalone/ECTesterStandalone.java5
-rw-r--r--src/cz/crcs/ectester/standalone/libs/LibresslLib.java19
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/Makefile18
-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/NativeKeyAgreementSpi.java20
-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/NativeSignatureSpi.java21
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/libressl.c537
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/native.h200
14 files changed, 846 insertions, 24 deletions
diff --git a/.gitmodules b/.gitmodules
index bab94d9..5d6d62f 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -10,3 +10,6 @@
[submodule "ext/boringssl"]
path = ext/boringssl
url = https://boringssl.googlesource.com/boringssl
+[submodule "ext/libressl"]
+ path = ext/libressl
+ url = https://github.com/libressl-portable/portable
diff --git a/build-standalone.xml b/build-standalone.xml
index d3b3cf5..844a199 100644
--- a/build-standalone.xml
+++ b/build-standalone.xml
@@ -206,6 +206,13 @@
<class name="cz.crcs.ectester.standalone.libs.jni.NativeECPrivateKey$Matrixssl"/>
<class name="cz.crcs.ectester.standalone.libs.jni.NativeKeyAgreementSpi$Matrixssl"/>
<class name="cz.crcs.ectester.standalone.libs.jni.NativeSignatureSpi$Matrixssl"/>
+ <class name="cz.crcs.ectester.standalone.libs.LibresslLib"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeProvider$Libressl"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeKeyPairGeneratorSpi$Libressl"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeECPublicKey$Libressl"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeECPrivateKey$Libressl"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeKeyAgreementSpi$Libressl"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeSignatureSpi$Libressl"/>
</javah>
</target>
</project>
diff --git a/ext/libressl b/ext/libressl
new file mode 160000
+Subproject 5542c1828a53a0fd28b754f68a8a5c80848e424
diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
index 3023c98..3049a70 100644
--- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
+++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
@@ -82,7 +82,8 @@ public class ECTesterStandalone {
new WolfCryptLib(),
new MbedTLSLib(),
new IppcpLib(),
- new MatrixsslLib()};
+ new MatrixsslLib(),
+ new LibresslLib()};
private Config cfg;
private Options opts = new Options();
@@ -736,8 +737,6 @@ public class ECTesterStandalone {
break;
}
- String suiteName = cli.getArg(0);
-
StandaloneTestSuite suite = new StandaloneDefaultSuite(writer, cfg, cli);
suite.run();
}
diff --git a/src/cz/crcs/ectester/standalone/libs/LibresslLib.java b/src/cz/crcs/ectester/standalone/libs/LibresslLib.java
new file mode 100644
index 0000000..cee4e4d
--- /dev/null
+++ b/src/cz/crcs/ectester/standalone/libs/LibresslLib.java
@@ -0,0 +1,19 @@
+package cz.crcs.ectester.standalone.libs;
+
+import java.security.Provider;
+import java.util.Set;
+
+/**
+ * @author Matěj Grabovský matej@mgrabovsky.net
+ */
+public class LibresslLib extends NativeECLibrary {
+ public LibresslLib() {
+ super("libressl_provider", "lib_libressl.so");
+ }
+
+ @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 c884dc5..aa24460 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/Makefile
+++ b/src/cz/crcs/ectester/standalone/libs/jni/Makefile
@@ -58,7 +58,7 @@ JNI_PLATFORMINCLUDEDIR ?= $(JNI_INCLUDEDIR)/$(JNI_PLATFORM)
###############################################################################
## Targets.
-all: tomcrypt botan cryptopp openssl boringssl gcrypt mbedtls ippcp matrixssl
+all: tomcrypt botan cryptopp openssl boringssl gcrypt mbedtls ippcp matrixssl libressl
# Common utils
c_utils.o: c_utils.c
@@ -165,6 +165,19 @@ matrixssl.o: matrixssl.c
$(CC) $(CFLAGS) -Imatrixssl/ -c $<
+# LibreSSL shim
+libressl: libressl_provider.so
+
+lib_libressl.so:
+ cp ../../../../../../../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.o: libressl.c
+ $(CC) -I../../../../../../../ext/libressl/include/ $(CFLAGS) -c $<
+
+
help:
@echo "# This makefile builds the JNI shims necessary to test native libraries."
@echo "# Targets:"
@@ -177,9 +190,10 @@ help:
@echo " - mbedtls"
@echo " - ippcp"
@echo " - matrixssl"
+ @echo " - libressl"
clean:
rm -rf *.o
rm -rf *.so
-.PHONY: all help clean openssl boringssl gcrypt tomcrypt botan cryptopp mbedtls ippcp matrixssl \ No newline at end of file
+.PHONY: all help clean openssl boringssl gcrypt tomcrypt botan cryptopp mbedtls ippcp matrixssl libressl
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
index 088f876..ef26b8c 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
@@ -115,6 +115,12 @@ public abstract class NativeECPrivateKey implements ECPrivateKey {
}
}
+ public static class Libressl extends Raw {
+ public Libressl(byte[] keyData, ECParameterSpec params) {
+ super(keyData, params);
+ }
+ }
+
public static class Mscng extends Raw {
// 0 -> implicit (meta = curveName UTF16, header = full);
// 1 -> explicit (meta = null, header = full);
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
index 577de44..62db5c4 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
@@ -116,6 +116,12 @@ public abstract class NativeECPublicKey implements ECPublicKey {
}
}
+ public static class Libressl extends ANSIX962 {
+ public Libressl(byte[] keyData, ECParameterSpec params) {
+ super(keyData, params);
+ }
+ }
+
public static class Mscng extends ANSIX962 {
// 0 -> implicit (meta = curveName UTF16, header = full);
// 1 -> explicit (meta = null, header = full);
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
index f5fdebf..dda9af8 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
@@ -373,4 +373,24 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
}
}
+ public abstract static class Libressl extends SimpleKeyAgreementSpi {
+ private String type;
+
+ public Libressl(String type) {
+ this.type = type;
+ }
+
+ @Override
+ native byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params);
+
+ @Override
+ native SecretKey generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params, String algorithm);
+ }
+
+ public static class LibresslECDH extends Libressl {
+ public LibresslECDH() {
+ super("ECDH");
+ }
+ }
+
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
index 963f871..3598d61 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
@@ -306,4 +306,22 @@ public abstract class NativeKeyPairGeneratorSpi extends KeyPairGeneratorSpi {
@Override
native KeyPair generate(AlgorithmParameterSpec params, SecureRandom random);
}
+
+ public static class Libressl extends NativeKeyPairGeneratorSpi {
+ public Libressl() {
+ 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 979e347..1a67e1f 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java
@@ -123,4 +123,14 @@ public abstract class NativeProvider extends Provider {
@Override
native void setup();
}
+
+ public static class Libressl extends NativeProvider {
+
+ public Libressl(String name, double version, String info) {
+ super(name, version, info);
+ }
+
+ @Override
+ native void setup();
+ }
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
index 81203d1..36cefdc 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
@@ -482,6 +482,27 @@ public abstract class NativeSignatureSpi extends SignatureSpi {
}
}
+ public abstract static class Libressl extends SimpleSignatureSpi {
+ private String type;
+
+ public Libressl(String type) {
+ this.type = type;
+ }
+
+ @Override
+ native byte[] sign(byte[] data, byte[] privkey, ECParameterSpec params);
+
+ @Override
+ native boolean verify(byte[] signature, byte[] data, byte[] pubkey, ECParameterSpec params);
+ }
+
+ public static class LibresslECDSAwithNONE extends Libressl {
+
+ public LibresslECDSAwithNONE() {
+ super("NONEwithECDSA");
+ }
+ }
+
public abstract static class Matrixssl extends SimpleSignatureSpi {
private String type;
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/libressl.c b/src/cz/crcs/ectester/standalone/libs/jni/libressl.c
new file mode 100644
index 0000000..6953bf2
--- /dev/null
+++ b/src/cz/crcs/ectester/standalone/libs/jni/libressl.c
@@ -0,0 +1,537 @@
+#include "native.h"
+#include <string.h>
+
+#include <openssl/conf.h>
+#include <openssl/opensslv.h>
+#include <openssl/objects.h>
+#include <openssl/obj_mac.h>
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/ec.h>
+#include <openssl/ecdh.h>
+#include <openssl/ecdsa.h>
+
+#include "c_utils.h"
+#include "c_timing.h"
+
+
+static jclass provider_class;
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_LibresslLib_createProvider(JNIEnv *env, jobject self) {
+ /* Create the custom provider. */
+ jclass local_provider_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeProvider$Libressl");
+ 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, LIBRESSL_VERSION_TEXT);
+ long ver_hi = (LIBRESSL_VERSION_NUMBER & 0xff000000L) >> 28;
+ long ver_mid = (LIBRESSL_VERSION_NUMBER & 0x00ff0000L) >> 20;
+ long ver_low = (LIBRESSL_VERSION_NUMBER & 0x0000ff00L) >> 12;
+ double version = (double)ver_hi + ((double)ver_mid/10) + ((double)ver_low/100);
+
+ return (*env)->NewObject(env, provider_class, init, name, version, name);
+}
+
+JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Libressl_setup(JNIEnv *env, jobject self) {
+ OPENSSL_init_crypto(0, NULL);
+
+ INIT_PROVIDER(env, provider_class);
+
+ ADD_KPG(env, self, "EC", "Libressl");
+ ADD_KA(env, self, "ECDH", "LibresslECDH");
+ ADD_SIG(env, self, "NONEwithECDSA", "LibresslECDSAwithNONE");
+
+ init_classes(env, "Libressl");
+}
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_LibresslLib_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_00024Libressl_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_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, (unsigned char *) data);
+ (*env)->ReleaseByteArrayElements(env, bytes, data, 0);
+ jobject result = (*env)->NewObject(env, biginteger_class, biginteger_init, 1, 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((unsigned char *) 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);
+
+ if ((*env)->IsInstanceOf(env, field, f2m_field_class)) {
+ return NULL;
+ }
+
+ 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;
+
+ 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);
+ BN_free(a_bn);
+ BN_free(b_bn);
+
+ if (!result) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Error creating EC_GROUP, EC_GROUP_new_curve_GFp.");
+ BN_free(gx_bn); BN_free(gy_bn);
+ return NULL;
+ }
+
+ g_point = EC_POINT_new(result);
+ if(!EC_POINT_set_affine_coordinates_GFp(result, g_point, gx_bn, gy_bn, NULL)) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Error creating EC_GROUP, EC_POINT_set_affine_coordinates_GFp.");
+ BN_free(gx_bn); BN_free(gy_bn); EC_POINT_free(g_point); EC_GROUP_free(result);
+ return NULL;
+ }
+
+ 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);
+
+ if (!EC_GROUP_set_generator(result, g_point, n_bn, h_bn)) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Error creating EC_GROUP, EC_GROUP_set_generator.");
+ BN_free(n_bn); BN_free(h_bn); BN_free(gx_bn); BN_free(gy_bn); EC_POINT_free(g_point); EC_GROUP_free(result);
+ return NULL;
+ }
+
+ EC_POINT_free(g_point);
+ 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_00024Libressl_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 = !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);
+ 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) {
+ BIGNUM *a;
+ BIGNUM *b;
+
+ BIGNUM *gx;
+ BIGNUM *gy;
+ jobject field;
+
+ BIGNUM *p = BN_new();
+ a = BN_new();
+ b = BN_new();
+ if (!EC_GROUP_get_curve_GFp(curve, p, a, b, NULL)) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Error creating ECParameterSpec, EC_GROUP_get_curve_GFp.");
+ BN_free(p); BN_free(a); BN_free(b);
+ return 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();
+ if (!EC_POINT_get_affine_coordinates_GFp(curve, EC_GROUP_get0_generator(curve), gx, gy, NULL)) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Error creating ECParameterSpec, EC_POINT_get_affine_coordinates_GFp.");
+ BN_free(a); BN_free(b); BN_free(gx); BN_free(gy);
+ 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);
+
+ 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);
+
+ BN_CTX *ctx = BN_CTX_new();
+ if (!ctx) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException",
+ "Could not create bignum context.");
+ return NULL;
+ }
+
+ BN_CTX_start(ctx);
+
+ BIGNUM *order = BN_CTX_get(ctx);
+ if (!order || !EC_GROUP_get_order(curve, order, ctx)) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException",
+ "Could not obtain curve order.");
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ return NULL;
+ }
+
+ jobject order_obj = bignum_to_biginteger(env, order);
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+
+ BIGNUM *h = BN_new();
+ EC_GROUP_get_cofactor(curve, h, NULL);
+ jint cofactor = BN_get_word(h);
+ BN_free(h);
+
+ 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);
+
+ 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_obj, 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);
+
+ native_timing_start();
+ int err = EC_KEY_generate_key(key);
+ native_timing_stop();
+
+ if (!err) {
+ throw_new(env, "java/security/GeneralSecurityException", "Error generating key, EC_KEY_generate_key.");
+ EC_KEY_free(key);
+ return NULL;
+ }
+
+ jbyteArray priv_bytes = (*env)->NewByteArray(env, key_bytes);
+ jbyte *key_priv = (*env)->GetByteArrayElements(env, priv_bytes, NULL);
+ memset(key_priv, 0, key_bytes);
+ BN_bn2bin(EC_KEY_get0_private_key(key), (unsigned char *) key_priv);
+ (*env)->ReleaseByteArrayElements(env, priv_bytes, key_priv, 0);
+
+ unsigned long key_len = 2*key_bytes + 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, (unsigned char *) key_pub, key_len, NULL);
+ (*env)->ReleaseByteArrayElements(env, pub_bytes, key_pub, 0);
+
+ 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_pub_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_00024Libressl_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_00024Libressl_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 = NULL;
+ 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;
+ }
+}
+
+EC_KEY *barray_to_pubkey(JNIEnv *env, const EC_GROUP *curve, jbyteArray pub) {
+ EC_KEY *result = EC_KEY_new();
+ EC_KEY_set_group(result, curve);
+ 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;
+}
+
+EC_KEY *barray_to_privkey(JNIEnv *env, const EC_GROUP *curve, jbyteArray priv) {
+ EC_KEY *result = EC_KEY_new();
+ EC_KEY_set_group(result, curve);
+ jsize priv_len = (*env)->GetArrayLength(env, 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);
+ BN_free(s);
+ 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) {
+ EC_GROUP *curve = create_curve(env, params);
+ if (!curve) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found.");
+ return NULL;
+ }
+
+ EC_KEY *pub = barray_to_pubkey(env, curve, pubkey);
+ EC_KEY *priv = barray_to_privkey(env, curve, privkey);
+
+ 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);
+ 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();
+
+ if (err <= 0) {
+ throw_new(env, "java/security/GeneralSecurityException", "Error computing ECDH, ECDH_compute_key.");
+ EC_KEY_free(pub); EC_KEY_free(priv); EC_GROUP_free(curve);
+ (*env)->ReleaseByteArrayElements(env, result, result_data, JNI_ABORT);
+ return NULL;
+ }
+ (*env)->ReleaseByteArrayElements(env, result, result_data, 0);
+
+ EC_KEY_free(pub);
+ EC_KEY_free(priv);
+ EC_GROUP_free(curve);
+ return result;
+}
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Libressl_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;
+}
+
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Libressl_sign(JNIEnv *env, jobject self, jbyteArray data, jbyteArray privkey, jobject params) {
+ EC_GROUP *curve = create_curve(env, params);
+ if (!curve) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found.");
+ return NULL;
+ }
+
+ EC_KEY *priv = barray_to_privkey(env, curve, privkey);
+
+ jsize data_size = (*env)->GetArrayLength(env, data);
+ jbyte *data_data = (*env)->GetByteArrayElements(env, data, NULL);
+ // TODO: Do more Signatures here, maybe use the EVP interface to get to the hashes easier and not hash manually?
+
+ native_timing_start();
+ ECDSA_SIG *signature = ECDSA_do_sign((unsigned char *) data_data, data_size, priv);
+ native_timing_stop();
+
+ (*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;
+ }
+
+ jsize sig_len = i2d_ECDSA_SIG(signature, NULL);
+ jbyteArray 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);
+ EC_KEY_free(priv);
+ EC_GROUP_free(curve);
+ return result;
+}
+
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Libressl_verify(JNIEnv *env, jobject self, jbyteArray signature, jbyteArray data, jbyteArray pubkey, jobject params) {
+ EC_GROUP *curve = create_curve(env, params);
+ if (!curve) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found.");
+ return JNI_FALSE;
+ }
+
+ EC_KEY *pub = barray_to_pubkey(env, curve, pubkey);
+
+ jsize sig_len = (*env)->GetArrayLength(env, signature);
+ jbyte *sig_data = (*env)->GetByteArrayElements(env, signature, NULL);
+ jbyte *sig_data_ptr = sig_data;
+ ECDSA_SIG *sig_obj = d2i_ECDSA_SIG(NULL, (const unsigned char **)&sig_data_ptr, sig_len);
+ (*env)->ReleaseByteArrayElements(env, signature, sig_data, JNI_ABORT);
+
+ 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();
+
+ if (result < 0) {
+ throw_new(env, "java/security/GeneralSecurityException", "Error verifying, ECDSA_do_verify.");
+ EC_KEY_free(pub); EC_GROUP_free(curve); ECDSA_SIG_free(sig_obj);
+ (*env)->ReleaseByteArrayElements(env, data, data_data, JNI_ABORT);
+ return JNI_FALSE;
+ }
+ (*env)->ReleaseByteArrayElements(env, data, data_data, JNI_ABORT);
+
+ ECDSA_SIG_free(sig_obj);
+ EC_KEY_free(pub);
+ EC_GROUP_free(curve);
+ return (result == 1) ? JNI_TRUE : JNI_FALSE;
+}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/native.h b/src/cz/crcs/ectester/standalone/libs/jni/native.h
index f4a9052..8f5b521 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/native.h
+++ b/src/cz/crcs/ectester/standalone/libs/jni/native.h
@@ -1,24 +1,5 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
-/* Header for class cz_crcs_ectester_standalone_libs_jni_Loader */
-
-#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_Loader
-#define _Included_cz_crcs_ectester_standalone_libs_jni_Loader
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class: cz_crcs_ectester_standalone_libs_jni_Loader
- * Method: setup
- * Signature: (Ljava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_Loader_setup
- (JNIEnv *, jclass, jstring);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
/* Header for class cz_crcs_ectester_standalone_libs_NativeECLibrary */
#ifndef _Included_cz_crcs_ectester_standalone_libs_NativeECLibrary
@@ -1880,3 +1861,184 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
}
#endif
#endif
+/* Header for class cz_crcs_ectester_standalone_libs_LibresslLib */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_LibresslLib
+#define _Included_cz_crcs_ectester_standalone_libs_LibresslLib
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_LibresslLib
+ * Method: createProvider
+ * Signature: ()Ljava/security/Provider;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_LibresslLib_createProvider
+ (JNIEnv *, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_LibresslLib
+ * Method: getCurves
+ * Signature: ()Ljava/util/Set;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_LibresslLib_getCurves
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_Libressl */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Libressl
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Libressl
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Libressl_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Libressl_serialVersionUID 1421746759512286392LL
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Libressl_MAX_ARRAY_SIZE
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Libressl_MAX_ARRAY_SIZE 2147483639L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Libressl_KEYS
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Libressl_KEYS 0L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Libressl_VALUES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Libressl_VALUES 1L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Libressl_ENTRIES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Libressl_ENTRIES 2L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Libressl_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Libressl_serialVersionUID 4112578634029874840LL
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Libressl_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Libressl_serialVersionUID -4298000515446427739LL
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Libressl
+ * Method: setup
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Libressl_setup
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Libressl */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Libressl
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Libressl
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Libressl_DEFAULT_KEYSIZE
+#define cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Libressl_DEFAULT_KEYSIZE 256L
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Libressl
+ * Method: keysizeSupported
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Libressl_keysizeSupported
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Libressl
+ * Method: paramsSupported
+ * Signature: (Ljava/security/spec/AlgorithmParameterSpec;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Libressl_paramsSupported
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Libressl
+ * Method: generate
+ * Signature: (ILjava/security/SecureRandom;)Ljava/security/KeyPair;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Libressl_generate__ILjava_security_SecureRandom_2
+ (JNIEnv *, jobject, jint, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Libressl
+ * Method: generate
+ * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)Ljava/security/KeyPair;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Libressl_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_Libressl */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Libressl
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Libressl
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Libressl */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Libressl
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Libressl
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Libressl */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Libressl
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Libressl
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Libressl
+ * Method: generateSecret
+ * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Libressl_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Libressl
+ * Method: generateSecret
+ * Signature: ([B[BLjava/security/spec/ECParameterSpec;Ljava/lang/String;)Ljavax/crypto/SecretKey;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Libressl_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2Ljava_lang_String_2
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject, jstring);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Libressl */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Libressl
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Libressl
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Libressl
+ * Method: sign
+ * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Libressl_sign
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Libressl
+ * Method: verify
+ * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Libressl_verify
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif